You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在加速度计事故检测代码中应用低通滤波器并存储滤波后数据

整合低通滤波器到加速度计事故检测回调

Hey,我来帮你把低通滤波器完美整合到你的加速度计事故检测逻辑里。首先得搞明白,低通滤波需要保留上一次的输出结果才能发挥平滑效果,所以咱们得先在类里加个成员变量存滤波后的历史值,不然每次用新数组的话,滤波就白做啦。

第一步:准备滤波所需的成员变量与方法

先把低通滤波器的代码放到你的类中,同时添加一个成员变量来存储上一次滤波后的加速度值(初始化可以用全0,第一次传感器读数进来后会自动更新):

// 低通滤波系数,0.05的取值可以根据实际需求调整:值越小平滑效果越强,响应速度越慢
private static final float alpha = 0.05f;
// 存储上一次滤波后的加速度值,保证滤波的连续性
private float[] mFilteredAccel = new float[3];

public float[] lowPass(float[] output, float[] input) {
    output[0] = output[0] + alpha * (input[0] - output[0]);
    output[1] = output[1] + alpha * (input[1] - output[1]);
    output[2] = output[2] + alpha * (input[2] - output[2]);
    return output;
}

第二步:修改传感器回调逻辑,加入滤波处理

接下来修改onSensorChanged方法,在更新mLastX、mLastY、mLastZ之前,先对原始传感器读数做滤波处理,再把滤波后的值存入这三个变量里。另外这里有个细节:计算抖动速度的时候,你可以选择用原始读数还是滤波后的数据——用滤波后的数据能减少传感器噪声导致的误触发,我这里默认改成用滤波后的值,你也可以根据需求调整:

public void onSensorChanged(int sensor, float[] values) {
    if (sensor != SensorManager.SENSOR_ACCELEROMETER) return;
    
    // 对原始加速度值进行低通滤波,更新滤波后的结果
    mFilteredAccel = lowPass(mFilteredAccel, values);
    
    long now = System.currentTimeMillis();
    if ((now - mLastForce) > SHAKE_TIMEOUT) {
        mShakeCount = 0;
    }
    
    if ((now - mLastTime) > TIME_THRESHOLD) {
        long diff = now - mLastTime;
        // 用滤波后的加速度值计算抖动速度,减少噪声干扰
        float speed = Math.abs(mFilteredAccel[0] + mFilteredAccel[1] + mFilteredAccel[2] 
                              - mLastX - mLastY - mLastZ) / diff * 10000;
        
        if (speed > FORCE_THRESHOLD) {
            if ((++mShakeCount >= SHAKE_COUNT) && (now - mLastShake > SHAKE_DURATION)) {
                mLastShake = now;
                mShakeCount = 0;
                if (mShakeListener != null) {
                    mShakeListener.onShake();
                }
            }
            mLastForce = now;
        }
        mLastTime = now;
        // 将滤波后的数值存入mLastX/Y/Z,供下一次计算速度使用
        mLastX = mFilteredAccel[0];
        mLastY = mFilteredAccel[1];
        mLastZ = mFilteredAccel[2];
    }
}

小提示

如果你的需求只是让mLastX/Y/Z存储滤波后的值,而速度计算仍然想用原始传感器数据,只需要把速度计算那行改回原来的写法即可:

float speed = Math.abs(values[SensorManager.DATA_X] + values[SensorManager.DATA_Y] + values[SensorManager.DATA_Z] 
                      - mLastX - mLastY - mLastZ) / diff * 10000;

内容的提问来源于stack exchange,提问作者Daniel Kalalian

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 22:42:40