
Hi all, I've made two simple action server A and B and one action client C that can communicate with both. I experienced a really strange behaviour: if i put the two server nodes within a launch file along with the client and i use the "roslaunch" to run the launch file, the two servers seem to run, but the client waits for the server. If i use "rosrun" to run the 3 single nodes in three different terminals, everything works well. The sequence of running the nodes doesnt matter as long as if i run as first the client using rosrun it waits the server and when i run later one of the server with rosrun it works perfectly. Anyone have a solution? i absolutely need to run everything within a launch file.As i have highlighted, the problem is not connected with the node' code lines as long as running them through "rosrun" i have the results i need that's why i dont post the code. Anyway the launch file is this one
<?xml version="1.0"?> <launch> <node pkg="action_test" type="GoDriveActionServer" name="GoDriveActionServer" launch-prefix="xterm -e" /> <node pkg="action_test" type="TakeVideoActionServer" name="TakeVideoActionServer" launch-prefix="xterm -e" /> <node pkg="action_test" type="ActionClient" name="ActionClient" launch-prefix="xterm -e" /> </launch> Thanks in advance
UPDATE
I also tried to make the client as easy as possible without waiting for the servers, without feedbacks and done callbacks, but running the three nodes within a launch file doesn't allow the client to communicate with the servers, instead i don't have any problem if i run the three nodes separately, everyone in a single terminal.
This is so so strange.
UPDATE WITH CODE
I tried to remove the launch-prefix adding the output="screen" but nothing.
Launching "roswtf" after i run roslaunch action_test action_test.launch i get:
Loaded plugin tf.tfwtf No package or stack in context ================================================================================ Static checks summary: No errors or warnings ================================================================================ Beginning tests of your ROS graph. These may take awhile... analyzing graph... ... done analyzing graph running graph rules... ... done running graph rules Online checks summary: Found 1 warning(s). Warnings are things that may be just fine, but are sometimes at fault WARNING The following node subscriptions are unconnected: * /SimpleActionClient: * /go_drive/feedback * /take_video/status * /go_drive/result * /take_video/result * /go_drive/status * /take_video/feedback * /GoDriveActionServer: * /GoDriveActionServer/cancel * /GoDriveActionServer/goal * /TakeVideoActionServer: * /TakeVideoActionServer/cancel * /TakeVideoActionServer/goal so i think there's nothing wrong
The code for the go_drive server is something like this (it's the same for the take video):
#include <ros/ros.h> #include <actionlib/server/simple_action_server.h> #include <action_test/GoDriveAction.h> class GoDriveAction { protected: ros::NodeHandle nh_; actionlib::SimpleActionServer<action_test::GoDriveAction> as_; std::string action_name_; // create messages that are used to published feedback/result action_test::GoDriveFeedback feedback_; action_test::GoDriveResult result_; public: GoDriveAction(std::string name) : as_(nh_, name, boost::bind(&GoDriveAction::executeCB, this, _1), false), action_name_(name) { ROS_INFO_STREAM(action_name_.c_str() << " server is running"); as_.start(); } ~GoDriveAction(void) { } void executeCB(const action_test::GoDriveGoalConstPtr &goal) { DO SOMETHING } }; int main(int argc, char** argv) { ros::init(argc, argv, "go_drive"); GoDriveAction go_drive(ros::this_node::getName()); ros::spin(); return 0; } and the client is something like:
#include .... SimpleActionClient::SimpleActionClient() : take_video_client_("take_video", true), go_drive_client_("go_drive", true) { ROS_INFO_STREAM("Starting simple action client"); // SUBSCRIBE SOMETHING } SimpleActionClient::~SimpleActionClient() { ROS_INFO_STREAM("Stopping simple action client"); } void SimpleActionClient::taskCallback(const getsomething::getsomething& msg){ DO SOMETHING go_drive_client_.sendGoal(go_drive_goal, boost::bind(&SimpleActionClient::goDriveDoneCb, this, _1, _2), boost::bind(&SimpleActionClient::goDriveActiveCb, this), boost::bind(&SimpleActionClient::goDriveFeedbackCb, this, _1)); } // Called every time feedback is received for the goal void SimpleActionClient::takeVideoFeedbackCb(const action_test::TakeVideoFeedbackConstPtr& feedback) { .... } void SimpleActionClient::goDriveFeedbackCb(const action_test::GoDriveFeedbackConstPtr& feedback) { .... } void SimpleActionClient::takeVideoDoneCb(const actionlib::SimpleClientGoalState& state, const action_test::TakeVideoResultConstPtr& result) { .... } void SimpleActionClient::goDriveDoneCb(const actionlib::SimpleClientGoalState& state, const action_test::GoDriveResultConstPtr& result) { .... } // Called once when the goal becomes active void SimpleActionClient::takeVideoActiveCb() { .... } // Called once when the goal becomes active void SimpleActionClient::goDriveActiveCb() { .... } int main (int argc, char **argv){ ros::init(argc, argv, "simple_action_client_node"); SimpleActionClient simple_action_client_node; ros::spin(); return 0; } I repeat, if i run all the nodes separately, so one terminal with **roscore** another one with **rosrun action_test GoDriveActionServer**, another with **rosrun action_test TakeVideoActionServer** and another with **rosrun action_test ActionClient** everything works absolutely well, but grouping them into a launch file can't run the servers.
Originally posted by dottant on ROS Answers with karma: 185 on 2019-01-15
Post score: 0
Original comments
Comment by aPonza on 2019-01-16:
I didn't understand the problem: in the end you are saying both roslaunching and rosrunning yield 2 functioning servers and a client that waits for the server(s?). Where's the difference? What's the expected behaviour? Also what's the launch prefix for?
Comment by dottant on 2019-01-16:
Maybe i didnt write it right:
- if i run the launch file i posted, the servers run advising that they are ready to receive goals, but the client stucks in the "waitForServer();
- if i run roscore in a terminal and the 3 nodes in diff terminals using "rosrun" everything works
Comment by aPonza on 2019-01-17:
From the update it seems you managed to get a minimum working example. What you experience does seem weird, so maybe it could help if we could see the code for that. I still don't understand the need for the launch prefix, by the way: have you tried removing it and using the output attribute?
Comment by dottant on 2019-01-17:
Sorry, but i think you didn't understand the point: the nodes work absolutely well if i run them separately without grouping them into a launch file, so the error is not within the code. Removing the launch-prefix and setting the output parameter to screen doesn't change anything.
Comment by aPonza on 2019-01-17:
A MCVE helps both you and others solve your problem. Yesterday I was thinking it could be a namespace issue or something with the fact roslaunch changes the cwd.