ROS进阶功能—action通信机制

ROS进阶功能—action通信机制

一、总述

ROS中常用的通信机制是话题(Topic)和服务(Service),但是在很多场景下,这两种通信机制往往满足不了所有需求。比如机械臂控制,如果用话题发布运动目标,由于话题是单向通信,则需要另外订阅一个话题来获得机器人运动过程中的状态反馈。如果用服务发布运动目标,虽然可以获得一次反馈信息,但是对于控制来说数据太少,而且当反馈迟迟没有收到时,就只能等待,做不了其他事情。那么有没有一种更加合适的通信机制来满足类似这样场景的需求呢?即action。

二、action

ROS中包含一个名为actionlib的功能包,用于实现action的通信机制。action是一种类似于Service的问答通信机制,不同之处在于action带有连续反馈,可以不断反馈任务进度,也可以在任务过程中中止运行。

三、action的工作机制

action也采用客户端/服务器(Client/Server)的工作模式。
在这里插入图片描述client和server之间通过actionlib定义的“action protocol”进行通讯。这种通讯协议是基于ROS的消息机制实现的,为用户提供了client和server的接口。

在这里插入图片描述Client向Server端发布任务目标以及在必要的时候取消任务,Server会向Client发布当前状态、实时反馈和任务执行的最终结果。
1)goal:任务目标。
2)cancel:请求取消任务。
3)status:通知client当前的状态。
4)feedback:周期反馈任务运行的监控数据。
5)result:向client发送任务的执行结果,这个topic只会发布一次。

四、action的简单案例

这个案例简单地实现了一个洗盘子的action通信功能。客户端发送洗盘子的目标,服务器端返回洗盘子的结果,并随时反馈洗盘子的进度。共用到action消息中的:goal、feedback和result.
首先是需要新建一个action文件夹,在其下定义一个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

之后要在CMakeLists.txt 文件中加入以下编译规则:

find_package(catkin REQUIRED genmsg actionlib_msgs actionlib)
add_action_files(DIRECTORY action FILES DoDishes.action) generate_messages(DEPENDENCIES actionlib_msgs)

并在package.xml 文件中加入以下依赖项:

<build_depend>actionlib</build_depend>
<build_depend>actionlib_msgs</build_depend>
<run_depend>actionlib</run_depend>
<run_depend>actionlib_msgs</run_depend>

然后就可以对文件进行编译,编译成功后会产生以下.msg 文件,这些都是action中需要用到的消息类型,由此可见action确实是根据topic实现的。

DoDishesAction.msg
DoDishesActionGoal.msg
DoDishesActionResult.msg
DoDishesActionFeedback.msg
DoDishesGoal.msg
DoDishesResult.msg
DoDishesFeedback.msg

编写客户端client:

#include <actionlib/client/simple_action_client.h>
#include "action_tutorials/DoDishesAction.h"
typedef actionlib::SimpleActionClient<action_tutorials::DoDishesAction> Client;
// 当action完成后会调用次回调函数一次
void doneCb(const actionlib::SimpleClientGoalState& state,
        const action_tutorials::DoDishesResultConstPtr& result)
{
    ROS_INFO("Yay! The dishes are now clean");
    ros::shutdown();
}
// 当action激活后会调用次回调函数一次
void activeCb()
{
    ROS_INFO("Goal just went active");
}
// 收到feedback后调用的回调函数
void feedbackCb(const action_tutorials::DoDishesFeedbackConstPtr& feedback)
{
    ROS_INFO(" percent_complete : %f ", feedback->percent_complete);
}
int main(int argc, char** argv)
{
    ros::init(argc, argv, "do_dishes_client");
    // 定义一个客户端
    Client client("do_dishes", true);
    // 等待服务器端
    ROS_INFO("Waiting for action server to start.");
    client.waitForServer();
    ROS_INFO("Action server started, sending goal.");
    // 创建一个action的goal
    action_tutorials::DoDishesGoal goal;
    goal.dishwasher_id = 1;
    // 发送action的goal给服务器端,并且设置回调函数
    client.sendGoal(goal,  &doneCb, &activeCb, &feedbackCb);
    ros::spin();
    return 0;
}

然后编写服务器端:

#include <ros/ros.h>
#include <actionlib/server/simple_action_server.h>
#include "action_tutorials/DoDishesAction.h"
 
typedef actionlib::SimpleActionServer<action_tutorials::DoDishesAction> Server;
 
// 收到action的goal后调用的回调函数
void execute(const action_tutorials::DoDishesGoalConstPtr& goal, Server* as)
{
    ros::Rate r(1);
    action_tutorials::DoDishesFeedback feedback;
    ROS_INFO("Dishwasher %d is working.", goal->dishwasher_id);
    // 假设洗盘子的进度,并且按照1hz的频率发布进度feedback
    for(int i=1; i<=10; i++)
    {
        feedback.percent_complete = i * 10;
        as->publishFeedback(feedback);
        r.sleep();
    }
    // 当action完成后,向客户端返回结果
    ROS_INFO("Dishwasher %d finish working.", goal->dishwasher_id);
    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::spin();
    return 0;
}

运行之后,客户端:
在这里插入图片描述
服务器端:
在这里插入图片描述

五、总结

action通信机制是实现智能机器人的很重要的部分,其中的概念其实并不是很困难,但它也仅仅只是一个工具,要实现智能机器人还是得需要一些更高级任务管理机制,比如状态机和行为树。

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我不是“耀”神

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值