KernelTwoFilterSmootherHarness.cpp

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

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