理解话题
目标:使用 rqt_graph 和命令行工具来内省 ROS 2 话题。
教程级别:初学者
时间:20 分钟
目录
背景
先决条件
任务
设置
2 rqt_graph
3 ros2 话题列表
4 ros2 话题回声
5 ros2 话题信息
6 ros2 接口显示
7 ros2 话题发布
8 ros2 话题赫兹
清理
摘要
下一步
背景
ROS 2 将复杂系统分解为许多模块化节点。话题是 ROS 图的一个重要元素,它们充当节点交换消息的总线。
一个节点可以向任意数量的话题发布数据,同时可以订阅任意数量的话题。
话题是数据在节点之间移动的主要方式之一,因此也是系统不同部分之间交换数据的方式。
先决条件
前一教程提供了一些关于节点的有用背景信息,我们在此基础上进行了扩展。
始终不要忘记在您打开的每个新终端中获取 ROS 2 的源。
任务
设置
到目前为止,您应该已经可以轻松启动 turtlesim 了。
打开一个新的终端并运行:
ros2 run turtlesim turtlesim_node
打开另一个终端并运行:
ros2 run turtlesim turtle_teleop_key
回想一下上一教程中提到的,这些节点的名称默认为 /turtlesim
和 /teleop_turtle
。
2 rqt_graph
在本教程中,我们将使用 rqt_graph
来可视化变化的节点和话题,以及它们之间的连接。
乌龟仿真教程告诉您如何安装 rqt 及其所有插件,包括 rqt_graph
。
要运行 rqt_graph,请打开一个新的终端并输入命令:
rqt_graph
您也可以通过打开 rqt
并选择插件 > 内省 > 节点图来打开 rqt_graph。
您应该能看到上面的节点和话题,以及图表中的两个动作(现在我们先忽略它们)。如果您将鼠标悬停在中心的话题上,您会看到像上图中那样的颜色高亮显示。
图表展示了 /turtlesim
节点和 /teleop_turtle
节点如何通过一个话题相互通信。 /teleop_turtle
节点正在向 /turtle1/cmd_vel
话题发布数据(您输入的按键来移动乌龟),而 /turtlesim
节点订阅了该话题以接收数据。
rqt_graph 的高亮显示功能在检查许多节点和话题以多种不同方式连接的更复杂系统时非常有帮助。
rqt_graph 是一个图形化内省工具。现在我们将看一些用于内省话题的命令行工具。
3 ros2 话题列表
在新终端运行 ros2 topic list
命令将返回系统中当前所有活跃话题的列表:
cxy@ubuntu2404-cxy:~$ ros2 topic list
/parameter_events
/rosout
/turtle1/cmd_vel
/turtle1/color_sensor
/turtle1/pose
ros2 topic list -t
将返回相同的话题列表,这次在括号中附加了话题类型:
cxy@ubuntu2404-cxy:~$ 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 中所有这些主题在哪里,您可以取消选中“隐藏”下的所有框:
现在,不过,还是保留那些选项勾选,以避免混淆。
4 ros2 主题回声
要查看正在某个主题上发布的数据,请使用:
ros2 topic echo <topic_name>
既然我们知道 /teleop_turtle
通过 /turtle1/cmd_vel
主题向 /turtlesim
发布数据,那么让我们使用 echo
来内省那个主题:
ros2 topic echo /turtle1/cmd_vel
最初,这个命令不会返回任何数据。那是因为它在等待 /teleop_turtle
发布一些内容。
返回运行 turtle_teleop_key
的终端,并使用箭头来移动乌龟。同时观察运行 echo
的终端,你会看到每次移动都会发布位置数据:
cxy@ubuntu2404-cxy:~$ ros2 topic echo /turtle1/cmd_vel
linear:x: 2.0y: 0.0z: 0.0
angular:x: 0.0y: 0.0z: 0.0
---
linear:x: 0.0y: 0.0z: 0.0
angular:x: 0.0y: 0.0z: 2.0
---
linear:x: 2.0y: 0.0z: 0.0
angular:x: 0.0y: 0.0z: 0.0
---
现在返回到 rqt_graph 并取消选中 Debug 框。
/_ros2cli_8346
是我们刚刚运行的 echo
命令创建的节点(数字可能有所不同)。现在您可以看到发布者正在 cmd_vel
主题上发布数据,而有两个订阅者订阅了它。
5 ros2 话题信息
主题不仅可以是一对一的交流;它们可以是一对多、多对一,或者多对多。
另一种看待这个问题的方式是运行:
ros2 topic info /turtle1/cmd_vel
将返回:
cxy@ubuntu2404-cxy:~ros2 topic info /turtle1/cmd_velel
Type: geometry_msgs/msg/Twist
Publisher count: 1
Subscription count: 1
6 ros2 接口显示
节点通过使用消息在主题上发送数据。发布者和订阅者必须发送和接收相同类型的消息以进行通信。
我们之前在运行 ros2 topic list -t
后看到的主题类型让我们知道每个主题上使用的是什么消息类型。回想一下, cmd_vel
主题的类型是:
geometry_msgs/msg/Twist
这意味着在 geometry_msgs
包中有一个名为 Twist
的 msg
。
现在我们可以在这个类型上运行 ros2 interface show <msg type>
来了解它的详细信息。具体来说,消息期望的数据结构是什么。
ros2 interface show geometry_msgs/msg/Twist
对于上面的消息类型,它产生:
cxy@ubuntu2404-cxy:~$ ros2 interface show geometry_msgs/msg/Twist
# This expresses velocity in free space broken into its linear and angular parts.Vector3 linearfloat64 xfloat64 yfloat64 z
Vector3 angularfloat64 xfloat64 yfloat64 z
这告诉你 /turtlesim
节点期望收到一条消息,其中包含两个向量, linear
和 angular
,每个向量有三个元素。如果你还记得我们之前看到的数据,它是通过 echo
命令传递给 /turtlesim
的,其结构是相同的:
linear:x: 2.0y: 0.0z: 0.0
angular:x: 0.0y: 0.0z: 0.0---
7 ros2 主题发布
现在您已经有了消息结构,您可以直接使用以下命令行将数据发布到主题:
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
是一个可选参数,意味着“发布一条消息然后退出”。
您将在终端中看到以下输出:
cxy@ubuntu2404-cxy:~$ 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}}"
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
选项并增加了 --rate 1
选项,这告诉 ros2 topic pub
以 1 赫兹的稳定流发布命令。
您可以刷新 rqt_graph 来图形化地查看发生了什么。您会看到 ros2 topic pub ...
节点 ( /_ros2cli_8766
) 正在 /turtle1/cmd_vel
主题上发布,现在被 ros2 topic echo ...
节点 ( /_ros2cli_26646
) 和 /turtlesim
节点接收。
最后,您可以在 pose
主题上运行 echo
并重新检查 rqt_graph:
ros2 topic echo /turtle1/pose
您可以看到 /turtlesim
节点也在发布到 pose
主题,新的 echo
节点已经订阅了该主题。
在发布带有时间戳的消息时, pub
有两种方法可以自动用当前时间填充它们。对于带有 std_msgs/msg/Header
的消息,可以将头字段设置为 auto
,以填充 stamp
字段。
ros2 topic pub /pose geometry_msgs/msg/PoseStamped '{header: "auto", pose: {position: {x: 1.0, y: 2.0, z: 3.0}}}'
如果消息没有使用完整的头部,而只是有一个类型为 builtin_interfaces/msg/Time
的字段,那么可以将其设置为值 now
。
ros2 topic pub /reference sensor_msgs/msg/TimeReference '{header: "auto", time_ref: "now", source: "dumy"}'
8 ros2 主题频率
在这个过程的最后一次反思中,您可以通过以下方式查看数据发布的速率:
ros2 topic hz /turtle1/pose
它将返回 /turtlesim
节点向 pose
主题发布数据的速率数据。
cxy@ubuntu2404-cxy:~ros2 topic hz /turtle1/posese
average rate: 62.336min: 0.014s max: 0.018s std dev: 0.00079s window: 64
average rate: 62.403min: 0.014s max: 0.018s std dev: 0.00065s window: 127
回想一下,您使用 ros2 topic pub --rate 1
将 turtle1/cmd_vel
的发布速率设置为稳定的 1 Hz。如果您使用 turtle1/cmd_vel
而不是 turtle1/pose
运行上述命令,您将看到反映该速率的平均值。
清理
在这一点上,你会有很多节点在运行。不要忘记通过在每个终端输入 Ctrl+C
来停止它们。
摘要
节点通过主题发布信息,这允许任意数量的其他节点订阅并访问该信息。在本教程中,您通过使用 rqt_graph 和命令行工具检查了几个节点之间通过主题的连接。现在您应该对数据如何在 ROS 2 系统中移动有了很好的了解。
下一步
接下来,您将通过教程“了解服务”学习 ROS 图中的另一种通信类型。https://docs.ros.org/en/jazzy/Tutorials/Beginner-CLI-Tools/Understanding-ROS2-Services/Understanding-ROS2-Services.html