Main MRPT website > C++ reference for MRPT 1.9.9
CMonteCarloLocalization2D.cpp
Go to the documentation of this file.
1 /* +------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | http://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2017, Individual contributors, see AUTHORS file |
6  | See: http://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See details in http://www.mrpt.org/License |
8  +------------------------------------------------------------------------+ */
9 
10 #include "slam-precomp.h" // Precompiled headerss
11 
13 
14 #include <mrpt/utils/CTicTac.h>
17 #include <mrpt/obs/CSensoryFrame.h>
18 
19 #include <mrpt/random.h>
20 
22 
24 
25 using namespace mrpt;
26 using namespace mrpt::bayes;
27 using namespace mrpt::poses;
28 using namespace mrpt::math;
29 using namespace mrpt::maps;
30 using namespace mrpt::obs;
31 using namespace mrpt::slam;
32 using namespace mrpt::random;
33 using namespace mrpt::utils;
34 using namespace std;
35 
37 
38 namespace mrpt
39 {
40 namespace slam
41 {
42 /** Fills out a "TPoseBin2D" variable, given a path hypotesis and (if not set to
43  * nullptr) a new pose appended at the end, using the KLD params in "options".
44  */
45 template <>
47  mrpt::slam::detail::TPoseBin2D& outBin, const TKLDParams& opts,
48  const CMonteCarloLocalization2D::CParticleDataContent* currentParticleValue,
49  const TPose3D* newPoseToBeInserted)
50 {
51  // 2D pose approx: Use the latest pose only:
52  if (newPoseToBeInserted)
53  {
54  outBin.x = round(newPoseToBeInserted->x / opts.KLD_binSize_XY);
55  outBin.y = round(newPoseToBeInserted->y / opts.KLD_binSize_XY);
56  outBin.phi = round(newPoseToBeInserted->yaw / opts.KLD_binSize_PHI);
57  }
58  else
59  {
60  ASSERT_(currentParticleValue)
61  outBin.x = round(currentParticleValue->x() / opts.KLD_binSize_XY);
62  outBin.y = round(currentParticleValue->y() / opts.KLD_binSize_XY);
63  outBin.phi = round(currentParticleValue->phi() / opts.KLD_binSize_PHI);
64  }
65 }
66 
67 /*---------------------------------------------------------------
68  ctor
69  ---------------------------------------------------------------*/
70 // Passing a "this" pointer at this moment is not a problem since it will be NOT
71 // access until the object is fully initialized
72 CMonteCarloLocalization2D::CMonteCarloLocalization2D(size_t M)
73  : m_poseParticles(M)
74 {
75  this->setLoggerName("CMonteCarloLocalization2D");
76 }
77 
78 /*---------------------------------------------------------------
79  Dtor
80  ---------------------------------------------------------------*/
83  const size_t i, bool& is_valid_pose) const
84 {
85  if (i >= m_poseParticles.m_particles.size())
86  THROW_EXCEPTION("Particle index out of bounds!");
87  is_valid_pose = true;
90 }
91 
92 /*---------------------------------------------------------------
93  PF_SLAM_computeObservationLikelihoodForParticle
94  ---------------------------------------------------------------*/
95 double
98  const size_t particleIndexForMap, const CSensoryFrame& observation,
99  const CPose3D& x) const
100 {
101  MRPT_UNUSED_PARAM(PF_options);
102  ASSERT_(
103  options.metricMap || particleIndexForMap < options.metricMaps.size())
104 
105  CMetricMap* map =
106  (options.metricMap) ? options.metricMap : // All particles, one map
107  options.metricMaps[particleIndexForMap]; // One map per particle
108 
109  // For each observation:
110  double ret = 1;
111  for (CSensoryFrame::const_iterator it = observation.begin();
112  it != observation.end(); ++it)
113  ret += map->computeObservationLikelihood(
114  it->get(), x); // Compute the likelihood:
115 
116  // Done!
117  return ret;
118 }
119 
120 // Specialization for my kind of particles:
123  CPose2D* particleData, const TPose3D& newPose) const
124 {
125  *particleData = CPose2D(TPose2D(newPose));
126 }
127 
129  CParticleList& old_particles, const vector<TPose3D>& newParticles,
130  const vector<double>& newParticlesWeight,
131  const vector<size_t>& newParticlesDerivedFromIdx) const
132 {
133  MRPT_UNUSED_PARAM(newParticlesDerivedFromIdx);
135  size_t(newParticlesWeight.size()), size_t(newParticles.size()));
136 
137  // ---------------------------------------------------------------------------------
138  // Substitute old by new particle set:
139  // Old are in "m_particles"
140  // New are in "newParticles",
141  // "newParticlesWeight","newParticlesDerivedFromIdx"
142  // ---------------------------------------------------------------------------------
143  // Free old m_particles: not needed since "d" is now a smart ptr
144 
145  // Copy into "m_particles"
146  const size_t N = newParticles.size();
147  old_particles.resize(N);
148  for (size_t i = 0; i < N; i++)
149  {
150  old_particles[i].log_w = newParticlesWeight[i];
151  old_particles[i].d.reset(new CPose2D(TPose2D(newParticles[i])));
152  }
153 }
154 
156  COccupancyGridMap2D* theMap, const double freeCellsThreshold,
157  const int particlesCount, const double x_min, const double x_max,
158  const double y_min, const double y_max, const double phi_min,
159  const double phi_max)
160 {
161  MRPT_START
162 
163  ASSERT_(theMap != nullptr)
164 
165  int sizeX = theMap->getSizeX();
166  int sizeY = theMap->getSizeY();
167  double gridRes = theMap->getResolution();
168  std::vector<double> freeCells_x, freeCells_y;
169  size_t nFreeCells;
170  unsigned int xIdx1, xIdx2;
171  unsigned int yIdx1, yIdx2;
172 
173  freeCells_x.reserve(sizeX * sizeY);
174  freeCells_y.reserve(sizeX * sizeY);
175 
176  if (x_min > theMap->getXMin())
177  xIdx1 = max(0, theMap->x2idx(x_min));
178  else
179  xIdx1 = 0;
180  if (x_max < theMap->getXMax())
181  xIdx2 = min(sizeX - 1, theMap->x2idx(x_max));
182  else
183  xIdx2 = sizeX - 1;
184  if (y_min > theMap->getYMin())
185  yIdx1 = max(0, theMap->y2idx(y_min));
186  else
187  yIdx1 = 0;
188  if (y_max < theMap->getYMax())
189  yIdx2 = min(sizeY - 1, theMap->y2idx(y_max));
190  else
191  yIdx2 = sizeY - 1;
192 
193  for (unsigned int x = xIdx1; x <= xIdx2; x++)
194  for (unsigned int y = yIdx1; y <= yIdx2; y++)
195  if (theMap->getCell(x, y) >= freeCellsThreshold)
196  {
197  freeCells_x.push_back(theMap->idx2x(x));
198  freeCells_y.push_back(theMap->idx2y(y));
199  }
200 
201  nFreeCells = freeCells_x.size();
202 
203  // Assure that map is not fully occupied!
204  ASSERT_(nFreeCells);
205 
206  if (particlesCount > 0)
207  {
209  m_poseParticles.m_particles.resize(particlesCount);
210  for (int i = 0; i < particlesCount; i++)
211  m_poseParticles.m_particles[i].d.reset(new CPose2D());
212  }
213 
214  const size_t M = m_poseParticles.m_particles.size();
215 
216  // Generate pose m_particles:
217  for (size_t i = 0; i < M; i++)
218  {
219  int idx =
220  round(getRandomGenerator().drawUniform(0.0, nFreeCells - 1.001));
221 
223  freeCells_x[idx] +
224  getRandomGenerator().drawUniform(-gridRes, gridRes));
226  freeCells_y[idx] +
227  getRandomGenerator().drawUniform(-gridRes, gridRes));
228  m_poseParticles.m_particles[i].d->phi(
229  getRandomGenerator().drawUniform(phi_min, phi_max));
230  m_poseParticles.m_particles[i].log_w = 0;
231  }
232 
233  MRPT_END
234 }
235 
238  const mrpt::obs::CActionCollection* action,
239  const mrpt::obs::CSensoryFrame* observation,
242 {
243  switch (PF_algorithm)
244  {
245  case CParticleFilter::pfStandardProposal:
246  pf.executeOn<
248  *this, action, observation, stats);
249  break;
250  case CParticleFilter::pfAuxiliaryPFStandard:
251  pf.executeOn<
253  *this, action, observation, stats);
254  break;
255  case CParticleFilter::pfAuxiliaryPFOptimal:
256  pf.executeOn<
258  *this, action, observation, stats);
259  break;
260  default:
261  {
262  THROW_EXCEPTION("Invalid particle filter algorithm selection!");
263  }
264  break;
265  }
266 }
267 }
268 }
#define ASSERT_EQUAL_(__A, __B)
A namespace of pseudo-random numbers genrators of diferent distributions.
float getYMin() const
Returns the "y" coordinate of top side of grid map.
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values, timewatch, extensions to STL.
#define min(a, b)
float getResolution() const
Returns the resolution of the grid map.
mrpt::poses::CPosePDFParticles::CParticleDataContent CParticleDataContent
The namespace for Bayesian filtering algorithm: different particle filters and Kalman filter algorith...
#define THROW_EXCEPTION(msg)
double x
X,Y,Z, coords.
Option set for KLD algorithm.
Definition: TKLDParams.h:20
TMonteCarloLocalizationParams options
MCL parameters.
STL namespace.
void clear()
Free all the memory associated to m_particles, and set the number of parts = 0.
mrpt::maps::TMetricMapList metricMaps
[update stage] Alternative way (if metricMap==nullptr): A metric map is supplied for each particle: T...
double yaw
Yaw coordinate (rotation angle over Z axis).
A generic implementation of the PF method "pfStandardProposal" (standard proposal distribution...
Statistics for being returned from the "execute" method.
mrpt::maps::CMetricMap * metricMap
[update stage] Must be set to a metric map used to estimate the likelihood of observations ...
Declares a class for storing a collection of robot actions.
const_iterator begin() const
Returns a constant iterator to the first observation: this is an example of usage: ...
void resetUniformFreeSpace(mrpt::maps::COccupancyGridMap2D *theMap, const double freeCellsThreshold=0.7, const int particlesCount=-1, const double x_min=-1e10f, const double x_max=1e10f, const double y_min=-1e10f, const double y_max=1e10f, const double phi_min=-M_PI, const double phi_max=M_PI)
Reset the PDF to an uniformly distributed one, but only in the free-space of a given 2D occupancy-gri...
CParticleList m_particles
The array of particles.
This base provides a set of functions for maths stuff.
Definition: CArrayNumeric.h:19
void PF_SLAM_implementation_replaceByNewParticleSet(CParticleList &old_particles, const std::vector< mrpt::math::TPose3D > &newParticles, const std::vector< double > &newParticlesWeight, const std::vector< size_t > &newParticlesDerivedFromIdx) const override
#define MRPT_END
float getXMin() const
Returns the "x" coordinate of left side of grid map.
#define MRPT_UNUSED_PARAM(a)
Can be used to avoid "not used parameters" warnings from the compiler.
float idx2x(const size_t cx) const
Transform a cell index into a coordinate value.
This namespace contains representation of robot actions and observations.
Declares a class for storing a "sensory frame", a set of "observations" taken by the robot approximat...
Definition: CSensoryFrame.h:54
unsigned int getSizeX() const
Returns the horizontal size of grid map in cells count.
double KLD_binSize_XY
Parameters for the KLD adaptive sample size algorithm (see Dieter Fox&#39;s papers), which is used only i...
Definition: TKLDParams.h:35
This class acts as a common interface to the different interfaces (see CParticleFilter::TParticleFilt...
Classes for 2D/3D geometry representation, both of single values and probability density distribution...
Definition: CPoint.h:17
double PF_SLAM_computeObservationLikelihoodForParticle(const mrpt::bayes::CParticleFilter::TParticleFilterOptions &PF_options, const size_t particleIndexForMap, const mrpt::obs::CSensoryFrame &observation, const mrpt::poses::CPose3D &x) const override
Evaluate the observation likelihood for one particle at a given location.
mrpt::poses::CPosePDFParticles m_poseParticles
mrpt::math::TPose3D getLastPose(const size_t i, bool &is_valid_pose) const override
Return the robot pose for the i&#39;th particle.
Auxiliary structure used in KLD-sampling in particle filters.
A class for storing an occupancy grid map.
#define MRPT_START
void executeOn(PARTICLEFILTERCAPABLE &obj, const mrpt::obs::CActionCollection *action, const mrpt::obs::CSensoryFrame *observation, TParticleFilterStats *stats=nullptr)
Executes a complete prediction + update step of the selected particle filtering algorithm.
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
#define ASSERTDEB_(f)
Defines an assertion mechanism - only when compiled in debug.
TParticleFilterAlgorithm
Defines different types of particle filter algorithms.
Declares a virtual base class for all metric maps storage classes.
Definition: CMetricMap.h:55
A class used to store a 2D pose, including the 2D coordinate point and a heading (phi) angle...
Definition: CPose2D.h:40
A class used to store a 3D pose (a 3D translation + a rotation in 3D).
Definition: CPose3D.h:88
The configuration of a particle filter.
Lightweight 3D pose (three spatial coordinates, plus three angular coordinates).
Lightweight 2D pose.
std::deque< CObservation::Ptr >::const_iterator const_iterator
You can use CSensoryFrame::begin to get a iterator to the first element.
#define ASSERT_(f)
float idx2y(const size_t cy) const
int round(const T value)
Returns the closer integer (int) to x.
Definition: round.h:25
void KLF_loadBinFromParticle(mrpt::slam::detail::TPoseBin2D &outBin, const TKLDParams &opts, const CMonteCarloLocalization2D::CParticleDataContent *currentParticleValue, const TPose3D *newPoseToBeInserted)
Fills out a "TPoseBin2D" variable, given a path hypotesis and (if not set to nullptr) a new pose appe...
void PF_SLAM_implementation_custom_update_particle_with_new_pose(CParticleDataContent *particleData, const mrpt::math::TPose3D &newPose) const override
GLenum GLint GLint y
Definition: glext.h:3538
GLenum GLint x
Definition: glext.h:3538
const_iterator end() const
Returns a constant iterator to the end of the list of observations: this is an example of usage: ...
unsigned int getSizeY() const
Returns the vertical size of grid map in cells count.
CRandomGenerator & getRandomGenerator()
A static instance of a CRandomGenerator class, for use in single-thread applications.
int x2idx(float x) const
Transform a coordinate value into a cell index.
void executeOn(mrpt::bayes::CParticleFilter &pf, const mrpt::obs::CActionCollection *action, const mrpt::obs::CSensoryFrame *observation, mrpt::bayes::CParticleFilter::TParticleFilterStats *stats, mrpt::bayes::CParticleFilter::TParticleFilterAlgorithm PF_algorithm)
float getCell(int x, int y) const
Read the real valued [0,1] contents of a cell, given its index.
mrpt::poses::CPosePDFParticles::CParticleList CParticleList



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: ae4571287 Thu Nov 23 00:06:53 2017 +0100 at dom oct 27 23:51:55 CET 2019