Lab 3 - Implementing the UKF
Implementing the UKF
We will store the sigma points and weights in matrices, like so:
Weights
Remember that the weigths are calculated as follow:
Implement the function MerweWeightSigmaPoints(n, alpha, beta, kappa)
and return \(\lambda\) and the vectors of weights \(W_m, W_c\).
Example
MerweWeightSigmaPoints(n=2, alpha=.1, beta=2., kappa=1.)
gives:
-1.97
array([-62.67666667, 16.66666667, 16.66666667, 16.66666667, 16.66666667])
array([-65.66666667, 16.66666667, 16.66666667, 16.66666667, 16.66666667])
Sigma Points
Remember the equations for the sigma points are:
The hardest part is \(\left( \sqrt{(n+\lambda)\Sigma}\right )_i\). This term is a matrix because \(\Sigma\) is a matrix.
The subscript \(i\) is choosing the i-th row vector of the matrix.
What is the square root of a matrix \(\Sigma\)?
We can define it as \(\Sigma = SS^T\)
Where \(S\) can be computed with the Cholesky decomposition.
Warning
It’s a common approximation, but you can find different definition.
Create the function SigmaPoints(mu, n, lambda_, Sigma)
that returns the sigma points.
Start by creating a matrix of size \((2n+1, n)\).
Calculate the matrix containing \(\left( \sqrt{(n+\lambda)\Sigma}\right )\) for each i using cholesky.
Example
SigmaPoints(np.array([10, 10]), 2, -1.97, np.array([[2., .1], [.1, 3]]))
gives:
array([[10. , 10. ],
[10.24494897, 10.01224745],
[10. , 10.2997499 ],
[ 9.75505103, 9.98775255],
[10. , 9.7002501 ]])
Unscented Transform
Recall the equations:
Create the function unscented_transform(sigmas, wm, wc, R)
:
\(\mu\) is just the dot product of \(w_m\) and \(\mathcal X\).
\(\Sigma\) is a square matrix of size \(n\).
\(\mathcal X^i-\mu\) is the substraction of two vectors of 1 dimension
Because they have only one dimension yoiu will need to use
numpy.outer
to multiply it by itself.Remember to add the process noise \(R\) to \(\Sigma\).
It should return the new mean and covariance.
Example
Using unscented_transform(sigmas, wm, wc, R=np.array([[1.5,.5],[.5,1.5]]))
, we obtain:
array([10., 10.])
array([[3.5, 0.6], [0.6, 4.5]])
The other values are the ones calculated with the previous examples.
UKF
Now we have everything to implement the filter itself.
Predict step
For the predict step, you need to pass each sigma point through the function \(f\):
Implement the function predict(sigma_points_fn, fx, mu, Sigma, wm, wc, R)
:
sigma_points_fn
is the function to calculate the sigma points defined earlier.fx
is the nonlinear function \(f\).Calculate the sigma points.
Pass each sigma points trough the function \(f\).
Apply the unscented transform on the new points.
Return the new mean and covariance and the sigma points
If we try with the previous values we obtain:
array([ 20. , 113.2])
array([[ 6.7 , 66.7 ],
[ 66.7 , 1238.1479615]])
Update step
Now, you need to implement the update step. Remember that the update step is converting the sigmas into measurement psace using the function \(h(x)\):
Then, we compute the new state estimate using the reisdual and Kalman gain:
and the new covariance is computed as :
Implement the update function update(hx, mu, Sigma, z, sigmas_f, wm, wc, Q)
:
hx
is the measurement functionmu, Sigma
are the mean and covariance after the prediction step.z
the measurement receivedsigmas_f
the sigma pointsQ
the measurement noise
You can use the following measurement function to test the code:
+ show/hide codeIf we try with the previous values we obtain and the following parameters we obtain:
update(hx, mu, Sigma, np.array([11, 11]), sigmas_f, wm, wc, np.diag([0.2, 0.5]))
array([11.38019055, 10.99044453])
array([[1.67846715, 0.50288057],
[0.50288057, 1.99941257]])
Using the UKF
Let’s solve some problems so you can gain confidence in how easy the UKF is to use. We will start with a linear problem you already know how to solve with the linear Kalman filter.
Although the UKF was designed for nonlinear problems, it finds the same optimal result as the linear Kalman filter for linear problems.
We will use the filter to track an object in 2D using a constant velocity model.
We define the state of the robot as:
The engineers are telling us that the robot moves following the Newtonian equations:
Use the previous equations to define the state transition matrix \(A\)
The sensors provide position but not velocity.
Define the measurement function as a matrix \(H\).
The sensor readings are in meters with an error of \(\sigma=0.3\) meters in both x and y. This gives us a measurement noise matrix of
Finally, let’s assume that the process noise can be represented by the discrete white noise model - that is, that over each time period the acceleration is constant.
Write the transifiton function
f_cv
.Write the measurement function
H_cv
.Use this function with the UKF and see what happens.