作者:Sam (甄峰) sam_code@hotmail.com
这里介绍几个ROS基本概念。
1. 节点(Node)
节点是ROS中最重要的概念之一。每个ROS运行实例被称为节点。
换句话说,每个ROS程序运行的进程,就是一个节点。每个机器人程序,可以有非常多个节点。
我们也可以运行同一个程序的多个副本(但要确保每个副本使用不同节点名),则每个副本都被当作一个独立节点。
节点(Node)可以用来提供某种数据或能力,比如读取某Sensor数据。也可以是一个获取这些数据并处理的节点(Node), 例如从别的节点那拿到Sensor并处理。但他们之间如何知道对方存在与否呢?哪些node需要哪种数据呢?这就需要有个管理者,它就是Node Master/ Node Core。
每个Node启动时,需要向它注册,申明自己提供什么服务或需要什么数据。
为何说Node是ROS核心,看看它通常被用来做什么:
控制电机速度,获取激光雷达数据,获取Camera数据,利用以上数据定位,路径规划。
启动一个Node:
#rosrun package-name executable-name
两个参数,参数1:功能包名。 参数2:可执行文件名。(后面会谈到功能包)
查看当前有哪些Node:
#rosnode list
停止一个Node:
#rosnode kill node-name
虽然也可以ctrl-c停止,但此时Node master 可能会没有及时注销此node. 造成误会。(当然这种情况可以:rosnode cleanup)
2. 节点管理器(Node Master/ Node Core)
为了每个独立的节点(Node)能够彼此通讯,ROS中有ROS节点管理器存在。
它用来保存节点的话题与服务的注册信息和查找表。
ROS Node在启动时连接到ROSCore上,如果ROSCore被终止,哪怕再次启动。ROS Node也不会自动重新连接。
启动roscore:
#roscore.
举例说明:
开三个终端,依次启动 roscore, turtle_teleop_key, turtlesim_node.
#roscore
#rosrun turtlesim turtlesim_node
#rosrun turtlesim turtle_teleop_key
首先启动roscore.
接着启动turtlesim功能包内的两个程序。
功能包turtlesim中的turtle_teleop_key程序接收Keyboard信号,发送消息给turtlesim_node,以控制小乌龟移动。
#rosnode list
则可以看到三个node,他们名字分别为:
/rosout
/teleop_turtle
/turtlesim
可以看到,节点名与可执行程序名并不一定相同。
3. 关于Node名,应用程序名的思考:
前面提到,Node就是一个进程,是一个应用程序的执行实例。
应用程序名,则是编译时指出编译结果是何种文件名。
Node名,可以理解为进程名。而同一时刻,正在运行的Node,名字不能重复。(应该类似PID不能重复)
但我们可能需要同一个应用程序运行多次,形成多个Node。该如何处理呢? 只需要在启动Node时,指定不同应用程序名即可。
#rosrun package-name executable-name __name:=Node-name
所以上面启动小乌龟的程序,就可以启动两次小乌龟如下:
#roscore
#rosrun turtlesim turtlesim_node __name:=tur1
#rosrun turtlesim turtlesim_node __name:=tur2
#rosrun turtlesim turtle_teleop_key
用键盘可以控制两个小乌龟运动。
#rosnode list
可以看到,两个乌龟程序node名分别为:tur1, tur2.
4. ROS Message:
Node之间,是通过Message来传递消息的。
Node之间通过Message通讯。每个Message就是一个数据结构。geonetry_msgs/Twist.msg.
5. ROS Topic(主题):
ROS Node之间通讯方式主要依靠的就是主题(Topic)和服务两种(服务后面再讲)。Message就是放在Topic中。
Message传递的的理念:
当一个节点想要分享信息时,它就会发布(publish)消息到对应的一个或多个Topic(主题);当一个节点想要接收消息时,它就会订阅(Subscribe)它所需要的一个或多个Topic。
ROS Master负责确保发布Node和订阅Node能找到对方。而Message是直接从发布Node传递到订阅Node. 并不需要经过Node Master。
A:消息以一种publish/subscribe的方式传递。
B:节点可以在给定的主题中发布/订阅消息。
C:一个节点可以订阅/发布多个不同主题。
D:允许多个Node订阅/发布同一个主题。
E:订阅节点和发布节点并不知道相互之间的存在。
Message注册和订阅过程:
Talker这个Node,启动后注册了一个Topic,名为bar, 并告知Node Master,接收端口为:1234。
Listener这个Node启动后订阅了一个Topic,名为bar.
Node Master告知Listener,主题的端口为1234。
Listener去连接1234端口,Talker监听到有人连接。就告知对方,数据接口是2345。
于是两个Node就连通起来了。
同一个时刻,只有一个Node Master。所以可以共享数据。
6. ROS Service (ROS服务)
ROS服务与Topic不同。
A:它是一种Request/reply的方式传递。
B:节点之间发送请iu和接受应答。
C:一对一模式,一个请求,一个响应。
7. 功能包/软件包 (Packages)
功能包适ROS中组织软件的主要形式,可以编写代码并编译,执行。一个功能包一般包含程序文件,库文件,编译描述文件,配置文件,脚本等。
它是一组用于实现特定功能的相关文件集合。每个功能包由一个清单文件(package.xml)定义。
功能包相关命令:
#rospack list :列出所有功能包。
#rospack find package-name : 寻找功能包
8. 功能包集(stack)
从Groovy版本开始,功能包集的概念被逐步淘汰,取而代之的是元功能包(metapackages)
9. 功能包的安装:
一些功能包已经被加入仓库中了。所以可以使用apt-get install来安装之。
例如:
sudo apt-get install ros-hydro-ros-tutorials