Search code examples
javaandroidaccelerometertimedeltadifferentiation

How should one calculate the time derivative of accelerometer data (jerk) in real-time (Java)?


I am trying to calculate the time-derivative of acceleration (jerk) from the streamed accelerometer data within the onReceive() looping Android method.

I assumed that, from one sensor update to the next, I could approximate this by simply calculating the delta acceleration (x, y, z) and the associated delta time. To ensure maximal accuracy, I used the System.nanoTime() method (and divided by 10e8).

Everything seemed happy, and jerk data was appearing, but I thought it wise to check that the sum of all delta_times (sumDeltaTime) was close to the difference between last_time and first_time. To my surprise, the difference was several thousand times out. Even replacing System.nanoTime() with System.currentTimeMillis() (divided by 10e2) did not change this discrepency. Here is my code:

// calculate jerk (time derivative of acceleration)

accel_count++;

if (accel_count == 1) {
    first_time = new_time = System.nanoTime() / 10e8; // captures first time value (in seconds)
    newAccel[0] = accel[0]; // x
    newAccel[1] = accel[1]; // y
    newAccel[2] = accel[2]; // z
    } else {
    prev_time = new_time; // assigns previous time value
    new_time = System.nanoTime() / 10e8; // immediately updates to the new time value (in seconds)
    prevAccel[0] = newAccel[0]; // x
    prevAccel[1] = newAccel[1]; // y
    prevAccel[2] = newAccel[2]; // z
    // set up for next iteration
    newAccel[0] = accel[0]; // x
    newAccel[1] = accel[1]; // y
    newAccel[2] = accel[2]; // z
    }
float[] delta_accel; // difference in acceleration between consecutive sensor measurements
delta_accel = new float[] {
    (newAccel[0] - prevAccel[0]), // x
    (newAccel[1] - prevAccel[1]), // y
    (newAccel[2] - prevAccel[2])  // z
    };
double delta_time = (new_time - prev_time); // time difference between consecutive sensor measurements (in seconds)

float[] jerk;
jerk = new float[] {
    (float) (delta_accel[0] / delta_time), // x
    (float) (delta_accel[1] / delta_time), // y
    (float) (delta_accel[2] / delta_time)  // z
    };

total_time = new_time - first_time; // total time duration of entire recording (in seconds)
sumDeltaTime += delta_time; // testing sum of deltas

Can anybody see what I must be doing wrong? Thanks!


Solution

  • You did not initialize prev_time on the first pass (accel_count == 1), so it was probably 0 the first time you calculated delta_time. This made the first delta_time unusually large, because new_time is much larger than 0, just as System.nanoTime() is much larger than 0.