Contents — find the section you need

ROS 2 本身并非机器人。它是一个基础架构,用于运行摄像头驱动、自定位、路径规划和电机控制等功能,这些功能以独立程序(节点)的形式运行,并通过标准化的消息传递和通信方式将它们组合起来。您可以在原型阶段使用单个 Python 文件开始开发,并逐步扩展到 C++、实时执行、多台计算机以及产品的安全监控。重要的不是记住 API,而是设计谁拥有数据、时间安排、可靠性以及关机时的安全状态。

图片:Robot Operating System logo,Wikimedia Commons (CC BY-SA 4.0)。该 logo 用于标识中间件,并不保证特定的发行版或 DDS 配置。

30 秒总结

  • 节点是一个只负责一项任务的进程,主题代表一个连续的数据流,服务代表一个简短的请求/响应,而动作则代表一个包含中间反馈的长任务。

  • ROS 2 的通信基于 DDS,每个端点都可以单独选择 QoS(可靠性、历史记录、深度、持久性和截止时间)。传感器和控制器无需使用相同的设置。

  • TF2 管理着一个包含时间坐标系的树状结构。如果混用 map、odom、base_link 和传感器坐标系,即使感知正确,机器人也会行驶到错误的位置。

  • 在实际硬件上,需要添加生命周期管理、看门狗机制、权限分离、日志记录以及网络掉线保护机制。在仿真环境中运行并不能证明安全性。

  • 从一开始就修复 ROS 2 Jazzy 等长期支持版本,并为其匹配 DDS、操作系统和驱动程序组合,从而构建一个可复现的工作空间。

1. ROS 2 概览

Diagram 1 · Use the button to switch views
Camera nodesensor driver /image_rawTopic + QoS Perception nodeperception Control nodecontroller DDS middleware (discovery, comms, QoS)Application layerOS / network / executor

图 1 — 在 ROS 2 中,节点通过 DDS 相互发现和通信。

不仅是主题名称,QoS、类型、时间和坐标系也都被视为合约的一部分。

ROS 2 图可以在运行时配置。相机节点发布图像,感知节点订阅这些图像,控制节点接收结果以及自身定位信息,并发布速度指令。即使将节点移动到不同的计算机,只要 DDS 发现和序列化功能正常工作,该图仍然有效。

2. 选择合适的通信原语

类型 使用场景 示例 设计注意事项
主题 连续流,多对多 /scan , /camera/image QoS、带宽、延迟、丢包
服务 短请求和响应 /reset_odometry 超时、可重入
动作 具有进度的长时间运行任务 导航、抓取 取消、安全中断
参数 启动时或低频配置 增益、帧名称 类型、更改权限、可复现性

主题消息不仅应包含值,还应包含 header.stamp 和 frame_id。如果图像时间戳和 IMU 时间戳不同步,算法仍然可以计算结果,但会错误估计运动。频繁重传相机图像会占用大量带宽,因此应根据每个传感器的特性选择 QoS。

3. QoS 作为“通信契约”

ROS 2 中需要检查的最低 QoS 设置包括:可靠性(尽力而为/可靠)、持久性(易失性/瞬态本地)、历史记录(保留最后/保留所有)、深度、截止时间和活跃度。高速激光雷达可能更适合“尽力而为”(Best Effort)模式,该模式会丢弃过期的数据包;而速度指令对丢包容忍度极低,因此应使用“可靠”(Reliable)模式并设置较短的截止时间。

如果发布者和订阅者的服务质量(QoS)不兼容,即使使用相同的主题名称也无法通信。应使用 ros2 topic info -v /scan 检查实际设置,而不是盲目信任传感器驱动程序的预设值。跨网络通信时,应同时测试最大传输单元(MTU)、Wi-Fi 重传、组播限制和时间同步。

4. TF2 和时间

机器人的位姿表示为坐标系之间的变换。典型的树状结构如下:

map ──(SLAM/Localization)──> odom ──(odometry)──> base_link
                                                        ├── base_laser
                                                        ├── imu_link
                                                        └── camera_link

map 是长期世界坐标系,odom 是平滑的短期里程计坐标系,base_link 是车辆参考坐标系。 SLAM 校正 map → odom,同时车轮/IMU 估计值以高速率更新 odom → base_link。TF2 保存带有时间戳的变换,并将其插值到每个传感器的采集时间。

将坐标系标准化为右手坐标系,并明确区分光学坐标系(z 向前,x 向右,y 向下)和车辆坐标系(x 向前,y 向左,z 向上)。使用 static_transform_publisher 修复静态变换,并且不要将动态变换发布为静态变换。TF 树中的循环或多个父节点是设计错误。

5. 包和实现流程

一个最小的 ROS 2 Python 节点如下所示。

import rclpy
from rclpy.node import Node
from std_msgs.msg import Float32

class Speed(Node):
    def __init__(self):
        super().__init__('speed_node')
        self.pub = self.create_publisher(Float32, '/speed', 10)
        self.timer = self.create_timer(0.02, self.tick)  # 50 Hz
    def tick(self):
        msg = Float32(); msg.data = 0.2
        self.pub.publish(msg)

rclpy.init(); node = Speed(); rclpy.spin(node)

在实际硬件上,不要直接向电机发送速度指令——应在两者之间添加上游节点、限速器、紧急停止装置和硬件监控。即使使用 C++ 的 rclcpp,也应检查回调组、执行器、内存分配和实时行为。

将工作区划分为 src、build、install 和 log,并使用 rosdep 解决依赖关系。使用 Docker 或开发容器锁定操作系统、DDS 和编译器,并将 ros2 doctor、ros2 node list、ros2 topic hz 和 tf2_tools 构建到 CI 和现场诊断中。

6. 生命周期与安全

传感器和执行器不应在通电后立即接受指令。生命周期节点的状态转换——未配置 → 非活动 → 活动 → 最终化——需要分别进行驱动程序初始化、校准、通信检查和输出授权。当看门狗失去心跳信号时,应将速度指令归零,并在硬件端断开制动器或继电器。

在安全方面,ROS 2 的消息通信本身并不符合功能安全标准。请检查 IEC 61508/ISO 26262/ISO 13849 及类似标准的适用范围,并将安全功能分离到监控系统、经过认证的 MCU 和物理紧急停止装置中。连接到网络时,应采用 SROS 2 密钥和证书、DDS 安全机制、访问控制和日志审计。

7. 当前生态系统和研究

Nav2 集成了自定位、建图、路径规划和控制功能,并通过动作和生命周期管理实现控制;ros2_control 则规范了硬件和控制器之间的边界。MoveIt 2 处理机械臂的运动学、碰撞检测和轨迹规划。在 Gazebo 或 Webots 中进行仿真,并使用 rosbag2 回放传感器日志,即可在不停止真实机器人的情况下进行回归测试。

零拷贝通信、使用 GPU/NPU 的类型化图像流水线、确定性执行器、分布式学习以及超越 DDS 的云机器人技术等方面的研究正在取得进展。采用新功能时,不仅要测试基准测试,还要测试网络掉线、时间偏差、进程重启、传感器丢包以及消息长度格式错误等问题。

总结

ROS 2 将机器人从一系列部件的集合转变为一个可重用的分布式系统。预先设计好节点职责、主题 QoS、TF2 的坐标和时序、生命周期以及安全状态,即使更换算法,整个系统也能保持健壮。

检查你的理解
节点间的连接是否能确保正常运行?

时间戳、帧、QoS 和速率也必须匹配。

接收到数据并不代表该数据可用于控制。

参考资料

Related reading

Explore another aspect of this fieldICP 失败的原因:初始化、异常值和对称几何Explore another aspect of this field从地图绘制到 ROS 2 导航——Jazzy 和 Nav2 的极简流程Explore another aspect of this field机器人坐标变换:矩阵、四元数和TF