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 roslaunch
ing and rosrun
ning 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.