How to cancel actionlib in client using C++

asked 2017-07-12 08:36:49 -0600

sam gravatar image

I want to cancel an ongoing action in the server. My ros distribution is indigo and I run the actionlib tutorial from this page: http://wiki.ros.org/actionlib

I have modified a little to see if I can cancel the action whenever I want. The following is my server source code

#include <actionlib_test/DoDishesAction.h>
#include <actionlib/server/simple_action_server.h>

typedef actionlib::SimpleActionServer<actionlib_test::DoDishesAction> Server;

void execute(const actionlib_test::DoDishesGoalConstPtr& goal, Server* as)
{
  ROS_INFO("I'm cleaning dish number %d",goal->dishwasher_id);
  for(int i=0; i<10; i++)
  {
      sleep(1);
  }
  ROS_INFO("cleaning done!");
  as->setSucceeded();
}

int main(int argc, char** argv)
{
  ros::init(argc, argv, "do_dishes_server");
  ros::NodeHandle n;
  Server server(n, "do_dishes", boost::bind(&execute, _1, &server), false);
  server.start();
  ros::Rate loop_rate(0.5);
  while(ros::ok())
  {
      ROS_INFO("ready!");
      //也是要spinOnce才夠接收actionlib
      ros::spinOnce();
      loop_rate.sleep();
  }

  return 0;
}

and the following is my client source code

#include <actionlib_test/DoDishesAction.h>
#include <actionlib/client/simple_action_client.h>

typedef actionlib::SimpleActionClient<actionlib_test::DoDishesAction> Client;

int main(int argc, char** argv)
{
  ros::init(argc, argv, "do_dishes_client");
  Client client("do_dishes", true); // true -> don't need ros::spin()
  Client client2("do_dishes", true); // true -> don't need ros::spin()
  client.waitForServer();
  actionlib_test::DoDishesGoal goal;
  goal.dishwasher_id = 1;  
  client.sendGoal(goal);
  sleep(2);
  //goal.dishwasher_id = 2;
  //client2.sendGoal(goal);
  //這行指令執行後會讓此node等到action執行結束或是5秒
  client.waitForResult(ros::Duration(0.1));
  client.cancelGoal();

  //if (client.getState() == actionlib::SimpleClientGoalState::SUCCEEDED)
  //  printf("Yay! The dishes are now clean");
  //printf("Current State: %s\n", client.getState().toString().c_str());
  ros::Rate loop_rate(5);
  //這邊可以偵測actionlib是否結束
  while(ros::ok())
  {
      //PENDING代表發出任務但server端尚未執行,ACTIVE代表正在執行,SUCCEEDED代表actionlib完成
      ROS_INFO("Current State: %s\n", client.getState().toString().c_str());
      loop_rate.sleep();
  }
  return 0;
}

I passed the compilation and I've tried to cancel my ongoing action by using client.cancelGoal();in the client, but it seems not work. The "cleaning done!" is still printed.

Thanks.

edit retag flag offensive close merge delete