当前位置:网站首页>ROS学习(23)action通信机制
ROS学习(23)action通信机制
2022-07-06 18:12:00 【敲代码的雪糕】
前言
ROS中常用的通信机制是话题和服务,但是很多场景下,这两种通信机制往往满足不了所有需求。
action通信机制,是一种带有连续反馈的上层通信机制,底层基于ROS话题通信。
一、什么是action
ROS中的actionlib功能包,用于实现action的通信机制。action类似于服务通信机制,不同之处在于action带有连续反馈,可以不断的反馈任务进度,也可以在任务过程中中止运行。
二、action的工作机制
action采用客户端/服务器的工作模式,如下:
Action客户端与Action服务端之间通过actionlib定义的action protocol进行通信,这种协议基于ROS的消息机制实现。
客户端向服务端发布任务目标以及在必要的时候取消任务,服务端会向客户端发布当前状态、实时反馈和任务执行的结果。如图:
三、action的定义
action通过.action文件定义,放置在功能包中的action文件夹下,格式如下:
#定义目标信息
uint32 dishwasher_id
#定义结果信息
uint32 total_dishes_cleaned
#定义周期反馈的消息
float32 percent_complete
可见,一个action的定义需要三部分:goal、result、feedback。
四、代码实现
主要实现action的客户端和服务端节点,新建名为action_tutorials功能包。
1、创建客户端
在action的定义中,描述了一个洗盘子的任务。客户端节点负责发出action请求,DoDishes_client.cpp文件内容如下:
#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;
}
2、创建服务端
服务器节点负责完成洗盘子的任务,并且反馈洗盘子的实时进度,DoDishes_server.cpp文件内容如下:
#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;
}
3、配置
在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>
<build_depend>roscpp</build_depend>
<run_depend>actionlib</run_depend>
<run_depend>actionlib_msgs</run_depend>
<run_depend>roscpp</run_depend>
然后编译功能包,如下:
从编译后生成的这些文件看,action确实是一种基于消息的、更加高层的通信机制。
4、运行
先启动master节点,命令如下:
roscore
启动服务端节点,命令如下:
rosrun action_tutorials DoDishes_server
再启动客户端节点,命令如下:
rosrun action_tutorials DoDishes_client
效果如下:
边栏推荐
- Compile command line terminal swift
- C语言实例_2
- C语言实例_5
- 字符串的相关编程题
- 刨析《C语言》【进阶】付费知识【完结】
- 蓝桥杯2022年第十三届省赛真题-积木画
- Baidu flying general BMN timing action positioning framework | data preparation and training guide (Part 1)
- Make Jar, Not War
- Match VIM from zero (0) -- Introduction to vimscript
- Public key \ private SSH avoid password login
猜你喜欢
tansig和logsig的差异,为什么BP喜欢用tansig
Basic introduction and use of dvajs
Baidu flying general BMN timing action positioning framework | data preparation and training guide (Part 2)
AcWing 345. Cattle station solution (nature and multiplication of Floyd)
设置Wordpress伪静态连接(无宝塔)
Appium automation test foundation uiautomatorviewer positioning tool
js如何快速创建一个长度为 n 的数组
LeetCode:1175. 质数排列
JVM 内存模型
Reptile practice (VI): novel of climbing pen interesting Pavilion
随机推荐
Baidu flying general BMN timing action positioning framework | data preparation and training guide (Part 2)
ZOJ Problem Set – 2563 Long Dominoes 【如压力dp】
The cradle of eternity
设置Wordpress伪静态连接(无宝塔)
Can't you understand the code of linked list in C language? An article allows you to grasp the secondary pointer and deeply understand the various forms of parameter passing in the function parameter
AcWing 361. Sightseeing cow problem solution (SPFA seeking positive ring)
制作带照明的DIY焊接排烟器
WCF基金会
mysqlbackup 还原特定的表
Box stretch and pull (left-right mode)
JVM memory model
uva 1401 dp+Trie
C语言实例_4
糊涂工具类(hutool)post请求设置body参数为json数据
Dark horse notes - create immutable sets and streams
Let's see how to realize BP neural network in Matlab toolbox
JS Es5 can also create constants?
Machine learning: the difference between random gradient descent (SGD) and gradient descent (GD) and code implementation.
增加 pdf 标题浮窗
JS ES5也可以创建常量?