How to design a moving average filter over a variable time array
6 Ansichten (letzte 30 Tage)
Ältere Kommentare anzeigen
Corey Peruffo
am 13 Mär. 2016
Beantwortet: Star Strider
am 14 Mär. 2016
Hi!
So basically i'm given an array of accelerometer data with a sample timestamp and ax,ay, and az accelerations. The sample frequency is variable in the sense that the timestamps do not have a constant delta-t between them. I'm asked to filter the data using a moving average filter that covers .1s of data capture. I am new to filtering and am unsure on where to even begin here.
Thanks!
0 Kommentare
Akzeptierte Antwort
Star Strider
am 14 Mär. 2016
Your data have a maximum sampling interval of 4 and a minimum sampling interval of 2, so you can safely interpolate them with a sampling interval of 2 without compromising your data. (No proof — just personal experience.)
I discourage the use of moving average filters because they offer no specific control over the frequency characteristics of the filter. I always use low-pass filters instead. Note that your signals have broad-band ‘impulse’ noise, so filtering all of it out is not possible.
I would process your signals as:
D = load('Corey Peruffo DataMovingAverage.mat');
t = D.time;
ax = D.ax;
ay = D.ay;
tmsd = [mean(diff(t)) std(diff(t)); max(diff(t)) min(diff(t)); median(diff(t)) mode(diff(t))];
ti = [0:2:max(t)]'; % Interpolating Time Vector
axiayi = interp1(t, [ax ay], ti, 'linear'); % Interpolate Signals
axi = axiayi(:,1);
ayi = axiayi(:,2);
figure(1)
plot(t, [ax ay])
grid
Ts = mean(diff(ti)); % Sampling Interval
Fs = 1/Ts; % Sampling Frequency
Fn = Fs/2; % Nyquist Frequency
L = length(ti);
Fxyi = fft([axi ayi])/L;
Fv = linspace(0, 1, fix(L/2)+1)*Fn; % Frequency Vector
Iv = 1:length(Fv); % Index Vector
figure(2)
semilogy(Fv, abs(Fxyi(Iv,:))*2)
grid
axis([0 0.1 ylim])
Wp = 0.006/Fn; % Passband Frequency (Normalised)
Ws = 0.012/Fn; % Stopband Frequency (Normalised)
Rp = 1; % Passband Ripple (dB)
Rs = 25; % Stopband Ripple (dB)
[n,Wn] = buttord(Wp, Ws, Rp, Rs); % Optimal Filter Order
[b,a] = butter(n,Wn,'low'); % Filter Transfer Finction Coefficients
[sos,g] = tf2sos(b,a); % Convert To Second-Order-Section For Stability
figure(3)
freqz(sos) % Filter Bode Plot
filt_xyi = filtfilt(sos, g, [axi, ayi]); % Filter Signal
figure(4)
plot(ti, filt_xyi)
grid
The numerator values of ‘Wp’ and ‘Ws’ are in Hz (or the inverse of whatever time interval your ‘time’ variable is). Experiment with those to get the result you want in the filtered signal. They might be too low to recover all the frequencies you want. I put ‘Ws’ at twice ‘Wp’. Putting them too close together will result in an unstable filter and no useful output. For a low-pass filter, ‘Ws’ must be greater than ‘Wp’.
0 Kommentare
Weitere Antworten (1)
Jan
am 13 Mär. 2016
Bearbeitet: Jan
am 13 Mär. 2016
If you provide example data, it would be possible to post some real code.
You can perform a linear interpolation at first to obtain the values with a fixed frequency. Afterwards a standatd moving average filter using conv or filter can be applied:
B = repmat(0.1, 1, 10); % E.g. a 10 point window
out = filter(B, 1, Signal);
3 Kommentare
Jan
am 14 Mär. 2016
@Corey: I assume you are able to import the data already. If so, please provide a MAT file and attach it as file directly in the forum. The less trouble the helpers have, the better.
What repmat does is explained exhaustively in the documentation:
doc repmat
Siehe auch
Kategorien
Mehr zu Matched Filter and Ambiguity Function finden Sie in Help Center und File Exchange
Produkte
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!