Search code examples
androidaccelerometerandroid-sensors

Android: incorrect velocity calculation using accelerometer


I hope this isn't a duplicate as I saw some related posts about accelerometer in android but none of them was helpful to me.

I need to get the X axis velocity (only) of my mobile device.

The problem is that when I move my device in a straight line (initial velocity = 0), first accelerating it and then decelerating (until full stop) the calculated speed I get doesn't match the real speed.

The main symptom of the problem is that after the device has stopped, my calculated velocity isn't 0.

I can see the acceleration and deceleration in the results (positive accel values at first and then negative accel values) but I think they aren't accurate enough.

This happens no matter in what direction I move my device (left/right).

I guess that what I'm asking for is a way to perhaps make the calculation in a smarter way which can improve the accuracy of results..

Here is my onSensorChanged code:

public void onSensorChanged(SensorEvent sensorEvent) {
    if((!isCancelled()) && (this.isConnected)) {
        if(mode.equals("ac")) {

            // Getting X acceleration
            currentAccelX = sensorEvent.values[0];

            // Getting current sample timestamp
            currentTimeStamp = sensorEvent.timestamp;

            // if first sample then interval = 0
            if(prevTimeStamp == 0) prevTimeStamp = currentTimeStamp;

            // calculating interval (in seconds)
            interval = (currentTimeStamp - prevTimeStamp) * NS2S;

            // updating prevTimeStamp for next sample..
            prevTimeStamp = currentTimeStamp;

            // My device shows acceleration of about 0.22 when isn't moving at all
            // so for ignoring this offset:
            if(Math.abs(currentAccelX) < 0.3) currentAccelX = 0;


            // Updating the X-axis velocity
            currentVelocityX += currentAccelX * interval;

            Log.d(TAG, "ACCEL X IS: " + currentAccelX + " INTERVAL IS: " + interval + " VELOCITY X IS: " + currentVelocityX); }}}

Here are the results (from log):

ACCEL X IS: 0.0 INTERVAL IS: 0.008392334 VELOCITY X IS: -0.17563461
ACCEL X IS: 0.5072479 INTERVAL IS: 0.008392334 VELOCITY X IS: -0.17137761
ACCEL X IS: 1.8605042 INTERVAL IS: 0.008392334 VELOCITY X IS: -0.15576364
ACCEL X IS: 2.970047 INTERVAL IS: 0.008392334 VELOCITY X IS: -0.130838
ACCEL X IS: 3.1661987 INTERVAL IS: 0.008392334 VELOCITY X IS: -0.10426621
ACCEL X IS: 2.5031128 INTERVAL IS: 0.008392334 VELOCITY X IS: -0.083259255
ACCEL X IS: 1.4252472 INTERVAL IS: 0.008392334 VELOCITY X IS: -0.07129811
ACCEL X IS: 0.66192627 INTERVAL IS: 0.008392334 VELOCITY X IS: -0.065743
ACCEL X IS: 0.8834839 INTERVAL IS: 0.008392334 VELOCITY X IS: -0.05832851
ACCEL X IS: 1.476593 INTERVAL IS: 0.008392334 VELOCITY X IS: -0.045936447
ACCEL X IS: 2.1182098 INTERVAL IS: 0.008392334 VELOCITY X IS: -0.028159723
ACCEL X IS: 2.5206451 INTERVAL IS: 0.008392334 VELOCITY X IS: -0.0070056263
ACCEL X IS: 2.5039368 INTERVAL IS: 0.008392334 VELOCITY X IS: 0.014008248
ACCEL X IS: 2.0747833 INTERVAL IS: 0.008392334 VELOCITY X IS: 0.03142052
ACCEL X IS: 1.6359253 INTERVAL IS: 0.008392334 VELOCITY X IS: 0.04514975
ACCEL X IS: 1.9437103 INTERVAL IS: 0.008392334 VELOCITY X IS: 0.061462015
ACCEL X IS: 2.5153046 INTERVAL IS: 0.008392334 VELOCITY X IS: 0.08257129
ACCEL X IS: 2.7262726 INTERVAL IS: 0.008392334 VELOCITY X IS: 0.10545108
ACCEL X IS: 2.6504364 INTERVAL IS: 0.008392334 VELOCITY X IS: 0.12769443
ACCEL X IS: 2.7267609 INTERVAL IS: 0.008392334 VELOCITY X IS: 0.15057832
ACCEL X IS: 3.2504425 INTERVAL IS: 0.008392334 VELOCITY X IS: 0.17785712
ACCEL X IS: 2.66333 INTERVAL IS: 0.008392334 VELOCITY X IS: 0.20020866
ACCEL X IS: 1.2032013 INTERVAL IS: 0.008392334 VELOCITY X IS: 0.21030633
ACCEL X IS: 0.0 INTERVAL IS: 0.008392334 VELOCITY X IS: 0.21030633
ACCEL X IS: -0.82492065 INTERVAL IS: 0.008392334 VELOCITY X IS: 0.20338333
ACCEL X IS: -1.1881866 INTERVAL IS: 0.008392334 VELOCITY X IS: 0.19341166
ACCEL X IS: -1.234375 INTERVAL IS: 0.008392334 VELOCITY X IS: 0.18305238
ACCEL X IS: -1.1171875 INTERVAL IS: 0.008392334 VELOCITY X IS: 0.17367657
ACCEL X IS: -0.66615295 INTERVAL IS: 0.008392334 VELOCITY X IS: 0.16808599
ACCEL X IS: 0.6031494 INTERVAL IS: 0.008392334 VELOCITY X IS: 0.17314783
ACCEL X IS: 1.6951294 INTERVAL IS: 0.008392334 VELOCITY X IS: 0.18737392
ACCEL X IS: 2.1244202 INTERVAL IS: 0.008392334 VELOCITY X IS: 0.20520276
ACCEL X IS: 2.0012054 INTERVAL IS: 0.008392334 VELOCITY X IS: 0.22199754
ACCEL X IS: 1.7078094 INTERVAL IS: 0.008392334 VELOCITY X IS: 0.23633005
ACCEL X IS: 1.6888428 INTERVAL IS: 0.008392334 VELOCITY X IS: 0.2505034
ACCEL X IS: 1.7953186 INTERVAL IS: 0.008392334 VELOCITY X IS: 0.2655703
ACCEL X IS: 2.3388367 INTERVAL IS: 0.008392334 VELOCITY X IS: 0.2851986
ACCEL X IS: 3.2739716 INTERVAL IS: 0.008392334 VELOCITY X IS: 0.31267485
ACCEL X IS: 4.067398 INTERVAL IS: 0.008392334 VELOCITY X IS: 0.3468098
ACCEL X IS: 4.221344 INTERVAL IS: 0.008392334 VELOCITY X IS: 0.38223672
 ACCEL X IS: 4.281769 INTERVAL IS: 0.008392334 VELOCITY X IS: 0.41817075
ACCEL X IS: 3.0664673 INTERVAL IS: 0.008392334 VELOCITY X IS: 0.44390556
ACCEL X IS: 1.0762634 INTERVAL IS: 0.008392333 VELOCITY X IS: 0.45293793
ACCEL X IS: -0.5091095 INTERVAL IS: 0.008392334 VELOCITY X IS: 0.44866532
ACCEL X IS: -0.82073975 INTERVAL IS: 0.008392334 VELOCITY X IS: 0.4417774
ACCEL X IS: 0.5644531 INTERVAL IS: 0.008392334 VELOCITY X IS: 0.4465145
ACCEL X IS: 3.284546 INTERVAL IS: 0.008392334 VELOCITY X IS: 0.4740795
ACCEL X IS: 4.3601074 INTERVAL IS: 0.008392334 VELOCITY X IS: 0.51067096
ACCEL X IS: 4.3199615 INTERVAL IS: 0.008392334 VELOCITY X IS: 0.54692554
ACCEL X IS: 3.0349426 INTERVAL IS: 0.008392334 VELOCITY X IS: 0.5723958
ACCEL X IS: 1.763977 INTERVAL IS: 0.008392334 VELOCITY X IS: 0.5871997
ACCEL X IS: 1.4712982 INTERVAL IS: 0.008392334 VELOCITY X IS: 0.5995473
ACCEL X IS: 2.1172028 INTERVAL IS: 0.008392334 VELOCITY X IS: 0.6173156
ACCEL X IS: 2.1423798 INTERVAL IS: 0.008392334 VELOCITY X IS: 0.63529515
ACCEL X IS: 1.6801605 INTERVAL IS: 0.008392334 VELOCITY X IS: 0.64939564
ACCEL X IS: 1.8257599 INTERVAL IS: 0.008392334 VELOCITY X IS: 0.66471803
ACCEL X IS: 1.8712311 INTERVAL IS: 0.008392334 VELOCITY X IS: 0.680422
ACCEL X IS: 2.1062775 INTERVAL IS: 0.008392334 VELOCITY X IS: 0.6980986
ACCEL X IS: 2.054016 INTERVAL IS: 0.008392334 VELOCITY X IS: 0.71533656
ACCEL X IS: 0.0 INTERVAL IS: 0.008392334 VELOCITY X IS: 0.71533656
ACCEL X IS: -2.2228088 INTERVAL IS: 0.008392334 VELOCITY X IS: 0.696682
ACCEL X IS: -2.936676 INTERVAL IS: 0.008392334 VELOCITY X IS: 0.6720364
ACCEL X IS: -3.1568298 INTERVAL IS: 0.008392334 VELOCITY X IS: 0.6455432
ACCEL X IS: -2.484604 INTERVAL IS: 0.008392334 VELOCITY X IS: 0.6246916
ACCEL X IS: -2.213089 INTERVAL IS: 0.008392334 VELOCITY X IS: 0.6061186
ACCEL X IS: -1.923996 INTERVAL IS: 0.008392334 VELOCITY X IS: 0.5899718
ACCEL X IS: -2.902832 INTERVAL IS: 0.008392334 VELOCITY X IS: 0.56561023
ACCEL X IS: -5.460327 INTERVAL IS: 0.008392334 VELOCITY X IS: 0.51978534
ACCEL X IS: -7.1407623 INTERVAL IS: 0.008392334 VELOCITY X IS: 0.45985767
ACCEL X IS: -8.03479 INTERVAL IS: 0.008392334 VELOCITY X IS: 0.39242703
ACCEL X IS: -8.921448 INTERVAL IS: 0.008392334 VELOCITY X IS: 0.31755525
ACCEL X IS: -10.293076 INTERVAL IS: 0.008392334 VELOCITY X IS: 0.23117232
ACCEL X IS: -11.660858 INTERVAL IS: 0.008392334 VELOCITY X IS: 0.1333105
ACCEL X IS: -12.821564 INTERVAL IS: 0.008392334 VELOCITY X IS: 0.025707655
ACCEL X IS: -12.108749 INTERVAL IS: 0.008392334 VELOCITY X IS: -0.07591301
ACCEL X IS: -9.302032 INTERVAL IS: 0.008392334 VELOCITY X IS: -0.15397877
ACCEL X IS: -5.889694 INTERVAL IS: 0.008392334 VELOCITY X IS: -0.20340705
ACCEL X IS: -3.0645447 INTERVAL IS: 0.008392334 VELOCITY X IS: -0.22912574
ACCEL X IS: -1.2965088 INTERVAL IS: 0.008392334 VELOCITY X IS: -0.24000648
ACCEL X IS: -0.36557007 INTERVAL IS: 0.008392334 VELOCITY X IS: -0.24307446
ACCEL X IS: 0.0 INTERVAL IS: 0.008392334 VELOCITY X IS: -0.24307446

*Please note that the initial velocity in the log isn't 0 (but -0.17563461) because of some sensor errors that cause "fake" acceleration values when phone wasn't moving.

Thank you very much.


Solution

  • I think you should use the Linear acceleration Sensor provided by Android API :

    https://developer.android.com/reference/android/hardware/Sensor.html#TYPE_LINEAR_ACCELERATION

    It seems to fit perfectly to your needs

    EDIT : To deal with precision issue you can try to perform a manual calibration (The phone must be flat on a table and the measure must be stable) to remove the offset. Look here for more details (especially the end) : https://electronics.stackexchange.com/a/33387

    But you should also keep in mind that sensor are not perfect especially in phones and that's why it is just maybe impossible to get the precision you want with some phone's sensors. The solution to that is either adapt your algorithm treatments to the precision delivered by sensor, either to perform sensor fusion (with gyroscope for example).