KalmanFilterHarness.cpp

Go to the documentation of this file.
00001 #include "indii/ml/filter/KalmanFilter.hpp"
00002 #include "indii/ml/filter/LinearModel.hpp"
00003 #include "indii/ml/aux/vector.hpp"
00004 #include "indii/ml/aux/matrix.hpp"
00005 
00006 #include "MobileRobot.hpp"
00007 
00008 #include <math.h>
00009 #include <iostream>
00010 #include <fstream>
00011 
00012 #define STATE_SIZE 5
00013 #define MEAS_SIZE 1
00014 #define ACTUAL_SIZE 3
00015 #define STEPS 100
00016 
00017 using namespace std;
00018 using namespace indii::ml::filter;
00019 
00020 namespace aux = indii::ml::aux;
00021 namespace ublas = boost::numeric::ublas;
00022 
00023 /**
00024  * @file KalmanFilterHarness.cpp
00025  *
00026  * Basic test of KalmanFilter.
00027  *
00028  * This test sets up a linear model for testing the Kalman filter
00029  * implementation. For comparison against an existing implementation, the
00030  * Bayesian Filtering Library (http://www.orocos.org/bfl), the model used is
00031  * identical to that described in that particularly library's tutorial
00032  * (http://people.mech.kuleuven.be/~tdelaet/getting_started_guide/).
00033  *
00034  * Results are output into files as follows:
00035  *
00036  * @section actualKF results/KalmanFilterHarness_actual.out
00037  *
00038  * Actual state of the robot at each time. Columns are as follows:
00039  *
00040  * @li time
00041  * @li x coordinate
00042  * @li y coordinate
00043  * @li orientation (radians)
00044  *
00045  * @section measKF results/KalmanFilterHarness_meas.out
00046  * 
00047  * Measurement at each time step. Columns are as follows:
00048  *
00049  * @li time
00050  * @li measurement
00051  *
00052  * @section predKF results/KalmanFilterHarness_pred.out
00053  *
00054  * Predicted state at each time step. Columns are as follows:
00055  *
00056  * @li time
00057  * @li mean x coordinate
00058  * @li mean y coordinate
00059  * @li mean orientation
00060  * @li The remaining columns give the covariance matrix between the above
00061  * state variables.
00062  *
00063  * @section resultsKF Results
00064  *
00065  * Results are as follows:
00066  *
00067  * \image html KalmanFilterHarness.png "Results, c.f. BFL Tutorial Figures 3.2 and 3.3"
00068  * \image latex KalmanFilterHarness.eps "Results, c.f. BFL Tutorial Figures 3.2 and 3.3"
00069  */
00070 
00071 void outputVector(ofstream& out, aux::vector vec);
00072 
00073 void outputMatrix(ofstream& out, aux::matrix mat);
00074 
00075 /**
00076  * Run tests
00077  */
00078 int main(int argc, const char* argv) {
00079   /* define model */
00080   aux::matrix A(STATE_SIZE,STATE_SIZE);
00081   aux::matrix G(STATE_SIZE,STATE_SIZE);
00082   aux::matrix C(MEAS_SIZE,STATE_SIZE);
00083   aux::symmetric_matrix Q(STATE_SIZE);
00084   aux::symmetric_matrix R(MEAS_SIZE);
00085 
00086   A.clear();
00087   A(0,0) = 1.0;
00088   A(0,3) = cos(0.8);
00089   A(1,1) = 1.0;
00090   A(1,3) = sin(0.8);
00091   A(2,2) = 1.0;
00092   A(3,3) = 1.0;
00093   A(4,4) = 1.0;
00094 
00095   G.clear();
00096   G(0,0) = 1.0;
00097   G(1,1) = 1.0;
00098 
00099   Q.clear();
00100   Q(0,0) = pow(0.01, 2.0);
00101   Q(1,1) = pow(0.01, 2.0);
00102   /* next three just so that Q is Cholesky decomposible, are zeroed by G */
00103   Q(2,2) = 1.0;
00104   Q(3,3) = 1.0;
00105   Q(4,4) = 1.0;
00106 
00107   C.clear();
00108   C(0,1) = 2.0;
00109 
00110   R.clear();
00111   R(0,0) = pow(0.05,2.0);
00112   
00113   LinearModel model(A, G, Q, C, R);
00114 
00115   /* initial state */
00116   aux::vector mu(STATE_SIZE);
00117   aux::symmetric_matrix sigma(STATE_SIZE);
00118 
00119   mu.clear();
00120   mu(0) = -1.0;
00121   mu(1) = 1.0;
00122   mu(2) = 0.8;
00123   mu(3) = 0.1;
00124   mu(4) = 0.0;
00125 
00126   sigma.clear();
00127   sigma(0,0) = 1.0;
00128   sigma(1,1) = 1.0;
00129   sigma(2,2) = 0.1;
00130   sigma(3,3) = 0.1;
00131   sigma(4,4) = 0.1;
00132 
00133   aux::GaussianPdf x0(mu, sigma);
00134 
00135   /* create filter */
00136   KalmanFilter<unsigned int> filter(&model, x0);
00137 
00138   /* set up robot simulator */
00139   MobileRobot robot;
00140 
00141   /* estimate and output results */
00142   aux::vector meas(MEAS_SIZE);
00143   aux::vector actual(ACTUAL_SIZE);
00144   aux::GaussianPdf pred(STATE_SIZE);
00145   unsigned int t = 0;
00146 
00147   ofstream fmeas("results/KalmanFilterHarness_meas.out");
00148   ofstream factual("results/KalmanFilterHarness_actual.out");
00149   ofstream fpred("results/KalmanFilterHarness_pred.out");
00150 
00151   /* output initial state */
00152   pred = filter.getFilteredState();
00153   actual = robot.getState();
00154 
00155   cerr << t << ' ';
00156 
00157   factual << t << '\t';
00158   outputVector(factual, actual);
00159   factual << endl;
00160 
00161   fpred << t << '\t';
00162   outputVector(fpred, pred.getExpectation());
00163   fpred << '\t';
00164   outputMatrix(fpred, pred.getCovariance());
00165   fpred << endl;
00166 
00167   for (t = 1; t <= STEPS; t++) {
00168       robot.move();
00169 
00170       meas = robot.measure();
00171       filter.filter(t, meas);
00172       pred = filter.getFilteredState();
00173       actual = robot.getState();
00174 
00175       cerr << t << ' ';
00176 
00177       /* output measurement */
00178       fmeas << t << '\t';
00179       outputVector(fmeas, meas);
00180       fmeas << endl;
00181 
00182       /* output actual state */
00183       factual << t << '\t';
00184       outputVector(factual, actual);
00185       factual << endl;
00186 
00187       /* output filtered state */
00188       fpred << t << '\t';
00189       outputVector(fpred, pred.getExpectation());
00190       fpred << '\t';
00191       outputMatrix(fpred, pred.getCovariance());
00192       fpred << endl;
00193   }
00194 
00195   fmeas.close();
00196   factual.close();
00197   fpred.close();
00198 
00199   return 0;
00200 }
00201 
00202 void outputVector(ofstream& out, aux::vector vec) {
00203   aux::vector::iterator iter, end;
00204   iter = vec.begin();
00205   end = vec.end();
00206   while (iter != end) {
00207     out << *iter;
00208     iter++;
00209     if (iter != end) {
00210       out << '\t';
00211     }
00212   }
00213 }
00214 
00215 void outputMatrix(ofstream& out, aux::matrix mat) {
00216   unsigned int i, j;
00217   for (j = 0; j < mat.size2(); j++) {
00218     for (i = 0; i < mat.size1(); i++) {
00219       out << mat(i,j);
00220       if (i != mat.size1() - 1 || j != mat.size2() - 1) {
00221   out << '\t';
00222       }
00223     }
00224   }
00225 }

Generated on Wed Dec 17 15:05:50 2008 for dysii Filtering Test Suite by  doxygen 1.5.3