在ROS(Robot Operating System)中,主题(Topics)是实现节点之间通信的主要机制之一。节点(Node)可以发布(publish)消息到话题,或者订阅(subscribe)话题以接收消息。这种基于发布/订阅的通信模型允许节点之间的松耦合交互,是ROS架构的核心特性之一。本文将详细介绍ROS2中的主题,并与ROS1中的主题进行比较。
ROS2 Topic简介
在ROS2中,Topic的工作原理基本保持不变,仍然是基于发布/订阅模式,但实现方式与ROS1有所不同,主要得益于ROS2底层使用的DDS(Data Distribution Service)通信中间件。
- DDS中间件: ROS2使用DDS作为其底层通信机制,这为话题通信提供了一种标准化的数据交换方式。DDS提供了高性能、可靠的数据传输机制,并支持不同的服务质量(QoS)策略,如可靠性、持久性和延迟等。
- 服务质量(QoS)策略: ROS2引入了QoS策略的概念,允许开发者根据具体的应用需求(如实时性、网络带宽限制等)来配置话题的行为。这是ROS1中不具备的功能,为ROS2的通信提供了更高的灵活性和可靠性。
- 安全性: 借助于DDS的安全特性,ROS2在节点间的通信中增加了安全性选项,包括加密、认证和访问控制等,实现了更好的安全性。
Topic的作用
ROS 2 将复杂的系统分解为许多模块化节点。主题是 ROS Graph的重要元素,充当节点交换消息(Message)的总线。
节点可以将数据发布到任意数量的主题,并同时订阅任意数量的主题。
Topic是数据在节点之间移动以及因此在系统的不同部分之间移动的主要方式之一。
ROS1中的话题通信同样基于发布/订阅模式,但是它依赖于自定义的通信协议和中心化的名称服务(ROS Master)来实现节点间的消息传递。
- ROS Master: ROS1中的节点通过与ROS Master通信来发现其他节点和话题。所有的话题注册和查找都需要通过ROS Master,这可能成为系统的瓶颈或单点故障。
- 自定义通信协议: ROS1使用自定义的TCPROS或UDPROS协议进行节点间的通信,而不是标准的中间件,这限制了与其他系统的互操作性。
- 服务质量(QoS): ROS1中没有直接支持QoS策略的概念,虽然可以通过一些机制间接实现类似功能,但不如ROS2中直接支持的灵活和强大。
Topic的命令行工具
显示所有活动topic列表
ros2 topic list
会得到类似如下的输出:
/parameter_events
/rosout
/turtle1/cmd_vel
/turtle1/color_sensor
/turtle1/pose
或者运行:
ros2 topic list -t
将返回相同的主题列表,这次主题类型附加在括号中:
/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]
这些属性,特别是类型,是节点在主题上移动时知道它们正在谈论相同信息的方式。如果您想知道所有这些主题在 rqt_graph 中的位置,您可以取消选中“隐藏”下的所有框:
显示主题
要查看某个主题上发布的数据,请使用:
ros2 topic echo <topic_name>
如果我们知道节点/teleop_turtle
通过/turtle1/cmd_vel
主题发布数据到/turtlesim,那么让我们echo
来显示该主题:
ros2 topic echo /turtle1/cmd_vel
起初,该命令不会返回任何数据。那是因为它正在等待/teleop_turtle
发布一些东西。
返回正在运行turtle_teleop_key
的终端并使用箭头移动乌龟。echo
同时观察您正在运行的终端,您将看到您所做的每个动作都发布了位置数据:
linear:
x: 2.0
y: 0.0
z: 0.0
angular:
x: 0.0
y: 0.0
z: 0.0
---
现在返回 rqt_graph 并取消选中“调试”框。
/_ros2cli_26646
是我们刚刚运行的命令创建的节点echo
(数字可能不同)。现在您可以看到发布者正在通过/turtle1/cmd_vel主题发布数据,并且有两个订阅者订阅了该主题。
显示主题信息
主题不一定只是一对一的交流;它们可以是一对多、多对一或多对多。可以用如下的命令显示主题信息:
ros2 topic info /turtle1/cmd_vel
将返回:
Type: geometry_msgs/msg/Twist
Publisher count: 1
Subscription count: 2
ROS 2接口显示
节点使用消息通过主题发送数据。发布者和订阅者必须发送和接收相同类型的消息才能进行通信。运行如下命令查看主题类型:
ros2 topic list -t cmd_vel
输出结果显示如下,这意味着包中geometry_msgs
有一个msg
名为Twist
.
geometry_msgs/msg/Twist
现在我们可以运行命令来来了解它的细节。具体来说,这个消息期望什么数据结构。
ros2 interface show geometry_msgs/msg/Twist
对于上面的消息类型,它会产生:
# This expresses velocity in free space broken into its linear and angular parts.
Vector3 linear
Vector3 angular
这告诉您该/turtlesim
节点正在等待一条包含两个向量 和 的消息,linear
每个angular
向量包含三个元素。如果您还记得我们看到的通过命令/teleop_turtle
传递的数据,它的结构相同:/turtlesim
echo
linear:
x: 2.0
y: 0.0
z: 0.0
angular:
x: 0.0
y: 0.0
z: 0.0
---
ROS 2主题发布
现在您已经有了消息结构,您可以使用以下命令直接从命令行将数据发布到主题上:
ros2 topic pub <topic_name> <msg_type> '<args>'
参数'<args>'
是您将传递到主题的实际数据,采用您在上一节中刚刚发现的结构。需要注意的是,该参数需要以 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}}"
--once
是一个可选参数,意思是“发布一条消息然后退出”。
您将在终端中看到以下输出:
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))
你会看到你的乌龟像这样移动:
乌龟(通常是它要模仿的真实机器人)需要稳定的命令流才能连续运行。因此,要让乌龟继续移动,您可以运行:
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}}"
这里的区别是删除了该--once
选项并添加了该选项,该选项告诉以 1 Hz 的稳定流发布命令。
rate 1ros2 topic pub
您可以刷新 rqt_graph 以图形方式查看发生的情况。您将看到节点 (/_ros2cli_30358) 正在通过主题(/turtle1/cmd_vel)进行发布,该主题现在被节点(/_ros2cli_26646) 和节点(/turtlesim)接收。
最后,您可以运行对pose
主题运行echo命令并重新检查 rqt_graph:
ros2 topic echo /turtle1/pose
您可以看到该/turtlesim
节点也正在发布到/turtle1/pose主题而/ros2cli_1682订阅了它。
ROS 2主题发布频率
您可以使用以下命令查看数据发布的速率:
ros2 topic hz /turtle1/pose
它将返回/turtlesim节点向/turtle1/pose主题发布数据的速率。
average rate: 59.354
min: 0.005s max: 0.027s std dev: 0.00284s window: 58
回想一下,您使用ros2 topic pub --rate
命令将/turtle1/cmd_vel
发布速率设置为稳定的 1 Hz 。如果您使用 turtle1/cmd_vel
而不是 turtle1/pose
运行上述命令,您将看到反映该速率的平均值。
总结
节点通过主题发布信息,这允许任意数量的其他节点订阅和访问该信息。在本节中,您使用 rqt_graph 和命令行工具检查了主题上多个节点之间的连接。您现在应该很好地了解数据如何在 ROS 2 系统中移动。
作者个人Blog:ROS 2基础概念#3:主题(Topic)| ROS 2学习笔记 - HY's Blog