javaandroidsensorsmotionshake

How to interpret the math behind detecting a shake event in Android?


I see a lot of answers online and they all have similar copy pasted code but none really have an explanation of the math that they use. I have a URL to the code on tutorialspoint which is the same as the answers I see on stackoverflow. However can someone explain to me this portion of the code:

   private final SensorEventListener mSensorListener = new SensorEventListener() {
  @Override
  public void onSensorChanged(SensorEvent event) {
     float x = event.values[0];
     float y = event.values[1];
     float z = event.values[2];
     mAccelLast = mAccelCurrent;
     mAccelCurrent = (float) Math.sqrt((double) (x * x + y * y + z * z));
     float delta = mAccelCurrent - mAccelLast;
     // What is this doing?
     mAccel = mAccel * 0.9f + delta;
     if (mAccel > 12) {
        Toast.makeText(getApplicationContext(), "Shake event detected", Toast.LENGTH_SHORT).show();
     }
  }

What is this line supposed to be doing

mAccel = mAccel * 0.9f + delta;

Where did the 0.9f come from and why are we multiplying it by itself and adding the delta? My physics isn't strong so it's not obvious to me.

https://www.tutorialspoint.com/how-to-detect-shake-event-in-android-app


Solution

  • I had a look at the code, also on the tutorialspoint page you linked. I see 3 steps in the algorithm:

    1. mAccelCurrent is calculated as the current absolute value of the acceleration
    2. delta is calculated as the difference between the current and previous absolute value of acceleration. This is done to get rid of constant acceleration value (gravity) and amplfy the shaking movement (change of acceleration).
    3. mAccel is calculated as the exponential smoothing of delta, a first order filtering, with a 0.9 coefficient, that, depending on the timing that this function is called, can be a high value or low value (if it's called frequently, it's a low value). You are right saying that a 0.1f multiplication looks to be missing, but if you look at the code in the protected void onCreate function, you can see that mAccel is initialized at 10f. In other words, mAccel is 10 times the exponential smoothing of delta.
    4. The result is then compared to 12, which looks to me as an arbitrary value.

    You could use the 0.1 multiplication if you preferred, it would be enough to reduce by 10 times also the value to which it's compared (1.2 instead of 12)