当前位置:网站首页>ROS學習(23)action通信機制
ROS學習(23)action通信機制
2022-07-07 01:47: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
效果如下:
边栏推荐
猜你喜欢

Yunna - work order management system and process, work order management specification

JVM 内存模型

js如何快速创建一个长度为 n 的数组

AcWing 1148. Secret milk transportation problem solution (minimum spanning tree)

百度飞将BMN时序动作定位框架 | 数据准备与训练指南 (下)

Baidu flying general BMN timing action positioning framework | data preparation and training guide (Part 1)

Typical problems of subnet division and super network construction

刨析《C语言》【进阶】付费知识【完结】

Right mouse button customization

ROS学习(25)rviz plugin插件
随机推荐
各种语言,软件,系统的国内镜像,收藏这一个仓库就够了: Thanks-Mirror
公钥\私人 ssh避password登陆
String to date object
Clickhouse fields are grouped and aggregated, and SQL is queried according to the granularity of any time period
When grep looks for a process, it ignores the grep process itself
JS ES5也可以创建常量?
How to prevent overfitting in cross validation
The difference between Tansig and logsig. Why does BP like to use Tansig
Gin introduction practice
Set WordPress pseudo static connection (no pagoda)
设置Wordpress伪静态连接(无宝塔)
Let's see how to realize BP neural network in Matlab toolbox
今日问题-2022/7/4 lambda体中修改String引用类型变量
Basic introduction and use of dvajs
454-百度面经1
Appium automation test foundation uiautomatorviewer positioning tool
Amway wave C2 tools
Gin 入门实战
百度飞将BMN时序动作定位框架 | 数据准备与训练指南 (上)
mysqlbackup 还原特定的表