Você está na página 1de 15

Sistemas de Medio

Filtros de Kalman
Matheus Vieira Portela - 10/0017959
matheus.v.portela@gmail.com
15 de outubro de 2013
Questo 1 - Filtro de mdia
(a) Forma recursiva
O ltro de mdia (em ingls, average lter), dado k medies x
1
, x
2
, , x
k1
, x
k

denido pela expresso:
x
k
=
x
1
+ x
2
+ + x
k1
+ x
k
k
(1)
Naturalmente, considerando apenas as primeiras k1 medies, a expresso torna-se:
x
k1
=
x
1
+ x
2
+ + x
k1
k 1
(2)
Primeiramente, vamos isolar as medies no termo da direita das equaes (1) e (2).
Obtemos, assim, o seguinte:
x
k
k = x
1
+ x
2
+ + x
k1
+ x
k
(3)
e
x
k1
(k 1) = x
1
+ x
2
+ + x
k1
(4)
Ento, substitui-se (4) em (3)
x
k
k = x
k1
(k 1) + x
k
(5)
e, enm, ao isolarmos x
k
, temos a equao do ltro de mdia em forma recursiva
x
k
=
k 1
k
x
k1
+
1
k
x
k
(6)
C.Q.D.
(b) Simulao em MATLAB
(i) Gerao de dados
Ao gerar os dados para serem utilizados na simulao, primeiramente considerou-se os
valores reais, isto , os dados puros sem rudo gaussiano. Alm disso, foi considerado
que o avio viaja com uma altitude de cruzeiro de 11 mil metros.
Em seguida, adicionou-se rudo proveniente do instrumento de medio, com mdia 0
e desvio padro de 4 m, conforme indicado no exerccio proposto.
(ii) Script
Filtro de mdia em forma recursiva
1
%% Average filter
%
% Implements recursive average filter
%
% Parameters:
% X_k - new value
% avg_k_1 - last average value
% k - current number of points
%
% Return:
% avg_k - new average value
%
function avg_k = average_filter(X_k, avg_k_1, k)
avg_k = ((k - 1)/k)*avg_k_1 + X_k/k;
end
Script completo
%% Generating data
rng(5); % Setting the random number generator seed
h = 11000; % Altitude
f1 = 1 - exp(-(1:180)/15); % Take-off
f2 = ones(1, 600); % Cruising
f3 = 1 - exp((-180:-1)/15); % Landing
real_data = h*[f1 f2 f3];
N = length(real_data); % number of points
noise = 4.*randn(N, 1);
data = real_data + noise;
time = 1:5:5*N;
% Saving generated data
save(simulation_data.mat, N, real_data, noise, data, time);
%% Displaying data
f = figure;
plot(time, real_data, g);
hold on;
plot(time, data, b);
%% Applying average filter
avg = data(1);
2
result = zeros(size(data));
for k = 1:length(data)
avg = average_filter(data(k), avg, k); % Averaging
result(k) = avg; % Saving current result
end
%% Displaying average filter results
plot(time, result, r);
title(Average filter);
xlabel(Time (s));
ylabel(Altitude (m));
legend(Real data, Acquired data, Average filter);
saveas(f, q1_results.png);
(iii) Resultados
Figura 1: Filtro de mdia
3
Questo 2 - Filtro de mdia mvel
(a) Forma recursiva
Diferentemente do ltro de mdia, a mdia mvel (em ingls, moving average) no
leva em considerao todas as k medidas x
1
, x
2
, , x
k1
, x
k
, mas apenas os ltimos
n valores para cada intervalo.
Dene-se a mdia mvel simples por meio da seguinte equao:
x
k
=
x
kn+1
+ x
kn+2
+ + x
k1
+ x
k
n
(7)
Para os primeiros k 1 termos, a equao escrita como
x
k1
=
x
kn
+ x
kn+1
+ + x
k1
n
(8)
Seguindo a metodologia empregada na Questo 1 (a), vamos isolar os termos de (7)
no intervalo de k n + 1 a k 1
x
k
n = x
kn+1
+ x
kn+2
+ + x
k1
+ x
k
(9)
x
k
n x
k
= x
kn+1
+ x
kn+2
+ + x
k1
(10)
e, agora, da equao (8)
x
k1
n = x
kn
+ x
kn+1
+ + x
k1
(11)
x
k1
n x
kn
= x
kn+1
+ x
kn+2
+ + x
k1
(12)
Substituindo (12) em (10), temos
x
k
n x
k
= x
k1
n x
kn
(13)
x
k
n = x
k1
n + x
k
x
kn
(14)
por m, chegamos expresso recursiva da mdia mvel simples
x
k
= x
k1
+
x
k
x
kn
n
(15)
C.Q.D.
(b) Simulao em MATLAB
(i) Gerao de dados
Utilizou-se os mesmos dados da Questo 1 (b).
4
(ii) Script
Filtro de mdia mvel em forma recursiva
%% Moving average
%
% Implements recursive moving average
%
% Parameters:
% X_k - new value
% X_k_n - last value of the moving average window
% avg_k_1 - last average value
% n - size of the moving average window
%
% Return:
% avg_k - new average value
%
function avg_k = moving_average(X_k, X_k_n, avg_k_1, n)
avg_k = avg_k_1 + (X_k - X_k_n)/n;
end
Script completo
%% Loading data
simulation_data = load(simulation_data.mat);
N = simulation_data.N; % Number of points
real_data = simulation_data.real_data;
noise = simulation_data.noise;
data = simulation_data.data;
time = simulation_data.time;
%% Displaying data
f = figure;
plot(time, real_data, g);
hold on;
plot(time, data, b);
%% Applying moving average filter
n = 15; % Bandwidth for the moving average
avg = mean(data(1:n)); % Initializing with simple average
result = zeros(length(data) - n, 1);
for k = (n + 1):length(data)
avg = moving_average(data(k), data(k - n), avg, n); % Averaging
result(k - n) = avg; % Saving current result
5
end
%% Displaying moving average
plot(time((n + 1):end), result, r);
title(sprintf(Moving average filter - n=%d, n));
legend(Real data, Acquired data, Moving average);
saveas(f, q2_results.png);
(iii) Resultados
Figura 2: Filtro de mdia mvel com janela n = 15
6
Questo 3 - Filtro de mdia mvel exponencial
(a) Forma exponencial
A mdia mvel exponencial denida recursivamente como:
x
k
= x
k1
+ (1 )x
k
(16)
Para k 1 e k 2, aplicando a expresso (16), obtemos as equaes a seguir
x
k1
= x
k2
+ (1 )x
k1
(17)
e
x
k2
= x
k3
+ (1 )x
k2
(18)
Substituindo (17) em (16)
x
k
= [ x
k2
+ (1 )x
k1
] + (1 )x
k
(19)
x
k
=
2
x
k2
+ (1 )x
k1
+ (1 )x
k
(20)
Agora, substituimos (18) em (20)
x
k
=
2
[ x
k3
+ (1 )x
k2
] + (1 )x
k1
+ (1 )x
k
(21)
chegando, nalmente, forma exponencial do ltro de mdia mvel exponencial
x
k
=
3
x
k3
+
2
(1 )x
k2
+ (1 )x
k1
+ (1 )x
k
(22)
C.Q.D.
(b) Simulao em MATLAB
(i) Gerao de dados
Utilizou-se os mesmos dados da Questo 1 (b).
(ii) Script
Filtro de mdia mvel exponencial em forma recursiva:
%% Exponential moving average
%
% Implements recursive exponential moving average
%
% Parameters:
% X_k - new value
% avg_k_1 - last average value
% alpha - decaying coefficient
7
%
% Return:
% avg_k - new average value
%
function avg_k = exponential_moving_average(X_k, avg_k_1, alpha)
avg_k = alpha*avg_k_1 + (1 - alpha)*X_k;
end
Script completo:
%% Loading data
simulation_data = load(simulation_data.mat);
N = simulation_data.N; % Number of points
real_data = simulation_data.real_data;
noise = simulation_data.noise;
data = simulation_data.data;
time = simulation_data.time;
%% Displaying data
f = figure;
plot(time, real_data, g);
hold on;
plot(time, data, b);
%% Applying exponential average filter
alpha = 0.25;
avg = data(1);
result = zeros(size(data));
for k = 1:length(data)
avg = exponential_moving_average(data(k), avg, alpha); % Averaging
result(k) = avg; % Saving current result
end
%% Displaying exponential moving average
plot(time, result, r);
title(sprintf(Exponential moving average filter - alpha=%.2f, alpha));
legend(Real data, Acquired data, Exponential moving average);
saveas(f, q3_results.png);
8
(iii) Resultados
Figura 3: Filtro de mdia mvel exponencial com decaimento = 0, 25
9
(c) Comparao de resultados
Todos os trs ltros (de mdia, de mdia mvel e de mdia mvel exponencial) produ-
ziram resultados signicativamente diferentes. Para compreend-los, vamos analisar
a natureza dos ltros aplicados.
O ltro de mdia considera que todas as medies so igualmente relevantes para o
resultado nal, assim, cada novo valor inserido com o mesmo peso dos anteriores.
Dessa forma, o ltro tende a convergir para o ponto intermedirio de todas as medies
realizadas. Por essa razo, o ltro diverge signicativamente da altura atual de vo,
no sendo recomendado para medies que variem signicativamente ao longo do
tempo. Entretanto, caso estejamos medindo valores constantes, o ltro de mdia
uma excelente escolha.
A mdia mvel tambm considera que todas as medies possuem a mesma impor-
tncia, entretanto, apenas para aquelas que esto dentro da sua janela. Todas as
outras medies que estejam fora do intervalo da mdia mvel so completamente
ignoradas. Assim, a mdia mvel apresenta leituras locais de tendncias de alta ou de
baixa, para o intervalo determinado. Nota-se que, para n k, o ltro de mdia mvel
tende ao mesmo resultado do ltro de mdia. Para a altitude de vo do avio, esse
ltro apresenta resultados muito mais relevantes que aqueles produzidos pelo ltro de
mdia.
Por m, a mdia mvel exponencial considera que as ltimas leituras so mais im-
portantes do que as anteriores, cuja relevncia decai exponencialmente de acordo com
o fator . Assim, o ltro acompanha a tendncia de alta ou de baixa das ltimas
leituras realizadas, sendo mais voltil que os ltros de mdia e mdia mvel. O sensor
de altitude do avio benecia-se da caracterstica de diminuir exponencialmente a
importncia dos pontos mais antigos, dessa forma, produzindo resultados relevantes.
10
Questo 4 - Filtro de Kalman
(a) Modelo do sistema
Para a aplicao denida, escolheu-se o seguinte modelo para o ltro de Kalman.
Etapa de estimao:
x
t|t1
= x
t1|t1
p
t|t1
= p
t1|t1
+ r
(23)
Etapa de atualizao:
K
t
= p
t|t1
(p
t|t1
+ q)
1
x
t|t
= x
t|t1
+ K
t
(y
t
x
t|t1
)
p
t|t
= (1 K
t
)p
t|t1
(24)
onde x
t1|t1
a ltima estimativa, p
t1|t1
a covarincia da ltima estimativa, x
t|t1
a medida intermediria antes de incorporar as medies, p
t|t1
a covarincia inter-
mediria antes de incorporar as medies, x
t|t
a nova estimativa, p
t|t
a covarincia
da ltima estimativa, y
t
a medio realizada, r a incerteza no modelo utilizado, q
a incerteza das medies e K
t
o ganho de Kalman.
(b) Valores iniciais
Implementou-se as equaes do ltro de Kalman generalizado:

t
= A
t1
+ Bu
t

t
= A

t1
A + R
K
t
=
t
C
T
(C
t
C
T
+ Q)

t
=
t
+ K
t
(z
t
C
t
)

t
= (I K
t
C)
t
(25)
onde a estimativa, a covarincia da estimativa, u o sinal de controle, z a
medio e K o ltro de Kalman.
Para tanto, os valores iniciais utilizados foram:
A = 1
B = 0 - no h sinal de controle
C = 1
R = 0.01 - o modelo no muito el
Q = 30 - as medidas so extremamente ruidosas
11
(c) Gerao de dados
Considerou-se que a bateria respeita as equaes de carga e descarga de um capacitor.
Dessa forma, os valores foram gerados conforme a equao
v(t) = V e
t/
C
(26)
onde v(t) o valor da tenso no instante t, V o valor inicial da tenso e
C
a
constante de tempo do capacitor.
Utilizou-se V = 14 e
C
= 1000.
(d) Script
Filtro de Kalman:
function [new_mean, new_cov] = kalman_filter(mean, cov, u, z, A, B, C, R, Q)
% Prediction phase
m = A*mean + B*u;
S = A*cov*A + R;
% Update phase
K = S*C*pinv(C*S*C + Q);
new_mean = m + K*(z - C*m);
I = eye(size(K, 1), size(C, 2));
new_cov = (I - K*C)*S;
end
Script completo:
%% Generating data
rng(5); % Setting the random number generator seed
voltage = 14; % Voltage (V)
time = (1:2600); % Time - life-time of 2600 hours
N = length(time); % Number of points
real_data = voltage*exp(-time/1000); % Real data
noise = 3*randn(N, 1); % Noise - mean = 0V, standard deviation = 3V
data = real_data + noise; % Acquired data
%% Initializing Kalman filter
result = zeros(length(data), 2);
% Initial belief - completely unknown
mean = 0;
cov = 10000;
% Measurement model
12
A = 1; % linear
R = 0.01; % system noise - not an accurate model
% Control model - no control
B = 0;
u = 0;
% Measurements model
C = 1; % linear
Q = 30; % measurement noise - highly noisy measurements
z = data;
%% Applying Kalman filter
for k = 1:length(data)
% Averaging
[mean, cov] = kalman_filter(mean, cov, u, z(k), A, B, C, R, Q);
% Saving current result
result(k, 1) = mean;
result(k, 2) = cov;
end
%% Displaying data
f1 = figure(1);
plot(time, data, b-);
hold on;
plot(time, real_data, g-);
plot(time, result(:, 1), r-);
title(Kalman filter);
legend(Acquired data, Real data, Kalman filter);
f2 = figure(2);
plot(time, result(:, 2), b);
title(Kalman filter covariance evolution);
saveas(f1, q4_results.png);
saveas(f2, q4_covariance.png);
13
(e) Resultados
Figura 4: Filtro de Kalman
Percebe-se que o ltro de Kalman implementado consegue aproximar os valores reais
da tenso na bateria com boa preciso. Possivelmente, os resultados podem ser me-
lhorados ao utilizar um Filtro de Kalman Estendido (Extended Kalman Filter, EKF)
uma vez que este capaz de utilizar modelos no-lineares para o sistema, tal como a
equao de descarga do capacitor.
14

Você também pode gostar