Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00026 #ifndef ParticleFilter_HPP
00027 #define ParticleFilter_HPP
00028
00029 #include <vector>
00030 #include <ctime>
00031 #include <cstdlib>
00032 #include <stdexcept>
00033 #include <cmath>
00034 #include "Estimation/BayesFilters/BayesFilter.hpp"
00035 #include "boost/shared_ptr.hpp"
00036
00037 #include <iostream>
00038
00039 namespace Estimation
00040 {
00041
00042 using boost::shared_ptr;
00043
00052 template<typename CMD, typename STATE>
00053 class PFCommandModel
00054 {
00055 public:
00073 virtual STATE updateState(const STATE &curState, const CMD &command) const = 0;
00074 };
00075
00085 template<typename MEAS, typename STATE>
00086 class PFMeasurementModel
00087 {
00088 public:
00101 virtual double getLikelihood(const MEAS &m, const STATE &s) = 0;
00102 };
00103
00113 template<typename CMD, typename MEAS, typename STATE>
00114 class Particle
00115 {
00116 public:
00117
00118
00120 typedef PFMeasurementModel<MEAS, STATE> MeasModelType;
00122 typedef PFCommandModel<CMD, STATE> CmdModelType;
00123
00125 Particle(const STATE &s) : m_state(s)
00126 {}
00127
00129 Particle(const Particle &p) : m_state(p.m_state), m_likelihood(p.m_likelihood)
00130 {}
00131
00143 virtual void update(const CMD &c, CmdModelType& mdl)
00144 {
00145 m_state = mdl.updateState(m_state, c);
00146 }
00147
00160 virtual double computeLikelihood(const MEAS &m, MeasModelType &mdl)
00161 {
00162 m_likelihood = mdl.getLikelihood(m, m_state);
00163 return m_likelihood;
00164 }
00165
00167 double getLikelihood() const
00168 {
00169 return m_likelihood;
00170 }
00171
00173 const STATE& getState() const
00174 {
00175 return m_state;
00176 }
00177
00178 protected:
00179 STATE m_state;
00180 double m_likelihood;
00181 };
00182
00262 template<typename CMD, typename MEAS, typename STATE>
00263 class ParticleFilter : public BayesFilter<CMD, MEAS, STATE>
00264 {
00265 public:
00266
00267
00269 typedef Particle<CMD, MEAS, STATE> ParticleType;
00271 typedef PFMeasurementModel<MEAS, STATE> MeasModelType;
00273 typedef PFCommandModel<CMD, STATE> CmdModelType;
00275 typedef STATE(*InjectionFnType)(void*);
00276
00285 ParticleFilter(unsigned nParticles=100, bool injection=false)
00286 : m_randomInjection(injection), m_injectionFunction(NULL),
00287 m_injectionArg(NULL),
00288 m_longTermRate(0.1), m_shortTermRate(0.5),
00289 m_randomPortion(0.0),
00290 m_elitism(false),
00291 m_dynamicInjection(true)
00292 {
00293 srand(static_cast<unsigned>(time(0)));
00294 setNumParticles(nParticles);
00295 }
00296
00307 virtual void initialize(const std::vector<STATE> &states);
00308
00319 inline virtual void CommandUpdate(const CMD &c)
00320 {
00321 updateParticles(c);
00322 }
00323
00335 virtual void MeasurementUpdate(const MEAS &m);
00336
00338 inline unsigned getNumParticles() const
00339 {
00340 return m_nParticles;
00341 }
00342
00344 void setNumParticles(unsigned n)
00345 {
00346 if(n == 0)
00347 {
00348 throw std::invalid_argument("Number of particles must be at least 1.");
00349 } else
00350 m_nParticles = n;
00351 }
00352
00354 inline void setMeasurementModel(shared_ptr<MeasModelType> m)
00355 {
00356 m_measModel = m;
00357 }
00358
00360 inline shared_ptr<MeasModelType> getMeasurementModel() const
00361 {
00362 return m_measModel;
00363 }
00364
00366 inline void setCommandModel(shared_ptr<CmdModelType> c)
00367 {
00368 m_cmdModel = c;
00369 }
00370
00372 inline shared_ptr<CmdModelType> getCommandModel() const
00373 {
00374 return m_cmdModel;
00375 }
00376
00378 inline bool getRandomInjection() const
00379 {
00380 return m_randomInjection;
00381 }
00382
00397 bool setRandomInjection(bool s);
00398
00416 inline void setRandomInjectionFunction(InjectionFnType fn,
00417 void* arg=NULL,
00418 bool enable=true)
00419 {
00420 m_injectionFunction = fn;
00421 m_injectionArg = arg;
00422 setRandomInjection(enable);
00423 }
00424
00433 inline InjectionFnType getRandomInjectionFunction() const
00434 {
00435 return m_injectionFunction;
00436 }
00437
00446 inline void* getRandomInjectionArgument() const
00447 {
00448 return m_injectionArg;
00449 }
00450
00458 STATE getMode() const;
00459
00460 inline virtual STATE getCurrentEstimate() const
00461 {
00462 return getMode();
00463 }
00464
00473 inline bool setFixedRandomInjectionRate(double r)
00474 {
00475 if (r > 0.0 && r < 1.0) {
00476 m_randomPortion = r;
00477 }
00478 return m_randomPortion;
00479 }
00480
00489 inline double getFixedRandomInjectionRate() const
00490 {
00491 return m_randomPortion;
00492 }
00493
00501 inline void setDynamicRandomInjection(bool enable)
00502 {
00503 m_dynamicInjection = enable;
00504 }
00505
00513 inline bool getDynamicRandomInjection() const
00514 {
00515 return m_dynamicInjection;
00516 }
00517
00527 inline double getShortTermDRIRate() const
00528 {
00529 return m_shortTermRate;
00530 }
00531
00541 inline double getLongTermDRIRate() const
00542 {
00543 return m_longTermRate;
00544 }
00545
00561 bool setDRIRates(double shortTerm, double longTerm);
00562
00570 inline void setElitism(bool enable)
00571 {
00572 m_elitism = enable;
00573 }
00574
00582 inline bool getElitism() const
00583 {
00584 return m_elitism;
00585 }
00586
00587 protected:
00595 void updateParticles(const CMD &c);
00596
00607 void computeLikelihoods(const MEAS &m);
00608
00622 void importanceSampling(int nParticles);
00623
00634 virtual void randomInjection(int nParticles);
00635
00637 double rand_d()
00638 {
00639 return static_cast<double>(rand()) / RAND_MAX;
00640 }
00641
00643 std::vector<ParticleType> m_particles;
00645 std::vector<ParticleType> m_prevParticles;
00647 shared_ptr<MeasModelType> m_measModel;
00649 shared_ptr<CmdModelType> m_cmdModel;
00651 unsigned m_nParticles;
00653 double m_totalLikelihood;
00654
00656 bool m_randomInjection;
00658 STATE (*m_injectionFunction)(void*);
00660 void* m_injectionArg;
00661
00663 double m_longTermLikelihood;
00665 double m_longTermRate;
00667 double m_shortTermLikelihood;
00669 double m_shortTermRate;
00671 double m_randomPortion;
00673 bool m_initMovingAvgs;
00675 bool m_elitism;
00677 bool m_dynamicInjection;
00678 };
00679
00680 #include "Estimation/BayesFilters/ParticleFilter/ParticleFilter_impl.hpp"
00681
00682 }
00683
00684 #endif