你的无人机飞不稳?可能是滤波算法没选对:聊聊飞控中的卡尔曼滤波与滑动平均
你的无人机飞不稳可能是滤波算法没选对聊聊飞控中的卡尔曼滤波与滑动平均调试无人机时最让人头疼的莫过于飞行抖动——明明传感器校准了PID参数也调了但飞行时依然像喝醉了一样左右摇晃。上周帮实验室学弟排查飞控问题时发现他的代码里直接用了MPU6050的原始数据做姿态解算传感器噪声导致电机疯狂抽搐。这让我想起三年前自己第一次调四轴时整整两周都在和滤波算法较劲。1. 为什么你的无人机需要滤波当MPU6050以1000Hz的频率输出数据时每个加速度计和陀螺仪读数都带着不同程度的噪声。我曾在示波器上观察过原始信号即使无人机静止放置Z轴加速度也会在0.98g到1.02g之间波动这种噪声直接用于姿态计算会导致欧拉角持续抖动。典型传感器噪声来源陀螺仪的温漂每℃可能带来0.1°/s的偏差加速度计的机械振动噪声电源纹波引起的ADC采样波动电磁干扰导致的信号失真去年给农业无人机做飞控升级时发现当喷洒泵工作时陀螺仪噪声幅度会增加3倍。这时如果只用简单的算术平均滤波飞行轨迹会出现明显锯齿。2. 滑动平均滤波快速上手的降噪方案对于资源有限的STM32F4系列芯片滑动平均滤波是性价比最高的选择。其核心思想是维护一个长度为N的队列存储最近N次采样值输出时计算队列均值#define FILTER_WINDOW_SIZE 10 float movingAverageFilter(float newValue) { static float buffer[FILTER_WINDOW_SIZE] {0}; static uint8_t index 0; static float sum 0; sum - buffer[index]; buffer[index] newValue; sum buffer[index]; index (index 1) % FILTER_WINDOW_SIZE; return sum / FILTER_WINDOW_SIZE; }窗口大小对滤波效果的影响基于MPU6050实测数据窗口大小延迟(ms)噪声抑制比CPU占用率5540%0.2%101060%0.3%202075%0.5%提示窗口超过20会导致控制延迟明显建议在姿态解算中不超过15但滑动平均有个致命缺陷——去年调试穿越机时发现当无人机快速翻转时滤波后的姿态角会滞后约20ms。这在高速机动时足以导致控制失控。3. 卡尔曼滤波动态系统的智能降噪卡尔曼滤波通过建立系统模型来区分真实运动与噪声。以陀螺仪数据融合为例其核心是两个方程状态预测x_k A * x_{k-1} B * u_k P_k A * P_{k-1} * A^T Q测量更新K P_k * H^T * (H * P_k * H^T R)^-1 x_k x_k K * (z_k - H * x_k) P_k (I - K * H) * P_k在STM32上的简化实现姿态估计场景typedef struct { float angle; // 估计角度 float bias; // 陀螺仪零偏 float P[2][2]; // 误差协方差矩阵 float Q_angle; // 过程噪声协方差 float Q_bias; float R_measure; // 测量噪声协方差 } KalmanFilter; float kalmanUpdate(KalmanFilter* kf, float newAngle, float newRate, float dt) { // 预测阶段 kf-angle dt * (newRate - kf-bias); kf-P[0][0] dt * (dt*kf-P[1][1] - kf-P[0][1] - kf-P[1][0] kf-Q_angle); kf-P[0][1] - dt * kf-P[1][1]; kf-P[1][0] - dt * kf-P[1][1]; kf-P[1][1] kf-Q_bias * dt; // 更新阶段 float S kf-P[0][0] kf-R_measure; float K[2]; K[0] kf-P[0][0] / S; K[1] kf-P[1][0] / S; float y newAngle - kf-angle; kf-angle K[0] * y; kf-bias K[1] * y; float P00_temp kf-P[0][0]; float P01_temp kf-P[0][1]; kf-P[0][0] - K[0] * P00_temp; kf-P[0][1] - K[0] * P01_temp; kf-P[1][0] - K[1] * P00_temp; kf-P[1][1] - K[1] * P01_temp; return kf-angle; }参数调优经验Q_angle建议从0.001开始调整对应系统过程噪声Q_bias通常设为0.003反映陀螺仪零偏变化率R_measure取值0.03左右对应加速度计噪声在树莓派CM4上跑的性能测试显示单个卡尔曼滤波器迭代约需12μs而滑动平均滤波仅需0.5μs。这也是为什么在F1/F4系列MCU上需要谨慎使用。4. 算法选型场景决定最佳方案通过对比实验发现使用250mm轴距四轴飞行器低速摄影无人机优先选择卡尔曼滤波角度估计误差0.5°适合云台稳定等对平滑性要求高的场景高速穿越机滑动平均窗口设为5配合二阶互补滤波控制延迟控制在5ms内牺牲部分平滑性换取响应速度折中方案——自适应滤波float adaptiveFilter(float accelAngle, float gyroRate, float dt) { static float estimatedAngle; float dynamicFactor fabs(gyroRate) * 0.1f; // 根据角速度动态调整 if(dynamicFactor 1.0f) dynamicFactor 1.0f; // 动态混合加速度计和陀螺仪数据 estimatedAngle (1 - dynamicFactor) * (estimatedAngle gyroRate * dt) dynamicFactor * accelAngle; return estimatedAngle; }这种方案在去年全国大学生飞行器竞赛中被多个队伍用于平衡响应速度与稳定性。实测在急转弯时姿态延迟可比纯卡尔曼滤波降低60%。5. 调试技巧从理论到实践的跨越卡尔曼滤波调试四步法先用示波器或SD卡记录原始传感器数据离线用Python/matlab仿真验证参数实际飞行时通过LED指示灯观察收敛状态结合PID调试逐步提高动态响应有个容易忽略的细节不同型号MPU6050的噪声特性可能相差3倍。去年批量测试时发现某批次的陀螺仪噪声方差比其他批次高2.8倍导致直接套用原有参数效果很差。常见问题排查表现象可能原因解决方案慢速飞行时抖动Q_angle设置过大从0.001开始逐步下调快速机动时失控窗口过大或R_measure太小减小滑动窗口/增大测量噪声静止时角度缓慢漂移陀螺仪零偏未校准增加Q_bias或开机时静止校准电机启动后姿态跳变电源噪声影响传感器增加RC滤波或改用线性稳压记得第一次成功调稳无人机时发现最大的噪声源居然是电调PWM信号对I2C总线的干扰。后来改用软件I2C并降低时钟频率到100kHz问题才彻底解决。