当前位置:网站首页>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()
边栏推荐
- 【952. 按公因数计算最大组件大小】
- Centos 7.9安装PostgreSQL14.4步骤
- MySQL高级-六索引优化
- 【genius_platform软件平台开发】第七十四讲:window环境下的静态库和动态库的一些使用方法(VC环境)
- typescript14-(单独指定参数和返回值的类型)
- typescript11-数据类型
- Mysql:Invalid default value for TIMESTAMP
- TiKV主要内存结构和OOM排查总结
- typescript12 - union types
- WMware Tools installation failed segmentation fault solution
猜你喜欢
随机推荐
MySQL database constraints, table design
System design. Short chain system design
ShardingSphere's unsharded table configuration combat (6)
程序员工作三年攒多少钱合适?
ShardingSphere之水平分库实战(四)
Centos 7.9安装PostgreSQL14.4步骤
Zabbix干啥用?
TiDB 在长银五八消费金融核心系统适配经验分享
tensorflow与GPU版本对应安装问题
typescript9-常用基础类型
《实战》基于电商领域的词性提取及其决策树模型建模
分布式.幂等性
响应式布局与px/em/rem的比对
BOM系列之history对象
typescript12-联合类型
822. Walk the Grid
Image processing tool design
TiCDC 架构和数据同步链路解析
DOM系列之 offset 系列
九州云入选“可信云最新评估体系及2022年通过评估企业名单”