一、ROS介绍

ROS是一个分布式的通信框架,帮助程序进程之间更方便地通信。也就是为了协调一个机器人中的多个部件,或者协调由多个机器人组成的机器人集群,能够让分散的部件实现互相通信。而每个部件都有配套的控制程序,来实现机器人的运动与视听功能等。ROS是一套通信框架而已,机器人中的各种算法和应用程序是用C++Python等常见编程语言进行开发的。

二、ROS性能

ROS的特性:元操作系统、分布式通信机制、松耦合软件框架、丰富的开源功能库等。

(1)元操作系统

ROS是一个机器人领域的元操作系统,它并不是真正意义上的操作系统,其底层的任务调度、编译、设备驱动等还是由它的原生操作系统Ubuntu Linux完成。ROS实际上是运行在Ubuntu Linux上的亚操作系统(软件框架),但提供硬件抽象、函数调用、进程管理这些类似操作系统的功能,也提供用于获取、编译、跨平台的函数和工具。

(2)分布式通信机制

ROS的核心思想就是将机器人的软件功能做成一个个节点,节点之间通过互相发送消息进行沟通。这些节点可以部署在同一台主机上,也可以部署在不同主机上,甚至还可以部署在互联网上。ROS网络通信机制中的主节点(master)负责对网络中各个节点之间的通信过程进行管理调度,同时提供一个用于配置网络中全局参数的服务。

(3)松耦合软件框架

ROS是松耦合软件框架,利用分布式通信机制实现节点间的进程通信。ROS的软件代码以松耦合方式组织,开发过程灵活,管理维护方便。

(4)丰富的开源功能库

ROS具有丰富的开源功能库。ROS是基于BSD(Berkeley Software Distribution,伯克利软件发行)协议的开源软件,允许任何人修改、重用、重发布以及在商业和闭源产品中使用,使用ROS能够快捷地搭建自己的机器人原型。

三、ROS学习资源

官网:www.ros.org

源码:github.com

Wiki:wiki.ros.org

问答:answers.ros.org

四、ROS系统架构

a、计算图视角

节点之间通过消息机制进行通信,这样就组成了一张网状图,也叫计算图,计算图中的节点、话题、服务、动作都要有唯一名称作为标识。

图1 ROS的计算图结构

图1中各节点之间的通信方式

(1)话题通信:节点2与节点3、节点2与节点5、节点4与节点5

(2)服务通信:节点2与节点4

(3)动作通信:节点1与节点2

1、消息

消息是构成计算图的关键,包括消息机制消息类型两部分。消息机制有话题服务动作三种,每种消息机制中传递的数据都具有特定的数据类型(即消息类型),消息类型可分为话题消息类型服务消息类型动作消息类型

2、数据包

ROS中专门用来保存和回放话题中数据的文件,可以将一些难以收集的传感器数据用数据包录制下来,然后反复回放来进行算法性能调试。

  • 数据包(bag)的本质是一个记录器。它像录音笔一样,把ROS系统中正在运行的各个话题(topic)的数据(如图像、雷达扫描数据)实时录制下来,存成一个文件。

  • 当需要使用这些数据时,过程就像播放器按下播放键。ROS工具(如 rosbag play)会严格按照录制时的时间戳,将数据重新“播放”到ROS系统中,就像这些数据是传感器正在实时发出的一样。

3、参数服务器

为整个ROS网络中的节点提供便于修改的参数。参数可以认为是节点中可供外部修改的全局变量,有静态参数动态参数。静态参数一般用于在节点启动时设置节点工作模式;动态参数可以用于在节点运行时动态配置节点或改变节点工作状态,比如电机控制节点里的PID控制参数。

4、节点

基本定义

  • 核心单元: 节点(Node)是ROS中可执行程序的基本单位。

  • 本质形态: 节点就是一个正在运行的可执行程序,在系统层面通常被称为进程。

产生方式

  • 创建与启动: 在ROS功能包中创建的每个可执行程序,当被启动并加载到系统内存中运行时,它就成为了一个ROS节点。

通信机制

  • 核心活动: 节点之间通过收发消息进行通信和协作。

  • 通信方式: 消息的收发机制主要分为三种类型:话题(Topic)、服务(Service)、动作(Action)

设计哲学

  • 设计目标: ROS利用节点将代码和功能进行解耦,从而提高了整个系统的容错性和可维护性。

  • 最佳实践: 在设计节点时,最好让每个节点都具有特定的单一功能,而不是创建一个包罗万象、功能复杂庞大的单一节点。

编程实现

  • C++实现: 如果需要用C++语言编写节点,需要用到ROS提供的roscpp库。

  • Python实现: 如果需要用Python语言编写节点,需要用到ROS提供的rospy库。

5、主节点

负责各个节点之间通信过程的调度管理。因此主节点必须要最先启动,可以通过roscore命令启动。

6、话题

ROS中最常用、最基本的通信方式,它实现了异步通信。

  • 通信模式: 发布/订阅(Publisher/Subscriber)。

  • 通信特点:

    • 单向与异步: 发送方(发布者,Publisher)只管往话题里“扔”数据,不需要等待接收方(订阅者,Subscriber)的回应。接收方也只管接收数据,不向发送方返回信息。

    • N对N通信: 可以有多个发布者向同一个话题发布数据,同时也可以有多个订阅者从同一个话题接收数据。

  • 数据格式: 所有在话题上传输的数据都必须有预定义的消息类型(.msg 文件),例如 std_msgs/Stringsensor_msgs/LaserScan

7、服务

用于处理一次性的、同步的计算任务,它实现了双向通信。

  • 通信模式: 请求/响应(Request/Reply)。

  • 通信特点:

    • 同步与阻塞: 客户端(Client)发送请求后会等待,直到服务器(Server)处理完请求并返回响应后,客户端才继续执行后续代码。

    • 一对一: 一个服务通常由一个服务器提供,可以被多个客户端请求,但每个请求的处理过程是独立的。

  • 数据格式: 必须使用预定义的服务类型(.srv 文件)。一个.srv文件包含两部分:请求(Request)的结构和响应(Response)的结构。

8、动作

服务的增强版,专门用于处理耗时较长、需要周期性反馈且可被抢占(取消)的任务。

  • 通信模式: 目标/结果/反馈(Goal/Result/Feedback)。

  • 通信特点:

    • 异步但带反馈: 客户端发送目标后,可以继续执行自己的任务,不必阻塞等待。服务器在处理过程中会不断发送反馈信息,并在任务完成时发送最终结果。

    • 可抢占: 客户端可以在任务执行过程中发送指令取消任务。

    • 状态监控: 可以监控任务的状态(例如:是否正在执行、是否被取消、是否成功)。

  • 数据格式: 必须使用预定义的动作类型(.action 文件)。它定义了三个部分:目标(Goal)、反馈(Feedback)和结果(Result)。

a、文件系统视角

1、工作空间

一个包含功能包、编译包和编译后可执行文件的文件夹。用户可以根据自己的需要创建多个工作空间,在每个工作空间中开发不同用途的功能包。

图2 ROS的文件系统结构

在图2中,我们创建了一个名为catkin_ws的工作空间,其中包含src、build和devel三个文件夹。

(1)src文件夹:放置各个功能包和配置功能包的CMake配置文件CMakeLists.txt。这里说明一下,由于ROS中的源码采用catkin工具进行编译,而catkin工具又基于CMake技术,所以我们在src源文件空间和各个功能包中都会见到一个CMake配置文件CMakeLists.txt,这个文件起到配置编译的作用。

(2)build文件夹:放置编译CMake和catkin功能包时产生的缓存、配置、中间文件等。

(3)devel文件夹:放置编译好的可执行程序,这些可执行程序是不需要安装就能直接运行的。一旦功能包源码编译和测试通过后,可以将这些编译好的可执行文件直接导出与其他开发人员分享。

2、功能包

ROS中软件组织的基本形式,具有创建ROS程序的最小结构和最少内容,它包含ROS节点源码、脚本、配置文件等。

(1)CMakeLists.txt文件:功能包配置文件,用于编译Cmake功能包编译时的编译配置。

 (2)package.xml文件:功能包清单文件,用xml的标签格式标记该功能包的各类相关信息,比如包的名称、开发者信息、依赖关系等,主要是为了使功能包的安装和分发更容易。

 (3)include/<pkg_name>目录:功能包头文件目录,可以把功能包程序中包含的*.h头文件放在这里。include目录之所以还要加一级路径<pkg_name>是为了更好地区分自己定义的头文件和系统标准头文件,<pkg_name>用实际功能包的名称替代。不过这个文件夹不是必要项,比如有些程序没有头文件。

(4)msg目录:存放非标准话题消息的定义文件。

(5)srv目录:存放非标准服务消息的定义文件。

(6)action目录:存放非标准动作消息的定义文件。

ROS支持用户自定义消息通信过程中使用的消息类型。msg、srv、action中的自定义消息不是必要的,比如程序只使用标准消息类型。

(7)scripts目录:存放Bash、Python等脚本文件,为非必要项。

(8)launch目录:存放节点的启动文件,*.launch文件用于启动一个或多个节点,在含有多个节点的大型项目中很有用,为非必要项。

(9)src目录:存放功能包节点所对应的源代码,一个功能包中可以有多个节点程序来完成不同的功能,每个节点程序都可以单独运行。这里src目录存放的是这些节点程序的源代码,你可以按需创建文件夹和文件来组织源代码,源代码可以用C++、Python等编写。

c、开源社区视角

图3 ROS的开源社区结构

图3展示了 ROS(Robot Operating System,机器人操作系统) 的文件系统组织结构,从宏观到微观清晰地划分了不同层级的概念。图中用不同颜色的方块和包含关系,说明了 repository(仓库)、meta package(元包)和 package(功能包)之间的关系。

1. 核心层级关系

图中有三个主要层级:Repository(仓库)、Meta Package(元包)、Package(功能包)。


2. 详细解读

第一层:Repository(仓库)
  • 解析:

    • 这是代码托管层面的概念(如 GitHub、GitLab 上的仓库)。

    • 一个 Repository 是一个版本控制单元,包含了特定的代码和文件。

    • 一个 Repository 可以只包含一个简单的 Package,也可以包含多个 Packages,甚至包含一个 Meta Package(如图中最左侧的灰色框所示,它包含了蓝色的 Meta Package 和两个绿色的 Package)。

    • 作用: 方便开发者进行版本管理和分发。

第二层:Meta Package(元包)
  • 解析:

    • 元包是一种特殊的功能包。

    • 它本身不包含任何实质性代码(如 C++ 源文件、Python 脚本),也不包含数据。

    • 它的核心作用是指向一组相关的功能包。图中它指向了它下方的两个绿色 Package。

    • 作用: 就像一个“目录”或“分组工具”。当你想安装某个完整的大型功能(如导航)时,只需安装对应的元包,它就会自动把相关的所有依赖包(例如路径规划、定位、地图处理等 Package)一起拉取下来。

第三层:Package(功能包)
  • 解析:

    • 这是 ROS 软件组织的最小单元和构建单元。任何一个 ROS 程序(无论是节点、配置文件还是启动文件)都必须组织成 Package 的形式。

    • 一个 Package 通常包含:package.xml(清单文件)、CMakeLists.txt(编译规则)、代码、启动文件、消息/服务定义等。

    • 作用: 实现具体的机器人功能,如驱动摄像头、处理激光雷达数据、运行 SLAM 算法等。


3. 组合关系分析

  • 包含关系:

    • 一个 Repository 可以包含多个 Packages。

    • 一个 Repository 也可以包含一个 Meta Package,而这个 Meta Package 又包含多个 Packages。

  • 横向对比:

    • 有些仓库结构简单,直接装了几个平级的 Package。

    • 有些仓库结构复杂,通过 Meta Package 对内部的 Package 进行了逻辑分组。

4.ROS 文件系统的逻辑结构:

  • 物理存储/版本控制看 Repository(仓库)。

  • 逻辑分组/依赖管理看 Meta Package(元包)。

  • 实际功能/代码实现看 Package(功能包)。

这种分层设计使得 ROS 在管理大型复杂机器人项目(包含成百上千个功能包)时,依然能保持良好的组织性和可维护性。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐