3. SITL技术原理
好,咱们进入第三章。前两章我们把 SITL 环境搭起来了,也跑通了第一个仿真。但说实话,那个仿真用的是默认的「通用四旋翼」,跟实际飞控差得还挺远。
这一章,我们就来干三件事:加载真正的多旋翼模型、配置传感器模型、以及入门参数调优。这三件事搞定了,你的仿真才算「活」了。
本章核心目标:让仿真模型的行为尽可能接近真实无人机。不是「能飞就行」,而是「飞起来的感觉要对」。
3.1 多旋翼模型加载:从默认到定制
ArduPilot 的 SITL 支持多种机型。默认启动的是 quad(四旋翼),但你也可以加载 hexa(六旋翼)、octa(八旋翼)、甚至 Y6 或自定义构型。
我个人习惯,在项目初期就明确机型。因为不同机型的混控矩阵、动力响应都不一样。你想想看,四旋翼和六旋翼的故障容错逻辑完全不同——四旋翼坏一个电机基本就炸了,六旋翼还能勉强飞回来。
3.1.1 加载指定机型
启动时用 --model 参数指定:
sim_vehicle.py -v ArduCopter --model hexa --console --map
这会加载一个六旋翼模型。你可以在控制台看到类似这样的输出:
AP: ArduCopter V4.5.0 (e1f2c3d4)
AP: Frame: HEXA
AP: Calibrating barometer... done
嗯,这里要注意:--model 参数不仅决定了外观,还决定了飞控内部的混控矩阵。我见过有人用四旋翼的模型去调六旋翼的参数,结果飞起来抖得跟筛子一样。
3.1.2 自定义构型
如果你用的是非标构型(比如 X8 共轴双桨、或者带倾转机构的 VTOL),就需要自己写混控文件了。
混控文件放在 libraries/AP_Motors/ 目录下,格式是 .mix。举个例子,一个简单的四旋翼混控文件片段:
# Motor 1: Front Right (CW)
Motor 1: 1.0 1.0 -1.0 -1.0
# Motor 2: Rear Left (CW)
Motor 2: 1.0 -1.0 1.0 -1.0
# Motor 3: Front Left (CCW)
Motor 3: 1.0 1.0 1.0 1.0
# Motor 4: Rear Right (CCW)
Motor 4: 1.0 -1.0 -1.0 1.0
每一行的四个数字分别代表:油门、横滚、俯仰、偏航的混控系数。正负号代表旋转方向。
我的经验:如果你要自定义混控,先在纸上画清楚电机布局和旋转方向。我曾经在项目里把两个电机的混控系数写反了,结果一解锁飞机直接在地上打转。排查了半小时才发现是符号错了。
3.2 传感器模型配置:GPS、IMU、磁力计
仿真里的传感器模型,说白了就是「模拟真实传感器的噪声和误差」。没有这些噪声,你的仿真就是「理想世界」,跟实际飞行差太远。
ArduPilot SITL 的传感器模型通过 --gimbal、--speedup 等参数控制,但更精细的配置在参数文件里。
3.2.1 GPS 模型
GPS 的主要参数包括:
| 参数名 | 默认值 | 说明 |
|---|---|---|
GPS_TYPE |
1(UBlox) | GPS 协议类型 |
GPS_HDOP |
0.8 | 水平精度因子,越小越好 |
GPS_POS1_X/Y/Z |
0 | GPS 天线在机体上的位置偏移 |
在 SITL 中,GPS 的噪声模型通过 SIM_GPS_* 参数控制:
# 设置 GPS 水平位置噪声(单位:米)
param set SIM_GPS_GLITCH 0.3
# 设置 GPS 丢失模拟(每隔 300 秒丢失一次)
param set SIM_GPS_DROP 0
为什么要调这个?我遇到过一个问题:仿真里 GPS 信号完美无缺,但实际飞的时候,树荫下 GPS 飘了 5 米,飞机直接往树上撞。所以我现在做仿真,一定会把 SIM_GPS_GLITCH 设到 0.5 以上,模拟真实环境。
3.2.2 IMU 模型
IMU 是飞控的核心传感器。它的噪声模型包括加速度计和陀螺仪两部分。
关键参数:
| 参数名 | 默认值 | 说明 |
|---|---|---|
INS_ACCEL_FILTER |
20 Hz | 加速度计低通滤波频率 |
INS_GYRO_FILTER |
80 Hz | 陀螺仪低通滤波频率 |
INS_ACC2OFFS_X/Y/Z |
0 | 加速度计零偏 |
在 SITL 中,IMU 噪声通过 SIM_IMU_* 参数模拟:
# 设置加速度计噪声标准差(m/s²)
param set SIM_IMU_ACC_BIAS 0.05
# 设置陀螺仪噪声标准差(rad/s)
param set SIM_IMU_GYR_BIAS 0.001
注意:IMU 噪声设得太大,飞控的 EKF(扩展卡尔曼滤波器)会发散。设得太小,仿真又太理想。我一般从默认值开始,然后逐步增大,直到飞控出现轻微的振动响应——这个状态最接近真实。
3.2.3 磁力计模型
磁力计(指南针)是很多问题的根源。在仿真里,磁力计模型默认是完美的——没有干扰、没有硬铁/软铁偏差。但实际飞行中,电机电流、机架钢材都会影响磁力计。
相关参数:
# 模拟磁力计干扰(单位:高斯)
param set SIM_MAG_OFFSET 0.02
# 模拟磁力计噪声
param set SIM_MAG_NOISE 0.01
我曾经在项目里遇到一个诡异的问题:仿真里航向保持得很好,但实际飞的时候,飞机总是慢慢偏航。排查了两天,最后发现是磁力计受到了电调 PWM 线的电磁干扰。从那以后,我仿真里一定会把 SIM_MAG_OFFSET 设到 0.05 以上,提前暴露问题。
3.3 参数调优入门:从 PID 开始
参数调优是个大话题,这里我们只讲入门——怎么让飞机飞得稳。
最核心的是 PID 参数。对于多旋翼,主要调三个环:横滚(Roll)、俯仰(Pitch)、偏航(Yaw)。
3.3.1 核心 PID 参数
| 参数名 | 作用 | 典型范围 |
|---|---|---|
ATC_RAT_RLL_P |
横滚角速率 P 增益 | 0.10 - 0.25 |
ATC_RAT_RLL_I |
横滚角速率 I 增益 | 0.10 - 0.20 |
ATC_RAT_RLL_D |
横滚角速率 D 增益 | 0.001 - 0.008 |
ATC_RAT_PIT_P |
俯仰角速率 P 增益 | 0.10 - 0.25 |
ATC_RAT_YAW_P |
偏航角速率 P 增益 | 0.15 - 0.30 |
3.3.2 调参步骤(我的习惯)
- 先调横滚和俯仰:这两个轴对称,参数可以一样。
- 从 P 开始:把 I 和 D 先设小,只调 P。慢慢增大,直到飞机出现轻微振荡,然后回调 20%。
- 加 I:I 的作用是消除稳态误差。如果飞机悬停时慢慢倾斜,说明 I 不够。
- 加 D:D 抑制振荡。如果飞机抖得厉害,适当增大 D。
- 最后调偏航:偏航响应可以慢一点,P 值通常比横滚小。
避坑指南:我曾经在调参时,把 P 设得太大,结果飞机一解锁就剧烈振荡,差点把桨甩飞。记住一个原则:P 是「力度」,I 是「持久力」,D 是「刹车」。三者要平衡。
3.4 本章知识体系
下面这张图总结了本章的核心逻辑:
3.5 实战:快速验证配置
最后,我们跑一个快速验证。启动 SITL,加载六旋翼模型,然后手动设置一些传感器噪声:
# 启动六旋翼
sim_vehicle.py -v ArduCopter --model hexa --console
# 在 MAVProxy 控制台中设置参数
param set SIM_GPS_GLITCH 0.5
param set SIM_IMU_ACC_BIAS 0.08
param set SIM_MAG_OFFSET 0.05
# 解锁并起飞
arm throttle
mode guided
takeoff 10
观察控制台输出和地图。如果飞机在悬停时出现轻微的漂移和抖动——恭喜你,你的仿真已经接近真实了。
注意:如果飞机直接炸了(Crash),别慌。检查一下参数是否设得太大,或者模型是否加载正确。我刚开始调的时候,几乎每三次就炸一次。这是正常的。