Kalman.h

Go to the documentation of this file.
00001 // ----------------------------------------------------------------------------
00002 //
00003 // $Id$ 
00004 //
00005 // Copyright 2008, 2009, 2010, 2011, 2012  Antonio Franchi and Paolo Stegagno    
00006 //
00007 // This file is part of MIP.
00008 //
00009 // MIP is free software: you can redistribute it and/or modify
00010 // it under the terms of the GNU General Public License as published by
00011 // the Free Software Foundation, either version 3 of the License, or
00012 // (at your option) any later version.
00013 //
00014 // MIP is distributed in the hope that it will be useful,
00015 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017 // GNU General Public License for more details.
00018 //
00019 // You should have received a copy of the GNU General Public License
00020 // along with MIP. If not, see <http://www.gnu.org/licenses/>.
00021 //
00022 // Contact info: antonio.franchi@tuebingen.mpg.de stegagno@diag.uniroma1.it
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 Nel filtro di Kalman ci sono 4 variabili fondamentali:
00076 1:- La stima dello stato al passo k fatta utilizzando le misure fino al passo k. Tale stima è indicata con X(k|k)
00077 2:- La stima dello stato al passo k+1 fatta utilizzando le misure fino al passo k. Tale stima è indicata con X(k+1|k).
00078 3:- La stima della uscita al passo k fatta utilizzando le misure fino al passo k. Tale stima è indicata con Y(k|k) e  coincide con la misura stessa 
00079     effettuata al passo k cioè Y(k).
00080 4:- La stima della uscita al passo k+1 fatta utilizzando le misure fino al passo k. Tale stima è indicata con Y(k+1|k).
00081 
00082 Dato il modello matematico del robot nella forma:
00083 X(k+1)=f(x(k),u(k),k) -- Equazione di stato
00084 Y(k)=h(x(k),u(k),k)   -- Equazione di uscita
00085 
00086 Le stime indicate di sopra ai passi 2 e 4 si fanno utilizzando, rispettivamente, le equazioni di stato e di uscita del modello matematico del robot.
00087 */
00088 #include <boost/concept_check.hpp>
00089 
00090 class KalmanFilter {
00091  private:
00092     Decimal  CycleTime;//Kalman filter sampling time in seconds.
00093 
00094   MIPMatrix *State_0;   //Estimate of robot status at time k: X(k|k). 3 data: x,y,theta.
00095   MIPMatrix *State_1;   //Estimate of robot status at time k+1: X(k+1|k). 3 data: x,y,theta.
00096   MIPMatrix *OutPred;   //Prediction of robot output at time k+1: Y(k+1|k). 3 data: x,y,theta.
00097   MIPMatrix *GPS_Meas;  //GPS measures at time k: Y(k|k); 2 data: x,y.
00098   MIPMatrix *ENC_Meas;  //Encoder measures at time k: used to calculate the robot status prediction X(k+1,k).
00099   
00100   Decimal RobotMass;//Mass of the robot.
00101   Decimal RobotMoI; //Moment of Inertia of the robot (yaw axis).
00102   
00103   Surface *Surf;         //Surface on which the robot is moving
00104   int CurrentRobotPlane; // Reference to the current plane where the robot is moving.
00105   int SemiSpace; //Side w.r.t. the next plane. Used to detect the change of the plane where the robot is moving.
00106   
00107   // Current robot distances from reference points  
00108   //Decimal CurRefPointDist;//Robot distance from reference point in the current surface plane
00109   //Decimal NextRefPointDist;//Robot distance from reference point in the next surface plane
00110   //Decimal PrevRefPointDist;//Robot distance from reference point in the previous surface plane
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;//Only for matrix functions test
00121   
00122   Decimal Force;//Force applied to the robot.
00123   Decimal Torque;//Torque applied to the robot.
00124   bool GPS_MeasAvail;//1 = GPS measure available; 0 = GPS measures not available;
00125   
00126   void initializeMatrixC();
00127   
00128   void initializeState_1();//This function initializes the robot predicted status matrix: State_1(k+1|k).
00129 
00130   void initializeMatrixF();//This function initializes the robot status noise matrix.
00131   
00132                 void initializeMatrixG();//This function initializes the robot output noise matrix.
00133 
00134   void initializeMatrixPp();//This function initializes the equivalent of the covariance error prediction matrix.
00135 
00136   void setSemiSpace();//This function sets a reference value (+1 or -1) to tag the semi-space where the robot is moving.
00137                       //The reference plane is the next w.r.t the one on which the robot is moving.
00138   
00139   void updRobotPlane();//This function updates the plane on which the robot is moving
00140   
00141   // The following functions implements the Kalman filter steps
00142   
00143   void outPred();//II: This function calculates the output prediction.
00144   
00145   //void Matrix_C();//III: This matrix is the Jacobian matrix of h() in X(k+1,k). It is 
00146                     // a (2x3) matrix and is built by the EKF constructor.
00147   
00148   void matrix_K();//IV: This function calculates the Kalman gain matrix K(k+1).
00149   
00150   void matrix_P();//V: This function calculates the matrix P(k+1).
00151 
00152   void estimateRobotStatus();//VI: This function estimates the matrix X(k+1,k+1) using GPS measures.
00153 
00154   void calculateStatusPrediction();//VIII: This function calculates the prediction of the status of the robot X(k+1|k)
00155 
00156   void calculate_A();//IX: This function calculates the Jacobian matrix of f() in X(k,k).
00157 
00158   void calculatePp();//X:  This function calculates the Pp(k+1) matrix
00159     
00160   //void Get_GPS_Measures();
00161  
00162        
00163  public:
00165   KalmanFilter (string namefile)
00166   {
00167           cout << "KalmanFilter::KalmanFilter() starting" << "\n";
00168    //tmpmat = new MIPMatrix(3,3,ZERO_MATRIX); //Used only for matrix functions test.
00169    State_0 = new MIPMatrix(A_ROW,1,ZERO_MATRIX);     
00170    State_1 = new MIPMatrix(A_ROW,1,ZERO_MATRIX);
00171           //cout << "KalmanFilter::KalmanFilter() starting 2" << "\n";   
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           //cout << "KalmanFilter::KalmanFilter() starting 3" << "\n";   
00176    Mat_Pp = new MIPMatrix(Pp_ROW,Pp_COL,IDENTITY_MATRIX);     
00177    Mat_A = new MIPMatrix(A_ROW,A_COL,IDENTITY_MATRIX);
00178    //cout << "KalmanFilter::KalmanFilter() starting 4" << "\n";
00179    Mat_C = new MIPMatrix(C_ROW,C_COL,ZERO_MATRIX);
00180           //cout << "KalmanFilter::KalmanFilter() starting 4a" << "\n";
00181    Mat_K = new MIPMatrix(K_ROW,K_COL,ZERO_MATRIX); 
00182           //cout << "KalmanFilter::KalmanFilter() starting 5" << "\n";
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           //cout << "KalmanFilter::KalmanFilter() starting 6" << "\n";
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();//In this particular case mat_C a constant matrix and is initialized at startup.
00196                         Mat_C->printMIPMatrix();
00197                         cout << "\n";
00198 
00199    //cout << "Initialize F matrix" << endl;
00200    initializeMatrixF();
00201                         //Mat_F->printMIPMatrix();
00202                         cout << "\n";
00203 
00204    //cout << "Initialize Matrix G" << endl;
00205    initializeMatrixG();
00206                         //Mat_G->printMIPMatrix();
00207                         cout << "\n";
00208 
00209    cout << "Initialize status prediction matrix: State_1." << endl;
00210    initializeState_1();//This function initializes the robot predicted status matrix: State_1(k+1|k). Initial conditions.
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;// It is assumed that the robot initial position belongs to the first plane.
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 //    delete OutPred_GPS;
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       // pos = Received GPS measures expressed in the Inertial Reference Frame to be translated in the Local Reference Frame.
00299       MIPMatrix *GPS_MeasInert;//GPS measures expressed in the inertial reference frame.
00300       MIPMatrix *GPS_Measlocal;//GPS measures expressed in the local reference frame.
00301       MIPMatrix *InertialToLocal;//Rototranslation matrix from Inertial reference frame to local reference frame.
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   //  cout << "Pause 2 sec" << "\n";
00325       
00326       tmp->operator=(*(Surf->GetRotTranslMatrix(CurrentRobotPlane)));
00327   //  tmp->printMIPMatrix();
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))//z_loc != 0. EPSILON=0.01
00350       {
00351    cout << "Wrong data received from GPS. Error too big for z_loc = " << z_loc << " it should be zero!!" << endl;
00352    //return false;
00353       }
00354        
00355       //Write the GPS measure in the input matrix of the Kalman Filter.
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 //       Decimal meas_speed;
00371 //       Decimal meas_turnrate;
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;//Rotation matrix from local reference frame to inertial reference frame
00382       MIPMatrix *RotIner2Loc;//Rotation matrix from inertial reference frame to local reference frame
00383       
00384       // d_x,d_y,d_theta are expressed in the global reference frame, while I need the corresponding values
00385       // in the local reference frame. This function calculates the required values taking into consideration that the robot measured
00386       // speed is the same in both reference frames, because the relative speed of the local reference frame w.r.t the inertial
00387       // reference frame is zero.
00388       
00389       cout << "KalmanFilter::getENCMeasures() (without noise) (d_x=" << d_x << ", d_y=" << d_y << ", d_theta=" << d_theta.dCastDeg() << ")\n";
00390       
00391       // Add noise to measures d_x, d_y, d_theta
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       //Robot movement in the inertial reference frame. 
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);//d_z=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       //Get rotation matrix from local to inertial reference frame
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       //Robot movement in the local reference frame.
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 //       ENC_Meas->SetMIPMatrixVal(4,1,meas_speed);
00451 //       ENC_Meas->SetMIPMatrixVal(5,1,meas_turnrate);
00452 // 
00453       //cout << "KalmanFilter::getENCMeasures().Robot status prediction calculated using ENC measures as if they were inputs: " << endl;
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)//This function calculates position error estimate.
00470   {
00471           MIPMatrix *LoclRobPos;//GPS measures expressed in the local reference frame.
00472       MIPMatrix *InerRobPos;//GPS measures expressed in the inertial reference frame.
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       //Estimated Robot position in the local reference frame. z_loc = 0; Component (4,1) of the vector is 1 for rototranslation matrix.
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       //Estimated Robot position in the inertial reference frame.
00489       InerRobPos->mul(*(Surf->GetRotTranslMatrix(CurrentRobotPlane)),*LoclRobPos);
00490       
00491       //Kalman Filtering position error.
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       //Predicted Robot position in the local reference frame. z_loc = 0; Component (4,1) of the vector is 1 for rototranslation matrix.
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       //Predicted Robot position in the inertial reference frame.
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()//Kalman filter algorithm implementation
00531   {
00532           Decimal tmp;
00533    Angle tmp_1;
00534    
00535           cout << "updateKalmanFilter() started." << endl;
00536    //Initial conditions already set at Kalman Filter instantiation. (Status prediction initialization and Pp matrix initialization). 
00537    //See EKF constructor. //I
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();//II: This function calculates the prediction of the output Y(k+1|k). 
00550       
00551       //Matrix_C();//III: Since this is a constant matrix it is calculated only once at EKF initialization.
00552       
00553       matrix_K();//IV: This function calculates the Kalman gain matrix K(k+1). 
00554      
00555              matrix_P();//V: This function calculates the matrix P(k+1).
00556      
00557       //cout << "updateKalmanFilter() estimating robot status using GPS measures." << endl;
00558       estimateRobotStatus();//VI: This function estimates the matrix X(k+1,k+1).
00559       
00560       calculateStatusPrediction();//VIII: This function calculates the prediction of the status of the robot X(k+1|k)=f(-)
00561       
00562       calculate_A();//IX: This function calculates the Jacobian matrix of f() in X(k,k).
00563       
00564       calculatePp();//X: This function calculates the Pp(k+1) matrix.      
00565 
00566       updRobotPlane();//This function calculates the plane on which the robot is moving.
00567       
00568       unsetGPSAvailability();
00569    }
00570    else
00571    {
00572       //GPS measures not available, execute odometry integration to predict the new robot status X(k+1,k) //VIII
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       //State_1->SetMIPMatrixVal(4, 1, ); 
00580       //State_1->SetMIPMatrixVal(5, 1, );
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 

Generated on Mon Feb 20 07:01:06 2017 for MIP by  doxygen 1.5.6