当前位置:网站首页>ROS Action communication
ROS Action communication
2022-07-31 01:10:00 【2021 Nqq】
文章目录
应用场景:Requires use of service communication,But timely feedback is required.
在ROS中提供了actionlib功能包集,用于实现 action 通信.action 是一种Similar to service communication的实现,Its implementation model is also included请求和响应,但是不同的是,during the request and response process,The server can also continuously feedback the current task progress,Clients can receive continuous feedback and can also cancel tasks.
action通信接口
- goal:目标任务
- cacel:取消任务
- status:服务端状态
- result:最终执行结果(只会发布一次)
- feedback:continuous feedback(可以发布多次)
自定义action文件(类似msg和service)
服务端 action01_server.cpp
/* 需求: 创建两个ROS节点,服务器和客户端, The client can send target data to the serverN(一个整型数据) The server will calculate1到N之间所有整数的和,This is a cyclic accumulation process,返回给客户端, This is based on the request-response pattern, It is also known that the server is a time-consuming operation from receiving a request to generating a response,Time-consuming for each accumulation0.1s, 为了良好的用户体验,Requires the server to be in the calculation process, 每累加一次,Just give the client a response to the execution progress in percentage format,使用action实现. 流程: 1.包含头文件; 2.初始化ROS节点; 3.创建 NodeHandle; 4.创建 action 服务对象; 5.处理请求(a. Parse the submitted target value;b. Generate continuous feedback;c. Final result response)Generate feedback and responses; 回调函数实现 6.spin()回旋 */
#include"ros/ros.h"
#include"actionlib/server/simple_action_server.h"
#include"demo01_action/AddIntsAction.h"
// 重命名
typedef actionlib::SimpleActionServer<demo01_action::AddIntsAction> Server;
// 5.处理请求(a. Parse the submitted target value;b. Generate continuous feedback;c. Final result response)——回调函数实现 客户端提供的goal 和 服务端的server对象
void cb(const demo01_action::AddIntsGoalConstPtr &goalPtr,Server* server){
// a. Parse the submitted target value
int goal_num = goalPtr->num;
ROS_INFO("The target value submitted by the client is :%d",goal_num);
// b. Generate continuous feedback 累加
ros::Rate rate(10);// 10Hz
int result = 0;
ROS_INFO("Start continuous feedback.....");
for(int i = 1; i <= goal_num; i++)
{
// 累加
result += i;
// 休眠
rate.sleep();
// Generate continuous feedback
// void publishFeedback(const demo01_action::AddIntsFeedback &feedback)
demo01_action::AddIntsFeedback fb;
fb.progress_bar = i / (double)goal_num;
server->publishFeedback(fb);
}
ROS_INFO("最终响应结果:%d",result);
// c. Final result response
demo01_action::AddIntsResult r;
r.result = result;
server->setSucceeded(r);
}
int main(int argc, char *argv[])
{
// 2.初始化ROS节点;
setlocale(LC_ALL,"");
ros::init(argc,argv,"addInts_server");// 节点
// 3.创建 NodeHandle;
ros::NodeHandle nh;
// 4.创建 action 服务对象;
/* SimpleActionServer(ros::NodeHandle n, NodeHandle std::string name, 话题名称 boost::function<void (const demo01_action::AddIntsGoalConstPtr &)> execute_callback, 回调函数 bool auto_start 是否自动启动 参数1: NodeHandle 参数2: 话题名称 参数3: 回调函数 参数4: 是否自动启动 */
Server server(nh,"addInts",boost::bind(&cb,_1,&server),false); // 话题,_1is used to occupy space,传入的是回调函数goal的参数
server.start();// 如果 atuto_start 为false, Then you need to manually call this function to start the service
ROS_INFO("服务启动......");
// 6.spin()回旋
ros::spin();
return 0;
}
客户端 action02_client.cpp
#include "ros/ros.h"
// 创建客户端对象
#include "actionlib/client/simple_action_client.h"
#include "demo01_action/AddIntsAction.h"
/* 需求: 创建两个ROS节点,服务器和客户端, The client can send target data to the serverN(一个整型数据) The server will calculate1到N之间所有整数的和,This is a cyclic accumulation process,返回给客户端, This is based on the request-response pattern, It is also known that the server is a time-consuming operation from receiving a request to generating a response,Time-consuming for each accumulation0.1s, 为了良好的用户体验,Requires the server to be in the calculation process, 每累加一次,Just give the client a response to the execution progress in percentage format,使用action实现. 流程: 1.包含头文件; 2.初始化ROS节点; 3.创建 NodeHandle; 4.创建 action 客户端对象; 5.发送请求 a. 连接建立: --- 回调函数 b. Handle continuous feedback:--- 回调函数 c. Process the final response:--- 回调函数 6.spin(). */
typedef actionlib::SimpleActionClient<demo01_action::AddIntsAction> Client;
// Callback when the response is successful,处理最终结果(第3步)状态、The result is litigation
void done_cb(const actionlib::SimpleClientGoalState &state, const demo01_action::AddIntsResultConstPtr &result){
// 响应是否成功
if (state.state_ == state.SUCCEEDED)
{
ROS_INFO("响应成功,最终结果 = %d",result->result);
} else {
ROS_INFO("请求失败!");
}
}
// 激活回调,Service has been activated(第1步)
void active_cb(){
ROS_INFO("The connection between the client and the server is established....");
}
// A callback for continuous feedback,Handle continuous feedback(第2步)
void feedback_cb(const demo01_action::AddIntsFeedbackConstPtr &feedback){
ROS_INFO("当前进度:%.2f",feedback->progress_bar);
}
int main(int argc, char *argv[])
{
// 2.初始化ROS节点
setlocale(LC_ALL,"");
ros::init(argc,argv,"addInts_client");
// 3.创建 NodeHandle
ros::NodeHandle nh;
// 4.创建 action 客户端对象
// SimpleActionClient(ros::NodeHandle & n, const std::string & name, bool spin_thread = true)
actionlib::SimpleActionClient<demo01_action::AddIntsAction> client(nh,"addInts");// 话题
// 5.发送请求
// 注意: 判断服务器状态,等待服务启动
ROS_INFO("等待服务器启动.....");
client.waitForServer();
// a. 连接建立: --- 回调函数
// b. Handle continuous feedback:--- 回调函数
// c. Process the final response:--- 回调函数
/* void sendGoal(const demo01_action::AddIntsGoal &goal, boost::function<void (const actionlib::SimpleClientGoalState &state, const demo01_action::AddIntsResultConstPtr &result)> done_cb,Process the final response boost::function<void ()> active_cb, 连接建立 boost::function<void (const demo01_action::AddIntsFeedbackConstPtr &feedback)> feedback_cb) Process feedback */
// 参数1: 设置目标值
demo01_action::AddIntsGoal goal;
goal.num = 100;
client.sendGoal(goal,&done_cb,&active_cb,&feedback_cb);
// 6.spin().
ros::spin();
return 0;
}
服务端 action01_server_p.py
#! /usr/bin/env python
""" 需求: 创建两个ROS 节点,服务器和客户端, The client can send target data to the serverN(一个整型数据)The server will calculate 1 到 N 之间所有整数的和, This is a cyclic accumulation process,返回给客户端,This is based on the request-response pattern, It is also known that the server is a time-consuming operation from receiving a request to generating a response,Time-consuming for each accumulation0.1s, 为了良好的用户体验,Requires the server to be in the calculation process, 每累加一次,Just give the client a response to the execution progress in percentage format,使用 action实现. 流程: 1.导包 2.初始化 ROS 节点 3.Use class encapsulation alone, 4.类中创建 action 服务端对象 5.处理请求(a.Parse the target value b. Send continuous feedback c. Respond to the final result)--- 回调函数 6.spin()回旋 """
import rospy
import actionlib
from demo01_action.msg import *
# 4.类中创建 action 服务端对象
# 5.处理请求(a.Parse the target value b. Send continuous feedback c. Respond to the final result)--- 回调函数
class MyAction:
def __init__(self):
#SimpleActionServer(name, ActionSpec, execute_cb=None, auto_start=True)
self.server = actionlib.SimpleActionServer("addInts",AddIntsAction,self.cb,False)
self.server.start()
rospy.loginfo("服务端启动.....")
# 回调函数
# 参数: 目标值
def cb(self,goal):
# a.Parse the target value
goal_num = goal.num
rospy.loginfo("目标值:%d",goal_num)
# b.循环累加,continuous feedback
rate = rospy.Rate(10)
sum = 0 # Accepts the summation result variable
rospy.loginfo("请求处理中.....")
for i in range(1,goal_num + 1):
# 累加
sum = sum + i
rate.sleep()
# Send continuous feedback
fb_obj = AddIntsFeedback()
fb_obj.progress_bar = i / goal_num
self.server.publish_feedback(fb_obj)
# c.Respond to the final result
rospy.loginfo("响应结果:%d",sum)
result = AddIntsResult()
result.result = sum
self.server.set_succeeded(result)
if __name__ == "__main__":
# 2.初始化 ROS 节点
rospy.init_node("action_server_p")
# 3.Use class encapsulation alone
myAction = MyAction()
# 6.spin()回旋
rospy.spin()
客户端 action02_client_p.py
#! /usr/bin/env python
""" 需求: 创建两个ROS 节点,服务器和客户端, The client can send target data to the serverN(一个整型数据)The server will calculate 1 到 N 之间所有整数的和, This is a cyclic accumulation process,返回给客户端,This is based on the request-response pattern, It is also known that the server is a time-consuming operation from receiving a request to generating a response,Time-consuming for each accumulation0.1s, 为了良好的用户体验,Requires the server to be in the calculation process, 每累加一次,Just give the client a response to the execution progress in percentage format,使用 action实现. 流程: 1.导包 2.初始化 ROS 节点 3.Use class encapsulation alone, 4.类中创建 action 服务端对象 5.处理请求(a.Parse the target value b. Send continuous feedback c. Respond to the final result)--- 回调函数 6.spin()回旋 """
import rospy
import actionlib
from demo01_action.msg import *
# 4.类中创建 action 服务端对象
# 5.处理请求(a.Parse the target value b. Send continuous feedback c. Respond to the final result)--- 回调函数
class MyAction:
def __init__(self):
#SimpleActionServer(name, ActionSpec, execute_cb=None, auto_start=True)
self.server = actionlib.SimpleActionServer("addInts",AddIntsAction,self.cb,False)
self.server.start()
rospy.loginfo("服务端启动.....")
# 回调函数
# 参数: 目标值
def cb(self,goal):
# a.Parse the target value
goal_num = goal.num
rospy.loginfo("目标值:%d",goal_num)
# b.循环累加,continuous feedback
rate = rospy.Rate(10)
sum = 0 # Accepts the summation result variable
rospy.loginfo("请求处理中.....")
for i in range(1,goal_num + 1):
# 累加
sum = sum + i
rate.sleep()
# Send continuous feedback
fb_obj = AddIntsFeedback()
fb_obj.progress_bar = i / goal_num
self.server.publish_feedback(fb_obj)
# c.Respond to the final result
rospy.loginfo("响应结果:%d",sum)
result = AddIntsResult()
result.result = sum
self.server.set_succeeded(result)
if __name__ == "__main__":
# 2.初始化 ROS 节点
rospy.init_node("action_server_p")
# 3.Use class encapsulation alone
myAction = MyAction()
# 6.spin()回旋
rospy.spin()
边栏推荐
- The client series of the DOM series
- Meta元宇宙部门第二季度亏损28亿 仍要继续押注?元宇宙发展尚未看到出路
- 认识DTU什么是4GDTU设备
- Xiaohei's leetcode journey: 104. The maximum depth of a binary tree
- 射频器件的基本参数2
- Zabbix干啥用?
- MySQL database constraints, table design
- Jetpack Compose learning (8) - State and remeber
- 查看zabbix-release-5.0-1.el8.noarch.rpm包内容
- Image processing tool design
猜你喜欢

typescript17-函数可选参数

297. 二叉树的序列化与反序列化

Analyze the capabilities and scenarios of the cloud native message flow system Apache Pulsar

Can deep learning solve the parameters of a specific function?

4G通信模块CAT1和CAT4的区别

1782. 统计点对的数目 双指针

设置浏览器滚动条样式

Ticmp - 更快的让应用从 MySQL 迁移到 TiDB

prometheus 监控概述

typescript12 - union types
随机推荐
typescript14-(单独指定参数和返回值的类型)
图像处理工具设计
tensorflow与GPU版本对应安装问题
场景之多数据源查询及数据下载问题
Thesis understanding: "Designing and training of a dual CNN for image denoising"
分布式.分布式锁
Mysql systemized JOIN operation example analysis
Bert usage and word prediction based on Keras_bert model
Parameter introduction and selection points of wireless module
解决:Parameter 0 of method ribbonServerList in com.alibaba.cloud.nacos.ribbon.NacosRibbonClientConfigu
DOM系列之 client 系列
蓝牙mesh系统开发三 Ble Mesh 配网器 Provisioner
黄东旭:TiDB的优势是什么?
Meta元宇宙部门第二季度亏损28亿 仍要继续押注?元宇宙发展尚未看到出路
TiDB 操作实践 -- 备份与恢复
Typescript18 - object type
使用docker安装mysql
Responsive layout vs px/em/rem
ROS Action通信
How to Add a Navigation Menu on Your WordPress Site