Homepage Demos Overview Downloads Tutorials Reference
Credits

ParticleFilter.h

Go to the documentation of this file.
00001 //-*-c++-*-
00002 
00003 #ifndef LOADED_ParticleFilter_h
00004 #define LOADED_ParticleFilter_h
00005 
00006 #include <vector>
00007 #include <string>
00008 
00009 #include "Particle.h"
00010 #include "ParticleShapes.h"
00011 #include "ShapePolygon.h"
00012 
00013 using namespace std;
00014 
00015 namespace DualCoding {
00016 
00017 //! ParticleFilter localizes the robot by matching local shapes against world shapes.
00018 
00019 /*! Create an instance of ParticleFilter, and set its parameters by modifying member
00020     variables such as num_particles and num_generations.  Then call its localize()
00021     method to determine the robot's location.  Subsequent calls will start with the current
00022     particle distribution unless you call uniformly_distribute() to randomize things.
00023 */
00024 
00025 class ParticleFilter {
00026 public:
00027   static const int NUM_PARTICLES = 2000;
00028   static const int NUM_GENERATIONS = 15;
00029   static const int NUM_TRIES = 5;
00030   static const float INITIAL_XY_NOISE =  100;
00031   static const float INITIAL_THETA_NOISE = 30 * M_PI/180;
00032   static const float NOISE_REDUCTION_XY = 0.85;
00033   static const float NOISE_REDUCTION_T = 0.9;
00034   static const float INFINITE_DISTANCE = 10000000;
00035   static const float STDEV = 50; 
00036   static const float ADDITION_PENALTY = 0.1;
00037   static const float PERCENT_RANDOM = 0.1;  //!< Percent of random particles in each resampling
00038   
00039   ShapeSpace &localShS;     //!< Local shape space
00040   ShapeSpace &worldShS;     //!< World shape space
00041   int numParticles;     //!< Number of particles to use
00042   int numGenerations;     //!< Maximum number of generations of resampling
00043   int numTries;       //!< Number of times to restart if no good initial guess 
00044   float noiseFactorXY;      //!< Scale of noise for translation parameters x,y
00045   float noiseFactorT;     //!< Scale of noise for rotation parameter theta
00046   Shape<PolygonData> worldBounds; //!< If valid shape, particles must lie inside it.
00047   int nlocal;       //!< Current number of local landmarks
00048   int nworld;       //!< Current number of world landmarks
00049   //! Bound box of world shapes
00050   //@{
00051   float xmin, xmax, xrange;
00052   float ymin, ymax, yrange;
00053   //@}
00054   vector<Particle> *curParticles; //!< Pointer to vector holding the current set of particles
00055   int bestIndex;      //!< Index of highest scoring particle from most recent resampling.
00056  
00057   //private:
00058   vector<Particle> *newParticles; //!< Pointer to vector where new particles are generated by resampling
00059   vector<PfRoot*> *localLms;    //!< Pointer to current vector of local landmarks
00060   vector<PfRoot*> *worldLms;    //!< Pointer to current vector of world landmarks
00061   vector<float> particleViewX;    //!< x coords of local landmarks according to the currently-selected particle
00062   vector<float> particleViewY;    //!< y coords of local landmarks according to the currently-selected particle
00063   vector<float> particleViewX2;   //!< x coords of other point of local line
00064   vector<float> particleViewY2;   //!< y coords of other point of local line
00065   vector<float> localScores;    //!< Match scores for local landmarks according to the currently-selected particle
00066   vector<int> localMatches;     //!< Index of best matching world landmark for each local landmark according to the currently-selected particle
00067 
00068 public:
00069   ParticleFilter(ShapeSpace &LocalShS, ShapeSpace &WorldShS) :
00070     localShS(LocalShS), worldShS(WorldShS),
00071     numParticles(NUM_PARTICLES),
00072     numGenerations(NUM_GENERATIONS),
00073     numTries(NUM_TRIES),
00074     noiseFactorXY(INITIAL_XY_NOISE),
00075     noiseFactorT(INITIAL_THETA_NOISE),
00076     worldBounds(),
00077     nlocal(0),
00078     nworld(0),
00079     xmin(0), xmax(0), xrange(0),
00080     ymin(0), ymax(0), yrange(0),
00081     curParticles(NULL),
00082     bestIndex(-1),
00083     newParticles(NULL),
00084     localLms(), worldLms(),
00085     particleViewX(), particleViewY(),
00086     particleViewX2(), particleViewY2(),
00087     localScores(), localMatches()
00088   {};
00089 
00090   //! Reset particle filter and restore default settings
00091   void reinitialize();
00092 
00093   //! Constrain new particles to world boundaries defined by a polygon
00094   void setWorldBounds(const Shape<PolygonData> &poly) { worldBounds = poly; }
00095 
00096   //! Invoke the particle filter: determine best match of local view to world map.  Returns index of best particle, or -1 if failure.
00097   int localize();
00098   
00099   //! Uniformly distribute particles throughout the region spanned by the world landmarks
00100   void uniformlyDistribute();
00101 
00102   //! Update the current particles when the robot moves
00103   void moveBy(float const xdelta, float const ydelta, AngPi const tdelta);
00104 
00105   //! Create two Particle vectors of length numParticles, stored in curParticles and newParticles.
00106   /*! This function is called once, automatically, by localize() to initialize the Particle vectors.
00107       It should only be called explicitly when the value of numParticles has changed.
00108   */
00109   void makeParticles();
00110 
00111   //private:
00112 
00113   //! Load the local and world landmarks from their shape spaces, and create or resize particles if necessary.
00114   void loadLms();
00115 
00116   //! Set the size of each Particle's addLocal vector to nlocal, and resize some internal vectors
00117   void resizeParticles();
00118 
00119   //! Set new Particle i to random dx, dy, and theta values.  Called by uniformlyDistribute().
00120   void randomizeNewParticle(int const i);
00121 
00122   //! Check particle scores, and randomize and repeat if no particle is close to a solution
00123   void getInitialGuess();
00124 
00125   //! Calculate the score for each Particle p, leaving it in p.prob
00126   void computeParticleScores();
00127 
00128   //! Set up particleView vectors based on the parameters of the i-th Particle
00129   void setParticleView(int const i);
00130   
00131   //! Match each local landmark against the world landmarks
00132   void computeLocalMatch(int const i, int const j);
00133 
00134   static float distanceFromLine(coordinate_t x, coordinate_t y, PfLine &wline);
00135 
00136   //! Generate newParticles from curParticles, then swap the two vectors and compute scores.
00137   void resample();
00138   
00139   void spawnInto(int const i, int const j);
00140 
00141   void determineAdditions(int const i);
00142 
00143   // void determineDeletions(int const i);
00144   
00145 public:
00146   static inline float normpdf(float const distsq) { return exp(-distsq/(STDEV*STDEV)); }
00147 
00148 private:
00149   ParticleFilter& operator=(const ParticleFilter&); //!< don't call this
00150   ParticleFilter(const ParticleFilter&); //!< don't call this
00151 
00152 };
00153 
00154 
00155 
00156 } // namespace
00157 
00158 #endif
00159 

DualCoding 3.0beta
Generated Wed Oct 4 00:01:54 2006 by Doxygen 1.4.7