Note: This tutorial assumes that you have completed the previous tutorials: 理解ROS节点.
(!) Please ask about problems and questions regarding this tutorial on answers.ros.org. Don't forget to include in your question the link to this page, the versions of your OS & ROS, and also add appropriate tags.

理解ROS话题

Description: 本教程介绍了ROS话题,以及如何使用rostopicrqt_plot命令行工具。

Tutorial Level: BEGINNER

Next Tutorial: 理解ROS服务和参数

开始

roscore

首先确保roscore正在运行, 打开一个终端:

$ roscore

如果你没有退出在上一篇教程中运行的roscore,则可能会显示错误消息:

  • roscore cannot run as another roscore/master is already running.
    Please kill other roscore/master processes before relaunching

这是正常的,因为只需要有一个roscore在运行就够了。

turtlesim

在本教程中我们也会使用到turtlesim,打开一个终端:

$ rosrun turtlesim turtlesim_node

通过键盘遥控turtle

我们还需要通过键盘来控制turtle,打开一个终端:

$ rosrun turtlesim turtle_teleop_key
  • [ INFO] 1254264546.878445000: Started node [/teleop_turtle], pid [5528], bound on [aqy], xmlrpc port [43918], tcpros port [55936], logging to [~/ros/ros/log/teleop_turtle_5528.log], using [real] time
    Reading from keyboard
    ---------------------------
    Use arrow keys to move the turtle.

现在你可以使用键盘上的方向键来控制turtle运动了。如果不能控制,请选中turtle_teleop_key的终端窗口以确保按键输入能够被捕获。

  • ROS/Tutorials/UnderstandingTopics/turtle_key.png

现在可以让乌龟来回走动了,让我们看看幕后发生的事情。

ROS话题

turtlesim_node节点和turtle_teleop_key节点之间是通过一个ROS话题来相互通信的。turtle_teleop_key在话题上发布键盘按下的消息,turtlesim订阅该话题以接收消息。让我们使用rqt_graph来显示当前运行的节点和话题。

注意:如果你使用的是ROS electric或早期版本,那么rqt是不可用的,请使用rxgraph代替。

使用rqt_graph

rqt_graph用动态的图显示了系统中正在发生的事情。rqt_graph是rqt程序包中的一部分。如果你发现没有安装,请:

  • $ sudo apt-get install ros-<distro>-rqt
    $ sudo apt-get install ros-<distro>-rqt-common-plugins

将<distro>替换成你安装的ROS发行版简称(比如kinetic或noetic等)。

打开一个终端:

$ rosrun rqt_graph rqt_graph

你会看到一个窗口:

ROS/Tutorials/UnderstandingTopics/rqt_graph_turtle_key.png

如果把鼠标放在/turtle1/command_velocity上方,相应的ROS节点(这里是蓝色和绿色)和话题(这里是红色)就会高亮显示。可以看到,turtlesim_nodeturtle_teleop_key节点正通过一个名为/turtle1/command_velocity的话题来相互通信。

ROS/Tutorials/UnderstandingTopics/rqt_graph_turtle_key2.png

介绍rostopic

rostopic命令工具能让你获取ROS话题的信息。

你可以使用帮助选项查看可用的rostopic的子命令,例如:

$ rostopic -h
  • rostopic is a command-line tool for printing information about ROS Topics.
    
    Commands:
            rostopic bw     display bandwidth used by topic
            rostopic delay  display delay of topic from timestamp in header
            rostopic echo   print messages to screen
            rostopic find   find topics by type
            rostopic hz     display publishing rate of topic    
            rostopic info   print information about active topic
            rostopic list   list active topics
            rostopic pub    publish data to topic
            rostopic type   print topic or field type
    
    Type rostopic <command> -h for more detailed usage, e.g. 'rostopic echo -h'

或者在输入rostopic 之后双击Tab键输出可能的子命令:

$ rostopic 
bw    echo  find  hz    info  list  pub   type 

接下来我们将使用其中的一些子命令来调查turtlesim。

使用rostopic echo

rostopic echo可以显示在某个话题上发布的数据。

用法:

rostopic echo [topic]

让我们看看由turtle_teleop_key节点发布的“指令、速度”数据。

在ROS Hydro及更新版本中,这些数据发布在/turtle1/cmd_vel话题上。打开一个终端:

$ rostopic echo /turtle1/cmd_vel

在ROS Groovy及早期版本中,这些数据发布在/turtle1/command_velocity话题上。打开一个终端:

$ rostopic echo /turtle1/command_velocity

你可能会看到什么都没发生,因为现在还没有数据被发布到该话题上。可以通过按下键盘方向键让turtle_teleop_key节点发布数据。记得如果不能控制乌龟,请选中turtle_teleop_key的终端窗口以确保按键输入能够被捕获。

在ROS Hydro及更新版本中,当按下向上键时,应该看到以下内容:

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

在ROS Groovy及早期版本中,当按下向上键时,应该看到以下内容:

---
linear: 2.0
angular: 0.0
---
linear: 2.0
angular: 0.0
---
linear: 2.0
angular: 0.0
---
linear: 2.0
angular: 0.0
---
linear: 2.0
angular: 0.0

现在让我们再看一下rqt_graph。先按下左上角的刷新按钮以显示新节点。正如你所看到的,rostopic echo(这里以红色显示)现在也订阅turtle1/command_velocity话题。

ROS/Tutorials/UnderstandingTopics/rqt_graph_echo.png

使用rostopic list

rostopic list能够列出当前已被订阅和发布的所有话题。

让我们查看一下list子命令需要的参数。打开一个终端:

$ rostopic list -h
  • Usage: rostopic list [/topic]
    
    Options:
      -h, --help            show this help message and exit
      -b BAGFILE, --bag=BAGFILE
                            list topics in .bag file
      -v, --verbose         list full details about each topic
      -p                    list only publishers
      -s                    list only subscribers

rostopic list中使用verbose选项:

$ rostopic list -v

会列出所有发布和订阅的主题及其类型的详细信息。

在ROS Hydro及更新版本中,

  • Published topics:
     * /turtle1/color_sensor [turtlesim/Color] 1 publisher
     * /turtle1/cmd_vel [geometry_msgs/Twist] 1 publisher
     * /rosout [rosgraph_msgs/Log] 2 publishers
     * /rosout_agg [rosgraph_msgs/Log] 1 publisher
     * /turtle1/pose [turtlesim/Pose] 1 publisher
    
    Subscribed topics:
     * /turtle1/cmd_vel [geometry_msgs/Twist] 1 subscriber
     * /rosout [rosgraph_msgs/Log] 1 subscriber

在ROS Groovy及早期版本中,

  • Published topics:
     * /turtle1/color_sensor [turtlesim/Color] 1 publisher
     * /turtle1/command_velocity [turtlesim/Velocity] 1 publisher
     * /rosout [roslib/Log] 2 publishers
     * /rosout_agg [roslib/Log] 1 publisher
     * /turtle1/pose [turtlesim/Pose] 1 publisher
    
    Subscribed topics:
     * /turtle1/command_velocity [turtlesim/Velocity] 1 subscriber
     * /rosout [roslib/Log] 1 subscriber

ROS消息

话题的通信是通过节点间发送ROS消息实现的。为了使发布者(turtle_teleop_key)和订阅者(turtulesim_node)进行通信,发布者和订阅者必须发送和接收相同类型的消息。这意味着话题的类型是由发布在它上面消息的类型决定的。使用rostopic type命令可以查看发布在话题上的消息的类型

使用rostopic type

rostopic type命令用来查看所发布话题的消息类型。

用法:

rostopic type [topic]

在ROS Hydro及更新版本中,

  • 运行:
    $ rostopic type /turtle1/cmd_vel
    • 你会看到:
      geometry_msgs/Twist

    我们可以使用rosmsg查看消息的详细信息:

    $ rosmsg show geometry_msgs/Twist
    • geometry_msgs/Vector3 linear
        float64 x
        float64 y
        float64 z
      geometry_msgs/Vector3 angular
        float64 x
        float64 y
        float64 z

在ROS Groovy及早期版本中,

  • 运行:
    $ rostopic type /turtle1/command_velocity
    • 你会看到:
      turtlesim/Velocity

    我们可以使用rosmsg查看消息的详细信息:

    $ rosmsg show turtlesim/Velocity
    • float32 linear
      float32 angular

现在我们已经知道了turtlesim节点想要的消息类型,然后就可以发布命令给turtle了。

继续学习rostopic

既然我们已经了解了ROS消息,接下来我们结合消息来使用rostopic

使用rostopic pub

rostopic pub可以把数据发布到当前某个正在广播的话题上。

用法:

rostopic pub [topic] [msg_type] [args]

在ROS Hydro及更新版本中,示例:

$ rostopic pub -1 /turtle1/cmd_vel geometry_msgs/Twist -- '[2.0, 0.0, 0.0]' '[0.0, 0.0, 1.8]'

在ROS Groovy及早期版本中,示例:

$ rostopic pub -1 /turtle1/command_velocity turtlesim/Velocity  -- 2.0  1.8

以上命令会发送一条消息给turtlesim,告诉它以2.0大小的线速度和1.8大小的角速度移动。

  • ROS/Tutorials/UnderstandingTopics/turtle(rostopicpub).png

这是一个十分复杂的例子,因此让我们来详细分析一下其中的每一个参数。

在ROS Hydro及更新版本中,

  • 这条命令将消息发布到指定的话题:

    rostopic pub
  • 这一选项会让rostopic只发布一条消息,然后退出:

     -1 
  • 这是要发布到的话题的名称:

    /turtle1/cmd_vel
  • 这是发布到话题时要使用的消息的类型:

    geometry_msgs/Twist
  • 这一选项(两个破折号)用来告诉选项解析器,表明之后的参数都不是选项。如果参数前有破折号(-)比如负数,那么这是必需的。

    --
  • 如前所述,一个turtlesim/Velocity消息有两个浮点型元素:linearangular。在本例中,'[2.0, 0.0, 0.0]'表示linear的值为x=2.0, y=0.0, z=0.0,而'[0.0, 0.0, 1.8]'是说angular的值为x=0.0, y=0.0, z=1.8。这些参数实际上使用的是YAML语法,在YAML命令行文档中有描述。

    '[2.0, 0.0, 0.0]' '[0.0, 0.0, 1.8]' 

在ROS Groovy及早期版本中,

  • 这条命令将消息发布到指定的话题:

    rostopic pub
  • 这一选项会让rostopic只发布一条消息,然后退出:

     -1 
  • 这是要发布到的话题的名称:

    /turtle1/command_velocity
  • 这是发布到话题时要使用的消息的类型:

    turtlesim/Velocity
  • 这一选项(两个破折号)用来告诉选项解析器,表明之后的参数都不是选项。如果参数前有破折号(-)比如负数,那么这是必需的。

    --
  • 如前所述,一个turtlesim/Velocity消息有两个浮点型元素:linearangular。在本例中,2.0linear的值,而1.8则是angular的值。这些参数实际上使用的是YAML语法,在YAML命令行文档中有描述。

    2.0 1.8 

你可能已经注意到turtle已经停止移动了。这是因为turtle需要一个稳定的频率为1Hz的指令流才能保持移动状态。我们可以使用rostopic pub -r命令来发布源源不断的命令:

在ROS Hydro及更新版本中,

  • $ rostopic pub /turtle1/cmd_vel geometry_msgs/Twist -r 1 -- '[2.0, 0.0, 0.0]' '[0.0, 0.0, -1.8]'

在ROS Groovy及早期版本中,

  • $ rostopic pub /turtle1/command_velocity turtlesim/Velocity -r 1 -- 2.0  -1.8

这将以1 Hz的速度发布velocity指令到velocity话题上。

  • ROS/Tutorials/UnderstandingTopics/turtle(rostopicpub)2.png

我们还可以看一下rqt_graph中的情形。按左上角的刷新按钮,可以看到rostopic pub节点(此处为红色)正在与rostopic echo节点(此处为绿色)进行通信:

ROS/Tutorials/UnderstandingTopics/rqt_graph_pub.png

可以看到,turtle正沿着一个圆形轨迹持续运动。我们可以在新终端中通过rostopic echo命令来查看turtlesim所发布的数据:

rostopic echo /turtle1/pose

使用rostopic hz

rostopic hz报告数据发布的速率。

用法:

rostopic hz [topic]

我们看一下turtlesim_node发布/turtle/pose得有多快:

$ rostopic hz /turtle1/pose

你会看到:

  • subscribed to [/turtle1/pose]
    average rate: 59.354
            min: 0.005s max: 0.027s std dev: 0.00284s window: 58
    average rate: 59.459
            min: 0.005s max: 0.027s std dev: 0.00271s window: 118
    average rate: 59.539
            min: 0.004s max: 0.030s std dev: 0.00339s window: 177
    average rate: 59.492
            min: 0.004s max: 0.030s std dev: 0.00380s window: 237
    average rate: 59.463
            min: 0.004s max: 0.030s std dev: 0.00380s window: 290

现在我们可以知道了turtlesim正以大约60Hz的频率发布有关乌龟的数据。我们也可以结合rostopic typerosmsg show命令来获取关于某个话题的更深层次信息:

在ROS Hydro及更新版本中,

  • $ rostopic type /turtle1/cmd_vel | rosmsg show

在ROS Groovy及早期版本中,

  • $ rostopic type /turtle1/command_velocity | rosmsg show

到此我们已经使用rostopic调查了这些主题,接下来将使用另一个工具来查看turtlesim发布的数据。

使用rqt_plot

注意:如果你使用的是ROS electric或早期版本,那么rqt是不可用的,请使用rxgraph代替。

rqt_plot命令可以在滚动时间图上显示发布到某个话题上的数据。这里我们将使用rqt_plot命令来绘制正被发布到/turtle1/pose话题上的数据。首先,在一个新终端中输入:

$ rosrun rqt_plot rqt_plot

这会弹出一个新窗口,可以在左上角的文本框里面添加任何想要绘制的话题。在里面输入/turtle1/pose/x后,之前不能按下的加号按钮将会变亮。按一下该按钮,并对/turtle1/pose/y重复相同的过程。现在你会在图中看到turtle的x-y位置。

ROS/Tutorials/UnderstandingTopics/rqt_plot.png

按下减号按钮会显示一组菜单可以让你在图中隐藏指定的话题。现在隐藏掉你刚才添加的话题并添加/turtle1/pose/theta,你会看到如下所示的图:

ROS/Tutorials/UnderstandingTopics/rqt_plot2.png

本部分教程到此为止,请使用Ctrl+C退出rostopic命令,但要保持turtlesim继续运行。

到此我们已经理解了ROS话题是如何工作的,接下来我们开始学习理解ROS服务和参数

Wiki: cn/ROS/Tutorials/UnderstandingTopics (last edited 2020-12-23 04:10:45 by yakamoz423)