☰
PX4 SITL仿真全链路打通:Gazebo、QGC与ROS 2实战
2026/10/2 10:50:10 网站建设 项目流程

如果你刚接触PX4,八成会被这套组合拳打懵:明明照着教程装了QGC、拉了源码,make 了一晚上,到头来 Gazebo 里飞机的螺旋桨转都不转,或者飞机起来了但地面站界面干干净净。这不是你笨,是现在的 PX4 生态已经不是"装个软件点运行"就能跑的年代了。PX4 固件、Gazebo 仿真器、XRCE-DDS 中间件、QGC 地面站这四样东西各管一段,中间哪根线没接通,整个系统就是瘫的。

这篇教程就是把这些线一根一根捋清楚。我会从架构原理讲到实际命令,再讲我跑通整个链路时踩过的坑,目标是让你在一台普通 Ubuntu 电脑上,用 QGC 看到仿真飞机的姿态、用 ROS 2 订阅到飞控的传感器数据,并且知道这套东西换到实机上该怎么迁移。适合刚入门 PX4 的开发同学,也适合那些已经被版本组合折磨到想放弃的人。

1. 先搞懂数据通道:PX4 1.14 后为什么要插一个 XRCE-DDS

1.1 uORB、MAVLink 与 DDS 的三角关系

PX4 内部有一套自研的轻量级通信机制叫 uORB,飞控里的姿态、传感器、遥控器指令全都在这个"内部总线"上跑。它高效、实时,但有个致命特点:只存在于 PX4 进程内部,外面的人根本看不见。

往外看,PX4 对外有一张"标准面孔"叫 MAVLink,这是无人机行业最常见的通信协议。QGC 地面站能显示姿态、地图、电池电量,靠的就是 MAVLink 消息。仿真器里的 Gazebo 也是通过 MAVLink 和 PX4 模拟进程交换数据的。

问题出在 ROS 2 这边。ROS 2 的通信基座是 DDS,一套去中心化、支持动态发现的中间件。早期想打通 PX4 和 ROS,只能用 MAVROS 这类"翻译官",先把 MAVLink 翻译成 ROS 话题,效率低、转发链路长,还容易丢消息。

PX4 从 v1.14 开始内置了 XRCE-DDS 客户端(microdds_client),让 PX4 可以直接以 DDS 参与者的身份和 ROS 2 对话。这个客户端用的是 XRCE-DDS 协议,也就是"约束资源环境下的 DDS",可以理解成给嵌入设备用的一个 DDS 精简版。

1.2 两条通道不是一回事:很多新人在这里翻车

我见过不少人把 MAVLink 和 DDS 当成一条路,结果 Gazebo 里飞机已经飞了,ROS 2 里ros2 topic list却干干净净,就开始怀疑人生。

其实在 PX4 SITL 仿真环境下,同时跑着两条完全独立的数据通道:

  • 第一条是 QGC 和仿真之间的 MAVLink 通道,负责显示和控制。
  • 第二条是 ROS 2 和仿真之间的 DDS 通道,负责传递传感器数据和指令。

这两条通道互不干扰。你ros2 topic list看不到话题,不代表飞控没起来;QGC 连不上飞机,也不代表仿真失败。搞清楚自己现在盯的是哪条通道,排查问题就快得多。

1.3 端口全景图:14540 / 14550 / 8888

数据要跑就得走端口,端口是最容易踩坑的地方。跑这套仿真时,你至少要知道三个端口:

端口用途常见问题
14540PX4 仿真进程与 QGC 之间的 MAVLink 数据QGC 收不到数据时检查这里
14550QGC 向仿真发送 MAVLink 指令被其他程序占用时 QGC 会连不上
8888PX4 microdds_client 与 XRCE-DDS Agent 通信Agent 没监听这个端口时 ROS 2 无话题

很多人仿真飞控起不来,bind: Address already in use一出来,就是 14550 被占用了。后面我会专门讲排查。

2. 环境组合:版本选对了,等于成功一半

2.1 推荐组合

先说结论,我目前用下来最稳的组合是:

组件推荐版本/分支说明
操作系统Ubuntu 22.04 LTS生态支持最全面,教程最多
ROS 2Humble和 Ubuntu 22.04 是官方配对
PX4 固件v1.14.x 稳定版如果你求稳,用它
GazeboGazebo Classic 11PX4 v1.14 默认配套仿真器
QGCQt 编译的最新稳定版4.2+,版本太老会握手失败

如果你非要体验新功能,可以拉 PX4 main 分支,那默认的仿真器就换成了 Gazebo(Ignition Fortress 之后的版本),命令也变成了make px4_sitl gz_x500。但如果你刚入门,我更建议先用 v1.14 稳定版把链路跑通,再考虑迁移到新版本。原因很简单:老版本踩坑的人多,搜得到解决方案。

2.2 PX4 工具链:自助安装脚本怎么用

PX4 官方仓库里带了一个环境配置脚本,路径是Tools/setup/ubuntu.sh。它的作用是帮你装好编译 PX4 需要的所有系统依赖:CMake、Ninja、Python 工具包、交叉编译器等。

但注意,它不会装 Gazebo,也不会装 QGC。Gazebo 是你在需要仿真的时候,用 make 命令自动拉起来的;QGC 要单独下载 AppImage 或用源码编译。我第一次用这脚本时以为万事大吉,结果跑 make 还是报一堆缺依赖,后来才发现脚本只管飞控本身。

建议执行顺序:

git clone https://github.com/PX4/PX4-Autopilot.git --recursive cd PX4-Autopilot bash ./Tools/setup/ubuntu.sh

如果网络不好,submodule 拉取可能失败,git submodule update --init --recursive这条命令得常备着。

2.3 到底要不要装 ROS 2?

这个问题得分场景。

你只是想用 QGC 看看姿态、手动飞一飞仿真飞机?那不需要装 ROS 2,PX4 单独跑就够。

你想订阅飞控传感器数据、跑视觉 SLAM、做自主决策?那必须装 ROS 2 Humble,还要把 XRCE-DDS Agent 跑起来。

我的建议是:第一次接触,先别关 ROS 2 的事,纯 PX4 + Gazebo + QGC 就能让你理解飞控的核心逻辑。等你弄明白 PX4 在干什么,再引入 DDS 那套,思维会清晰得多。硬着头皮一步到位反而容易一堆乱麻。

安装 ROS 2 Humble 就用官方文档里的 apt 源安装方式,然后注意source /opt/ros/humble/setup.bash,这个不能漏。QGC 和 Gazebo 的安装其实都可以后置,真正要先装的是 PX4 依赖链。

2.4 Gazebo Classic 和 Fortress 的选择

PX4 社区现在处于两代 Gazebo 并存的阶段:

  • Gazebo Classic 11:老牌仿真器,模型资源丰富,PX4 v1.14 的默认选择。
  • Gazebo(gz-sim):新一代仿真器,和 ROS 2 的集成更紧密,PX4 main 分支已经默认用它。

我个人的建议是:新手用 Classic。不是因为新版本不好,而是旧版本的故障模式已经被摸透了,网上随手一搜就是答案。Fortress 对模型格式和资源路径的要求不一样,报错信息也更加抽象,等你解决完这些,可能已经没精力学 PX4 了。

3. 实操:把 PX4 SITL 仿真拉起来

3.1 从克隆到第一架飞机

环境准备好以后,真正的 SITL(Software In The Loop,软件在环仿真)操作就开始了。所谓 SITL,就是飞控代码不是跑在真实硬件上,而是作为一个 Linux 进程在你的电脑上跑,再由仿真器提供虚拟的传感器数据。

最经典的启动命令是:

cd PX4-Autopilot make px4_sitl gazebo_x500

这条命令会先编译 PX4 固件,再启动 Gazebo,并把 x500 四旋翼模型塞进仿真世界。注意第一次编译时间取决于你的 CPU,我之前用一台普通笔记本大概十分钟左右。

启动成功后,你的终端里会陆续出现几条关键信息,其中最重要的是这条:

INFO [commander] Ready for takeoff!

看到这行字,说明 PX4 已经认为自己的传感器有效、姿态估算正常,随时可以解锁起飞了。

3.2 make 命令到底拆成了什么

很多人不理解make px4_sitl gazebo_x500为什么是这么个写法。拆开看就懂了:

  • px4_sitl:编译目标,生成的是 SITL 版本的 PX4 可执行文件,也就是跑在 Linux 上的飞控。
  • gazebo:指定启动的仿真器是 Gazebo Classic。
  • x500:仿真里加载的具体机型模型,这里是 x500 四旋翼。

如果你想换机型,比如跑固定翼,就换模型名,例如:

make px4_sitl gazebo_plane

不同版本 PX4 的模型命名有差异。如果你是 v1.14 稳定版,gazebo_x500是准确且保险的。如果用的是 main 分支,那要换成gz_x500,否则会报找不到模型。

3.3 启动成功之后,QGC 还没出现

记着,这一步是 PX4 起来了、Gazebo 起来了,但 QGC 不会自己弹出来。你得另外打开 QGC。QGC 默认会自动通过 UDP 14550 端口探测本地仿真器,一般几秒内就能认出 PX4 SITL。

打开 QGC 后,你应该能在左上角看到电池电压、姿态指示器和"飞行状态"界面。如果 Gazebo 里飞机在动,QGC 的俯仰滚转角也会跟着动。到了这一步,PX4 和 QGC 这条 MAVLink 通道已经通了。

3.4 手动起飞的方式

在仿真里试飞,我最推荐用 QGC 的起飞机动:切到任务界面,点"起飞"滑条,飞机就会自动解锁并上升到设定高度。这比用遥控器手势省心得多。

如果你已经接好了 RC 遥控器模拟器(比如用 USB 加密狗接真实遥控器),那可以先在 QGC 里完成遥控器校准,然后在 Safety 界面设置好失控保护,再用内八手势解锁。仿真里大多数时候我更推荐直接软件解锁,原因是很多新手在电脑前面右手杆往下一推,Gazebo 里的飞机纹丝不动,就开始怀疑是自己手势不对,其实只是遥控器通道没映射好。

4. 打通 ROS 2:跑起 XRCE-DDS Agent

4.1 Agent 是什么,为什么 PX4 自己不够

PX4 内置的 microdds_client 只是一个"客户端",它负责把 PX4 的 uORB 消息翻译成 XRCE-DDS 格式,然后发往一个叫"Agent"的中间进程。Agent 收到以后再转成标准 DDS 消息,ROS 2 节点才能订阅到。反过来,ROS 2 发出去的指令也由 Agent 转给 microdds_client,最终落回到 uORB。

你可以把 Agent 想象成快递中转站:PX4 是镇上的杂货铺,ROS 2 是城里的大超市,天上飞的 DDS 是公路,Agent 就是服务区,所有快递都得在服务区过一遍。

4.2 安装和启动方式

用源码编译是最可靠的,因为 apt 里不一定有你想要的版本。我的做法:

git clone -b humble https://github.com/uxlfoundation/micro-ROS-Agent.git cd micro-ROS-Agent # 建议先建一个独立的 colcon 工作空间,别和 ROS 2 的根空间混在一起

然后编译:

sudo apt install python3-colcon-common-extensions colcon build source install/setup.bash

启动命令:

ros2 run micro_ros_agent micro_ros_agent udp4 --middleware_rmw_fastrtps_cdr --port 8888

这里有两个关键点:一是用udp4,表示 IPv4 UDP 通信;二是--middleware_rmw_fastrtps_cdr,强制指定 Fast DDS 作为 RMW 实现。PX4 默认集成的就是 Fast DDS,如果你这时候 ROS 2 用的是 CycloneDDS,两端 RMW 不一致,就会出现 Agent 启动了但话题看不到的怪事。

4.3 启动顺序其实有讲究

我建议先启动 Agent,再启动 PX4 SITL。这样 PX4 起来的时候 microdds_client 立刻就能连上 Agent,不会有反复重连的等待。

但如果你已经先把 PX4 跑起来了,再启动 Agent,问题也不大。microdds_client 有自动重连机制,Agent 一上线,几十秒内就会握手成功。你观察终端日志,看到类似microdds_client connected to 127.0.0.1:8888的信息就说明通了。

4.4 ROS 2 里怎么验证

跑完 Agent 和 PX4 后,另开一个终端:

source /opt/ros/humble/setup.bash source ~/micro_ros_agent/install/setup.bash ros2 topic list

正常你会看到一大堆fmu/out/开头的 ROS 话题,比如:

/fmu/out/vehicle_attitude /fmu/out/sensor_combined /fmu/out/vehicle_local_position /fmu/out/vehicle_status

拿姿态话题试一下:

ros2 topic echo /fmu/out/vehicle_attitude

如果屏幕上持续翻滚四元数数据,就说明 ROS 2 已经能实时看到仿真飞控的自身姿态了。

5. QGC 上手:从连上到准备起飞

5.1 新建连接还是自动连接

安装 QGC 后第一次打开,它会自动搜本地的 UDP 端口。大多数情况下,PX4 仿真一跑起来,QGC 左上角的"连接状态"就从灰色变成绿色。

如果没变绿,手动添加连接也不麻烦。QGC 的通信设置里新建一个 UDP 连接,监听端口填 14550,目标端口填 14540,一般就通了。注意端口别写反,我在这上面浪费过十分钟。

另一种隐蔽情况是虚拟机。如果你在 Windows 上用 VMware 跑 Ubuntu,QGC 和 PX4 仿真都在虚拟机里面,那一般没问题;但如果你 QGC 装在 Windows 宿主,PX4 在虚拟机里,两者之间的网络桥接配置就要额外处理,最容易直接卡在这一步。所以初学者最好全程在同一个系统里搞定所有事。

5.2 仿真里的解锁逻辑

QGC 连上以后,界面上有个大大的"Arm"按钮(不同版本叫法略有差异)。点它,飞控进入"解锁准备"状态,再配合 Gazebo 窗口里已经加载的飞机,你就能用左下角的滑条起飞了。

需要提醒的是,SITL 里 GPS 是仿真出来的,所以 QGC 的地图可能显示飞机在某个不存在的点上,这很正常。起飞是否成功,看 QGC 的飞行界面高度读数变化。

5.3 内八解锁到底要设置什么参数

这个问题很多人在帖子里问。我要先泼一盆冷水:纯 SITL 环境里,你根本不需要纠结内八外八,QGC 点按钮就能解锁。

换成真实遥控器,解锁的关键不在于某个单独的"内八参数",而是一整套条件:

  • 遥控器完成了校准,通道方向正确。
  • RC_MAP_ARM_SWITCH参数没有被映射到某个拨杆通道。一旦映射了,飞控会认为你想用拨杆解锁,这时候摇杆手势就不再生效。
  • 解锁时油门必须在最低位,方向舵(偏航)打到一侧,保持一两秒。

如果你检查完这几点还是不解锁,先看飞行模式是否切到了可以解锁的模式(比如 Position 或 Manual),再查 QGC 的操纵杆故障诊断界面。实际经验里,八成不是参数不对,而是遥控器通道校准没做干净。

5.4 用 QGC 查看仿真内部状态

QGC 的价值不只在显示飞行数据。它还可以看飞控参数、实时调 PID、抓日志。

在 Analzye Tools(不同版本叫法可能不同)里能看到日志下载功能。SITL 模式下,PX4 会把飞控日志写到~/PX4-Autopilot/build/px4_sitl_default/tmp/rootfs/fs/microsd/log这里。这条路径很长,但你只需要记住:QGC 里的日志也能导出,和真实飞控的使用习惯一致。

6. 跑这套链路最容易踩的五个坑

6.1 Gazebo 模型下载卡死

Gazebo Classic 启动时,如果当前环境没有某个模型,会自动去网上下载。国内网络环境下,这一卡就是五分钟起步,界面看着像死机。

解决办法是先手动把模型下载好放到本地。常见的做法是去模型数据库里找到x500、sun、ground_plane这几个模型,下载后解压到~/.gazebo/models/目录下。之后 Gazebo 启动就不会再往外面请求资源。

还有一个细节:模型文件名和 Gazebo 寻找的名字必须完全一致,大小写都不能错。目录名字错了,照样报找不到模型。

6.2 端口占用导致连接失败

最常见的是 14550 被其他程序占用。你之前可能装过其他地面站软件,或者上一次 QGC 退出时没有释放端口。

排查命令:

sudo lsof -i :14550

看到有进程占着,先杀掉再重新启动仿真。如果是 QGC 自己没退出干净,直接重启系统更省事。

6.3 无图形环境或者 WSL 里的坑

如果你用的是 WSL2,默认没有图形界面,Gazebo 会启动失败。WSL2 现在支持 WSLg,可以显示窗口,但性能一般。

更稳的选择是装一套 Ubuntu 22.04 桌面系统,或者用 Windows 宿主机上的 Gazebo?但这会引入跨系统通信问题。所以再次强调:新手统一起步,别一开始就搞分布式。

6.4 编译慢到你怀疑人生

PX4 的 SITL 编译涉及大量 C++ 代码。给两个提升速度的思路:

  • 开启 ccache 缓存:sudo apt install ccache,之后第二次编译快非常多。
  • 用 Ninja 做生成器:PX4 默认已经配置了 Ninja,所以关键是不要反复全量编译,只编译改动过的部分。

如果只是改了某个模块,你可以直接:

make px4_sitl gazebo_x500

不要在 make 前随便加clean,除非你想从零开始。

6.5 常见错误对照表

现象可能原因解决思路
bind: Address already in use14550 端口被占用lsof -i :14550查进程并处理
QGC 连不上仿真端口不对或没开检查 UDP 14550/14540 配置
ROS 2 没有 DDS 话题Agent 没启动或 RMW 不一致检查 8888 端口、统一用 Fast DDS
Gazebo 长时间黑屏模型下载卡住手动部署模型到~/.gazebo/models
编译缺依赖ubuntu.sh 没完整跑完重跑脚本,或按报错逐个安装
启动报找不到型号PX4 版本和模型命名不匹配检查是gazebo_x500还是gz_x500

7. 进阶视角:这套链路迁到实机时要改什么

7.1 仿真和真机的三大差异

很多人在仿真里飞得溜,一上真机就懵。因为这套链路有三大差异:

  • 传感器噪声。仿真里的 GPS、IMU 数据过于理想,真机里 GPS 漂移、震动噪声全来。
  • 执行器延迟。Gazebo 的电机模型是理想响应,真机电机和电调存在延迟和温漂。
  • 通信环节。仿真里 PX4、Gazebo、QGC 全在一个系统,不存在信号遮挡和延迟。

这提醒我们一个重要原则:仿真验证的是逻辑,不是稳定性。解锁、起飞、降落这套基本流程可以在仿真里跑通,但 PID 参数必须带真机微调。

7.2 板载计算机这类架构怎么摆

最近不少人问我在 RK3588 这类板载计算机上怎么开发 PX4。我见到的正规做法,一般是飞控(比如 Pixhawk 系列)跑 PX4 固件,负责姿态控制、电机驱动;RK3588 作为板载计算机,跑 ROS 2、视觉识别路径规划,通过串口或以太网与飞控通信。

在这种架构里,PX4 和板载计算机之间同样可以用 XRCE-DDS 或 MAVLink 通信。PX4 把姿态、传感器数据发出来,板载计算机处理完成后把期望速度或目标位置发回给飞控。QGC 作为地面站,也通过同一路通信通道监控整个系统。

7.3 什么可以继续保留

你在这套仿真里学会的几件事,迁移到实机后一点都不会浪费:

  • PX4 的编译方式和固件更新逻辑。
  • QGC 的调参与日志分析方法。
  • ROS 2 和 PX4 的数据接口,尤其是fmu/out和fmu/in系列的话题。
  • 解锁前的安全检查清单。

我自己最大的体会是,这套东西的价值不在于"仿真里能飞",而在于它把真实开发流程完整压扁在了一台电脑上。你调试 PID、分析日志、验证传感器融合的姿态,和真机操作几乎是一套逻辑。把这里的习惯养好,真机上手会从容很多。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询