Fast Kalman Filter#
Implementation of the Fast Kalman Filter algorithm for orientation estimation described in “Novel MARG-Sensor Orientation Algorithm Using Fast Kalman Filter” [GWWQ17].
The Fast Kalman Filter (FKF) is a quaternion-based orientation estimation algorithm that focuses on the fusion of accelerometer and magnetometer measurements.
In the FKF, the quaternion kinematic equation is the process model, similar to the EKF. Likewise, the measurement model is based on the accelerometer and magnetometer readings.
The FKF algorithm is computationally efficient, because it symbolically solves the linear system of equations of the observation model.
The steps of the KF are summarized as:
State Prediction
Covariance Prediction
Kalman Gain
State Update
Covariance Update
We update the state, \(\mathbf{q}_t\), at every time \(t\), with the predicted state \(\mathbf{q}_t^-\), the measurements \(\mathbf{y}_t\), the state transition matrix \(\Phi_t\), the covariance matrix \(\mathbf{P}_t\), the process noise covariance matrix \(\boldsymbol\varepsilon_t\), and the Kalman Gain \(\mathbf{G}_t\).
Prediction Model#
The first two steps correspond to the prediction model, and are computed like in the common Extended Kalman Filter.
The state vector is defined by the quaternion itself, without considering biases over the sensors.
The state prediction (we can call it the “predicted quaternion”) is estimated as:
where \(\xi_t\) is the process noise, and the state transition matrix \(\Phi_t\) is:
with the omega operator is defined as:
We use the measured angular rates \(\mathbf{\omega}_t\) from the gyroscope to approximate the instantaneous change in the quaternion. Then, we multiply by \(\frac{\Delta t}{2}\) to numerically integrate it, and get the predicted quaternion \(\mathbf{q}_t^-\).
At step 2, the Covariance Prediction is computed with:
where \(\mathbf{\Sigma}_{\xi_t}\) is the process noise covariance
\(\mathbf{\Sigma}_{\mathrm{gyro}}\) is the angular rates’ covariance, usually defined as:
The terms \(\sigma_{\omega_x}\), \(\sigma_{\omega_y}\), and \(\sigma_{\omega_z}\) are the standard deviations at each axis of the gyroscope.
In this implementation, we assume they are equal, and we define \(\mathbf{\Sigma}_{\mathrm{gyro}}\) as:
\(\mathbf{\Xi}_t\) is the matrix built from the quaternion’s elements:
Correction Model#
The last three steps are the correction model, where we update the predicted state \(\mathbf{q}_t^-\) with the measurements \(\mathbf{q}_{am}\).
The Kalman Gain is computed in step three as:
where \(\mathbf{\Sigma}_{v_t}\) is the measurement quaternion’s variance approximated with:
Defining \(\mathbf{\Sigma}_a\) and \(\mathbf{\Sigma}_m\) as the covariances of accelerometer and magnetomer, respectively, we define the covariance matrix \(\mathbf{\Sigma}_{\mathrm{am}}\) as:
\(\mathbf{J}\) is the Jacobian matrix of the measurement model.
and the measurement quaternion \(\mathbf{q}_{am}\) is computed from the accelerometer and magnetometer readings in the body frame.
with:
and:
What makes the FKF computationally efficient is that the Jacobian matrix \(\mathbf{J}\), and the measurement quaternion \(\mathbf{q}_{am}\) are reduced symbolically, instead of numerically calculating them.
So, instead of performing several matrix multiplications and vector operations, the FKF algorithm solves the linear system of equations symbolically, and updates the state vector directly.
Then, we correct our predicted state \(\mathbf{q}_t^-\) with the measurements \(\mathbf{q}_{am}\) using the Kalman Gain \(\mathbf{G}_t\):
Finally, we update the covariance matrix:
- class ahrs.filters.fkf.FKF(gyr: ndarray | None = None, acc: ndarray | None = None, mag: ndarray | None = None, **kwargs)#
Class of Fast Kalman Filter algorithm
- Parameters:
gyr (numpy.ndarray, default: None) – N-by-3 array with measurements of angular velocity in rad/s
acc (numpy.ndarray, default: None) – N-by-3 array with measurements of acceleration in in m/s^2
mag (numpy.ndarray, default: None) – N-by-3 array with measurements of magnetic field in nT
frequency (float, default: 100.0) – Sampling frequency in Hz.
Dt (float, default: 0.01) – Sampling period in seconds. If
frequencyis given,Dtis computed as 1/frequency.sigma_g (float, default: 0.01) – Standard deviation of the gyroscope noise.
sigma_a (float, default: 0.01) – Standard deviation of the accelerometer noise.
sigma_m (float, default: 0.01) – Standard deviation of the magnetometer noise.
Pk (float, default: 0.01) – Initial value of the diagonal values of covariance matrix.
- Omega4(x: ndarray) ndarray#
Omega operator.
Given a vector \(\mathbf{x}\in\mathbb{R}^3\), return a \(4\times 4\) matrix of the form:
\[\begin{split}\boldsymbol\Omega(\mathbf{x}) = \begin{bmatrix} 0 & -\mathbf{x}^T \\ \mathbf{x} & \lfloor\mathbf{x}\rfloor_\times \end{bmatrix} = \begin{bmatrix} 0 & -x_1 & -x_2 & -x_3 \\ x_1 & 0 & x_3 & -x_2 \\ x_2 & -x_3 & 0 & x_1 \\ x_3 & x_2 & -x_1 & 0 \end{bmatrix}\end{split}\]- Parameters:
x (numpy.ndarray) – Three-dimensional vector.
- Returns:
Omega – Omega matrix.
- Return type:
numpy.ndarray
- kalman_update(q_1: ndarray, q_am: ndarray, Pk_1: ndarray, Phi: ndarray, Sigma_eps: ndarray, Sigma_v: ndarray) Tuple[ndarray, ndarray]#
Kalman update step.
- Parameters:
q_1 (numpy.ndarray) – Previous state vector.
q_am (numpy.ndarray) – Measurement vector.
Pk_1 (numpy.ndarray) – Previous covariance matrix.
Phi (numpy.ndarray) – State transition matrix.
Sigma_eps (numpy.ndarray) – Process noise covariance matrix.
Sigma_v (numpy.ndarray) – Measurement noise covariance matrix.
- Returns:
xk (numpy.ndarray) – Updated state vector.
Pk (numpy.ndarray) – Updated covariance matrix.
- measurement_quaternion_acc_mag(q: ndarray, acc: ndarray, mag: ndarray) Tuple[ndarray, ndarray]#
Measurement model of Accelerometer and Magnetometer.
- Parameters:
q (numpy.ndarray) – Predicted quaternion.
acc (numpy.ndarray) – Sample of tri-axial Accelerometer.
mag (numpy.ndarray) – Sample of tri-axial Magnetometer.
- Returns:
q – Measurement quaternion.
- Return type:
numpy.ndarray