Android: ложное обнаружение акселерометра - PullRequest
3 голосов
/ 27 октября 2009

У меня есть фрагмент кода для обнаружения движений акселерометра. Иногда он работает, правильно обнаруживая легкие движения, но иногда он обнаруживает движения, когда я тоже держал свое устройство в режиме ожидания. Есть ли проблемы со встроенным акселерометром на 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 ]

1 голос
/ 27 октября 2009

Вот несколько несоответствий кода ...

  • Возможно, проблема с обновлением last_x, last_y и last_z. Я считаю, что они должны быть включены в if ((curTime - lastUpdate) > 100) { заявление. Другими словами, они обновляются каждый раз, когда вызывается onSensorChanged, а не каждые 100 миллисекунд. Возможно, вам следует перенести обновление этих трех переменных в фигурную скобку над ними.

  • В строке, где вы вычисляете speed, формула заканчивается на ... / diffTime * 10000; Вы хотите умножить просто diffTime на 10000 или весь результат? Так как / и * обычно имеют одинаковый приоритет оператора в большинстве известных мне языков (таких как Java ), ваше уравнение будет оцениваться слева направо, делится первым на diffTime , затем , умножив этот результат на 10000.

    Я предполагаю, что вы хотите умножить diffTime на 10000, таким образом делит окончательный результат на эту сумму. Это разница между делением на 10000 или умножением на 10000, что означает, что вы, вероятно, получаете значения для speed, которые на 10 ^ 8 больше, чем вы должны, таким образом отключая порог, даже когда устройство не используется. Вам нужно заключить в скобки скобки, например ... / (diffTime * 10000);, чтобы убедиться, что оно выполнено до деления.

    Кроме того, если вы собираетесь масштабировать diffTime от миллисекунд до секунд, ваш коэффициент масштабирования должен составлять 1000.

0 голосов
/ 28 октября 2009

Я лично в своей библиотеке дополненной реальности использую скользящее среднее для обновлений:

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

Это имеет тенденцию довольно сглаживать данные, и вы можете настроить коэффициент фильтрации, чтобы получить желаемую отзывчивость.

rawZValue - это необработанное значение, поступающее от акселерометра.

...