48 const bayes::CParticleFilter::TParticleFilterOptions& opts,
51 : averageMap(mapsInitializers), SFs(), SF2robotPath(), options()
53 m_particles.resize(opts.sampleSize);
54 for (
auto& m_particle : m_particles)
61 const CPose3D nullPose(0, 0, 0);
65 options = predictionOptions;
82 const size_t M = m_particles.size();
83 for (
size_t i = 0; i < M; i++)
85 m_particles[i].log_w = 0;
87 m_particles[i].d->mapTillNow.clear();
89 m_particles[i].d->robotPath.resize(1);
90 m_particles[i].d->robotPath[0] = initialPose.
asTPose();
96 averageMapIsUpdated =
false;
103 const size_t nParts = m_particles.size(), nOldKeyframes = prevMap.
size();
104 if (nOldKeyframes == 0)
110 for (
size_t idxPart = 0; idxPart < nParts; idxPart++)
112 auto& p = m_particles[idxPart];
115 p.d->mapTillNow.clear();
117 p.d->robotPath.resize(nOldKeyframes);
118 for (
size_t i = 0; i < nOldKeyframes; i++)
122 prevMap.
get(i, keyframe_pose, sfkeyframe_sf);
129 bool kf_pose_set =
false;
133 keyframe_pose.get());
135 if (pdf_parts->particlesCount() == nParts)
137 kf_pose =
CPose3D(pdf_parts->m_particles[idxPart].d);
143 kf_pose = keyframe_pose->getMeanVal();
145 p.d->robotPath[i] = kf_pose.
asTPose();
146 for (
const auto& obs : *sfkeyframe_sf)
148 p.d->mapTillNow.insertObservation(*obs, &kf_pose);
154 SF2robotPath.
clear();
155 SF2robotPath.reserve(nOldKeyframes);
156 for (
size_t i = 0; i < nOldKeyframes; i++) SF2robotPath.push_back(i);
158 averageMapIsUpdated =
false;
167 void CMultiMetricMapPDF::getEstimatedPosePDF(
170 ASSERT_(m_particles[0].d->robotPath.size() > 0);
171 getEstimatedPosePDFAtTime(
172 m_particles[0].d->robotPath.size() - 1, out_estimation);
178 void CMultiMetricMapPDF::getEstimatedPosePDFAtTime(
182 size_t i, n = m_particles.size();
189 for (i = 0; i < n; i++)
191 out_estimation.
m_particles[i].d = m_particles[i].d->robotPath[timeStep];
192 out_estimation.
m_particles[i].log_w = m_particles[i].log_w;
196 uint8_t CRBPFParticleData::serializeGetVersion()
const {
return 0; }
206 uint8_t CMultiMetricMapPDF::serializeGetVersion()
const {
return 0; }
211 out.WriteAs<uint32_t>(m_particles.size());
212 for (
const auto& part : m_particles)
215 out << part.d->mapTillNow;
216 out.WriteAs<uint32_t>(part.d->robotPath.size());
217 for (
const auto& p : part.d->robotPath)
out << p;
219 out << SFs << SF2robotPath;
222 void CMultiMetricMapPDF::serializeFrom(
235 SF2robotPath.clear();
237 averageMapIsUpdated =
false;
243 m_particles.resize(n);
244 for (i = 0; i < n; i++)
249 in >> m_particles[i].log_w >> m_particles[i].d->mapTillNow;
252 m_particles[i].d->robotPath.resize(m);
253 for (j = 0; j < m; j++) in >> m_particles[i].d->robotPath[j];
256 in >> SFs >> SF2robotPath;
265 const size_t i,
bool& is_valid_pose)
const 267 if (i >= m_particles.size())
270 if (m_particles[i].d->robotPath.empty())
272 is_valid_pose =
false;
273 return TPose3D(0, 0, 0, 0, 0, 0);
277 return *m_particles[i].d->robotPath.rbegin();
287 void CMultiMetricMapPDF::rebuildAverageMap()
289 float min_x = 1e6, max_x = -1e6, min_y = 1e6, max_y = -1e6;
291 if (averageMapIsUpdated)
return;
296 for (
auto& p : m_particles)
302 min_x = min(min_x, grid->
getXMin());
303 max_x = max(max_x, grid->getXMax());
304 min_y = min(min_y, grid->getYMin());
305 max_y = max(max_y, grid->getYMax());
309 for (
auto& p : m_particles)
312 grid->
resizeGrid(min_x, max_x, min_y, max_y, 0.5f,
false);
315 float grid_resolution = 0.1f;
316 for (
auto& p : m_particles)
321 min_x = min(min_x, grid->getXMin());
322 max_x = max(max_x, grid->getXMax());
323 min_y = min(min_y, grid->getYMin());
324 max_y = max(max_y, grid->getYMax());
330 avrg_grid->
setSize(min_x, max_x, min_y, max_y, grid_resolution, 0);
333 double sumLinearWeights = 0;
334 for (
auto& p : m_particles) sumLinearWeights += exp(p.log_w);
337 for (
auto& p : m_particles)
340 ASSERT_(grid->getSizeX() == avrg_grid->getSizeX());
341 ASSERT_(grid->getSizeY() == avrg_grid->getSizeY());
352 std::vector<float> floatMap;
353 floatMap.resize(avrg_grid->map.size(), 0);
357 for (
auto& p : m_particles) sumW += exp(p.log_w);
359 if (sumW == 0) sumW = 1;
361 for (
auto& p : m_particles)
365 std::vector<COccupancyGridMap2D::cellType>::iterator srcCell;
366 auto firstSrcCell = grid->
map.begin();
367 auto lastSrcCell = grid->map.end();
368 std::vector<float>::iterator destCell;
371 float w = exp(p.log_w) / sumW;
373 ASSERT_(grid->map.size() == floatMap.size());
376 for (srcCell = firstSrcCell, destCell = floatMap.begin();
377 srcCell != lastSrcCell; srcCell++, destCell++)
378 (*destCell) += w * (*srcCell);
382 std::vector<float>::iterator srcCell;
383 auto destCell = avrg_grid->map.begin();
385 ASSERT_(avrg_grid->map.size() == floatMap.size());
387 for (srcCell = floatMap.begin(); srcCell != floatMap.end();
388 srcCell++, destCell++)
389 *destCell = static_cast<COccupancyGridMap2D::cellType>(*srcCell);
395 averageMapIsUpdated =
true;
403 const size_t M = particlesCount();
407 getEstimatedPosePDF(*posePDF);
410 const uint32_t new_sf_id = SFs.size();
411 SFs.insert(posePDF, CSensoryFrame::Create(sf));
412 SF2robotPath.resize(new_sf_id + 1);
413 SF2robotPath[new_sf_id] = m_particles[0].d->robotPath.size() - 1;
416 for (
size_t i = 0; i < M; i++)
422 &m_particles[i].d->mapTillNow, &robotPose);
423 anymap = anymap || map_modified;
426 averageMapIsUpdated =
false;
433 void CMultiMetricMapPDF::getPath(
434 size_t i, std::deque<math::TPose3D>& out_path)
const 437 out_path = m_particles[i].d->robotPath;
443 double CMultiMetricMapPDF::getCurrentEntropyOfPaths()
447 m_particles[0].d->robotPath.size();
456 for (i = 0; i < N; i++)
460 getEstimatedPosePDFAtTime(i, posePDFParts);
473 double CMultiMetricMapPDF::getCurrentJointEntropy()
475 double H_joint, H_paths, H_maps;
479 H_paths = getCurrentEntropyOfPaths();
481 float min_x = 1e6, max_x = -1e6, min_y = 1e6, max_y = -1e6;
484 for (
auto& p : m_particles)
489 min_x = min(min_x, grid->getXMin());
490 max_x = max(max_x, grid->getXMax());
491 min_y = min(min_y, grid->getYMin());
492 max_y = max(max_y, grid->getYMax());
496 for (
auto& p : m_particles)
499 grid->
resizeGrid(min_x, max_x, min_y, max_y, 0.5f,
false);
503 double sumLinearWeights = 0;
504 for (
auto& p : m_particles) sumLinearWeights += exp(p.log_w);
509 for (
auto& p : m_particles)
514 H_maps += exp(p.log_w) * entropy.
H / sumLinearWeights;
517 printf(
"H_paths=%e\n", H_paths);
518 printf(
"H_maps=%e\n", H_maps);
520 H_joint = H_paths + H_maps;
526 size_t i, max_i = 0, n = m_particles.size();
527 double max_w = m_particles[0].log_w;
529 for (i = 0; i < n; i++)
531 if (m_particles[i].log_w > max_w)
533 max_w = m_particles[i].log_w;
539 return &m_particles[max_i].d->mapTillNow;
545 void CMultiMetricMapPDF::updateSensoryFrameSequence()
552 for (
size_t i = 0; i < SFs.size(); i++)
555 SFs.get(i, previousPosePDF, dummy);
558 getEstimatedPosePDFAtTime(SF2robotPath[i], posePartsPDF);
561 previousPosePDF->copyFrom(posePartsPDF);
570 void CMultiMetricMapPDF::saveCurrentPathEstimationToTextFile(
571 const std::string& fil)
576 for (
auto& m_particle : m_particles)
578 for (
size_t i = 0; i < m_particle.d->robotPath.size(); i++)
583 f,
"%.04f %.04f %.04f %.04f %.04f %.04f ", p.
x, p.
y, p.
z, p.
yaw,
595 void CMultiMetricMapPDF::TPredictionParams::dumpToTextStream(
596 std::ostream&
out)
const 598 out <<
"\n----------- [CMultiMetricMapPDF::TPredictionParams] ------------ " 602 "pfOptimalProposal_mapSelection = %i\n",
603 pfOptimalProposal_mapSelection);
605 "ICPGlobalAlign_MinQuality = %f\n",
606 ICPGlobalAlign_MinQuality);
608 KLD_params.dumpToTextStream(
out);
609 icp_params.dumpToTextStream(
out);
616 void CMultiMetricMapPDF::TPredictionParams::loadFromConfigFile(
619 pfOptimalProposal_mapSelection =
iniFile.read_int(
620 section,
"pfOptimalProposal_mapSelection",
621 pfOptimalProposal_mapSelection,
true);
625 KLD_params.loadFromConfigFile(
iniFile, section);
626 icp_params.loadFromConfigFile(
iniFile, section);
A namespace of pseudo-random numbers generators of diferent distributions.
mrpt::math::TPose3D asTPose() const
void clearParticles()
Free the memory of all the particles and reset the array "m_particles" to length zero.
float getResolution() const
Returns the resolution of the grid map.
#define THROW_EXCEPTION(msg)
std::string std::string format(std::string_view fmt, ARGS &&... args)
This class stores a sequence of <Probabilistic Pose,SensoryFrame> pairs, thus a "metric map" can be t...
CParticleList m_particles
The array of particles.
int void fclose(FILE *f)
An OS-independent version of fclose.
double roll
Roll coordinate (rotation angle over X coordinate).
#define IMPLEMENTS_SERIALIZABLE(class_name, base, NameSpace)
To be added to all CSerializable-classes implementation files.
double yaw
Yaw coordinate (rotation angle over Z axis).
A set of TMetricMapInitializer structures, passed to the constructor CMultiMetricMap::CMultiMetricMap...
std::vector< cellType > map
Store of cell occupancy values.
#define MRPT_THROW_UNKNOWN_SERIALIZATION_VERSION(__V)
For use in CSerializable implementations.
#define ASSERT_(f)
Defines an assertion mechanism.
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 class allows loading and storing values and vectors of different types from a configuration text...
This base provides a set of functions for maths stuff.
float getXMin() const
Returns the "x" coordinate of left side of grid map.
This namespace contains representation of robot actions and observations.
string iniFile(myDataDir+string("benchmark-options.ini"))
Declares a class for storing a "sensory frame", a set of "observations" taken by the robot approximat...
#define IS_CLASS(obj, class_name)
True if the given reference to object (derived from mrpt::rtti::CObject) is of the given class...
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'.
Classes for 2D/3D geometry representation, both of single values and probability density distribution...
Auxiliary class used in mrpt::maps::CMultiMetricMapPDF.
double pitch
Pitch coordinate (rotation angle over Y axis).
int fprintf(FILE *fil, const char *format,...) noexcept MRPT_printf_format_check(2
An OS-independent version of fprintf.
#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...
A class for storing an occupancy grid map.
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
Virtual base class for "archives": classes abstracting I/O streams.
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).
mrpt::vision::TStereoCalibResults out
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).
double getCovarianceEntropy() const
Compute the entropy of the estimated covariance matrix.
void computeEntropy(TEntropyInfo &info) const
Computes the entropy and related values of this grid map.
FILE * fopen(const char *fileName, const char *mode) noexcept
An OS-independent version of fopen.
void resizeGrid(float new_x_min, float new_x_max, float new_y_min, float new_y_max, float new_cells_default_value=0.5f, bool additionalMargin=true) noexcept
Change the size of gridmap, maintaining previous contents.
void setSize(float x_min, float x_max, float y_min, float y_max, float resolution, float default_value=0.5f)
Change the size of gridmap, erasing all its previous contents.
This class stores any customizable set of metric maps.
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()
Clear the contents of this container.
void clear()
Remove all stored pairs.
Declares a class that represents a Probability Density function (PDF) of a 3D pose.