I am getting raw acceleration data from an accelerometer and am trying to double integrate it in order to get the position.
The android phone used to get the data is set on a flat surface for 3 seconds to diminish drift. I take the mean of acceleration over the resting period to zero out the beginning. This worked out fine, but when we integrate to velocity and position (using cumtrapz) we are getting unrealistically high y values (meters/s for velocity and meters for position.)
The raw data is waving the phone at a certain tempo.
Does anyone have ideas on why the position gets such high values? Below are the graphs showing what I described as well as my code.
Edit: Even when the phones is not rotated, the values are unrealistic and not indicative of how the phone moved. In the attached pictures, the phone was moved in the shape of a box on a flat surface with no rotation involved.
%VarName2 = accelerometer values in X direction
%VarName3 = accelerometer values in Y direction
%VarName4 = accelerometer values in Z direction
%elapsedArray = time values for each sample of accelerometer data
ddx = VarName2 - mean(VarName2(1:limit));
ddx = ddx(1:length(ddx)-200);
elapsedArray = elapsedArray(1:length(elapsedArray)-200);
ddy = VarName3 - mean(VarName3(1:limit));
ddy = ddy(1:length(ddy)-200);
ddz = VarName4 - mean(VarName4(1:limit));
ddz = ddz(1:length(ddz)-200);
velX = cumtrapz(ddx .* elapsedArray);
velY = cumtrapz(ddy .* elapsedArray);
velZ = cumtrapz(ddz .* elapsedArray);
dx = velX - mean(velX(1:limit));
dy = velY - mean(velY(1:limit));
dz = velZ - mean(velZ(1:limit));
posX = cumtrapz(dx .* elapsedArray);
posY = cumtrapz(dy .* elapsedArray);
posZ = cumtrapz(dz .* elapsedArray);
x = posX - mean(posX(1:limit));
y = posY - mean(posY(1:limit));
z = posZ - mean(posZ(1:limit));
figure;
plot(ddx);
title('Acceleration in X')
xlabel('Time (sec)')
ylabel('Acc (meters squared');
figure;
plot(dx);
title('Velocity in X')
xlabel('Time (sec)')
ylabel('Velocity (meters)');
figure;
plot(x);
title('Position X')
xlabel('Time (sec)')
ylabel('Position (meters)');
figure;
plot(y);
title('Position Y')
xlabel('Time (sec)')
ylabel('Position (meters)');
figure;
plot(z);
title('Position Z')
xlabel('Time (sec)')
ylabel('Position (meters)');
Acceleration in X direction
Velocity and Position in X direction
What you are seeing is the result of time drift. Let's assume that the accelerometer readings you are measuring have a very small error, dErr, at every time point. Once you integrate these values to get velocity, the error at each time point will be multiplied by a factor t. Integrating a second time to get position will cause the original error to be multiplied by a factor of t^2. Therefore, the error at each time point will propogate at dErr(t)*t^2.
In order to get a good estimate for position, you can try to incorporate prior information about position, but will likely have to use a combination of accelerometer and gyroscope data. You might also have to look into Kalman Filters.
Here is a Google Tech Talk explaining this issue: https://youtu.be/C7JQ7Rpwn2k?t=23m33s
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With