Как встряхнуть вверх и вниз с помощью акселерометра в Android?

Я пробовал следующим образом, но он не работает идеально. Если устройство держится в обычном режиме, то также срабатывает событие встряхивания.

@Override
public void onSensorChanged(SensorEvent event) {
    // TODO Auto-generated method stub

    long curTime = System.currentTimeMillis();
    // only allow one update every 200Ms.
    if ((curTime - lastUpdate) > 200) {

        lastUpdate = curTime;

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

        Vibrator vibrate = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);

        if (Round(y, 4) > 22) {
            vibrate.vibrate(200);
            Log.d("sensor", "==== Up Detected===");

        } else if (Round(y, 4) < -20) {
            vibrate.vibrate(200);
            Log.d("sensor", "==== Down Detected=== ");

        }

        mLastX = x;
        mLastY = y;
        mLastZ = z;
    }

}

public static float Round(float Rval, int Rpl) {
    float p = (float) Math.pow(10, Rpl);

    Rval = Rval * p;
    float tmp = Math.round(Rval);
    return (float) tmp / p;
}

Пожалуйста помоги.

Любая помощь будет высоко ценится..

Спасибо


person moDev    schedule 11.01.2013    source источник


Ответы (2)


Значения датчика очень сырые и шумные. Вам нужно добавить слой цифровой обработки сигнала поверх них, чтобы получить хорошие результаты. Простое использование необработанных значений приведет к большому дрожанию результатов. Вы пытаетесь выполнить некоторые базовые действия с задержкой по времени, но вам нужно больше фильтровать.

Кроме того, вы вибрируете в ответ на тряску. Эта вибрация заставит акселерометр увидеть движение, что приведет к большему количеству ложных срабатываний.

person Gabe Sechan    schedule 11.01.2013
comment
Я не понял первую часть вашего ответа - person moDev; 11.01.2013
comment
Значениям, которые вы получаете от датчиков, нельзя доверять как таковым — они имеют много ложных показаний и не совсем точны. В электротехнике есть исследование о том, как анализировать и корректировать показания сигналов, оно называется «Цифровая обработка сигналов». Одной из концепций здесь является фильтр — это способ принятия, отклонения или частичного принятия чтения. Вам нужен один, я просто понятия не имею, какой использовать. - person Gabe Sechan; 11.01.2013

Примените фильтр нижних частот в качестве значений по оси Y.

Базовый фильтр будет таким, как указано в документации.

public void onSensorChanged(SensorEvent event){
  // In this example, alpha is calculated as t / (t + dT),
 // where t is the low-pass filter's time-constant and
 // dT is the event delivery rate.

 final float alpha = 0.8;

 // Isolate the force of gravity with the low-pass filter.
 gravity[0] = alpha * gravity[0] + (1 - alpha) * event.values[0];
 gravity[1] = alpha * gravity[1] + (1 - alpha) * event.values[1];
 gravity[2] = alpha * gravity[2] + (1 - alpha) * event.values[2];

 // Remove the gravity contribution with the high-pass filter.
 linear_acceleration[0] = event.values[0] - gravity[0];
 linear_acceleration[1] = event.values[1] - gravity[1];
 linear_acceleration[2] = event.values[2] - gravity[2];
  }
person nayab    schedule 14.01.2013