理解了节点怎样运行,以及怎样查看节点的信息,现在来看看节点之间是怎样实现互相通信的。
首先还是先打开命令终端运行roscore,这是一切开始的前提:
roscore
接着我们试着运行乌龟节点(turtlesim_node),记住要在新的命令终端运行:
rosrun turtlesim turtlesim_node
此时有一个小乌龟出现:
接着在新的终端再运行另外一个节点:
rosrun turtlesim turtle_teleop_key
这个节点我们可以翻译成“乌龟键盘控制节点”,此节点开启之后,我们就可以使用键盘来控制小乌龟的运动了。控制时注意,请选中turtle_teleop_key所在的终端窗口以确保我们的按键输入能够被捕获:
但是这两个节点之间究竟做了什么不为人知的事情?
答案是两个节点之间存在主题(或话题)的发布和订阅关系,即turtlesim_node节点和turtle_teleop_key节点之间是通过一个ROS主题来互相通信的,也就是说如果一个节点要向另一个节点发送数据,就要向某个ROS主题发布消息,另一个节点再订阅这个ROS主题,以此接收消息。
那这个主题是什么呢?这里可以先使用ROS的一个程序来显示节点和主题之间的关系图,程序是:rqt_graph,它是rqt程序包中的一部分,如果没有安装它,可以使用下面的命令安装:
sudo apt-get install ros-indigo-rqt
注:这里的indigo可以替换为其他ROS版本。
装完之后,我们新开一个命令终端,运行它:
rosrun rqt_graph rqt_graph
此时我们可以看到两个节点和一个主题之间的关系图:
没错,上面两个节点(turtlesim_node节点和turtle_teleop_key节点)就是通过/turtle1/cmd_vel这个主题进行互相通信的。如果我们是用ROS Hydro之前的版本,这个主题就是/turtle1/command_velocity。
那这个主题里面的信息都有什么,结构是怎么样的……没问题,我们可以使用一个命令工具进行查询:rostopic。
比如我们想查询刚才联系两个节点的主题/turtle1/cmd_vel的内部信息和结构,那么使用以下命令:
rostopic info /turtle1/cmd_vel
这时我们会发现显示了这个主题的消息类型、发布者和订阅者有关的信息,如图:
当然我们可以显示“乌龟键盘控制节点”turtle_teleop_key在这个主题/turtle1/cmd_vel上发布的消息数据,查看的格式是:
rostopic echo topic_name
例如:打开新的终端,输入:
rostopic echo /turtle1/cmd_vel
这时我们就可以按键盘的上下左右键来查看了,当然前提是已经运行了节点turtle_teleop_key:
rosrun turtlesim turtle_teleop_key
并且处于活动的窗口也是这个turtle_teleop_key所在的终端窗口,以确保我们的按键输入能够被捕获:
在turtle_teleop_key所在的终端窗口按了上下左右键之后,/turtle1/cmd_vel所在终端窗口可能出现下面显示内容:
注:ROS版本不同显示内容不同,ROS Hydro之前的版本显示的内容为:
---
linear: 2.0
angular: 0.0
---
linear: 2.0
angular: 0.0
---
综上所述,我们对ROS主题这一概念有一个比较清晰的认识了,概括的说就是:
两个节点之间通过主题进行通信,主题的发布和订阅对象都是节点(通过rosnode info查看一个运行的节点,我们会发现节点信息里包含它发布的主题和订阅的主题)。主题可以比喻成一个有自己名字的中间商,节点要向外发送数据、发出信息,就必须通过这个中间商,其他节点再来这个中间商这里获取消息。但是两个节点之间不是直接连接的关系,中间商这里存储有很多节点的消息,要获取什么消息由消息的类型来确定,这种关系叫相互解耦,节点之间无需知晓对方的存在。由此也可以看出,发布者和订阅者(比如上面所说的两个节点)要找哪个主题进行通信,是根据它们之间的消息类型确定的,这里的两个节点的消息类型是geometry_msgs/Twist,可以翻译成“几何类型消息”,这也可以理解,因为小乌龟要运动,两节点之间传递的当然是这类几何类型的消息。在节点的那一篇博客也说道,在ROS里,节点指的是程序进程,由此也看出ROS进程之间的通信机制——发布订阅同类主题消息。比如我要完成“开车”这个动作,多个进程之间传递的消息类型就会是类似于“汽车驾驶控制要做的动作”这样的类型。
用上面的“乌龟节点”和“键盘控制乌龟节点”例子来解释就是:
turtle_teleop_key(键盘控制乌龟节点/teleop_turtle):发布者;
turtlesim_node(乌龟节点/turtlesim):订阅者;
/turtle1/cmd_vel:主题(中间商)。
此时如果我们用命令:rostopic info /turtle1/cmd_vel,去查这个主题的内容的话,我们会发现里面确实有上面两个节点的名字,分别在发布者和订阅者项里。geometry_msgs/Twist指消息的类型,即节点要发送的消息的类型,这也意味着主题的类型是由发布在它上面的消息类型决定的。
当然,该主题不止包含有上面两个节点的名字,还有其他节点的名字,因为这个主题的发布者和订阅者可以很多(从名字后面的s可以看出它的发布者和订阅者是复数形式),所以可以看到还有其他节点(/rostopic_3790……)也订阅了这个主题。
到此,主题基本的概念理解告一段落。主题命令工具rostopic的其余参数选项的使用,会在以后继续深入了解。
如有说得不准确的地方欢迎各位指正。