MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn moreOpportunities for recent engineering grads.

Apply Today
Asked by Adam on 19 Nov 2011

Hi guys,

I'm trying to model a jump, using simulink I've found the displacement ( height vs. distance), I'm trying to find the velocity and acceleration of the jump. I've tried to use a derivative block, where I've inserted after my transfer block it (between the y displacement and my XY graph). The velocity isn't coming out right, and reducing the size of the step size doesn't seem to be helping.

Could anyone give me any advice?

I can attach the m file or a screenshot if needed.

Thanks

Answer by Guy Rouleau on 12 Jan 2012

I like to use a filtered derivative to do that.

A transfer function in the form s/(tau*s+1)^2 with the right "tau" will give you something close to "s" for low frequency and close to "1" for high frequency, limiting that spike that you probably see in your model.

You can find some doc on that in the SimMechanics doc:

http://www.mathworks.com/help/toolbox/physmod/mech/ug/f2-117031.html

Answer by Elige Grant on 12 Jan 2012

This is a function I wrote to convert seismograms from one domain to another:

function dataout = iomega(datain, dt, datain_type, dataout_type)

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % IOMEGA is a MATLAB script for converting displacement, velocity, or % acceleration time-series to either displacement, velocity, or % acceleration times-series. The script takes an array of waveform data % (datain), transforms into the frequency-domain in order to more easily % convert into desired output form, and then converts back into the time % domain resulting in output (dataout) that is converted into the desired % form. % % Variables: % ---------- % % datain = input waveform data of type datain_type % % dataout = output waveform data of type dataout_type % % dt = time increment (units of seconds per sample) % % 1 - Displacement % datain_type = 2 - Velocity % 3 - Acceleration % % 1 - Displacement % dataout_type = 2 - Velocity % 3 - Acceleration % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% Make sure that datain_type and dataout_type are either 1, 2 or 3 if (datain_type < 1 || datain_type > 3) error('Value for datain_type must be a 1, 2 or 3'); elseif (dataout_type < 1 || dataout_type > 3) error('Value for dataout_type must be a 1, 2 or 3'); end

% Determine Number of points (next power of 2), frequency increment % and Nyquist frequency N = 2^nextpow2(max(size(datain))); df = 1/(N*dt); Nyq = 1/(2*dt);

% Save frequency array iomega_array = 1i*2*pi*(-Nyq : df : Nyq-df); iomega_exp = dataout_type - datain_type;

% Pad datain array with zeros (if needed) size1 = size(datain,1); size2 = size(datain,2); if (N-size1 ~= 0 && N-size2 ~= 0) if size1 > size2 datain = vertcat(datain,zeros(N-size1,1)); else datain = horzcat(datain,zeros(1,N-size2)); end end

% Transform datain into frequency domain via FFT and shift output (A) % so that zero-frequency amplitude is in the middle of the array % (instead of the beginning) A = fft(datain); A = fftshift(A);

% Convert datain of type datain_type to type dataout_type for j = 1 : N if iomega_array(j) ~= 0 A(j) = A(j) * (iomega_array(j) ^ iomega_exp); else A(j) = complex(0.0,0.0); end

end

% Shift new frequency-amplitude array back to MATLAB format and % transform back into the time domain via the inverse FFT. A = ifftshift(A); datain = ifft(A);

% Remove zeros that were added to datain in order to pad to next % biggerst power of 2 and return dataout. if size1 > size2 dataout = real(datain(1:size1,size2)); else dataout = real(datain(size1,1:size2)); end

return

Show 2 older comments

x on 12 Dec 2012

Hi Elige Grant,

I am doing a project using accelerometer to track the movement of the human body. I want to use your iomega function to get displacement fromt the accelerometer readings as follows,

posx = iomega(accelx,1/Fs,3,1); posy = iomega(accely,1/Fs,3,1); posz = iomega(accelz,1/Fs,3,1);

As the accelx/accely/accelz are vectors, posx/posy/posz are also vectors. So I can plot the movement path by plot3d(posx, posy, posz). However, the output is not quite as expected. Note that I already filtered and calibrated the accelerometer readings before calling iomega.

Could you please let me know 1) can I use iomega for accelerometer to path purpose? 2) what else I should do for use the iomega?

Many thanks!

x on 12 Dec 2012

Hi Walter Roberson,

Thanks for your comment. actually, after I used iomega to get position, I also used polyfit and polyval function to eliminate the trend term (which I assume I must do it). However, I found it make the results "not quite as expected". So I used just iomega, it looks like it works. I attached the corresponding figures here. As you can see, the top figure is that I only used iomega, the bottom one I used polyfit & polyval after iomega. Note that the data should reflet I did a "reach and retrieve" action.

any comments? http://s20.postimage.org/hnmec222l/fig.jpg

## 2 Comments

Direct link to this comment:http://www.mathworks.com/matlabcentral/answers/21700#comment_47185

Heres an image of the simulation: http://imageshack.us/f/51/18107661.png/

Direct link to this comment:http://www.mathworks.com/matlabcentral/answers/21700#comment_57084

Take a look at the demo model sldemo_bounce. It might help.