48 const bayes::CParticleFilter::TParticleFilterOptions &opts,
51 averageMap( mapsInitializers ),
52 averageMapIsUpdated(false),
58 m_particles.resize( opts.sampleSize );
70 if (predictionOptions!=NULL)
71 options = *predictionOptions;
88 const size_t M = m_particles.size();
89 for (
size_t i=0;i<M;i++)
91 m_particles[i].log_w = 0;
93 m_particles[i].d->mapTillNow.clear();
95 m_particles[i].d->robotPath.resize(1);
96 m_particles[i].d->robotPath[0]=initialPose;
100 SF2robotPath.clear();
102 averageMapIsUpdated =
false;
107 const size_t nParts = m_particles.size(), nOldKeyframes = prevMap.
size();
108 if(nOldKeyframes == 0)
114 for (
size_t idxPart = 0; idxPart<nParts; idxPart++)
116 auto &
p = m_particles[idxPart];
119 p.d->mapTillNow.clear();
121 p.d->robotPath.resize(nOldKeyframes);
122 for (
size_t i = 0; i < nOldKeyframes; i++)
124 CPose3DPDFPtr keyframe_pose;
125 CSensoryFramePtr sfkeyframe_sf;
126 prevMap.
get(i, keyframe_pose, sfkeyframe_sf);
131 bool kf_pose_set =
false;
136 if (pdf_parts->particlesCount() == nParts)
138 kf_pose = *pdf_parts->m_particles[idxPart].d;
144 kf_pose = keyframe_pose->getMeanVal();
146 p.d->robotPath[i] = kf_pose;
147 for (
const auto &obs : *sfkeyframe_sf)
149 p.d->mapTillNow.insertObservation(&(*obs), &kf_pose);
155 SF2robotPath.
clear();
156 SF2robotPath.reserve(nOldKeyframes);
157 for (
size_t i = 0; i < nOldKeyframes; i++)
158 SF2robotPath.push_back(i);
160 averageMapIsUpdated =
false;
171 ASSERT_(m_particles[0].d->robotPath.size()>0);
172 getEstimatedPosePDFAtTime( m_particles[0].d->robotPath.size()-1, out_estimation );
178 void CMultiMetricMapPDF::getEstimatedPosePDFAtTime(
183 size_t i,
n = m_particles.size();
192 out_estimation.
m_particles[i].d.reset(
new CPose3D(m_particles[i].d->robotPath[timeStep]));
193 out_estimation.
m_particles[i].log_w = m_particles[i].log_w;
229 n =
static_cast<uint32_t>(m_particles.size());
233 out << m_particles[i].log_w << m_particles[i].d->mapTillNow;
234 m =
static_cast<uint32_t>(m_particles[i].d->robotPath.size());
237 out << m_particles[i].d->robotPath[j];
239 out << SFs << SF2robotPath;
258 SF2robotPath.clear();
260 averageMapIsUpdated =
false;
266 m_particles.resize(
n);
272 in >> m_particles[i].log_w >> m_particles[i].d->mapTillNow;
275 m_particles[i].d->robotPath.resize(m);
277 in >> m_particles[i].d->robotPath[j];
280 in >> SFs >> SF2robotPath;
292 TPose3D CMultiMetricMapPDF::getLastPose(
const size_t i,
bool &is_valid_pose)
const 294 if (i>=m_particles.size())
THROW_EXCEPTION(
"Particle index out of bounds!");
296 if (m_particles[i].d->robotPath.empty())
298 is_valid_pose =
false;
303 return *m_particles[i].d->robotPath.rbegin();
317 void CMultiMetricMapPDF::rebuildAverageMap()
319 float min_x = 1e6, max_x=-1e6, min_y = 1e6, max_y = -1e6;
322 if (averageMapIsUpdated)
328 for (part=m_particles.begin();part!=m_particles.end();++part)
330 ASSERT_( part->d->mapTillNow.m_gridMaps.size()>0 );
332 min_x =
min( min_x, part->d->mapTillNow.m_gridMaps[0]->getXMin() );
333 max_x = max( max_x, part->d->mapTillNow.m_gridMaps[0]->getXMax() );
334 min_y =
min( min_y, part->d->mapTillNow.m_gridMaps[0]->getYMin() );
335 max_y = max( max_y, part->d->mapTillNow.m_gridMaps[0]->getYMax() );
339 for (part=m_particles.begin();part!=m_particles.end();++part)
340 part->d->mapTillNow.m_gridMaps[0]->resizeGrid(min_x,max_x,min_y,max_y,0.5f,
false);
342 for (part=m_particles.begin();part!=m_particles.end();++part)
344 min_x =
min( min_x, part->d->mapTillNow.m_gridMaps[0]->getXMin() );
345 max_x = max( max_x, part->d->mapTillNow.m_gridMaps[0]->getXMax() );
346 min_y =
min( min_y, part->d->mapTillNow.m_gridMaps[0]->getYMin() );
347 max_y = max( max_y, part->d->mapTillNow.m_gridMaps[0]->getYMax() );
351 ASSERT_( averageMap.m_gridMaps.size()>0 );
352 averageMap.m_gridMaps[0]->setSize(
357 m_particles[0].d->mapTillNow.m_gridMaps[0]->getResolution(),
361 double sumLinearWeights = 0;
362 for (part=m_particles.begin();part!=m_particles.end();++part)
363 sumLinearWeights += exp( part->log_w );
366 for (part=m_particles.begin();part!=m_particles.end();++part)
368 ASSERT_(part->d->mapTillNow.m_gridMaps[0]->getSizeX() == averageMap.m_gridMaps[0]->getSizeX());
369 ASSERT_(part->d->mapTillNow.m_gridMaps[0]->getSizeY() == averageMap.m_gridMaps[0]->getSizeY());
380 std::vector<float> floatMap;
381 floatMap.resize(averageMap.m_gridMaps[0]->map.size(),0);
385 for (part=m_particles.begin();part!=m_particles.end();++part)
386 sumW+=exp(part->log_w);
390 for (part=m_particles.begin();part!=m_particles.end();++part)
399 float w = exp(part->log_w) / sumW;
401 ASSERT_( part->d->mapTillNow.m_gridMaps[0]->map.size() == floatMap.size() );
404 for (srcCell = firstSrcCell, destCell = floatMap.begin();srcCell!=lastSrcCell;srcCell++,destCell++)
405 (*destCell) +=
w * (*srcCell);
413 ASSERT_( averageMap.m_gridMaps[0]->map.size() == floatMap.size() );
415 for (srcCell=floatMap.begin();srcCell!=floatMap.end();srcCell++,destCell++)
416 *destCell = static_cast<COccupancyGridMap2D::cellType>( *srcCell );
422 averageMapIsUpdated =
true;
430 const size_t M = particlesCount();
434 getEstimatedPosePDF(*posePDF);
437 const uint32_t new_sf_id = SFs.size();
441 SF2robotPath.resize(new_sf_id+1);
442 SF2robotPath[new_sf_id] = m_particles[0].d->robotPath.size() - 1;
445 for (
size_t i=0;i<M;i++)
451 anymap = anymap || map_modified;
454 averageMapIsUpdated =
false;
461 void CMultiMetricMapPDF::getPath(
size_t i, std::deque<math::TPose3D> &out_path)
const 463 if (i>=m_particles.size())
465 out_path = m_particles[i].d->robotPath;
471 double CMultiMetricMapPDF::getCurrentEntropyOfPaths()
474 size_t N=m_particles[0].d->robotPath.size();
488 getEstimatedPosePDFAtTime(i,posePDFParts);
501 double CMultiMetricMapPDF::getCurrentJointEntropy()
503 double H_joint,H_paths,H_maps;
504 size_t i,M = m_particles.size();
508 H_paths = getCurrentEntropyOfPaths();
511 float min_x = 1e6, max_x=-1e6, min_y = 1e6, max_y = -1e6;
517 for (part=m_particles.begin();part!=m_particles.end();++part)
519 ASSERT_( part->d->mapTillNow.m_gridMaps.size()>0 );
521 min_x =
min( min_x, part->d->mapTillNow.m_gridMaps[0]->getXMin() );
522 max_x = max( max_x, part->d->mapTillNow.m_gridMaps[0]->getXMax() );
523 min_y =
min( min_y, part->d->mapTillNow.m_gridMaps[0]->getYMin() );
524 max_y = max( max_y, part->d->mapTillNow.m_gridMaps[0]->getYMax() );
528 for (part=m_particles.begin();part!=m_particles.end();++part)
529 part->d->mapTillNow.m_gridMaps[0]->resizeGrid(min_x,max_x,min_y,max_y,0.5f,
false);
533 double sumLinearWeights = 0;
535 sumLinearWeights += exp(m_particles[i].log_w);
542 ASSERT_( m_particles[i].d->mapTillNow.m_gridMaps.size()>0 );
544 m_particles[i].d->mapTillNow.m_gridMaps[0]->computeEntropy( entropy );
545 H_maps += exp(m_particles[i].log_w) * entropy.
H / sumLinearWeights;
548 printf(
"H_paths=%e\n",H_paths);
549 printf(
"H_maps=%e\n",H_maps);
551 H_joint = H_paths + H_maps;
557 size_t i,max_i=0,
n = m_particles.size();
558 double max_w = m_particles[0].log_w;
562 if ( m_particles[i].log_w > max_w )
564 max_w = m_particles[i].log_w;
570 return &m_particles[max_i].d->mapTillNow;
576 void CMultiMetricMapPDF::updateSensoryFrameSequence()
580 CPose3DPDFPtr previousPosePDF;
581 CSensoryFramePtr dummy;
583 for (
size_t i=0;i<SFs.size();i++)
586 SFs.get(i,previousPosePDF,dummy);
589 getEstimatedPosePDFAtTime(SF2robotPath[i], posePartsPDF);
592 previousPosePDF->copyFrom( posePartsPDF );
601 void CMultiMetricMapPDF::saveCurrentPathEstimationToTextFile(
const std::string &fil )
608 for (
size_t i=0;i<it->d->robotPath.size();i++)
612 os::fprintf(f,
"%.04f %.04f %.04f %.04f %.04f %.04f ",
614 p.yaw,
p.pitch,
p.roll );
626 pfOptimalProposal_mapSelection(0),
627 ICPGlobalAlign_MinQuality(0.70f),
628 update_gridMapLikelihoodOptions(),
639 out.
printf(
"\n----------- [CMultiMetricMapPDF::TPredictionParams] ------------ \n\n");
A namespace of pseudo-random numbers genrators of diferent distributions.
FILE BASE_IMPEXP * fopen(const char *fileName, const char *mode) MRPT_NO_THROWS
An OS-independent version of fopen.
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values, timewatch, extensions to STL.
void dumpToTextStream(mrpt::utils::CStream &out) const MRPT_OVERRIDE
This method should clearly display all the contents of the structure in textual form, sending it to a CStream.
void loadFromConfigFile(const mrpt::utils::CConfigFileBase &source, const std::string §ion) MRPT_OVERRIDE
This method load the options from a ".ini"-like file or memory-stored string list.
This namespace provides a OS-independent interface to many useful functions: filenames manipulation...
This class stores a sequence of <Probabilistic Pose,SensoryFrame> pairs, thus a "metric map" can be t...
The virtual base class which provides a unified interface for all persistent objects in MRPT...
double getCovarianceEntropy() const
Compute the entropy of the estimated covariance matrix.
void dumpToTextStream(mrpt::utils::CStream &out) const MRPT_OVERRIDE
This method should clearly display all the contents of the structure in textual form, sending it to a CStream.
int BASE_IMPEXP void BASE_IMPEXP fclose(FILE *f)
An OS-independent version of fclose.
mrpt::slam::CICP::TConfigParams icp_params
ICP parameters, used only when "PF_algorithm=2" in the particle filter.
void dumpToTextStream(mrpt::utils::CStream &out) const MRPT_OVERRIDE
This method should clearly display all the contents of the structure in textual form, sending it to a CStream.
float ICPGlobalAlign_MinQuality
[prediction stage][pf optimal proposal only] If useICPGlobalAlign_withGrid=true, this is the minimum ...
#define THROW_EXCEPTION(msg)
int BASE_IMPEXP fprintf(FILE *fil, const char *format,...) MRPT_NO_THROWS MRPT_printf_format_check(2
An OS-independent version of fprintf.
IMPLEMENTS_SERIALIZABLE(CLogFileRecord_FullEval, CHolonomicLogFileRecord, mrpt::nav) IMPLEMENTS_SERIALIZABLE(CHolonomicFullEval
A set of TMetricMapInitializer structures, passed to the constructor CMultiMetricMap::CMultiMetricMap...
void clear()
Clear the contents of this container.
GLubyte GLubyte GLubyte GLubyte w
This class allows loading and storing values and vectors of different types from a configuration text...
int read_int(const std::string §ion, const std::string &name, int defaultValue, bool failIfNotFound=false) const
This base class is used to provide a unified interface to files,memory buffers,..Please see the deriv...
CParticleList m_particles
The array of particles.
double H
The target variable for absolute entropy, computed as: H(map)=Sumx,y{ -p(x,y)*ln(p(x,y)) -(1-p(x,y))*ln(1-p(x,y)) }
This base provides a set of functions for maths stuff.
#define MRPT_UNUSED_PARAM(a)
Can be used to avoid "not used parameters" warnings from the compiler.
#define MRPT_THROW_UNKNOWN_SERIALIZATION_VERSION(__V)
For use in CSerializable implementations.
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...
size_t size() const
Returns the count of pairs (pose,sensory data)
void loadFromConfigFile(const mrpt::utils::CConfigFileBase &source, const std::string §ion) MRPT_OVERRIDE
This method load the options from a ".ini"-like file or memory-stored string list.
GLsizei const GLchar ** string
mrpt::slam::TKLDParams KLD_params
Classes for 2D/3D geometry representation, both of single values and probability density distribution...
Auxiliary class used in mrpt::maps::CMultiMetricMapPDF.
void get(size_t index, mrpt::poses::CPose3DPDFPtr &out_posePDF, mrpt::obs::CSensoryFramePtr &out_SF) const
Access to the i'th pair, first one is index '0'.
#define MRPT_LOAD_CONFIG_VAR(variableName, variableType, configFileObject, sectionNameStr)
An useful macro for loading variables stored in a INI-like file under a key with the same name that t...
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
A class used to store a 2D pose, including the 2D coordinate point and a heading (phi) angle...
A class used to store a 3D pose (a 3D translation + a rotation in 3D).
static CPose3DPDFParticlesPtr Create()
#define IS_CLASS(ptrObj, class_name)
Evaluates to true if the given pointer to an object (derived from mrpt::utils::CSerializable) is of t...
The struct for passing extra simulation parameters to the prediction/update stage when running a part...
Lightweight 3D pose (three spatial coordinates, plus three angular coordinates).
void clearParticles()
Free the memory of all the particles and reset the array "m_particles" to length zero.
int pfOptimalProposal_mapSelection
[pf optimal proposal only] Only for PF algorithm=2 (Exact "pfOptimalProposal") Select the map on whic...
This class stores any customizable set of metric maps.
unsigned __int32 uint32_t
Declares a class that represents a Rao-Blackwellized set of particles for solving the SLAM problem (T...
Used for returning entropy related information.
void loadFromConfigFile(const mrpt::utils::CConfigFileBase &source, const std::string §ion) MRPT_OVERRIDE
This method load the options from a ".ini"-like file or memory-stored string list.
void clear()
Remove all stored pairs.
virtual int printf(const char *fmt,...) MRPT_printf_format_check(2
Writes a string to the stream in a textual form.
bool insertObservationsInto(mrpt::maps::CMetricMap *theMap, const mrpt::poses::CPose3D *robotPose=NULL) const
Insert all the observations in this SF into a metric map or any kind (see mrpt::maps::CMetricMap).
Declares a class that represents a Probability Density function (PDF) of a 3D pose.