ROS 动作库的请求与相应(基于c++) 创建并使用ROS action服务器(代码详细解释)

action文件:

# Define the goal
uint32 dishwasher_id  # Specify which dishwasher we want to use
---
# Define the result
uint32 total_dishes_cleaned
---
# Define a feedback message
float32 percent_complete

action_server.cpp文件

#include <ros/ros.h>
/*用于实现简单操作的操作库*/
#include <actionlib/server/simple_action_server.h>
/*这是从FibonacciAction.msg文件自动生成的标头*/
#include <eai_tutorials/FibonacciAction.h>

class FibonacciAction
{
protected:
  ros::NodeHandle nh_; //构造节点句柄并在构造动作期间将其传递到动作服务端
  /*定义动作库服务器变量*/
  actionlib::SimpleActionServer<eai_tutorials::FibonacciAction> as_;
 /*定义动作服务名*/
  std::string action_name_;
  /*定义动作服务器反馈变量*/
  eai_tutorials::FibonacciFeedback feedback_;
 /*定义动作服务器执行结果变量*/
  eai_tutorials::FibonacciResult result_;

public:
/*类的构造函数,创建了一个操作服务端,并指定操作函数为executeCB,回调函数传递一个指向目标消息的指针。注意:这是一个boost共享指针,通过将“ConstPtr”附加到目标消息类型的末尾来给出*/
  FibonacciAction(std::string name):
    as_(nh_, name, boost::bind(&FibonacciAction::executeCB, this, _1), false),
    action_name_(name){
    as_.start();
  }
/*类的析构函数*/
  ~FibonacciAction(void){}

/*操作函数为executeCB,回调函数传递一个指向目标消息的指针。注意:这是一个boost共享指针,通过将“ConstPtr”附加到目标消息类型的末尾来给出*/
  void executeCB(const eai_tutorials::FibonacciGoalConstPtr &goal)
  {
    // helper variables
    ros::Rate r(1);
    bool success = true;

    // 初始化fibonacci 队列
    feedback_.sequence.clear();
    feedback_.sequence.push_back(0);
    feedback_.sequence.push_back(1);

    // publish info to the console for the user
    ROS_WARN("%s: Executing, creating fibonacci sequence of order %i with seeds %i, %i", action_name_.c_str(), goal->order, feedback_.sequence[0], feedback_.sequence[1]);

    /*动作服务端的一个重要组件是允许动作客户端请求取消当前目标执行的能力。当客户端请求抢占当前目标时,操作服务端应取消目标,执行必要的清理,并调用函数setPreempted(),该函数表示操作已被用户请求抢占。设置操作服务端检查抢占请求的速率由服务端的实现者决定。
*/
    for(int i=1; i<=goal->order; i++)
    {
      // check that preempt has not been requested by the client
      if (as_.isPreemptRequested() || !ros::ok())
      {
        ROS_WARN("%s: Preempted", action_name_.c_str());
        // set the action state to preempted
        as_.setPreempted();
        success = false;
        break;
      }
//这里将Fibonacci序列放入反馈变量中
      feedback_.sequence.push_back(feedback_.sequence[i] + feedback_.sequence[i-1]);
      // 在动作服务端提供的反馈通道上发布反馈
      as_.publishFeedback(feedback_);
      
      r.sleep();
    }
/*一旦动作完成计算Fibonacci序列,该动作通过设置成功通知动作客户端动作完成*/
    if(success)
    {
      result_.sequence = feedback_.sequence;
      ROS_WARN("%s: Succeeded", action_name_.c_str());
      // set the action state to succeeded
      as_.setSucceeded(result_);
    }
  }
};

int main(int argc, char** argv)
{
  ros::init(argc, argv, "fibonacci");
  FibonacciAction fibonacci("fibonacci");
  ros::spin();
  return 0;
}

 action_client.cpp文件:

#include <ros/ros.h>
/*用于实现简单操作的操作库*/
#include <actionlib/client/simple_action_client.h>
/*定义了可能的目标状态*/
#include <actionlib/client/terminal_state.h>
/*这是从FibonacciAction.msg文件自动生成的标头*/
#include <eai_tutorials/FibonacciAction.h>

int main (int argc, char **argv)
{
  ros::init(argc, argv, "test_fibonacci");
/*指定要与动作服务端通信的消息类型。动作客户端构造函数还接受两个参数,即要连接的服务端名称和用于自动旋转线程的布尔选项*/
  actionlib::SimpleActionClient<eai_tutorials::FibonacciAction> ac("fibonacci", true);
/*由于动作服务端可能未启动并运行,因此客户端将在继续之前等待操作服务端启动*/
  ROS_WARN("Waiting for action server to start.");
  // wait for the action server to start
  ac.waitForServer(); //will wait for infinite time
/*此处创建目标消息,设置目标值并将其发送到操作服务端*/
  ROS_WARN("Action server started, sending goal.");
  // send a goal to the action
  eai_tutorials::FibonacciGoal goal;
  goal.order = 20;
  ac.sendGoal(goal);

  /*动作客户端现在等待目标完成后再继续。等待超时设置为30秒,这意味着如果目标尚未完成,则30秒后函数将返回false*/
  bool finished_before_timeout = ac.waitForResult(ros::Duration(30.0));
/*如果在超时之前完成目标,则报告目标状态,否则通知用户目标未在指定的时间内完成*/
  if (finished_before_timeout)  {
    actionlib::SimpleClientGoalState state = ac.getState();
    ROS_WARN("Action finished: %s",state.toString().c_str());
  }
  else
    ROS_WARN("Action did not finish before the time out.");

  return 0;
}

 

 

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值