4. PX4与ROS2通信机制
PX4 与 ROS 2 的通信并不是一条“直连总线”,而是由飞控内部消息系统、桥接中间件和 DDS 网络三层叠加而成。理解这三层各自负责什么、数据在何处被序列化、在何处被转发,是排查 Offboard 控制延迟、话题丢包和模式切换失败的关键。本节围绕 uORB、MicroRTPS、MicroDDS 与 XRCE-DDS 四个概念,梳理它们的分工与数据流。
一、四层概念的分工
PX4 飞控内部使用 uORB(micro Object Request Broker)作为发布/订阅消息总线。所有传感器、估计器、控制器、commander 状态机之间的数据交换,都以 uORB 话题(topic)形式存在,例如 sensor_combined、vehicle_local_position、vehicle_command、offboard_control_mode。uORB 是进程内、共享内存式的轻量机制,不跨设备、不跨网络。
要让机载计算机上的 ROS 2 节点访问这些话题,就需要一个“桥”。PX4 官方主推的桥是 Micro XRCE-DDS,其客户端运行在飞控上(uxrce_dds_client),代理端(Agent)运行在机载计算机上(MicroXRCEAgent)。MicroRTPS 是早期基于 Fast RTPS 的桥接方案,现已被 XRCE-DDS 取代,但在旧版本 PX4 与部分教程中仍会出现。MicroDDS 通常指 PX4 侧对 DDS 的轻量化实现与集成层,是 XRCE-DDS 客户端在 PX4 中的具体落地形态。四者关系可概括为:uORB 是飞控内部总线,MicroRTPS 是旧桥,MicroDDS/XRCE-DDS 是新桥,ROS 2 侧统一以 DDS 话题呈现。
二、桥接原理与数据流
以 XRCE-DDS 为例,一条从 ROS 2 到 PX4 的控制指令,其完整路径如下:ROS 2 节点发布 /fmu/in/offboard_control_mode 与 /fmu/in/trajectory_setpoint;机载计算机上的 MicroXRCEAgent 通过串口或 UDP 接收这些 DDS 话题;Agent 将数据按 XRCE 协议打包,经串口(如 /dev/ttyACM0)或 UDP 发送给飞控;飞控内 uxrce_dds_client 解包后,把消息写入对应的 uORB 话题,例如 offboard_control_mode 与 trajectory_setpoint;commander 与 mc_pos_control 等模块订阅这些 uORB 话题,执行 Offboard 模式判断与控制解算。反向数据流(如 vehicle_local_position、vehicle_status)则沿相反方向,从 uORB 经 XRCE-DDS 客户端、Agent,最终成为 ROS 2 的 /fmu/out/... 话题。
三、关键配置与启动流程
在 PX4 侧,需要确保 XRCE-DDS 客户端已启动并连接到正确的串口或 UDP 端口。典型配置如下:
# PX4 参数设置(QGroundControl 或 param set)
XRCE_DDS_CFG = 0 # 0=串口, 1=UDP
XRCE_DDS_PRT = 0 # 串口设备索引
XRCE_DDS_BAUD = 921600
# 机载计算机启动 Agent
MicroXRCEAgent serial --dev /dev/ttyACM0 -b 921600
# 或使用 UDP
MicroXRCEAgent udp4 -p 8888
启动后,可用 ros2 topic list 查看是否出现 /fmu/in/ 与 /fmu/out/ 前缀的话题。若没有出现,优先检查 Agent 是否运行、串口权限、波特率以及 PX4 参数是否生效。常见误区是只启动了 Agent 却未在 PX4 中启用 uxrce_dds_client,或串口被 QGroundControl 占用导致连接失败。
四、MicroRTPS 与 XRCE-DDS 的对比
| 对比项 | MicroRTPS | XRCE-DDS |
|---|---|---|
| 底层协议 | RTPS / Fast RTPS | XRCE-DDS |
| PX4 支持状态 | 旧版本,已逐步弃用 | 当前主推,v1.14+ 默认 |
| ROS 2 侧代理 | micro-rtps-agent | MicroXRCEAgent |
| 话题命名 | fmu/... | /fmu/in/... 与 /fmu/out/... |
| 资源占用 | 相对较高 | 更轻量,适合嵌入式 |
| 推荐场景 | 维护旧工程 | 新项目与 Offboard 开发 |
五、案例与排障复盘
假设一个 Offboard 程序发布 /fmu/in/trajectory_setpoint 后,无人机不响应。排查顺序应为:先用 ros2 topic echo /fmu/out/vehicle_status 确认飞控状态是否正常;再用 ros2 topic hz /fmu/in/trajectory_setpoint 确认发布频率是否稳定;接着检查 offboard_control_mode 是否以高于 2 Hz 的频率持续发布,因为 PX4 要求 Offboard 模式进入前必须收到持续的控制模式心跳;最后确认 vehicle_command 中的 VEHICLE_CMD_DO_SET_MODE 是否正确切换到 Offboard。若话题存在但数据不更新,多半是 Agent 与飞控之间的串口/UDP 链路中断,或 QoS 配置不匹配导致 DDS 未真正匹配。
/fmu/in/... 与 /fmu/out/...,而飞控内部是 offboard_control_mode、trajectory_setpoint 等 uORB 名称,两者通过桥接映射,不能混用。