UnscentedKalmanSmootherHarness.cpp

Go to the documentation of this file.
00001 #include "indii/ml/filter/UnscentedKalmanFilter.hpp"
00002 #include "indii/ml/filter/UnscentedKalmanSmoother.hpp"
00003 
00004 #include "MobileRobotUnscentedKalmanFilterModel.hpp"
00005 #include "MobileRobot.hpp"
00006 
00007 #include <math.h>
00008 #include <iostream>
00009 #include <fstream>
00010 #include <stack>
00011 
00012 #define SYSTEM_SIZE 5
00013 #define SYSTEM_NOISE_SIZE 2
00014 #define MEAS_SIZE 1
00015 #define MEAS_NOISE_SIZE 1
00016 #define ACTUAL_SIZE 3
00017 #define STEPS 250
00018 
00019 using namespace std;
00020 using namespace indii::ml::filter;
00021 
00022 namespace aux = indii::ml::aux;
00023 namespace ublas = boost::numeric::ublas;
00024 
00025 /**
00026  * @file UnscentedKalmanSmootherHarness.cpp
00027  *
00028  * Basic test of UnscentedKalmanSmoother.
00029  *
00030  * Results are output into files as follows:
00031  *
00032  * @section actualUKS results/UnscentedKalmanSmootherHarness_actual.out
00033  *
00034  * Actual state of the robot at each time. Columns are as follows:
00035  *
00036  * @li time
00037  * @li x coordinate
00038  * @li y coordinate
00039  * @li orientation (radians)
00040  *
00041  * @section measUKS results/UnscentedKalmanSmootherHarness_meas.out
00042  * 
00043  * Measurement at each time step. Columns are as follows:
00044  *
00045  * @li time
00046  * @li measurement
00047  *
00048  * @section filterUKS results/UnscentedKalmanSmootherHarness_filter.out
00049  *
00050  * Predicted state (filtered) at each time step. Columns are as follows:
00051  *
00052  * @li time
00053  * @li mean x coordinate
00054  * @li mean y coordinate
00055  * @li mean orientation
00056  * @li The remaining columns give the covariance matrix between the above
00057  * state variables.
00058  *
00059  * @section smoothUKS results/UnscentedKalmanSmootherHarness_smooth.out
00060  *
00061  * Predicted state (smoothed) at each time step. Columns are as follows:
00062  *
00063  * @li time
00064  * @li mean x coordinate
00065  * @li mean y coordinate
00066  * @li mean orientation
00067  * @li The remaining columns give the covariance matrix between the above
00068  * state variables.
00069  *
00070  * Note that as the smoothing is performed in a backwards pass, this file has
00071  * entries in reverse time order.
00072  *
00073  * @section resultsUKS Results
00074  *
00075  * Results are as follows:
00076  *
00077  * \image html UnscentedKalmanSmootherHarness.png "Results"
00078  * \image latex UnscentedKalmanSmootherHarness.eps "Results"
00079  */
00080 
00081 void outputVector(ofstream& out, aux::vector vec);
00082 
00083 void outputMatrix(ofstream& out, aux::matrix mat);
00084 
00085 /**
00086  * Run tests
00087  */
00088 int main(int argc, const char* argv) {
00089   /* define model */
00090   MobileRobotUnscentedKalmanFilterModel model;
00091 
00092   /* set up robot simulator */
00093   MobileRobot robot(0.1, 5e-3);
00094 
00095   /* initial state */
00096   aux::vector mu(SYSTEM_SIZE);
00097   aux::symmetric_matrix sigma(SYSTEM_SIZE);
00098 
00099   mu.clear();
00100   mu(0) = -1.0;
00101   mu(1) = 1.0;
00102   mu(2) = 0.8;
00103   mu(3) = 0.1;
00104   mu(4) = 5e-3;
00105 
00106   sigma.clear();
00107   sigma(0,0) = 1.0;
00108   sigma(1,1) = 1.0;
00109   sigma(2,2) = 0.01;
00110   sigma(3,3) = 1e-6;
00111   sigma(4,4) = 1e-6;
00112 
00113   aux::GaussianPdf x0(mu, sigma);
00114 
00115   /* create smoother */
00116   UnscentedKalmanFilter<unsigned int> filter(&model, x0);
00117 
00118   /* estimate and output results */
00119   stack<aux::GaussianPdf> filteredStates;
00120   stack<aux::vector> outputs;
00121   aux::vector meas(MEAS_SIZE);
00122   aux::vector actual(ACTUAL_SIZE);
00123   aux::GaussianPdf pred(SYSTEM_SIZE);
00124   unsigned int t = 0;
00125 
00126   ofstream fmeas("results/UnscentedKalmanSmootherHarness_meas.out");
00127   ofstream factual("results/UnscentedKalmanSmootherHarness_actual.out");
00128   ofstream ffilter("results/UnscentedKalmanSmootherHarness_filter.out");
00129   ofstream fbackfilter(
00130       "results/UnscentedKalmanSmootherHarness_backfilter.out");
00131   ofstream fsmooth("results/UnscentedKalmanSmootherHarness_smooth.out");
00132 
00133   /* output initial state */
00134   actual = robot.getState();
00135   pred = filter.getFilteredState();
00136   filteredStates.push(pred);
00137 
00138   cerr << t << ' ';
00139 
00140   factual << t << '\t';
00141   outputVector(factual, actual);
00142   factual << endl;
00143 
00144   ffilter << t << '\t';
00145   outputVector(ffilter, pred.getExpectation());
00146   ffilter << '\t';
00147   outputMatrix(ffilter, pred.getCovariance());
00148   ffilter << endl;
00149 
00150   /* filter */
00151   for (t = 1; t <= STEPS; t++) {
00152     robot.move();
00153 
00154     meas = robot.measure();
00155     filter.filter(t, meas);
00156     pred = filter.getFilteredState();
00157     actual = robot.getState();
00158     outputs.push(meas);
00159     filteredStates.push(pred);
00160 
00161     cerr << t << ' ';
00162 
00163     /* output measurement */
00164     fmeas << t << '\t';
00165     outputVector(fmeas, meas);
00166     fmeas << endl;
00167 
00168     /* output actual state */
00169     factual << t << '\t';
00170     outputVector(factual, actual);
00171     factual << endl;
00172 
00173     /* output filtered state */
00174     ffilter << t << '\t';
00175     outputVector(ffilter, pred.getExpectation());
00176     ffilter << '\t';
00177     outputMatrix(ffilter, pred.getCovariance());
00178     ffilter << endl;
00179   }
00180 
00181   /* smooth */
00182   t--;
00183   pred = filter.getFilteredState();
00184   UnscentedKalmanSmoother<unsigned int> smoother(&model, t, pred);
00185 
00186   cerr << t << ' ';
00187   fsmooth << t << '\t';
00188   outputVector(fsmooth, pred.getExpectation());
00189   fsmooth << '\t';
00190   outputMatrix(fsmooth, pred.getCovariance());
00191   fsmooth << endl;
00192 
00193   pred = smoother.getBackwardFilteredState();
00194   fbackfilter << t << '\t';
00195   outputVector(fbackfilter, pred.getExpectation());
00196   fbackfilter << '\t';
00197   outputMatrix(fbackfilter, pred.getCovariance());
00198   fbackfilter << endl;
00199 
00200   outputs.pop();
00201   filteredStates.pop();
00202 
00203   for (t = STEPS - 1; t >= 1; t--) {
00204     smoother.smooth(t, outputs.top(), filteredStates.top());
00205     outputs.pop();
00206     filteredStates.pop();
00207 
00208     cerr << t << ' ';
00209 
00210     /* output backward filtered state */
00211     pred = smoother.getBackwardFilteredState();
00212     fbackfilter << t << '\t';
00213     outputVector(fbackfilter, pred.getExpectation());
00214     fbackfilter << '\t';
00215     outputMatrix(fbackfilter, pred.getCovariance());
00216     fbackfilter << endl;
00217 
00218     /* output smoothed state */
00219     pred = smoother.getSmoothedState();
00220     fsmooth << t << '\t';
00221     outputVector(fsmooth, pred.getExpectation());
00222     fsmooth << '\t';
00223     outputMatrix(fsmooth, pred.getCovariance());
00224     fsmooth << endl;
00225   }
00226 
00227   fmeas.close();
00228   factual.close();
00229   ffilter.close();
00230   fbackfilter.close();
00231   fsmooth.close();
00232 
00233   return 0;
00234 }
00235 
00236 void outputVector(ofstream& out, aux::vector vec) {
00237   aux::vector::iterator iter, end;
00238   iter = vec.begin();
00239   end = vec.end();
00240   while (iter != end) {
00241     out << *iter;
00242     iter++;
00243     if (iter != end) {
00244       out << '\t';
00245     }
00246   }
00247 }
00248 
00249 void outputMatrix(ofstream& out, aux::matrix mat) {
00250   unsigned int i, j;
00251   for (j = 0; j < mat.size2(); j++) {
00252     for (i = 0; i < mat.size1(); i++) {
00253       out << mat(i,j);
00254       if (i != mat.size1() - 1 || j != mat.size2() - 1) {
00255   out << '\t';
00256       }
00257     }
00258   }
00259 }

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