0
$\begingroup$

Rosanswers logo

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.

$\endgroup$

1 Answer 1

0
$\begingroup$

Rosanswers logo

You're setting the server node name as

"ros::init(argc, argv, "go_drive");"
                       ^

which is the same as the client's action name (see \param name definition)

SimpleActionClient::SimpleActionClient() : 
  take_video_client_("take_video", true),
                     ^
  go_drive_client_("go_drive", true)
                   ^

so this works while rosrunning, but you are renaming the nodes in the launch file:

<node pkg="action_test" type="GoDriveActionServer" name="GoDriveActionServer" launch-prefix="xterm -e" />
                                                   ^
<node pkg="action_test" type="TakeVideoActionServer" name="TakeVideoActionServer" launch-prefix="xterm -e" /> 
                                                     ^

so this doesn't work while roslaunching.


Originally posted by aPonza with karma: 589 on 2019-01-17

This answer was ACCEPTED on the original site

Post score: 0


Original comments

Comment by dottant on 2019-01-17:
thank you so much, i didn't realize about it, i've set them as i called them in the cmakelists

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.