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
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef PARTICLEFILTER_H_
00029 #define PARTICLEFILTER_H_
00030
00031 #include <rtabmap/utilite/UMath.h>
00032 #include <rtabmap/utilite/ULogger.h>
00033
00034
00035 namespace rtabmap {
00036
00037
00038 #define TWOPI (6.2831853071795864769252867665590057683943387987502)
00039
00040
00041
00042
00043
00044 #define RAND (rand())/((double) RAND_MAX)
00045
00046
00047
00048
00049
00050
00051 #define RANDN (sqrt(-2.0*log(RAND))*cos(TWOPI*RAND))
00052
00053 std::vector<double> cumSum(const std::vector<double> & v)
00054 {
00055 std::vector<double> cum(v.size());
00056 double sum = 0;
00057 for(unsigned int i=0; i<v.size(); ++i)
00058 {
00059 cum[i] = v[i] + sum;
00060 sum += v[i];
00061 }
00062 return cum;
00063 }
00064
00065 std::vector<double> resample(const std::vector<double> & p,
00066 const std::vector<double> & w,
00067 bool normalizeWeights = false)
00068 {
00069 std::vector<double> np;
00070 if(p.size() != w.size() || p.size() == 0)
00071 {
00072 UERROR("particles (%d) and weights (%d) are not the same size", p.size(), w.size());
00073 return np;
00074 }
00075
00076 std::vector<double> cs;
00077 if(normalizeWeights)
00078 {
00079 double wSum = uSum(w);
00080 std::vector<double> wNorm(w.size());
00081 for(unsigned int i=0; i<w.size(); ++i)
00082 {
00083 wNorm[i] = w[i]/wSum;
00084 }
00085 cs = cumSum(wNorm);
00086 }
00087 else
00088 {
00089 cs = cumSum(w);
00090 }
00091 for(unsigned int j=0; j<cs.size(); ++j)
00092 {
00093 cs[j]/=cs.back();
00094 }
00095
00096 np.resize(p.size());
00097 for(unsigned int i=0; i<np.size(); ++i)
00098 {
00099 unsigned int index = 0;
00100 double randnum = RAND;
00101 for(unsigned int j=0; j<cs.size(); ++j)
00102 {
00103 if(randnum < cs[j])
00104 {
00105 index = j;
00106 break;
00107 }
00108 }
00109 np[i] = p[index];
00110 }
00111 return np;
00112 }
00113
00114
00115 class ParticleFilter
00116 {
00117 public:
00118 ParticleFilter(unsigned int nParticles = 200,
00119 double noise = 0.1,
00120 double lambda = 10.0,
00121 double initValue = 0.0) :
00122 noise_(noise),
00123 lambda_(lambda)
00124 {
00125 particles_.resize(nParticles, initValue);
00126 }
00127
00128 void init(double initValue = 0.0f)
00129 {
00130 particles_ = std::vector<double>(particles_.size(), initValue);
00131 }
00132
00133 double filter(double val)
00134 {
00135 std::vector<double> weights(particles_.size(), 1);
00136 double sumWeights = 0;
00137 for(unsigned int i=0; i<particles_.size(); ++i)
00138 {
00139
00140 particles_[i] += noise_ * RANDN;
00141
00142
00143 double dist = fabs(particles_[i] - val);
00144
00145 double w = exp(-lambda_*dist);
00146 if(uIsFinite(w) && w > 0)
00147 {
00148 weights[i] = w;
00149 }
00150 sumWeights += weights[i];
00151 }
00152
00153
00154
00155 double value =0.0;
00156 for(unsigned int i=0; i<weights.size(); ++i)
00157 {
00158 weights[i] /= sumWeights;
00159 value += weights[i] * particles_[i];
00160 }
00161
00162
00163 particles_ = resample(particles_, weights, false);
00164
00165 return value;
00166 }
00167
00168 private:
00169 std::vector<double> particles_;
00170 double noise_;
00171 double lambda_;
00172 };
00173
00174 }
00175
00176
00177 #endif