首页 / 资讯中心 / 文章详情

PX4仿真环境搭建:PX4、Gazebo、XRCE-DDS与QGC四组件关系详解

PX4仿真环境搭建:PX4、Gazebo、XRCE-DDS与QGC四组件关系详解 ★ FEATURED ARTICLE
1. 从零搭建 PX4 仿真链路前先把四个组件的关系理清楚很多人第一次接触 PX4 仿真看到 PX4、Gazebo、XRCE-DDS、QGC 这四个名词就懵了不知道谁依赖谁、谁先启动谁后启动。我刚开始搭这套环境的时候也走过弯路把 QGC 先打开等着连飞机结果 PX4 那边 SITL 还没跑起来地面站一直显示等待飞控连接白白耗了一下午。所以这篇内容我不打算一上来就甩命令而是先把这四个东西各自扮演什么角色讲透后面操作起来你才知道每一步在干什么。PX4 是飞控固件本身也就是真正跑飞行控制算法的那套代码。在真机上它烧录在飞控硬件里在仿真里它以一个叫 SITLSoftware In The Loop软件在环的进程形式跑在你的电脑上。你可以把它理解成虚拟飞控它照样输出姿态、位置、电机指令只不过这些指令没有真的驱动电机而是发给了仿真器。Gazebo 是仿真器负责物理世界那一半重力、空气阻力、碰撞、传感器噪声、摄像头图像、激光雷达点云全都由它算。PX4 把控制指令发给 GazeboGazebo 把仿真出来的传感器数据回传给 PX4形成一个闭环。没有 GazeboPX4 就是闭着眼睛算控制没有任何意义。XRCE-DDS 是通信中间件全称 eXtremely Resource Constrained Environments DDS。它解决的是 PX4 和外部程序比如你的 ROS 2 节点、自定义 Offboard 控制程序之间怎么对话的问题。PX4 内部用的是 uORB 消息机制外部程序想读写这些消息就得靠 XRCE-DDS 做桥接。它相当于一个翻译官把 PX4 的 uORB 话题翻译成 DDS 话题让 ROS 2 那边能订阅和发布。QGC 是 QGroundControl 地面站负责参数配置、航线规划、飞行监控、固件烧录这些地面操作。仿真里它连的是 SITL 暴露出来的 UDP 端口看起来跟连真机一模一样。你可以用它解锁、切换飞行模式、看姿态仪表、改参数是验证仿真是否正常的最直观工具。把这四者的数据流串起来是这样的QGC 通过 UDP 给 PX4 发指令PX4 通过 Gazebo 的桥接插件收发仿真数据同时 PX4 通过 XRCE-DDS 和 ROS 2 交换消息。四条链路各司其职缺一个都跑不通完整的 Offboard 开发流程。提示如果你只是想跑个仿真看看飞机能不能飞其实 PX4 Gazebo QGC 三件套就够了XRCE-DDS 是给需要写外部控制程序的人准备的。但既然标题里带了 XRCE-DDS说明目标是做 Offboard 开发那四个都得配齐。理解了这层关系后面环境搭建的顺序就顺理成章了先装基础依赖再编译 PX4然后配 Gazebo 模型接着装 QGC最后打通 XRCE-DDS 和 ROS 2。下面按这个顺序一步步来。2. 环境准备阶段最容易翻车的几个细节2.1 系统版本和 Ubuntu 22.04 的取舍这套工具链对系统版本相当敏感。目前最省心的组合是 Ubuntu 22.04 ROS 2 Humble因为 PX4 官方对 22.04 的支持最完整ROS 2 Humble 也是长期支持版本和 Gazebo 的兼容性经过大量验证。如果你还在用 Ubuntu 20.04装 ROS 2 Foxy 也能跑但部分新版本的 PX4 和 Gazebo 插件会出现依赖冲突排查起来很费时间。我实测下来Ubuntu 22.04 上装 Gazebo 有两个选择一是 Gazebo Classic就是 gazebo11 那一代二是新版 Ignition Gazebo现在改名叫 Gazebo Sim比如 Fortress、Garden 这些版本。PX4 目前对两者的支持都在但 Classic 的教程和现成模型更多新手建议先用 Classic 把流程跑通等熟悉了再迁移到新版。如果你是在 VMware 虚拟机里跑这里有个高频坑Gazebo 界面会疯狂闪烁甚至黑屏。根本原因是虚拟机的 3D 加速没开或者显存不够。解决办法是进虚拟机设置把加速 3D 图形勾上显存拉到 2GB 以上然后在 Ubuntu 里确认显卡驱动走的是软件渲染还是硬件加速。实在不行就装 VMware Tools 并开启 3D 支持或者干脆用双系统仿真流畅度会好很多。2.2 依赖安装别跳过官方脚本PX4 官方提供了一个ubuntu.sh脚本一键装齐编译工具链、Gazebo、Python 依赖等等。很多人喜欢手动一个个 apt install结果漏了某个包编译到一半报错回头找问题更麻烦。我的建议是老老实实用官方脚本git clone https://github.com/PX4/PX4-Autopilot.git --recursive bash ./PX4-Autopilot/Tools/setup/ubuntu.sh注意--recursive这个参数不能省PX4 仓库带了很多子模块比如 mavlink、uORB 消息定义不递归拉取的话编译时会出现找不到头文件的错误。脚本跑完后重启一次系统让用户组和路径变更生效。装完基础依赖后Gazebo 的模型库还需要单独下载。Gazebo 启动时会去网上拉模型国内网络环境下经常卡住或者超时导致场景里只有地面没有建筑和飞机。解决办法是提前把模型缓存下来git clone https://github.com/osrf/gazebo_models.git ~/.gazebo/models或者设置 Gazebo 的模型路径指向本地目录。这一步做完后面启动仿真才不会出现世界是空的这种尴尬情况。2.3 编译 PX4第一次编译要有点耐心依赖装好后进入 PX4-Autopilot 目录编译 SITL 目标cd PX4-Autopilot make px4_sitl gazebo-classic第一次编译会花比较久十几分钟到半小时都正常取决于机器性能。编译过程中如果报错八成是依赖没装全或者子模块没拉全。这时候别急着重装系统先看报错信息里缺的是哪个包针对性补上就行。编译成功后会自动启动 Gazebo 和 PX4 SITL你会看到 Gazebo 窗口里出现一架飞机默认是 iris 四旋翼同时终端里 PX4 开始打印启动日志。如果 Gazebo 起来了但飞机没出现多半是模型路径问题如果 PX4 日志里一直报 Waiting for simulator说明 Gazebo 和 PX4 之间的桥接没建立检查一下是不是 Gazebo 版本和 PX4 期望的不一致。注意make px4_sitl gazebo-classic和make px4_sitl gazebo在不同 PX4 版本里指向的仿真器不一样。新版本里gazebo可能指向新版 Gazebo Simgazebo-classic才指向 Classic。跑之前先确认你的 PX4 版本对应哪个目标别跑错了还以为是环境坏了。3. Gazebo 仿真环境里那些影响体验的配置项3.1 世界文件与机型的对应关系PX4 启动 SITL 时默认加载的世界文件是Tools/sitl_gazebo/worlds/empty.world或者类似的空场景。如果你想换成带建筑、带障碍物的场景可以通过环境变量指定export PX4_SITL_WORLDwarehouse.world make px4_sitl gazebo-classic机型也是同理默认是 iris你可以换成固定翼、VTOL、 rover 等等。机型定义文件在Tools/sitl_gazebo/models或者ROMFS/px4fmu_common/init.d-posix下面每个机型对应一套传感器配置和初始参数。换机型的时候要注意不同机型的电机数量、传感器类型不一样Offboard 控制程序里的消息字段也得跟着改不然会出现控制指令发出去了但飞机没反应的情况。3.2 传感器噪声与仿真真实性Gazebo 默认给传感器加的噪声比较理想化GPS 几乎不漂、IMU 几乎没噪声。这在调试基础控制逻辑时是好事但如果你要测试滤波算法或者做鲁棒性验证就得把噪声调得更接近真实。方法是在机型对应的 sdf 文件里修改传感器插件的噪声参数比如给 GPS 加上水平/垂直位置噪声给 IMU 加上高斯噪声。这里有个经验调噪声不要一次调太猛否则 PX4 的 EKF扩展卡尔曼滤波可能直接发散飞机在仿真里就炸了。建议从小幅噪声开始逐步加大观察 EKF 的状态估计是否还能收敛。这个过程本身也是理解滤波器鲁棒性的好机会。3.3 摄像头与视觉仿真的坑做视觉相关开发比如目标检测、视觉定位时需要在 Gazebo 里给飞机挂摄像头。PX4 的 iris 机型默认可能没带摄像头你得在模型文件里加一个 camera 传感器插件并配置好图像话题的发布。Gazebo 会把图像通过一个叫gazebo_ros_camera的插件发布成 ROS 话题ROS 2 那边订阅就能拿到图像流。实测中常见的问题是图像话题发布了但收不到数据或者帧率极低。前者多半是插件没加载或者话题名对不上用ros2 topic list确认一下后者通常是 Gazebo 的渲染设置问题把 Gazebo 的实时更新率调低一点或者关掉不必要的阴影和特效帧率会明显改善。4. QGC 地面站连接与飞行模式调试4.1 连接 SITL 的正确姿势QGC 装好后官网下载 AppImage 或者用 apt 装都行启动它会自动扫描 UDP 端口。PX4 SITL 默认在 14550 端口广播 MAVLink 消息QGC 一般能自动识别并连接。如果没自动连上手动添加一个 UDP 连接地址填127.0.0.1:14550即可。连接成功后QGC 左上角会显示飞机图标和Ready To Fly之类的状态。这时候你可以进参数页面看 PX4 的参数树进飞行页面看姿态仪表。如果 QGC 一直显示等待飞控先确认 PX4 SITL 进程还在跑再确认端口没被占用。4.2 飞行模式没反应的排查思路QGC 飞行模式没反应是个高频问题。表现是你在地面站上点了某个飞行模式比如 Position、Offboard但飞机状态栏没变化。原因通常有这么几类第一类是遥控器没校准或者没连接。PX4 默认要求有 RC 输入才能切换某些模式仿真里虽然可以用虚拟摇杆但如果没配置好模式切换请求会被拒绝。解决办法是在 QGC 里做一次遥控器校准或者修改参数允许无 RC 切换。第二类是模式切换的条件不满足。比如 Offboard 模式要求外部程序先持续发送设定点消息PX4 收到一定数量后才会真正进入 Offboard。如果你只是在地面站上点了一下没有外部程序在发消息它自然不会切过去。第三类是解锁状态不对。飞机没解锁的时候很多模式是切不了的。先在 QGC 里点解锁或者用 MAVLink 命令解锁再试模式切换。排查的时候建议打开 QGC 的 MAVLink 控制台看模式切换请求发出去后 PX4 回了什么。如果回了拒绝原因顺着原因查就快多了。4.3 参数配置的持久化QGC 里改的参数默认存在飞控里仿真重启后会丢失因为 SITL 每次启动都是全新状态。如果你有一批常用参数想每次自动加载可以写一个启动脚本在 PX4 启动后通过 MAVLink 批量下发参数或者直接把参数写进 PX4 的机型配置文件里。后者更彻底但改错了会影响所有用这个机型的人建议只在个人分支上这么干。5. XRCE-DDS 打通 PX4 与 ROS 2 的关键步骤5.1 为什么需要 XRCE-DDS 而不是 MAVROS早期做 PX4 和 ROS 的桥接大家用的是 MAVROS它基于 MAVLink 协议。MAVROS 能用但消息类型受限很多 PX4 内部的 uORB 话题它映射不过来而且延迟相对高。XRCE-DDS 是 PX4 官方现在主推的方案它直接把 uORB 话题映射成 DDS 话题ROS 2 原生就能订阅消息类型完整实时性也更好。简单说MAVROS 像是翻译二手消息XRCE-DDS 像是直接接内部总线。做 Offboard 高频控制或者需要访问冷门 uORB 话题时XRCE-DDS 优势明显。5.2 编译并启动 XRCE-DDS AgentXRCE-DDS 分两部分跑在 PX4 里的客户端Client和跑在电脑上的代理Agent。PX4 固件里已经内置了客户端你只需要编译并启动 Agentgit clone https://github.com/eProsima/Micro-XRCE-DDS-Agent.git cd Micro-XRCE-DDS-Agent mkdir build cd build cmake .. make sudo make install sudo ldconfig /usr/local/lib/装好后启动 Agent指定 UDP 端口PX4 默认用 8888MicroXRCEAgent udp4 -p 8888Agent 启动后再启动 PX4 SITL。PX4 启动时会自动去连这个端口连上后终端会打印 XRCE client connected 之类的日志。这时候你在 ROS 2 里ros2 topic list就能看到一堆/fmu/开头的话题比如/fmu/out/vehicle_attitude、/fmu/in/offboard_control_mode等等。5.3 ROS 2 工作空间与消息包要在 ROS 2 里读写这些话题需要对应的消息定义包。PX4 提供了px4_msgs包把它 clone 到你的 ROS 2 工作空间里编译cd ~/ros2_ws/src git clone https://github.com/PX4/px4_msgs.git cd ~/ros2_ws colcon build source install/setup.bash编译完px4_msgs你就能在自定义节点里#include px4_msgs/msg/vehicle_attitude.hpp之类的头文件发布和订阅 PX4 话题了。注意px4_msgs的版本要和你的 PX4 固件版本匹配版本差太多会出现消息字段对不上的问题。5.4 Offboard 控制的最小闭环Offboard 控制的核心逻辑是外部程序持续以一定频率通常大于 2Hz向/fmu/in/offboard_control_mode发送心跳告诉 PX4 我还在控制同时向/fmu/in/trajectory_setpoint或/fmu/in/vehicle_attitude_setpoint发送设定点。PX4 收到足够数量的设定点后才会允许切换到 Offboard 模式。一个最小可用的 Offboard 节点大概长这样伪代码逻辑// 定时器 10Hz void timer_callback() { // 1. 发心跳 offboard_control_mode_msg.timestamp now(); offboard_control_mode_pub-publish(msg); // 2. 发设定点 trajectory_setpoint_msg.timestamp now(); trajectory_setpoint_msg.position {0, 0, -5}; // 悬停 5 米 trajectory_setpoint_pub-publish(msg); }启动节点后在 QGC 里切 Offboard 模式飞机应该会起飞到 5 米高度悬停。如果切不过去检查心跳频率够不够、设定点有没有发出去、飞机有没有解锁。提示Offboard 模式下如果外部程序停止发送设定点超过一定时间默认 0.5 秒左右PX4 会自动退出 Offboard 并执行失效保护。调试的时候如果程序崩了飞机可能会直接掉下来所以建议先在低空、有保护的情况下测试。6. 整套链路联调时我踩过的坑和排查方法6.1 时间戳不同步导致消息被丢弃PX4 和 ROS 2 对消息时间戳的处理比较严格。如果 ROS 2 节点发出去的消息时间戳和 PX4 内部时钟差太多PX4 会认为消息过期直接丢弃。仿真里 PX4 用的是仿真时间ROS 2 默认用的是系统时间两者不一致就会出问题。解决办法是在 ROS 2 节点里用 PX4 发布的时间戳作为基准或者配置 ROS 2 使用仿真时间。我一般是在节点里订阅/fmu/out/vehicle_attitude拿它的 timestamp 作为当前时间再填到要发的消息里这样时间戳就对齐了。6.2 话题名对不上PX4 的 uORB 话题经过 XRCE-DDS 映射后话题名会带上/fmu/out/或/fmu/in/前缀。out是 PX4 往外发的ROS 2 订阅in是 PX4 往里收的ROS 2 发布。新手容易搞反把该订阅的写成发布结果一直收不到数据。用ros2 topic list和ros2 topic info确认话题方向和类型能省很多时间。6.3 Gazebo 卡顿拖垮整个仿真Gazebo 是吃 CPU 和 GPU 的大户。如果你的机器性能一般仿真跑起来后 PX4 的控制频率会跟着掉表现为飞机响应迟钝甚至失控。优化方向有几个降低 Gazebo 的物理更新率、关掉不必要的光照和阴影、减少场景里的物体数量、用 headless 模式不开 Gazebo 界面跑纯算法验证。headless 模式特别适合做批量测试命令大概是make px4_sitl gazebo-classic HEADLESS1没有界面渲染CPU 占用大幅下降仿真速度能快不少。等算法调好了再开界面看效果。6.4 虚拟机里的网络与端口问题在虚拟机里跑这套环境UDP 端口有时候会被宿主机的防火墙或者虚拟网络配置挡住。表现是 QGC 连不上、XRCE Agent 连不上。排查方法是先在虚拟机内部用netstat -anu看端口有没有在监听再从宿主机 ping 一下虚拟机确认网络通。如果用的是 NAT 模式可能需要改成桥接模式或者手动做端口转发。7. 从跑通到用好一些提升效率的实践建议环境跑通只是第一步真正做开发的时候效率差异体现在细节上。我自己的习惯是写一个启动脚本把 PX4、Gazebo、XRCE Agent、QGC、ROS 2 节点的启动顺序和参数都固化下来一条命令拉起整套环境。这样每次调试不用重复敲命令也避免了漏启动某个组件。另外建议把常用的 Offboard 控制逻辑封装成 ROS 2 的 launch 文件参数通过 yaml 配置切换测试场景时只改配置不改代码。PX4 的参数也可以用脚本批量下发避免每次重启仿真都手动在 QGC 里点一遍。还有一点仿真里验证过的控制逻辑上真机前一定要重新检查安全逻辑比如失效保护、地理围栏、失控返航这些。仿真环境太理想很多边界情况不会暴露真机上出问题代价就大了。我见过不少人在仿真里飞得很顺一上真机就炸机基本都是忽略了仿真和现实的差距。最后PX4 的日志系统很强大仿真跑完后可以用 Flight Review 分析飞行数据看姿态跟踪误差、电机输出、EKF 状态。养成看日志的习惯很多隐藏的问题能在早期发现比等到炸机再回头查要划算得多。
阅读完成 · 觉得有帮助?
咨询建站