2. PX4与ROS2基础回顾
在进入多机命名空间与通信配置之前,必须先把 PX4 与 ROS 2 各自的运行模型和通信机制梳理清楚。多机场景下出现的绝大多数问题,例如话题重名、命名空间冲突、QoS 不匹配、消息丢失、节点互相看不到,本质上都源于对这两套系统的中间件层理解不够。本节从 PX4 的模块化架构与 uORB 内部总线出发,再过渡到 ROS 2 的节点、话题、服务、动作四类通信原语,最后落到 DDS 这一真正承载跨进程、跨主机通信的中间件层。
一、PX4 架构:模块化 + uORB 内部总线
PX4 是一个运行在 NuttX 实时操作系统上的飞控固件,采用模块化设计。整个系统由若干独立模块组成,每个模块负责一项明确职责,例如传感器驱动、姿态估计、位置控制、混控输出、commander 状态机、导航器等。这些模块并不是通过函数调用直接耦合,而是通过一条名为 uORB 的内部发布/订阅总线交换数据。
uORB 是 PX4 的微对象请求代理(micro Object Request Broker),可以理解为飞控内部的轻量级消息中间件。每个数据流被定义为一个 topic,例如 sensor_combined、vehicle_attitude、vehicle_local_position、vehicle_command、actuator_motors。模块向某个 topic 发布消息,其他模块订阅该 topic 即可获得数据,发布者与订阅者互不知晓对方身份。这种设计让 PX4 的模块可以独立启动、停止、替换,也方便通过 MAVLink 或 uORB-ROS 2 桥接把内部数据暴露给外部系统。
理解 uORB 的关键点有三条:第一,它是进程内/板内的通信机制,不跨网络;第二,topic 有固定消息定义,字段和单位在编译期确定;第三,发布频率由发布模块决定,订阅者按自身节奏读取最新值或队列值。PX4 与 ROS 2 之间的桥接,本质上就是把 uORB topic 映射为 ROS 2 topic,因此 uORB 的命名和频率会直接影响上层 ROS 2 侧看到的数据。
二、ROS 2 通信原语:节点、话题、服务、动作
ROS 2 把计算单元抽象为节点(Node),节点之间通过四种主要方式通信:话题(Topic)、服务(Service)、动作(Action),以及参数(Parameter)。其中前三者是本节重点。
- 话题:发布/订阅模型,单向、异步、多对多。适合高频连续数据流,例如
/fmu/out/vehicle_attitude、/fmu/out/vehicle_local_position。发布者只管发,订阅者只管收,双方通过 DDS 匹配。 - 服务:请求/响应模型,同步、一对一。适合短时、需要返回结果的操作,例如查询参数、触发校准、请求模式切换。
- 动作:基于服务与话题组合的长时任务模型,带目标、反馈、结果三部分。适合耗时且需要中途反馈的任务,例如起飞到指定高度、飞往航点、执行降落。
在多机场景中,节点名和话题名会加上命名空间前缀,例如 /uav1/fmu/out/vehicle_attitude 与 /uav2/fmu/out/vehicle_attitude。命名空间的作用就是把同一套节点和话题复制到不同逻辑域中,避免不同无人机之间互相串扰。这也是后续章节配置多机通信的核心手段。
三、DDS:ROS 2 真正的通信中间件
ROS 2 默认不自己实现网络传输,而是把通信交给 DDS(Data Distribution Service)。DDS 是一个以数据为中心的发布/订阅标准,负责发现、匹配、序列化、传输和 QoS 管理。ROS 2 节点在启动后,会通过 DDS 的发现协议自动寻找同一域(Domain)内的其他节点,并基于 topic 名和类型建立连接。
DDS 中有几个必须掌握的概念:
- Domain ID:通信域编号,只有同一 Domain 内的节点才能互相发现。多机场景常用不同 Domain 隔离不同无人机,或统一 Domain 配合命名空间区分。
- QoS:服务质量策略,包括可靠性(Reliable/Best Effort)、历史深度、持久性、截止时间等。发布者与订阅者的 QoS 必须兼容,否则话题匹配失败,表现为“节点在跑但收不到数据”。
- 发现机制:DDS 自动发现对端,无需手动指定 IP 和端口,但跨主机时需要网络组播可达,否则会出现“本机能看到、跨机看不到”。
micro-ros-agent 或 px4_ros_com 会把 uORB 数据转换为 ROS 2 话题。此时 DDS 的 Domain ID、QoS 和命名空间共同决定了上层能否正确收到飞控数据。四、uORB 与 ROS 2 话题的映射关系
下面这张图展示了从 PX4 内部 uORB 总线,经过桥接层,到 ROS 2 节点与 DDS 网络的整体数据链路。理解这条链路,才能明白多机命名空间应该加在哪一层。
五、核心概念对照表
| 概念 | 所属层 | 作用 | 多机场景关注点 |
|---|---|---|---|
| uORB | PX4 内部 | 板内发布/订阅总线 | topic 名固定,不直接跨机 |
| 节点 Node | ROS 2 | 计算单元 | 需加命名空间前缀区分 |
| 话题 Topic | ROS 2 | 异步数据流 | 同名话题必须隔离 |
| 服务 Service | ROS 2 | 同步请求/响应 | 注意服务名冲突 |
| 动作 Action | ROS 2 | 长时任务与反馈 | 目标、反馈、结果均需隔离 |
| DDS | 中间件 | 发现、匹配、传输 | Domain ID 与 QoS 必须一致 |
六、典型误区与复盘
误区一:把 uORB topic 当成 ROS 2 topic 直接使用。uORB 只在飞控板内有效,ROS 2 侧看到的是桥接后的话题,名称通常带 /fmu/out/ 前缀,不能混用。
误区二:只改节点名,不改话题名。多机时如果两个桥接节点都发布 /fmu/out/vehicle_attitude,订阅者会收到混合数据。必须通过命名空间或重映射把话题也隔离。
误区三:忽略 QoS 兼容性。PX4 桥接常用 Best Effort,而某些订阅者默认 Reliable,导致匹配失败。排查时应先看 ros2 topic info -v 的 QoS 是否兼容。
误区四:跨主机时 Domain ID 不一致。两台机器 Domain ID 不同,DDS 发现不到对方,表现为“本机正常、跨机无数据”。
复盘时可以用一条命令快速确认当前 ROS 2 侧能看到哪些话题与节点:
ros2 node list
ros2 topic list
ros2 topic info /uav1/fmu/out/vehicle_attitude -v
ros2 topic echo /uav2/fmu/out/vehicle_local_position --once
如果 ros2 topic list 能看到话题但 echo 无数据,优先检查 QoS 与 Domain ID;如果连话题都看不到,优先检查桥接节点是否启动、命名空间是否写对、DDS 发现是否跨主机可达。掌握这条从 uORB 到 DDS 的完整链路,后续多机命名空间与通信配置才有稳定的判断依据。