32 #ifndef GRT_PARTICLE_FILTER_HEADER
33 #define GRT_PARTICLE_FILTER_HEADER
36 #include "../../Util/GRTCommon.h"
40 template<
class PARTICLE,
class SENSOR_DATA>
62 warningLog.setProceedingText(
"[WARNING ParticleFilter]");
63 errorLog.setProceedingText(
"[ERROR ParticleFilter]");
95 const PARTICLE&
operator[](
const unsigned int &i)
const {
131 this->numDeadParticles = rhs.numDeadParticles;
150 this->warningLog = rhs.warningLog;
151 this->errorLog = rhs.errorLog;
166 for(
unsigned int i=0; i<initModel.size(); i++){
167 if( initModel[i].size() != 2 ){
168 errorLog <<
"ERROR: The " << i <<
" dimension of the initModel does not have 2 dimensions!" << std::endl;
181 errorLog <<
"ERROR: Failed to init particles!" << std::endl;
227 errorLog <<
"ERROR: The particle filter has not been initialized!" << std::endl;
232 errorLog <<
"ERROR: Failed to complete preFilterUpdate!" << std::endl;
242 errorLog <<
"ERROR: Particle " << i <<
" failed prediction!" << std::endl;
249 if( !
update( *iter, data ) ){
250 errorLog <<
"ERROR: Particle " << i <<
" failed update!" << std::endl;
258 errorLog <<
"ERROR: Failed to normalize particle weights! " << std::endl;
265 errorLog <<
"ERROR: Failed to compute the final estimat!" << std::endl;
274 errorLog <<
"ERROR: Failed to resample particles!" << std::endl;
280 errorLog <<
"ERROR: Failed to complete postFilterUpdate!" << std::endl;
299 numDeadParticles = 0;
310 virtual bool reset(){
319 case INIT_MODE_UNIFORM:
322 case INIT_MODE_GAUSSIAN:
326 errorLog <<
"ERROR: Unknown initMode!" << std::endl;
368 return numDeadParticles;
486 if( estimationMode == MEAN || estimationMode == WEIGHTED_MEAN ||
487 estimationMode == ROBUST_MEAN || estimationMode == BEST_PARTICLE )
502 if( initMode == INIT_MODE_UNIFORM || initMode == INIT_MODE_GAUSSIAN )
520 if( this->initModel.size() == initModel.size() ){
534 if( this->processNoise.size() == processNoise.size() ){
548 if( this->measurementNoise.size() == measurementNoise.size() ){
563 errorLog <<
"predict( PARTICLE &p ) Prediction function not implemented! This must be implemented by the derived class!" << std::endl;
577 virtual bool update( PARTICLE &p, SENSOR_DATA &data ){
578 errorLog <<
"update( PARTICLE &p, SENSOR_DATA &data ) Update function not implemented! This must be implemented by the derived class!" << std::endl;
593 numDeadParticles = 0;
596 if( grt_isinf( iter->w ) ){
606 warningLog <<
"normalizeWeights() - Weight norm is zero!" << std::endl;
611 Float weightUpdate = 1.0 /
wNorm;
615 iter->w *= weightUpdate;
637 const unsigned int N = (
unsigned int)
x.size();
638 unsigned int bestIndex = 0;
639 unsigned int robustMeanParticleCounter = 0;
640 Float bestWeight = 0;
645 for(
unsigned int j=0; j<N; j++){
650 for(
unsigned int j=0; j<N; j++){
656 for(
unsigned int j=0; j<N; j++){
657 x[j] /= Float(numParticles);
662 for(
unsigned int j=0; j<N; j++){
666 x[j] += iter->x[j] * iter->w;
679 for(
unsigned int j=0; j<N; j++){
695 for(
unsigned int j=0; j<N; j++){
696 x[j] += iter->x[j] * iter->w;
700 robustMeanParticleCounter++;
705 for(
unsigned int j=0; j<N; j++){
721 errorLog <<
"ERROR: Unknown estimation mode!" << std::endl;
754 weights.reserve(numParticles);
762 sort(weights.begin(),weights.end(),IndexedDouble::sortIndexedDoubleByValueAscending);
763 const unsigned int numWeights = (
unsigned int)weights.size();
764 unsigned int randIndex = 0;
767 if( numWeights == 0 ){
777 cumsum[0] = weights[0].value;
778 for(
unsigned int i=1; i<numWeights; i++){
783 const unsigned int numRandomParticles = (
unsigned int) round(numParticles/100.0*10.0);
786 if( numParticles-n > numParticles-numRandomParticles){
793 for(
unsigned int i=0; i<numWeights; i++){
794 if( randValue <=
cumsum[i] ){
800 (*tempParticles)[n] =
particles[ weights[randIndex].index ];
803 PARTICLE &p = (*tempParticles)[n];
806 case INIT_MODE_UNIFORM:
809 case INIT_MODE_GAUSSIAN:
813 errorLog <<
"ERROR: Unknown initMode!" << std::endl;
855 Float
gauss(Float
x,Float mu,Float sigma){
856 return 1.0/(SQRT_TWO_PI*sigma) * exp( -
SQR(x-mu)/(2.0*
SQR(sigma)) );
870 Float
rbf(
const Float
x,
const Float mu,Float sigma,Float weight=1.0){
871 return weight * exp( -
SQR( fabs(x-mu) / sigma ) );
887 const unsigned int N = (
unsigned int)x.size();
888 for(UINT i=0; i<N; i++){
889 sum += fabs(x[i]-mu[i]);
891 return weight * exp( -
SQR(sum/sigma) );
900 Float
SQR(
const Float
x){
return x*
x; }
909 unsigned int numDeadParticles;
929 enum InitModes{INIT_MODE_UNIFORM=0,INIT_MODE_GAUSSIAN};
930 enum EstimationModes{MEAN=0,WEIGHTED_MEAN,ROBUST_MEAN,BEST_PARTICLE};
936 #endif //GRT_PARTICLE_FILTER_HEADER
Float getWeightSum() const
virtual bool update(PARTICLE &p, SENSOR_DATA &data)
bool setNormalizeWeights(const bool normWeights)
virtual bool initParticles(const UINT numParticles)
virtual bool filter(SENSOR_DATA &data)
bool setEstimationMode(const unsigned int estimationMode)
bool initialized
A flag that indicates if the filter has been initialized.
virtual bool postFilterUpdate(SENSOR_DATA &data)
VectorFloat x
The state estimation.
bool verbose
A flag that indicates if warning and info messages should be printed.
ParticleFilter & operator=(const ParticleFilter &rhs)
Float rbf(const Float x, const Float mu, Float sigma, Float weight=1.0)
bool setInitModel(const Vector< VectorFloat > initModel)
virtual bool resize(const unsigned int size)
unsigned int getStateVectorSize() const
Float rbf(const VectorFloat &x, const VectorFloat &mu, Float sigma, Float weight=1.0)
Float getRandomNumberGauss(Float mu=0.0, Float sigma=1.0)
Float robustMeanWeightDistance
The distance parameter used in the ROBUST_MEAN estimation mode.
bool setProcessNoise(const VectorFloat &processNoise)
bool setResampleThreshold(const Float resampleThreshold)
unsigned int initMode
The mode used to initialize the particles, this should be one of the InitModes enums.
Float wDotProduct
Stores the dot product of all the weights, used to test for degeneracy.
Float estimationLikelihood
The likelihood of the estimated state.
virtual bool checkForResample()
virtual ~ParticleFilter()
PARTICLE & operator()(const unsigned int &i)
unsigned int getEstimationMode() const
const PARTICLE & operator()(const unsigned int &i) const
bool getInitialized() const
ParticleFilter(const ParticleFilter &rhs)
Vector< VectorFloat > initModel
The noise model for the initial starting guess.
bool normWeights
A flag that indicates if the weights should be normalized at each filter iteration.
const PARTICLE & operator[](const unsigned int &i) const
unsigned int estimationMode
The estimation mode (used to compute the state estimation)
bool setVerbose(const bool verbose)
Vector< PARTICLE > getParticles()
unsigned int getInitMode() const
VectorFloat processNoise
The noise covariance in the system.
Vector< PARTICLE > getOldParticles()
VectorFloat cumsum
The cumulative sum Vector used for resampling the particles.
VectorFloat measurementNoise
The noise covariance in the measurement.
bool setMeasurementNoise(const VectorFloat &measurementNoise)
unsigned int getNumParticles() const
unsigned int getNumDeadParticles() const
virtual bool computeEstimate()
Float resampleThreshold
The threshold below which the particles will be resampled.
virtual bool normalizeWeights()
unsigned int numParticles
The number of particles in the filter.
Random rand
A random number generator.
Float wNorm
Stores the total weight norm value.
Float gauss(Float x, Float mu, Float sigma)
Float getRandomNumberUniform(Float minRange=0.0, Float maxRange=1.0)
Vector< PARTICLE > & particles
A reference to the current active particle Vector.
int getRandomNumberInt(int minRange, int maxRange)
Vector< PARTICLE > particleDistributionB
A Vector of particles, this will either hold the particles before or after a resample.
Float minimumWeightThreshold
Any weight below this value will not be resampled.
unsigned int stateVectorSize
The size of the state Vector (x)
VectorFloat setProcessNoise() const
virtual bool init(const unsigned int numParticles, const Vector< VectorFloat > &initModel, const VectorFloat &processNoise, const VectorFloat &measurementNoise)
Float getEstimationLikelihood() const
PARTICLE & operator[](const unsigned int &i)
bool setInitMode(const unsigned int initMode)
virtual bool predict(PARTICLE &p)
virtual bool preFilterUpdate(SENSOR_DATA &data)
VectorFloat getStateEstimation() const
Vector< PARTICLE > particleDistributionA
A Vector of particles, this will either hold the particles before or after a resample.