KernelForwardBackwardSmootherHarness.cpp

Go to the documentation of this file.
00001 #include "indii/ml/filter/KernelForwardBackwardSmoother.hpp"
00002 #include "indii/ml/filter/ParticleFilter.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 #define H aux::hopt(SYSTEM_SIZE, P)
00022 
00023 using namespace std;
00024 using namespace indii::ml::filter;
00025 
00026 namespace aux = indii::ml::aux;
00027 
00028 /**
00029  * @file KernelForwardBackwardSmootherHarness.cpp
00030  *
00031  * Basic test of KernelForwardBackwardSmoother.
00032  *
00033  * Results are output into files as follows:
00034  *
00035  * @section actualPS results/KernelForwardBackwardSmootherHarness_actual.out
00036  *
00037  * Actual state of the robot at each time. Columns are as follows:
00038  *
00039  * @li time
00040  * @li x coordinate
00041  * @li y coordinate
00042  * @li orientation (radians)
00043  *
00044  * @section measPS results/KernelForwardBackwardSmootherHarness_meas.out
00045  * 
00046  * Measurement at each time step. Columns are as follows:
00047  *
00048  * @li time
00049  * @li measurement
00050  *
00051  * @section filterPS results/KernelForwardBackwardSmootherHarness_filter.out
00052  *
00053  * Predicted state at each time step. Columns are as follows:
00054  *
00055  * @li time
00056  * @li mean x coordinate
00057  * @li mean y coordinate
00058  * @li mean orientation
00059  * @li The remaining columns give the covariance matrix between the above
00060  * state variables.
00061  *
00062  * @section smoothPS results/KernelForwardBackwardSmootherHarness_smooth.out
00063  *
00064  * Predicted state (smoothed) at each time step. Columns are as follows:
00065  *
00066  * @li time
00067  * @li mean x coordinate
00068  * @li mean y coordinate
00069  * @li mean orientation
00070  * @li The remaining columns give the covariance matrix between the above
00071  * state variables.
00072  *
00073  * Note that as the smoothing is performed in a backwards pass, this file has
00074  * entries in reverse time order.
00075  *
00076  * @section resultsPS Results
00077  *
00078  * Results are as follows:
00079  *
00080  * \image html KernelForwardBackwardSmootherHarness.png "Results"
00081  * \image latex KernelForwardBackwardSmootherHarness.eps "Results"
00082  */
00083 
00084 void outputVector(ofstream& out, aux::vector vec);
00085 
00086 void outputMatrix(ofstream& out, aux::matrix mat);
00087 
00088 /**
00089  * Run tests
00090  */
00091 int main(int argc, char* argv[]) {
00092   boost::mpi::environment env(argc, argv);
00093   boost::mpi::communicator world;
00094   const unsigned int rank = world.rank();
00095   const unsigned int size = world.size();
00096 
00097   aux::Random::seed(rank);
00098 
00099   /* set up robot simulator */
00100   MobileRobot robot(0.1, 5e-3);
00101 
00102   /* define model */
00103   MobileRobotParticleFilterModel model(0.1, 5e-3);
00104   aux::GaussianPdf prior(model.suggestPrior());
00105   aux::DiracMixturePdf x0(prior, P / size);
00106 
00107   /* create filter */
00108   ParticleFilter<> filter(&model, x0);
00109   StratifiedParticleResampler resampler(P);
00110 
00111   /* estimate and output results */
00112   stack<aux::DiracMixturePdf> filteredStates;
00113   stack<aux::DiracMixturePdf> incrementFilteredStates;
00114   stack<bool> resamples;
00115 
00116   aux::vector meas(MEAS_SIZE);
00117   aux::vector actual(ACTUAL_SIZE);
00118   aux::DiracMixturePdf pred(SYSTEM_SIZE);
00119   unsigned int t = 0;
00120 
00121   ofstream fmeas("results/KernelForwardBackwardSmootherHarness_meas.out");
00122   ofstream factual("results/KernelForwardBackwardSmootherHarness_actual.out");
00123   ofstream ffilter("results/KernelForwardBackwardSmootherHarness_filter.out");
00124   ofstream fsmooth("results/KernelForwardBackwardSmootherHarness_smooth.out");
00125 
00126   aux::vector mu(SYSTEM_SIZE);
00127   aux::symmetric_matrix sigma(SYSTEM_SIZE);
00128 
00129   /* output initial state */
00130   pred = filter.getFilteredState();
00131   actual = robot.getState();
00132   mu = pred.getDistributedExpectation();
00133   sigma = pred.getDistributedCovariance();
00134 
00135   if (rank == 0) {
00136     cerr << t << ' ';
00137 
00138     factual << t << '\t';
00139     outputVector(factual, actual);
00140     factual << endl;
00141 
00142     ffilter << t << '\t';
00143     outputVector(ffilter, mu);
00144     ffilter << '\t';
00145     outputMatrix(ffilter, sigma);
00146     ffilter << endl;
00147   }
00148 
00149   for (t = 1; t <= T; t++) {
00150     if (rank == 0) {
00151       robot.move();
00152       meas = robot.measure();
00153     }
00154     boost::mpi::broadcast(world, meas, 0);
00155 
00156     if (filter.getFilteredState().calculateDistributedEss() < 0.8*P) {
00157       filter.resample(&resampler);
00158       resamples.push(true);
00159     } else {
00160       resamples.push(false);
00161     }
00162 
00163     filter.filter(t);
00164     incrementFilteredStates.push(filter.getFilteredState());
00165     filter.filter(meas);
00166     filteredStates.push(filter.getFilteredState());
00167 
00168     pred = filter.getFilteredState();    
00169     actual = robot.getState();
00170     mu = pred.getDistributedExpectation();
00171     sigma = pred.getDistributedCovariance();
00172 
00173     if (rank == 0) {
00174       cerr << t << ' ';
00175 
00176       /* output measurement */
00177       fmeas << t << '\t';
00178       outputVector(fmeas, meas);
00179       fmeas << endl;
00180 
00181       /* output actual state */
00182       factual << t << '\t';
00183       outputVector(factual, actual);
00184       factual << endl;
00185 
00186       /* output filtered state */
00187       ffilter << t << '\t';
00188       outputVector(ffilter, mu);
00189       ffilter << '\t';
00190       outputMatrix(ffilter, sigma);
00191       ffilter << endl;
00192     }
00193   }
00194 
00195   /* smooth */
00196   t--;
00197   pred = filter.getFilteredState();
00198   
00199   aux::Almost2Norm N;
00200   aux::AlmostGaussianKernel K(SYSTEM_SIZE, H);
00201   KernelForwardBackwardSmoother<> smoother(&model, N, K, t, pred);
00202   
00203   mu = pred.getDistributedExpectation();
00204   sigma = pred.getDistributedCovariance();
00205   unsigned int flags;
00206 
00207   if (rank == 0) {
00208     cerr << t << ' ';
00209 
00210     fsmooth << t << '\t';
00211     outputVector(fsmooth, mu);
00212     fsmooth << '\t';
00213     outputMatrix(fsmooth, sigma);
00214     fsmooth << endl;
00215   }
00216 
00217   filteredStates.pop();
00218   
00219   /* perform other steps */
00220   for (t = T - 1; t >= 1; t--) {
00221     /* optimisations */
00222     flags = NO_STANDARDISATION;
00223     if (!resamples.top()) {
00224       flags |= NO_RESAMPLING;
00225     }
00226 
00227     /* proposal */
00228     //aux::GaussianPdf q(filteredStates.top().getDistributedExpectation(),
00229     //    filteredStates.top().getDistributedCovariance());
00230 
00231     smoother.smooth(t, filteredStates.top(), incrementFilteredStates.top(),
00232         flags);
00233     
00234     incrementFilteredStates.pop();
00235     filteredStates.pop();
00236     resamples.pop();
00237 
00238     pred = smoother.getSmoothedState();
00239     mu = pred.getDistributedExpectation();
00240     sigma = pred.getDistributedCovariance();
00241 
00242     if (rank == 0) {
00243       cerr << t << ' ';
00244 
00245       /* output smoothed state */
00246       fsmooth << t << '\t';
00247       outputVector(fsmooth, mu);
00248       fsmooth << '\t';
00249       outputMatrix(fsmooth, sigma);
00250       fsmooth << endl;
00251     }
00252   }
00253 
00254   fmeas.close();
00255   factual.close();
00256   ffilter.close();
00257   fsmooth.close();
00258 
00259   return 0;
00260 }
00261 
00262 void outputVector(ofstream& out, aux::vector vec) {
00263   aux::vector::iterator iter, end;
00264   iter = vec.begin();
00265   end = vec.end();
00266   while (iter != end) {
00267     out << *iter;
00268     iter++;
00269     if (iter != end) {
00270       out << '\t';
00271     }
00272   }
00273 }
00274 
00275 void outputMatrix(ofstream& out, aux::matrix mat) {
00276   unsigned int i, j;
00277   for (j = 0; j < mat.size2(); j++) {
00278     for (i = 0; i < mat.size1(); i++) {
00279       out << mat(i,j);
00280       if (i != mat.size1() - 1 || j != mat.size2() - 1) {
00281         out << '\t';
00282       }
00283     }
00284   }
00285 }

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