Mastering ROS for Robotics Programming(Second Edition)
上QQ阅读APP看书,第一时间看更新

Creating the ROS action server

In this section, we will discuss demo_action_server.cpp. The action server receives a goal value that is a number. When the server gets this goal value, it will start counting from zero to this number. If the counting is complete, it will successfully finish the action, if it is preempted before finishing, the action server will look for another goal value.

This code is a bit lengthy, so we can discuss the important code snippet of this code.

Let's start with the header files:

#include <actionlib/server/simple_action_server.h> 
#include "mastering_ros_demo_pkg/Demo_actionAction.h" 

The first header is the standard action library to implement an action server node. The second header is generated from the stored action files. It should include accessing our action definition:

class Demo_actionAction 
{  

This class contains the action server definition:

actionlib::SimpleActionServer<mastering_ros_demo_pkg::Demo_actionAction> as; 

Create a simple action server instance with our custom action message type:

mastering_ros_demo_pkg::Demo_actionFeedback feedback; 

Create a feedback instance for sending feedback during the operation:

mastering_ros_demo_pkg::Demo_actionResult result; 

Create a result instance for sending the final result:

Demo_actionAction(std::string name) : 
  as(nh_, name, boost::bind(&Demo_actionAction::executeCB, this, _1), false), 
  action_name(name) 

This is an action constructor, and an action server is created here by taking an argument such as Nodehandle, action_name, and executeCB, where executeCB is the action callback where all the processing is done:

as.registerPreemptCallback(boost::bind(&Demo_actionAction::preemptCB, this)); 

This line registers a callback when the action is preempted. The preemtCB is the callback name executed when there is a preempt request from the action client:

 void executeCB(const mastering_ros_demo_pkg::Demo_actionGoalConstPtr &goal) 
 { 
 if(!as.isActive() || as.isPreemptRequested()) return; 

This is the callback definition which is executed when the action server receives a goal value. It will execute callback functions only after checking whether the action server is currently active or it is preempted already:

 for(progress = 0 ; progress < goal->count; progress++){ 
  //Check for ros 
  if(!ros::ok()){ 

This loop will execute until the goal value is reached. It will continuously send the current progress as feedback:

  if(!as.isActive() || as.isPreemptRequested()){ 
   return; 
  }  

Inside this loop, it will check whether the action server is active or it is preempted. If it occurs, the function will return:

  if(goal->count == progress){ 
   result.final_count = progress; 
   as.setSucceeded(result); 
  } 

If the current value reaches the goal value, then it publishes the final result:

 Demo_actionAction demo_action_obj(ros::this_node::getName()); 

In main(),we create an instance of Demo_actionAction, which will start the action server.