Android低通滤波器和高通滤波器

时间:2014-06-09 11:49:39

标签: android accelerometer lowpass-filter

我有一个非常基本的问题。 在Android加速度计的情况下,什么是低通滤波器和高通滤波器?

当我看到加速计传感器的输出时,我看到如果我不使用任何过滤器,(例如:我让手机闲置在桌面上)我得到z轴+ ve值。现在,如果我认为使用基本物理学,它会给出小g的精确值(9.8approx),即由于重力引起的加速度。

要获得线性加速度,如果我向手机添加任何力,它将更改加速度计值,但它将是我应用的g + a。所以为了得到a为什么我不能直接从加速度计得到的值中减去?

有什么用?
我理解为低通的基本定义:允许低值,高通:允许高值。 请帮我理解一下。我对此很困惑。

4 个答案:

答案 0 :(得分:27)

如果查看文档,您将看到SensorEvent返回一个数组,该数组表示所有力的向量。 http://developer.android.com/reference/android/hardware/SensorEvent.html#values 这就是加速度的分量如何分解成每个轴:

 values[0] //acceleration on x axis
 values[1] //acceleration on y axis
 values[2] //acceleration on z axis

您需要找到重力运行的方向,然后将其分解为其组成部分。重力的大小总是为9.8,但方向,以及它如何分解成组成部分,将会改变。 假设我们可以得到引力值并将该向量存储在像gravity[3]这样的数组中:

 gravity[0] //gravity x axis
 gravity[1] //gravity y axis
 gravity[2] //gravity z axis

手机上的总加速度TT = g + a。要获得a,我们需要a = T - g

 linear_acceleration[0] = event.values[0] - gravity[0];
 linear_acceleration[1] = event.values[1] - gravity[1];
 linear_acceleration[2] = event.values[2] - gravity[2];

注意这是如何逐个元素计算所有元素的,因为它是一个向量运算。

棘手的部分是找到gravity,因为手机中只有一个加速计可以同时测量重力和其他力。我们想要从一个传感器中找到两种不同的力。如果我们只能在孤立的时间点查看力,我们就无法提取信息。然而,我们确实在一段时间内得到样本,通过观察力随时间的变化,我们可以提取信息。

这意味着我们需要根据这些力的变化速度过滤掉这一个来源的结果。重力引起的加速度不会很快变化,因为它根本不会发生变化。重力是一种恒定的力量。然而,其他力量会随着时间而改变。如果我们通过使用高通滤波器滤除像重力这样的缓慢变化的力,那么剩余的力就是快速变化的力,就像施加在手机上的力一样。这就是使用高通滤波器的原因。

答案 1 :(得分:17)

低通滤波器:传递低频信号并降低频率高于阈值频率的信号幅度

高通滤波器:传递高频信号并降低频率低于阈值频率的信号幅度

如果你看一下documentation,它说:“为了测量设备的实际加速度,重力的贡献必须消除。这可以是通过应用高通滤波器来实现。相反,可以使用低通滤波器来隔离重力。“

您可以查看有关低通滤波的本教程:http://www.raweng.com/blog/2013/05/28/applying-low-pass-filter-to-android-sensors-readings/

阅读http://developer.android.com/reference/android/hardware/SensorEvent.html#values处的文档,您可以看到您可以通过执行以下操作访问所有x,y,z轴上的 a 值:

values[0] - a on x axis
values[1] - a on y axis
values[2] - a on z axis

答案 2 :(得分:0)

如果直接从包含噪声的这些值中减去,加速度计的输出会包含噪声。为了消除噪声,需要实现高通和低通滤波器。

答案 3 :(得分:0)

我通常使用这个公式来过滤来自线性传感器(如陀螺仪)数据的accelometer传感器数据的数据。 如果您不确定是否有内置陀螺仪传感器,请使用它。

private float[] values;
private float[] valuesN;
private float[] prev;
private float[] prevHF;
private boolean doHPF = false;

// ind - index of three dimensions (x, y, z)
private void makeHPFf() {
    for (int ind = 0; ind < 3; ind++) {
        valuesN[ind] = values[ind] * 0.002f * 9.8f;
        if (doHPF)
            values[ind] = valuesN[ind] - prev[ind] + (prevHF[ind] * 0.8f);
        prev[ind] = valuesN[ind];
        prevHF[ind] = values[ind];
    }

    if (!doHPF)
        doHPF = true;
}