ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question
1

Using actionlib client within subscriber callback

asked 2014-08-21 07:10:47 -0500

dalishi gravatar image

updated 2014-08-21 07:57:03 -0500

dornhege gravatar image

Hi Guys,

I have been using the actionlib client to send goals to the navigation stack. Now the case is I have to get the goal position from a subscriber and I put the actionlib client in the callback of the subscriber as follows. The problem is we want the robot to be able to deal with new coming goal even the current goal has not reached, i.e. the robot will always moving towards the new goal. I don't know how to deal with the callback to deal with the latest coming message from the subscriber. Thanks.

void PoseCallback(const geometry_msgs::PoseStamped::ConstPtr& goal, MoveBaseClient* ac)
{
move_base_msgs::MoveBaseGoal mb_goal;

// fill in the mb_goal
  ...

  ac->sendGoal(mb_goal);

 ac->waitForResult();

  if(ac->getState() == actionlib::SimpleClientGoalState::SUCCEEDED)

    ROS_INFO("The robot has reached the goal");
  else

    ROS_INFO("The base failed to get to the goal");

}

int main(int argc, char** argv)

{

  ros::init(argc, argv, "move_base_client");

  ros::NodeHandle nh;

  MoveBaseClient ac("move_base", true);

  while(!ac.waitForServer(ros::Duration(5.0)))

{

  ROS_INFO("Waiting for the move_base action server to come up");

  }

 ros::Subscriber pose_sub = nh.subscribe<geometry_msgs::PoseStamped>("nav_topics", 1, boost::bind(PoseCallback, _1, &ac));

 ros::spin();

  return 0;

}
edit retag flag offensive close merge delete

2 Answers

Sort by ยป oldest newest most voted
2

answered 2014-08-21 14:36:34 -0500

paulbovbel gravatar image

updated 2014-08-21 21:29:07 -0500

The problem is that you're blocking on the poseCb with:

ac->waitForResult();

Take a look at the SimpleActionClient API. The 'actionlib' way to do what you want is to register another callback - SimpleDoneCallback (e.g. doneCb) - when you send the goal, and have your poseCb return then and there.

In the doneCb, you will receive something every time a goal terminates. If you send goal 1, and then goal 2 before goal 1 completes, you will receive a doneCb with a SimpleClientGoalState reflecting the preempted or cancelled status, as per the SimpleActionClient contract that only one goal can be active at a time. For more reference check the flowchart and policies in http://wiki.ros.org/actionlib/Detaile... .

Of course, you could always just skip actionlib entirely and send goals to the move_base_simple/goaltopic instead, depending on your usecase.

edit flag offensive delete link more

Comments

Thanks paulbovbel, I am switching to publishing to the move_base_simple/goal and will explore the actionlib way later. Thanks.

dalishi gravatar image dalishi  ( 2014-08-21 20:35:08 -0500 )edit
1

answered 2014-08-21 12:39:09 -0500

ahubers gravatar image

updated 2014-08-21 12:39:37 -0500

I believe you're more than capable to just send a new goal. Right now it seems that you're halting any future goals with this line of code:

  ac->waitForResult();

  if(ac->getState() == actionlib::SimpleClientGoalState::SUCCEEDED)

    ROS_INFO("The robot has reached the goal");
  else

    ROS_INFO("The base failed to get to the goal");

To my knowledge, removing these lines will just send the most recent goal to the action server, and it will try to execute that until a new goal arrives.

Does this answer your question or is there something I've misread?

edit flag offensive delete link more

Comments

Thanks ahubers, you workaround should solve my problem. But in this way, I am not able to track the execution status of the goal that I have sent.

dalishi gravatar image dalishi  ( 2014-08-21 20:37:16 -0500 )edit

Question Tools

2 followers

Stats

Asked: 2014-08-21 07:10:47 -0500

Seen: 2,155 times

Last updated: Aug 21 '14