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 概览
图 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 和速率也必须匹配。
接收到数据并不代表该数据可用于控制。
评论
请先登录。
暂无数据。