6.4. Filters¶
Filters, in astrodynamics, are generally used to estimate the state of a system, based on a model description and measurement data. Tudat provides a few filters, based on the Kalman filter concept, that you can use for these or any other purpose you see fit. The filtering techinques currently offered in Tudat are:
Linear Kalman Filter (LKF): an extremely effective and versatile procedure for combining noisy sensor outputs to estimate the state of a linear system with uncertain dynamics
Extended Kalman Filter (EKF): extends the LKF to non-linear applications, by using a first-order Taylor series approximation of the system around the current estimate
Unscented Kalman Filter (UKF): similar to the EKF, but addresses the non-linearity by using a deterministic sampling approach (instead of using system and measurement Jacobians)
You can find more information on the mathematical background of these filters in virtually any guidance, navigation and control book. However, the references used to define the filters in Tudat are:
LKF: E. Mooij, AE4870B - Re-entry Systems, Lecture Notes, Delft University of Technology, 2016.
EKF: Ogata, K., Discrete-Time Control Systems, 2nd ed. Pearson Education Asia, 2002.
UKF: Wan, E. and Van Der Merwe, R., “The Unscented Kalman Filter for Nonlinear Estimation,” in Adaptive Systems for Signal Processing, Communications, and Control Symposium. Institute of Electrical and Electronics Engineers, 2000, pp. 153–158.
On this page, you will find a description of how to create a Kalman filter object, either based on the linear, extended, or unscented principle. In general, you will notice that the creation of a filter, requires the input of two template arguments. These are called IndependentVariableType
and DependentVariableType
, and they respectively denote the type (i.e., double
, long double
, etc.) for the independent variable (usually time) and the dependent variables. Note that the dependent variable is internally defined as an Eigen::Matrix< DependentVariableType, Eigen::Dynamic, 1 >
object (which corresponds to a vector of unspecified length).
6.4.1. Linear Kalman Filter¶
- class LinearKalmanFilter¶
std::shared_ptr< LinearKalmanFilter< IndependentVariableType, DependentVariableType > > linearFilter = std::make_shared< LinearKalmanFilter< IndependentVariableType, DependentVariableType > >( stateTransitionMatrix, controlMatrix, measurementMatrix, systemUncertainty, measurementUncertainty, filteringTimeStep, initialTime, initialEstimatedStateVector, initialEstimatedStateCovarianceMatrix );
In the code above, the inputs are given by:
stateTransitionMatrixFunction
: a function returning the state transition matrix, as a function of time, state and control inputcontrolMatrixFunction
: a function returning the control matrix as a function of time, state and control inputmeasurementMatrixFunction
: a function returning the measurement matrix as a function of time, state and control inputsystemUncertainty
: a matrix defining the uncertainty in modeling of the systemmeasurementUncertainty
: a matrix defining the uncertainty in modeling of the measurementsfilteringTimeStep
: a scalar representing the value of the constant filtering time stepinitialTime
: a scalar representing the value of the initial timeinitialStateVector
: a vector representing the initial (estimated) state of the system; it is used as first a-priori estimate of the state vectorinitialCovarianceMatrix
: a matrix representing the initial (estimated) covariance of the system; it is used as first a-priori estimate of the covariance matrixintegrator
: a pointer to integrator to be used to propagate state
Note
Currently, the creation of the LKF is only supported in the method above. A class such as
LinearKalmanFilterSettings
has not yet been implemented.
6.4.2. Extended Kalman Filter¶
- class ExtendedKalmanFilter¶
std::shared_ptr< FilterBase< IndependentVariableType, DependentVariableType > > filterObject; filterObject = createFilter( filterSettings, systemFunction, measurementFunction, stateJacobianFunction, stateNoiseJacobianFunction, measurementJacobianFunction, measurementNoiseJacobianFunction );
Here, the inputs are as follows:
filterSettings
: a pointer to aExtendedKalmanFilterSettings
object, described at the end of this sectionsystemFunction
: a function returning the state as a function of time and state vector; this can be a differential equation if theintegratorSettings
is set (i.e., if it is not anullptr
)measurementFunction
: a function returning the measurement as a function of time and statestateJacobianFunction
: a function returning the Jacobian of the system w.r.t. the state; its input values can be time and state vectorstateNoiseJacobianFunction
: a function returning the Jacobian of the system function w.r.t. the system noise; its input values can be time and state vectormeasurementJacobianFunction
: a function returning the Jacobian of the measurement function w.r.t. the state; its input values can be time and state vectormeasurementNoiseJacobianFunction
: a function returning the Jacobian of the measurement function w.r.t. the measurement noise. The input values can be time and state vector
The filter settings above, can be defined for an extended Kalman filter as:
- class ExtendedKalmanFilterSettings¶
std::shared_ptr< FilterSettings< IndependentVariableType, DependentVariableType > > filterSettings = std::make_shared< ExtendedKalmanFilterSettings< IndependentVariableType, DependentVariableType > >( systemUncertainty, measurementUncertainty, filteringTimeStep, initialTime, initialStateVector, initialCovarianceMatrix, integratorSettings );
where each element is defined as:
systemUncertainty
: a matrix defining the uncertainty in modeling of the systemmeasurementUncertainty
: a matrix defining the uncertainty in modeling of the measurementsfilteringTimeStep
: a scalar representing the value of the constant filtering time stepinitialTime
: a scalar representing the value of the initial timeinitialStateVector
: a vector representing the initial (estimated) state of the system; it is used as first a-priori estimate of the state vectorinitialCovarianceMatrix
: a matrix representing the initial (estimated) covariance of the system; it is used as first a-priori estimate of the covariance matrixintegratorSettings
: a pointer to integration settings defining the integrator to be used to propagate the state
6.4.3. Unscented Kalman Filter¶
- class UnscentedKalmanFilter¶
std::shared_ptr< FilterBase< IndependentVariableType, DependentVariableType > > filterObject; filterObject = createFilter( filterSettings, systemFunction, measurementFunction )
Here, the inputs are as follows:
filterSettings
: a pointer to aUnscentedKalmanFilterSettings
object, described at the end of this sectionsystemFunction
: a function returning the state as a function of time and state vector; this can be a differential equation if theintegratorSettings
is set (i.e., if it is not anullptr
)measurementFunction
: a function returning the measurement as a function of time and state
The filter settings above, can be defined for an extended Kalman filter as:
- class UnscentedKalmanFilterSettings¶
std::shared_ptr< FilterSettings< IndependentVariableType, DependentVariableType > > filterSettings = std::make_shared< UnscentedKalmanFilterSettings< IndependentVariableType, DependentVariableType > >( systemUncertainty, measurementUncertainty, filteringTimeStep, initialTime, initialStateVector, initialCovarianceMatrix, integratorSettings, constantValueReference, customConstantParameters );
where each element is defined as:
systemUncertainty
: a matrix defining the uncertainty in modeling of the systemmeasurementUncertainty
: a matrix defining the uncertainty in modeling of the measurementsfilteringTimeStep
: a scalar representing the value of the constant filtering time stepinitialTime
: a scalar representing the value of the initial timeinitialStateVector
: a vector representing the initial (estimated) state of the system; it is used as first a-priori estimate of the state vectorinitialCovarianceMatrix
: a matrix representing the initial (estimated) covariance of the system; it is used as first a-priori estimate of the covariance matrixintegratorSettings
: a pointer to integration settings defining the integrator to be used to propagate the stateconstantValueReference
: reference to be used for the values of the \(\alpha\) and \(\kappa\) parameters; this variable has to be part of theConstantParameterReferences
enumeration (custom parameters are supported)customConstantParameters
: values of the constant parameters \(\alpha\) and \(\kappa\), input as a pair, in case thecustom_parameters
enumeration is used in the previous field
The supported values for
constantValueReference
are based on UKF literature, and correspond to the values of \(\alpha\) and \(\kappa\) shown in the table below (where \(N\) denotes the length of the state vector). Note that the values of these two parameters have the following meaning:\(\alpha\) is used to distribute the sigma points around the a-priori estimate
\(\kappa\) is a secondary scaling parameter, also used to distribute the sigma points around the a-priori estimate, but it has a smaller influence
constantValueReference
\(\alpha\)
\(\kappa\)
reference_Wan_and_Van_der_Merwe
(default)0.003
0.0
reference_Lisano_and_Born_and_Axelrad
1.0
3.0 - \(N\)
reference_Challa_and_Moore_and_Rogers
0.001
0.1
customConstantParameters
–
–
6.4.4. Using a Kalman Filter Object¶
To use the filters after their creation, you will need to update the system with the data corresponding to the new time step. This can be done by using the function updateFilter
, which takes one inputs:
currentMeasurementVector
: a vector denoting the current external measurement which will be used to correct the estimated a-priori state (thus to obtain the a-posteriori estimate)
Note that the filter object comes equipped with two noise generators. These produce random Gaussian noise based on the system and measuremenet uncertainty properties input by you. They can be retrieved with the commands produceSystemNoise
and produceMeasurementNoise
. You will find cases of how to use the noise and the other features mentioned on this page, in:
/Tudat/Mathematics/Filters/UnitTests
where a few examples for each filtering technique are shown. One of the test cases shown for the extended (EKF) and unscented (UKF) filters is also shown in an example application, which you can find in Kalman Filter for State Estimation.
The last element that should be discussed is the control system. It may be the case that you also need a control input together with the time and state. This can be added with the creation of a ControlWrapper
of the type explained in the next section, Adding a Control Input.
These are the only major steps that you will need to take to keep the filter running. At the end of the estimation process, however, you can retrieve, however, retireve the history of the estimated states and covariance matrices by using the functions getEstimatedStateHistory
and getEstimatedCovarianceHistory
, respectively.
6.4.5. Adding a Control Input¶
It may be that for your application, your system needs to be controlled. This can be achieved by creating a control system (ControlSystem
, or ControlWrapper
in the unit tests), that provides the state function (and possibly the state Jacobian) with the current commanded vector.
The way this is done is by adding an extra input to the state function, i.e.,
Eigen::Vector3d stateFunction( const double currentTime, const Eigen::Vector3d& currentState, const Eigen::Vector3d& currentControl )
The last input of the stateFunction
is another vector which denotes the commanded control vector. Note how this function, however is incompatible with the definition of systemFunction
, i.e., the input to the ExtendedKalmanFilter
and UnscentedKalmanFilter
classes. In fact, this should be of type
std::function< DependentVector( const IndependentVariableType, const DependentVector& ) >
which one has two inputs (a double
and an Eigen::Vector3d
, in our case). The extra vector can be added by using the very handy std::bind
command. This function allows us to bind the output of a function as an input to another function. Thus, by using the control class mentioned above, one can replace the systemFunction
input with:
std::bind( &stateFunction, std::placeholders::_1, std::placeholders::_2, std::bind( &ControlSystem::getCurrentStateVector, controlSystem ) )
where the controlSystem
object is of type ControlSystem
. Using this method, if the control system is regularly updated (possibly every time step), the control vector will be automatically retrieved and parsed by the filter.
In Kalman Filter for State Estimation you will find an example where a control system is added to both an EKF and a UKF, which are used to estimate the state of a simple estimation application.
Tip
In general, you can apply the principle above to feed any other variable or object to the state and/or measurement functions.