计算图是ROS处理数据的一种点对点的网络形式。程序运行时,所有进程以及他们所进行的数据处理,将会通过一种点对点的网络形式表现出来,包括以下几个重要概念:
Node
)Master
)roscore
命令即可启动。Topic
)Service
)Request
– 响应Response
式 的双向通信方式。Action
)Goal
– 结果Result
– 反馈Feedback
式 的双向通信方式。Message
)Bag
)*.bag
作为文件扩展名。先了解一下节点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客户端库(rospy
、roscpp
等)与其他节点通信,可以发送或接收消息Message
。
首先你已经根据 搭建ROS开发环境教程 创建catkin
工作空间,并启动ROS:
$ roscore
再新开一个终端,并使用rosnode list
查看当前存在的节点Node
:
$ rosnode list
/rosout
可见此时仅存在1个节点rosout
,rosout
节点用于收集和记录节点调试输出信息,所以它总是在运行的。
启动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
:
上图中椭圆框即为节点Node
,节点之间的箭头说明它们之间存在通信,箭头上的备注即为话题Topic
。
ROS使用的通信方式包括 话题Topic
、服务Service
、动作Action
,此外,某种意义上 参数Parameter
也可认为是一种通信方式。下面将对这4种通信方式进行详细介绍:
先了解一下话题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话题。
话题Topic
是一种单向通信方式, 其中发布消息的节点称为发布者Topic-Publisher
,而接收消息的节点称为订阅者Topic-Subscriber
。
如上图所示,节点A和节点B分别到主节点Master
注册为Topic-Publisher
和Topic-Subscriber
。在主节点master的管理下,节点A发布Topic
,节点B订阅该Topic
,实现节点A到节点B的单向通信。
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-Publisher
到Topic-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
继续1.2节的内容,使用rqt_graph
可视化工具,将鼠标放到箭头上会有高亮显示:
可知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]'
先了解一下话题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服务和参数。
服务通信是双向的,它不仅可以发送消息,同时还会有反馈。一个服务Service
被分成服务端Service-Server
和客户端Service-Client
,其中服务端只在有请求Request
的时候才响应Response
,而客户端会在发送请求后接收响应,这样通过类似“请求-应答”的机制完成整个服务通信。
与话题Topic
不同,服务Service
是一次性消息通信。因此,当服务的请求和响应完成时,两个连接的节点将被断开。服务Service
通常被用作请求机器人执行特定操作时使用的命令,或者用于根据特定条件需要产生事件的节点。由于它是一次性的通信方式,又因为它在网络上的负载很小,所以它也被用作代替话题的手段,因此是一种非常有用的通信手段。
如上图所示,节点A和节点B分别到主节点Master
注册为服务的服务端Service-Server
和客户端Service-Client
。在主节点Master
的管理下,节点B(客户端)向节点A(服务端)发送请求,节点A响应该请求,实现节点之间的双向通信。
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.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的背景上的轨迹
再来使用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"
以下内容参考 ROS官方Wiki | actionlib。
与服务Service
非常相似,动作Action
具有与请求和响应分别对应的目标Goal
和结果Result
,除此之外动作中还多了反馈Feedback
。如下图:
Action
本质上是基于Topic
的扩展,目标Goal
、结果Result
、反馈Feedback
是通过Topic
接口实现的。主要弥补了Service
通信的一个不足,如果Service
的请求迟迟得不到响应,将会导致消息阻塞。而Action
可以查看状态进度,也可以终止请求,所以适合用于长时间的任务。
action
消息文件是动作中使用的消息文件,它使用*.action
扩展名,与msg
和srv
不同,它不是一个比较常见的消息文件,也没有专有的命令行操作。下文以Fibonacci.action
为例:
$ roscd actionlib_tutorials
$ cat action/Fibonacci.action
#goal definition
int32 order
---
#result definition
int32[] sequence
---
#feedback
int32[] sequence
目标、结果、反馈的数据结构用---
分隔。
先了解一下参数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
标记语言的语法。
与上文提到的通信方式不同,参数也可以说是特殊的“通信方式”。特殊点在于参数服务器是节点存储参数的地方,可以认为参数Parameter
是节点中使用的全局变量。参数服务器使用网络传输,在节点管理器Master
中运行,实现整个通信过程。
继续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存在多种通信方式,总结如下:
类型 | 方向 | 同/异步 | 备注 | 使用场景 |
---|---|---|---|---|
话题Topic |
单向 | 异步 | 连续单向地发送/接收数据 | 实时性、周期性的消息 |
服务Service |
双向 | 同步 | 请求Request – 响应Response |
临时而非周期性的消息,应避免消息阻塞 |
动作Action |
双向 | 异步 | 目标Goal – 结果Result – 反馈Feedback |
长时间的任务,解决服务Service 消息阻塞的问题 |
参数Parameter |
双向 | 异步 | 可以认为Parameter 是节点中使用的全局变量 |
配置文件 |
ROS学习资源推荐:
[1] ROS Wiki
[2] ROS Robot Programming (EN) / ROS机器人编程 (CN)
[3] 机器人操作系统入门(MOOC课程)
[4] 古月居博客 推荐阅读ROS探索总结专栏
记录学习所得,如有错误,欢迎指正。
如有侵权,联系删除。