Differentiating a noisy position signal

19 views (last 30 days)
Michael Delpapa
Michael Delpapa on 9 Nov 2015
Answered: Star Strider on 9 Nov 2015
Hello,
I have a position signal measured at 10 kHz from a laser position sensor. I want to differentiate the position signal to find acceleration and therefore be able to find Force.
A 0.6kg weight is falling 10 cm to compress a meniscus sample. As the sample is compressed the position read from the laser sensor is larger.
The position signal is good data, and the velocity is what is expected. However, the velocity and acceleration plots are very noisy. I have tried a moving average filter and savitsky golay filter, but can't get them to work properly.
I have attached plots of the position, velocity, and acceleration data. Please let me know if you have any suggestions.
Thank you, Michael

Answers (1)

Star Strider
Star Strider on 9 Nov 2015
The .fig file contains all the data, so I was able to extract it and experiment with it. I was able to clean your signal to some extent, however you will have to experiment with the filter characteristics (passband, stopband, ripple amplitudes) if my design does not do what you want. I chose a Chebyshev filter for its sharp cutoff. I subtracted the mean because it made the signal easier to work with. The amplitude of the filtered signal is less than the original because much of the energy of the noise is no longer present. I used the gradient function to calculate the derivative.
The final step will be to use a Savitzky-Golay on the filtered data. I didn’t implement the Savtizky-Golay filter here, because my primary interest is in providing a relatively ‘clean’ signal for you to implement it on. (I am using R2015b.)
The code:
openfig('Michael Delpapa Noisy Droptower Figures.fig'); % Load Figure
Sp = subplot(4,1,1); % Select Top Subplot
L = findobj(gca, 'Type','line'); % Get ‘line’ Object
Lx = get(L, 'XData'); % Extract Data
Ly = get(L, 'YData');
Lym = mean(Ly);
Ly = Ly-Lym; % Subtract Mean
Ts = mean(diff(Lx)); % Sampling Interval
Fs = 1/Ts; % Sampling Frequency
Fn = Fs/2; % Nyquist Frequency
LL = length(Ly); % Data Vector Length
FLx = fft(Ly)/LL; % FFT
Fv = linspace(0, 1, fix(LL/2)+1)*Fn; % Frequency Vector
Iv = 1:length(Fv); % Index Vector
figure(2)
semilogy(Fv, abs(FLx(Iv)))
grid
hold on
plot([1000 1000], ylim, 'r')
hold off
% axis([0 1000 ylim])
legend('Data', 'Desired \itf\rm_{co}')
Wp = 1000/Fn; % Passband Frequency
Ws = 1500/Fn; % Stopband Frequency
Rp = 1; % Passband Ripple
Rs = 75; % Stopband Ripple
[n,Wp] = cheb1ord(Wp, Ws, Rp, Rs); % Filter Order
[b, a] = cheby1(n,Rp,Wp); % Design Filter
[sos,g] = tf2sos(b,a); % Convert To SOS For Stability
figure(3)
freqz(sos, 1024, Fs) % Filter Characteristics Plot
Yf = filtfilt(sos, g, Ly); % Filtered Signal
figure(4)
plot(Lx,Ly, Lx, Yf)
grid
axis([42.52 42.75 ylim])
legend('Original', 'Filtered')
figure(5)
plot(Lx,gradient(Yf))
grid
axis([42.52 42.75 ylim])
legend('Derivative of Filtered Signal')

Community Treasure Hunt

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

Start Hunting!