ParticleSmootherHarness.cpp

Go to the documentation of this file.
00001 #include "indii/ml/filter/ParticleFilter.hpp"
00002 #include "indii/ml/filter/ParticleSmoother.hpp"
00003 #include "indii/ml/filter/StratifiedParticleResampler.hpp"
00004 #include "indii/ml/aux/Random.hpp"
00005 
00006 #include "MobileRobotParticleFilterModel.hpp"
00007 #include "MobileRobot.hpp"
00008 
00009 #include <math.h>
00010 #include <iostream>
00011 #include <fstream>
00012 #include <vector>
00013 #include <stack>
00014 
00015 #define SYSTEM_SIZE 2
00016 #define MEAS_SIZE 1
00017 #define ACTUAL_SIZE 3
00018 
00019 #define T 250
00020 #define P 250
00021 
00022 using namespace std;
00023 using namespace indii::ml::filter;
00024 
00025 namespace aux = indii::ml::aux;
00026 
00027 /**
00028  * @file ParticleSmootherHarness.cpp
00029  *
00030  * Basic test of ParticleSmoother.
00031  *
00032  * Results are output into files as follows:
00033  *
00034  * @section actualPS results/ParticleSmootherHarness_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 measPS results/ParticleSmootherHarness_meas.out
00044  * 
00045  * Measurement at each time step. Columns are as follows:
00046  *
00047  * @li time
00048  * @li measurement
00049  *
00050  * @section filterPS results/ParticleSmootherHarness_filter.out
00051  *
00052  * Predicted state 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 smoothPS results/ParticleSmootherHarness_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 resultsPS Results
00076  *
00077  * Results are as follows:
00078  *
00079  * \image html ParticleSmootherHarness.png "Results"
00080  * \image latex ParticleSmootherHarness.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, char* argv[]) {
00091   boost::mpi::environment env(argc, argv);
00092   boost::mpi::communicator world;
00093   const unsigned int rank = world.rank();
00094   const unsigned int size = world.size();
00095 
00096   aux::Random::seed(rank);
00097 
00098   /* set up robot simulator */
00099   MobileRobot robot(0.1, 5.0e-3);
00100 
00101   /* define model */
00102   MobileRobotParticleFilterModel model(0.1, 5.0e-3);
00103   aux::GaussianPdf prior(model.suggestPrior());
00104   aux::DiracMixturePdf x0(prior, P / size);
00105 
00106   /* create filter */
00107   ParticleFilter<unsigned int> filter(&model, x0);
00108 
00109   /* create resampler */
00110   StratifiedParticleResampler resampler(P);
00111 
00112   /* estimate and output results */
00113   stack<aux::DiracMixturePdf> filteredStates;
00114   aux::vector meas(MEAS_SIZE);
00115   aux::vector actual(ACTUAL_SIZE);
00116   aux::DiracMixturePdf pred(SYSTEM_SIZE);
00117   unsigned int t = 0;
00118 
00119   ofstream fmeas("results/ParticleSmootherHarness_meas.out");
00120   ofstream factual("results/ParticleSmootherHarness_actual.out");
00121   ofstream ffilter("results/ParticleSmootherHarness_filter.out");
00122   ofstream fsmooth("results/ParticleSmootherHarness_smooth.out");
00123 
00124   aux::vector mu(SYSTEM_SIZE);
00125   aux::symmetric_matrix sigma(SYSTEM_SIZE);
00126 
00127   /* output initial state */
00128   pred = filter.getFilteredState();
00129   actual = robot.getState();
00130   mu = pred.getDistributedExpectation();
00131   sigma = pred.getDistributedCovariance();
00132 
00133   if (rank == 0) {
00134     cerr << t << ' ';
00135 
00136     factual << t << '\t';
00137     outputVector(factual, actual);
00138     factual << endl;
00139 
00140     ffilter << t << '\t';
00141     outputVector(ffilter, mu);
00142     ffilter << '\t';
00143     outputMatrix(ffilter, sigma);
00144     ffilter << endl;
00145   }
00146 
00147   for (t = 1; t <= T; t++) {
00148     if (rank == 0) {
00149       robot.move();
00150       meas = robot.measure();
00151     }
00152     boost::mpi::broadcast(world, meas, 0);
00153 
00154     if (filter.getFilteredState().calculateDistributedEss() < 0.8*P) {
00155       filter.resample(&resampler);
00156     }
00157 
00158     filter.filter(t, meas);
00159     
00160     pred = filter.getFilteredState();
00161     actual = robot.getState();
00162     mu = pred.getDistributedExpectation();
00163     sigma = pred.getDistributedCovariance();
00164 
00165     filteredStates.push(pred);
00166 
00167     if (rank == 0) {
00168       cerr << t << ' ';
00169 
00170       /* output measurement */
00171       fmeas << t << '\t';
00172       outputVector(fmeas, meas);
00173       fmeas << endl;
00174 
00175       /* output actual state */
00176       factual << t << '\t';
00177       outputVector(factual, actual);
00178       factual << endl;
00179 
00180       /* output filtered state */
00181       ffilter << t << '\t';
00182       outputVector(ffilter, mu);
00183       ffilter << '\t';
00184       outputMatrix(ffilter, sigma);
00185       ffilter << endl;
00186     }
00187   }
00188 
00189   /* smooth */
00190   t--;
00191   pred = filter.getFilteredState();
00192   ParticleSmoother<unsigned int> smoother(&model, t, pred);
00193 
00194   mu = pred.getDistributedExpectation();
00195   sigma = pred.getDistributedCovariance();
00196 
00197   if (rank == 0) {
00198     cerr << t << ' ';
00199 
00200     fsmooth << t << '\t';
00201     outputVector(fsmooth, mu);
00202     fsmooth << '\t';
00203     outputMatrix(fsmooth, sigma);
00204     fsmooth << endl;
00205   }
00206   filteredStates.pop();
00207 
00208   for (t = T - 1; t >= 1; t--) {
00209     smoother.smooth(t, filteredStates.top());
00210     filteredStates.pop();
00211 
00212     pred = smoother.getSmoothedState();
00213     mu = pred.getDistributedExpectation();
00214     sigma = pred.getDistributedCovariance();
00215 
00216     if (rank == 0) {
00217       cerr << t << ' ';
00218 
00219       /* output smoothed state */
00220       fsmooth << t << '\t';
00221       outputVector(fsmooth, mu);
00222       fsmooth << '\t';
00223       outputMatrix(fsmooth, sigma);
00224       fsmooth << endl;
00225     }
00226   }
00227 
00228   fmeas.close();
00229   factual.close();
00230   ffilter.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