@[toc]
参考官方文档:Understanding topics
背景
ROS 2将复杂的系统分解成许多模块节点。话题(Topic)是ROS图的一个重要元素,作为节点交换信息的总线。
一个节点可以向任意数量的话题发布数据,并同时拥有对任意数量的话题的订阅。
1. 准备工作
打开一个新的终端并运行:
ros2 run turtlesim turtlesim_node
打开另一个终端并运行:
ros2 run turtlesim turtle_teleop_key
回顾一下前面的教程,这些节点的名称默认为/turtlesim和/teleop_turtle。
2. rqt_graph
在本教程中,我们将使用rqt_graph来可视化变化的节点和话题,以及它们之间的联系。
Using turtlesim and rqt:使用 turtlesim 和 rqt告诉你如何安装rqt和它的所有插件,包括rqt_graph。
要运行rqt_graph,请打开一个新的终端并输入命令:
rqt_graph
也可以通过打开 rqt 并选择 Plugins > Introspection > Node Graph
如果你把鼠标悬停在话题上,你会看到像下图这样的颜色突出显示。
该图描述了 /turtlesim 节点和 /teleop_turtle 节点是如何通过一个话题相互通信的。/teleop_turtle 节点正在向 /turtle1/cmd_vel 话题发布数据(你为移动乌龟而输入的按键),而 /turtlesim 节点被订阅到该话题以接收数据。
rqt_graph 的彩色高亮功能在检查具有许多节点和以许多不同方式连接的话题的更复杂系统时非常有用。
3. ros2 topic list 命令
在一个新的终端中运行 ros2 topic list 命令,将返回一个当前系统中所有活动的话题的列表。
ros2 topic list
ros2 topic list -t 将返回相同的话题列表,但在括号中附加了话题类型。
ros2 topic list -t
如果你想知道所有这些话题在rqt_graph中的位置,你可以参照下图设置rqt_graph。
4. ros2 topic echo 命令
要查看关于一个话题的正在发布的数据,使用这条命令:
ros2 topic echo <topic_name>
既然我们知道/ teleop_turtle 通过 /turtle1/cmd_vel 话题向 /turtlesim 发布数据,让我们用 echo 来查看这个话题:
ros2 topic echo /turtle1/cmd_vel
起初,这个命令不会返回任何数据。这是因为它在等待 /teleop_turtle 发布内容。回到运行 turtle_teleop_key 的终端,用方向键来移动乌龟的位置,同时观察正在运行 echo 的终端,你会看到每一次移动都会发布位置数据:
现在回到rqt_graph,取消勾选Debug:
/_ros2cli_3351 是我们刚刚运行的echo所创建的节点(数字可能不同)。现在你可以看到,发布者正在cmd_vel话题上发布数据,并且有两个订阅者在订阅。
5. ros2 topic info 命令
话题不一定只能是点对点的通信,它可以是一对多、多对一或多对多。
通过这条命令可以查看 /turtle1/cmd_vel 话题的相关信息:
ros2 topic info /turtle1/cmd_vel
将会返回以下内容:
Type: geometry_msgs/msg/Twist
Publisher count: 1
Subscription count: 2
6. ros2 interface show 命令
节点使用消息(message)在话题上发送数据。发布者和订阅者必须发送和接收相同类型的消息来进行通信。
我们之前通过运行 ros2 topic list -t 来查看每个话题使用的是什么消息类型。回顾一下,cmd_vel 话题的类型是:
geometry_msgs/msg/Twist
这意味着在 geometry_msgs 包中有一个叫做 Twist 的 msg。
现在运行下面这条命令来了解它的细节,具体来说,就是这个消息有什么样的数据结构:
ros2 interface show geometry_msgs/msg/Twist
返回的结果是:
7. ros2 topic pub 命令
现在你已经知道了消息结构,你可以直接从命令行中使用这种命令发布数据到一个话题:
ros2 topic pub <topic_name> <msg_type> '<args>'
'\<args>' 参数是你将传递给话题的实际数据,其结构就是在步骤6.中通过 ros2 interface show 命令得到的。
需要注意的是,这个参数要用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 选项,增加了 --rate 1 选项,它告诉 ros2 topic pub 以 1Hz 的速度稳定发布命令。
现在你可以打开 rqt_graph 以图形化的方式查看正在发生什么。你可以看到通过 ros 2 topic pub 命令启动的节点(/_ros2cli_3704)正在通过 /turtle1/cmd_vel 话题发布消息,而 /turtlesim 节点和通过 ros2 topic echo 命令启动的节点(/_ros2cli_3839)正在从这个话题接收消息。
最后,你可以运行 echo 命令查看 /pose 话题然后刷新 rqt_graph
ros2 topic echo /turtle1/pose
你可以看到 /turtlesim 节点也在向 pose 话题发布信息,而 echo 命令创建的新节点也在订阅该话题
8. ros2 topic hz 命令
你可以使用 ros2 topic hz 命令检查数据发布的速度:
ros2 topic hz /turtle1/pose
它将返回 /turtlesim 节点向 pose 话题发布数据的速度
因为刚才使用了 ros2 topic pub --rate 1 命令,以 1Hz 的稳定速度向 turtle1/cmd_vel 话题发布数据,所以下面这条命令返回的速度也是 1Hz:
ros2 topic hz /turtle1/cmd_vel
9. 清理
到这一步,你已经有很多个正在运行的节点,别忘了在每个终端中按 Ctrl+C关闭它们