00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00030
00032
00033
00034 #ifndef __KALMAN_H_
00035 #define __KALMAN_H_
00036
00037 #include <stdlib.h>
00038 #include <time.h>
00039
00040 #include <Types.h>
00041 #include <fstream>
00042
00043 #include <S1.h>
00044 #include <R2.h>
00045 #include <Surface.h>
00046 #include <MIPMatrix.h>
00047
00048 #define GRAV 9.81 // Gravity acceleration.
00049 #define EPSILON 0.01 // Maximum acceptable error in calculus.
00050
00051
00052 #define A_ROW 3 // Number of rows in the A(k) matrix.
00053 #define A_COL 3 // Number of columns in the A(k) matrix.
00054 #define C_ROW 2 // Number of rows in the C(k) matrix. C_ROW must be equal to G_ROW, see function matrix_K
00055 #define C_COL 3 // Number of columns in the C(k) matrix.
00056 #define Pp_ROW 3 // Number of rows in the Pp(k) matrix.
00057 #define Pp_COL 3 // Number of columns in the Pp(k) matrix.
00058 #define K_ROW 3 // Number of rows in the K(k+1) matrix.
00059 #define K_COL 2 // Number of columns in the K(k+1) matrix.
00060 #define P_ROW 3 // Number of rows in the P(k+1) matrix.
00061 #define P_COL 3 // Number of columns in the P(k+1) matrix.
00062 #define F_ROW 3 // Number of rows in the F(k) matrix.
00063 #define F_COL 3 // Number of columns in the F(k) matrix.
00064 #define G_ROW 2 // Number of rows in the G(k+1) matrix. G_ROW must be equal to C_ROW, see function matrix_K
00065 #define G_COL 2 // Number of columns in the G(k+1) matrix.
00066 #define OUT_PRED_ROWS 2 // Number of rows in the OutPred(k+1) matrix.
00067 #define GPS_MEAS 2 // GPS vector data.
00068 #define ENC_MEAS 3 // Encoder measures used as measured inputs to calculate robot status prediction X(k+1,k).
00069
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088 #include <boost/concept_check.hpp>
00089
00090 class KalmanFilter {
00091 private:
00092 Decimal CycleTime;
00093
00094 MIPMatrix *State_0;
00095 MIPMatrix *State_1;
00096 MIPMatrix *OutPred;
00097 MIPMatrix *GPS_Meas;
00098 MIPMatrix *ENC_Meas;
00099
00100 Decimal RobotMass;
00101 Decimal RobotMoI;
00102
00103 Surface *Surf;
00104 int CurrentRobotPlane;
00105 int SemiSpace;
00106
00107
00108
00109
00110
00111
00112 MIPMatrix *Mat_Pp;
00113 MIPMatrix *Mat_A;
00114 MIPMatrix *Mat_C;
00115 MIPMatrix *Mat_K;
00116 MIPMatrix *Mat_P;
00117 MIPMatrix *Mat_G;
00118 MIPMatrix *Mat_F;
00119
00120 MIPMatrix *tmpmat;
00121
00122 Decimal Force;
00123 Decimal Torque;
00124 bool GPS_MeasAvail;
00125
00126 void initializeMatrixC();
00127
00128 void initializeState_1();
00129
00130 void initializeMatrixF();
00131
00132 void initializeMatrixG();
00133
00134 void initializeMatrixPp();
00135
00136 void setSemiSpace();
00137
00138
00139 void updRobotPlane();
00140
00141
00142
00143 void outPred();
00144
00145
00146
00147
00148 void matrix_K();
00149
00150 void matrix_P();
00151
00152 void estimateRobotStatus();
00153
00154 void calculateStatusPrediction();
00155
00156 void calculate_A();
00157
00158 void calculatePp();
00159
00160
00161
00162
00163 public:
00165 KalmanFilter (string namefile)
00166 {
00167 cout << "KalmanFilter::KalmanFilter() starting" << "\n";
00168
00169 State_0 = new MIPMatrix(A_ROW,1,ZERO_MATRIX);
00170 State_1 = new MIPMatrix(A_ROW,1,ZERO_MATRIX);
00171
00172 OutPred = new MIPMatrix(OUT_PRED_ROWS,1,ZERO_MATRIX);
00173 GPS_Meas = new MIPMatrix(GPS_MEAS,1,ZERO_MATRIX);
00174 ENC_Meas = new MIPMatrix(ENC_MEAS,1,ZERO_MATRIX);
00175
00176 Mat_Pp = new MIPMatrix(Pp_ROW,Pp_COL,IDENTITY_MATRIX);
00177 Mat_A = new MIPMatrix(A_ROW,A_COL,IDENTITY_MATRIX);
00178
00179 Mat_C = new MIPMatrix(C_ROW,C_COL,ZERO_MATRIX);
00180
00181 Mat_K = new MIPMatrix(K_ROW,K_COL,ZERO_MATRIX);
00182
00183 Mat_P = new MIPMatrix(P_ROW,P_COL,ZERO_MATRIX);
00184 Mat_G = new MIPMatrix(G_ROW,G_COL,ZERO_MATRIX);
00185 Mat_F = new MIPMatrix(F_ROW,F_COL,ZERO_MATRIX);
00186
00187 cout << "Kalman Surface construction" << "\n";
00188 Surf = new Surface(namefile);
00189
00190 CycleTime = 0.1;
00191 Force = 0;
00192 Torque = 0;
00193
00194 cout << "Matrix_C" << endl;
00195 initializeMatrixC();
00196 Mat_C->printMIPMatrix();
00197 cout << "\n";
00198
00199
00200 initializeMatrixF();
00201
00202 cout << "\n";
00203
00204
00205 initializeMatrixG();
00206
00207 cout << "\n";
00208
00209 cout << "Initialize status prediction matrix: State_1." << endl;
00210 initializeState_1();
00211 State_1->printMIPMatrix();
00212 cout << "\n";
00213
00214 cout << "Initialize Matrix Pp" << endl;
00215 initializeMatrixPp();
00216 Mat_Pp->printMIPMatrix();
00217 cout << "\n";
00218
00219 CurrentRobotPlane = 0;
00220 SemiSpace = 0;
00221 setSemiSpace();
00222 unsetGPSAvailability();
00223 cout << "KalmanFilter Constructor OK" << endl;
00224 }
00225
00228 ~KalmanFilter ()
00229 {
00230 delete State_0;
00231 delete State_1;
00232
00233 delete OutPred;
00234 delete GPS_Meas;
00235 delete ENC_Meas;
00236 delete Mat_Pp;
00237 delete Mat_A;
00238 delete Mat_C;
00239 delete Mat_K;
00240 delete Mat_P;
00241 delete Mat_G;
00242 delete Mat_F;
00243 delete Surf;
00244 cout << "KalmanFilter destructor OK" << endl;
00245 }
00246
00247 void setAppliedForce (Decimal F)
00248 {
00249 Force = F;
00250 return;
00251 }
00252
00253 void setAppliedTorque (Decimal To)
00254 {
00255 Torque = To;
00256 return;
00257 }
00258
00259 void setCycleTime (Decimal T)
00260 {
00261 CycleTime = T;
00262 return;
00263 }
00264
00265 void setCurrentRobotPlane (int Plane)
00266 {
00267 CurrentRobotPlane = Plane;
00268 return;
00269 }
00270
00272 void setGPSAvailability()
00273 {
00274 GPS_MeasAvail = true;
00275 }
00276
00278 void unsetGPSAvailability()
00279 {
00280 GPS_MeasAvail = false;
00281 }
00282
00283 Decimal getAppliedForce(){return Force;}
00284
00285 Decimal getAppliedTorque(){return Torque;}
00286
00287 Decimal getCycleTime(){return CycleTime;}
00288
00289 int getCurrentRobotPlane(){return CurrentRobotPlane;}
00290
00291 int getGPSAvailability(){return GPS_MeasAvail;}
00292
00293 MIPMatrix* getRobStatus(){return State_0;}
00294
00295
00296 bool TranslateGPSMeasures(Position3D &pos)
00297 {
00298
00299 MIPMatrix *GPS_MeasInert;
00300 MIPMatrix *GPS_Measlocal;
00301 MIPMatrix *InertialToLocal;
00302
00303 MIPMatrix *tmp;
00304
00305 Decimal x_loc;
00306 Decimal y_loc;
00307 Decimal z_loc;
00308
00309 GPS_MeasInert = new MIPMatrix(4,1,ZERO_MATRIX);
00310 GPS_Measlocal = new MIPMatrix(4,1,ZERO_MATRIX);
00311 InertialToLocal = new MIPMatrix(4,4,ZERO_MATRIX);
00312
00313 tmp = new MIPMatrix(4,4,ZERO_MATRIX);
00314
00315 GPS_MeasInert->SetMIPMatrixVal(1,1,pos.x());
00316 GPS_MeasInert->SetMIPMatrixVal(2,1,pos.y());
00317 GPS_MeasInert->SetMIPMatrixVal(3,1,pos.z());
00318 GPS_MeasInert->SetMIPMatrixVal(4,1,1);
00319
00320 cout << "Kalman Filter:setGPSMeasures(): GPS data in the inertial reference frame:" << endl;
00321 GPS_MeasInert->printMIPMatrix();
00322 cout << "\n";
00323
00324
00325
00326 tmp->operator=(*(Surf->GetRotTranslMatrix(CurrentRobotPlane)));
00327
00328
00329 if(InertialToLocal->inv44(*tmp) == 0)
00330 {
00331 cout << "Kalman Filter::setGPSMeasures(): Invalid GPS measures." << "\n";
00332 return false;
00333 }
00334
00335 cout << "Kalman Filter:setGPSMeasures(): Rototranslation Matrix from inertial to local reference frame:" << endl;
00336 InertialToLocal->printMIPMatrix();
00337 cout << "\n";
00338
00339 GPS_Measlocal->mul(*InertialToLocal,*GPS_MeasInert);
00340
00341 x_loc = GPS_Measlocal->GetMIPMatrixVal(1,1);
00342 y_loc = GPS_Measlocal->GetMIPMatrixVal(2,1);
00343 z_loc = GPS_Measlocal->GetMIPMatrixVal(3,1);
00344
00345 delete GPS_MeasInert;
00346 delete GPS_Measlocal;
00347 delete InertialToLocal;
00348
00349 if((z_loc < -EPSILON) || (z_loc > EPSILON))
00350 {
00351 cout << "Wrong data received from GPS. Error too big for z_loc = " << z_loc << " it should be zero!!" << endl;
00352
00353 }
00354
00355
00356 GPS_Meas->SetMIPMatrixVal(1,1,x_loc);
00357 GPS_Meas->SetMIPMatrixVal(2,1,y_loc);
00358 cout << "Kalman Filter:setGPSMeasures(): GPS data in the local reference frame:" << endl;
00359 GPS_Meas->printMIPMatrix();
00360 cout << "\n";
00361 cout << "Kalman Filter:setGPSMeasures(): GPS z_loc= " << z_loc << endl;
00362
00363 return true;
00364 }
00365
00366
00367 void processENCMeasures(Decimal d_x, Decimal d_y, Angle d_theta)
00368
00369 {
00370
00371
00372 Angle newtheta;
00373 Angle oldtheta;
00374 Decimal dx_loc;
00375 Decimal dy_loc;
00376 Decimal Noise;
00377 Angle *Noise_1;
00378
00379 MIPMatrix *ds_Iner;
00380 MIPMatrix *ds_Loc;
00381 MIPMatrix *RotLoc2Iner;
00382 MIPMatrix *RotIner2Loc;
00383
00384
00385
00386
00387
00388
00389 cout << "KalmanFilter::getENCMeasures() (without noise) (d_x=" << d_x << ", d_y=" << d_y << ", d_theta=" << d_theta.dCastDeg() << ")\n";
00390
00391
00392 srand(time(NULL));
00393 Noise=(drand48() - 0.5)*0.01;
00394 d_x = d_x + Noise;
00395 cout << "KalmanFilter::getENCMeasures() d_x Noise=" << Noise << "\n";
00396 srand(time(NULL));
00397 Noise=(drand48() - 0.5)*0.01;
00398 d_y = d_y + Noise;
00399 cout << "KalmanFilter::getENCMeasures() d_y Noise=" << Noise << "\n";
00400 srand(time(NULL));
00401 Noise = (drand48() - 0.5)*0.01;
00402 cout << "KalmanFilter::getENCMeasures() d_theta Noise=" << Noise << "\n";
00403 d_theta.operator=(d_theta.dCastDeg() + Noise);
00404 cout << "KalmanFilter::getENCMeasures() with noise (d_x=" << d_x << ", d_y=" << d_y << ", d_theta=" <<
00405 d_theta.dCast2Pi() << " = " << d_theta.dCastDeg() << ")\n";
00406
00407
00408 ds_Iner = new MIPMatrix(3,1,ZERO_MATRIX);
00409 ds_Iner->SetMIPMatrixVal(1,1,d_x);
00410 ds_Iner->SetMIPMatrixVal(2,1,d_y);
00411 ds_Iner->SetMIPMatrixVal(3,1,0);
00412 cout << "KalmanFilter::outEstim_ENC(), ds_Iner vector components: " << "\n";
00413 cout << "dx_Iner= " << ds_Iner->GetMIPMatrixVal(1,1) << "\n";
00414 cout << "dy_Iner= " << ds_Iner->GetMIPMatrixVal(2,1) << "\n";
00415 cout << "dz_Iner= " << ds_Iner->GetMIPMatrixVal(3,1) << "\n";
00416 cout << "d_theta= " << d_theta.dCastDeg() << "\n";
00417
00418 RotLoc2Iner = new MIPMatrix(3,3,ZERO_MATRIX);
00419 RotIner2Loc = new MIPMatrix(3,3,ZERO_MATRIX);
00420
00421
00422 cout << "KalmanFilter::getENCMeasures(), RotTranslMatrix matrix: " << "\n";
00423 (Surf->GetRotTranslMatrix(CurrentRobotPlane))->printMIPMatrix();
00424 RotLoc2Iner->MinorMatrix(*(Surf->GetRotTranslMatrix(CurrentRobotPlane)),4,4);
00425 cout << "KalmanFilter::getENCMeasures(), RotLoc2Iner matrix: " << "\n";
00426 RotLoc2Iner->printMIPMatrix();
00427 RotIner2Loc->inv33(*RotLoc2Iner);
00428 cout << "KalmanFilter::getENCMeasures(), RotIner2Loc matrix: " << "\n";
00429 RotIner2Loc->printMIPMatrix();
00430
00431
00432 ds_Loc = new MIPMatrix(3,1,ZERO_MATRIX);
00433 ds_Loc->mul(*RotIner2Loc,*ds_Iner);
00434 dx_loc = ds_Loc->GetMIPMatrixVal(1,1);
00435 dy_loc = ds_Loc->GetMIPMatrixVal(2,1);
00436 cout << "KalmanFilter::getENCMeasures(), ds_Loc vector components: " << "\n";
00437 cout << "dx_loc= " << dx_loc << "\n";
00438 cout << "dy_loc= " << dy_loc << "\n";
00439 cout << "dz_loc= " << ds_Loc->GetMIPMatrixVal(3,1) << "\n";
00440 cout << "d_theta= " << d_theta.dCastDeg() << "\n";
00441
00442 if(ds_Loc->GetMIPMatrixVal(3,1) != 0.0)
00443 cout << "KalmanFilter::getENCMeasures(): ERROR - dz_loc <> 0!!! " << ds_Loc->GetMIPMatrixVal(3,1) << "\n";
00444
00445 newtheta.operator=(d_theta);
00446
00447 ENC_Meas->SetMIPMatrixVal(1,1,dx_loc);
00448 ENC_Meas->SetMIPMatrixVal(2,1,dy_loc);
00449 ENC_Meas->SetMIPMatrixVal(3,1,newtheta.dCast2Pi());
00450
00451
00452
00453
00454 cout << "KalmanFilter::getENCMeasures(), ds_Loc vector components: " << "\n";
00455 cout << "dx_loc= " << ENC_Meas->GetMIPMatrixVal(1,1) << "\n";
00456 cout << "dy_loc= " << ENC_Meas->GetMIPMatrixVal(2,1) << "\n";
00457 cout << "newtheta= " << ENC_Meas->GetMIPMatrixVal(3,1) << "\n";
00458 cout << "KalmanFilter::getENCMeasures() (d_theta): " << newtheta.dCastDeg() << "\n";
00459
00460
00461 delete RotLoc2Iner;
00462 delete RotIner2Loc;
00463 delete ds_Iner;
00464 delete ds_Loc;
00465 return;
00466 }
00467
00468
00469 void PositionErrorEstimate(Position3D &pos)
00470 {
00471 MIPMatrix *LoclRobPos;
00472 MIPMatrix *InerRobPos;
00473
00474 Decimal X_err;
00475 Decimal Y_err;
00476 Decimal Z_err;
00477
00478 cout << "KalmanFilter::PositionErrorEstimate()" << "\n";
00479 LoclRobPos = new MIPMatrix(4,1,ZERO_MATRIX);
00480 InerRobPos = new MIPMatrix(4,1,ZERO_MATRIX);
00481
00482
00483 LoclRobPos->SetMIPMatrixVal(1,1,State_0->GetMIPMatrixVal(1,1));
00484 LoclRobPos->SetMIPMatrixVal(2,1,State_0->GetMIPMatrixVal(2,1));
00485 LoclRobPos->SetMIPMatrixVal(3,1,0);
00486 LoclRobPos->SetMIPMatrixVal(4,1,1);
00487
00488
00489 InerRobPos->mul(*(Surf->GetRotTranslMatrix(CurrentRobotPlane)),*LoclRobPos);
00490
00491
00492 cout << "KalmanFilter::PositionErrorEstimate(): Robot position from proxi interface." << "\n";
00493 cout << "X_pos (proxi) = " << pos.x() << "\n";
00494 cout << "Y_pos (proxi) = " << pos.y() << "\n";
00495 cout << "Z_pos (proxi) = " << pos.z() << "\n";
00496
00497 cout << "KalmanFilter::PositionErrorEstimate(): Estimated Robot position." << "\n";
00498 cout << "X_pos (estimated) = " << InerRobPos->GetMIPMatrixVal(1,1) << "\n";
00499 cout << "Y_pos (estimated) = " << InerRobPos->GetMIPMatrixVal(2,1) << "\n";
00500 cout << "Z_pos (estimated) = " << InerRobPos->GetMIPMatrixVal(3,1) << "\n";
00501
00502 cout << "KalmanFilter::PositionErrorEstimate(): Estimated position error." << "\n";
00503 cout << "X_err = " << pos.x()-InerRobPos->GetMIPMatrixVal(1,1) << "\n";
00504 cout << "Y_err = " << pos.y()-InerRobPos->GetMIPMatrixVal(2,1) << "\n";
00505 cout << "Z_err = " << pos.z()-InerRobPos->GetMIPMatrixVal(3,1) << "\n";
00506
00507
00508 LoclRobPos->SetMIPMatrixVal(1,1,State_1->GetMIPMatrixVal(1,1));
00509 LoclRobPos->SetMIPMatrixVal(2,1,State_1->GetMIPMatrixVal(2,1));
00510 LoclRobPos->SetMIPMatrixVal(3,1,0);
00511 LoclRobPos->SetMIPMatrixVal(4,1,1);
00512
00513
00514 InerRobPos->mul(*(Surf->GetRotTranslMatrix(CurrentRobotPlane)),*LoclRobPos);
00515
00516 cout << "KalmanFilter::PositionErrorEstimate(): Predicted Robot position." << "\n";
00517 cout << "X_pos (estimated) = " << InerRobPos->GetMIPMatrixVal(1,1) << "\n";
00518 cout << "Y_pos (estimated) = " << InerRobPos->GetMIPMatrixVal(2,1) << "\n";
00519 cout << "Z_pos (estimated) = " << InerRobPos->GetMIPMatrixVal(3,1) << "\n";
00520
00521 cout << "KalmanFilter::PositionErrorEstimate(): Predicted position error." << "\n";
00522 cout << "X_err = " << pos.x()-InerRobPos->GetMIPMatrixVal(1,1) << "\n";
00523 cout << "Y_err = " << pos.y()-InerRobPos->GetMIPMatrixVal(2,1) << "\n";
00524 cout << "Z_err = " << pos.z()-InerRobPos->GetMIPMatrixVal(3,1) << "\n";
00525
00526 return;
00527 }
00528
00529
00530 void updateKalmanFilter()
00531 {
00532 Decimal tmp;
00533 Angle tmp_1;
00534
00535 cout << "updateKalmanFilter() started." << endl;
00536
00537
00538 cout << "Previous estimated state: x= " << State_0->GetMIPMatrixVal(1,1) << ", y= " << State_0->GetMIPMatrixVal(2,1)
00539 << ", theta= " << State_0->GetMIPMatrixVal(3,1) << "\n";
00540 cout << "Previous predicted state: x= " << State_1->GetMIPMatrixVal(1,1) << ", y= " << State_1->GetMIPMatrixVal(2,1)
00541 << ", theta= " << State_1->GetMIPMatrixVal(3,1) << "\n";
00542 cout << "Encoder measures: dx_loc= " << ENC_Meas->GetMIPMatrixVal(1,1) << ", dy_loc= " << ENC_Meas->GetMIPMatrixVal(2,1)
00543 << ", dtheta= " << ENC_Meas->GetMIPMatrixVal(3,1) << "\n";
00544
00545 if(GPS_MeasAvail == true)
00546 {
00547 cout << "updateKalmanFilter() - GPS measure available." << endl;
00548
00549 outPred();
00550
00551
00552
00553 matrix_K();
00554
00555 matrix_P();
00556
00557
00558 estimateRobotStatus();
00559
00560 calculateStatusPrediction();
00561
00562 calculate_A();
00563
00564 calculatePp();
00565
00566 updRobotPlane();
00567
00568 unsetGPSAvailability();
00569 }
00570 else
00571 {
00572
00573 tmp = State_1->GetMIPMatrixVal(1,1) + ENC_Meas->GetMIPMatrixVal(1,1);
00574 State_1->SetMIPMatrixVal(1, 1, tmp);
00575 tmp = State_1->GetMIPMatrixVal(2,1) + ENC_Meas->GetMIPMatrixVal(2,1);
00576 State_1->SetMIPMatrixVal(2, 1, tmp);
00577 tmp_1.operator=(State_1->GetMIPMatrixVal(3,1) + ENC_Meas->GetMIPMatrixVal(3,1));
00578 State_1->SetMIPMatrixVal(3, 1, tmp_1.dCast2Pi());
00579
00580
00581 }
00582 cout << "Last estimated state: x= " << State_0->GetMIPMatrixVal(1,1) << ", y= " << State_0->GetMIPMatrixVal(2,1)
00583 << ", theta= " << State_0->GetMIPMatrixVal(3,1) << "\n";
00584 cout << "Last predicted state: x= " << State_1->GetMIPMatrixVal(1,1) << ", y= " << State_1->GetMIPMatrixVal(2,1)
00585 << ", theta= " << State_1->GetMIPMatrixVal(3,1) << "\n";
00586
00587 return;
00588 }
00589 };
00590 #endif
00591
00592
00593
00594