学习资料参考ROS2入门教程.
节点实现了机器人各种各样的功能,但这些功能并不是独立的,之间会有千丝万缕的联系,其中最重要的一种联系方式就是话题,它是节点间传递数据的桥梁。
ROS2将复杂系统分解为多个模块化节点。话题是ROS图的重要元素,充当节点交换消息的总线。
一个节点可以向任意数量的话题发布数据,同时订阅任意数量的话题。
到目前为止,您应该可以轻松启动gurisim了。
打开新终端并运行:
ros2 run turtlesim turtlesim_node
打开另一个终端
ros2 run turtlesim turtle_teleop_key
在本教程中,我们将使用rqt_graph可视化不断变化的节点和主题,以及它们之间的连接。
[guirsim教程](https://docs.ros.org/en/humble/Tutorials/Beginner-CLI-Tools/Introducing-Turtlesim/Introducing-Turtlesim.html)告诉您如何安装rqt及其所有插件,包括rqt_graph。
打开一个新终端,启动rqt_graph
rqt_graph
您还可以打开rqt_graph,方法是打开rqt并选择Plugins>Introspection>Node graph。
您应该会看到上面的节点和主题,以及围绕图形外围的两个操作(我们暂时忽略这些操作)。如果将鼠标悬停在中心的主题上,您将看到如上图所示的颜色高亮显示。
该图描述了/turlsim节点和/teleop_turtle节点如何通过主题相互通信。/teleop_turtle节点将数据(您输入以移动龟的击键)发布到/curl1/cmd_vel主题,/curlsim节点订阅该主题以接收数据。
rqt_graph的突出显示功能在检查以多种不同方式连接的多个节点和主题的更复杂系统时非常有用。
rqt_graph是一个图形化的自省工具。现在我们来看一些用于内省主题的命令行工具。
在新终端中运行ros2主题列表命令将返回系统中当前活动的所有主题的列表:
$ ros2 topic list
/parameter_events
/rosout
/turtle1/cmd_vel
/turtle1/color_sensor
/turtle1/pose
不清楚这些话题传输的是什么数据,没问题,这个命令试一下:
ros2 topic list -t
$ 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]
这回我们不仅可以看到所有话题的列表,还可以清晰的看到每个话题传输的数据类型是什么。
如果想看到节点之间的话题到底发了什么数据内容,可以这样:
ros2 topic echo
我们现在好奇键盘节点到底给小海龟发了什么,小海龟这么听话的动起来呢?
ros2 topic echo /turtle1/cmd_vel
输入之后可能暂时看不到任何内容,这是因为我们还没有发布数据,在运行键盘控制节点的终端中点击键盘,很快就可以看到数据啦:
$ ros2 topic echo /turtle1/cmd_vel
linear:
x: 2.0
y: 0.0
z: 0.0
angular:
x: 0.0
y: 0.0
z: 0.0
---
linear:
x: 0.0
y: 0.0
z: 0.0
angular:
x: 0.0
y: 0.0
z: 2.0
---
linear:
x: 2.0
y: 0.0
z: 0.0
angular:
x: 0.0
y: 0.0
z: 0.0
---
原来键盘控制节点将点击的键盘按键变成了线速度和角速度,通过话题发送给海龟仿真器,海龟才动起来的。
话题不必只是点对点的交流;它可以是一对多、多对一或多对多。
另一种方法是执行指令:
$ ros2 topic info /turtle1/cmd_vel
将会返回
$ ros2 topic info /turtle1/cmd_vel
Type: geometry_msgs/msg/Twist
Publisher count: 1
Subscription count: 1
节点使用消息通过主题发送数据。发布者和订阅者必须发送和接收相同类型的消息才能进行通信。
在运行ros2 topic list-t之后,我们前面看到的主题类型让我们知道每个主题上使用的消息类型。回想一下,cmd_vel主题的类型是:
geometry_msgs/msg/Twist
这意味着在geometry_msgs包中有一个名为Twist的消息。
现在,我们可以对该类型运行ros2接口show来了解其详细信息,特别是消息所需的数据结构。
ros2 interface show 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
float64 x
float64 y
float64 z
Vector3 angular
float64 x
float64 y
float64 z
原来Twist中包含了两个三维向量,分别表示线速度和角速度。
既然您有了消息结构,就可以使用以下命令从命令行直接将数据发布到主题:
ros2 topic pub <topic_name> <msg_type> ''
“”参数是您将传递给主题的实际数据,位于您在上一节中刚刚发现的结构中。
需要注意的是,这个参数需要以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是一个可选参数,表示“发布一条消息然后退出”。
您将在终端中收到以下消息:
$ 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选项,增加了–rate1选项,它告诉ros2主题pub以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}}"
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))
您可以刷新rqt_graph,以图形方式查看发生了什么。您将看到ros 2主题pub…节点(/_ros2cli_30358)正在/curl1/cmd_vel主题上发布,现在ros2主题echo…节点(/_ros2cl_26646)和/curlsim节点都在接收它。
如果我们想查看某一个话题的发布频率,依然可以通过命令行来实现:
ros2 topic hz /turtle1/pose
很快就可以看到turtlesim节点发布pose话题的频率啦:
$ ros2 topic hz /turtle1/pose
average rate: 62.454
min: 0.014s max: 0.018s std dev: 0.00073s window: 64
average rate: 62.509
min: 0.014s max: 0.018s std dev: 0.00071s window: 127
average rate: 62.513
min: 0.014s max: 0.018s std dev: 0.00072s window: 190
average rate: 62.496
min: 0.014s max: 0.018s std dev: 0.00073s window: 253
回想一下,您使用ros2 topic pub–rate 1将turtle1/cmd_vel的速率设置为稳定的1 Hz。如果您使用turtle1/cm d_evel而不是turtle1/pose运行上述命令,您将看到一个反映该速率的平均值。
$ ros2 topic hz /turtle1/cmd_vel
WARNING: topic [/turtle1/cmd_vel] does not appear to be published yet
average rate: 1.000
min: 0.999s max: 1.000s std dev: 0.00042s window: 3
average rate: 1.000
min: 0.998s max: 1.000s std dev: 0.00077s window: 5
average rate: 1.000
min: 0.998s max: 1.000s std dev: 0.00073s window: 7
average rate: 1.000
此时,您将有许多节点在运行。不要忘记通过在每个终端中输入Ctrl+C来停止它们。