ESC
输入关键词搜索文章标题和内容

ROS2核心概念与架构详解:从零理解新一代机器人操作系统

本文由 linuxROS 整理发布,首发于 linuxros.cn,转载请注明出处。

ROS2核心概念与架构详解:从零理解新一代机器人操作系统

基于Jazzy Jalisco LTS(支持至2029年),从DDS通信底层到上层API,讲解ROS2的架构设计、核心概念与开发环境搭建。适合ROS1老手迁移、ROS零基础入门、以及想理解ROS2设计哲学的开发者。


一、ROS2是什么?

ROS2(Robot Operating System 2)不是传统意义上的操作系统,而是一套分布式机器人软件框架。它运行在Linux/Windows/macOS之上,提供硬件抽象、进程间通信、包管理和常用算法库。

核心设计目标

目标 实现方式
去中心化 无Master节点,基于DDS自发现
实时性 支持实时操作系统和实时调度
安全性 DDS-Security提供认证加密
跨平台 Ubuntu 24.04 / Windows 10 / macOS
多语言 C++17 / Python 3.10+ / Rust

版本说明:Jazzy Jalisco是第10个ROS2发行版,2024年5月发布,LTS支持至2029年5月。推荐搭配Gazebo Harmonic仿真器。前一版Humble Hawksbill(Ubuntu 22.04)仍被广泛使用但逐步退役。


二、ROS2 vs ROS1:为什么要升级?

架构对比

flowchart LR subgraph ROS1["ROS1架构(中心化)"] direction TB M1["Master节点\n(单点故障风险)"] N1["Node A"] N2["Node B"] N1 -->|"注册"| M1 N2 -->|"注册"| M1 N1 <-.->|"TCP/UDP直连"| N2 end ROS1 -.->|"对比"| ROS2 subgraph ROS2["ROS2架构(去中心化)"] direction TB DDS["DDS中间件\n(自发现)"] N3["Node A"] N4["Node B"] N3 <-->|"自动发现+通信"| DDS N4 <-->|"自动发现+通信"| DDS end style ROS1 fill:#FFEBEE,stroke:#D32F2F style ROS2 fill:#E8F5E9,stroke:#388E3C style M1 fill:#FFCDD2 style DDS fill:#C8E6C9

关键差异:

特性 ROS1 ROS2
通信中间件 自研TCP/UDP DDS(工业标准)
发现机制 Master节点(XML-RPC) DDS自发现
参数管理 全局参数服务器 节点本地参数
QoS配置 无 可配置可靠性、持久性、深度
节点生命周期 无 状态机管理(Unconfigured→Active)
安全 无 DDS-Security认证加密
推荐OS Ubuntu 20.04 Ubuntu 24.04
Python版本 Python 2.7/3 Python 3.10+
推荐仿真器 Gazebo Classic Gazebo Harmonic

三、DDS通信层:ROS2的"神经网络"

四层架构

flowchart TB subgraph 用户层["用户应用层"] N1["Node A<br/>(Python)"] N2["Node B<br/>(C++)"] end subgraph RCL["ROS客户端库 (rcl)"] RCL1["rclpy<br/>Python绑定"] RCL2["rclcpp<br/>C++绑定"] RCLC["rcl<br/>C核心库"] end subgraph RMW["ROS中间件接口(rmw)"] FAST["rmw_fastrtps<br/>(默认)"] CYCLONE["rmw_cyclonedds"] end subgraph DDS["DDS实现层"] FAST_DDS["eProsima Fast DDS"] CYCLONE_DDS["Eclipse Cyclone DDS"] end N1 --> RCL1 --> RCLC N2 --> RCL2 --> RCLC RCLC --> RMW RMW --> DDS style 用户层 fill:#E3F2FD,stroke:#1976D2 style RCL fill:#FFF8E1,stroke:#F57C00 style RMW fill:#F3E5F5,stroke:#7B1FA2 style DDS fill:#E8F5E9,stroke:#388E3C

逐层解释:

  1. 用户应用层:开发者编写的ROS2节点,调用rclcpp或rclpy的API
  2. RCL(ROS Client Library):C语言核心库rcl,上层提供rclcpp(C++)和rclpy(Python)绑定
  3. RMW(ROS Middleware):抽象DDS层,通过rmw_fastrtps或rmw_cyclonedds适配不同DDS实现
  4. DDS实现层:Jazzy默认使用eProsima Fast DDS 2.14,也支持Eclipse Cyclone DDS

DDS vs ROS1的核心优势

DDS的自发现机制替代了ROS1的Master节点。节点启动后自动通过DDS协议发现网络中的其他节点和话题,无需中央服务器。这带来了三个关键好处:

  • 无单点故障:任何节点崩溃不影响整体系统
  • 动态加入/离开:机器人运行中可以随时加入新的传感器或计算节点
  • 跨网络通信:不同机器上的ROS2节点通过DDS直接通信
# 查看当前使用的DDS实现
echo $RMW_IMPLEMENTATION
# 默认输出: rmw_fastrtps_cpp

# 切换到Cyclone DDS
export RMW_IMPLEMENTATION=rmw_cyclonedds_cpp

四、五大核心概念

1. 节点(Node)

节点是ROS2的最小执行单元。每个节点是一个独立进程,负责一个具体功能。

# minimal_node.py — 最简ROS2节点
import rclpy
from rclpy.node import Node

class MinimalNode(Node):
    def __init__(self):
        super().__init__('minimal_node')
        self.get_logger().info('ROS2节点已启动!')

def main():
    rclpy.init()
    node = MinimalNode()
    rclpy.spin(node)      # 阻塞等待回调
    node.destroy_node()
    rclpy.shutdown()

if __name__ == '__main__':
    main()

运行命令:

来自 linuxros.cn · linuxROS
# 安装ROS2 (Ubuntu 24.04)
# 详见: https://docs.ros.org/en/jazzy/Installation.html
ros2 run my_package minimal_node

2. 话题(Topic)

话题采用发布-订阅模式,是ROS2中最常用的通信方式,适用于连续数据流。

特性 说明
通信模式 发布者→话题→订阅者
方向性 单向(One-way)
适用场景 传感器数据流、状态广播
典型消息 sensor_msgs/Image、nav_msgs/Odometry
# 发布者示例
self.publisher = self.create_publisher(String, 'chatter', 10)
msg = String()
msg.data = 'Hello ROS2!'
self.publisher.publish(msg)

3. 服务(Service)

服务采用请求-响应模式,适合单次交互。

特性 说明
通信模式 客户端→服务端→响应
方向性 双向(Two-way)
适用场景 参数查询、触发计算
# 服务端示例
self.srv = self.create_service(AddTwoInts, 'add_two_ints', self.callback)

def callback(self, request, response):
    response.sum = request.a + request.b
    return response

4. 动作(Action)

动作是带反馈的异步任务,适合长时间执行的操作。

特性 说明
通信模式 客户端→服务端(目标+反馈+结果)
方向性 双向
特色 可中途取消、实时反馈进度
适用场景 导航到目标点、机械臂运动
# 动作反馈示例
goal_handle.publish_feedback(feedback_msg)    # 发布进度
goal_handle.succeed()                         # 标记完成
result = Fibonacci.Result()
result.sequence = feedback_msg.partial_sequence
return result

5. 参数(Parameter)

参数是节点的运行时配置,支持动态修改,带类型检查和范围约束。

# 声明参数(带范围和描述)
from rcl_interfaces.msg import ParameterDescriptor, IntegerRange

descriptor = ParameterDescriptor(
    description='最大线速度(m/s)',
    integer_range=[IntegerRange(from_value=0, to_value=100, step=1)]
)
self.declare_parameter('max_speed', 50, descriptor)

五大概念对比总览

概念 通信模式 方向 适用场景
话题 发布-订阅 单向 传感器数据流
服务 请求-响应 双向 单次计算/查询
动作 目标-反馈-结果 双向 长时间任务
参数 键值配置 - 运行时配置

五、QoS(服务质量)策略

ROS2对比ROS1的一个关键增强就是QoS策略,可以精细控制数据传输行为。

核心QoS策略

策略 选项 含义
Reliability RELIABLE / BEST_EFFORT 可靠传输 vs 尽力而为
Durability VOLATILE / TRANSIENT_LOCAL 新订阅者能否收到历史消息
History KEEP_LAST / KEEP_ALL 保留最近N条 vs 全部保留
Depth 整数 缓存队列深度
Deadline 时间间隔 消息最大间隔时间

实战配置示例

from rclpy.qos import QoSProfile, ReliabilityPolicy, DurabilityPolicy, HistoryPolicy

# 场景1:传感器数据(允许丢帧,低延迟优先)
sensor_qos = QoSProfile(
    reliability=ReliabilityPolicy.BEST_EFFORT,
    durability=DurabilityPolicy.VOLATILE,
    history=HistoryPolicy.KEEP_LAST,
    depth=5
)

# 场景2:控制指令(不允许丢失)
control_qos = QoSProfile(
    reliability=ReliabilityPolicy.RELIABLE,
    durability=DurabilityPolicy.VOLATILE,
    history=HistoryPolicy.KEEP_LAST,
    depth=10
)

# 场景3:状态数据(晚加入也能获取最新状态)
status_qos = QoSProfile(
    reliability=ReliabilityPolicy.RELIABLE,
    durability=DurabilityPolicy.TRANSIENT_LOCAL,
    history=HistoryPolicy.KEEP_LAST,
    depth=1
)

六、工作空间与文件结构

标准工作空间

ros2_ws/
├── src/                          # 源代码目录
│   ├── my_package/              # Python包
│   │   ├── my_package/          # 代码目录
│   │   │   ├── __init__.py
│   │   │   └── my_node.py
│   │   ├── launch/              # Launch文件
│   │   ├── config/              # 参数YAML
│   │   ├── package.xml          # 包清单
│   │   └── setup.py             # Python安装配置
│   └── my_interfaces/           # 自定义接口包
│       ├── msg/                 # 自定义消息
│       ├── srv/                 # 自定义服务
│       ├── action/              # 自定义动作
│       ├── CMakeLists.txt       # CMake构建
│       └── package.xml
├── build/                        # 编译中间产物
├── install/                      # 安装产物
└── log/                          # 日志

创建和构建

# 创建工作空间
mkdir -p ~/ros2_ws/src
cd ~/ros2_ws

# 创建Python包
ros2 pkg create --build-type ament_python my_package \
  --dependencies rclpy std_msgs

# 创建C++包
ros2 pkg create --build-type ament_cmake my_cpp_package \
  --dependencies rclcpp std_msgs

# 创建接口包(消息/服务/动作)
ros2 pkg create --build-type ament_cmake my_interfaces \
  --dependencies rosidl_default_generators

# 构建
colcon build --symlink-install
source install/setup.bash

七、常用命令行工具速查

# === 节点 ===
ros2 node list                    # 列出所有节点
ros2 node info /node_name         # 查看节点详情

# === 话题 ===
ros2 topic list                   # 列出所有话题
ros2 topic list -t                # 列出话题及类型
ros2 topic echo /topic_name       # 实时查看数据
ros2 topic info /topic_name       # 查看话题信息
ros2 topic hz /topic_name         # 查看发布频率
ros2 topic pub /topic std_msgs/msg/String "data: 'hello'"

# === 服务 ===
ros2 service list                 # 列出所有服务
ros2 service call /add_two_ints example_interfaces/srv/AddTwoInts "{a: 5, b: 3}"

# === 动作 ===
ros2 action list                  # 列出所有动作
ros2 action send_goal /fibonacci action_tutorials_interfaces/action/Fibonacci "{order: 10}"

# === 参数 ===
ros2 param list /node_name        # 列出节点的参数
ros2 param get /node_name param   # 获取参数值
ros2 param set /node_name param value  # 设置参数值

# === 数据记录 ===
ros2 bag record /topic1 /topic2   # 录制话题
ros2 bag play my_bag/             # 回放
ros2 bag info my_bag/             # 查看bag信息

八、Jazzy Jalisco新特性速览

新特性 说明
Gazebo Harmonic 推荐仿真器,通过ros_gz桥接ROS2
ROSBag记录服务 支持录制和回放服务调用
CLI自定义日志 --log-file-name指定日志文件名
服务信息增强 ros2 service info显示已连接客户端数
动作类型查询 ros2 action type /action_name返回类型

九、总结

ROS2的核心设计思路是去中心化+工业级通信。理解DDS架构和五大概念(节点/话题/服务/动作/参数)的关系是掌握ROS2的关键。

你要做的事 用哪个概念
发送传感器数据 话题(Publisher)
请求一次计算 服务(Client→Server)
执行长时间任务(可取消+反馈) 动作(ActionClient)
运行时改配置 参数(Parameter)
管理节点启停 生命周期节点 + Launch

本文首发于linuxros.cn,转载请注明出处。

版权声明

作者linuxROS
协议本作品采用 CC BY-NC-SA 4.0 许可协议:署名-非商业性使用-相同方式共享
关注欢迎关注微信公众号 linuxROS,获取更多机器人 / 嵌入式 / Linux 干货
返回首页