Calculating distance using Linear acceleration android

Ashwin picture Ashwin · Oct 17, 2012 · Viewed 33.2k times · Source

Possible Duplicate:
Android accelerometer accuracy (Inertial navigation)

I am using the following code to calculate the distance. tnew and anew are arraylists containing timestamps and accelerations respectively.

 double distance=0;
 double init_vel=0;
long time_prev=tnew.next();
   while(anew.hasNext())
   {
    float temp_acc=anew.next();
    long temp_time=tnew.next();

    interval=(temp_time-time_prev)/1000f;   //milliseconds to seconds
    double fin_vel=init_vel+(temp_acc*interval);
    distance+=(init_vel*interval)+0.5f*temp_acc*interval*interval;

    init_vel=fin_vel;
    time_prev=temp_time;
   }


Is there any logical mistake in the code? Because I am getting values much smaller than the actual length.

Output of LogCat :

--------- beginning of /dev/log/system

--------- beginning of /dev/log/main

V/PhonetapeActivity( 8842): Sensor Listener Registered

V/PhonetapeActivity( 8842): Sensor Unregistered

V/PhonetapeActivity( 8842): No. of Iterations : 49

V/PhonetapeActivity( 8842): Value of acceleration : 3.5762787E-7

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665585965

V/PhonetapeActivity( 8842): Value of acceleration : -0.15275347

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665586017

V/PhonetapeActivity( 8842): Value of acceleration : 0.15585232

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665586077

V/PhonetapeActivity( 8842): Value of acceleration : 1.075269

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665586138

V/PhonetapeActivity( 8842): Value of acceleration : 3.6529458

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665586199

V/PhonetapeActivity( 8842): Value of acceleration : 9.645137

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665586257

V/PhonetapeActivity( 8842): Value of acceleration : 17.022213

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665586316

V/PhonetapeActivity( 8842): Value of acceleration : 9.721476

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665586376

V/PhonetapeActivity( 8842): Value of acceleration : -18.729362

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665586437

V/PhonetapeActivity( 8842): Value of acceleration : -22.868385

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665586497

V/PhonetapeActivity( 8842): Value of acceleration : -16.777517

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665586557

V/PhonetapeActivity( 8842): Value of acceleration : -7.0492268

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665586617

V/PhonetapeActivity( 8842): Value of acceleration : -3.860828

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665586677

V/PhonetapeActivity( 8842): Value of acceleration : 1.7244682

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665586737

V/PhonetapeActivity( 8842): Value of acceleration : 5.0734243

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665586797

V/PhonetapeActivity( 8842): Value of acceleration : 6.4193974

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665586857

V/PhonetapeActivity( 8842): Value of acceleration : 2.739545

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665586917

V/PhonetapeActivity( 8842): Value of acceleration : 5.559997

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665586977

V/PhonetapeActivity( 8842): Value of acceleration : 4.2290807

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665587037

V/PhonetapeActivity( 8842): Value of acceleration : 5.0012918

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665587097

V/PhonetapeActivity( 8842): Value of acceleration : 5.9317436

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665587157

V/PhonetapeActivity( 8842): Value of acceleration : 5.20226

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665587217

V/PhonetapeActivity( 8842): Value of acceleration : 7.1381693

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665587276

V/PhonetapeActivity( 8842): Value of acceleration : 7.6460614

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665587337

V/PhonetapeActivity( 8842): Value of acceleration : 5.566694

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665587396

V/PhonetapeActivity( 8842): Value of acceleration : 3.355657

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665587457

V/PhonetapeActivity( 8842): Value of acceleration : 1.8876343

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665587517

V/PhonetapeActivity( 8842): Value of acceleration : -0.8815446

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665587577

V/PhonetapeActivity( 8842): Value of acceleration : -0.9595623

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665587646

V/PhonetapeActivity( 8842): Value of acceleration : -4.233544

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665587697

V/PhonetapeActivity( 8842): Value of acceleration : -1.9580669

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665587765

V/PhonetapeActivity( 8842): Value of acceleration : -1.4569702

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665587822

V/PhonetapeActivity( 8842): Value of acceleration : -0.6058636

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665587876

V/PhonetapeActivity( 8842): Value of acceleration : -0.21207428

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665587937

V/PhonetapeActivity( 8842): Value of acceleration : 0.5068469

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665587997

V/PhonetapeActivity( 8842): Value of acceleration : 5.614555

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665588057

V/PhonetapeActivity( 8842): Value of acceleration : -4.5297813

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665588122

V/PhonetapeActivity( 8842): Value of acceleration : -0.29250193

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665588178

V/PhonetapeActivity( 8842): Value of acceleration : -2.4922757

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665588237

V/PhonetapeActivity( 8842): Value of acceleration : -1.7652755

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665588297

V/PhonetapeActivity( 8842): Value of acceleration : -2.3279366

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665588357

V/PhonetapeActivity( 8842): Value of acceleration : -1.8127642

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665588419

V/PhonetapeActivity( 8842): Value of acceleration : -1.956768

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665588477

V/PhonetapeActivity( 8842): Value of acceleration : -0.8337221

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665588537

V/PhonetapeActivity( 8842): Value of acceleration : -0.24841261

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665588601

V/PhonetapeActivity( 8842): Value of acceleration : 0.23997736

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665588657

V/PhonetapeActivity( 8842): Value of acceleration : 0.14441395

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665588723

V/PhonetapeActivity( 8842): Value of acceleration : 0.23150349

V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665588777

V/PhonetapeActivity( 8842):  1st while loop ended

V/PhonetapeActivity( 8842): 2nd while loop ended

V/PhonetapeActivity( 8842): Avg value : 0.4006781578063965

V/PhonetapeActivity( 8842): Max Value : 17.022213

V/PhonetapeActivity( 8842): Min Value : -22.868385

V/PhonetapeActivity( 8842): Standard Deviation : -0.0031174493

V/PhonetapeActivity( 8842): 3rd while loop started

V/PhonetapeActivity( 8842): startpos=3 endpos=8

V/PhonetapeActivity( 8842): acceleration=0.1558523178100586 interval=0.061000000685453415

V/PhonetapeActivity( 8842): distance=5.799264876044276E-4

V/PhonetapeActivity( 8842): next init velocity=0.009506991493243078

V/PhonetapeActivity( 8842): acceleration=1.0752689838409424 interval=0.061000000685453415

V/PhonetapeActivity( 8842): distance=0.005160928954000712

V/PhonetapeActivity( 8842): next init velocity=0.07509840024458736

V/PhonetapeActivity( 8842): acceleration=3.6529457569122314 interval=0.057999998331069946

V/PhonetapeActivity( 8842): distance=0.021805144861910285

V/PhonetapeActivity( 8842): next init velocity=0.2869692480489858

V/PhonetapeActivity( 8842): acceleration=9.645136833190918 interval=0.05900000035762787

V/PhonetapeActivity( 8842): distance=0.07231105232279186

V/PhonetapeActivity( 8842): next init velocity=0.8560323246566197

V/PhonetapeActivity( 8842): acceleration=17.022212982177734 interval=0.05999999865889549

V/PhonetapeActivity( 8842): distance=0.18495295465057213

V/PhonetapeActivity( 8842): next init velocity=1.8773650807587172

V/PhonetapeActivity( 8842): 3rd while loop ended

V/PhonetapeActivity( 8842): final distance=0.18495295465057213

V/PhonetapeActivity( 8842): values of acceleration, timestamp, distance, start_time and calibrating reset


If you observe the logcat, first it iterates through 49 values of acceleration and their respective time stamps in milliseconds. Then there is a avg, sum, max, min etc.
Then if you see there is a startpos=3 and endpos=8. This is the iteration number range, I am using to calculate the distance .i.e I am using the values of acceleration and timestamp only from iteration 3 to 8.
This is because, I detect the start of distance calculation from a rise in acceleration to a sudden change in the opposite direction. You can see that the values from 3-8 fit into the logic. From 3 there is a considerable rise in acceleration and after 8 there is a sudden decrease.

Answer

TheCodeArtist picture TheCodeArtist · Oct 19, 2012

Accelerometers are very precise but bad at dead-reckoning. Gyroscopes are good at that but they "drift" over time. "Sensor-fusion" is the process of using accel/gyro data in tandem to correct one's deficiency using the other. AFAIR, "sensor-fusion" is NOT enabled on Galaxy Ace. LINEAR_ACCELERATION is nothing but ACCELEROMETER - gravity component. On devices without gyroscope, fusion is not possible by definition it requires accel+gyro.

The accelerometer data contains the gravity component of 9.8. This is filtered out by simply determining the difference between 2 consecutive samples of accelerometer data. This gives us the LINEAR_ACCELERATION data.

Check this out for actual internal code :
frameworks/base/services/sensorservice/LinearAccelerationSensor.cpp
The function LinearAccelerationSensor::process() is of interest in the above file.

Also rudimentary operations like filtering/averaging that the above link and video talk about, need to performed on the accel data obtained in your app. The processed values obtained in this manner will be better(though not as good as the ones that would have been obtaioned had sensor fusion been present on your device) than the raw values. These can then be used to calculate the velocity and position more accurately.

That said, 16 samples a second (@poll-rate=60ms) is relatively inaccurate in itself. You might want to try registering the sensorEventListner using SENSOR_DELAY_FASTEST to see the maximum number of samples that you can obtain on you device.

Also note that the accelerometers on phones are clamped to certain MAX sensitivity (usually -/+ 2/4/8 G range). While normal walking/running might operate under these ranges, a sudden impulse in acceleration (for example on a bike) will definitely be clamped to the MAX and you will lose sync in dead-reckoning. This can be checked by noting the number of samples that are very close to the -/+MAX. Lot of samples at -/+MAX imply that you would have most certainly lost sync with the actual position.