ROS2 架构与核心工具
本文是对 ROS2 系统架构及关键软件栈的深度技术笔记。关于 ROS 历史与基本安装,请参阅 仿真平台 中的 ROS 小节。
ROS2 系统架构
通信中间件:DDS
ROS2 的核心设计决策是采用 DDS (Data Distribution Service) 作为通信中间件。DDS 是 OMG 组织制定的实时数据分发标准,具有以下特性:
| 特性 | 说明 |
|---|---|
| 去中心化 | 无需 Master 节点,通过 Simple Discovery Protocol (SDP) 自动发现 |
| QoS 策略 | 可配置可靠性(Reliable/Best-Effort)、持久性(Transient Local/Volatile)、历史深度等 |
| 实时性 | 支持确定性延迟,适用于硬实时场景 |
| 安全性 | DDS-Security 插件支持身份认证、访问控制、数据加密 |
常用 DDS 实现:
| DDS 实现 | 维护方 | 特点 | 推荐场景 |
|---|---|---|---|
| Cyclone DDS | Eclipse 基金会 | ROS2 Humble 默认,稳定 | 通用开发 |
| Fast DDS | eProsima | 功能最全,曾为默认 | 需要完整 DDS 特性 |
| Connext DDS | RTI | 商业版,认证级别高 | 工业/军工部署 |
| Zenoh | Eclipse (实验性) | 非 DDS,但 ROS2 适配中 | 跨网络/云边协同 |
ROS2 节点通信模式
graph TB
subgraph Node_A["节点 A (感知)"]
PA[Publisher<br/>/camera/image]
CA[Client<br/>/detect_object]
end
subgraph Node_B["节点 B (规划)"]
SB[Subscriber<br/>/camera/image]
SRV[Service Server<br/>/detect_object]
AC[Action Client<br/>/navigate_to]
end
subgraph Node_C["节点 C (导航)"]
AS[Action Server<br/>/navigate_to]
PC[Publisher<br/>/cmd_vel]
end
subgraph Node_D["节点 D (底盘)"]
SD[Subscriber<br/>/cmd_vel]
end
PA -- "Topic (异步)" --> SB
CA -- "Service (同步请求-响应)" --> SRV
AC -- "Action (异步+反馈)" --> AS
PC -- "Topic" --> SD
style Node_A fill:#e1f5fe
style Node_B fill:#fff3e0
style Node_C fill:#e8f5e9
style Node_D fill:#fce4ec
四种通信模式详解
1. Topic(话题):异步发布-订阅,一对多
# Publisher
self.pub = self.create_publisher(Twist, '/cmd_vel', 10)
msg = Twist()
msg.linear.x = 0.5
self.pub.publish(msg)
# Subscriber
self.sub = self.create_subscription(Twist, '/cmd_vel', self.callback, 10)
2. Service(服务):同步请求-响应,一对一
# Service Server
self.srv = self.create_service(SetBool, '/enable_motor', self.handle)
# Service Client
self.cli = self.create_client(SetBool, '/enable_motor')
future = self.cli.call_async(request)
3. Action(动作):异步 + 反馈 + 可取消,适用于长时任务
# Action Server
self._action_server = ActionServer(
self, NavigateToPose, 'navigate_to_pose', self.execute_callback)
# 执行回调中发送反馈
feedback_msg.distance_remaining = distance
goal_handle.publish_feedback(feedback_msg)
4. Parameter(参数):动态配置节点参数
ros2 param set /my_node max_speed 1.5
ros2 param get /my_node max_speed
QoS 配置策略
QoS 策略对机器人系统至关重要,错误配置会导致话题无法通信:
| QoS 策略 | 传感器数据推荐 | 控制命令推荐 | 地图数据推荐 |
|---|---|---|---|
| Reliability | Best Effort | Reliable | Reliable |
| Durability | Volatile | Volatile | Transient Local |
| History Depth | 1-5 | 1 | 1 |
| Deadline | 33ms (30Hz) | 10ms (100Hz) | N/A |
关键软件包
ros2_control:硬件抽象层
ros2_control 是 ROS2 的硬件抽象框架,将硬件接口与控制算法解耦。
核心组件:
- Controller Manager:加载/卸载/切换控制器的守护进程
- Hardware Interface:抽象硬件为 Command/State 接口
- Controllers:接收指令、输出控制量
硬件接口类型:
| 接口类型 | 语义 | 示例 |
|---|---|---|
hardware_interface::HI_POSITION |
位置指令 | 关节角度 (rad) |
hardware_interface::HI_VELOCITY |
速度指令 | 关节角速度 (rad/s) |
hardware_interface::HI_EFFORT |
力/力矩指令 | 关节力矩 (Nm) |
常用控制器:
controller_manager:
ros__parameters:
update_rate: 500 # Hz
joint_state_broadcaster:
type: joint_state_broadcaster/JointStateBroadcaster
arm_controller:
type: joint_trajectory_controller/JointTrajectoryController
gripper_controller:
type: position_controllers/GripperActionController
自定义 Hardware Interface 示例:
class MyRobotHardware : public hardware_interface::SystemInterface {
CallbackReturn on_activate(const rclcpp_lifecycle::State &) override {
// 初始化串口/CAN 通信
serial_port_.open("/dev/ttyUSB0", 115200);
return CallbackReturn::SUCCESS;
}
hardware_interface::return_type read(
const rclcpp::Time &, const rclcpp::Duration &) override {
// 从编码器读取关节状态
for (size_t i = 0; i < num_joints_; i++) {
hw_states_position_[i] = serial_port_.read_encoder(i);
hw_states_velocity_[i] = serial_port_.read_velocity(i);
}
return hardware_interface::return_type::OK;
}
hardware_interface::return_type write(
const rclcpp::Time &, const rclcpp::Duration &) override {
// 向电机发送指令
for (size_t i = 0; i < num_joints_; i++) {
serial_port_.send_command(i, hw_commands_position_[i]);
}
return hardware_interface::return_type::OK;
}
};
MoveIt 2:运动规划框架
MoveIt 2 是 ROS2 最主流的机械臂运动规划框架,提供从路径规划到轨迹执行的完整流程。
核心模块:
| 模块 | 功能 | 关键算法 |
|---|---|---|
| Motion Planning | 路径规划 | OMPL (RRT, PRM, BIT*), Pilz Industrial Planner |
| Kinematics | 正/逆运动学 | KDL, TRAC-IK, IKFast (解析解) |
| Collision Checking | 碰撞检测 | FCL (Flexible Collision Library) |
| Servo | 实时笛卡尔控制 | 增量式 IK,支持手柄/键盘 |
| MoveIt Task Constructor | 多阶段任务 | 级联规划子任务 |
OMPL 规划器选择指南:
| 规划器 | 特点 | 适用场景 |
|---|---|---|
| RRTConnect | 双向 RRT,速度快 | 通用场景(默认) |
| RRT* | 渐近最优 | 需要高质量路径 |
| PRM* | 预建路线图 | 重复规划同一空间 |
| BIT* | 批量采样最优 | 高维空间最优规划 |
| CHOMP | 基于优化 | 平滑轨迹 |
MoveIt Servo 适合遥操作和视觉伺服场景,以 100-1000Hz 频率接收增量指令:
# 发送笛卡尔增量指令
twist_msg = TwistStamped()
twist_msg.header.frame_id = "tool0"
twist_msg.twist.linear.x = 0.01 # 10mm/cycle
twist_msg.twist.angular.z = 0.05 # rad/cycle
servo_twist_pub.publish(twist_msg)
更多运动规划理论请参阅 运动规划。
Nav2:自主导航栈
Nav2 是 ROS2 的导航框架,主要用于移动机器人的自主导航。
架构层次:
| 层次 | 组件 | 功能 |
|---|---|---|
| 感知 | Costmap 2D | 多层代价地图(静态层、障碍物层、膨胀层) |
| 全局规划 | Planner Server | 生成全局路径 |
| 局部控制 | Controller Server | 跟踪路径、避障 |
| 行为 | Behavior Server | 异常恢复(旋转、后退、等待) |
| 导航管理 | BT Navigator | 行为树协调整个导航流程 |
全局规划器对比:
| 规划器 | 算法 | 特点 | 适用场景 |
|---|---|---|---|
| NavFn | Dijkstra/A* | 经典,稳定 | 通用导航 |
| SMAC 2D | A* 变体 | 支持更多启发式 | 二维地图导航 |
| SMAC Hybrid-A* | Hybrid A* | 考虑运动学约束 | 阿克曼转向车辆 |
| SMAC Lattice | 状态格子 | 自定义运动原语 | 非标准运动模型 |
| Theta* | Theta* | 任意角度路径 | 需要平滑路径 |
局部控制器对比:
| 控制器 | 算法 | 特点 | 适用场景 |
|---|---|---|---|
| DWB | Dynamic Window | 经典,稳定 | 差速/全向移动底盘 |
| RPP | Regulated Pure Pursuit | 曲率调节 | 室外/高速场景 |
| MPPI | Model Predictive Path Integral | GPU 加速、可学习代价 | 复杂地形、需要最优控制 |
| Rotation Shim | 原地旋转预处理 | 搭配其他控制器使用 | 窄通道启动 |
# Nav2 参数配置示例
controller_server:
ros__parameters:
controller_frequency: 20.0
FollowPath:
plugin: "dwb_core::DWBLocalPlanner"
max_vel_x: 0.5
max_vel_theta: 1.0
critics: ["RotateToGoal", "Oscillation", "ObstacleFootprint", "PathAlign", "PathDist", "GoalDist"]
更多 SLAM 相关内容请参阅 SLAM。
Micro-ROS:嵌入式 ROS2
Micro-ROS 将 ROS2 通信能力带到微控制器(MCU)级别,基于 micro-XRCE-DDS 实现。
支持的硬件平台:
| 平台 | 芯片示例 | RTOS | 特点 |
|---|---|---|---|
| ESP32 | ESP32-S3 | FreeRTOS | 低成本,WiFi 内置 |
| STM32 | STM32F4/F7/H7 | FreeRTOS/Zephyr | 工业级,丰富外设 |
| Teensy | Teensy 4.1 (Cortex-M7) | FreeRTOS | 高性能,Arduino 兼容 |
| Raspberry Pi Pico | RP2040 | FreeRTOS | 超低成本 |
典型应用:将 IMU、编码器、电机驱动器直接作为 ROS2 节点参与通信。
// Micro-ROS on ESP32: 发布 IMU 数据
rcl_publisher_t imu_publisher;
sensor_msgs__msg__Imu imu_msg;
void timer_callback(rcl_timer_t * timer, int64_t last_call_time) {
read_mpu6050(&imu_msg);
rcl_publish(&imu_publisher, &imu_msg, NULL);
}
Agent 模式:MCU 通过串口/WiFi/USB 连接到运行在主机上的 micro-ROS Agent,Agent 将数据桥接到完整 DDS 网络。
# 启动 micro-ROS Agent
ros2 run micro_ros_agent micro_ros_agent serial --dev /dev/ttyUSB0 -b 115200
常用 CLI 工具
# 节点管理
ros2 node list
ros2 node info /my_node
# 话题调试
ros2 topic list
ros2 topic echo /cmd_vel
ros2 topic hz /camera/image_raw # 查看发布频率
ros2 topic bw /pointcloud # 查看带宽
# 服务调用
ros2 service call /set_mode std_srvs/srv/SetBool "{data: true}"
# Action 监控
ros2 action list
ros2 action send_goal /navigate_to_pose nav2_msgs/action/NavigateToPose "{...}"
# TF 调试
ros2 run tf2_tools view_frames # 生成 TF 树 PDF
ros2 run tf2_ros tf2_echo base_link camera_link
# Launch 文件
ros2 launch my_package my_launch.py
# 录制回放
ros2 bag record -a -o my_bag
ros2 bag play my_bag
开发最佳实践
- 使用 Launch 文件管理节点:避免手动逐个启动
- 善用 QoS 配置:传感器用 Best Effort,控制指令用 Reliable
- Lifecycle 节点:用 managed node 控制节点生命周期(unconfigured -> inactive -> active)
- Composition:将多个节点加载到同一进程,减少序列化开销
- 使用 colcon 构建:
colcon build --symlink-install支持 Python 热更新
相关资源
- ROS2 官方文档
- ros2_control 文档
- MoveIt 2 文档
- Nav2 文档
- 相关笔记:运动规划 | SLAM | 开发工具链