ROS2 Jazzy: 理解话题

249 阅读8分钟

背景

ROS2将复杂系统分解为许多模块化节点。话题是ROS图的重要元素,它充当节点交换消息的总线。

节点可以向任意数量的话题发布数据,同时也可以订阅任意数量的话题。

话题是数据在节点之间(从而在系统的不同部分之间)移动的主要方式之一。

准备

这一节中,同样不要忘记在使用ROS2前需要先设置环境:

# Replace ".bash" with your shell if you're not using bash
# Possible values are: setup.bash, setup.sh, setup.zsh
source /opt/ros/jazzy/setup.bash

任务

1、启动turturlesim

到目前为止,您应该可以轻松的启动turturlesim了。打开一个新的终端并运行:

ros2 run turtlesim turtlesim_node

打开另一个新的终端并运行:

ros2 run turtlesim turtle_teleop_key

回忆或查看一下之前的文章可以知道:这些节点的名称默认为/turtlesim和/teleop_turtle。

2、rqt_graph

这一次,我们将使用rqt_graph可视化不断变化的节点和主题,以及它们之间的连接。

首先安装需要安装rpt

sudo apt update
sudo apt install '~nros-jazzy-rqt*'

然后运行rqt_graph,打开一个新终端输入以下命令:

rqt_graph

你也可以运行rqt并选择Plugins > Introspection > Node Graph来打开rqt_graph。

您应该可以看到上面显示的节点和主题,以及图外围的两个操作(现在我们先忽略它们)。如果您将鼠标悬停在中心的主题上,您会看到像上面的图片一样高亮的颜色。

这幅图描述了/turtlesim节点和/teleop_turtle节点如何在一个话题上相互通信。/teleop_turtle节点正在向/turtle1/cmd_vel话题发布数据(你输入的移动乌龟的按键指令),而/turtlesim节点订阅该话题以接收数据。

rqt_graph的高亮显示特性非常有用,它使您能很方便的查看多节点和多话题以许多不同方式连接的更复杂的系统。

rqt_graph是一个图形查看工具。现在我们来看一些用于查看话题的命令行工具。

3、ros2 topic list

在新终端中运行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]

这些属性(尤其是类型)能让节点确认它们在通过话题传递信息时,彼此讨论的是同一种数据。

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终端,会看到每次移动时发布的实时位置数据:

linear:
  x: 2.0
  y: 0.0
  z: 0.0
angular:
  x: 0.0
  y: 0.0
  z: 0.0
  ---

现在返回到rqt_graph并取消选中Debug框。

/_ros2cli_26646是我们刚才运行的echo命令创建的节点(数字可能不同)。现在可以看到发布者通过cmd_vel话题发布数据,而两个订阅者订阅了该话题。

5、ros2 topic info

话题不仅是一对一的交流;它们也可以是一对多、多对一或多对多。

另一种查看方式是使用以下命令:

ros2 topic info /turtle1/cmd_vel

它会返回以下结果:

Type: geometry_msgs/msg/Twist
Publisher count: 1
Subscription count: 2

6、ros2 interface show

节点使用消息在话题上发送数据。发布者和订阅者必须发送和接收相同类型的消息才能进行通信。

我们在前面运行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

对于上述消息类型,输出如下:

# This expresses velocity in free space broken into its linear and angular parts.

    Vector3  linear
            float64 x
            float64 y
            float64 z
    Vector3  angular
            float64 x
            float64 y
            float64 z

这表明/turtlesim节点期望接收包含两个三维向量(线速度和角速度)的消息。回想之前通过echo命令看到的/teleop_turtle传递给/turtlesim的数据,其结构完全一致:

linear:
  x: 2.0
  y: 0.0
  z: 0.0
angular:
  x: 0.0
  y: 0.0
  z: 0.0
  ---

7、ros2 topic pub

现在您已经了解了消息的结构,就可以直接从命令行发布数据到指定话题:

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

其中'<args>'参数是您传递给主题的实际数据。

海龟(以及它模拟的真实机器人)需要持续的命令流才能保持运动。要让海龟持续移动,可使用以下命令(注意参数需采用YAML语法):

ros2 topic pub /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}}"

默认情况下,ros2 topic pub会以1Hz频率持续发布命令。

如果只想发布单次命令,而不是持续命令,可以添加--once选项:

ros2 topic pub --once -w 2 /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表示"发布一次后退出"
  • -w 2表示"等待两个匹配的订阅者"(因为当前有turtlesim和topic echo两个订阅者)

您会在终端看到以下输出:

Waiting for at least 2 matching subscription(s)...
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))

同时您也会看到此时海龟会象这样移动:

您可以通过刷新rqt_graph可以看到新的发布节点(/_ros2cli_30358)正在向/turtle1/cmd_vel主题发布消息,而该主题同时被/_ros2cli_26646回显节点和/turtlesim节点订阅

最后,您可以对位姿话题运行回显命令并重新检查节点关系:

ros2 topic echo /turtle1/pose

您可以刷rqt_graph看到/turtlesim节点也在向位姿主题发布消息,而新的回显节点已订阅该主题。

当您想发布带时间戳的消息时,可以使用pub提供的两种时间戳自动填充方式:

  • 对于包含std_msgs/msg/Header的消息,设置header: "auto"可自动填充时间戳:
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 topic hz

您可以使用以下命令查看话题数据发布速率:

ros2 topic hz /turtle1/pose

它将返回/turtlesim节点发布位姿话题频率的统计数据:

average rate: 59.354
  min: 0.005s max: 0.027s std dev: 0.00284s window: 58

如果对turtle1/cmd_vel运行此命令,您将看到反映该比率的平均值。需要注意的是,这个速率反映了ros2 topic hz命令创建的订阅的接收速率,实际测量频率可能受平台资源和QoS配置影响,可能与发布端频率不完全一致。

9、ros2 topic bw

查看话题带宽使用情况:

ros2 topic bw /turtle1/pose

它返回带宽利用率和发布到/turtle1/pose主题的消息数。

Subscribed to [/turtle1/pose]
1.51 KB/s from 62 messages
    Message size mean: 0.02 KB min: 0.02 KB max: 0.02 KB

同样需要注意的是,带宽反映了ros2 topic bw命令创建的订阅的接收速率,该速率可能会受到平台资源和QoS配置的影响,并且可能与发布者的带宽不完全匹配。

10、ros2 topic find

列出指定类型的所有可用主题:

ros2 topic find <topic_type>

例如查找geometry_msgs/msg/Twist类型的主题

ros2 topic find geometry_msgs/msg/Twist

输出结果为:

/turtle1/cmd_vel

11、Clean up

此时系统中运行着多个节点,记得在每个终端按Ctrl+C停止它们。

总结

节点通过话题发布信息,它允许任意数量的其他节点订阅和获取数据。本节中,您使用rqt_graph和命令行工具检查了多个节点通过话题建立的连接关系。现在您应该已经理解了ROS2系统中数据的流动方式。


关注【智践行】公众号,发送 【机器人】 获得机器人经典学习资料