# Weird behaviour converting velocity to displacement

I'm trying to convert accelerometer data from accelerations to displacement,

I assume that the initial velocity is zero and the initial position is also zero.

Here's my code,

Fs = 500;
T = 1/Fs;
t = (0:length(y) -1)*T;

vel = cumtrapz(t, acc);
disp = cumtrapz(t, vel);


here are the respective plots from acceleration to displacement,   what am I doing wrong?

I've implemented a kalman filter but the result is the same. I'm trying to work around with wavelet decomposition, any help would be very appreciated to resolve this problem.

• Why do you think you're doing something wrong? Jan 29 '14 at 19:26
• @JasonR because the acceleration is from the y axis, all I do it to move the accelerometer up and down 2 times. The final position in the same as in the beginning. Jan 29 '14 at 19:50
• How to you get the middle plot? Jan 30 '14 at 1:51
• I've implemented the Kalman filter and the results are the same as using only the cumtrapz function. Feb 4 '14 at 18:30

You have two problems here.

First, as hotpaw2 mentioned, double integration is sensitive to any non-zero bias in your accelerometer, which will certainly be present if you are using a MEMS accelerometer. Suppose you have a bias of $b$; then, your position at time $t$ is

$$p(t) = \int_0^t \int_0^{t^\prime} b \ dt^{\prime\prime} \ dt^\prime = \frac{b}{2} t^2$$.

Another problem will be the measurement noise that is riding on your signal. Double integration of this noise signal will behave like a second-order random walk and will also cause your position to diverge over time.

A common approach to this sort of problem is to use a Kalman Filter. Also, this is a good introduction to position estimation using accelerometers.

• I was not able to implement that Kalman Filter in matlab. Any simpler suggestion? Feb 3 '14 at 17:38

Double integration is very sensitive to any offset noise in acceleration measurement.

Even a very tiny non-zero acceleration offset will, when double integrated and given enough time, send the calculated position outside the radius of the galaxy.

Some sort of position or location measurements, with respect to some fixed reference point, in addition to acceleration data, may be required to compensate for any offset and noise in the acceleration data.

• This is more of a comment. Mind expanding? Jan 30 '14 at 1:51

It depends what type of accelerometer you are using and what you want the displacement signal for. I'm not an expert in signal processing, but I have sure used a lot of accelerometers.

Most piezoelectric accelerometers do not work down to DC - these accelerometers use charge amplifiers and the Low Frequency response is dependant on the time constant of the amplifier. Accelerometers like these are commonly used for, e.g, structural and machinery vibration monitoring. Employing a band pass filter as you have done is appropriate. You could also fit a straight line to the acceleration signal and then subtract that line before integration, then do the same to the resulting velocity signal. Just be aware that this approach has limitations at low frequencies.

If, on the other hand, you are using a sensor that can measure down to DC (e.g. piezo-resistive accelerometers) you will not have the low frequency limitations of piezoelectric accleerometers. If, though, you want to use the signal to work out distance moved, then see LukeP's links, though the results are not likley to be accurate...

I resolved the issue, applying a butterworth band-pass in both acceleration and velocity,

close all
clear all
clc

Fs = 500;
T = 1/Fs;
x = linspace(1,2000,2000);
t = (0:length(a) -1)*T;

a = a.*9.8;

al = bandpass_butterworth(a, [0.5 25], Fs,2);

vel = cumtrapz(t,al);
vel = bandpass_butterworth(vel, [0.5 25], Fs,2);

pos = cumtrapz(t,vel);

subplot(311), plot(t,al);
ylabel('Acceleration [m/s^2]');
subplot(312), plot(t,vel);
ylabel('Velocity [m/s]');
subplot(313), plot(t,pos);
ylabel('Position [m]');
xlabel('Time [s]'); As you can see, the initial position almost corresponds to the final one. This example is not the same as the original signal as I don't have the other one anymore.

• I would caution you to look closely to see if this solution actually gives you the result you want. You're applying a bandpass filter that blocks DC, so you're guaranteed that in the steady state, the filter output will tend back to a DC level of zero (in your case, indicating zero displacement from the starting point). Try inputting a set of data where you don't move the accelerometer back to the original position and you should still see the filter output decay to zero (erroneously). Feb 10 '14 at 16:50
• @JasonR I understand your point, but in my experience the initial position is equal to the last position. I thought about that and I think in this particular case, this can be a solution. Feb 10 '14 at 16:59

The problem you encountered is related to the presence of a DC component in the velocity.

Another way to solve the problem could be to use the detrend() function (if you are working with MATLAB) in such a way to remove only that component.

If this does not work well enough than you can thing about applying a filter, high-pass should be enough. Unless you need to remove some noise from the signal, you can set di cut-off frequency to a really low value in order to touch only the DC component you want to remove.

A comment related to the integration method you are using. The trapezium rule only suffers from the introduction of low-frequency components and therefore does not require the use of a low-pass filter (this is why I said an high-pass filter should be enough for your signals).

Finally, some references related to time integration of acceleration measurements:

J.G.T. Ribeiro, J.L.F. Freire, J.T.P. de Castro, Some comments on digital integration to measure displacements using accelerometers

J.G.T. Ribeiro, J.L.F. Freire, J.T.P. de Castro, New improvements in the digital double integration filtering method to measure displacements using accelerometers