3. 仿真场景设计:基于Gazebo/JSBSim的典型飞行场景构建
仿真场景设计,说白了就是给飞控算法出考题。你想想看,一个算法在理想环境下跑得再好,到了真实环境里遇到风、遇到GPS丢星,立马就崩了,那有什么用?
我个人习惯,在SITL阶段至少要把四个典型场景跑透:悬停、巡航、风扰、GPS丢失。这四关过了,飞控才算有了基本的鲁棒性。
核心观点:仿真不是为了证明算法“能飞”,而是为了证明算法“在极端情况下不会炸”。
3.1 场景一:悬停——飞控的“呼吸”测试
悬停是所有多旋翼飞控的起点。如果连悬停都做不好,后面的巡航、抗风全是空谈。
在Gazebo中启动悬停场景很简单,但要注意几个关键参数:
# 启动PX4 SITL + Gazebo悬停场景
make px4_sitl gazebo
# 或者指定无人机模型
make px4_sitl gazebo_iris
嗯,这里要注意:默认的悬停场景是无风、无干扰的理想环境。我建议你在悬停测试中关注三个指标:
- 高度保持精度:±0.1m以内算及格,±0.05m算优秀
- 水平漂移量:理想情况下应小于0.2m
- 姿态角波动:滚转/俯仰角波动应小于±2°
我的经验:有一次我在项目中遇到悬停时无人机像“喝醉了酒”一样左右晃。查了半天,发现是IMU的加速度计噪声参数没配好。后来在仿真里把振动模型加上,问题就复现了。所以悬停测试一定要开振动模拟,别用理想IMU。
3.2 场景二:巡航——考验路径跟踪能力
巡航场景主要测试飞控的轨迹跟踪精度和速度控制。说白了,就是看无人机能不能按你规划的路径飞。
在Gazebo中,我通常用offboard模式发送位置/速度指令:
# 通过MAVSDK发送巡航指令
# 设置目标位置 (x, y, z) = (10, 10, -5)
# 设置目标速度 2 m/s
# 关键参数:
# - 巡航速度:建议从1m/s开始,逐步增加到5m/s
# - 转弯半径:与速度相关,速度越快转弯半径越大
# - 路径跟踪误差:RMS误差应小于0.5m
为什么会这样?因为巡航场景暴露的是飞控的前馈-反馈协调能力。纯反馈控制会导致转弯时滞后,而前馈项如果调得太激进又会超调。
| 巡航速度 | 建议转弯半径 | 典型跟踪误差 |
|---|---|---|
| 1 m/s | 2 m | ±0.2 m |
| 3 m/s | 5 m | ±0.4 m |
| 5 m/s | 10 m | ±0.8 m |
避坑指南:我曾经在巡航测试中遇到无人机在转弯时突然“甩尾”。后来发现是偏航角速度限制设得太低,导致转弯时偏航跟不上。记住:巡航场景一定要同时测试直线段和弯道段,别只飞直线。
3.3 场景三:风扰——飞控的“抗压”测试
风扰场景是仿真中最接近真实环境的测试。我个人认为,没有经过风扰测试的飞控,不配叫“完成”。
在Gazebo中模拟风扰有两种方式:
- 方法一:使用Gazebo的WindPlugin——直接给无人机施加风力
- 方法二:在SITL层面注入扰动——修改空气动力学模型
我推荐用WindPlugin,因为它更接近真实物理:
<!-- 在Gazebo world文件中添加风插件 -->
<plugin name="wind_plugin" filename="libWindPlugin.so">
<wind_direction>180</wind_direction>
<wind_speed_mean>5</wind_speed_mean>
<wind_speed_variation>2</wind_speed_variation>
</plugin>
风扰测试的典型场景包括:
- 阵风测试:突然施加5-8m/s的阵风,观察飞控恢复时间
- 持续侧风:施加恒定侧风,观察位置保持误差
- 风切变:在不同高度施加不同风速,模拟真实大气环境
关键指标:抗风能力通常用“最大可抵抗风速”来衡量。消费级无人机一般在5-8m/s,工业级可以到12-15m/s。在仿真中,我建议从3m/s开始,每次增加1m/s,直到飞控失稳。
3.4 场景四:GPS丢失——飞控的“盲飞”测试
GPS丢失是真实飞行中最常见的故障之一。你想想看,在城市峡谷、隧道或者强电磁干扰环境下,GPS信号说丢就丢。
在SITL中模拟GPS丢失很简单:
# 通过MAVSDK或mavlink命令模拟GPS丢失
# 方法1:直接断开GPS模块
# 方法2:发送GPS数据无效标志
# 观察飞控行为:
# - 是否自动切换到光流/视觉定位?
# - 高度保持是否依赖气压计?
# - 位置漂移速度是多少?
我个人习惯,GPS丢失测试要分三个等级:
| 等级 | 场景描述 | 飞控预期行为 |
|---|---|---|
| L1 | GPS短暂丢失(<5s) | 保持最后位置,等待GPS恢复 |
| L2 | GPS丢失(5-30s) | 切换到视觉/光流定位,或进入悬停模式 |
| L3 | GPS永久丢失 | 触发返航(如果无视觉)或紧急降落 |
避坑指南:我曾经在项目中遇到GPS丢失后无人机直接“放飞自我”——因为它没有配置任何备用定位源。后来我在仿真里加了光流传感器,并设置了传感器失效切换逻辑。记住:GPS丢失测试一定要配合传感器融合策略一起测,别只测“丢GPS”这一个动作。
3.5 场景组合与自动化测试
单个场景测完了,还得测组合场景。比如:巡航中遇到阵风,同时GPS丢失——这才是真实世界的常态。
我建议用Python脚本把四个场景串起来,实现自动化测试:
# 自动化测试脚本伪代码
def run_scenario_sequence():
# 1. 启动SITL + Gazebo
# 2. 悬停测试(60s)
# 3. 巡航测试(120s)
# 4. 风扰测试(90s)
# 5. GPS丢失测试(60s)
# 6. 记录日志,分析性能指标
下面这张图展示了四个场景的测试流程和关键节点:
我的建议:自动化测试脚本一定要记录时间戳和传感器状态。这样在分析日志时,你能精确知道“在哪个时间点,哪个传感器失效了,飞控做了什么反应”。没有时间戳的日志,说白了就是一堆废数据。
3.6 场景参数配置清单
最后,我整理了一份场景参数配置清单,方便你快速搭建测试环境:
| 场景 | 关键参数 | 推荐值 | 备注 |
|---|---|---|---|
| 悬停 | 高度、水平漂移、姿态波动 | ±0.1m, <0.2m, ±2° | 开启振动模拟 |
| 巡航 | 速度、转弯半径、跟踪误差 | 1-5 m/s, 2-10m, <0.5m | 包含直线+弯道 |
| 风扰 | 风速、风向、阵风幅度 | 3-12 m/s, 随机方向 | 从3m/s逐步增加 |
| GPS丢失 | 丢失时长、备用定位源 | 5s/30s/永久 | 配置传感器切换逻辑 |
这四个场景,每一个都能暴露飞控的不同短板。悬停测的是基础稳定性,巡航测的是轨迹跟踪,风扰测的是鲁棒性,GPS丢失测的是故障处理能力。把它们组合起来跑一遍,你的飞控才算真正经得起考验。