4. Gazebo基础操作

Gazebo 这个工具,说白了就是我们的「虚拟试飞场」。在真机上天之前,所有的航线逻辑、参数调优、故障注入,都得在这里跑一遍。我个人习惯把 Gazebo 当作一个「沙盒」——你可以在里面随便摔飞机,摔完了点一下重启就行,成本为零。

这一章我们重点解决三件事:怎么把仿真世界跑起来、怎么选对无人机模型、以及怎么让传感器数据看起来像真的一样。

4.1 世界模型加载:你的虚拟试飞场

Gazebo 启动时需要一个「世界文件」(.world),它定义了地面、光照、重力、风场等环境参数。PX4 官方提供了一套现成的世界文件,存放在 Tools/sitl_gazebo/worlds 目录下。

4.1.1 启动一个空世界

最简单的启动方式,直接用 make 命令带上目标机型:

make px4_sitl gazebo

这会加载默认的 empty.world——一个平坦的灰色地面,啥也没有。适合做最基础的姿态控制测试。

小技巧: 如果你只想跑仿真,不想每次都编译 PX4,可以用 make px4_sitl gazebo-classic 跳过固件编译步骤,前提是你已经编译过一次。

4.1.2 加载自定义世界

想换个带建筑、树木、跑道的地图?指定 PX4_SITL_WORLD 环境变量就行:

export PX4_SITL_WORLD=$HOME/PX4-Autopilot/Tools/sitl_gazebo/worlds/warehouse.world
make px4_sitl gazebo

我项目中常用的是 baylands.world——一个沿海机场场景,有跑道、机库和海岸线,非常适合做航线验证。你想想看,如果你的航线在空旷的平地上能飞,但在有障碍物的场景里会不会撞树?这就是换世界文件的意义。

4.1.3 世界文件结构速览

一个 .world 文件本质上是 SDF(Simulation Description Format)格式的 XML。核心结构如下:

元素 作用 常用参数
<scene> 场景光照与背景 ambient、sky、shadows
<model> 静态物体(建筑、地面) static、pose、geometry
<physics> 物理引擎参数 gravity、max_step_size
<plugin> 功能插件(风场、GPS 模拟) wind、magnetic_field
注意: 世界文件中的 <physics> 参数会影响仿真实时性。我曾经把 max_step_size 设得太大,结果飞机在空中像「瞬移」一样,根本没法控制。建议保持默认值 0.001。

4.2 无人机模型选择:从四旋翼到VTOL

PX4 在 Gazebo 中支持的机型非常多。启动时通过 PX4_SIM_MODEL 环境变量来选择:

export PX4_SIM_MODEL=iris
make px4_sitl gazebo

4.2.1 常用机型一览

模型名称 机型类型 适用场景
iris 四旋翼 基础飞行、航线验证
typhoon_h480 六旋翼 载重测试、故障注入
standard_vtol 垂直起降固定翼 过渡飞行、长航时测试
plane 固定翼 高速巡航、滑跑起降
rover 地面车 无人车路径规划

我个人最常用的是 iris 模型。它稳定、轻量,而且传感器配置齐全——GPS、IMU、磁力计、气压计、光流都有。说白了,它就是仿真界的「训练机」。

4.2.2 模型文件在哪?

所有模型定义都在 Tools/sitl_gazebo/models 目录下。每个模型一个文件夹,里面包含:

  • model.sdf:模型本体描述(几何、惯性、关节)
  • model.config:元信息(名称、作者、版本)
  • meshes/:3D 网格文件(.dae 或 .stl)
关键点: 如果你想修改飞机的物理参数(比如重量、电机推力),直接编辑 model.sdf 中的 <inertial> 和 <link> 节点。我曾在一次项目中把无人机重量减半,结果 PID 参数全得重调——仿真里改参数比真机快多了。

4.3 传感器仿真配置:让数据「像真的」

仿真和真机最大的区别在哪?传感器噪声。真机上的 IMU 有漂移、GPS 有跳变、磁力计有干扰。如果仿真里传感器数据太「干净」,那你写出来的航线逻辑到真机上大概率会翻车。

4.3.1 传感器插件机制

Gazebo 通过插件(plugin)来模拟传感器。每个传感器插件都是一个动态库(.so 文件),在模型 SDF 文件中通过 <plugin> 标签加载。

以 IMU 为例,它的插件配置长这样:

<plugin name="imu_plugin" filename="libgazebo_imu_plugin.so">
  <robotNamespace>/</robotNamespace>
  <linkName>base_link</linkName>
  <gyroscopeNoiseDensity>0.00018665</gyroscopeNoiseDensity>
  <accelerometerNoiseDensity>0.0018683</accelerometerNoiseDensity>
  <gyroscopeRandomWalk>0.000038785</gyroscopeRandomWalk>
  <accelerometerRandomWalk>0.0061815</accelerometerRandomWalk>
</plugin>

这些噪声参数不是随便填的。我一般会从真实传感器的数据手册里抄——比如 MPU9250 的陀螺仪噪声密度大约是 0.005 °/s/√Hz,换算成 rad/s 就是上面的值。

4.3.2 常用传感器插件

传感器 插件名称 关键参数
IMU libgazebo_imu_plugin.so gyroscopeNoiseDensity, accelerometerNoiseDensity
GPS libgazebo_gps_plugin.so gpsNoise, eph, epv
磁力计 libgazebo_magnetometer_plugin.so noiseDensity, randomWalk
气压计 libgazebo_barometer_plugin.so noiseDensity, pressureStdDev
光流 libgazebo_opticalflow_plugin.so pixelNoise, minHeight

4.3.3 如何调整噪声水平?

嗯,这里有个坑。很多人觉得噪声越小越好,其实不是。仿真噪声应该匹配你实际使用的传感器型号。比如:

  • 消费级 GPS(u-blox M8N):水平精度 2.5m,设置 eph=2.5
  • 工业级 GPS(RTK 差分):水平精度 0.02m,设置 eph=0.02
  • 视觉里程计:噪声比 GPS 小,但会有漂移累积
避坑指南: 我曾经在仿真里把 GPS 噪声设成 0,结果航线飞得完美无缺。一上真机,GPS 跳了 3 米,飞机直接偏航撞树。从那以后,我每次仿真都会故意加一点噪声——宁可仿真里飞得「烂一点」,也比真机炸机强。

4.4 知识结构总览

下面这张图把本章的核心逻辑串起来了。你可以把它当作操作前的「检查清单」:

Gazebo基础操作知识结构 Gazebo 基础操作知识结构 世界模型加载 无人机模型选择 传感器仿真配置 empty.world / warehouse.world SDF 格式 / physics 参数 iris / typhoon_h480 / vtol model.sdf / model.config IMU / GPS / 磁力计 / 气压计 噪声参数 / 插件配置 操作流程:启动 → 选模型 → 调传感器 → 验证 PX4_SIM_MODEL 环境变量选择机型 PX4_SITL_WORLD 环境变量选择世界 噪声参数调优 匹配真实传感器 核心原则:仿真越「真实」,真机越安全 世界 + 模型 + 传感器 = 完整的仿真环境

4.5 实战小练习

光看不练可不行。我建议你按下面的步骤走一遍:

  1. 启动 iris 在 baylands 世界:export PX4_SIM_MODEL=iris; export PX4_SITL_WORLD=baylands; make px4_sitl gazebo
  2. 打开 Gazebo 的 Topic 列表:在 Gazebo 界面中点击 Window → Topics,观察 /gazebo/default/pose/info 数据
  3. 修改 IMU 噪声参数:编辑 Tools/sitl_gazebo/models/iris/model.sdf,把 gyroscopeNoiseDensity 增大 10 倍,重启仿真看效果
  4. 切换机型:换成 standard_vtol,观察起飞和过渡飞行的区别
我的经验: 每次换机型或改传感器参数后,记得用 make clean 清理缓存。否则 Gazebo 可能加载旧模型,你改了半天发现没生效——嗯,我踩过这个坑。

Gazebo 的操作熟练度,直接决定了你后续做航线验证的效率。别急着飞复杂的航线,先把世界、模型、传感器这三个基础模块玩透。它们就像你的工具箱——工具顺手了,活才能干得漂亮。