目录
1.ROS的概念
ROS全称:
机器人操作系统(Robot Operating System)
ROS简介:
是一个用于编写机器人软件的灵活框架,它集成了大量的工具、库、协议,提供了类似操作系统所提供的功能,可以极大简化繁杂多样的机器人平台下的复杂任务创建与稳定行为控制。
2.ROS的设计目标
1.提高机器人研发中的软件复用率
2.被设计成为一种分布式结构,使得框架中的每个功能模块都可以被单独设计、编译,并且在运行时以松散耦合的方式结合在一起。
3.ROS主要为机器人开发提供硬件抽象、底层驱动、消息传递、程序管理、应用原型等功能和机制,同时整合了许多第三方工具和库文件,帮助用户快速完成机器人应用的建立、编写和多机整合。
4.ROS中的功能模块都封装于独立的功能包(Package)或元功能包(Meta Package)中,便于在社区中共享和分发。
3.ROS组成
ROS:核心通信机制、开发工具、应用功能和生态系统
4.ROS特点
(1)点对点的设计
在ROS中,每一个进程都以一个节点的形式运行,可以分布于多个不同的主机。节点间的通信消息通过一个带有发布和订阅功能的RPC传输系统,从发布节点传送到接收节点。这种点对点的设计可以分散定位、导航等功能带来的实时计算压力,适应多机器人的协同工作。
(2)多语言支持
目前已经支持Python、C++、Java、Octave和LISP等多种不同的语言,也可以同时使用这些语言完成不同模块的编程。
(3)架构精简、集成度高
ROS框架具有的模块化特点使得每个功能节点可以进行单独编译,并且使用统一的消息接口让模块的移植、复用更加便捷。同时,ROS开源社区中移植、集成了大量已有开源项目中的代码,例如Open SourceComputer VisionLibrary(OpenCV库)、Point CloudLibrary(PCL库)等,开发者可以使用丰富的资源实现机器人应用的快速开发。
(4)组件化工具包丰富
例如3D可视化工具rviz,开发者可以根据ROS定义的接口在其中显示机器人3D模型、周围环境地图、机器人导航路线等信息。此外,ROS中还有消息查看工具、物理仿真环境等组件。
(5)免费并且开源
5.ROS架构设计
1)ROS结构上分为三个层次:OS层、中间层和应用层。
1.OS层
ROS并不是一个传统意义上的操作系统,无法像Windows、Linux一样直接运行在计算机硬件之上,而是需要依托于Linux系统。所以在OS层,我们可以直接使用ROS官方支持度最好的Ubuntu操作系统,也可以使用macOS、Arch、Debian等操作系统。
2.中间层
Linux是一个通用系统,并没有针对机器人开发提供特殊的中间件,所以ROS在中间层做了大量工作,其中最为重要的就是基于TCPROS/UDPROS的通信系统。ROS的通信系统基于TCP/UDP网络,在此之上进行了再次封装,也就是TCPROS/UDPROS。通信系统使用发布/订阅、客户端/服务器等模型,实现多种通信机制的数据传输。
除了TCPROS/UDPROS的通信机制外,ROS还提供一种进程内的通信方法——Nodelet,可以为多进程通信提供一种更优化的数据传输方式,适合对数据传输实时性方面有较高要求的应用。
在通信机制之上,ROS提供了大量机器人开发相关的库,如数据类型定义、坐标变换、运动控制等,可以提供给应用层使用。
3.应用层
在应用层,ROS需要运行一个管理者——Master,负责管理整个系统的正常运行。ROS社区内共享了大量的机器人应用功能包,这些功能包内的模块以节点为单位运行,以ROS标准的输入输出作为接口,开发者不需要关注模块的内部实现机制,只需要了解接口规则即可实现复用,极大地提高了开发效率。
2)系统实现的角度分类:计算图、文件系统、开源社区
1.计算图
从计算图的角度来看,ROS系统软件的功能模块以节点为单位独立运行,可以分布于多个相同或不同的主机中,在系统运行时通过端对端的拓扑结构进行连接。
一、节点
节点(Node)就是一些执行运算任务的进程,一个系统一般由多个节点组成,也可以称为“软件模块”。节点概念的引入使得基于ROS的系统在运行时更加形象:当许多节点同时运行时,可以很方便地将端对端的通信绘制成如图所示的节点关系图,在这个图中进程就是图中的节点,而端对端的连接关系就是节点之间的连线
二、消息
节点之间最重要的通信机制就是基于发布/订阅模型的消息(Message)通信。每一个消息都是一种严格的数据结构,支持标准数据类型(整型、浮点型、布尔型等),也支持嵌套结构和数组(类似于C语言的结构体struct),还可以根据需求由开发者自主定义。
三、话题
消息以一种发布/订阅(Publish/Subscribe)的方式传递(见图)。一个节点可以针对一个给定的话题(Topic)发布消息(称为发布者/Talker),也可以关注某个话题并订阅特定类型的数据(称为订阅者/Listener)。发布者和订阅者并不了解彼此的存在,系统中可能同时有多个节点发布或者订阅同一个话题的消息。
四、服务
虽然基于话题的发布/订阅模型是一种很灵活的通信模式,但是对于双向的同步传输模式并不适合。在ROS中,我们称这种同步传输模式为服务(Service),其基于客户端/服务器(Client/Server)模型,包含两个部分的通信数据类型:一个用于请求,另一个用于应答,类似于Web服务器。与话题不同的是,ROS中只允许有一个节点提供指定命名的服务。
五、节点管理器
为了统筹管理以上概念,系统当中需要有一个控制器使得所有节点有条不紊地执行,这就是ROS节点管理器(ROS Master)。ROSMaster通过远程过程调用(RPC)提供登记列表和对其他计算图表的查找功能,帮助ROS节点之间相互查找、建立连接,同时还为系统提供参数服务器,管理全局参数。ROS Master就是一个管理者,没有它的话,节点将无法找到彼此,也无法交换消息或调用服务,整个系统将会瘫痪。
2.文件系统
类似于操作系统,ROS将所有文件按照一定的规则进行组织,不同功能的文件被放置在不同的文件夹下,如图所示。
1)功能包(Package)
功能包是ROS软件中的基本单元,包含ROS节点、库、配置文件等。
2)功能包清单(PackageManifest)
每个功能包都包含一个名为package.xml的功能包清单,用于记录功能包的基本信息,包含作者信息、许可信息、依赖选项、编译标志等。
3)元功能包(MetaPackage)
在新版本的ROS中,将原有功能包集(Stack)的概念升级为“元功能包”,主要作用都是组织多个用于同一目的的功能包。例如一个ROS导航的元功能包中会包含建模、定位、导航等多个功能包。
4)元功能包清单
在图中并未显示,类似于功能包清单,不同之处在于元功能包清单中可能会包含运行时需要依赖的功能包或者声明一些引用的标签。
5)消息(Message)类型
消息是ROS节点之间发布/订阅的通信信息,可以使用ROS提供的消息类型,也可以使用.msg文件在功能包的msg文件夹下自定义所需要的消息类型。
6)服务(Service)类型
服务类型定义了ROS客户端/服务器通信模型下的请求与应答数据类型,可以使用ROS系统提供的服务类型,也可以使用.srv文件在功能包的srv文件夹中进行定义。
7)代码(Code)
用来放置功能包节点源代码的文件夹。
PS
功能包
这些文件夹的主要功能如下。
1)config:放置功能包中的配置文件,由用户创建,文件名可以不同。
2)include:放置功能包中需要用到的头文件。
3)scripts:放置可以直接运行的Python脚本。
4)src:放置需要编译的C++代码。
5)launch:放置功能包中的所有启动文件。
6)msg:放置功能包自定义的消息类型。
7)srv:放置功能包自定义的服务类型。
8)action:放置功能包自定义的动作指令。
9)CMakeLists.txt:编译器编译功能包的规则。
10)package.xml:功能包清单,下图是一个典型的功能包清单示例。
如图为ROS功能包的package.xml文件示例
从功能包清单中可以清晰地看到该功能包的名称、版本号、信息描述、作者信息和许可信息。除此之外,<build_depend></build_depend>标签定义了功能包中代码编译所依赖的其他功能包,而<run_depend></run_depend>标签定义了功能包中可执行程序运行时所依赖的其他功能包。在开发ROS功能包的过程中,这些信息需要根据功能包的具体内容进行修改。
元功能包
元功能包是一种特殊的功能包,只包含一个package.xml元功能包清单文件。它的主要作用是将多个功能包整合成为一个逻辑上独立的功能包,类似于功能包集合的概念。
虽然元功能包清单的package.xml文件与功能包的package.xml文件类似,但是需要包含一个引用的标签如下:
<export>
<metapackage/>
</export>
此外,元功能包清单不需要<build_depend>标签声明编译过程依赖的其他功能包,只需要使用<run_depend>标签声明功能包运行时依赖的其他功能包。
以导航元功能包为例,可以通过以下命令看到该元功能包中package.xml文件的内容,如图2-8所示。
$ roscd navigation
$ gedit package.xml
ROS相关命令
ROS针对功能包的创建、编译、修改、运行设计了一系列命令,表简要列出了这些命令的作用
catkin_create_pkg:创建功能包
rospack:获取功能包的信息
catkin_make:编译工作空间中的功能包
rosdep:自动安装功能包依赖的其他包
roscp:拷贝功能包中的文件
rosrun:运行功能包中的可执行文件
roslaunch:运行启动文件
3.开源社区
ROS开源社区中的资源非常丰富,而且可以通过网络共享以下软件和知识
-
发行版(Distribution):类似于Linux发行版,ROS发行版包括一系列带有版本号、可以直接安装的功能包,这使得ROS的软件管理和安装更加容易,而且可以通过软件集合来维持统一的版本号。
-
软件源(Repository):ROS依赖于共享网络上的开源代码,不同的组织机构可以开发或者共享自己的机器人软件。
-
ROS wiki:记录ROS信息文档的主要论坛。所有人都可以注册、登录该论坛,并且上传自己的开发文档、进行更新、编写教程。
-
邮件列表(Mailing List):ROS邮件列表是交流ROS更新的主要渠道,同时也可以交流ROS开发的各种疑问。
-
ROS Answers:ROS Answers是一个咨询ROS相关问题的网站,用户可以在该网站提交自己的问题并得到其他开发者的回答。
-
博客(Blog):发布ROS社区中的新闻、图片、视频(http://www.ros.org/news)。
6.ROS通讯机制
ROS是一个分布式框架,为用户提供多节点(进程)之间的通信服务,所有软件功能和工具都建立在分布式通信机制上
1)话题通信机制
话题在ROS中使用最为频繁,其通信模型也较为复杂。如图所示,在ROS中有两个节点:一个是发布者Talker,另一个是订阅者Listener。两个节点分别发布、订阅同一个话题,启动顺序没有强制要求,此处假设Talker首先启动,可分成图中所示的七步来分析建立通信的详细过程。
1.Talker注册
Talker启动,通过1234端口使用RPC向ROS Master注册发布者的信息,包含所发布消息的话题名;ROS Master会将节点的注册信息加入注册列表中。
2.Listener注册
Listener启动,同样通过RPC向ROS Master注册订阅者的信息,包含需要订阅的话题名。
3.ROS Master进行信息匹配
Master根据Listener的订阅信息从注册列表中进行查找,如果没有找到匹配的发布者,则等待发布者的加入;如果找到匹配的发布者信息,则通过RPC向Listener发送Talker的RPC地址信息。
4.Listener发送连接请求
Listener接收到Master发回的Talker地址信息,尝试通过RPC向Talker发送连接请求,传输订阅的话题名、消息类型以及通信协议(TCP/UDP)。
5.Talker确认连接请求
Talker接收到Listener发送的连接请求后,继续通过RPC向Listener确认连接信息,其中包含自身的TCP地址信息。
6.Listener尝试与Talker建立网络连接
Listener接收到确认信息后,使用TCP尝试与Talker建立网络连接。
7.Talker向Listener发布数据
成功建立连接后,Talker开始向Listener发送话题消息数据。
PS:
前五个步骤使用的通信协议都是RPC,最后发布数据的过程才使用到TCP。ROS Master在节点建立连接的过程中起到了重要作用,但是并不参与节点之间最终的数据传输。节点建立连接后,可以关掉ROS Master,节点之间的数据传输并不会受到影响,但是其他节点也无法加入这两个节点之间的网络。
2)服务通信机制
服务是一种带有应答的通信机制,通信原理如图所示,与话题的通信相比,其减少了Listener与Talker之间的RPC通信
1.Talker注册
Talker启动,通过1234端口使用RPC向ROS Master注册发布者的信息,包含所提供的服务名;ROS Master会将节点的注册信息加入注册列表中。
2.Listener注册
Listener启动,同样通过RPC向ROS Master注册订阅者的信息,包含需要查找的服务名
3.ROS Master进行信息匹配
Master根据Listener的订阅信息从注册列表中进行查找,如果没有找到匹配的服务提供者,则等待该服务的提供者加入;如果找到匹配的服务提供者信息,则通过RPC向Listener发送Talker的TCP地址信息。
4.Listener与Talker建立网络连接
Listener接收到确认信息后,使用TCP尝试与Talker建立网络连接,并且发送服务的请求数据。
5.Talker向Listener发布服务应答数据
Talker接收到服务请求和参数后,开始执行服务功能,执行完成后,向Listener发送应答数据。
PS:
应答数据
Talker接收到服务请求和参数后,开始执行服务功能,执行完成后,向Listener发送应答数据。
话题和服务的区别!!!
话题是ROS中基于发布/订阅模型的异步通信模式,这种方式将信息的产生和使用双方解耦,常用于不断更新的、含有较少逻辑处理的数据通信;而服务多用于处理ROS中的同步通信,采用客户端/服务器模型,常用于数据量较小但有强逻辑处理的数据交换。
3)参数管理机制
参数类似于ROS中的全局变量,由ROS Master进行管理,其通信机制较为简单,不涉及TCP/UDP的通信,如图所示
1.Talker设置变量
Talker使用RPC向ROSMaster发送参数设置数据,包含参数名和参数值;ROS Master会将参数名和参数值保存到参数列表中。
2.Listener查询参数值
Listener通过RPC向ROSMaster发送参数查找请求,包含所要查找的参数名
3.ROS Master向Listener发送参数值
Master根据Listener的查找请求从参数列表中进行查找,查找到参数后,使用RPC将参数值发送给Listener。
PS:
这里需要注意的是,如果Talker向Master更新参数值,Listener在不重新查询参数值的情况下是无法知晓参数值已经被更新的。所以在很多应用场景中,需要一种动态参数更新的机制