ROS action客户端和服务端通信(Ubuntu )

news2024/11/17 16:41:12

ROS action客户端和服务端通信

@gcusms

ROS 一般都是用 servicetopic 进行数据之间的交互传输,因为这种通信方式无法满数据实时反馈的要求,所以采用 action 动作消息反馈通信机制(实时反馈的任务进度,并且可以随时终止运行)可以更加有效的控制数据流的输入输出和机器人运动控制,并且在导航中消息传输有更加灵活的数据传输
在这里插入图片描述

工作模式图

工作模式入如下面的图所示 (client 和 server)
加粗样式
client 和 server 之间通过 actionlib 定义的 “action protocol” 进行通讯。这种通讯协议是基于 ROS 的消息机制实现的,提供了 client 和 server 的接口

  1. goal:任务目标
  2. cancel:请求取消任务
  3. status:通知 client (客户端)当前的状态
  4. feedback:周期反馈任务运行的监控数据
  5. result:向 client(客户端) 发送任务的执行结果,最终任务完成的结果只会发送一次

数据文件定义

action 通信机制的消息格式是以 .action 文件名为后缀的格式定义的,例如 XXX.action

# 定义需要发送到目标值
uint32 id 
---
# 结果值
uint32 total_date
---
# feedback 过程进度反馈值 
float32 percent_complete

在这里插入图片描述
我的 action 文件名字定义为 test.action

CMakeLists.txt 配置文件的修改

完成 action 文件的定义之后就可以开始创建功能包
使用命令:✋:

catkin_create_pkg action_test roscpp rospy actionlib actionlib_msgs std_msgs

创建一个名为 action_test 的功能包,然后修改 CMakelists.txt 里面的配置

在这里插入图片描述

find_package(catkin REQUIRED COMPONENTS
  actionlib
  actionlib_msgs
  rospy
  std_msgs
  roscpp
)

在这里插入图片描述

## Generate actions in the 'action' folder
add_action_files(
  FILES
  test.action
)

## Generate added messages and services with any dependencies listed here
generate_messages(
  DEPENDENCIES
  std_msgs
  actionlib_msgs
)

其他的相关配置如同创建话题发布消息即可


客户端 Client

代码编写,编写一个循环反馈的程序
创建客户端的步骤如下:

  1. 包含相关的头文件
  2. 初始化 ROS 节点
  3. 创建 NodeHandle
  4. 创建 action 的关联对象
  5. 编写处理的请求,也是代码数据处理的主要部分
  6. 循环

对于客户端,主要是编写是三个函数:

  1. 任务开始的回调函数
  2. 任务进度过程中接受到的进度反馈函数

主要的(需要注意)代码块

  • Client 客户端声明
typedef actionlib::SimpleActionClient<action_test::testAction> Client;
  • 任务开始调用的函数
// 任务开始后调用的函数
void activeCb()
{
    ROS_INFO("开始任务");
}
  • 进度反馈函数
    注意 feddback 申明指针的定义 testFeedbackConstPtr =【action文件名字】& FeedbackConstPtr
// 收到 feedback 后调用的回调函数
void feedbackCb(const action_test::testFeedbackConstPtr& feedback)
{
    ROS_INFO(" 完成的进度 : %f ", feedback->percent_complete);
}

具体的代码如下

#include <actionlib/client/simple_action_client.h>
#include "action_test/testAction.h"

typedef actionlib::SimpleActionClient<action_test::testAction> Client;

// 当action完成后会调用次回调函数一次
void doneCb(const actionlib::SimpleClientGoalState& state,
        const action_test::testResultConstPtr& result)
{
    ROS_INFO("任务完成");
    ros::shutdown();
}

// 任务开始后调用的函数
void activeCb()
{
    ROS_INFO("开始任务");
}

// 收到 feedback 后调用的回调函数
void feedbackCb(const action_test::testFeedbackConstPtr& feedback)
{
    ROS_INFO(" 完成的进度 : %f ", feedback->percent_complete);
}

int main(int argc, char** argv)
{
    setlocale(LC_ALL,"");
    ros::init(argc, argv, "do_dishes_client");

    // 定义一个客户端
    Client client("do_dishes", true);

    // 等待服务器端
    ROS_INFO("等待服务器开始运行");
    client.waitForServer();
    ROS_INFO("服务器开始运行");

    // 创建一个action的goal
    action_test::testGoal goal;
    goal.send_id = 1;

    // 发送action的goal给服务器端,并且设置回调函数
    client.sendGoal(goal,  &doneCb, &activeCb, &feedbackCb);

    ros::spin();

    return 0;
}

服务端 Server

创建服务端的步骤如下:

  1. 包含相关的头文件
  2. 初始化 ROS 节点
  3. 创建 NodeHandle
  4. 创建 action 的客户端对象
  5. 编写处理的请求,也是代码数据处理的主要部分
  6. 循环

对于客户端,主要是编写是三个函数:

  1. 任务开始的回调函数
  2. 任务进度过程中的进度反馈函数
  3. 任务完成结束反馈函数

主要的(需要注意)代码块

  • 接收到 goal 后调用的函数
void MissionOne(const action_test::testGoalConstPtr& goal, Server* as)
  • 消息反馈对象声明和 publishFeedback 函数
action_test::testFeedback feedback;
as->publishFeedback(feedback);
  • 任务结束反馈的函数
as->setSucceeded();

具体的代码如下

#include <ros/ros.h>
#include <actionlib/server/simple_action_server.h>
#include "action_test/testAction.h"

typedef actionlib::SimpleActionServer<action_test::testAction> Server;

// 收到action的 goal 后调用的回调函数
void MissionOne(const action_test::testGoalConstPtr& goal, Server* as)
{
    ros::Rate r(1);
    action_test::testFeedback feedback;

    ROS_INFO("任务 %d 正在工作中.", goal->send_id);

    // 假设洗盘子的进度,并且按照1hz的频率发布进度feedback
    for(int i=1; i<=10; i++)
    {
        feedback.percent_complete = i * 10;
        as->publishFeedback(feedback);
        r.sleep();
    }

    // 当action完成后,向客户端返回结果
    ROS_INFO("任务 %d 完成.", goal->send_id);
    as->setSucceeded();
}

int main(int argc, char** argv)
{
    setlocale(LC_ALL,"");
    ros::init(argc, argv, "do_dishes_server");
    ros::NodeHandle n;

    // 定义一个服务器
    Server server(n, "do_dishes", boost::bind(&MissionOne, _1, &server), false);

    // 服务器开始运行
    server.start();

    ros::spin();

    return 0;
}

上述代码块中的客户端和服务端编写的过程中,函数传递的对象一般使用引用活着指针来对数据进行操作,获取到 action 文件里面的数据需要以 GalConsPtr 来声明常数指针进行后序的操作


测试

打开一个新的终端,如果还没有加载到环境变量当中,重新添加临时的环境声明,不过下次需要重新声明加载一次

source devel/setup.bash
  1. 启动 ros 中的 master 节点
roscore

2.启动客户端

rosrun action_test action02_client 

3.启动服务端

rosrun action_test action01_server 

在这里插入图片描述

至此,完成了 ROS 中的 action 简易的通信机制,这种通信机制尝尝会应用于很多的场景,例如路径规划,机器人关节控制


🌸🌸🌸完结撒花🌸🌸🌸


🌈🌈Redamancy🌈🌈


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/60789.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

用 AWTK 和 AWPLC 快速开发嵌入式应用程序 (6)-在线调试

AWPLC 目前还处于开发阶段的早期&#xff0c;写这个系列文章的目的&#xff0c;除了用来验证目前所做的工作外&#xff0c;还希望得到大家的指点和反馈。如果您有任何疑问和建议&#xff0c;请在评论区留言。 1. 背景 AWTK 全称 Toolkit AnyWhere&#xff0c;是 ZLG 开发的开源…

vuex学习记录

为什么要用vuex 由于vue本身的特点。及页面是由多个组件构成。而组件又呈现一个二叉树状态。然后父向子需要进行通信。那如果是非父子关系&#xff0c;应该如何传值呢&#xff1f; 什么是vuex 专门为vue.js应用程序开发的状态管理模式。它采用集中式存储管理数据&#xff0c…

详解 Go 语言中的 init () 函数

阅读目录Go init 函数的详细说明包初始化Go init 函数的详细说明 初始化每个包后&#xff0c;会自动执行 init&#xff08;&#xff09;函数&#xff0c;并且执行优先级高于主函数的执行优先级。 init 函数通常用于&#xff1a; 变量初始化检查 / 修复状态注册器运行计算 包…

c语言零基础入门(完整版)

1软件下载 官网下载: https://sourceforge.net/projects/orwelldevcpp/ 百度网盘&#xff1a;https://pan.baidu.com/s/1mhHDjO8 提取密码&#xff1a;mken 推荐用百度网盘&#xff0c;官方下载太慢了 开始安装 首先双击打开刚刚下载的软件 点击0k 因为在安装过程中不能使用…

【计算机视觉】图像形成与颜色

图像形成与颜色 光照及阴影 辐射度学 颜色 颜色信息反映了入射光的能量分布与波长&#xff0c;可见光的波长在400nm到760nm之间。 RGB RGB分别代表三个基色&#xff08;R-红色、G-绿色、B-蓝色&#xff09;&#xff0c;如(0,0,0)表示黑色、(255, 255, 255)表示白色。其中2…

TS装饰器bindThis优雅实现React类组件中this绑定

初学React类组件时&#xff0c;最不爽的一点应该就是 this 指向问题了吧&#xff01;初识React的时候&#xff0c;肯定写过这样错误的demo。 import React from react; export class ReactTestClass extends React.Component {constructor(props) { super(props); this.state …

程序员如何进化成架构师?

作为程序员的上端&#xff0c;每一个架构师都承担着艰巨的任务&#xff1a;不仅仅要和产品进行周旋&#xff0c;还需要有十分坚实的技术作为基础打底。 那么&#xff0c;架构师都在考虑什么呢&#xff1f; 说到底还是程序架构、结构性的问题。 比如最近十分火爆的分布式系统…

STM32CubeIDE(stm32f767)添加DSP库

对于stm32f4 系列可以使用STM32Cube添加相应的库&#xff0c;自动生成代码。可以参考下面写的文章 (1条消息) STM32CubeMX关于添加DSP库的使用_W_oilpicture的博客-CSDN博客_cubemx dsp库 不过&#xff0c;对于stm32f767等M7的内核目前可能并不适用&#xff0c;需要自己手动添…

CS162 shell

本文记录我在做shell这个作业时用到有关资源&#xff0c;如Linux系统调用、Linux基础知识、C语言知识等。 这里只是非常简略地记录了一下&#xff0c;并且可能有理解不正确的地方&#xff0c;你可以把本文当作一个索引和没有思路时的启发&#xff0c;详细的信息可以再去查&…

SVM(支持向量机)基本形式推导

据说在dl之前是SVM撑起了ml的半片天&#xff0c;学习后发现SVM是由纯粹的数学推导、转化、求解、优化“堆砌”而来&#xff0c;不如说是数学撑起了ml&#xff0c;ml是数学的学科。以下根据老师ppt上讲解的思路讲讲个人对SVM基本形式推导的理解。 margin&#xff08;间隔&#x…

[附源码]计算机毕业设计现代诗歌交流平台Springboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

2. IMU原理及姿态融合算法详解

文章目录2. IMU原理及姿态融合算法详解一、组合二、 原理a) 陀螺仪b) 加速度计c) 磁力计三、 旋转的表达a) 欧拉角b) 旋转矩阵c) 四元数d) 李群 SO(3)\text{SO}(3)SO(3) 及 李代数 so(3)\text{so}(3)so(3)四、 传感器的噪声及去除a) 陀螺仪b) 加速度计c) 磁力计五、姿态解算原理…

CSS基础-选择器进阶,背景相关属性(颜色/图片)

CSS基础-选择器进阶,背景相关属性(颜色/图片) 目标&#xff1a;能够理解 复合选择器 的规则&#xff0c;并使用 复合选择器 在 HTML 中选择元素 学习路径&#xff1a;1. 复合选择器2. 并集选择器3. 交集选择器4. hover伪类选择器5. Emmet语法 本次我们所学的内容&#xff1a; 1…

Kafka - 15 Kafka Offset | 自动和手动提交Offset | 指定Offset消费 | 漏消费和重复消费 | 消息积压

文章目录1. Offset 的默认维护位置2. 自动提交 Offset3. 手动提交 Offset1. 同步提交 offset2. 异步提交 offset4. 指定 Offset 消费5. 指定时间消费6. 漏消费和重复消费7. 消费者事务8. 数据积压&#xff08;消费者如何提高吞吐量&#xff09;1. Offset 的默认维护位置 Kafka…

触发器——SR锁存器

组合逻辑的基本单元电路是门电路 另外一种电路叫做时序逻辑电路&#xff0c;时序逻辑电路的输出不但和输入有关&#xff0c;还和原来的状态有关 在这样的电路中&#xff0c;一定要具有存储功能&#xff0c;存储原来的状态&#xff0c;一定也要有反馈回路&#xff0c;返回原来…

4-7:用Redis优化登陆模块

相关功能 使用Redis存储验证码 验证码需要频繁的访问与刷新&#xff0c;对性能要求较高。验证码不需永久保存&#xff0c;通常在很短的时间后就会失效。 (Redis可以设置有效时间&#xff0c;分布式应用也可以绕过session共享的问题)分布式部署时&#xff0c;存在Session共享的…

2022物联卡排行榜公司有哪些?

科技的发展日新月异&#xff0c;我们国家的发展战略也是支持高新科技公司的发展&#xff0c;所以越来越多的高新科技公司出现&#xff0c;但凡是高新科技公司&#xff0c;在设备的联网中&#xff0c;都会用到物联卡&#xff0c;所以物联卡的市场也愈发火爆&#xff0c;那么今天…

Zygote在Framework中起什么作用?

前言 提到Zygote可能了解一些的小伙伴会说&#xff0c;它是分裂进程用的。没错它最大的作用的确是分裂进程&#xff0c;但是它除了分裂进程外还做了什么呢。还是老规矩&#xff0c;让我们抱着几个问题来看文章。最后在结尾&#xff0c;再对问题进行思考回复。 你能大概描述一…

【springboot进阶】使用aop + 注解方式,简单实现spring cache redis 功能

目录 一、实现思路 二、定义缓存注解 三、aop 切面处理 四、使用方式 五、灵活的运用 六、总结 前几天有同学看了 SpringBoot整合RedisTemplate配置多个redis库 这篇文章&#xff0c;提问spring cache 能不能也动态配置多个redis库。介于笔者没怎么接触过&#xff0c;所以…