20

我正在为 Android 开发一个应用程序,我需要从加速度计读数中消除重力。我已经阅读了关于这个问题的多个讨论,我也在这里找到了一个算法,但我并没有真正理解它。

我想过滤每个轴的重力,而不是总加速度。

你能帮帮我吗?我的代码应该是这样的:

public void onSensorChanged(SensorEvent sensorEvent) {
    float vals[] = sensorEvent.values;
    float accelerationX = filterGravity(vals[0]);
    float accelerationY = filterGravity(vals[1]);
    float accelerationZ = filterGravity(vals[2]);
}

我应该在 filterGravity() 方法中放置什么代码?

4

4 回答 4

25

对于基本解决方案,您需要一个低通滤波器,其他方法(如卡尔曼滤波器)对于背后的数学运算非常困难。Android 的一个简单示例是单击您在http://developer.android.com/reference/android/hardware/SensorEvent.html#values上的链接。

简单地说,低通滤波器会根据您的所有历史值建立加权平均值。例如,如果您的过滤因子为 0.1,则意味着将当前值的 10% 添加到先前的平均值中:newMeanValue = currentValue 的 10% + oldMeanValue 的 90%。这意味着即使有一个突然的峰值,它也只会因为 10% 而缓慢地推动你的平均值。

于 2011-08-02T13:38:44.993 回答
14

您需要的是线性加速。在此处检查 Sensor.TYPE_LINEAR_ACCELERATION 。

于 2011-08-02T13:44:50.220 回答
10

如果您没有带有 TYPE_LINEAR_ACCELERATION 的手机,您就会被 TYPE_ACCELERATION 卡住,它无法将重力(倾斜)与线性加速度分开。

一种选择是应用低通滤波器。如果陀螺仪可用,另一种方法是使用传感器融合。两种方法都有其优点和缺点。

我在开源项目Acceleration Explorer中有很多工作示例。

于 2013-07-25T16:53:38.220 回答
-2

不太确定您要完成什么,但如果您正在寻找幅度(这将给出 0 和 1 之间的结果),那么您所做的就是将结果除以 10

public void onSensorChanged(SensorEvent sensorEvent) {
float vals[] = sensorEvent.values;
float accelerationX = (vals[0]/10);
float accelerationY = (vals[1]/10);
float accelerationZ = (vals[2]/10);

}

在游戏环境中,当传感器完全倾斜时,您的对象将处于最大速度

于 2011-08-02T14:27:25.537 回答