ROS2教程 04 话题Topic

简介: 本文是关于ROS2(机器人操作系统2)中话题(Topic)机制的教程,详细介绍了ROS2中话题的命令使用,包括列出、回显、发布、信息查询、类型查询等功能,并通过示例代码展示了如何创建发布者(Publisher)和订阅者(Subscriber)节点,以及如何测试发布-话题-订阅通信。

一、ROS2 话题Topic 示意图

在这里插入图片描述
ROS2的Topic可以是一对一,一对多,多对一,多对多,同一个话题Topic可以被不同的节点Node订阅与发布

二、与ros1区别

topic下有多种命令,以下是ros1的topic命令:
可以看到和ros2的topic没有什么区别

Commands: rostopic bw display bandwidth used by topic rostopic delay
display delay of topic from timestamp in header rostopic echo print
messages to screen rostopic find find topics by type rostopic hz
display publishing rate of topic rostopic info print information about
active topic rostopic list 获取话题列表 list active topics rostopic pub
发布话题数据 publish data to topic rostopic type print topic or field type

三、ros2 topic

① ros2 topic list

输出当前存在的话题Topic列表

ros2 topic list
OUTPUT:
/parameter_events
/rosout
/turtle1/cmd_vel
/turtle1/color_sensor
/turtle1/pose

输出话题名同时输出话题类型

当添加 -t 后缀时将同时输出话题列表与各个话题的消息类型Message Type

ros2 topic list -t
OUTPUT:
/parameter_events [rcl_interfaces/msg/ParameterEvent]
/rosout [rcl_interfaces/msg/Log]
/turtle1/cmd_vel [geometry_msgs/msg/Twist]
/turtle1/color_sensor [turtlesim/msg/Color]
/turtle1/pose [turtlesim/msg/Pose]

② ros2 topic echo

如果要查看topic list中某个具体的的话题正在发布的内容,可以使用ros2 topic echo + 话题名

ros2 topic echo /turtle1/cmd_vel
OUTPUT:
---
linear:
  x: 2.0
  y: 0.0
  z: 0.0
angular:
  x: 0.0
  y: 0.0
  z: 0.0
---
linear:
  x: 2.0
  y: 0.0
  z: 0.0
angular:
  x: 0.0
  y: 0.0
  z: 0.0
---

③ ros2 topic pub

pub可以在终端中直接发布命令,这在需要直接在命令行中简单输入即可调试时比较好用

ros2 topic pub <topic_name> <msg_type> '<args>'

不同的发布方式

单次发布
其中–once代表仅循环发布一次,然后退出,输入的结构内容是用yaml语法写的,因此在命令行中看起来比较繁杂。

ros2 topic pub --once /turtle1/cmd_vel geometry_msgs/msg/Twist "{linear: {x: 2.0, y: 0.0, z: 0.0}, angular: {x: 0.0, y: 0.0, z: 1.8}}"
OUTPUT:
publisher: beginning loop
publishing #1: geometry_msgs.msg.Twist(linear=geometry_msgs.msg.Vector3(x=2.0, y=0.0, z=0.0), angular=geometry_msgs.msg.Vector3(x=0.0, y=0.0, z=1.8))

循环发布
在pub后加入 --rate 1,代表循环频率为1HZ

ros2 topic pub --rate 1 /turtle1/cmd_vel geometry_msgs/msg/Twist "{linear: {x: 2.0, y: 0.0, z: 0.0}, angular: {x: 0.0, y: 0.0, z: 1.8}}"
OUTPUT:
publisher: beginning loop
publishing #1: geometry_msgs.msg.Twist(linear=geometry_msgs.msg.Vector3(x=2.0, y=0.0, z=0.0), angular=geometry_msgs.msg.Vector3(x=0.0, y=0.0, z=1.8))

publishing #2: geometry_msgs.msg.Twist(linear=geometry_msgs.msg.Vector3(x=2.0, y=0.0, z=0.0), angular=geometry_msgs.msg.Vector3(x=0.0, y=0.0, z=1.8))

publishing #3: geometry_msgs.msg.Twist(linear=geometry_msgs.msg.Vector3(x=2.0, y=0.0, z=0.0), angular=geometry_msgs.msg.Vector3(x=0.0, y=0.0, z=1.8))

④ ros2 topic info

info可以显示话题Topic的类型与多少个节点Node正在发布它与订阅它

ros2 topic info /turtle1/cmd_vel

获取更详细的信息

ros2 topic info /turtle1/cmd_vel -v
# ros2 topic info /turtle1/cmd_vel -verbose
OUTPUT:
Type: geometry_msgs/msg/Twist
Publisher count: 1
Subscription count: 2

⑤ ros2 topic type

查看话题Topic的消息类型Message Type

ros2 topic type /turtle1/cmd_vel
OUTPUT:
geometry_msgs/msg/Twist

以下命令用的不多:

⑥ ros2 topic hz

查看话题Topic发布的平均频率HZ

ros2 topic hz /turtle1/cmd_vel
OUTPUT:
average rate: 1.000
    min: 1.000s max: 1.000s std dev: 0.00001s window: 2
average rate: 1.000
    min: 0.999s max: 1.000s std dev: 0.00030s window: 4
average rate: 1.000
    min: 0.999s max: 1.000s std dev: 0.00025s window: 6
average rate: 1.000
    min: 0.999s max: 1.001s std dev: 0.00042s window: 7

⑦ ros2 topic bw

查看话题所占用的带宽

ros2 topic bw /turtle1/cmd_vel
OUTPUT:
91 B/s from 3 messages
    Message size mean: 52 B min: 52 B max: 52 B
153 B/s from 8 messages
    Message size mean: 52 B min: 52 B max: 52 B
126 B/s from 9 messages
    Message size mean: 52 B min: 52 B max: 52 B
198 B/s from 18 messages
    Message size mean: 52 B min: 52 B max: 52 B
191 B/s from 21 messages
    Message size mean: 52 B min: 52 B max: 52 B
186 B/s from 24 messages
    Message size mean: 52 B min: 52 B max: 52 B

⑧ ros2 topic find

由消息类型Message Type 反查消息类型为该类型Type的话题Topic

ros2 topic find geometry_msgs/msg/Twist
OUTPUT:
/turtle1/cmd_vel

⑨ ros2 topic delay

delay Display delay of topic from timestamp in header

四、查看Message Type的具体结构

当要查看具体消息类型Message Type的结构时,可以使用如下命令:

ros2 interface show geometry_msgs/msg/Twist
OUTPUT:
Vector3  linear
    float64 x
    float64 y
    float64 z
Vector3  angular
    float64 x
    float64 y
    float64 z

五、Topic机制

在ROS2中已经没有了Master的概念,避免master挂了,以提升系统的稳定性

六、发布者Publisher

1.新建功能包

ros2 pkg create --build-type ament_python py_pub_sub

2.新建源码文件

在py_pub_sub功能包的py_pub_sub文件夹下新建源码文件publisher_member_function.py

touch publisher_member_function.py

3.编写源码

ros2中提供的消息接口可以通过以下命令来查看

ros2 interface list

进而查看具体的消息类型的结构

ros2 interface show std_msgs/msg/String
OUTPUT:
# This was originally provided as an example message.
# It is deprecated as of Foxy
# It is recommended to create your own semantically meaningful message.
# However if you would like to continue using this please use the equivalent in example_msgs.

string data

编写步骤

编写步骤:
1.编程接口初始化
2.创建节点并初始化
3.创建发布者对象
4.创建话题并填充话题消息
5.发布话题消息
6.销毁节点并关闭接口

示例源码

import rclpy # rclpy是ROS Client Library for Python的缩写,与Node有关的内容在这个库中
from rclpy.node import Node 
from std_msgs.msg import String # std_msgs是ROS内置的数据类型库,里面有msg、srv等一系列基础的数据类型 


class MinimalPublisher(Node): # Node为这个类的父类

    def __init__(self):
        super().__init__('minimal_publisher') # 调用父类中Node的构造函数,在此处直接为其赋名minimal_publisher
        # 创建publisher,数据类型为String,话题名为topic_name, 队列长度为10,它是QoS (quality of service) setting之一
        self.example_publisher = self.create_publisher(String, 'topic_name', 10)   # 创建发布者对象     
        timer_period = 0.5  # 定时器周期 in seconds
        self.timer = self.create_timer(timer_period, self.timer_callback) # 创建定时器 每个周期调用一次回调函数self.timer_callback
        self.i = 0 # 用于回调函数的一个计数器counter

    def timer_callback(self): # 定时器的回调函数
        msg = String() # 定义消息类型为String类
        msg.data = 'Hello World: %d' % self.i # 添加消息内容
        self.example_publisher.publish(msg) # 发布消息
        self.get_logger().info('Publishing: "%s"' % msg.data) # 可选的打印日志到控制台console
        self.i += 1

# 上面的部分为类内容
# 下面的部分是main函数
def main(args=None): # 主函数
    rclpy.init(args=args) # 初始化 rclpy

    minimal_publisher = MinimalPublisher() # 定义MinimalPublisher类

    rclpy.spin(minimal_publisher) # 循环

    # Destroy the node explicitly
    # (optional - otherwise it will be done automatically
    # when the garbage collector destroys the node object)
    minimal_publisher.destroy_node() # 可以不写,会自动执行
    rclpy.shutdown() #关闭


if __name__ == '__main__': # 该条下的所有代码仅当本脚本直接执行时会触发,如果在其他文件引用本文件,则不会触发以下的代码
    main()

4.添加依赖

在功能包目录下打开package.xml,修改以下内容[可选,不影响使用]
例子:

<description>Examples of minimal publisher/subscriber using rclpy</description>
<maintainer email="hermanye233@icloud.com">Herman Ye</maintainer>
<license>Apache License 2.0</license>

继续添加内容[必须]
当功能包里的代码被执行时,这些语句声明了功能包的依赖

<exec_depend>rclpy</exec_depend>
<exec_depend>std_msgs</exec_depend>

5.添加入口点

打开setup.py,添加入口点

maintainer='Herman Ye',
maintainer_email='hermanye233@icloud.com',
description='Examples of minimal publisher/subscriber using rclpy',
license='Apache License 2.0',

在entry_points下的这个位置添加以下命令

'talker = py_pub_sub.publisher_member_function:main',

最终效果:

entry_points={
   
   
    'console_scripts': [
    'talker = py_pub_sub.publisher_member_function:main',
    ],
},

6.检查setup.cfg

setup.cfg是自动填写的,它将功能包的可执行文件放入lib中,ros2 run将会在lib中查找这些执行性文件是否存在并调用

[develop]
script_dir=$base/lib/py_pub_sub
[install]
install_scripts=$base/lib/py_pub_sub

七、订阅 subscription

1.新建源码文件

在功能包src文件夹下新建源码文件pose_subscriber.cpp

touch pose_subscriber.cpp

2.编写源码

编写步骤

1.编程接口初始化
2.创建节点并初始化
3.创建订阅者对象
4.通过回调函数处理话题数据
5.销毁节点、关闭接口
源码部分注释同publisher

示例源码

import rclpy 
from rclpy.node import Node

from std_msgs.msg import String 


class MinimalSubscriber(Node):

    def __init__(self):
        super().__init__('minimal_subscriber')
        # 订阅者的构造函数和回调函数不需要定时器Timer,因为当收到Message时,就已经启动回调函数了
        # 注意此处不是subscriber,而是subscription
        # 数据类型,话题名,回调函数名,队列长度
        self.subscription = self.create_subscription(String,'topic_name',self.listener_callback,10)
        self.subscription  # prevent unused variable warning

    def listener_callback(self, msg):
        self.get_logger().info('I heard: "%s"' % msg.data) #回调函数内容为打印msg.data里的内容


def main(args=None):
    rclpy.init(args=args)

    minimal_subscriber = MinimalSubscriber()

    rclpy.spin(minimal_subscriber)

    # Destroy the node explicitly
    # (optional - otherwise it will be done automatically
    # when the garbage collector destroys the node object)
    minimal_subscriber.destroy_node()
    rclpy.shutdown()


if __name__ == '__main__':
    main()

3.添加依赖

因为之前添加过了,所以不用再添加,如果subscriber有额外要使用的库,则需要添加新增的库

4.添加入口点

打开setup.py,添加入口点
在entry_points下的这个位置添加以下命令

'listener = py_pub_sub.subscriber_member_function:main',

最终效果:

    entry_points={
   
   
        'console_scripts': [
        'talker = py_pub_sub.publisher_member_function:main',
        'listener = py_pub_sub.subscriber_member_function:main',
        ],
    },

ros2 run 在功能包中所能观测到的可执行文件的名字即此处设置的talker与listener

八、测试发布-话题-订阅通信

1.编译

colcon build --packages-select py_pub_sub

2.运行测试

ros2 run py_pub_sub listener
ros2 run py_pub_sub talker
目录
相关文章
|
1月前
|
Ubuntu 机器人 Linux
|
1月前
|
传感器 数据可视化 机器人
【ROS速成】半小时入门机器人ROS系统简明教程之可视化系统(三)
半小时入门机器人ROS系统简明教程之可视化系统
|
1月前
|
机器人
【ROS速成】半小时入门机器人ROS系统简明教程之安装测速(二)
半小时入门机器人ROS系统简明教程之安装测速
|
3月前
|
存储 自然语言处理 机器人
ROS2教程06 ROS2行动
这篇文章是关于ROS2(Robot Operating System 2)行动(Action)通信机制的教程,包括行动的概念、特点、命令行工具的使用,以及如何编写行动的客户端和服务器代码,并介绍了如何测试行动通信。
114 4
ROS2教程06 ROS2行动
|
3月前
|
机器人 Shell Python
ROS2教程05 ROS2服务
这篇文章是关于ROS2(Robot Operating System 2)服务的教程,涵盖了服务的概念、特性、命令行工具的使用,以及如何编写服务的服务器和客户端代码,并提供了测试服务通信机制的示例。
86 4
ROS2教程05 ROS2服务
|
3月前
|
传感器 算法 数据可视化
ROS2教程04 ROS2话题
这篇文章是关于ROS2(Robot Operating System 2)的教程,主要介绍了ROS2中话题的概念、特性、使用方式,以及如何编写发布者和订阅者的代码。
83 3
ROS2教程04 ROS2话题
|
3月前
|
存储 Ubuntu 安全
ROS2教程02 ROS2的安装、配置和测试
本文是关于ROS2(机器人操作系统2)的安装、配置和测试的教程。内容包括使用一键安装脚本快速安装ROS2 Humble版,手动安装步骤,设置语言环境、添加软件源、更新软件包、安装ROS2桌面版和开发工具,配置ROS2环境,创建工作空间,配置ROS2领域以避免网络冲突,以及如何删除ROS2。此外,还包括了测试ROS2是否安装成功的两个案例:基本的Topic通信测试和使用Turtlesim演示程序。适用于Ubuntu 22.04操作系统。
271 1
ROS2教程02 ROS2的安装、配置和测试
|
3月前
|
传感器 自然语言处理 机器人
ROS2教程03 ROS2节点
本文是关于ROS2(机器人操作系统2)节点的教程,涵盖了节点的概念、特性、使用方法,以及如何编写、测试和使用ROS2节点相关的命令行工具。文章介绍了节点的独立性、任务执行、跨硬件分布和多语言编写能力。详细解释了如何启动节点、查看节点信息、编写节点代码(包括面向过程和面向对象的方法),以及如何为功能包添加依赖和入口点。此外,还探讨了重映射节点名称和使用节点命令行工具的方法,如 `ros2 node info` 和 `ros2 node list`。适合已安装ROS2 Humble和Ubuntu 22.04操作系统,并具有Shell基础知识的读者学习。
94 1
|
3月前
|
机器人 Shell 开发者
ROS2教程08 ROS2的功能包、依赖管理、工作空间配置与编译
这篇文章是关于ROS2(Robot Operating System 2)中功能包、依赖管理、工作空间配置和编译的教程,涵盖了ROS2工作空间的概念、如何获取和安装功能包的依赖、构建工作空间的步骤,以及如何创建和管理ROS2功能包,包括使用命令行工具对功能包进行操作的方法。
373 0
ROS2教程08 ROS2的功能包、依赖管理、工作空间配置与编译
|
3月前
|
编解码 机器人 C++
ROS2教程07 ROS2自定义消息接口
这篇文章是关于如何在ROS2(Robot Operating System 2)中创建和使用自定义消息类型的教程,包括消息类型的定义、特点、命令行工具的使用,以及如何编写和测试自定义消息类型接口的步骤。
79 0
ROS2教程07 ROS2自定义消息接口

推荐镜像

更多