仿真环境总览:HITL 与 SITL 到底怎么选?

各位同学,欢迎来到《仿真联调》的第一章。

做飞控开发,最怕什么?怕炸机。一块 Pixhawk 几千块,配上机架、电机、电池,一次实飞失误可能就是几千块的损失。所以我一直跟团队说:先仿真,再实飞。这不是保守,这是职业习惯。

今天咱们先搞清楚两个核心概念:纯软件仿真(SITL)和半实物仿真(HITL)。然后我会带你走一遍 Gazebo + PX4 + QGroundControl 的协同流程。嗯,这套组合拳打好了,后面 29 章你会走得很顺。

1. 什么是 SITL?说白了就是“全虚拟”

SITL,全称 Software-in-the-Loop。你的飞控代码、传感器模型、物理引擎全部跑在电脑上。没有硬件,没有真实飞控板。

我个人习惯在开发新算法时先用 SITL。为什么?快。改完代码直接重启仿真,不用烧录、不用接线、不用等硬件初始化。你想想看,一天迭代几十次,省下来的时间都是实打实的。

SITL 的核心价值:低成本、高迭代速度、适合算法验证和回归测试。

但 SITL 有个坑——它无法模拟硬件延迟和传感器噪声的真实分布。我曾经在 SITL 里调好了一版 EKF 参数,上真机后直接发散。后来查原因,是 IMU 采样抖动和总线延迟在仿真里被理想化了。所以 SITL 通过后,别急着飞。

2. 什么是 HITL?半实物,更真实

HITL,Hardware-in-the-Loop。你把真实的飞控板(比如 Pixhawk)接到电脑上,但飞机本身还是虚拟的。飞控跑真实固件,传感器数据由仿真器通过串口或 UDP 注入。

这样做的好处很明显:你测试的是真实硬件上的真实代码。包括 bootloader、驱动层、实时调度、外设通信,全都在真实环境下跑。我在项目中遇到过好几次:SITL 里一切正常,HITL 里却出现串口丢帧、PWM 输出抖动。这些问题只有 HITL 才能暴露。

对比维度 SITL(纯软件) HITL(半实物)
硬件需求 仅电脑 电脑 + 飞控板 + 数传/线缆
启动速度 秒级 分钟级(需烧录固件)
测试覆盖 算法逻辑 算法 + 驱动 + 硬件时序
典型场景 新功能开发、CI 自动化 硬件适配、系统集成测试

注意:HITL 不是万能的。它无法模拟电机烧毁、桨叶断裂这类物理故障。真机测试仍然不可替代。HITL 的作用是帮你把硬件层面的 bug 提前抓出来,而不是替代实飞。

3. 三剑客:Gazebo + PX4 + QGroundControl

这套组合是目前开源飞控领域最主流的仿真方案。我简单拆解一下各自角色:

  • Gazebo:物理引擎 + 传感器仿真。它负责算重力、空气阻力、碰撞,然后输出 IMU、GPS、光流等数据。
  • PX4:飞控固件。在 SITL 模式下它作为本地进程运行;在 HITL 模式下它跑在真实飞控板上。
  • QGroundControl:地面站。显示姿态、航迹、参数,也可以发指令、调参、看日志。

三者的关系其实很简单:Gazebo 模拟世界 → PX4 做决策 → QGC 做监控。数据流是闭环的。

我的建议:初学者先从 SITL 入手。装好 PX4 工具链后,直接运行 make px4_sitl gazebo,QGC 会自动连接。整个过程不到 5 分钟就能看到飞机在 Gazebo 里动起来。这种即时反馈对建立信心很有帮助。

4. 协同工作流程:从启动到起飞

下面我列一个标准流程,你照着做就能跑通第一次仿真联调。

  1. 启动 Gazebo 仿真环境:终端执行 gazebo --verbose worlds/iris.world。你会看到一个四旋翼模型停在跑道上。
  2. 启动 PX4 SITL:在 PX4 固件目录下执行 make px4_sitl gazebo。这会编译飞控并自动连接 Gazebo。
  3. 打开 QGroundControl:启动后它会自动发现本地的 PX4 实例。你会在主界面看到飞机姿态、GPS 状态、电池电压等数据。
  4. 解锁并起飞:在 QGC 里点击“Arm”解锁,然后推油门。Gazebo 里的飞机会缓缓升空。

嗯,这里要注意:第一次启动时,Gazebo 加载模型可能会慢,耐心等。我曾经因为等不及反复重启,结果发现是电脑内存不够。建议至少 8GB 内存,16GB 更稳。

# 典型启动命令(SITL 模式)
cd ~/PX4-Autopilot
make px4_sitl gazebo

# 如果只想启动 Gazebo 而不自动加载飞机
gazebo --verbose worlds/iris.world

# 查看仿真状态
pxh> commander status

5. 一张图看懂整体架构

下面这张 SVG 图展示了 SITL 模式下三者的数据流向。我特意把关键端口和协议标出来了,方便你排查连接问题。

Gazebo + PX4 + QGC 协同架构图 SITL 仿真协同架构 Gazebo 物理引擎 + 传感器 PX4 SITL 飞控固件(本地进程) QGroundControl 地面站监控 MAVLink UDP 14560 MAVLink TCP 5760 数据流说明 1. Gazebo 模拟 IMU/GPS/气压计 → 通过 MAVLink 发给 PX4 2. PX4 运行控制律 → 输出电机 PWM → Gazebo 更新物理状态 3. PX4 将姿态/航迹/状态 → 通过 TCP 发给 QGC 显示 HITL 模式下 PX4 节点替换为真实飞控板,通过串口/UDP 与 Gazebo 通信

6. 避坑指南:我踩过的几个坑

最后分享几个实战中容易翻车的地方,你遇到了可以少走弯路。

  • 端口冲突:QGC 默认占用 5760 端口。如果你同时开了多个仿真实例,记得改端口。我曾经在 CI 里同时跑 4 个 SITL,结果全部连到同一个 QGC 上,数据全乱了。
  • Gazebo 卡死:如果 Gazebo 启动后黑屏或卡在 "waiting for master",检查 ~/.gazebo 目录权限。我遇到过因为之前异常退出导致 lock 文件残留,删掉就好了。
  • 固件版本不匹配:PX4 固件和 Gazebo 模型有对应关系。我建议用 PX4 v1.14 以上版本,搭配 Gazebo 11。老版本模型接口有差异,容易报 sensor 数据超时。

调试小技巧:在 PX4 终端输入 pxh> listener sensor_accel,可以实时查看加速度计数据。如果数值一直为 0,说明 Gazebo 和 PX4 之间的 MAVLink 通道没通。这时候先检查 gazebo --verbose 的输出,看有没有 "waiting for vehicle" 的提示。

好了,第一章就到这里。你先把 SITL 跑通,感受一下三剑客的配合节奏。后面我们会一步步深入,从单机仿真做到多机协同,再到故障注入和硬件在环。每一步我都会把实战中积累的经验拆给你看。