当service通信不能很好的完成任务时候, actionlib则可以比较适合实现长时间的通信过
程, actionlib通信过程可以随时被查看过程进度, 也可以终止请求, 这样的一个特性, 使得它
在一些特别的机制中拥有很高的效率。

1、通信原理

Action的工作原理是client-server模式, 也是一个双向的通信模式。 通信双方在ROS
Action Protocol下通过消息进行数据的交流通信。 client和server为用户提供一个简单的
API来请求目标( 在客户端) 或通过函数调用和回调来执行目标( 在服务器端) 。
工作模式的结构示意图如下:

我们可以看到,客户端会向服务器发送目标指令和取消动作指令,而服务器则可以给客户端发送
实时的状态信息,结果信息,反馈信息等等,从而完成了service没法做到的部分.

2、Action 规范

利用动作库进行请求响应, 动作的内容格式应包含三个部分, 目标、 反馈、 结果。
目标
机器人执行一个动作, 应该有明确的移动目标信息, 包括一些参数的设定, 方向、 角度、 速
度等等。 从而使机器人完成动作任务。
反馈
在动作进行的过程中, 应该有实时的状态信息反馈给服务器的实施者, 告诉实施者动作完成
的状态, 可以使实施者作出准确的判断去修正命令。
结果
当运动完成时, 动作服务器把本次运动的结果数据发送给客户端, 使客户端得到本次动作的
全部信息, 例如可能包含机器人的运动时长, 最终姿势等等

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

#include <actionlib/client/simple_action_client.h>
#include "learning_communication/DoDishesAction.h" typedef actionlib::SimpleActionClient<learning_communication::DoDishesAction> Client; // 当action完成后会调用该回调函数一次
void doneCb(const actionlib::SimpleClientGoalState& state,
const learning_communication::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 learning_communication::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
learning_communication::DoDishesGoal goal;
goal.dishwasher_id = ; // 发送action的goal给服务器端,并且设置回调函数
client.sendGoal(goal, &doneCb, &activeCb, &feedbackCb); ros::spin(); return ;
}

最新文章

  1. andriod一次退出所有的Activity
  2. Part 4 using entity framework
  3. 打造强大的BaseModel(1):让Model自我描述
  4. JavaSE学习总结第23天_多线程1
  5. 简易富文本编辑器bootstrap-wysiwyg源码注释
  6. 在内存中观察CRL托管内存及GC行为
  7. 求m区间内的最小值
  8. 2723:不吉利日期-poj
  9. PHP基础(一)--字符串函数大盘点(基础篇)
  10. [转]自建Syncthing中继服务器(私密传输或造福大众)
  11. 转:在Struts 2中实现文件上传
  12. YUV420序列转成图片
  13. ShowHand
  14. Chakra TypedArray代码实现笔记
  15. android studio 编译sdk版降低报错解决方法
  16. 大型运输行业实战_day15_1_全文检索之Lucene
  17. SQL 2008 R2 收缩日志,不用修改简单模式
  18. Vagrant配置虚拟机
  19. apache的AllowOverride以及Options使用详解
  20. CSS过渡动画之transition

热门文章

  1. [Python+Java双语版自动化测试(接口测试+Web+App+性能+CICD)
  2. SparkStreaming获取kafka数据的两种方式:Receiver与Direct
  3. Mybatis缓存+配置
  4. Network基础(五):配置静态路由、配置浮动路由、配置多路由的静态路由、配置默认路由
  5. centos6 sersync2使用
  6. vue消息提示Message
  7. 5. 使用grafana模板
  8. 高博SLAM14讲 ch5 点云拼接例程实现与bug处理
  9. PAT甲级——A1151 LCA_in_a_BinaryTree【30】
  10. PAT甲级——A1146 TopologicalOrder【25】