This study will utilize SciLab to explore the characteristics of low-pass filters. SciLab, Octave and MATLAB are all powerful scientific computing programs with significant overlap in functionality. As a result, any of these programs could be suitable for this investigation.
We will aim to understand and compare the characteristics of various filter types, including the Simple Moving Average, Weighted Moving Average, Exponential Moving Average, Butterworth Low Pass Filter and Alpha-Beta Filter.
Let’s use a noisy sine signal for the job.
for a clear sine;
pi = 3.1415;
M_SQRT2 = 1.4142;
t = 0 : 0.05 : 4*pi;
y = sin(t);
plot(t,y)
adding some noise;
r_var = 0.3*(0.5 - rand(t));
noisy_sine = y + r_var;
scf();
plot(t,noisy_sine)
Simple Moving Average
This filter applies a moving average to the integral of the previous data points.
SciLab code;
sma_filter_coeff = 32; //or 8
sma_array = zeros(1,length(t));
aux_array = zeros(1,length(sma_filter_coeff))
aux_total = 0;
for i = 1:length(t)
aux_array(sma_filter_coeff) = real_signal(i);
aux_total = real_signal(i)
for j = 1:(sma_filter_coeff-1)
aux_array(j) = aux_array(j+1)
aux_total = aux_total + aux_array(j);
end
sma_array(i) = aux_total/sma_filter_coeff;
end
Weighted Moving Average
SciLab code;
wma_filter_coeff = 16; //or 8
wma_array = zeros(1,length(t));
average = 0;
for i = 1:length(t)
average = average - (average/wma_filter_coeff);
average = average + (noisy_sine(i)/wma_filter_coeff);
wma_array(i) = average;
end
Exponential Moving Average
SciLab code;
ema_filter_coeff = 32; //or 8
ema_array = zeros(1,length(t));
alpha = 2/(ema_filter_coeff + 1)
for i = 1:length(t)-1
ema_array(i+1) = noisy_sine(i)*alpha + ema_array(i)*(1-alpha);
end
Butterworth Filter
A second order butterworth filter;
butterworth_array = zeros(1,length(t));
samplerate = 1;
cutoff = 0.05;
QcRaw = (2 * pi * cutoff) / samplerate;
QcWarp = tan(QcRaw);
gain = 1.0 / (1.0 + M_SQRT2/QcWarp + 2.0/(QcWarp*QcWarp));
by_2 = (1.0 - M_SQRT2/QcWarp + 2.0/(QcWarp*QcWarp)) * gain;
by_1 = (2.0 - 4.0/(QcWarp*QcWarp)) * gain;
by_0 = 1; ax_0 = gain; ax_1 = 2 * gain; ax_2 = gain;
xv_0 = 0; xv_1 = 0; xv_2 = 0; yv_0 = 0; yv_1 = 0; yv_2 = 0;
for i = 1:length(t)
xv_2 = xv_1;
xv_1 = xv_0;
xv_0 = noisy_sine(i);
yv_2 = yv_1;
yv_1 = yv_0;
yv_0 = ax_0 * xv_0 + ax_1 * xv_1 + ax_2 * xv_2 - by_1 * yv_0 - by_2 * yv_1;
butterworth_array(i) = yv_0;
end
Alpha-Beta Filter
In fact, the alpha-beta filter is not strictly a low-pass filter; it's primarily an estimator. However, it can be used for signal smoothing in a way that resembles a low-pass filter. Let's see how this works.
dt = 0.1;
ALPHA = 0.2;
BETA = 0.0001;
position = zeros(1,length(t));
speed = zeros(1,length(t));
measured = zeros(1,length(t));
prediction_error = 0;
for i = 2:length(t)
measured(i) = noisy_sine(i);
position(i) = position(i-1) + ( speed(i-1) * dt );
speed(i) = speed(i-1);
prediction_error = measured(i) - position(i);
position(i) = position(i) + ALPHA * prediction_error;
speed(i) = speed(i) + ( BETA / dt) * prediction_error;
position(i-1) = position(i);
speed(i-1) = speed(i);
end
All filters above in a frame (detail);