为什么要使用低通滤波器消除加速度计的重力效应?
加速度计重力分离低通滤波方案原理解答
核心背景
MEMS加速度计的原始输出本身是比力值,同时包含两个分量:
- 固定大小、方向始终指向地心的重力加速度分量
- 设备运动产生的线性加速度分量
你看到的通用公式Ad = -g - ∑F / mass就是加速度计的测量模型:Ad为加速度计原始输出,∑F / mass就是你需要的线性运动加速度,因此理论上只要从原始输出中减去当前姿态下的重力三轴分量,就能得到目标值。
为什么不能直接用固定重力值减去?
重力的三轴分量不是固定值:设备姿态发生旋转时,重力在加速度计x/y/z三个轴上的投影会实时变化,除非设备永远保持固定姿态,否则不可能用一个预先设定的固定重力值完成减法。
低通滤波方案的设计逻辑
重力分量的变化特征和线性加速度完全不同:
- 重力分量只会随设备姿态变化而改变,属于低频变化信号,正常使用场景下不会出现突变
- 线性加速度由设备运动产生,多是瞬态的高频变化信号
该方案用一阶IIR低通滤波器,从加速度计原始输出中提取出低频分量,这个分量就是当前姿态下的实时重力三轴估计值,再用原始输出减去该重力值,就得到了剥离重力后的线性加速度。
代码参数与逻辑解释
你贴的代码中:
- 常量
alpha是低通滤波的平滑系数,取值范围0~1:- 取值越接近1,重力估计值越平滑,抗高频运动干扰能力越强,但跟踪姿态变化的速度会变慢
- 取值越接近0,重力估计值跟踪姿态变化的速度越快,但更容易混入运动加速度产生的误差
- 0.8是移动端场景的通用经验值,平衡了平滑度和姿态跟踪速度
- 重力估计更新逻辑:
每次新采样到加速度计原始值gravity[0] = alpha * gravity[0] + (1 - alpha) * event.values[0]; gravity[1] = alpha * gravity[1] + (1 - alpha) * event.values[1]; gravity[2] = alpha * gravity[2] + (1 - alpha) * event.values[2];event.values时,用80%的历史重力估计值加20%的新采样值更新重力估计,本质就是过滤掉采样值里的高频分量,保留低频的重力相关分量。 - 线性加速度计算逻辑:
直接从原始采样值中剥离掉估计出的重力分量,得到仅由运动产生的线性加速度。linear_acceleration[0] = event.values[0] - gravity[0]; linear_acceleration[1] = event.values[1] - gravity[1]; linear_acceleration[2] = event.values[2] - gravity[2];
该方案的优势
- 纯软件实现、算力开销极低,无需依赖陀螺仪、磁力计等额外传感器,仅用加速度计即可完成计算,非常适合移动设备、嵌入式等低资源场景
- 实时性好、延迟极低,远低于需要融合多传感器做姿态解算的方案
- 调参简单,仅需调整
alpha一个参数即可适配不同使用场景
内容的提问来源于stack exchange,提问作者moumenShobakey
相关产品推荐
相关产品推荐

