理解互补滤波原理,实现IMU传感器融合的姿态估计。
| 传感器 | 优势 | 劣势 | 频率 |
|---|---|---|---|
| 陀螺仪 | 短期精度高 | 零偏漂移 | 高通 |
| 加速度计 | 长期稳定 | 噪声大/受运动干扰 | 低通 |
| 磁力计 | 航向绝对参考 | 磁干扰 | 低通 |
θ̂(t) = α·[θ̂(t-1) + ωgyro·dt] + (1-α)·θaccel
α∈(0,1),通常0.95~0.99
高通取陀螺仪 + 低通取加速度计 = 全通
# 二阶互补滤波(Mahony简化版)
error = accel_angle - angle
angle += gyro * dt + Kp * error * dt
bias += Ki * error * dt # 在线估计零偏
gyro_corrected = gyro - bias
angle += gyro_corrected * dtdef comp_filter_3axis(q, gyro, accel, mag, dt, alpha=0.98):
# 1. 陀螺仪积分(预测)
q_pred = integrate_quat(q, gyro, dt)
# 2. 加速度计修正(roll/pitch)
accel_err = cross(accel, gravity_ref)
# 3. 磁力计修正(yaw)
mag_err = cross(mag_body, mag_ref)
# 4. 互补融合
correction = (1-alpha) * (accel_err + mag_err)
return integrate_quat(q, gyro+correction, dt)=== 互补滤波 vs 原始传感器 ===
方法 平均误差(deg)
----------------------------------------
纯陀螺仪积分 5.72°
互补滤波 0.51°
误差降低: 91.1%
✅ 互补滤波利用传感器互补频率特性
✅ α=0.98常用平衡值
✅ 二阶版本可在线估计零偏
✅ 三轴需加速度计(roll/pitch)+磁力计(yaw)
1. 强振动下互补滤波表现。2. 一阶vs二阶对比。3. 不同α截止频率计算。
掌握互补滤波与三轴传感器融合
class MahonyFilter:
def __init__(self, kp=2.0, ki=0.005):
self.kp, self.ki = kp, ki
self.bias = [0, 0, 0]
def update(self, q, gyro, accel, dt):
accel_n = normalize(accel)
gravity = quat_rotate(q, [0, 0, -1])
error = cross(accel_n, gravity)
self.bias = [b + self.ki*e*dt for b,e in zip(self.bias, error)]
gyro_corr = [g + self.kp*e + b for g,e,b in zip(gyro, error, self.bias)]
return normalize(integrate_quat(q, gyro_corr, dt))
| 特性 | Mahony | Madgwick |
|---|---|---|
| 方法 | PI控制 | 梯度下降 |
| 零偏估计 | 显式(积分项) | 隐式 |
| 计算量 | 稍大 | 较小 |
| 动态精度 | 略优 | 相当 |
本课涉及的核心公式和算法需要反复练习才能真正掌握。建议通过修改仿真参数、添加扰动等方式深入理解每个参数对系统行为的影响。在实际飞行中,这些参数的选择往往需要在理论分析的基础上结合实验微调。
| 指标 | 消费级 | 工业级 | 研究级 |
|---|---|---|---|
| 姿态精度 | ±2° | ±0.5° | ±0.1° |
| 位置精度(GPS) | ±2m | ±0.5m | ±2cm(RTK) |
| 悬停精度 | ±1m | ±0.3m | ±0.05m |
| 控制频率 | 400Hz | 1kHz | 1kHz+ |
| 传感器融合 | 互补滤波 | EKF | EKF/VIO |
| 续航时间 | 20-30min | 30-45min | 视载荷而定 |
不同传感器采样率不同,需要精确的时间同步:
| 传感器 | 采样率 | 延迟 | 同步方式 |
|---|---|---|---|
| IMU | 1kHz | <1ms | 硬件中断 |
| GPS | 5-10Hz | 50-200ms | PPS+时间戳 |
| 气压计 | 50Hz | 5-20ms | 软件对齐 |
| 磁力计 | 100Hz | <5ms | 软件对齐 |
| 光流 | 30Hz | 10-30ms | 时间戳补偿 |
# 传感器到达时立即更新(异步EKF)
# 而不是等待所有传感器一起更新
def ekf_update_loop():
while True:
msg = next_sensor_message()
if msg.type == 'IMU':
ekf.predict(msg.gyro, msg.accel, msg.dt)
elif msg.type == 'GPS':
ekf.update_position(msg.lat, msg.lon, msg.alt)
elif msg.type == 'BARO':
ekf.update_altitude(msg.pressure)
elif msg.type == 'MAG':
ekf.update_heading(msg.mag)
elif msg.type == 'FLOW':
ekf.update_flow(msg.vx, msg.vy)
在实际飞控系统中,算法必须在有限的计算资源下实时运行。以下为本课核心算法的复杂度分析:
| 算法/模块 | 时间复杂度 | 空间复杂度 | 典型耗时 |
|---|---|---|---|
| 互补滤波 | O(1) | O(1) | <1μs |
| 卡尔曼滤波(15态) | O(n²) | O(n²) | ~50μs |
| EKF(15态) | O(n³) | O(n²) | ~200μs |
| 串级PID | O(1) | O(1) | <5μs |
| A*(N节点) | O(N log N) | O(N) | 1-100ms |
| RRT(N步) | O(N·K) | O(N) | 10-500ms |
| 最小snap(M段) | O(M³) | O(M²) | ~1ms |
无人机飞控是典型的实时嵌入式系统,必须满足严格的时序约束:
# 典型飞控任务优先级(高→低)
# 1. IMU采样+姿态估计 (1kHz, 优先级最高)
# 2. 角速度PID控制 (1kHz)
# 3. 姿态PID控制 (500Hz)
# 4. EKF状态更新 (200Hz)
# 5. 位置/速度控制 (100Hz)
# 6. 路径规划/避障 (10-50Hz)
# 7. 通信/日志 (1-10Hz)
# RTOS调度: 优先级抢占 + 时间片轮转
飞控软件是安全关键系统,代码质量要求极高:
# 单元测试示例
def test_pid_output():
pid = PID(kp=1.0, ki=0, kd=0)
assert pid.update(1.0, 0.01) == 1.0 # P=1*1.0
def test_pid_integral_limit():
pid = PID(kp=0, ki=1.0, kd=0, i_limit=5.0)
for _ in range(1000):
pid.update(1.0, 0.01) # 大量积分
assert abs(pid.integral) <= 5.0 # 不超过限幅
def test_kalman_convergence():
kf = KalmanFilter(...)
for _ in range(100):
kf.predict()
kf.update(measurement)
assert kf.P[0,0] < initial_P # 协方差下降
| 特性 | PX4 | ArduPilot | Betaflight |
|---|---|---|---|
| 定位 | 研究/工业 | 工业/爱好者 | 竞速穿越 |
| 代码量 | ~500K行 | ~800K行 | ~200K行 |
| 支持的机型 | 多旋翼/固定翼/VTOL | 多旋翼/固定翼/直升机/车/船 | 多旋翼/固定翼 |
| 导航能力 | 强(全面) | 强(最全面) | 弱(仅自稳) |
| 实时性 | NuttX RTOS | ChibiOS/RTOS | Bare-metal |
| 仿真支持 | SITL/Gazebo/AirSim | SITL/Gazebo | 有限 |
| 社区活跃度 | 高 | 最高 | 高(竞速圈) |
无人机系统属于安全关键(Safety-Critical)系统,设计时必须遵循以下原则:
本课所学技术在以下场景中直接应用:
将本课模块集成到完整系统时的注意事项: