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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24119672/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 07:49:01  来源:igfitidea点击:

Android Low pass filter and High pass filter

androidaccelerometerlowpass-filter

提问by Jeet

I have a very basic question. What is Low Pass filter and High Pass filter in case of Android Accelerometer?

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

When I see the output from the Accelerometer Sensor, I see If I don't use any filter, (Case : I kept my cell phone idle on table) I get z Axis +ve value. Now If I think using basic physics, it gives me exact value(9.8approx) for small g i.e Acceleration due to gravity.

当我看到加速度计传感器的输出时,我看到如果我不使用任何过滤器,(案例:我将手机放在桌子上闲置)我得到 z 轴 +ve 值。现在,如果我考虑使用基本物理学,它为我提供了小 g 的精确值(9.8approx),即重力加速度。

To get the linear acceleration, If I add any force to phone it will change the Accelerometer value, but it will be g + athat I applied. So to get awhy can't I just subtract directly from the value I am getting from Accelerometer?

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

What is the use?
A basic definition I understand for low pass: To allow low value, High Pass : To allow high value.

有什么用?
我理解的低通基本定义:允许低值,高通:允许高值。

回答by shuttle87

If you look at the documentation you will see that SensorEvent returns an array which represents the vector of all the forces. http://developer.android.com/reference/android/hardware/SensorEvent.html#valuesThis is how the components of the acceleration break down into each axis:

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

You need to find which direction gravity is operating in then decompose that into its component parts. The magnitude of the gravity force will always be 9.8 but the direction, and hence how it breaks down into the component parts, will change. Assumingthat we could get the value of gravity and store that vector in an array like gravity[3]:

您需要找到重力运行的方向,然后将其分解为各个组成部分。重力的大小将始终为 9.8,但方向以及它分解为组成部分的方式会发生变化。假设我们可以获得重力值并将该向量存储在如下数组中gravity[3]

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

The total acceleration, T, on the phone is T = g + a. To get just awe would need a = T - g:

T手机上的总加速度为T = 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];

Notice how this calculates everything element by element because it's a vector operation.

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

The tricky part is finding gravitybecause there is only one accelerometer in the phone which measures both the gravity AND the other forces at the same time. We have 2 different forces that we want to find from the one sensor. If we could only look at the forces at an isolated point in time we wouldn't be able to extract the information. However we do get samples over a range of times and by looking at how the forces change over time we can extract the information.

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

This means we need to filter out the results from that one source based on how quickly those forces change. The magnitude of acceleration due to gravity does not change quickly because it doesn't change at all. Gravity is a constant force. However other forces will change over time. If we filter out the slow changing forces like gravity by using a high-pass filter then the remaining forces are the fast changing ones like the forces being applied to the phone. This is why the high-pass filter is used.

这意味着我们需要根据这些力的变化速度来过滤来自该来源的结果。重力加速度的大小不会快速变化,因为它根本没有变化。重力是一种恒定的力。然而,其他力量会随着时间而改变。如果我们使用高通滤波器过滤掉像重力这样缓慢变化的力,那么剩下的力就是快速变化的力,比如施加到手机上的力。这就是使用高通滤波器的原因。

回答by Claudiu S

Low Pass Filter: passes low-frequency signals and reduces the amplitude of signals with frequencies higher than the threshold frequency

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

High Pass Filter: passes high-frequency signals and reduces the amplitude of signals with frequencies lower than the threshold frequency

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

If you look at the documentation, it says: "in order to measure the real acceleration of the device, the contribution of the force of gravity must be eliminated. This can be achieved by applying a high-pass filter. Conversely, a low-pass filtercan be used to isolate the force of gravity."

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

You could check out this tutorial on low pass filtering: http://www.raweng.com/blog/2013/05/28/applying-low-pass-filter-to-android-sensors-readings/

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

Reading the docs at http://developer.android.com/reference/android/hardware/SensorEvent.html#values, you can see that you can access the avalues on all x,y,z axis by doing:

阅读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

回答by Vinay Kumar

Output of accelerometer includes noise if you subtract directly from these values that include noise. To eliminate noise it is required to implement highpass and lowpass filters.

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

回答by Guy4444

I usually use this formula To filter the data from the accelometer sensor data coming out to linear sensor(like gyroscope) data. Use it if you are not sure there is a built-in Gyroscopic sensor.

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

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