47 const bayes::CParticleFilter::TParticleFilterOptions& opts,
50 : averageMap(mapsInitializers),
51 averageMapIsUpdated(false),
57 m_poseParticles.m_particles.resize(opts.sampleSize);
59 it != m_poseParticles.m_particles.end(); ++it)
66 const CPose3D nullPose(0, 0, 0);
70 if (predictionOptions !=
nullptr) options = *predictionOptions;
87 const size_t M = m_poseParticles.m_particles.size();
88 for (
size_t i = 0; i < M; i++)
90 m_poseParticles.m_particles[i].log_w = 0;
92 m_poseParticles.m_particles[i].d->mapTillNow.clear();
94 m_poseParticles.m_particles[i].d->robotPath.resize(1);
95 m_poseParticles.m_particles[i].d->robotPath[0] = initialPose;
101 averageMapIsUpdated =
false;
108 const size_t nParts = m_poseParticles.m_particles.size(), nOldKeyframes = prevMap.
size();
109 if (nOldKeyframes == 0)
115 for (
size_t idxPart = 0; idxPart < nParts; idxPart++)
117 auto&
p = m_poseParticles.m_particles[idxPart];
120 p.d->mapTillNow.clear();
122 p.d->robotPath.resize(nOldKeyframes);
123 for (
size_t i = 0; i < nOldKeyframes; i++)
127 prevMap.
get(i, keyframe_pose, sfkeyframe_sf);
134 bool kf_pose_set =
false;
138 keyframe_pose.get());
140 if (pdf_parts->particlesCount() == nParts)
142 kf_pose = *pdf_parts->m_particles[idxPart].d;
148 kf_pose = keyframe_pose->getMeanVal();
150 p.d->robotPath[i] = kf_pose;
151 for (
const auto& obs : *sfkeyframe_sf)
153 p.d->mapTillNow.insertObservation(&(*obs), &kf_pose);
159 SF2robotPath.
clear();
160 SF2robotPath.reserve(nOldKeyframes);
161 for (
size_t i = 0; i < nOldKeyframes; i++) SF2robotPath.push_back(i);
163 averageMapIsUpdated =
false;
172 void CMultiMetricMapPDF::getEstimatedPosePDF(
175 ASSERT_(m_poseParticles.m_particles[0].d->robotPath.size() > 0);
176 getEstimatedPosePDFAtTime(
177 m_poseParticles.m_particles[0].d->robotPath.size() - 1, out_estimation);
183 void CMultiMetricMapPDF::getEstimatedPosePDFAtTime(
187 size_t i,
n = m_poseParticles.m_particles.size();
194 for (i = 0; i <
n; i++)
197 new CPose3D(m_poseParticles.m_particles[i].d->robotPath[timeStep]));
198 out_estimation.
m_particles[i].log_w = m_poseParticles.m_particles[i].log_w;
205 void CRBPFParticleData::writeToStream(
226 void CMultiMetricMapPDF::writeToStream(
236 n =
static_cast<uint32_t>(m_poseParticles.m_particles.size());
238 for (i = 0; i <
n; i++)
240 out << m_poseParticles.m_particles[i].log_w << m_poseParticles.m_particles[i].d->mapTillNow;
241 m =
static_cast<uint32_t>(m_poseParticles.m_particles[i].d->robotPath.size());
243 for (j = 0; j < m; j++) out << m_poseParticles.m_particles[i].d->robotPath[j];
245 out << SFs << SF2robotPath;
262 m_poseParticles.clearParticles();
264 SF2robotPath.clear();
266 averageMapIsUpdated =
false;
272 m_poseParticles.m_particles.resize(
n);
273 for (i = 0; i <
n; i++)
278 in >> m_poseParticles.m_particles[i].log_w >> m_poseParticles.m_particles[i].d->mapTillNow;
281 m_poseParticles.m_particles[i].d->robotPath.resize(m);
282 for (j = 0; j < m; j++) in >> m_poseParticles.m_particles[i].d->robotPath[j];
285 in >> SFs >> SF2robotPath;
294 const size_t i,
bool& is_valid_pose)
const 296 if (i >= m_poseParticles.m_particles.size())
299 if (m_poseParticles.m_particles[i].d->robotPath.empty())
301 is_valid_pose =
false;
302 return TPose3D(0, 0, 0, 0, 0, 0);
306 return *m_poseParticles.m_particles[i].d->robotPath.rbegin();
319 void CMultiMetricMapPDF::rebuildAverageMap()
321 float min_x = 1e6, max_x = -1e6, min_y = 1e6, max_y = -1e6;
324 if (averageMapIsUpdated)
return;
329 for (part = m_poseParticles.m_particles.begin(); part != m_poseParticles.m_particles.end(); ++part)
331 ASSERT_(part->d->mapTillNow.m_gridMaps.size() > 0);
333 min_x =
min(min_x, part->d->mapTillNow.m_gridMaps[0]->getXMin());
334 max_x = max(max_x, part->d->mapTillNow.m_gridMaps[0]->getXMax());
335 min_y =
min(min_y, part->d->mapTillNow.m_gridMaps[0]->getYMin());
336 max_y = max(max_y, part->d->mapTillNow.m_gridMaps[0]->getYMax());
340 for (part = m_poseParticles.m_particles.begin(); part != m_poseParticles.m_particles.end(); ++part)
341 part->d->mapTillNow.m_gridMaps[0]->resizeGrid(
342 min_x, max_x, min_y, max_y, 0.5f,
false);
344 for (part = m_poseParticles.m_particles.begin(); part != m_poseParticles.m_particles.end(); ++part)
346 min_x =
min(min_x, part->d->mapTillNow.m_gridMaps[0]->getXMin());
347 max_x = max(max_x, part->d->mapTillNow.m_gridMaps[0]->getXMax());
348 min_y =
min(min_y, part->d->mapTillNow.m_gridMaps[0]->getYMin());
349 max_y = max(max_y, part->d->mapTillNow.m_gridMaps[0]->getYMax());
353 ASSERT_(averageMap.m_gridMaps.size() > 0);
354 averageMap.m_gridMaps[0]->setSize(
355 min_x, max_x, min_y, max_y,
356 m_poseParticles.m_particles[0].d->mapTillNow.m_gridMaps[0]->getResolution(), 0);
359 double sumLinearWeights = 0;
360 for (part = m_poseParticles.m_particles.begin(); part != m_poseParticles.m_particles.end(); ++part)
361 sumLinearWeights += exp(part->log_w);
364 for (part = m_poseParticles.m_particles.begin(); part != m_poseParticles.m_particles.end(); ++part)
367 part->d->mapTillNow.m_gridMaps[0]->getSizeX() ==
368 averageMap.m_gridMaps[0]->getSizeX());
370 part->d->mapTillNow.m_gridMaps[0]->getSizeY() ==
371 averageMap.m_gridMaps[0]->getSizeY());
382 std::vector<float> floatMap;
383 floatMap.resize(averageMap.m_gridMaps[0]->map.size(), 0);
387 for (part = m_poseParticles.m_particles.begin(); part != m_poseParticles.m_particles.end(); ++part)
388 sumW += exp(part->log_w);
390 if (sumW == 0) sumW = 1;
392 for (part = m_poseParticles.m_particles.begin(); part != m_poseParticles.m_particles.end(); ++part)
397 part->d->mapTillNow.m_gridMaps[0]->map.begin();
399 part->d->mapTillNow.m_gridMaps[0]->map.end();
403 float w = exp(part->log_w) / sumW;
406 part->d->mapTillNow.m_gridMaps[0]->map.size() ==
410 for (srcCell = firstSrcCell, destCell = floatMap.begin();
411 srcCell != lastSrcCell; srcCell++, destCell++)
412 (*destCell) +=
w * (*srcCell);
418 averageMap.m_gridMaps[0]->map.begin();
420 ASSERT_(averageMap.m_gridMaps[0]->map.size() == floatMap.size());
422 for (srcCell = floatMap.begin(); srcCell != floatMap.end();
423 srcCell++, destCell++)
424 *destCell = static_cast<COccupancyGridMap2D::cellType>(*srcCell);
430 averageMapIsUpdated =
true;
438 const size_t M = m_poseParticles.particlesCount();
442 mrpt::make_aligned_shared<CPose3DPDFParticles>();
443 getEstimatedPosePDF(*posePDF);
446 const uint32_t new_sf_id = SFs.size();
448 SF2robotPath.resize(new_sf_id + 1);
449 SF2robotPath[new_sf_id] = m_poseParticles.m_particles[0].d->robotPath.size() - 1;
452 for (
size_t i = 0; i < M; i++)
458 &m_poseParticles.m_particles[i].d->mapTillNow, &robotPose);
459 anymap = anymap || map_modified;
462 averageMapIsUpdated =
false;
469 void CMultiMetricMapPDF::getPath(
470 size_t i, std::deque<math::TPose3D>& out_path)
const 472 if (i >= m_poseParticles.m_particles.size())
THROW_EXCEPTION(
"Index out of bounds");
473 out_path = m_poseParticles.m_particles[i].d->robotPath;
479 double CMultiMetricMapPDF::getCurrentEntropyOfPaths()
483 m_poseParticles.m_particles[0].d->robotPath.size();
492 for (i = 0; i < N; i++)
496 getEstimatedPosePDFAtTime(i, posePDFParts);
509 double CMultiMetricMapPDF::getCurrentJointEntropy()
511 double H_joint, H_paths, H_maps;
512 size_t i, M = m_poseParticles.m_particles.size();
516 H_paths = getCurrentEntropyOfPaths();
518 float min_x = 1e6, max_x = -1e6, min_y = 1e6, max_y = -1e6;
524 for (part = m_poseParticles.m_particles.begin(); part != m_poseParticles.m_particles.end(); ++part)
526 ASSERT_(part->d->mapTillNow.m_gridMaps.size() > 0);
528 min_x =
min(min_x, part->d->mapTillNow.m_gridMaps[0]->getXMin());
529 max_x = max(max_x, part->d->mapTillNow.m_gridMaps[0]->getXMax());
530 min_y =
min(min_y, part->d->mapTillNow.m_gridMaps[0]->getYMin());
531 max_y = max(max_y, part->d->mapTillNow.m_gridMaps[0]->getYMax());
535 for (part = m_poseParticles.m_particles.begin(); part != m_poseParticles.m_particles.end(); ++part)
536 part->d->mapTillNow.m_gridMaps[0]->resizeGrid(
537 min_x, max_x, min_y, max_y, 0.5f,
false);
540 double sumLinearWeights = 0;
541 for (i = 0; i < M; i++) sumLinearWeights += exp(m_poseParticles.m_particles[i].log_w);
546 for (i = 0; i < M; i++)
548 ASSERT_(m_poseParticles.m_particles[i].d->mapTillNow.m_gridMaps.size() > 0);
550 m_poseParticles.m_particles[i].d->mapTillNow.m_gridMaps[0]->computeEntropy(entropy);
551 H_maps += exp(m_poseParticles.m_particles[i].log_w) * entropy.
H / sumLinearWeights;
554 printf(
"H_paths=%e\n", H_paths);
555 printf(
"H_maps=%e\n", H_maps);
557 H_joint = H_paths + H_maps;
563 size_t i, max_i = 0,
n = m_poseParticles.m_particles.size();
564 double max_w = m_poseParticles.m_particles[0].log_w;
566 for (i = 0; i <
n; i++)
568 if (m_poseParticles.m_particles[i].log_w > max_w)
570 max_w = m_poseParticles.m_particles[i].log_w;
576 return &m_poseParticles.m_particles[max_i].d->mapTillNow;
582 void CMultiMetricMapPDF::updateSensoryFrameSequence()
589 for (
size_t i = 0; i < SFs.size(); i++)
592 SFs.get(i, previousPosePDF, dummy);
595 getEstimatedPosePDFAtTime(SF2robotPath[i], posePartsPDF);
598 previousPosePDF->copyFrom(posePartsPDF);
607 void CMultiMetricMapPDF::saveCurrentPathEstimationToTextFile(
614 it != m_poseParticles.m_particles.end(); ++it)
616 for (
size_t i = 0; i < it->d->robotPath.size(); i++)
621 f,
"%.04f %.04f %.04f %.04f %.04f %.04f ",
p.x,
p.y,
p.z,
p.yaw,
633 CMultiMetricMapPDF::TPredictionParams::TPredictionParams()
634 : pfOptimalProposal_mapSelection(0),
635 ICPGlobalAlign_MinQuality(0.70f),
636 update_gridMapLikelihoodOptions(),
649 "\n----------- [CMultiMetricMapPDF::TPredictionParams] ------------ " 653 "pfOptimalProposal_mapSelection = %i\n",
654 pfOptimalProposal_mapSelection);
656 "ICPGlobalAlign_MinQuality = %f\n",
657 ICPGlobalAlign_MinQuality);
659 KLD_params.dumpToTextStream(out);
660 icp_params.dumpToTextStream(out);
670 pfOptimalProposal_mapSelection = iniFile.
read_int(
671 section,
"pfOptimalProposal_mapSelection",
672 pfOptimalProposal_mapSelection,
true);
676 KLD_params.loadFromConfigFile(iniFile, section);
677 icp_params.loadFromConfigFile(iniFile, section);
A namespace of pseudo-random numbers genrators of diferent distributions.
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values, timewatch, extensions to STL.
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.
int void fclose(FILE *f)
An OS-independent version of fclose.
#define IMPLEMENTS_SERIALIZABLE(class_name, base, NameSpace)
This must be inserted in all CSerializable classes implementation files.
#define THROW_EXCEPTION(msg)
std::shared_ptr< CPose3DPDFParticles > Ptr
A set of TMetricMapInitializer structures, passed to the constructor CMultiMetricMap::CMultiMetricMap...
void clear()
Clear the contents of this container.
GLubyte GLubyte GLubyte GLubyte w
void loadFromConfigFile(const mrpt::utils::CConfigFileBase &source, const std::string §ion) override
This method load the options from a ".ini"-like file or memory-stored string list.
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.
std::shared_ptr< CPose3DPDF > Ptr
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...
std::shared_ptr< CSensoryFrame > Ptr
size_t size() const
Returns the count of pairs (pose,sensory data)
void get(size_t index, mrpt::poses::CPose3DPDF::Ptr &out_posePDF, mrpt::obs::CSensoryFrame::Ptr &out_SF) const
Access to the i'th pair, first one is index '0'.
GLsizei const GLchar ** string
Classes for 2D/3D geometry representation, both of single values and probability density distribution...
Auxiliary class used in mrpt::maps::CMultiMetricMapPDF.
int fprintf(FILE *fil, const char *format,...) noexcept MRPT_printf_format_check(2
An OS-independent version of fprintf.
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).
#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.
FILE * fopen(const char *fileName, const char *mode) noexcept
An OS-independent version of fopen.
void dumpToTextStream(mrpt::utils::CStream &out) const override
This method should clearly display all the contents of the structure in textual form, sending it to a CStream.
#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 class stores any customizable set of metric maps.
unsigned __int32 uint32_t
bool insertObservationsInto(mrpt::maps::CMetricMap *theMap, const mrpt::poses::CPose3D *robotPose=nullptr) 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 Rao-Blackwellized set of particles for solving the SLAM problem (T...
Used for returning entropy related information.
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.
Declares a class that represents a Probability Density function (PDF) of a 3D pose.