如何使用FFT去除加速度计信号噪声 优化横滚俯仰角计算精度
基于FFT的加速度计振动噪声去除实操方案
前置准备:明确信号与噪声的频率边界
卡车电机的工作转速通常为每分钟几百到几千转,对应基频为转速/60 Hz,叠加谐波后的振动噪声频率一般不超过200Hz;而车辆姿态变化的有效信号频率通常低于10Hz,两者频带差异是FFT滤波的核心前提。如果有条件可以先采一段带干扰的原始数据做FFT分析,确定噪声的实际频率范围,滤波阈值会更精准。
FFT去噪完整执行步骤
- 对三个轴的原始加速度数据做分帧处理,每帧采样点数取2的n次方(比如256、512点,根据你的采样率调整,采样率建议设为噪声最高频率的5~10倍)
- 对每帧的三轴数据分别做FFT变换得到对应频域序列,将有效信号带宽之外的频率分量的实部、虚部全部置0,比如确定有效信号是0~10Hz,就把10Hz以上的所有频点值设为0
- 把处理后的频域序列做IFFT逆变换,得到滤波后的时域加速度数据,再用原公式计算横滚角、俯仰角即可
C语言实现参考
原有姿态计算逻辑不需要大幅修改,仅需要在数据采集和姿态计算之间插入滤波环节即可,示例逻辑如下:
#define FFT_POINTS 512 // 每帧采样点数,根据实际需求调整 float aux_x_raw[FFT_POINTS], aux_y_raw[FFT_POINTS], aux_z_raw[FFT_POINTS]; float aux_x_filtered[FFT_POINTS], aux_y_filtered[FFT_POINTS], aux_z_filtered[FFT_POINTS]; // 1. 采集满一帧原始加速度数据 for(int i=0; i<FFT_POINTS; i++){ aux_x_raw[i] = get_acc_x(); // 替换为你实际的加速度采集接口 aux_y_raw[i] = get_acc_y(); aux_z_raw[i] = get_acc_z(); } // 2. 分别对三个轴的原始数据做FFT滤波:FFT变换 -> 置零高频分量 -> IFFT逆变换 fft_filter(aux_x_raw, aux_x_filtered, FFT_POINTS); // fft_filter为FFT/IFFT处理函数,可直接移植嵌入式常用的FFT库实现 fft_filter(aux_y_raw, aux_y_filtered, FFT_POINTS); fft_filter(aux_z_raw, aux_z_filtered, FFT_POINTS); // 3. 用滤波后的数据计算姿态,可取当前帧最后一个点,也可取整帧滤波后数据的平均值计算 float roll = atan2(aux_y_filtered[FFT_POINTS-1], aux_z_filtered[FFT_POINTS-1]) * 57.3; float pitch = atan2((-aux_x_filtered[FFT_POINTS-1]), sqrt(aux_y_filtered[FFT_POINTS-1] * aux_y_filtered[FFT_POINTS-1] + aux_z_filtered[FFT_POINTS-1] * aux_z_filtered[FFT_POINTS-1])) * 57.3;
可选优化方案
如果嵌入式平台算力有限,FFT的实时性达不到要求,也可以先尝试IIR低通滤波替代FFT方案,参数匹配的前提下对电机振动的抑制效果相近,代码量更小,运算开销仅为FFT的1/10不到。
内容的提问来源于stack exchange,提问作者Jovem Cansado
相关产品推荐
相关产品推荐

