1. 课程导入
1.1 ROS2的起源:从实验室到工业化的必然演进
ROS(Robot Operating System,机器人操作系统)最初于2007年由斯坦福大学人工智能实验室与Willow Garage公司联合推出。ROS1的设计初衷是为学术研究提供一个灵活、模块化的机器人软件开发框架。它采用分布式计算架构,通过节点(Node)、话题(Topic)、服务(Service)和动作(Action)等机制实现模块间通信,极大降低了机器人系统集成的复杂度。
然而,随着机器人技术从实验室走向真实世界,ROS1的架构性缺陷逐渐暴露:
- 单点故障风险:ROS1依赖中心化的ROS Master进行节点发现与参数管理,一旦Master宕机,整个系统瘫痪。
- 实时性不足:底层基于TCP/UDP的通信机制无法保证硬实时传输,难以满足工业控制、自动驾驶等场景的确定性延迟要求。
- 多机通信脆弱:ROS1的节点间通信缺乏安全认证与加密机制,在多机器人协同或跨网段场景下配置复杂且易出错。
- 生命周期管理缺失:ROS1节点无法优雅地启动、暂停或重启,进程崩溃后难以自动恢复。
2014年,Open Source Robotics Foundation(OSRF)联合各大工业伙伴启动了ROS2项目,目标是从底层重新设计一套适用于生产环境的机器人中间件。ROS2于2017年发布首个正式版Ardent Apalone,此后以每年2个版本的节奏迭代,目前最新的长期支持版本为Humble Hawksbill(2022年发布,支持至2027年)。
1.2 ROS2的设计目标与核心架构原则
ROS2的设计目标可以归纳为以下六个维度,它们共同构成了ROS2区别于ROS1的架构哲学:
| 设计维度 | 具体目标 | 实现手段 |
|---|---|---|
| 实时性 | 支持硬实时与软实时混合调度 | DDS的RTPS协议 + 可配置QoS策略 |
| 可靠性 | 无单点故障,系统可自恢复 | 去中心化发现协议,节点可动态加入/退出 |
| 安全性 | 通信加密、权限认证、审计日志 | DDS-Security规范 + SROS2工具链 |
| 跨平台 | 支持Linux/Windows/macOS/RTOS | 抽象RMW层,适配不同DDS实现 |
| 可裁剪性 | 适应从微控制器到大型计算集群 | 支持仅发布/订阅的轻量模式 |
| 生态兼容 | 尽量复用ROS1工具与库 | 提供ros1_bridge、ros2_control等迁移工具 |
在架构层面,ROS2引入了RMW(ROS Middleware Interface,ROS中间件接口)抽象层。所有上层API(rclcpp/rclpy)通过RMW与具体的DDS实现交互,用户可以在不修改代码的情况下切换底层DDS供应商。这种设计使得ROS2既保持了ROS1的易用性,又获得了工业级中间件的性能与可靠性。
1.3 ROS1与ROS2的核心区别对比
理解ROS1与ROS2的区别,是学习ROS2的第一道门槛。下面从通信架构、编程接口、工具链三个层面进行对比:
1.3.1 通信架构对比
- 节点发现机制:ROS1需要启动roscore(Master)作为中心节点,所有节点启动时向Master注册,并通过Master获取其他节点的地址信息。ROS2则采用DDS的对等发现(Peer-to-Peer Discovery)机制,节点启动后通过组播(默认端口7400)自动发现彼此,无需任何中心节点。
- 数据传输方式:ROS1的Topic通信基于TCPROS(默认)或UDPROS,数据序列化采用自有的CDR格式。ROS2使用RTPS(Real-Time Publish-Subscribe)协议,支持UDP单播/组播、TCP、共享内存等多种传输方式,并允许通过QoS策略控制数据可靠性(RELIABLE vs BEST_EFFORT)和持久性。
- 服务质量(QoS):这是ROS2最具突破性的特性。ROS1中所有通信都是尽力而为(best-effort),无法保证数据不丢失。ROS2允许每个Topic/Service独立设置QoS策略,例如:
reliability(可靠/尽力)、durability(是否保留历史数据给后加入的订阅者)、deadline(最大消息间隔)等。
# ROS1 启动方式(需要Master)
$ roscore
$ rosrun turtlesim turtlesim_node
$ rosrun turtlesim turtle_teleop_key
# ROS2 启动方式(无需Master,直接运行)
$ ros2 run turtlesim turtlesim_node
$ ros2 run turtlesim turtle_teleop_key
1.3.2 编程接口对比
ROS2的客户端库(rclcpp/rclpy)在API设计上尽量保持与ROS1相似,但引入了几个重要变化:
- 节点生命周期:ROS2引入了
rclcpp_lifecycle,节点具有unconfigured → inactive → active → finalized的状态机,支持动态配置和暂停/恢复。 - 参数系统:ROS2参数支持更丰富的数据类型(包括数组、字节、嵌套结构),并可通过
ros2 param命令动态读写。 - 时钟与时间:ROS2使用
rclcpp::Clock抽象,支持系统时间、ROS时间(可模拟)和稳态时间。 - 多线程执行器:ROS2的
Executor支持单线程、多线程和静态单线程三种模式,用户可精细控制回调执行方式。
1.3.3 工具链与命令对比
| 功能 | ROS1命令 | ROS2命令 |
|---|---|---|
| 查看节点列表 | rosnode list |
ros2 node list |
| 查看话题列表 | rostopic list |
ros2 topic list |
| 查看话题内容 | rostopic echo /topic |
ros2 topic echo /topic |
| 查看TF树 | rosrun tf view_frames |
ros2 run tf2_tools view_frames |
| 启动Launch文件 | roslaunch pkg file.launch |
ros2 launch pkg file.launch.py |
| 编译工作空间 | catkin_make |
colcon build |
ros前缀换成ros2,命令结构完全一致。实际上,ROS2的CLI工具采用了动词-名词结构(如ros2 topic echo),且Launch文件从XML格式改为Python格式(.launch.py),支持更复杂的逻辑控制。此外,ROS2中catkin被colcon取代,编译产物默认放在install/目录而非devel/目录。
1.4 学习路径与资源推荐
ROS2的学习曲线比ROS1更陡峭,因为它涉及DDS、QoS、实时系统等底层概念。建议按照以下路径循序渐进:
- 第一阶段:基础概念(1-2周)——掌握节点、话题、服务、动作四大通信原语,熟悉
rclpy或rclcpp的基本用法。 - 第二阶段:工具链与调试(1周)——熟练使用
ros2 topic/service/node/param/launch命令,学会用rqt_graph、PlotJuggler等可视化工具。 - 第三阶段:工程化实践(2-3周)——学习colcon编译、ROS2包结构、Launch文件编写、参数服务器、命名空间与重映射。
- 第四阶段:进阶主题(3-4周)——深入QoS策略、生命周期节点、tf2坐标变换、Nav2导航栈、MoveIt2机械臂控制。
- 第五阶段:项目实战(持续)——从仿真(Gazebo/Webots)迁移到真实机器人,尝试多机协同或与工业设备集成。
推荐学习资源清单
- 官方文档:
docs.ros.org(ROS2文档站,包含Tutorials、Concepts、API参考) - 书籍:《Programming Robots with ROS2》(英文)、《ROS2机器人开发实践》(中文)
- 视频课程:The Construct(
app.theconstructsim.com)提供ROS2交互式仿真课程 - 开源项目:Navigation2(
github.com/ros-navigation)、MoveIt2(moveit.ros.org) - 社区:ROS Discourse论坛(
discourse.ros.org)、中文社区(fishros.com)
turtlesim和demo_nodes_cpp包跑通基本通信流程,再逐步深入底层机制。遇到问题时,善用ros2 doctor检查环境,用ros2 topic info -v查看话题的QoS配置,这些工具能帮你快速定位问题。
1.5 常见误区与复盘
根据多年教学经验,初学者在学习ROS2时最容易陷入以下几个误区:
- 误区一:用ROS1的思维写ROS2代码——例如在ROS2中仍然手动调用
init()后直接创建Publisher,却忽略了ROS2节点的生命周期管理。正确做法是使用rclcpp::Node的共享指针,并让Executor统一管理回调。 - 误区二:忽视QoS配置——当订阅者与发布者的QoS不兼容时,ROS2不会报错,但订阅者会收不到数据。例如发布者设置为
BEST_EFFORT,订阅者设置为RELIABLE,两者无法通信。排查此类问题需使用ros2 topic info -v查看双方QoS。 - 误区三:混淆工作空间概念——ROS2中
src/、build/、install/、log/四个目录各有用途。每次修改代码后必须重新colcon build并source install/setup.bash,否则运行的是旧版本。 - 误区四:忽略DDS实现差异——默认的Fast DDS在局域网内表现良好,但在跨网段或高丢包环境下,可能需要切换为Cyclone DDS或调整发现协议参数。学会通过
RMW_IMPLEMENTATION环境变量切换DDS是进阶必备技能。