Code covered by the BSD License  

Highlights from
Kalman filtering framework

image thumbnail
from Kalman filtering framework by David Ogilvie
Object framework for filtering using Kalman filter, EKF, or UKF.

Reentry
% from Julier and Uhlmann's UKF article

function Reentry

b0 = -0.59783;
H0 = 13.406;
Gm0 = 3.9860e5;
R0 = 6374;

iter = 2000;
dt = 0.1;

Q = diag([2.4064e-5, 2.4064e-5, 1e-6]);
A = zeros(5,3); % noise term is given by w = A * randn(3,1);
A(3:5, 1:3) = sqrt(Q);

% true initial state
m0 = [6500.4 ; 349.14 ; -1.8093 ; -6.7967 ; 0.6932];
P0 = diag([1e-6, 1e-6, 1e-6, 1e-6, 1e-6, 0]);
trueState = m0;  % FIXME: plus randomness coming from P0

% prior distribution assumed by filter
mu0 = [6500.4 ; 349.14 ; -1.8093 ; -6.7967 ; 0];
K0 = diag([1e-6, 1e-6, 1e-6, 1e-6, 1]);
%K0 = diag([1 1 1 1 1]);

% FIXME: This is cartesian.  Should try J-U polar coords.
H = [1 0 0 0 0; 0 1 0 0 0];


%%%%%

ekfSysModel = EKFContinuousSystemModel(@f, A, @J_f);
ukfSysModel = UnscentedContinuousSystemModel(@f, A);

% FIXME: UKF fails if there isn't noise in the observer model,
% because we know the exact position of some of the variables, so
% covariance has zero eigenvals, so cholesky factorization is singular.
%obsModel = LinearObserverModel(H, zeros(2));
obsModel = LinearObserverModel(H, [2 0; 0 2]);

%obsModel = UnscentedObserverModel(obsModel);

ekfFilt = BLUEFilter(ekfSysModel, obsModel);
ukfFilt = BLUEFilter(ukfSysModel, obsModel);

ekfPrediction = zeros(5,iter);
ekfPrediction(:,1) = mu0;
ukfPrediction = zeros(5,iter);
ukfPrediction(:,1) = mu0;

stateVec = zeros([5 iter]); % true state
stateVec(:,1) = trueState;

measVec = zeros([2 iter]); % measurements

% first simulate time evolution and measurements, so we can reuse the
% same data for EKF and UKF.
for i = 2:iter
    % simulate time evolution and measurement
    trueState = ukfSysModel.simulate(trueState, dt);
    observation = obsModel.simulate(trueState, dt);

    stateVec(:,i) = trueState;
    measVec(:,i) = observation;
end

%sysModelEKF.nSteps = 1;
%sysModelUKF.nSteps = 1;

% covariances for each step of filter
ekfCov = K0;
ukfCov = K0; 

for k = 2:iter
    % filter the simulated observation
    [ekfPrediction(:,k), ekfCov] = ekfFilt.filter(ekfPrediction(:,k-1), ...
                                                  ekfCov, measVec(:,k), ...
                                                  dt);
    [ukfPrediction(:,k), ukfCov] = ukfFilt.filter(ukfPrediction(:,k-1), ...
                                                  ukfCov, measVec(:,k), ...
                                                  dt);
end

times = dt * 1:iter;

figure
theta = -0.03:0.001:0.05;
arcx = R0 * cos(theta);
arcy = R0 * sin(theta);
plot(arcx, arcy, 'r-');
hold on;
plot(ekfPrediction(1,:), ekfPrediction(2,:), 'b-');
plot(ukfPrediction(1,:), ukfPrediction(2,:), 'r:');
hold off

figure
for k=1:5
    subplot(1,5,k)
    hold on;
    plot(times, ekfPrediction(k,:) - stateVec(k,:), 'b-');
    plot(times, ukfPrediction(k,:) - stateVec(k,:), 'r:');
    hold off;
    
    fprintf('RMS error in variable %d with EKF = %f\n', k, ...
            std(ekfPrediction(k,:) - stateVec(k,:)));
    fprintf('RMS error in variable %d with UKF = %f\n', k, ...
            std(ukfPrediction(k,:) - stateVec(k,:)));
    fprintf('\n');
end



function xdot = f(x,t)
% used in xdot = f(x) + w
    R = sqrt(x(1,:).^2 + x(2,:).^2);
    V = sqrt(x(3,:).^2 + x(4,:).^2);
    b = b0 * exp(x(5,:));
    D = b .* exp((R0 - R) / H0) .* V;
    G = -Gm0 ./ R.^3;
    
    xdot(1,:) = x(3,:);
    xdot(2,:) = x(4,:);
    xdot(3,:) = D .* x(3,:) + G .* x(1,:);
    xdot(4,:) = D .* x(4,:) + G .* x(2,:);
    xdot(5,:) = 0;
end

function J = J_f(x,t)
    R = sqrt(x(1,:).^2 + x(2,:).^2);
    V = sqrt(x(3,:).^2 + x(4,:).^2);
    b = b0 * exp(x(5,:));
    D = b .* exp((R0 - R) / H0) .* V;
    G = -Gm0 ./ R.^3;
    
    dG_dx =  3 * Gm0 * R^(-5) * x([1 2]);
    dD_dx([1 2]) = b * (-1/H0) *(1/R) * exp((R0 - R)/H0) * V * x([1 2]);
    dD_dx([3 4]) = b * exp((R0-R)/H0) * (1/V) * x([3 4]);
    dD_dx(5) = D;
    
    J = zeros(5,5);
    J(1,3) = 1;
    J(2,4) = 1;

    %J(3,:) = dD_dx * x(3) + [dG_dx(1) * x(1)+G, dG_dx(2) * x(1), D, 0, 0]
    
    J(3,1) = dD_dx(1) * x(3) + dG_dx(1) * x(1) + G;
    J(3,2) = dD_dx(2) * x(3) + dG_dx(2) * x(1);
    J(3,3) = dD_dx(3) * x(3) + D;
    J(3,4) = dD_dx(4) * x(3);
    J(3,5) = dD_dx(5) * x(3);
    
    J(4,1) = dD_dx(1) * x(4) + dG_dx(1) * x(2);
    J(4,2) = dD_dx(2) * x(4) + dG_dx(2) * x(2) + G;
    J(4,3) = dD_dx(3) * x(4);
    J(4,4) = dD_dx(4) * x(4) + D;
    J(4,5) = dD_dx(5) * x(4);
end


end

Contact us at files@mathworks.com