为什么使用 ROS 2 ?
ROS 时间线
颜色加深的为 LTS (长期支持版本),只推荐使用这些版本。
ROS Noetic 是 ROS 1 的最终版本。未来的 ROS 版本将全部基于 ROS 2。
ROS 发展
ROS 2 是在 ROS 1 不完善且发现了很多已知不可修复的问题而从底层全面重新开发的新一代机器人操作系统。ROS 2 是从零开始开发的全新的 ROS。教育和科研用 ROS 1 完全可行(目前学术界还是偏爱 ROS 1,大量优秀开源工作都是基于 ROS 1 实现的,但基于 ROS 2 的项目也开始崭露头角)。ROS 2 的目标之一是使其与工业应用兼容。
以⾃动驾驶为代表的新的机器⼈应⽤场景对于中间层和开发框架在实时性、可靠性、伸缩性、跨平台可移植等⽅⾯提出了⼤量新的需求,ROS 1 由于设计上的先天性缺陷不能满⾜这些需求,ROS 2 因此产⽣。在经历了近些年的快速迭代后,ROS 2 ⽬前已经相对完备和稳定,对于我们开发者⽽⾔, 是时候拥抱 ROS 2 了 。
ROS 2 VS ROS 1
1. 平台依赖
1.1 平台
ROS1 只在 ubuntu 进行 CI 测试,但 ROS 社区的中也做了对其他 linux 发行版的支持。ROS2 目前正在 Ubuntu、Mac OS 以及 Windows 上进行 CI 测试和支持。
1.2 语言 (重要⭐)
C++
ROS1 的核心是瞄准 C++03,并且在其 API 中不使用 C++11 功能。ROS2 广泛使用 C++11,并部分使用 C++14。将来,ROS2 会开始使用 C++17。
Python
ROS1 的目标版本是 Python 2 。ROS2 至少需要 Python 3.5。
1.3 中间件 (重要⭐)
ROS1 使用自定义序列化格式、自定义传输协议以及自定义中央发现机制。
ROS2 具有抽象的中间件接口,通过该接口提供序列化、传输和发现。目前,此接口的所有实现都基于 DDS 标准。这使得 ROS2 能够提供各种优质的 QoS 服务策略,从而改善不同网络的通信。
1.4 网络化 (重要⭐)
当创建多机 ROS2 应用程序时,不必将一台机器定义为"主机"。每台机器都将是独立的,能够独立启动,相互连接和断开连接,设置比 ROS1 少。同一局域网下,各台机器之间共享 ROS 通信数据。(比 ROS1 强太多了!!!)
2. 编译系统
2.1 支持 CMake 和其他编译系统
每个 ROS 包其实都是一个 CMake 项目。在 ROS2 中,支持其他编译系统。目前已经支持了 Python 包。
2.2 Python 包
在 ROS1 中, 只用到了一小部分 setup.py 的功能,因为 setup.py 文件是通过 CMake 进行处理的。
在 ROS2 中,Python 类型的功能包可以使用 setup.py 的所有功能,例如输入点,可以使用 python3 setup.py install 进行安装。
2.3 环境设置
在 ROS1 中,编译工具生成必须来自脚本,以便在能够在 build 功能包之前设置环境。
在 ROS2 中,环境设置被分为功能包脚本和工作目录脚本。每个包都提供必要的脚本,使其在 build 之后可以运行。编译工具仅调用工作目录特定脚本,然后调用功能包特定脚本。
2.4 独立编译 (重要⭐)
在 ROS1 中,多个包使用同一个 CMake 编译。虽然加快了编译速度,但每个包都需要确保正确定义交叉包目标依赖性。
在 ROS2 中,仅支持独立的编译,即每个包都是单独编译的。安装目录可以独立或合并。
2.5 install 目录 (重要⭐)
在 ROS1 中,编译完一个包是不需要安装到 install 目录的。将源码和 devel 目录相结合使用。但是每个包都必须支持 devel 目录才行。
在 ROS2 中,在编译功能包后必须安装功能包(install)才能使用。
ROS1 之所以有 devel 目录是方便开发人员能 够修改文件,比如 Pythn 代码和 launch 文件,想让用户修改完代码后不用编译就能使得修改生效。在 ROS2 中使用 symlinks 替代了这个功能,即 colcon build --symlink-install
。
3. 消息与服务
3.1 参数
参数的概念完全改变。ROS2 已经没有全局参数了。每个参数都特定于节点。
节点声明并管理自己的参数,当节点被杀死时,这些参数被销毁。
3.2 消息定义中的可选默认值
在 ROS2 中,消息中的原始值现在可以具有默认值,当消息编译时设置。
3.3 服务 (重要⭐)
在 ROS1 中,服务是同步的。当服务客户端向服务器请求时,它会被卡住,直到服务器响应(或失败)。
在 ROS2 中,服务是异步的。呼叫服务时,可以添加回调功能,当服务器响应时将触发该功能。在此期间,主线程不会卡住。
当然,如果愿意,也可以同步使用服务。
3.4 统一 duration 和 time 的类型
在 ROS1 中,客户端库中定义了 duration 和 time 的类型。数据结构的成员名称在 C++(sec, nsec)和 Python (secs, nsecs)中有所不同。
在 ROS2 中,这些类型被定义为消息,因此跨语言一致。
3.5 从 header 消息中删除序号字段
该字段已弃用很长时间,在 ROS1 中大家基本上都不赋值的。
4. 客户端库
4.1 Topic 命名空间
目前 ROS2 不支持 Topic 名称中的命名目录。这主要是由于 DDS Topic 名称中有字符的限制。设计文档描述了将来应如何添加此内容。
4.2 通知 Notifications
在 ROS1 中,有关 ROS graph 的所有信息必须从 Master 节点获取。在 ROS2 中使用广播的方式取代,例如,某个参数发生了改变,则会发出通知。
4.3 具有生命周期的组件 (重要⭐)
在 ROS1 中,每个节点通常都有其自己的功能。在 ROS2 中,建议将具有相同生命周期的组件中分到一组。
4.4 线程模式 (重要⭐)
在 ROS1 中,开发人员只能在单线程执行或多线程执行之间进行选择。在 ROS2 中,C++(例如跨多个节点)中提供了更精细的执行模型,自定义执行器可以轻松实现。
4.5 ROS Graph
在 ROS1 节点中,Topic 只能在启动时重新映射 remap。在 ROS2 中,可以在运行时进行话题的重映射和别名。
4.6 一个进程里允许有多个节点 (重要⭐)
在 ROS1 中,不可能在进程中创建多个节点。这是由于 API 本身,也因为内部的逻辑所决定的。但在 ROS2 中,可以在进程中创建多个节点。
5. ROS Launch (重要⭐)
在 ROS1 launch 启动文件中,XML 的定义功能非常有限。在 ROS2 launch 文件中,使用 Python 编写,从而能够使用更复杂的逻辑(如条件等)。
ROS 1 --> ROS 2
ROS1 和 ROS2 之间的核心概念及主要实现方式相似。
但是 但是 但是
如果已经在 ROS1 中为一个或多个机器人建立了工程库,或者对于一个拥有数十个开发人员的完整组织,则切换到 ROS2 可能代表大量工作。
ROS1 至 ROS2 的迁移也是我们需要了解和掌握的工作。