当前位置:网站首页>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
效果如下:
边栏推荐
- ROS学习(26)动态参数配置
- uva 1401 dp+Trie
- Sword finger offer II 035 Minimum time difference - quick sort plus data conversion
- AcWing 904. 虫洞 题解(spfa求负环)
- Add PDF Title floating window
- Google发布安全更新,修复Chrome中已被利用的0 day
- AcWing 344. 观光之旅题解(floyd求无向图的最小环问题)
- Appium基础 — Appium Inspector定位工具(一)
- MySQL最基本的SELECT(查询)语句
- AcWing 344. Solution to the problem of sightseeing tour (Floyd finding the minimum ring of undirected graph)
猜你喜欢

LeetCode:1175. 质数排列

Right mouse button customization

Yunna | work order management software, work order management software app

Appium基础 — Appium Inspector定位工具(一)

AcWing 1148. 秘密的牛奶运输 题解(最小生成树)

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

【唯一】的“万字配图“ | 讲透【链式存储结构】是什么?

How can I code for 8 hours without getting tired.

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

Blue Bridge Cup 2022 13th provincial competition real topic - block painting
随机推荐
Set WordPress pseudo static connection (no pagoda)
LeetCode:1175. 质数排列
Shell script quickly counts the number of lines of project code
The difference between Tansig and logsig. Why does BP like to use Tansig
永久的摇篮
AcWing 1148. 秘密的牛奶运输 题解(最小生成树)
JVM memory model
dvajs的基础介绍及使用
Box stretch and pull (left-right mode)
C language instance_ five
Mongodb checks whether the table is imported successfully
Right mouse button customization
C语言实例_3
编译命令行终端 swift
Ds-5/rvds4.0 variable initialization error
Transplant DAC chip mcp4725 to nuc980
AcWing 345. 牛站 题解(floyd的性质、倍增)
Dark horse notes - create immutable sets and streams
使用nodejs完成判断哪些项目打包+发版
Reptile practice (VI): novel of climbing pen interesting Pavilion