传感器故障诊断:IMU异常检测、GPS信号丢失、气压计漂移处理

传感器出问题,是无人机坠毁的头号元凶。

我做了这么多年飞控,见过太多因为传感器故障炸机的案例。说白了,飞控再聪明,也架不住传感器给它喂假数据。今天咱们就聊聊三个最要命的传感器故障:IMU异常、GPS丢失、气压计漂移。

一、IMU异常检测:飞控的“内耳”出问题了

IMU就是无人机的内耳。它告诉你飞机现在是什么姿态,朝哪个方向在转。一旦它出问题,飞控就变成了瞎子。

常见的IMU异常有哪些?

  • 数据跳变:加速度计或陀螺仪的输出突然出现不合理的大幅跳动
  • 数据冻结:传感器数值卡在某个值不动了,飞机明明在动,数据却不变
  • 温漂严重:温度变化导致零偏值偏移,悬停时飞机会慢慢往一边偏
  • 振动耦合:桨叶振动被传感器误读为姿态变化,导致飞控误判

核心检测逻辑

我个人习惯用“三明治检测法”:

  1. 范围检测:看数值是否在物理合理范围内。比如加速度计模值应该在0.8g~1.2g之间,超出这个范围直接报警
  2. 变化率检测:看相邻采样点的差值是否过大。陀螺仪角速度变化率超过500°/s²,基本可以判定是异常跳变
  3. 一致性检测:如果有双IMU,对比两个传感器的输出。差值超过阈值,说明至少有一个坏了
// IMU异常检测伪代码示例
bool checkIMUHealth(IMUData &data) {
    // 1. 加速度计模值检测
    float accel_norm = sqrt(data.ax*data.ax + data.ay*data.ay + data.az*data.az);
    if (accel_norm < 0.8f || accel_norm > 1.2f) {
        return false;  // 加速度计异常
    }
    
    // 2. 陀螺仪变化率检测
    static float last_gyro[3];
    float gyro_rate = fabs(data.gx - last_gyro[0]);
    if (gyro_rate > 500.0f) {
        return false;  // 陀螺仪跳变
    }
    
    // 3. 双IMU一致性检测(如果有)
    if (dual_imu_enabled) {
        float diff = fabs(data.gx - imu2_data.gx);
        if (diff > 10.0f) {
            return false;  // 两个IMU不一致
        }
    }
    
    return true;
}

我的经验之谈

我在项目中遇到过一台无人机,每次飞完3分钟就开始剧烈抖动。查了半天,发现是IMU的减震海绵老化了。高频振动直接传到了传感器上,飞控以为飞机在疯狂翻滚,拼命打舵修正,结果越修正越抖。

嗯,这里要注意:IMU的减震设计比你想的重要得多。别光看算法,机械安装同样关键。

二、GPS信号丢失:从“有定位”到“无头苍蝇”

GPS一丢,无人机就失去了绝对位置信息。你想想看,在几千米外飞着,突然不知道自己在哪了,慌不慌?

GPS丢失的典型场景

  • 高楼峡谷:城市飞行时,信号被遮挡,卫星颗数骤降
  • 电磁干扰:高压线、基站附近,GPS信号被压制
  • 天线遮挡:机身姿态变化导致GPS天线被碳纤维机身挡住
  • 卫星几何分布差:虽然能搜到星,但HDOP值很大,定位精度极差

避坑指南

我曾经遇到过一架飞机,GPS信号在悬停时突然从12颗星掉到3颗星。飞控立刻切入了无GPS模式,但因为没有提前做位置预估,飞机直接开始飘移。最后撞树上了。

教训是什么?GPS丢失不可怕,可怕的是丢失后没有平滑过渡。

我建议的处理策略

  1. 分级预警:卫星颗数<8颗时发出警告,<5颗时强制切换模式
  2. 位置预估:GPS正常时,用卡尔曼滤波器持续估计位置和速度。GPS丢失后,用IMU积分推算位置,虽然会漂,但比直接丢失强
  3. 自动返航触发:如果GPS丢失超过5秒,且飞机在远距离,自动触发返航逻辑——前提是返航点已经记录
  4. 视觉辅助:如果有下视摄像头,可以用光流法辅助定位,减少对GPS的依赖
// GPS丢失处理逻辑
void handleGPSLoss() {
    static uint32_t loss_start_time = 0;
    
    if (gps_satellites < 5) {
        if (loss_start_time == 0) {
            loss_start_time = millis();
            // 记录丢失时的位置和速度
            last_known_pos = current_pos;
            last_known_vel = current_vel;
        }
        
        // 用IMU积分推算位置
        uint32_t elapsed = millis() - loss_start_time;
        estimated_pos = last_known_pos + last_known_vel * elapsed / 1000.0f;
        
        // 超过5秒触发返航
        if (elapsed > 5000) {
            triggerReturnToLaunch();
        }
    } else {
        loss_start_time = 0;  // GPS恢复
    }
}

三、气压计漂移:高度数据的“慢性毒药”

气压计这东西,说白了就是个测大气压力的传感器。但它有个毛病——特别怕风、怕温度变化、怕阳光直射。

气压计漂移的几种表现

漂移类型 原因 典型表现
温漂 传感器自身发热或环境温度变化 悬停时高度缓慢下降或上升
风压干扰 侧风导致气压计进气口压力变化 迎风飞行时高度突然跳变
零偏漂移 传感器老化或污染 地面校准后,起飞后高度偏差越来越大
阳光直射 光照导致封装内部温度不均 飞行一段时间后高度数据缓慢偏移

我的处理方案

气压计漂移不能完全消除,但可以大幅抑制。我常用的方法有:

  • 硬件隔离:给气压计加海绵罩,避免阳光直射和风直接吹到传感器
  • 软件滤波:用低通滤波器,截止频率设在0.5Hz左右,滤掉高频风压干扰
  • 融合GPS高度:GPS高度虽然精度差,但长期稳定性好。用互补滤波把气压计和GPS高度融合,短期看气压计,长期看GPS
  • 地面校准补偿:起飞前记录地面气压值,飞行中实时减去这个基准值,消除零偏
// 气压计-高度融合(互补滤波)
float fuseAltitude(float baro_alt, float gps_alt, float dt) {
    static float fused_alt = 0;
    float alpha = 0.98f;  // 气压计权重
    
    // 起飞时记录基准
    static float baro_baseline = 0;
    if (is_ground) {
        baro_baseline = baro_alt;
    }
    
    // 减去基准
    float baro_corrected = baro_alt - baro_baseline;
    
    // 互补滤波
    fused_alt = alpha * (fused_alt + baro_corrected) + (1 - alpha) * gps_alt;
    
    return fused_alt;
}

一个小技巧

如果你发现气压计在悬停时高度一直在缓慢下降,别急着怀疑传感器坏了。先看看是不是电机散热把热风吹到了气压计上。我遇到过好几次,把气压计挪个位置就解决了。

四、综合诊断策略:多传感器交叉验证

单个传感器出问题不可怕,可怕的是你没法判断它是不是在说谎。所以,我建议用多传感器交叉验证的方法。

怎么交叉验证?

  • IMU vs GPS:IMU积分得到的位移,和GPS测得的位移做对比。偏差太大,说明至少有一个有问题
  • 气压计 vs GPS高度:气压计高度变化率,和GPS高度变化率做对比。如果气压计显示在下降,GPS显示在上升,肯定有一个在撒谎
  • 加速度计 vs 陀螺仪:加速度计测重力方向,陀螺仪积分得到姿态。两者算出的俯仰角/横滚角应该一致

最后提醒一句

传感器故障诊断,核心不是“修”,而是“判”。判断出哪个传感器坏了,然后果断把它从控制回路里踢出去。宁可用一个精度差但可靠的传感器,也不要让一个坏传感器污染整个系统。

我曾经在测试中,故意让一个IMU输出错误数据。飞控如果没有检测机制,3秒内就会翻机。有了检测机制,至少能撑到手动切换模式。

好了,传感器故障诊断这块就聊到这儿。下一章咱们聊聊执行器故障——电机堵转、舵面卡死这些更刺激的问题。