ROS学习笔记#基础篇#(三)——ROS通信机制

目录

  • 一、计算图级
    • 1.1 关键概念
    • 1.2 理解节点(Node)
  • 二、通信方式
    • 2.1 话题(Topic)
      • 2.1.1 话题的概念
      • 2.1.2 话题的消息文件(.msg)
      • 2.1.3 话题的示例
    • 2.2 服务(Service)
      • 2.2.1 服务的概念
      • 2.2.2 服务的消息文件(.srv)
      • 2.2.3 服务的示例
    • 2.3 动作(Action)
      • 2.3.1 动作的概念
      • 2.3.2 动作的消息文件(.action)
    • 2.4 参数(Parameter)
      • 2.4.1 参数的概念
      • 2.4.2 参数的示例
  • 三、总结

一、计算图级

1.1 关键概念

计算图是ROS处理数据的一种点对点的网络形式。程序运行时,所有进程以及他们所进行的数据处理,将会通过一种点对点的网络形式表现出来,包括以下几个重要概念:

  • 节点Node
    一个节点其实只不过是ROS程序包中的一个可执行文件,ROS节点之间可以通过多种通信机制进行通信。
  • 主节点Master
    主节点负责管理节点到节点的连接和消息通信,故亦可称“节点管理器”,通过roscore命令即可启动。
  • 话题Topic
    话题(亦可称为“主题”)是一种单向通信方式。
  • 服务Service
    服务是一种 请求Request响应Response式 的双向通信方式。
  • 动作Action
    动作是一种 目标Goal结果Result反馈Feedback式 的双向通信方式。
  • 消息Message
    消息是节点之间通信的数据结构
  • Bag
    用户可以保存ROS中发送和接收的消息的数据,这时用于保存的文件以*.bag作为文件扩展名。

1.2 理解节点(Node)

先了解一下节点Node操作命令rosnode的用法:

命令 说明
rosnode ping test connectivity to node
rosnode list list active nodes
rosnode info print information about node
rosnode machine list nodes running on a particular machine or list machines
rosnode kill kill a running node
rosnode cleanup purge registration information of unreachable nodes

一个节点其实只不过是ROS程序包中的一个可执行文件,ROS节点可以使用ROS客户端库(rospyroscpp等)与其他节点通信,可以发送或接收消息Message

首先你已经根据 搭建ROS开发环境教程 创建catkin工作空间,并启动ROS:

$ roscore

再新开一个终端,并使用rosnode list查看当前存在的节点Node

$ rosnode list
/rosout

可见此时仅存在1个节点rosoutrosout节点用于收集和记录节点调试输出信息,所以它总是在运行的。

启动Turtle例程:

$ rosrun turtlesim turtlesim_node
$ rosrun turtlesim turtle_teleop_key
注意:执行以上命令均需新开一个终端并配置ROS环境变量

使用rosnode list查看当前存在的节点Node

$ rosnode list
/rosout         # rosout节点用于收集和记录节点调试输出信息,所以它总是在运行的
/teleop_turtle  # turtle_teleop_key的节点
/turtlesim      # turtlesim_node的节点

也可以借助可视化工具rqt_graph便于直观理解:

$ rqt_graph

Hide一栏不勾选debug
ROS学习笔记#基础篇#(三)——ROS通信机制_第1张图片
上图中椭圆框即为节点Node,节点之间的箭头说明它们之间存在通信,箭头上的备注即为话题Topic

二、通信方式

ROS使用的通信方式包括 话题Topic服务Service动作Action,此外,某种意义上 参数Parameter 也可认为是一种通信方式。下面将对这4种通信方式进行详细介绍:

2.1 话题(Topic)

先了解一下话题Topic操作命令rostopic的用法:

命令 说明
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

以下内容参考 ROS官方教程 | 理解ROS话题。

2.1.1 话题的概念

话题Topic是一种单向通信方式, 其中发布消息的节点称为发布者Topic-Publisher,而接收消息的节点称为订阅者Topic-Subscriber

Node_A Master Node_B 注册 Topic-Publisher 注册 Topic-Subscriber 周期发布消息 Message loop [ 自定义频率 ] Node_A Master Node_B

如上图所示,节点A和节点B分别到主节点Master注册为Topic-PublisherTopic-Subscriber。在主节点master的管理下,节点A发布Topic,节点B订阅该Topic,实现节点A到节点B的单向通信。

2.1.2 话题的消息文件(.msg)

msg文件是用于话题的消息文件,扩展名为*.msg。相关操作命令为rosmsg:

命令 说明
rosmsg show Show message description
rosmsg info Alias for rosmsg show
rosmsg list List all messages
rosmsg md5 Display message md5sum
rosmsg package List messages in a package
rosmsg packages List packages that contain messages

msg文件是最简单的消息文件,只需定义Topic-PublisherTopic-Subscriber的消息的数据结构,以下文的geometry_msgs/Twist为例:

$ 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

2.1.3 话题的示例

继续1.2节的内容,使用rqt_graph可视化工具,将鼠标放到箭头上会有高亮显示:
ROS学习笔记#基础篇#(三)——ROS通信机制_第2张图片
可知turtle1为主节点Master/turtle1/cmd_vel为话题Topic,其中/teleop_turtle为发布者Topic-Publisher/turtlesim为订阅者Topic-Subscriber。我们也可以使用rostopic来进行操作:

  • 查看当前存在的Topic
$ rostopic list
/rosout
/rosout_agg
/statistics
/turtle1/cmd_vel
/turtle1/color_sensor
/turtle1/pose
  • 查看话题/turtle1/cmd_vel的具体信息:
$ rostopic info /turtle1/cmd_vel 
Type: geometry_msgs/Twist

Publishers: 
 * /teleop_turtle (http://ubuntu:35093/)

Subscribers: 
 * /turtlesim (http://ubuntu:35745/)
  • 查看话题/turtle1/cmd_vel的消息类型:
$ rostopic type /turtle1/cmd_vel
geometry_msgs/Twist

查看该消息类型msg的详细定义:

$ 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
  • 查看话题/turtle1/cmd_vel发布的消息:
$ rostopic echo /turtle1/cmd_vel

此时需要选中运行turtle_teleop_key终端,按下方向键,rostopic终端会输出/teleop_turtle发布的消息,类似如下内容:

linear: 
  x: 2.0
  y: 0.0
  z: 0.0
angular: 
  x: 0.0
  y: 0.0
  z: 0.0
  • 向节点/turtlesim发布消息:

发送1条消息便退出:

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

按照固定的频率发布消息:

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

可以看到ROS小乌龟进行圆周运动:
ROS学习笔记#基础篇#(三)——ROS通信机制_第3张图片

2.2 服务(Service)

先了解一下话题Service操作命令rosservice的用法:

命令 说明
rosservice args print service arguments
rosservice call call the service with the provided args
rosservice find find services by service type
rosservice info print information about service
rosservice list list active services
rosservice type print service type
rosservice uri print service ROSRPC uri

以下内容参考 ROS官方教程 | 理解ROS服务和参数。

2.2.1 服务的概念

服务通信是双向的,它不仅可以发送消息,同时还会有反馈。一个服务Service被分成服务端Service-Server客户端Service-Client,其中服务端只在有请求Request的时候才响应Response,而客户端会在发送请求后接收响应,这样通过类似“请求-应答”的机制完成整个服务通信。

与话题Topic不同,服务Service一次性消息通信。因此,当服务的请求和响应完成时,两个连接的节点将被断开。服务Service通常被用作请求机器人执行特定操作时使用的命令,或者用于根据特定条件需要产生事件的节点。由于它是一次性的通信方式,又因为它在网络上的负载很小,所以它也被用作代替话题的手段,因此是一种非常有用的通信手段。

Node_A Master Node_B 注册 Service-Server 注册 Service-Client 服务请求消息 Request 服务响应消息 Response Node_A Master Node_B

如上图所示,节点A和节点B分别到主节点Master注册为服务的服务端Service-Server和客户端Service-Client。在主节点Master的管理下,节点B(客户端)向节点A(服务端)发送请求,节点A响应该请求,实现节点之间的双向通信。

2.2.2 服务的消息文件(.srv)

srv文件是服务使用的消息文件,扩展名为*.srv。相关操作命令为rossrv:

命令 说明
rossrv show Show service description
rossrv info Alias for rossrv show
rossrv list List all services
rossrv md5 Display service md5sum
rossrv package List services in a package
rossrv packages List packages that contain services

由于服务是双向的,所以需定义请求响应两个部分,以下文的turtlesim/Spawn为例:

$ rossrv show turtlesim/Spawn
float32 x
float32 y
float32 theta
string name     # 服务的客户端请求的数据结构
---             ---
string name     # 服务的服务端响应的数据结构

请求响应的数据结构用---分隔。

2.2.3 服务的示例

继续2.1.3节的内容,使用rosservice list查看当前存在的Service

$ rosservice list
/clear
/kill
/reset
/rosout/get_loggers
/rosout/set_logger_level
/rqt_gui_py_node_22277/get_loggers
/rqt_gui_py_node_22277/set_logger_level
/spawn
/teleop_turtle/get_loggers
/teleop_turtle/set_logger_level
/turtle1/set_pen
/turtle1/teleport_absolute
/turtle1/teleport_relative
/turtlesim/get_loggers
/turtlesim/set_logger_level

可见当前存在多个Service,下面以clear, spawn这2个服务示例:

使用rosservice type查看clear的消息Message类型:

$ rosservice type clear
std_srvs/Empty

可见该服务的类型为空(Empty),这表明在调用这个服务是不需要参数(比如,请求不需要发送数据,响应也没有数据)。下面我们使用rosservice call命令调用服务,因为服务类型是空,所以进行无参数调用:

$ rosservice call clear

便清除了turtlesim_node的背景上的轨迹
ROS学习笔记#基础篇#(三)——ROS通信机制_第4张图片
再来使用rosservice type查看spawn的消息类型srv

$ rosservice type spawn
turtlesim/Spawn
$ rossrv show turtlesim/Spawn
float32 x
float32 y
float32 theta
string name     # 服务的客户端请求的数据参数
---             ---
string name     # 服务的服务端响应的数据参数

这个服务使得我们可以在给定的位置和角度生成一只新的乌龟。名字参数是可选的,这里我们不设具体的名字,让turtlesim自动创建一个。

$ rosservice call spawn 2 2 0.2 ""
name: "turtle2"

可见服务返回了新产生的乌龟的名字为turtle2,如下图:
ROS学习笔记#基础篇#(三)——ROS通信机制_第5张图片

2.3 动作(Action)

以下内容参考 ROS官方Wiki | actionlib。

2.3.1 动作的概念

与服务Service非常相似,动作Action具有与请求和响应分别对应的目标Goal结果Result,除此之外动作中还多了反馈Feedback。如下图:

Node_A Master Node_B 注册 Action-Server 注册 Action-Client 目标 Goal 结果 Result 反馈 Feedback Node_A Master Node_B

Action本质上是基于Topic的扩展,目标Goal、结果Result、反馈Feedback是通过Topic接口实现的。主要弥补了Service通信的一个不足,如果Service的请求迟迟得不到响应,将会导致消息阻塞。而Action可以查看状态进度,也可以终止请求,所以适合用于长时间的任务。

2.3.2 动作的消息文件(.action)

action消息文件是动作中使用的消息文件,它使用*.action扩展名,与msgsrv不同,它不是一个比较常见的消息文件,也没有专有的命令行操作。下文以Fibonacci.action 为例:

$ roscd actionlib_tutorials
$ cat action/Fibonacci.action
#goal definition
int32 order
---
#result definition
int32[] sequence
---
#feedback
int32[] sequence

目标结果反馈的数据结构用---分隔。

2.4 参数(Parameter)

先了解一下参数Parameter操作命令rosparam的用法:

命令 说明
rosparam set set parameter
rosparam get get parameter
rosparam load load parameters from file
rosparam dump dump parameters to file
rosparam delete delete parameter
rosparam list list parameter names

注:rosparam使用YAML标记语言的语法。

2.4.1 参数的概念

与上文提到的通信方式不同,参数也可以说是特殊的“通信方式”。特殊点在于参数服务器是节点存储参数的地方,可以认为参数Parameter是节点中使用的全局变量。参数服务器使用网络传输,在节点管理器Master中运行,实现整个通信过程。

Node_A Parameter Server 参数 Parameter 参数 Parameter Node_A Parameter Server

2.4.2 参数的示例

继续2.2.3节的内容,使用rosparam list查看当前存在的Parameter

$ rosparam list 
/background_b
/background_g
/background_r
/rosdistro
/roslaunch/uris/host_ubuntu__35757
/rosversion
/run_id

获取与设置参数:

$ rosparam get / #获取所有参数
background_b: 255
background_g: 86
background_r: 69
#其它省略...
$ rosparam get /background_r #获取特定参数
69
$ rosparam set background_r 150 #设置背景色中Red值为150
$ rosservice call clear         #调用清除服务使得修改后的参数生效

如下图,背景色发生了变化:
ROS学习笔记#基础篇#(三)——ROS通信机制_第6张图片

三、总结

ROS存在多种通信方式,总结如下:

类型 方向 同/异步 备注 使用场景
话题Topic 单向 异步 连续单向地发送/接收数据 实时性、周期性的消息
服务Service 双向 同步 请求Request – 响应Response 临时而非周期性的消息,应避免消息阻塞
动作Action 双向 异步 目标Goal – 结果Result – 反馈Feedback 长时间的任务,解决服务Service消息阻塞的问题
参数Parameter 双向 异步 可以认为Parameter是节点中使用的全局变量 配置文件

如下图:
ROS学习笔记#基础篇#(三)——ROS通信机制_第7张图片


ROS学习资源推荐:
[1] ROS Wiki
[2] ROS Robot Programming (EN) / ROS机器人编程 (CN)
[3] 机器人操作系统入门(MOOC课程)
[4] 古月居博客 推荐阅读ROS探索总结专栏


记录学习所得,如有错误,欢迎指正。
如有侵权,联系删除。

你可能感兴趣的:(ROS学习笔记)