Go to the documentation of this file.00001
00002 #include "kalman_filter.h"
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include <vcl_cstdlib.h>
00027 #include <vcl_iostream.h>
00028
00029 #include <vnl/algo/vnl_svd.h>
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056 KalmanFilter::KalmanFilter(
00057 unsigned int ns, unsigned int nm, unsigned int nc,
00058 const vnl_matrix<double> &Ai,
00059 const vnl_matrix<double> &Hi,
00060 const vnl_matrix<double> &Bi,
00061 const vnl_matrix<double> &z_initial,
00062 const vnl_matrix<double> &x_initial,
00063 const vnl_matrix<double> &Pi
00064 ):
00065
00066 num_signal_dimensions(ns), num_measurement_dimensions(nm),
00067 num_control_dimensions(nc), A(Ai), H(Hi), B(Bi),
00068 x(x_initial), x_pred(x_initial), z(z_initial),
00069 P(Pi), K(ns, nm)
00070 {
00071
00072 if ((A.rows()!=num_signal_dimensions)||
00073 (A.cols()!=num_signal_dimensions))
00074 {
00075 vcl_cerr << "Error in Kalman constructor:\n"
00076 << "\tMatrix A must be of size ns*ns\n";
00077 vcl_exit(-1);
00078 }
00079
00080 if ((H.rows()!=num_measurement_dimensions)||
00081 (H.cols()!=num_signal_dimensions))
00082 {
00083 vcl_cerr << "Error in Kalman constructor:\n"
00084 << "\tMatrix H must be of size nm*ns\n";
00085 vcl_exit(-1);
00086 }
00087
00088 if ((B.cols()!=num_control_dimensions)||
00089 (B.rows()!=num_signal_dimensions))
00090 {
00091 vcl_cerr << "Error in Kalman constructor:\n"
00092 << "\tMatrix B must be of size ns*nc\n";
00093 vcl_exit(-1);
00094 }
00095
00096 if ((x_pred.rows()!=num_signal_dimensions)||
00097 (x_pred.cols()!=1))
00098 {
00099 vcl_cerr << "Error in Kalman constructor:\n"
00100 << "\tMatrix x must be of size ns*1\n";
00101 vcl_exit(-1);
00102 }
00103
00104 if ((Pi.rows()!=num_signal_dimensions)||
00105 (Pi.cols()!=num_signal_dimensions))
00106 {
00107 vcl_cerr << "Error in Kalman constructor:\n"
00108 << "\tMatrix p_initial must be of size ns*1\n";
00109 vcl_exit(-1);
00110 }
00111 }
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134 KalmanFilter::KalmanFilter(
00135 unsigned int ns, unsigned int nm,
00136 const vnl_matrix<double> &Ai,
00137 const vnl_matrix<double> &Hi,
00138 const vnl_matrix<double> &z_initial,
00139 const vnl_matrix<double> &x_initial,
00140 const vnl_matrix<double> &Pi
00141 ):
00142
00143 num_signal_dimensions(ns), num_measurement_dimensions(nm),
00144 num_control_dimensions(0), A(Ai), H(Hi),
00145 x(x_initial), x_pred(x_initial), z(z_initial),
00146 P(Pi), K(ns, nm)
00147 {
00148
00149 if ((A.rows()!=num_signal_dimensions)||
00150 (A.cols()!=num_signal_dimensions))
00151 {
00152 vcl_cerr << "Error in Kalman constructor:\n"
00153 << "\tMatrix A must be of size ns*ns\n";
00154 vcl_exit(-1);
00155 }
00156
00157 if ((H.rows()!=num_measurement_dimensions)||
00158 (H.cols()!=num_signal_dimensions))
00159 {
00160 vcl_cerr << "Error in Kalman constructor:\n"
00161 << "\tMatrix H must be of size nm*ns\n";
00162 vcl_exit(-1);
00163 }
00164
00165 if ((x_pred.rows()!=num_signal_dimensions)||
00166 (x_pred.cols()!=1))
00167 {
00168 vcl_cerr << "Error in Kalman constructor:\n"
00169 << "\tMatrix x must be of size ns*1\n";
00170 vcl_exit(-1);
00171 }
00172
00173 if ((Pi.rows()!=num_signal_dimensions)||
00174 (Pi.cols()!=num_signal_dimensions))
00175 {
00176 vcl_cerr << "Error in Kalman constructor:\n"
00177 << "\tMatrix p_initial must be of size ns*1\n";
00178 vcl_exit(-1);
00179 }
00180 }
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196 void KalmanFilter::measurement_update(const vnl_matrix<double> &zk,
00197 const vnl_matrix<double> &Rk)
00198 {
00199
00200 if ((zk.rows()!=num_measurement_dimensions)||
00201 (zk.cols()!=1))
00202 {
00203 vcl_cerr << "Error in Kalman measurement_update\n"
00204 << "\tzk must have dimensions nm*1\n";
00205 vcl_exit(-1);
00206 }
00207
00208 if ((Rk.rows()!=num_measurement_dimensions)||
00209 (Rk.cols()!=num_measurement_dimensions))
00210 {
00211 vcl_cerr << "Error in Kalman measurement_update\n"
00212 << "\tRk must have dimensions nm*nm\n";
00213 vcl_exit(-1);
00214 }
00215
00216 this->z = zk;
00217
00218
00219 vnl_matrix<double> Tmp(Rk);
00220
00221 Tmp += H*P*H.transpose();
00222
00223 vnl_svd<double> Tmp2(Tmp);
00224
00225 K = P*H.transpose()*Tmp2.inverse();
00226
00227
00228
00229
00230 x = x_pred + K*(zk-H*x_pred);
00231
00232
00233 vnl_matrix<double> ident(P);
00234 ident.set_identity();
00235
00236 P = (ident - K*H)*P;
00237 }
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252 vnl_matrix<double>
00253 KalmanFilter::predict(const vnl_matrix<double> &Qk)
00254 {
00255
00256 if ((Qk.rows()!=num_signal_dimensions)||
00257 (Qk.cols()!=num_signal_dimensions))
00258 {
00259 vcl_cerr << "Error in Kalman predict\n"
00260 << "\tQk must have dimensions ns*ns\n";
00261 vcl_exit(-1);
00262 }
00263
00264
00265 x_pred = A*x;
00266
00267
00268 P = A*P*A.transpose() + Qk;
00269
00270 return x_pred;
00271 }
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286 vnl_matrix<double>
00287 KalmanFilter::predict(const vnl_matrix<double> &Qk,
00288 const vnl_matrix<double> &uk)
00289 {
00290
00291 if ((Qk.rows()!=num_signal_dimensions)||
00292 (Qk.cols()!=num_signal_dimensions))
00293 {
00294 vcl_cerr << "Error in Kalman predict\n"
00295 << "\tQk must have dimensions ns*ns\n";
00296 vcl_exit(-1);
00297 }
00298
00299 if ((uk.rows()!=num_control_dimensions)||
00300 (uk.cols()!=1))
00301 {
00302 vcl_cerr << "Error in Kalman predict\n"
00303 << "\tuk must have dimensions nc*1\n";
00304 vcl_exit(-1);
00305 }
00306
00307
00308 x_pred = A*x + B*uk;
00309
00310
00311 P = A*P*A.transpose() + Qk;
00312
00313 return x_pred;
00314 }
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330 vnl_matrix<double> KalmanFilter::update_predict
00331 (
00332 const vnl_matrix<double> &zk,
00333 const vnl_matrix<double> &Rk,
00334 const vnl_matrix<double> &Qk
00335 )
00336 {
00337 measurement_update(zk, Rk);
00338 return predict(Qk);
00339 }
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350 vcl_ostream &operator<<(vcl_ostream &os, const KalmanFilter &kf)
00351 {
00352 os << "Current state of Kalman Filter is:\n"
00353 << "estimate = " << kf.x.transpose()
00354 << "prediction = " << kf.x_pred.transpose()
00355 << "measurement = " << kf.z.transpose()
00356 << "error covariance =\n" << kf.P
00357 << "Kalman gain =\n" << kf.K
00358 << "A =\n" << kf.A
00359 << "H =\n" << kf.H;
00360 if (kf.num_control_dimensions>0)
00361 os << "B =\n" << kf.B;
00362 return os;
00363 }