ROS actionlib任务机制详解

action作为ROS中三种基础通讯方式之一,在service的基础上,增加了反馈与中断,是很好的任务控制机制实现基础。actionlib是基于action通讯方式的ROS包集,包含了便捷丰富的功能接口,用来实现对任务服务器,客户端的高级设计。

下图为action通讯机制:

在这里插入图片描述

基础使用

如果暂时只想简单使用,不想关心深入的任务机制问题,wiki actionlib 基础教程给出了最基础的server与client实现,教程中使用SimpleActionServer提供的接口,这也是我们使用最多最便捷工具,提供的清晰简易的接口,例如导航move_base,机械臂move_group规划都是使用这种方式实现的,设计更复杂的任务机制时,会配合ActionServer一起使用,注意少了Simple。

在这一部分,需要了解部分实现方式与消息接口。

消息接口:

目标(Goal)

目标由ActionClient发送到ActionServer。消息类型就是你使用的actionGoal类型,其实就是action消息里的Goal部分。

反馈(Feedback)

反馈为服务器实现者提供了一种方法,可以通知ActionClient目标的增量进度,比如执行到了第几步。

结果(Result)

完成目标后,结果将从ActionServer发送到ActionClient。与反馈不同,结果是一次发送,只有比较重要的步骤完成或者失败后会返回一个整个任务的状态。

实现方式

  1. 确定action消息类型,可以自定义或者使用基础消息类型,基础消息需要在头文件引入,而自定义消息需要在cmakelist文件中添加,同时两种方式都需要将actionlib添加进acmkelist与package两个文件的依赖,参考基础教程。

  2. 代码实现:

    举例C++的server实现:

    #include <chores/DoDishesAction.h>  // 使用的自定义消息类型
    #include <actionlib/server/simple_action_server.h> // 使用SimpleActionServer的接口实现功能
    
    typedef actionlib::SimpleActionServer<chores::DoDishesAction> Server; // 定义SimpleActionServer类
    //当server接受Goal之后,调用execute函数,完成任务主体功能
    void execute(const chores::DoDishesGoalConstPtr& goal, Server* as)  // Note: "Action" is 	not 	appended to DoDishes here
    {
         
      // 函数实现任务功能
      as->setSucceeded(); // 完成任务后将server状态设置为成功
    }
    
    int main(int argc, char** argv)
    {
         
      ros::init(argc, argv, "do_dishes_server");
      ros::NodeHandle n;
      // 初始化类对象,并定义action名称为“do_dishes”,绑定execute为任务回调函数,并传入参数server,方便在回调函数中使用对象接口,false为不在初始化时,自动启动
      Server server(n, "do_dishes", boost::bind(&execute, _1, &server), false);
      server.start(); // 开始server 
      ros::spin(); // 进入回调,以固定频率轮循并完成回调队列中的任务
      return 0;
    }
    
  3. action消息会自动转换为msg消息,并发出五个接口,action_name + /goal /status /feedback /result /cancel,这几个接口同样可以直接使用,使用topic发送消息的形式,而不是直接使用actionlib接口

    例如生成了NameActionGoal.msg与NameGoal.msg,前者主要是用于生成topic消息的类型发出,而后者是在程序中actionlib对象发送的消息内容,注意区分

高级任务交互

本部分主要记录SimpleAcitionServer与ActionServer的复杂任务代码实现,状态机制等原理参考给出的相关教程。

原理

可以参考actionlib高级交互技术,非常好的总结了状态转换的过程。

功能实现

wiki actionlib Tutorials给出了一些深入使用的相关教程,可以阅读了解并测试。

actionlib的所有接口都在 here.

simple_action_server与action_server区别:

  1. 简单与复杂(画重点)
  2. 阅读过原理之后可以了解到,simple就是做了简化,包括任务的状态机制,以及新任务的处理机制
  3. 更多的需要关注的是在使用过程中如何选择,很简单,看下边的接口文档,了解接口都有什么,当你需要的任务功能simple不能满足时,选后者,如果都不能实现,那就选简单的呗
  4. 一般情况下simple可以满足大多数任务需求,但是当任务复杂,需要关注更多更细致的状态时,就要更换action_server,最明显的差异是两者对于新任务的处理,simple会直接放弃旧的开始新的,没有改变的方法,而后者可以灵活的处理新任务,无论是拒绝或者执行或者实现更复杂的任务队列
  5. 在功能,代码复杂度上相差不多,根据需求灵活选用即可

SimpleActionServer

接口:simple_action_server

包含所有的能用接口,其实就这几种:

  • 对象初始化
  • 回调函数注册绑定
  • 三种状态改变,注意包含参数,可以设置result的消息内容
  • 状态判断,注意setPreempted 和 isPreemptRequested的区别
  • 反馈发布

例子:

#include <ros/ros.h>
#include <ros/time.h>
#include "pan_tilt_msgs/PanTiltCmdAction.h"
#include "pan_tilt_driver.h"
#include <actionlib/server/simple_action_server.h>
#include <string>

typedef actionlib::SimpleActionServer<pan_tilt_msgs::PanTiltCmdAction> Server;

class PanTiltDriverAction
{
   
public:
  PanTiltDriverAction();
  ~PanTiltDriverAction();
  void ExecuteCb(const pan_tilt_msgs::PanTiltCmdGoalConstPtr& goal);
  void preemptCB(
  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值