how to convert a accelerometer data to displacements

I have an accelerometer data which i have collected from gyroscope. I like to convert those acceleration to displacements as disturbances for calculating the dynamics of suspension. The problem is when i tried to convert the acceleration data to displacement by using two integrators in series the displacement data seems non realistic. In actual acceleration data i found there are decelerations as well but in displacement output i see all positive values. Please suggest me some techniques.......

4 Comments

How are you doing the double integration?
i have just use two integrators in series.......
jawad, did the solution below help?
How we can do spotting any trends in FFT peaks as a "function" of water depth Using function command?

Sign in to comment.

 Accepted Answer

Doing this sort of conversion is best done in the frequency domain. This should work now. Two things weren't working before:
1. Before I defined N as "nextpow2(N1)" instead of "2^nextpow2(N1)
2. I forgot to handle the case where f(i) = 0, we cannot divide by 0 !!
function disp_time_data = acc2disp(acc_time_data,dt)
% acc_time_data should be acceleration amplitudes evenly spaced in time
% dt in units of seconds per sample
N1 = length(acc_time_data);
N = 2^nextpow2(N1);
if N > N1
acc_time_data(N1+1:N) = 0; % pad array with 0's
end
df = 1 / (N*dt); % frequency increment
Nyq = 1 / (2*dt); % Nyquist frequency
acc_freq_data = fftshift(fft(acc_time_data));
disp_freq_data = zeros(size(acc_freq_data));
f = -Nyq:df:Nyq-df; % I think this is how fftshift organizes it
for i = 1 : N
if f(i) ~= 0
disp_freq_data(i) = acc_freq_data(i)/(2*pi*f(i)*sqrt(-1))^2;
else
disp_freq_data(i) = 0;
end
end
disp_time_data = ifft(ifftshift(disp_freq_data));
disp_time_data = disp_time_data(1:N1);
return
Try my sine wave example:
dt = 0.01; % seconds per sample
N = 512; % number of samples
t = 0 : dt : (N-1)*dt; % in seconds
wave_freq = 1; % in Hertz
acc_time_data = sin(2*pi*wave_freq*t);
The numerical answer obtained should be close to the analytical result by double-integrating by hand, i.e.:
disp_time_data_analytical = -1/(2*pi*wave_freq)^2*sin(2*pi*wave_freq*t);
The difference comes from the fact that we are chopping off the sine wave abruptly. You will notice that the "true" answer is super-imposed on a low-frequency sine wave - this is why it may be important to run a high-pass filter on the displacement result. It is possible to avoid this by removing any trend from the data, tapering each side of your timeseries down to 0, and then padding each side evenly with 0's (up to the next power of 2) before "converting" from acceleration to displacement.

11 Comments

Don't be mis-led by the OP's inaccurate use of "convert". It's not really a conversion. It's a calculation. Acceleration be integrated will be velocity. Velocity be integrated will be position (or displacement). That is why the OP mentioned "two integrators in series".
Out of curiosity, why does this work better than doing the integral numerically in the time domain?
Fangjun, I dealt with ground velocity and ground acceleration data during my graduate studies (I am an earthquake seismologist by "trade"). I routinely "convert" these various timeseries to displacement by the method I described above because is much more numerically stable than trying to integrate or double-integrate in the time domain (or differentiate twice if you were going from disp. to acc.).
Sean, I knew why back in graduate school. I have since forgotten the specifics/details why it is a more numerically stable result. I will have to look that up later.
Yes, the double derivation would obviously be unstable, but the integration should be stable, and since the measurements were accelerations it shouldn't be an issue.
Why does this appear to produce low values?
acc_time_data = 0:99;
dt = 0.5;
sum(abs(disp_time_data)) %a significant imaginary component
ans =
77.108
Seems _very_ low.
Thank you for the clarification!
Yeah... the answer shouldn't have any imaginary parts. Trying to work that out now. Like I mentioned, I have the solution at home. I was trying to work from memory what this function would look like.
Also, the acc_time_data should be more like something I mentioned above.
Sean de... check out page 94 here:
http://books.google.com/books?id=GnfpELDfzmEC&pg=PA95&lpg=PA95&dq=integration+differentiation+time+domain+versus+multiplication+division+in+frequency&source=bl&ots=oysKAgsSG2&sig=xjMXX6dSxy7eP5s5FKJSgjS4OIM&hl=en&ei=6fSNTtWbIuf-sQL7j72VAQ&sa=X&oi=book_result&ct=result&resnum=6&ved=0CEoQ6AEwBQ#v=onepage&q&f=false
See my above answer for the corrected code. Should be able to handle my sine wave example.
Hi Elige Grant, I have similar requirement where I need to convert acceleration data from 3-axis accelerometer into displacements in the corresponding direction. Theoretically speaking, the above method only works if the signal is zero mean. In general, this data will not be zero mean. In such case how can we use this method?
Also, as you said above, I can see the true output is superimposed on a low frequency sinusoid. However I did not understand how high pass filtering of this result will help to overcome this problem. Appreciate your suggestions. Thanks.
I believe you need to set disp_freq_data(1) to zero also.
Hello Dr. Seis, Thanks for answering this. I appreciate your efforts towards the community. I am new with Matlab and working with vibrational data too. I was wondering how to tune the displacement data we get? As the output from this code is completely different from what it supoosed to be.

Sign in to comment.

More Answers (1)

There is really no solution for this problem except that you need to check the quality of your accelerometer signal data. Is it noisy?
You can make up an ideal acceleration signal first and feed that signal to you double-integrator model to verify that you have everything right, for example, sample time, initial value, coefficient, etc.

14 Comments

Not true. This conversion should be performed in the frequency domain, not the time domain. Will provide solution later.
@Elige, Why does it have to do with frequency domain or time domain?
@Fangjun: I'm curious as well.
And why the value intuitively seems low for:
acc_time_data = 0:99;
well what is the criteria to know about noise????......because i have just text file which are the measurement for road roughness.......
acc_time_data should be acceleration amplitudes. For example, if the measured acceleration is a 1Hz sine wave:
dt = 0.01; % seconds per sample
N = 512; % number of samples
t = 0 : dt : (N-1)*dt; % in seconds
wave_freq = 1; % in Hertz
acc_time_data = sin(2*pi*wave_freq*t);
You should assume any measurement has some kind of noise. The approach for you is to test your double-integrator with an ideal signal first.
why not i upload my plot so that you have a look???? Please tell me how i can attach a file to this conversations.....
a free web hosting site somewhere. Make sure it's saves as .mat file, .txt file or .rtf file or we won't open it.
That's not really necessary. If you don't have a clue what is the noise, we won't have any better idea. Again, test your algorithm first with an idea signal. It won't be that hard to prove this simple algorithm. Then, if the result from measured data doesn't seem right, you need to trace back to find out the quality of the measurement. Elige Grant's answer seems to be promising since he had lots of similar experience before. You could also test out that function first with an ideal signal and then test it out on your measured data.
I'm working on getting the code to work for my sine wave now.
http://www.4shared.com/file/9jbdpGR3/test123.html
will be waiting for comments
See my answer for corrected Matlab code.
could you please re-share the uploaded file again with us, as i think the (4shared) link you are sharing is expired. thanks in advance.

Sign in to comment.

Categories

Find more on MATLAB in Help Center and File Exchange

Asked:

on 6 Oct 2011

Commented:

on 28 Jun 2022

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!