Android 低通滤波器和高通滤波器
Posted
技术标签:
【中文标题】Android 低通滤波器和高通滤波器【英文标题】:Android Low pass filter and High pass filter 【发布时间】:2014-07-29 22:58:55 【问题描述】:我有一个非常基本的问题。 android加速度计的低通滤波器和高通滤波器是什么?
当我看到加速度计传感器的输出时,我看到如果我不使用任何过滤器,(案例:我的手机在桌子上闲置)我得到 z 轴 +ve 值。现在,如果我认为使用基本物理学,它会为我提供小 g 的精确值(9.8 近似值),即重力加速度。
为了获得线性加速度,如果我对手机施加任何力,它会改变加速度计的值,但我应用的是g + a
。那么,要获得a
,为什么我不能直接从我从加速度计获得的值中减去?
有什么用? 我对低通的基本定义:允许低价值,高通:允许高价值。
【问题讨论】:
【参考方案1】:低通滤波器:通过低频信号,并降低频率高于阈值频率的信号的幅度
高通滤波器:通过高频信号,降低频率低于阈值频率的信号幅度
如果您查看documentation,它说:“为了测量设备的真实加速度,必须消除重力的影响。这可以通过以下方式实现应用高通滤波器。相反,低通滤波器可用于隔离重力。”
你可以看看这个关于低通滤波的教程:Samir Bhide: Applying Low Pass Filter to Android Sensor's 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
【讨论】:
这就是我要问的。为什么我们不能直接从我们得到的加速度计值中减去 9.8……它只是手机传感器的实际加速度……不是吗?如果您在 Android 文档中看到,他们使用 .8 作为 alpha 来计算它。为什么要使用 alpha?【参考方案2】:如果您查看文档,您会看到 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
手机上的总加速度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];
请注意这是如何逐个元素计算所有内容的,因为它是向量运算。
棘手的部分是找到gravity
,因为手机中只有一个加速度计可以同时测量重力和其他力。我们想要从一个传感器中找到 2 种不同的力。如果我们只能在一个孤立的时间点查看力,我们将无法提取信息。但是,我们确实会在一段时间内获得样本,并且通过观察力如何随时间变化,我们可以提取信息。
这意味着我们需要根据这些力量变化的速度来过滤掉来自那个来源的结果。重力加速度的大小不会很快改变,因为它根本不会改变。重力是一种恒定的力。然而,其他力量会随着时间而改变。如果我们使用高通滤波器过滤掉缓慢变化的力,比如重力,那么剩下的力就是快速变化的力,比如施加在手机上的力。这就是使用高通滤波器的原因。
【讨论】:
【参考方案3】:如果直接从这些包含噪声的值中减去加速度计的输出,则包含噪声。为了消除噪声,需要实现高通和低通滤波器。
【讨论】:
【参考方案4】:我通常使用这个公式来过滤从加速度计传感器数据出来的数据到线性传感器(如陀螺仪)数据。 如果您不确定是否有内置陀螺仪传感器,请使用它。
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;
【讨论】:
以上是关于Android 低通滤波器和高通滤波器的主要内容,如果未能解决你的问题,请参考以下文章