安卓低通滤波器和高通滤波器

23

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

当我查看加速度计传感器的输出时,如果我不使用任何滤波器(情况:将手机静置在桌子上),我会得到z轴正值。现在如果我考虑基本物理知识,它会为我提供小g即重力加速度的精确值(约为9.8)。

要获得线性加速度,如果我对手机施加任何力,它都会改变加速度计的值,但它将是我施加的g+a。那么,为什么我不能直接从加速度计得到的值中减去g来获取a呢?

这有什么用途?
我理解的低通滤波器的基本定义是:允许低值通过,高通滤波器则是:允许高值通过。

4个回答

30

如果您查看文档,您将看到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];

请注意,这是一个向量操作,它逐个元素计算所有内容。
寻找“重力”是棘手的,因为手机中只有一个加速度计可以同时测量重力和其他力。我们想要从一个传感器中获取两种不同的力。如果我们只能在某个孤立的时间点观察力,我们将无法提取信息。然而,我们可以在一定时间范围内获得样本,并通过观察力如何随时间变化来提取信息。
这意味着我们需要根据这些力的快速变化程度过滤出来自该源的结果。由于重力加速度的大小不会快速改变,因为它根本不会改变。重力是一个恒定的力。然而,其他力会随时间改变。如果我们使用高通滤波器过滤掉缓慢变化的力(例如重力),那么剩下的力就是快速变化的力,例如施加在手机上的力。这就是为什么使用高通滤波器的原因。

19

低通滤波器:通过低频信号并减小高于阈值频率的信号振幅。

高通滤波器:通过高频信号并减小低于阈值频率的信号振幅。

如果您查看文档,它说:“为了测量设备的实际加速度,必须消除重力的影响。这可以通过应用高通滤波器来实现。相反,可以使用低通滤波器来隔离重力。”

您可以查看Samir Bhide: 将低通滤波器应用于Android传感器读数来了解有关低通滤波的教程。

此处阅读文档,您可以发现可以通过以下方式访问所有x、y、z轴上的a值:

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

2
这就是我所问的。为什么我们不能直接从我们得到的加速度计值中减去9.8...它只是手机传感器的实际加速度...不是吗?如果你看一下Android文档,他们使用了0.8作为alpha来计算它。为什么要使用alpha呢? - Jeet

0

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


0

我通常使用这个公式来过滤加速度计传感器数据,将其转换为线性传感器(如陀螺仪)数据。如果您不确定是否有内置的陀螺仪传感器,请使用此公式。

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;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接