ROS学习笔记系列是对 ROS中文教程的记录总结。
笔记三包括:
- 3.1 ROS节点
- 3.2 ROS话题
3.1 ROS 节点
3.1.1 ROS图的概念
其实图、节点的概念来自图论,只不过这里是更具体的对象。一个图如下,V1,V2等就是节点 (node),它们可以是实际的机器人,或者可执行文件,也可以是函数,在不同情况下可以有不同的抽象。
有了节点,关键的是要相互通信。不过,在ROS中,通信并不是像上图中那样相邻的相互传递信息,因为这样很慢,比如V4给V5要发一条消息,为什么要经过其他节点呢?而且,V4要给其他所有节点发消息,按照上图的箭头走也太麻烦了。
实际上采用的方法是,V4把消息发布 (publish) 在一个服务器上(或者云端),其他节点也从这个服务器订阅 (subscribe) 消息,这样消息就能够并行地快速地传输。发布的过程也叫做广播 (broadcast) ,这个服务器的提供了谈论话题 (topic) 的场所。还记得以前有“话题作文”吗?这里话题的意思大同小异。
看一下看官方解释,还有其他专有名词:
- Nodes: 节点,一个节点即为一个可执行文件,它可以通过ROS与其它节点进行通信。
- Messages: 消息,消息是一种ROS数据类型,用于订阅或发布到一个话题。
- Topics: 话题,节点可以发布消息到话题,也可以订阅话题以接收消息。
- Master : 节点管理器,ROS名称服务(比如帮助节点找到彼此)。
- rosout: ROS中相当于标准输出stdout/stderr。rosout是一个节点(可执行文件),可以订阅、发布消息。
- roscore: 主机+ rosout + 参数服务器 (参数服务器会在后面介绍)。
3.1.2 查看ROS节点
首先在一个终端运行 roscore
,这句指令让将我们的电脑连接到一个服务器,这样节点发布的话题才有地方放。注意此时要联网。
$ roscore
然后打开另一个终端,(千万不要把上一个终端 kill 了,不然就和服务器断开了!),输入 rosnode list
,查看当前有哪些节点;输入 rosnode info [节点名]
可以查看节点信息。
$ rosnode list
$ rosnode info /rosout
可见当前有 /rosout 节点,这个节点是连接服务器后默认产生的,用来订阅、发布消息,还提供收集节点信息等服务 (service) 。
3.1.3 增加ROS节点
ROS 服务器只执行 /rosout 一个程序有点无聊,别忘了我们的最终目的——使用ROS完成对我们的机器人的控制与通信。不过先脚踏实地,继续学习节点的内容,我们就先增加节点吧。
$ rosrun [package_name] [node_name]
语句是运行节点的语句,我们运行服务器端已有的一个节点(随时想起,一个节点就是一个可执行文件)。
$ rosrun turtlesim turtlesim_node
不出意外的话会出现一只可爱的小乌龟。此时再输入
$ rosnode list
就会发现多了一个节点-- turtlesim_node,如下图。
3.2 ROS话题
3.2.1 控制小海龟运动
刚才已经说过ROS 话题 的意义,就是提供了一个存放消息的池子,节点可以往里面发布消息,也可订阅消息。下面我们将继续上面的内容,使用键盘上下左右键控制小海龟的运动。
如果您接着 3.1 ROS节点学习 ,可不必运行前两句,否则,在三个不同终端运行以下三句。
$ roscore # 运行一个新的终端
$ rosrun turtlesim turtlesim_node # 运行小海龟节点
$ rosrun turtlesim turtles_teleop_key # 运行按键远程控制节点
然后使用上下左右键控制小海龟运动,运行效果如下(记得将鼠标放在rosrun turtlesim turtles_teleop_key
这一个终端哦)
3.2.2 小海龟运动的分析
其实,整个控制逻辑是很好理解的。运行两个节点之后,服务器上相当于运行着两个程序,一个在读取键盘状态并输出速度信息(前进后退或转向),另一个在监听速度信息并控制小海龟运动,所有速度信息的抽象就是话题 。
用ROS的行话来说:
turtlesim_node节点和turtle_teleop_key节点之间是通过一个ROS话题来互相通信的。turtle_teleop_key在一个话题上发布按键输入消息,而turtlesim则订阅该话题以接收该消息
我们不妨做一些可视化来看一下。
首先是 rqt_graph
命令。如果您还没有安装此命令,请执行
$ sudo apt-get install ros-kinetic-rqt
$ sudo apt-get install ros-kinetic-rqt-common-plugins
然后在一个新的终端运行
$ rosrun rqt_graph rqt_graph
一切正常的话能够得到下图,椭圆内的是节点,箭头代表消息流向,箭头上放着的就是话题。
3.2.3 rostopic 指令
rostopic 子指令 | 功能 |
---|---|
rostopic -h | 查看帮助 |
rostopic bw | 显示话题使用的带宽 |
rostopic echo [topic] | 打印信息到屏幕 |
rostopic hz [topic] | 显示话题的发布速率 |
rostopic list [-h等] | 打印正在运行的话题的信息 |
rostopic pub [topic] [msg_type] [args] | 发布数据到节点 |
rostopic type [topic] | 打印话题类型 |
- 我们在新的终端执行
$ rostopic echo turtle1/cmd_vel
也就是上面节点于话题那张图上的话题,然后回到按键控制终端,按下按键,新的终端就会输出小海龟的要转动的角度和前进的距离。
刚刚数据的输出是怎样实现的呢?其实很简单,相当于添加了一个新的节点,它监听速度信息然后在命令窗口输出。刷新(左上角)节点图,可见新增了一个新的节点。
- 在终端执行
$ rostopic list -h
$ rostopic list -v
可见,rostopic list -h
为帮助指令,rostopic list -v
的功能是列出每个话题的具体信息,运行如下:
- 在终端执行
$ rostopic type /turtle1/cmd_vel
$ rosmsg show geometry_msgs/Twist
可见 rostpic type [话题]
列出了话题的类型,相当于列出C++中的类,rosmsg 更加具体地查看类中变量的类型。
- 在终端输入
$ rostopic pub -1 /turtle1/cmd_vel geometry_msgs/Twist -- '[2.0, 0.0, 0.0]' '[0.0, 0.0, 1.8]'
这条语句执行后,小海龟逆时针运动一段距离。语句颇长,我们慢慢解析
rostopic pub
说明将会发布消息到特定话题
-l
(单个破折号)rostopic 发布一条消息后立即退出
turtle/cmd_vel
消息所发布的话题名称
geometry_msg/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]'
此时更新节点图,发现多了新的节点,这个节点就是刚刚我们执行的这条语句产生的。
- 在终端输入
$ rostopic hz /turtle1/pose
可查看话题发布消息的速率,运行如下,可见话题发布的速率平均为62Hz左右,具体的最短间隔,最长间隔,时间均方根和总次数等。
- 在终端输入
$ rosrun rqt_plot rqt_plot
可以绘图,查看变量的波形图,如下。可见小海龟的 (x, y) 位置随时间的变化。
小结一下
ROS的节点是什么意思呢,什么又叫话题?它们关键的指令分别为roscode 和 rostopic ,如何具体使用呢?想想小海龟如何运动,我们看过的图行是使用哪些指令实现的?深度思考,不会就继续思考或者往回看。