KalmanSmootherHarness.cpp

Go to the documentation of this file.
00001 #include "indii/ml/filter/KalmanFilter.hpp"
00002 #include "indii/ml/filter/KalmanSmoother.hpp"
00003 #include "indii/ml/filter/LinearModel.hpp"
00004 
00005 #include "MobileRobot.hpp"
00006 
00007 #include <math.h>
00008 #include <iostream>
00009 #include <fstream>
00010 #include <stack>
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 KalmanSmootherHarness.cpp
00025  *
00026  * Basic test of KalmanSmoother.
00027  *
00028  * This test sets up a linear model for testing the Kalman two-filter
00029  * smoother implementation. It may be validated against the
00030  * Rauch-Tung-Striebel (RTS) smoother and Kalman filter results.
00031  *
00032  * Results are output into files as follows:
00033  *
00034  * @section actualKS results/KalmanSmootherHarness_actual.out
00035  *
00036  * Actual state of the robot at each time. Columns are as follows:
00037  *
00038  * @li time
00039  * @li x coordinate
00040  * @li y coordinate
00041  * @li orientation (radians)
00042  *
00043  * @section measKS results/KalmanSmootherHarness_meas.out
00044  * 
00045  * Measurement at each time step. Columns are as follows:
00046  *
00047  * @li time
00048  * @li measurement
00049  *
00050  * @section filter results/KalmanSmootherHarness_filter.out
00051  *
00052  * Predicted stateKS (filtered) at each time step. Columns are as follows:
00053  *
00054  * @li time
00055  * @li mean x coordinate
00056  * @li mean y coordinate
00057  * @li mean orientation
00058  * @li The remaining columns give the covariance matrix between the above
00059  * state variables.
00060  *
00061  * @section smoothKS results/KalmanSmootherHarness_smooth.out
00062  *
00063  * Predicted state (smoothed) at each time step. Columns are as follows:
00064  *
00065  * @li time
00066  * @li mean x coordinate
00067  * @li mean y coordinate
00068  * @li mean orientation
00069  * @li The remaining columns give the covariance matrix between the above
00070  * state variables.
00071  *
00072  * Note that as the smoothing is performed in a backwards pass, this file has
00073  * entries in reverse time order.
00074  *
00075  * @section resultsKS Results
00076  *
00077  * Results are as follows:
00078  *
00079  * \image html KalmanSmootherHarness.png "Results"
00080  * \image latex KalmanSmootherHarness.eps "Results"
00081  */
00082 
00083 void outputVector(ofstream& out, aux::vector vec);
00084 
00085 void outputMatrix(ofstream& out, aux::matrix mat);
00086 
00087 /**
00088  * Run tests
00089  */
00090 int main(int argc, const char* argv) {
00091   /* define model */
00092   aux::matrix A(STATE_SIZE,STATE_SIZE);
00093   aux::matrix G(STATE_SIZE,STATE_SIZE);
00094   aux::matrix C(MEAS_SIZE,STATE_SIZE);
00095   aux::symmetric_matrix Q(STATE_SIZE);
00096   aux::symmetric_matrix R(MEAS_SIZE);
00097 
00098   A.clear();
00099   A(0,0) = 1.0;
00100   A(0,3) = cos(0.8);
00101   A(1,1) = 1.0;
00102   A(1,3) = sin(0.8);
00103   A(2,2) = 1.0;
00104   A(3,3) = 1.0;
00105   A(4,4) = 1.0;
00106 
00107   G.clear();
00108   G(0,0) = 1.0;
00109   G(1,1) = 1.0;
00110 
00111   Q.clear();
00112   Q(0,0) = pow(0.01, 2.0);
00113   Q(1,1) = pow(0.01, 2.0);
00114   /* next three just so that Q is Cholesky decomposible, are zeroed by G */
00115   Q(2,2) = 1.0;
00116   Q(3,3) = 1.0;
00117   Q(4,4) = 1.0;
00118 
00119   C.clear();
00120   C(0,1) = 2.0;
00121 
00122   R.clear();
00123   R(0,0) = pow(0.05,2.0);
00124   
00125   LinearModel model(A, G, Q, C, R);
00126 
00127   /* initial state */
00128   aux::vector mu(STATE_SIZE);
00129   aux::symmetric_matrix sigma(STATE_SIZE);
00130 
00131   mu.clear();
00132   mu(0) = -1.0;
00133   mu(1) = 1.0;
00134   mu(2) = 0.8;
00135   mu(3) = 0.1;
00136   mu(4) = 0.0;
00137 
00138   sigma.clear();
00139   sigma(0,0) = 1.0;
00140   sigma(1,1) = 1.0;
00141   sigma(2,2) = 0.1;
00142   sigma(3,3) = 0.1;
00143   sigma(4,4) = 0.1;
00144 
00145   aux::GaussianPdf x0(mu, sigma);
00146 
00147   /* create smoother */
00148   KalmanFilter<unsigned int> filter(&model, x0);
00149 
00150   /* set up robot simulator */
00151   MobileRobot robot(0.1, 5e-3);
00152 
00153   /* estimate and output results */
00154   stack<aux::GaussianPdf> filteredStates;
00155   stack<aux::vector> outputs;
00156   aux::vector meas(MEAS_SIZE);
00157   aux::vector actual(ACTUAL_SIZE);
00158   aux::GaussianPdf pred(STATE_SIZE);
00159   unsigned int t = 0;
00160 
00161   ofstream fmeas("results/KalmanSmootherHarness_meas.out");
00162   ofstream factual("results/KalmanSmootherHarness_actual.out");
00163   ofstream ffilter("results/KalmanSmootherHarness_filter.out");
00164   ofstream fbackfilter("results/KalmanSmootherHarness_backfilter.out");
00165   ofstream fsmooth("results/KalmanSmootherHarness_smooth.out");
00166 
00167   /* output initial state */
00168   actual = robot.getState();
00169   pred = filter.getFilteredState();
00170   filteredStates.push(pred);
00171 
00172   cerr << t << ' ';
00173 
00174   factual << t << '\t';
00175   outputVector(factual, actual);
00176   factual << endl;
00177 
00178   ffilter << t << '\t';
00179   outputVector(ffilter, pred.getExpectation());
00180   ffilter << '\t';
00181   outputMatrix(ffilter, pred.getCovariance());
00182   ffilter << endl;
00183 
00184   /* filter */
00185   for (t = 1; t <= STEPS; t++) {
00186     robot.move();
00187 
00188     meas = robot.measure();
00189     filter.filter(t, meas);
00190     pred = filter.getFilteredState();
00191     actual = robot.getState();
00192     outputs.push(meas);
00193     filteredStates.push(pred);
00194 
00195     cerr << t << ' ';
00196 
00197     /* output measurement */
00198     fmeas << t << '\t';
00199     outputVector(fmeas, meas);
00200     fmeas << endl;
00201 
00202     /* output actual state */
00203     factual << t << '\t';
00204     outputVector(factual, actual);
00205     factual << endl;
00206 
00207     /* output filtered state */
00208     ffilter << t << '\t';
00209     outputVector(ffilter, pred.getExpectation());
00210     ffilter << '\t';
00211     outputMatrix(ffilter, pred.getCovariance());
00212     ffilter << endl;
00213   }
00214 
00215   /* smooth */
00216   t--;
00217   pred = filter.getFilteredState();
00218   KalmanSmoother<unsigned int> smoother(&model, t, pred);
00219 
00220   cerr << t << ' ';
00221 
00222   fsmooth << t << '\t';
00223   outputVector(fsmooth, pred.getExpectation());
00224   fsmooth << '\t';
00225   outputMatrix(fsmooth, pred.getCovariance());
00226   fsmooth << endl;
00227 
00228   pred = smoother.getBackwardFilteredState();
00229   fbackfilter << t << '\t';
00230   outputVector(fbackfilter, pred.getExpectation());
00231   fbackfilter << '\t';
00232   outputMatrix(fbackfilter, pred.getCovariance());
00233   fbackfilter << endl;
00234 
00235   outputs.pop();
00236   filteredStates.top();
00237 
00238   for (t = STEPS - 1; t >= 1; t--) {
00239     smoother.smooth(t, outputs.top(), filteredStates.top());
00240     outputs.pop();
00241     filteredStates.pop();
00242 
00243     cerr << t << ' ';
00244 
00245     /* output backward filtered state */
00246     pred = smoother.getBackwardFilteredState();
00247     fbackfilter << t << '\t';
00248     outputVector(fbackfilter, pred.getExpectation());
00249     fbackfilter << '\t';
00250     outputMatrix(fbackfilter, pred.getCovariance());
00251     fbackfilter << endl;
00252 
00253     /* output smoothed state */
00254     pred = smoother.getSmoothedState();
00255     fsmooth << t << '\t';
00256     outputVector(fsmooth, pred.getExpectation());
00257     fsmooth << '\t';
00258     outputMatrix(fsmooth, pred.getCovariance());
00259     fsmooth << endl;
00260   }
00261 
00262   fmeas.close();
00263   factual.close();
00264   ffilter.close();
00265   fbackfilter.close();
00266   fsmooth.close();
00267 
00268   return 0;
00269 }
00270 
00271 void outputVector(ofstream& out, aux::vector vec) {
00272   aux::vector::iterator iter, end;
00273   iter = vec.begin();
00274   end = vec.end();
00275   while (iter != end) {
00276     out << *iter;
00277     iter++;
00278     if (iter != end) {
00279       out << '\t';
00280     }
00281   }
00282 }
00283 
00284 void outputMatrix(ofstream& out, aux::matrix mat) {
00285   unsigned int i, j;
00286   for (j = 0; j < mat.size2(); j++) {
00287     for (i = 0; i < mat.size1(); i++) {
00288       out << mat(i,j);
00289       if (i != mat.size1() - 1 || j != mat.size2() - 1) {
00290   out << '\t';
00291       }
00292     }
00293   }
00294 }

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