Android:加速度计误检测

时间:2009-10-27 13:31:20

标签: android accelerometer

我有一个代码片段来检测加速度计的移动。通过正确检测轻微的动作,它可以工作一段时间,但有时它会在我保持设备闲置时检测到动作。 Android上的内置加速度计检测有问题吗?

我使用的是HTC G-1设备。我的代码片段如下。我如何解决它,以便我可以检测到小的设备移动,但在设备空闲时却没有检测到任何东西?

private static final int SHAKE_THRESHOLD = 50;

public void onSensorChanged(int sensor, float[] values) {

    if (sensor == SensorManager.SENSOR_ACCELEROMETER) {
        long curTime = System.currentTimeMillis();
        // only allow one update every 100ms.
        if ((curTime - lastUpdate) > 100) {
            long diffTime = (curTime - lastUpdate);
            lastUpdate = curTime;

            x = values[SensorManager.DATA_X];
            y = values[SensorManager.DATA_Y];
            z = values[SensorManager.DATA_Z];

            float speed = Math.abs(x+y+z - last_x - last_y - last_z) / diffTime * 10000;

            if (speed > SHAKE_THRESHOLD) { 
                long curTime = System.currentTimeMillis();
                long diff = (curTime - shakeTime);              
                shakeTime = curTime;

                if (myFlagIgnoreShakeDetection==true)  //Caused unneccessary accelerometer   
                                                       //notification looping when device is idle
                   return;

                // Doing something...
            }
         last_x = x;
         last_y = y;
         last_z = z;
        }

    }

}

2 个答案:

答案 0 :(得分:1)

以下是一些代码差异......

  • 关于last_xlast_ylast_z的更新可能存在问题。我相信它们应该包含在里面 if ((curTime - lastUpdate) > 100) {语句中。换句话说,每次调用onSensorChanged时都会更新它们,而不是每100毫秒更新一次。您应该将这三个变量的更新移动到它们上面的大括号中。

  • 在您计算speed的行上,公式以... / diffTime * 10000;结尾?您想要将diffTime乘以10000,还是整个结果?由于/*在我所知的大多数语言中通常具有相同的operator precedence(例如Java),因此您的等式将从左到右进行评估,首先除以diffTime 然后将该结果乘以10000。

    我猜你的意思是将diffTime乘以10000,因此最终结果除以该数量。这是除以10000或乘以10000之间的差异,这意味着您可能获得的speed值比您应该大10 ^ 8,因此即使设备处于空闲状态也会使阈值跳闸。你需要在乘法中加上括号,比如... / (diffTime * 10000);,以确保它在分割之前执行

    此外,如果您打算将diffTime从毫秒缩放到秒,则您的比例因子应为1000。

答案 1 :(得分:0)

我个人,在我的增强现实库中,使用滚动平均值进行更新:

float kFilteringFactor = (float)0.05;    
rollingZ = (float) ((rawZValue * kFilteringFactor) + (rollingZ * (1.0 - kFilteringFactor)));

这样可以很好地平滑数据,您可以调整过滤因子以获得所需的响应能力。

rawZValue是来自加速度计的原始值。