RTAB-Map 0.23.10
Real-Time Appearance-Based Mapping
Loading...
Searching...
No Matches
ParticleFilter.h
1/*
2Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
3All rights reserved.
4
5Redistribution and use in source and binary forms, with or without
6modification, are permitted provided that the following conditions are met:
7 * Redistributions of source code must retain the above copyright
8 notice, this list of conditions and the following disclaimer.
9 * Redistributions in binary form must reproduce the above copyright
10 notice, this list of conditions and the following disclaimer in the
11 documentation and/or other materials provided with the distribution.
12 * Neither the name of the Universite de Sherbrooke nor the
13 names of its contributors may be used to endorse or promote products
14 derived from this software without specific prior written permission.
15
16THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
20DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*/
27
28#ifndef PARTICLEFILTER_H_
29#define PARTICLEFILTER_H_
30
33
34
35namespace rtabmap {
36
37// taken from http://www.developpez.net/forums/d544518/c-cpp/c/equivalent-randn-matlab-c/
38#define TWOPI (6.2831853071795864769252867665590057683943387987502) /* 2 * pi */
39
40/*
41 RAND is a macro which returns a pseudo-random numbers from a uniform
42 distribution on the interval [0 1]
43*/
44#define RAND (rand())/((double) RAND_MAX)
45
46/*
47 RANDN is a macro which returns a pseudo-random numbers from a normal
48 distribution with mean zero and standard deviation one. This macro uses Box
49 Muller's algorithm
50*/
51#define RANDN (sqrt(-2.0*log(RAND))*cos(TWOPI*RAND))
52
53std::vector<double> cumSum(const std::vector<double> & v)
54{
55 std::vector<double> cum(v.size());
56 double sum = 0;
57 for(unsigned int i=0; i<v.size(); ++i)
58 {
59 cum[i] = v[i] + sum;
60 sum += v[i];
61 }
62 return cum;
63}
64
65std::vector<double> resample(const std::vector<double> & p, // particles
66 const std::vector<double> & w, // weights
67 bool normalizeWeights = false)
68{
69 std::vector<double> np; //new particles
70 if(p.size() != w.size() || p.size() == 0)
71 {
72 UERROR("particles (%d) and weights (%d) are not the same size", (int)p.size(), (int)w.size());
73 return np;
74 }
75
76 std::vector<double> cs;
77 if(normalizeWeights)
78 {
79 double wSum = uSum(w);
80 std::vector<double> wNorm(w.size());
81 for(unsigned int i=0; i<w.size(); ++i)
82 {
83 wNorm[i] = w[i]/wSum;
84 }
85 cs = cumSum(wNorm); // cumulative sum
86 }
87 else
88 {
89 cs = cumSum(w); // cumulative sum
90 }
91 for(unsigned int j=0; j<cs.size(); ++j)
92 {
93 cs[j]/=cs.back();
94 }
95
96 np.resize(p.size());
97 for(unsigned int i=0; i<np.size(); ++i)
98 {
99 unsigned int index = 0;
100 double randnum = RAND;
101 for(unsigned int j=0; j<cs.size(); ++j)
102 {
103 if(randnum < cs[j])
104 {
105 index = j;
106 break;
107 }
108 }
109 np[i] = p[index];
110 }
111 return np;
112}
113
114
116{
117public:
118 ParticleFilter(unsigned int nParticles = 200,
119 double noise = 0.1,
120 double lambda = 10.0,
121 double initValue = 0.0) :
122 noise_(noise),
123 lambda_(lambda)
124 {
125 particles_.resize(nParticles, initValue);
126 }
127
128 void init(double initValue = 0.0f)
129 {
130 particles_ = std::vector<double>(particles_.size(), initValue);
131 }
132
133 double filter(double val)
134 {
135 std::vector<double> weights(particles_.size(), 1);
136 double sumWeights = 0;
137 for(unsigned int i=0; i<particles_.size(); ++i)
138 {
139 // add noise to particle
140 particles_[i] += noise_ * RANDN;
141
142 // compute weight
143 double dist = fabs(particles_[i] - val);
144 //dist = sqrt(dist*dist);
145 double w = exp(-lambda_*dist);
146 if(uIsFinite(w) && w > 0)
147 {
148 weights[i] = w;
149 }
150 sumWeights += weights[i];
151 }
152
153
154 //normalize and compute estimated value
155 double value =0.0;
156 for(unsigned int i=0; i<weights.size(); ++i)
157 {
158 weights[i] /= sumWeights;
159 value += weights[i] * particles_[i];
160 }
161
162 //resample the particles
163 particles_ = resample(particles_, weights, false);
164
165 return value;
166 }
167
168private:
169 std::vector<double> particles_;
170 double noise_;
171 double lambda_;
172};
173
174}
175
176
177#endif /* PARTICLEFILTER_H_ */
ULogger class and convenient macros.
#define UERROR(...)
Definition ULogger.h:62
Basic mathematics functions.
T uSum(const std::list< T > &list)
Definition UMath.h:318
bool uIsFinite(const T &value)
Definition UMath.h:53