classdef EKFSystemModel < BaseDiscreteSystemModel
%EKFSYSTEMMODEL Class modeling a discrete time system with EKF predictions
% sysModel = EKFSystemModel(f, Q, J_x) creates a class
% representing the discrete time system x(t) which evolves via
% x(t+1) = f(x(t), t) + v
% where v is gaussian noise with mean 0 and covariance Q
%
% sysModel = EKFSystemModel(f, Q, J_x, J_v), models the nonlinear system:
% x(t+1) = f(x(t), t, v)
%
% sysModel = EKFSystemModel(f, Q, J_x, 'Name1', Value1, 'Name2', Value2, ...)
% sysModel = EKFSystemModel(f, Q, J_x, J_v, 'Name1', Value1, 'Name2', Value2, ...)
%
% Optional Inputs:
% 'Name1', Value1, 'Name2', Value2, ... is a variable length
% list of parameter/value pairs.
%
% properties
% f - function
% Q - noise covariance matrix
% J_x - jacobian of f with respect to x
% J_v - jacobian of f with respect to v
% isLinearNoise - true if the system model has additive noise
%
properties
% inherits f, Q, isLinearNoise from BaseDiscreteSystemModel
%J_x; % Jacobian of f with respect to x
%J_v; % Jacobian of f with respect to v
end
methods
function sysModel = EKFSystemModel(f, Q, J_x, varargin)
if nargin == 0
superargs = {};
elseif nargin == 1
superargs = {f};
elseif nargin == 2
error('Must specify Jacobian');
elseif nargin == 3
superargs = {f, Q, 'J_x', J_x};
else
% the fourth argument can be either J_v or start of
% property/value pairs.
if isa(varargin{1}, 'function_handle')
superargs = [{f, Q, 'J_x', J_x, 'J_v', varargin{1}}, ...
varargin{2:end}];
else
superargs = [{f, Q, 'J_x', J_x}, varargin{:}]
end
end
sysModel = sysModel@BaseDiscreteSystemModel(superargs{:});
end
function [x, P] = predict(this, x, P, dt, curTime)
[x, P] = ekfTransform(this.f, this.J_x, x, P, this.Q, ...
curTime, this.isLinearNoise, this.J_v);
end
end
end