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 话题呈现。

核心记忆:uORB 管飞控内部,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 与 ROS 2 通信数据流(XRCE-DDS 桥接) PX4 飞控 uORB 消息总线 offboard_control_mode commander / mc_pos_control 模式判断与控制解算 uxrce_dds_client XRCE 客户端 串口 /dev/ttyACM0 或 UDP 机载计算机 MicroXRCEAgent XRCE 代理端 DDS 域 /fmu/in 与 /fmu/out ROS 2 节点 Offboard 控制程序 rclcpp / rclpy 接口 ROS 2 应用层 发布 /fmu/in/... trajectory_setpoint 订阅 /fmu/out/... vehicle_local_position Offboard 控制逻辑 位置 / 速度 / 姿态设定 QoS 与时间同步 上行指令 下行状态 DDS 发布 DDS 订阅 uORB 负责飞控内部,XRCE-DDS 负责飞控与机载计算机,DDS 负责 ROS 2 网络

三、关键配置与启动流程

在 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 未真正匹配。

常见误区:把 uORB 话题名直接当作 ROS 2 话题名使用。ROS 2 侧看到的是 /fmu/in/... 与 /fmu/out/...,而飞控内部是 offboard_control_mode、trajectory_setpoint 等 uORB 名称,两者通过桥接映射,不能混用。