ROS2 Topics和Services

news/2024/7/25 1:28:20/文章来源:https://blog.csdn.net/hbin5110209161/article/details/139247114

本文主要介绍ROS的Topics概念,如何创建Publisher和Subscriber,通过Topic在ROS程序间通信;介绍ROS的Services概念,如何创建Client和Server并建立通信。
更多内容,访问专栏目录获取实时更新。

ROS Topics

Topics可以被视为一种具名的总线,用于节点间交换数据,通过Topics可以发布和订阅消息,实现单向的流式通信。需要注意的重点包括:

  • 单向流式通信(发布/订阅模式)
  • 匿名通信
  • 每个Topic都有特定的消息格式
  • 可以在ROS节点中通过Python, C++等多种语言实现
  • 一个节点可以拥有多个Topic

Publisher in Python

在ROS2基础编程一文中,我们已经创建了工作空间和工作包,在此基础上,来通过Python实现一个Topic的发布者。
my_py_pkg工作包下创建一个新的文件robot_news_station.py
在这里插入图片描述
robot_news_station.py

#!/usr/bin/env python3
import rclpy
from rclpy.node import Node
from example_interfaces.msg import String  # do not forget to add package dependencyclass RobotNewsPublisherNode(Node):def __init__(self):super().__init__("robot_news_publisher")self.robot_name = "HiRobot"self.publisher = self.create_publisher(String, "robot_news", 10)self.timer = self.create_timer(1, self.publish_news)self.get_logger().info("Robot News Publisher has been started")def publish_news(self):msg = String()msg.data = "Hi, this is " + str(self.robot_name) + " from the robot news publisher"self.publisher.publish(msg)def main(args=None):rclpy.init(args=args)node = RobotNewsPublisherNode()rclpy.spin(node)rclpy.shutdown()if __name__ == "__main__":main()

还需要添加依赖包引用,修改package.xml文件:
在这里插入图片描述

然后装载我们的新节点,修改setup.py:
在这里插入图片描述

之后执行下面的指令就可以启动我们的publisher了:

colcon build --packages-select my_py_pkg --symlink-install
source ~/.bashrc
ros2 run my_py_pkg robot_news_station
ros2 topic echo /robot_news

Subscriber in Python

创建订阅者的方式与创建发布者类似,这里我们添加了一个名为robot_news_subscriber.py的文件:

#!/usr/bin/env python3
import rclpy
from rclpy.node import Node
from example_interfaces.msg import String  # do not forget to add package dependencyclass RobotNewsSubscriberNode(Node):def __init__(self):super().__init__("robot_news_subscriber")self.subscriber = self.create_subscription(String, "robot_news", self.subscribe_news_callback, 10)self.get_logger().info("Robot News Subscriber has been started")def subscribe_news_callback(self, msg):self.get_logger().info(msg.data)def main(args=None):rclpy.init(args=args)node = RobotNewsSubscriberNode()rclpy.spin(node)rclpy.shutdown()if __name__ == "__main__":main()

不要忘记修改setup.pycolcon build编译。之后同时运行publisher和subscriber就可以看到右侧命令行里的subscriber每1s收到一条来自publisher的信息,并打印:
在这里插入图片描述

使用命令行工具调试Topics

ros2 topic list
ros2 topic info <topic_name>  # 查看所有激活的topic
ros2 topic echo <topic_name>   # 创建一个订阅者监听发布的消息
ros2 interface show <msg_type>  # 显示话题消息的类型
ros2 topic hz <topic_name>  # 获取发布频率
ros2 topic bw <topic_name>  # 获取消息的长度,byte width
ros2 topic pub <topic_name>  <msg_type> <msg_data>  # 发布一个topic
ros2 topic pub -r 10 /robot_news example_interfaces/msg/String "{data: 'hello from robot'}"
ros2 node list
ros2 info <node_name>
ros2 run <pkg_name> <node_name> --ros-args -r __node:=<new_node_name>
ros2 run <pkg_name> <node_name> --ros-args -r __node:=<new_node_name> -r <topic_name>:=<new_topic_name>

Ros Services

前文提到Topics实现的是单向的传输,通过发布/订阅模式建立连接,但用在一些需要请求/回复的分布式系统中就不太合适了。
Services可以帮助我们实现请求/回复的通信模式,一条消息用于请求,一条用于回复,ROS节点以字符串名称提供服务,客户端通过发送请求消息并等待回复来调用服务,从而建立持久性的连接。

Service Server in Python

ros2 interface show example_interfaces/srv

执行上面的指令,你能看到example_interface包里提供了哪些服务,这里我们使用AddTwoInts来演示如何创建一个service server
add_two_ints_server.py

#!/usr/bin/env python3
import rclpy
from rclpy.node import Node
from example_interfaces.srv import AddTwoIntsclass AddTwoIntsServerNode(Node):def __init__(self):super().__init__("add_two_ints_server")self.server = self.create_service(AddTwoInts, "add_two_ints", self.callback_add_two_ints)self.get_logger().info("Add Two Ints Server has started")def callback_add_two_ints(self, request, response):response.sum = request.a + request.bself.get_logger().info(str(request.a) + " + " + str(request.b) + " = " + str(response.sum))return responsedef main(args=None):rclpy.init(args=args)node = AddTwoIntsServerNode()rclpy.spin(node)rclpy.shutdown()if __name__ == "__main__":main()

编译并运行,通过ros2 service list就能在服务列表里看到我们启动的服务了。
在这里插入图片描述

ros2 service call /add_two_ints example_interfaces/srv/AddTwoInts "{a: 3, b: 4}"

执行上面的指令就可以在命令行里调用我们创建的service。

Service Client in Python

add_two_ints_client.py

#!/usr/bin/env python3
import rclpy
from rclpy.node import Node
from example_interfaces.srv import AddTwoIntsdef main(args=None):rclpy.init(args=args)node = Node("add_two_ints_no_oop")client = node.create_client(AddTwoInts, "add_two_ints")while not client.wait_for_service(1):node.get_logger().warn("Waiting for server Add Two Ints...")request = AddTwoInts.Request()request.a = 3request.b = 8future = client.call_async(request)rclpy.spin_until_future_complete(node, future)try:response = future.result()node.get_logger().info(str(request.a) + " + " + str(request.b) + " = " + str(response.sum))except Exception as e:node.get_logger().error("Service call failed %r" % (e,))rclpy.shutdown()if __name__ == "__main__":main()

使用命令行工具调试Services

ros2 service list
ros2 service type <service_name>
ros2 interface show <service type>
ros2 service call <service_name> <service_type> <value>
ros2 run <pkg_name> <node_name> --ros-args -r <service_name>:=<new_service_name>

ROS Interface

ROS应用之间有三种通信接口:messages, services和actions,ROS2使用IDL(interface definition language)来描述这些接口,使得在不同应用,不同编程语言间进行交互更加简单。例如前文提到的Topic和Service:

Topic:

  • Name:话题名
  • 消息定义:Msg,如example_interfaces/msg/Int64

Service:

  • Name: 服务名
  • 服务定义:Srv,如example_interfaces/srv/AddTwoInts (包含request和response)

创建自定义的Msg

创建一个新的工作包my_robot_interfaces,移除目录下的includesrc文件夹,并新建msg文件夹:
在这里插入图片描述
msg文件夹下新建msg定义文件: HardwareStatus.msg

int64 temperature
string debug_message

更新package.xml,添加:

<build_depend>rosidl_default_generators</build_depend><exec_depend>rosidl_default_runtime</exec_depend><member_of_group>rosidl_interface_packages</member_of_group>

更新CMakeLists.txt,添加:

find_package(rosidl_default_generators REQUIRED)rosidl_generate_interfaces(${PROJECT_NAME}"msg/HardwareStatus.msg"
)ament_export_dependencies(rosidl_default_runtime)
ament_package()

然后编译工作包,就可以在其他工程中使用该Msg定义了。

使用自定义的Msg

my_py_pkg工作包下创建一个新的publisher:hw_status_publisher.py

#!/usr/bin/env python3
import rclpy
from rclpy.node import Node
from my_robot_interfaces.msg import HardwareStatusclass HardwareStatusPublisherNode(Node):def __init__(self):super().__init__("hardware_status_publisher")self.hw_status_publisher = self.create_publisher(HardwareStatus, "hardware_status", 10)self.timer = self.create_timer(1, self.publish_hw_status)self.get_logger().info("Hardware Status Publisher has been started")def publish_hw_status(self):msg = HardwareStatus()msg.temperature = 45msg.debug_message = "No error"self.hw_status_publisher.publish(msg)def main(args=None):rclpy.init(args=args)node = HardwareStatusPublisherNode()rclpy.spin(node)rclpy.shutdown()if __name__ == "__main__":main()

不要忘记在package.xml中添加对my_robot_interface的依赖,并把新的节点加载到setup.py并编译。运行haredware_status_publisher并监听,可以看到如下的效果:
在这里插入图片描述

创建自定义的Srv

my_robot_interfaces工作包目录下创建srv文件夹,并新建文件ComputerRectangleArea.srv

float64 length
float64 width
---
float64 area

更新CMakeLists.txt
在这里插入图片描述
成功编译了工作包后我们就能够获得自定义的Srv了
在这里插入图片描述

如有错误,欢迎留言或来信指正:hbin6358@163.com

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

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SpringJDBC

1.前言 Spring JDBC可以帮助开发者节省大量开发工作 自动去处理一些低级细节 比如&#xff1a;异常处理、打开和关闭资源(Connection、PreparedStatement、Statement、ResultSet) 需要下载的jar包&#xff1a; spring-jdbc(普通jar包、源码jar包)由于没有依赖其他的jar包 所以只…

vite+js配置

vite js 配置路径 npm install types/node --save-dev vite.config.js import { defineConfig } from vite import vue from vitejs/plugin-vue //需要引入 import path from path// https://vitejs.dev/config/ export default defineConfig({plugins: [vue()],resolve: {a…

WORD、PPT技巧

WORD技巧 编辑设置 word标题导航窗口怎么调出word2016&#xff0c;缩小了页面&#xff0c;可是怎么是竖着的一页一页排列啊&#xff1f;以前不是好几页横排着的么&#xff1f;怎么设置&#xff0c;求救&#xff1a;在Word标题栏那一行找到“视图”&#xff0c;点击“显示比例…

【算法】位运算算法——两整数之和

题解&#xff1a;两整数之和(位运算算法) 目录 1.题目2.位运算算法3.参考代码4.总结 1.题目 题目链接&#xff1a;LINK 2.位运算算法 这个题目难点就在于不能用、- 那什么能够代替加号呢&#xff1f; 既然数的层面不能用号&#xff0c;那二进制的角度去用号即可。 恰好&a…

FPGA——eMMC验证

一.FPGA基础 1.FPGA烧录流程 (1) 加载流文件 —— bitfile (2) 烧录文件 —— cmm 二.MMC 1.基础知识 (1)jz4740、mmc、emmc、sd之间的关系&#xff1f; jz4740——处理器 mmc——存储卡标准 emmc——mmc基础上发展的高效存储解决方案 sd—— 三.eMMC和SD case验证 1.ca…

MySQL数据表的“增删查改“

我们学习数据库, 最重要的就是要学会对数据表表进行"增删查改"(CRUD).(C -- create, R -- retrieve, U -- update, D -- delete) 目录 一. "增"(create) 1. 普通新增 2. 指定列新增 3. 一次插入多行 4. 用insert插入时间 5. 小结 二. "查"…

LuatOS学习

开发顺序 Lua是脚本语言中运行速度最快的语言 资源占用极低 脚本语言运行方式 脚本语言是从上往下一行一行运行的 变量 coun 123456 a,b,c 1,2,3交换 a,b b,a在测试环境中&#xff0c;用print(a,b)打印 nil类型 未声明的变量就是nil&#xff0c;nil用来表示此变量为空…

使用uniapp编写的微信小程序进行分包

简介&#xff1a; 由于小程序发布的时候每个包最多只能放置2MB的东西&#xff0c;所以把所有的代码资源都放置在一个主包当中不显示&#xff0c;所以就需要进行合理分包&#xff0c;&#xff0c;但是分包后整个小程序最终不能超过20MB。 一般情况下&#xff0c;我习惯将tabba…

ubuntu使用oh my zsh美化终端

ubuntu使用oh my zsh美化终端 文章目录 ubuntu使用oh my zsh美化终端1. 安装zsh和oh my zsh2. 修改zsh主题3. 安装zsh插件4. 将.bashrc移植到.zshrcReference 1. 安装zsh和oh my zsh 首先安装zsh sudo apt install zsh然后查看本地有哪些shell可以使用 cat /etc/shells 将默…

通过el-tree自定义渲染网页版工作目录,实现鼠标悬浮显示完整名称、用icon区分文件和文件夹等需求

目录 一、通过el-tree自定义渲染网页版工作目录 1.1、需求介绍 1.2、使用el-tree生成文档目录 1.2.1、官方基础用法 ①效果 ②代码&#xff1a; 1.2.2、自定义文档目录&#xff08;实现鼠标悬浮显示完整名称、用icon区分文件和文件夹&#xff09; ①效果&#xff08;直接效…

在winnas中使用docker desktop遇到的问题及解决方法记录

最近在尝试从群晖转向winnas&#xff0c;一些简单的服务依然计划使用docker来部署。群晖的docker简单易用且稳定&#xff0c;在win上使用docker desktop过程中遇到了不少问题&#xff0c;在此记录一下以供后来人参考。 一、安装docker desktop后启动时遇到无法启动docker引擎 …

5G专网驻网失败分析(suci无效)

suci 5G终端第一次驻网时&#xff0c;注册消息Registartion request中携带的5GS mobile identity要携带suci类型的mobile identity。 注册消息协议规范见5G NAS 协议3gpp TS24.501 8.2.6 Registration request。 suci协议规范参见3gpp TS24.501 9.11.3.4 5GS mobile identity …

常用批处理命令及批处理文件编写技巧

一常用批处理命令 1.查看命令用法&#xff1a;命令 /? //如&#xff1a;cd /? 2.切换盘符目录&#xff1a;cd /d D:\test 或直接输入 d: //进入上次d盘所在的目录 3.切换目录&#xff1a;cd test 4.清屏:cls 5.“arp -a” //它会列出当前设备缓存中的所有…

进程互斥经典问题(读写者问题、理发店问题)

目录 读写者问题 问题描述 问题分析 进程互斥问题三部曲 读者写者算法实现 一、找进程——确定进程关系 二、找主营业务 三、找同步约束 a.互斥 b.资源 c.配额 理发店问题 问题描述 问题分析 进程互斥问题三部曲 理发店问题算法实现 一、找进程——确定进程…

弘君资本股市行情:股指预计保持震荡上扬格局 关注汽车、银行等板块

弘君资本指出&#xff0c;近期商场体现全体分化&#xff0c;指数层面上看&#xff0c;沪指一路震动上行&#xff0c;创出年内新高&#xff0c;创业板指和科创50指数体现相对较弱&#xff0c;依然是底部震动走势。从盘面体现上看&#xff0c;轮动依然是当时商场的主基调&#xf…

基于SpringBoot的旅游管理系统

基于SpringBoot的旅游管理系统 旅游管理系统开发技术功能模块代码结构数据库设计运行截图源码获取 旅游管理系统 开发技术 技术&#xff1a;SpringBoot、MyBatis-Plus、MySQL、Beetl、Layui。 框架&#xff1a;基于开源框架Snowy-Layui开发。 工具&#xff1a;IDEA、Navicat等…

The Sandbox 和 Bitkub 联手增强东南亚元宇宙中心

作为去中心化游戏虚拟世界和区块链平台的先驱&#xff0c;The Sandbox 正与泰国领先的区块链网络 Bitkub Blockchain Technology Co., Ltd. 展开创新合作。双方合作的目的是将Bitkub元宇宙的影响力扩展到The Sandbox&#xff0c;建立一个元宇宙中心&#xff0c;向用户承诺从 Bi…

ssm150旅游网站的设计与实现+jsp

旅游网站设计与实现 摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本旅游网站就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理完毕庞…

MySQL数据库案例实战教程:数据类型、语法与高级查询详解

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤&#xff5e;✨✨ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢&#xff0c;在这里我会分享我的知识和经验。&am…

《架演》共创者第一次线上沟通会议总结

《架演》共创者第一次线上沟通——启动会 会议主题&#xff1a;《架演》共创启动会议会议时间&#xff1a;2024年5月28日&#xff0c;20:00 - 21:00会议地点&#xff1a;腾讯会议主持人&#xff1a;寒山参会人员&#xff1a; 夏军、mirror、刘哥、悟缺席人员&#xff1a;可心、…