第二章 传感器原理与数据融合

做飞控这些年,我最大的体会就是:姿态解算就像在嘈杂的酒吧里听清朋友说话。传感器就是你的耳朵,但每个耳朵都有点“耳背”——陀螺仪漂移、加速度计抖动、磁力计受干扰。怎么把这些不完美的信号融合成可靠的姿态?这就是本章要聊的核心。

本章知识体系

传感器原理与数据融合 陀螺仪 角速度测量 加速度计 重力加速度测量 磁力计 地磁场测量 误差模型与校准 误差模型与校准 误差模型与校准 数据融合算法 互补滤波 | Mahony | Madgwick 姿态输出

2.1 陀螺仪:角速度的忠实记录者

陀螺仪测量的是角速度,单位是 °/s 或 rad/s。说白了,就是告诉你飞机转得有多快。我最早接触的是 MPU6050 里的 MEMS 陀螺仪,那玩意儿便宜但噪声大。

工作原理:MEMS 陀螺仪利用科里奥利力效应。内部有一个高速振动的质量块,当传感器旋转时,质量块会受到一个垂直于振动方向的力,这个力的大小与角速度成正比。通过检测这个力,就能算出角速度。

我的经验:陀螺仪最怕的是零偏漂移。刚上电时数据还行,飞了十分钟就开始慢慢偏。我有个项目,就是因为没做温补,悬停时飞机慢慢自旋。后来加了温度补偿,问题才解决。

误差模型

  • 零偏(Bias):静止时输出不为零,随时间缓慢变化
  • 比例因子误差:实际角速度与测量值之间的比例偏差
  • 交叉轴耦合:一个轴的旋转会影响到其他轴的输出
  • 随机游走:积分后产生的随机误差累积

校准方法

// 陀螺仪零偏校准 - 静止采样取平均
void calibrateGyro() {
    float sum[3] = {0, 0, 0};
    int samples = 200;
    
    for (int i = 0; i < samples; i++) {
        readGyro(gx, gy, gz);
        sum[0] += gx;
        sum[1] += gy;
        sum[2] += gz;
        delay(5);
    }
    
    gyroBias[0] = sum[0] / samples;
    gyroBias[1] = sum[1] / samples;
    gyroBias[2] = sum[2] / samples;
}

注意:校准时要确保无人机完全静止。我曾经在桌面上校准,结果桌子在抖,校准出来的零偏全是错的。后来我都是把飞机放地上,等三分钟再校准。

2.2 加速度计:重力方向的感知者

加速度计测量的是比力,也就是物体受到的加速度(包括重力)。静止时,它测到的就是重力加速度 g。利用这个特性,我们可以算出俯仰角和横滚角。

工作原理:MEMS 加速度计内部有一个微小的质量块,通过弹簧结构悬挂。当有加速度时,质量块会移动,改变电容值。测量电容变化就能算出加速度。

为什么加速度计不能单独用?因为它分不清重力加速度和运动加速度。你想想看,飞机往前加速时,加速度计会以为重力方向变了,导致姿态计算错误。这就是为什么需要陀螺仪来帮忙。

误差模型

  • 零偏:静止时输出不为 0g 或 1g
  • 比例因子:不同轴灵敏度不一致
  • 非线性:大加速度下输出失真
  • 噪声:高频振动噪声,尤其是电机转动时

六面校准法

位置 X轴 Y轴 Z轴
水平朝上 0g 0g +1g
水平朝下 0g 0g -1g
左侧朝上 0g +1g 0g
右侧朝上 0g -1g 0g
前倾朝上 +1g 0g 0g
后倾朝上 -1g 0g 0g

避坑指南:我曾经用塑料支架做六面校准,结果支架本身有弹性,放上去后不是完全水平。后来我改用金属直角块,精度才上来。校准这事,工装很重要。

2.3 磁力计:航向的指南针

磁力计测量的是地磁场。没有它,无人机就不知道自己的航向(偏航角)。但磁力计也是最娇气的传感器——周围有铁磁物质就会干扰。

工作原理:常见的是各向异性磁阻(AMR)传感器。内部有磁阻材料,外部磁场会改变其电阻值。通过测量电阻变化,就能算出磁场强度。

误差模型

  • 硬铁干扰:永磁体或带磁物体产生的固定偏移
  • 软铁干扰:铁磁材料对磁场的扭曲,导致椭圆变形
  • 比例因子误差:各轴灵敏度不一致
  • 非正交误差:三个轴不是严格垂直

椭圆拟合校准

// 磁力计校准 - 采集数据后做椭圆拟合
void calibrateMag() {
    // 旋转无人机采集所有方向的数据
    // 理想情况下,数据点应分布在球面上
    // 实际是椭球,需要求偏移和缩放矩阵
    
    // 最小二乘法拟合椭球
    // 得到偏移量 offset[3] 和缩放矩阵 scale[3][3]
    
    // 校准后的值 = scale * (raw - offset)
}

警告:磁力计校准必须在远离铁磁物质的地方进行。我见过有人直接在金属桌子上校准,结果飞出去后航向偏了 30 度。还有,电机和电调也会产生磁场干扰,最好在装机后做最终校准。

2.4 互补滤波:简单有效的融合方法

互补滤波的原理很直观:陀螺仪动态响应快但会漂移,加速度计和磁力计没有漂移但噪声大。那就让陀螺仪负责高频部分,加速度计和磁力计负责低频部分。

说白了就是:

姿态 = α × (陀螺仪积分) + (1-α) × (加速度计/磁力计计算)

其中 α 通常取 0.98 左右。α 越大,越信任陀螺仪;α 越小,越信任加速度计。

我的习惯:α 值我一般根据运动剧烈程度动态调整。悬停时 α 小一点,让加速度计多参与;快速机动时 α 大一点,避免加速度计被运动加速度干扰。

2.5 Mahony 与 Madgwick:更优雅的姿态解算

这两个算法都是基于四元数的,比互补滤波更精确。我个人更常用 Madgwick,因为它收敛速度快,而且计算量适中。

Mahony 算法

  • 基于 PI 控制器的思想
  • 用加速度计和磁力计的测量值修正陀螺仪的积分误差
  • 计算量小,适合低性能 MCU

Madgwick 算法

  • 基于梯度下降法
  • 每一步都向误差减小的方向调整四元数
  • 收敛速度快,精度高
  • 需要调整步长参数 β
// Madgwick 算法核心 - 简化版
void MadgwickUpdate(float gx, float gy, float gz, 
                    float ax, float ay, float az,
                    float mx, float my, float mz, float dt) {
    // 1. 计算陀螺仪的四元数导数
    // 2. 用加速度计计算误差梯度
    // 3. 用磁力计计算误差梯度
    // 4. 梯度下降法修正四元数
    // 5. 归一化四元数
    
    // 具体实现可参考 Sebastian Madgwick 的论文
}

选型建议

  • STM32F103 级别:用互补滤波或 Mahony
  • STM32F4 及以上:用 Madgwick,精度更好
  • 带 FPU 的芯片:可以跑更复杂的 EKF(扩展卡尔曼滤波)

嗯,这里要注意一点:Madgwick 的 β 参数很关键。β 太大,算法会过度信任加速度计,导致动态响应变差;β 太小,又收敛太慢。我一般从 0.1 开始调,看实际效果再微调。

做飞控这些年,我越来越觉得传感器融合就像和人打交道——每个传感器都有自己的脾气,你要了解它、信任它该信任的部分、忽略它该忽略的部分。互补滤波、Mahony、Madgwick,说到底都是帮我们做这件事的工具。

最后分享一个经验:不管用什么算法,一定要做传感器数据的时间戳对齐。我踩过这个坑——陀螺仪和加速度计采样时间差了 2ms,结果姿态解算出来一直在抖。后来加了时间戳同步,问题就解决了。


公众号:蓝海资料掘金营,微信deep3321