
1. 为什么 MicoAir H743 要配 uXRCE-DDS1.1 这块板子是什么来头MicoAir H743 是国产飞控里性价比相当能打的一块板子主控用 STM32H743主频跑到 480MHz相比上一代 F765 那类芯片算力余量大了不少。接口方面该有的都有UART 串口、CAN、I2C、SBUS 输入、PPM 输入、多个 PWM 输出通道IMU 一般是 BMI088 加 ICM20602 的组合支持双冗余。板子本身兼容 PX4 和 ArduPilot 双生态因为我主要跑 PX4所以这篇笔记里所有内容都是基于 PX4 固件来写的。如果你手里是一台六旋翼或者四旋翼的机器想在机载电脑上用 ROS 2 直接订阅飞控的姿态、位置、IMU 数据而不是像传统玩法那样用 Mission Planner 或 QGroundControl 去读 MAVLink 报文那 uXRCE-DDS 就是绕不开的一环。说白了它解决的是“飞控怎么把内部消息以 DDS 协议的方式吐给 ROS 2”这个事。1.2 传统 MAVLink 和 DDS 到底差在哪先聊一个基础问题为什么不用 MAVLink 非得折腾 DDS。MAVLink 是个轻量级串行协议设计哲学就是省带宽、结构简单、适合在 PX4 和地面站之间传控制指令和遥测数据。它的问题也很明显消息类型是固定的主题topic的概念很弱自定义数据要手动扩展消息定义跟 ROS 2 那种真正的发布订阅模型对不上。DDS 是数据分发服务本质上是分布式系统里的消息总线。ROS 2 从底层就构建在 DDS 之上所以最理想的方式是让飞控直接以 DDS 节点的身份出现在 ROS 2 网络里。但飞控上跑的是嵌入式 RTOS资源有限没法直接挂一个完整的 DDS 实现所以 PX4 做了一个折中方案飞控上跑一个轻量级客户端机载电脑上跑一个代理客户端和代理之间通过串口或者 UDP 传输消息代理再以真正的 DDS 节点身份加入 ROS 2 网络。这就是 uXRCE-DDS 的由来。1.3 什么人需要这篇配置笔记我写这篇笔记的定位很明确给那些已经能飞、正准备上手机载电脑和 ROS 2 的人。你可能已经用 Mission Planner 发过 MAVLink 指令给飞控也大概知道 PX4 的 offboard 模式怎么切但对 DDS 这套东西还有点懵。这篇笔记不涉及视觉算法和路径规划的高层设计专注把 uXRCE-DDS 客户端配置这条链路彻底打通。配置过程中我踩过不少坑比如串口波特率不匹配导致客户端反复重启、代理版本和固件版本对不上导致主题没数据、甚至还有因为接线方向搞反导致完全没输出的情况。这些我都会在后面单独开一节讲。2. 先搞懂 uXRCE-DDS 的工作方式2.1 客户端和代理的角色划分uXRCE-DDS 其实是 Micro XRCE-DDS 的缩写核心思想是把一个完整 DDS 节点拆成两个部分。飞控这边跑的是 Micro XRCE-DDS Client它只负责和代理建立连接、收发序列化后的消息。注意客户端本身不参与课题发现discovery、不管理 QoS 策略这些重活全部甩给代理。代理Agent运行在机载电脑上通常是 Linux 环境它把客户端串口传过来的二进制数据翻译成标准 DDS 消息然后以真实 DDS 节点的身份出现在 ROS 2 网络中。这样拆的好处非常明显飞控端的资源占用被压到最低CPU 只要处理串口收发和消息序列化就行。而代理端有完整的 DDS 协议栈可以做 QoS 匹配、主题注册、类型信息交换这些复杂操作。对飞控这种资源受限的嵌入式设备来说这是目前兼顾性能和资源消耗的最佳方案。2.2 传输方式选串口还是 UDPuXRCE-DDS 的物理传输层支持串口、UDP 和 TCP。我在 MicoAir H743 上主要用串口方式因为串口连接稳定不存在局域网延迟抖动问题而且飞行中机载电脑和飞控之间本来就要用杜邦线或者排线连顺手就把 DDS 通道放在同一根物理链路上。UDP 方式适合机载电脑和飞控通过有线以太网连接的情况但 MicoAir H743 板载没有以太网口需要额外转接实际用的人不多。TCP 理论上更可靠但实时性比 UDP 差实时控制系统里通常不推荐。我当时的选型逻辑很简单既然是机载场景板子和电脑挨得近串口是最不容易出问题的选择。如果你后续做室内集群之类的应用飞控和电脑隔得远再考虑 UDP 也来得及。2.3 几个关键参数先记下来配置 uXRCE-DDS 时最核心的 PX4 参数是 UXRCE_DDS_CFG它决定客户端跑在哪个串口上。MicoAir H743 上常见的选项有 TELEM1、TELEM2、UART6、UART7 这些我最后用 TELEM2。另外还有两个配套参数SER_TEL2_BAUD 控制串口波特率目前 PX4 官方推荐 921600老版本固件还有一个 UXRCE_DDS_PTCFG 用于选择物理传输类型新版本里这个参数被移到了编译层面后面细说。这里要特别强调一点波特率必须和 MicroXRCEAgent 启动命令里的 -b 参数完全一致两个地方哪怕差一个零都会导致客户端连接失败。我见过太多人在这里翻车。2.4 时间同步比你想的重要uXRCE-DDS 的 Time Synchronization 机制容易被忽略但实际影响非常大。飞控端和代理端各自维护自己的时间基准如果不同步ROS 2 里收到的消息时间戳是漂移的做数据融合、延时补偿时会出现莫名其妙的偏差。PX4 的实现是基于 timesync 请求应答机制客户端定期发时间同步请求代理应答后客户端校正本地时间偏移。这个机制默认开启你不用手动配置但如果发现 ROS 2 消息头里的 stamp 和系统时间对不上先检查串口波特率是否稳定再考虑是不是代理版本太老导致同步协议实现有 bug。3. 固件准备和烧录实操3.1 编译固件前必须确认的版本问题PX4 从 v1.14 开始正式支持 uXRCE-DDS如果你的固件还是 1.13 或者更早版本那用的是老旧的 micrortps 方案配置方式完全不同。我建议直接用最新稳定版固件我自己当前用的是 v1.15 分支。编译 MicoAir H743 的固件时需要先确认源码里有没有对应的板级配置。MicoAir 团队一般会维护自己的 PX4 分支如果没有可以用兼容的通用目标板替代但代价是个别板载外设可能无法正确初始化。最稳妥的方式是去 MicoAir 的官方仓库拉代码然后用它自带的构建脚本编译。编译命令通常长这样make micoair_h743_default upload如果源码里没有这个目标名可以先执行 make list_config_targets 查一下或者去 boards 目录下找找 MicoAir 相关的文件夹。3.2 两种烧录方式实测对比烧录 PX4 固件到 MicoAir H743我试过两种方式。第一种是 QGroundControl 的固件刷写功能。用 USB 线把飞控连到电脑QGC 识别后选择本地固件文件点刷写就行。这种方式最简单适合不想折腾命令行的朋友但有个前提你需要先把编译好的 .px4 固件文件准备好。第二种是命令行烧录在编译命令后面直接加上传参数比如上面的 make ... upload。这种方式的好处是编译完自动烧录不用手动选文件而且可以通过串口日志实时看烧录进度。我第一次烧的时候因为 USB 驱动没装好折腾了半天后来在 Linux 下用命令行一次就成功了。烧录完成后连接 QGC 或者 Mission Planner 验证固件版本号确认目标板信息正确。不要急着配置 uXRCE-DDS先确认飞控本身跑起来没问题否则后面排查问题会非常痛苦。3.3 老版本固件和新版本固件在配置上的差异如果你因为某些原因只能停留在 PX4 v1.13那配置方式就不一样了。v1.13 用的是 micrortps 桥接方案需要在编译固件前修改 fmu.yaml 文件定义哪些 uORB 主题要被桥接到 DDS 里然后重新编译固件再启动一个 micrortps_agent 可执行文件。这个方法其实也不复杂但有一个致命问题fmu.yaml 里配置的主题必须和机载电脑端 ROS 2 的消息类型严格对应改错一个字段整个桥接可能就废了。uXRCE-DDS 方案则不需要手动维护主题列表客户端启动后自动注册飞控上所有 uORB 主题省去了大量潜在出错点。所以如果你是刚入门我强烈建议直接用支持 uXRCE-DDS 的新版本固件别在旧方案上浪费时间。4. 客户端配置逐步操作4.1 硬件接线和串口选型接线是整个配置过程里最容易出问题的一环。MicoAir H743 的 TELEM2 串口通常是六针或者四针排针包含电源、地、TX、RX 等。连接机载电脑时一定要做交叉连接飞控的 TX 接电脑串口模块的 RX飞控的 RX 接电脑串口模块的 TX电源和地直接连通。我一开始想当然地直连 TX 到 TX结果一点数据都没有后来用示波器量了才发现问题。哪怕你用的是 USB 转 TTL 模块也要确认模块的逻辑电平是 3.3VH743 的 IO 不是 5V 耐受的接 5V 电平可能直接烧串口引脚。如果你手头是一块 USB 转串口芯片做的调试模块比如 CP2102 或者 CH340先确认 VCC 跳线帽在 3.3V 档位再接线。接反了轻则无数据重则硬件损坏。4.2 PX4 参数配置的具体步骤接线完成后先用 USB 把飞控连到 QGC进入参数设置界面搜索并修改以下几个参数UXRCE_DDS_CFG选择 TELEM2SER_TEL2_BAUD设置为 921600SYS_USB_AUTO保持默认即可这个不影响串口配置参数设置完成后需要重启飞控才能生效。重启后如果参数保持住说明写入成功了。这里有个小细节很多国产飞控默认会把 TELEM2 用作 MAVLink 遥测输出所以你在配置完 DDS 后TELEM2 上不会再出 MAVLink 数据Mission Planner 连这个口会失败。这是正常现象不是板子坏了。如果你还需要同时用地面站建议要么走 USB 连接要么把地面站接到 TELEM1 或另一个独立串口。重启后在 QGC 的 MAVLink Console 里输入以下命令确认客户端状态uxrce_dds_client status正常情况下会输出客户端的开启状态和当前配置的传输方式。如果提示 not running说明参数没生效或者固件版本不支持。4.3 启动 MicroXRCEAgent机载电脑这一侧的代理程序是 MicroXRCEAgent安装方式有源码编译和二进制包两种。我习惯用源码编译因为可以保证和固件版本同步git clone https://github.com/eProsima/Micro-XRCE-DDS-Agent.git cd Micro-XRCE-DDS-Agent mkdir build cd build cmake .. make sudo make install编译完成后启动代理MicroXRCEAgent serial --dev /dev/ttyUSB0 -b 921600注意 -b 的参数必须和飞控固件里的 SER_TEL2_BAUD 一致。启动后如果一切正常终端会显示客户端连接成功的日志类似 client connected 的提示。如果日志里出现连接超时或者没有反应优先检查串口设备路径是否选对。可以用 dmesg | grep tty 查看系统识别的串口设备或者试一下 ls /dev/ttyUSB*。4.4 用 ROS 2 验证数据通没通代理连接成功后打开一个 ROS 2 环境终端执行ros2 topic list如果你能看到 /fmu/out/vehicle_attitude、/fmu/out/vehicle_odometry 等以 /fmu/out 开头的话题说明上行数据链路已经通了。这里 /fmu/out 前缀代表从飞控往外发布的消息/fmu/in 前缀则是从 ROS 2 发往飞控的指令话题。再执行ros2 topic echo /fmu/out/vehicle_attitude能持续输出四元数姿态数据说明整个链路完全打通。到这一步uXRCE-DDS 客户端的核心配置就算完成了。我自己的习惯是再跑一下 ros2 topic hz /fmu/out/vehicle_attitude 看频率正常情况下姿态消息在 100Hz 左右。如果频率远低于这个值优先检查波特率是不是设低了串口线是否需要更换。5. 常见问题和排查实录5.1 客户端日志不断显示超时重连这是最典型的问题。现象是代理终端里日志反复显示 client disconnected过一会又 connected循环往复。原因基本有两种。第一种是波特率不匹配飞控那边设 921600代理这边启动忘了加 -b 参数默认可能就 115200两边对不上。解决办法很简单确认两边参数一致。第二种是串口被其他程序占用。比如 QGC 或者 Mission Planner 还连着同一个串口代理拿不到权限或者数据冲突。我用 Mission Planner 折腾的时候遇到过这个问题拔掉地面站连接后立刻就好了。5.2 波特率设置正确但速度很慢如果代理日志显示连接成功但 ros2 topic hz 频率只有 10Hz 左右通常是波特率虽然设对了但飞控串口的 DMA 没有开启或者总线负载过高。PX4 的 uXRCE-DDS 客户端默认发布频率在某些主题上有限制这是正常的但 vehicle_attitude 这种高频核心消息应该能到 100Hz 级别。如果上不去检查一下飞控那边是否还运行着其他不必要的串口驱动比如同时开了 MAVLink 遥测或者外部 GPS 的同一个 UART。5.3 主题列表有但 echo 没数据有时候 ros2 topic list 能看到 /fmu/out/xxx但 echo 就是没有输出。这个问题我排查了挺久最后发现是 QoS 设置不匹配。PX4 的 uXRCE-DDS 客户端发布出来的消息默认 QoS 可能和 ros2 topic echo 默认订阅 QoS 不一致。解决办法是在订阅时显式指定 QoS或者用 rqt_graph 看看数据链路是否连接上了。如果你是用 Python 写订阅节点记得在创建订阅时设置合适的 QoS 深度和可靠性策略。5.4 Mission Planner 连不上飞控了这个不是 uXRCE-DDS 本身的问题但很容易让人误判。配置完 DDS 后TELEM2 被 DDS 客户端占用Mission Planner 如果还通过 TELEM2 连接自然连不上。热词里提到的 mission planner 发送 mavlink 信息给飞控在这个场景下就得换个口。我自己的解决方案是调试阶段用 USB 连 Mission Planner飞行阶段用机载电脑连 DDS两者互不干扰。如果你必须用数传模块和地面站通信那就把数传接到 TELEM1把 TELEM2 留给 DDS。5.5 固件版本、代理版本和消息类型不匹配uXRCE-DDS 代理版本和 PX4 固件版本如果差距太大可能出现主题注册失败或者消息类型对不上的情况。这个没有特别好的自动化排查手段只能尽量保持两端都更新到较新的稳定版本。我在一次升级固件后没有同步升级代理结果 /fmu/out/vehicle_attitude 话题一直不出现更新代理后立刻恢复正常。所以建议如果有人问你“为什么我升级固件后 DDS 就坏了”先让他升级代理。5.6 问题排查速查表症状可能原因排查方式代理日志显示超时重连波特率不匹配或串口被占用检查 -b 参数关闭地面站串口连接有话题列表但 echo 无数据QoS 不匹配或消息类型不兼容显式指定 QoS升级代理版本topic list 看不到 /fmu/out 话题客户端未启动参数配置错误uxrce_dds_client status 检查ROS 2 发指令飞控无响应/fmu/in 话题 QoS 不匹配检查发布者的 QoS 设置姿态频率过低波特率过低或总线负载高确保 921600关闭不必要外设TELEM2 无法用 MAVLink 连串口被 DDS 占用改用 TELEM1 或 USB 连接地面站6. 实操中的一些体会6.1 我的使用感受整个配置流程走下来最大的感受是 uXRCE-DDS 相比旧版 micrortps 方案真的是省心太多了。不用手动维护主题映射表不用每次改消息类型都重新编译固件客户端启动后自动把飞控上的 uORB 主题桥接出来调试效率高了不少。我手头这台六旋翼配完 DDS 后在 ROS 2 里跑 offboard 位置控制姿态数据延迟体感上比原来用 MAVLink 转发然后再解析要低得多。而且重要的是数据不再是大地坐标系下拼凑出来的而是直接拿到了飞控内部的估计状态后续做滤波融合的底子好了很多。6.2 还可以往哪些方向扩展如果你已经跑通了 DDS 链路后面可以尝试的事情很多。比如在 /fmu/in 方向发送 offboard_control_mode 和 trajectory_setpoint 消息在 ROS 2 侧实现自己的位置控制器再比如用 /fmu/out/vehicle_local_position 做机载端避障规划甚至可以把多台 MicoAir H743 飞控都接入同一个 ROS 2 网络做简单的集群编队原型验证。我个人目前正在尝试把视觉里程计的数据通过 /fmu/in/vehicle_visual_odometry 反馈给飞控代替 GPS 做室内定位。这个方向对延迟很敏感uXRCE-DDS 串口模式的表现值得一试。最后再分享一个小技巧调试 uXRCE-DDS 时别急着上机器人操作系统那一堆工具先把代理日志研究明白。代理启动时输出的每个警告、每条连接记录都包含大量信息很多问题光看日志就能定位到根因比盲目改参数高效得多。