So, I was asked to design a Kalman filter and run some simulations to see the results. Given equations:
x(k+1) = -0.8*x(k) + sin(0.1k) + w(k)
y(k) = x(k) + v(k)
where w(k) and v(k) are processing and measurment noises
w(k)~N(0, 0.01)
v(k)~N(0, 1)
I want to make sure that everything works fine and makes sense in my code.
A = -0.8;
B = 1;
C = 1;
% Covariance matrices
% Processing noise
W = 0.01;
Q=W;
% Measurement noise
V = 1;
R=V;
% Initial conditions
x0 = 0;
P0 = 0;
xpri = x0;
Ppri = P0;
xpost = x0;
Ppost = P0;
% State
Y = zeros(1, size(t,2));
X = Y;
X(1) = x0;
% xpri - x priori
% xpost - x posteriori
% Ppri - P priori
% Ppost - P posteriori
for i = 1:size(t,2)
%Simulation
Y(i) = C*sin((i-1)*0.1)+normrnd(0,sqrt(V));
if i > 1
% Prediction
xpri = A*xpost+B*sin((i-1)*0.1);
Ppri = A*Ppost*A' + Q;
eps = Y(i) - C*xpri;
S = C*Ppri*C' + R;
K = Ppri*C'*S^(-1);
xpost = xpri + K*eps;
Ppost = Ppri - K*S*K';
X(i) = xpost;
end
end
plot(t, Y, 'b', t, X, 'r')
title('Kalman's Filter')
xlabel('Time')
ylabel('Value')
legend('Measured value', 'Estimated value')
Does this KF work properly? If not, what is wrong?
The code looks OK and the results also. What makes you suspicious?
Here is a generic Kalman-filter implementation as a function that you can check out if you want to double-check. But with the filter, its all about the tuning of the covariance matrices P
, Q
, R
...
function [v_f,xyz] = KF(u,z,A,B,C,D,x0,P0,Q,R)
%% initialization
persistent x P
if isempty(x)||isempty(P)
% state vector
x = reshape(x0,numel(x0),1); % ensure vector size
if nargin < 8 || isempty(P0)
P0 = eye(length(x)); %default initialization
emd
P = P0; % covariance matrix
end
%% covariance matrices
if nargin < 9 || isempty(Q)
Q = diag( ones(length(x) )*1e1; % proess-noise-covariance
end
% % Q = 0 -> perfect model. Q =/= 0 -> pay more attention to the measurements.
%
if nargin < 10
R = diag( ones(length(z)) ) *1e1; % measurement-noise-covariance
end
% The higher R, the less trusting the measurements
%% prediction
x_P = A*x + B*u;
P = A*P*A.' + Q; % covariance matrix
%% update
H = C;
K = P*H.'*(H*P*H.' +R)^-1;
x = x_P + K*(z - H*x_P);
P = (eye(length(x)) - K*H)*P;
%% Output
y = C*x;
end
In any case, I would suggest to transfer this question to the codereview-pages because you have apparently no problem and just want to review your code, right?