0
$\begingroup$

Good day,

I have been reading papers about position integration from accelerometer readings.

I have consulted this paper from freescale on how that is achievable and this article regarding leaky integrators to help in preventing accumulation of errors from integration.

I was testing this algorithm by moving the imu by approximately 0.1 meter. The algorithm does get it right at the instant it arrives at approx 0.1 meter however when left still at that position, the integrated position goes to zero.

It turns out the velocity readings become negative at a certain period after reaching 0.1 meters.

Does anyone have any suggestions in dealing with this error?

Plots (Red is the position, Blue is the velocity.)

The imu(accelerometer) was moved alternating positions 0 meters and 0.1 meters with a stop of approximately 3-5 seconds in between before moving to the next position

  1. Actual Data enter image description here enter image description here

  2. Desired Data output (Green - Desired position integration) enter image description here

Code:

// Get acceleration per axis
float AccX = accelmagAngleArray.AccX;
float AccY = accelmagAngleArray.AccY;
float AccZ = accelmagAngleArray.AccZ;

AccX -= dc_offsetX;
AccY -= dc_offsetY;
AccZ -= dc_offsetZ;

//Calculate Current Velocity (m/s)
float leakRateAcc = 0.99000;
velCurrX = velCurrX*leakRateAcc + ( prevAccX + (AccX-prevAccX)/2 ) * deltaTime2;
velCurrY = velCurrY*leakRateAcc + ( prevAccY + (AccY-prevAccY)/2 ) * deltaTime2;
velCurrZ = velCurrZ*0.99000 + ( prevAccZ + (AccZ-prevAccZ)/2 ) * deltaTime2;
prevAccX = AccX;
prevAccY = AccY;
prevAccZ = AccZ;

//Discrimination window for Acceleration
if ((0.12 > AccX) && (AccX > -0.12)){
  AccX = 0;
}

if ((0.12 > AccY) && (AccY > -0.12)){
  AccY = 0;
}

//Count number of times acceleration is equal to zero to drive velocity to zero when acceleration is "zero"
//X-axis---------------
if (AccX == 0){ //Increment no of times AccX is = to 0
    counterAccX++;    
}
else{ //Reset counter
    counterAccX = 0;
}

if (counterAccX>25){ //Drive Velocity to Zero
velCurrX = 0;
    prevVelX = 0;
    counterAccX = 0;
}

//Y-axis--------------
if (AccY == 0){ //Increment no of times AccY is = to 0
    counterAccY++;    
}
else{ //Reset counter
    counterAccY = 0;
}

if (counterAccY>25){ //Drive Velocity to Zero
    velCurrY = 0;
    prevVelY = 0;
    counterAccY = 0;
}

//Print Acceleration and Velocity
cout << " AccX = " << AccX ;// << endl;
cout << " AccY = " << AccY ;// << endl;
cout << " AccZ = " << AccZ << endl;

cout << " velCurrX = " << velCurrX ;// << endl;
cout << " velCurrY = " << velCurrY ;// << endl;
cout << " velCurrZ = " << velCurrZ << endl;

//Calculate Current Position in Meters
float leakRateVel = 0.99000;
posCurrX = posCurrX*leakRateVel + ( prevVelX + (velCurrX-prevVelX)/2 ) * deltaTime2;
posCurrY = posCurrY*leakRateVel + ( prevVelY + (velCurrY-prevVelY)/2 ) * deltaTime2;
posCurrZ = posCurrZ*0.99000 + ( prevVelZ + (velCurrZ-prevVelZ)/2 ) * deltaTime2;
prevVelX = velCurrX;
prevVelY = velCurrY;
prevVelZ = velCurrZ;

//Print X and Y position in meters
cout << " posCurrX = " << posCurrX ;// << endl;
cout << " posCurrY = " << posCurrY ;// << endl;
cout << " posCurrZ = " << posCurrZ << endl;
$\endgroup$
0
$\begingroup$

I am now able to get position from the accelerometer.enter image description here Plot (Green - Acc, Blue -Vel, Red - Pos)

I was able to get the propper values through disabling the leaky integrator (setting the factor from 0.99 to 1).

$\endgroup$
  • $\begingroup$ I was able to do this with the quadcopter at the table and sliding it around, however it proved to be unreliable inflight $\endgroup$ – user123456098 Jul 26 '16 at 10:36
  • $\begingroup$ Thanks for the shared code and details. I'm about to build an app with similar requirements as drone position tracking(relying purely on IMU) and have found this very useful. Have you managed to improve your dead reckoning algorithm since posting this answer? $\endgroup$ – Armands L. Dec 18 '17 at 6:53
  • $\begingroup$ @ArmandsL. I am sorry but I have not been able to improve on this due to the inherent vibrations of the quadcopter inflight that generates noise from the accelerometer's measurements. $\endgroup$ – user123456098 Feb 1 '18 at 8:20
  • $\begingroup$ @user123456098 Did u try discreminate window to eliminate vibrations? $\endgroup$ – Khalil Laleh Aug 1 '18 at 14:05
  • $\begingroup$ @Khalil_Laleh I'm sorry as I have abandoned this endeavor a long time ago but I'll try to look into that when I have the time $\endgroup$ – user123456098 Aug 2 '18 at 4:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.