SigPack - the C++ signal processing library
 
Loading...
Searching...
No Matches
kalman_UKF.cpp
Go to the documentation of this file.
1
15#include "sigpack.h"
16
17using namespace std;
18using namespace sp;
19
20int main()
21{
22 // Number of samples
23 arma::uword Nsamp = 120;
24 arma::uword N = 6; // Nr of states [X,Y,Vx,Vy,Ax,Ay]
25 arma::uword M = 2; // Nr of measurements
26 arma::uword L = 0; // Nr of inputs
27
28 // // Instatiate a Extended Kalman Filter
29 // EKF kalman(N,M,L);
30 // Instatiate an Unscented Kalman Filter
31 UKF kalman( N, M, L );
32
33 // Initialisation and setup of system
34 double P0 = 50;
35 double Q0 = 0.001;
36 double R0 = 8;
37
38 // Meas interval
39 double dT = 0.1;
40
41 // [X,Y,Vx,Vy,Ax,Ay] 2D position, velocity and acceleration as states
42 arma::mat x = { 0, 5, 10, 50, -0.5, -9.8 };
43 arma::inplace_trans( x );
44 arma::mat x_init( x * 0.5 ); // Init state as 50% of actual value
45 kalman.set_state_vec( x_init );
46
47 // Set transition function
48 arma::mat A = { { 1, 0, dT, 0, dT * dT / 2, 0 }, { 0, 1, 0, dT, 0, dT * dT / 2 }, { 0, 0, 1, 0, dT, 0 }, { 0, 0, 0, 1, 0, dT }, { 0, 0, 0, 0, 1, 0 }, { 0, 0, 0, 0, 0, 1 } };
49 kalman.set_trans_mat( A );
50 // fcn_t f0 = FCN_XUW{ return x(0)+x(2)*dT+x(4)*dT*dT/2; };
51 // fcn_t f1 = FCN_XUW{ return x(1)+x(3)*dT+x(5)*dT*dT/2; };
52 // fcn_t f2 = FCN_XUW{ return x(2)+x(4)*dT; };
53 // fcn_t f3 = FCN_XUW{ return x(3)+x(5)*dT; };
54 // fcn_t f4 = FCN_XUW{ return x(4); };
55 // fcn_t f5 = FCN_XUW{ return x(5); };
56 // fcn_v f = {f0,f1,f2,f3,f4,f5};
57 // kalman.set_trans_fcn(f);
58
59 // Set process noise
60 arma::mat Q = Q0 * arma::diagmat( arma::vec( "1 1 0.1 0.1 0.01 0.01" ) );
61 kalman.set_proc_noise( Q );
62
63 // Nonlinear measurement function
64 fcn_t h0 = FCN_XUW
65 {
66 return sqrt( x( 0 ) * x( 0 ) + x( 1 ) * x( 1 ) );
67 };
68 fcn_t h1 = FCN_XUW
69 {
70 return atan2( x( 1 ), x( 0 ) );
71 };
72 fcn_v h = { h0, h1 };
73 kalman.set_meas_fcn( h );
74
75 // Nonlinear measurement jacobian - analytical
76 // fcn_t h_zero = FCN_XUW{ return 0; };
77 // fcn_t h00_j = FCN_XUW{ return x(0)/sqrt(x(0)*x(0)+x(1)*x(1)); };
78 // fcn_t h01_j = FCN_XUW{ return x(1)/sqrt(x(0)*x(0)+x(1)*x(1)); };
79 // fcn_t h10_j = FCN_XUW{ return -x(1)/(x(0)*x(0)+x(1)*x(1)); };
80 // fcn_t h11_j = FCN_XUW{ return x(0)/(x(0)*x(0)+x(1)*x(1)); };
81 // fcn_m h_jac =
82 // {
83 // {h00_j,h01_j,h_zero,h_zero,h_zero,h_zero},
84 // {h10_j,h11_j,h_zero,h_zero,h_zero,h_zero}
85 // };
86 // kalman.set_meas_jac(h_jac);
87
88 // Error cov
89 arma::mat P = P0 * arma::eye<arma::mat>( N, N );
90 kalman.set_err_cov( P );
91
92 // Meas noise (for distance and angle)
93 arma::mat R = { { 1, 0 }, { 0, 0.005 } };
94 R *= R0;
95 kalman.set_meas_noise( R );
96
97 // Create simulation data
98 arma::mat z( M, Nsamp, arma::fill::zeros );
99 arma::mat z0( M, Nsamp, arma::fill::zeros );
100 for( arma::uword n = 0; n < Nsamp; n++ )
101 {
102 arma::mat v0( N, 1, arma::fill::zeros );
103
104 // Update state
105 x = A * x + Q * arma::randn( N, 1 );
106
107 // Update measurement
108 z0( 0, n ) = x( 0 );
109 z0( 1, n ) = x( 1 );
110
111 // Add meas noise
112 z.col( n ) = eval_fcn( h, z0.col( n ) ) + 0.5 * R * arma::randn( M, 1 );
113 }
114
115 arma::mat xhat_log( N, Nsamp );
116 arma::mat e_log( M, Nsamp );
117 arma::cube P_log( N, N, Nsamp );
118 arma::mat xs_log( M, Nsamp );
119 arma::cube Ps_log( N, N, Nsamp );
120 arma::cube K_log( N, M, Nsamp );
121
122 // Kalman filter loop
123 for( arma::uword n = 0; n < Nsamp; n++ )
124 {
125 // Update
126 kalman.update( z.col( n ) );
127 xhat_log.col( n ) = kalman.get_state_vec();
128
129 // Predict
130 kalman.predict();
131
132 e_log.col( n ) = kalman.get_err();
133 P_log.slice( n ) = kalman.get_err_cov();
134 K_log.slice( n ) = kalman.get_kalman_gain();
135 }
136
137 // RTS smoother
138 kalman.rts_smooth( xhat_log, P_log, xs_log, Ps_log );
139
140 // Display result
141 gplot gp0;
142 gp0.window( "Plot", 10, 10, 500, 500 );
143 gp0.set_term( "qt" );
144 gp0.plot_add( z0.row( 0 ), z0.row( 1 ), "True Y", "lines dashtype 2 linecolor \"black\"" );
145 gp0.plot_add( arma::mat( z.row( 0 ) % cos( z.row( 1 ) ) ), arma::mat( z.row( 0 ) % sin( z.row( 1 ) ) ), "Meas Y", "points" );
146 gp0.plot_add( xhat_log.row( 0 ), xhat_log.row( 1 ), "Kalman x hat" );
147 gp0.plot_add( xs_log.row( 0 ), xs_log.row( 1 ), "RTS smooth" );
148 gp0.plot_show();
149
150 gplot gp1;
151 gp1.window( "Plot", 800, 10, 500, 500 );
152 gp1.set_term( "qt" );
153 gp1.plot_add( xhat_log.row( 4 ), "Acc x" );
154 gp1.plot_add( xhat_log.row( 5 ), "Acc y" );
155 gp1.plot_show();
156
157 gplot gp2;
158 gp2.window( "Plot", 800, 10, 500, 500 );
159 gp2.set_term( "qt" );
160
161 arma::mat ppp = P_log.tube( 0, 0 );
162 gp2.plot_add( ppp, "P x" );
163 ppp = P_log.tube( 1, 1 );
164 gp2.plot_add( ppp, "P y" );
165 ppp = P_log.tube( 2, 2 );
166 gp2.plot_add( ppp, "P Vx" );
167 ppp = P_log.tube( 3, 3 );
168 gp2.plot_add( ppp, "P Vy" );
169 ppp = P_log.tube( 4, 4 );
170 gp2.plot_add( ppp, "P Ax" );
171 ppp = P_log.tube( 5, 5 );
172 gp2.plot_add( ppp, "P Ay" );
173 gp2.plot_show();
174
175 return 0;
176}
Unscented Kalman filter class.
Definition kalman.h:591
Gnuplot class.
Definition gplot.h:27
void plot_show(void)
Show plots.
Definition gplot.h:401
void set_term(const char *ttype)
Set output terminal.
Definition gplot.h:757
void plot_add(const T1 &x, const T2 &y, const std::string lb, const std::string ls="lines")
Push plot y vs. x with label and linespec.
Definition gplot.h:325
void window(const int fig, const char *name, const int x, const int y, const int width, const int height)
Configure the figure used Windows environment.
Definition gplot.h:190
void rts_smooth(const arma::mat &Xf, const arma::cube &Pf, arma::mat &Xs, arma::cube &Ps)
Rauch-Tung-Striebel smoother. See https://users.aalto.fi/~ssarkka/course_k2012/full_course_booklet_20...
Definition kalman.h:784
arma::mat get_err_cov(void)
Definition kalman.h:261
arma::mat get_state_vec(void)
Definition kalman.h:246
void set_meas_noise(const arma::mat &_R)
Definition kalman.h:224
void set_state_vec(const arma::mat &_x)
Definition kalman.h:194
arma::mat get_err(void)
Definition kalman.h:251
void set_meas_fcn(fcn_v _h)
Definition kalman.h:240
void set_err_cov(const arma::mat &_P)
Definition kalman.h:214
void set_trans_mat(const arma::mat &_A)
Definition kalman.h:199
void update(const arma::mat z)
Correct and update the internal states. UKF.
Definition kalman.h:741
arma::mat get_kalman_gain(void)
Definition kalman.h:256
void set_proc_noise(const arma::mat &_Q)
Definition kalman.h:219
void predict(const arma::mat u)
Predict the internal states using a control input.
Definition kalman.h:709
#define FCN_XUW
Definition kalman.h:11
int main()
Definition base.h:8
std::function< double(arma::mat, arma::mat, arma::mat)> fcn_t
Definition kalman.h:12
std::vector< fcn_t > fcn_v
Definition kalman.h:13
arma_inline arma::mat eval_fcn(const fcn_v f, const arma::mat &x, const arma::mat &u, const arma::mat &w)
Evaluate function f(x,u,w)
Definition kalman.h:24