42 : m_parent(parent), m_log_w_metric_history()
46 m_accumRobotMovementIsValid =
false;
52 CLocalMetricHypothesis::~CLocalMetricHypothesis() { clearParticles(); }
60 void CLocalMetricHypothesis::getAs3DScene(
70 std::make_shared<opengl::CGridPlaneXY>(-100, 100, -100, 100, 0, 5);
71 obj->setColor(0.4f, 0.4f, 0.4f);
80 std::map<TPoseID, CPose3DPDFParticles> lstPoses;
81 std::map<TPoseID, CPose3DPDFParticles>::iterator it;
82 getPathParticles(lstPoses);
88 std::lock_guard<std::mutex> lock(m_parent->m_map_cs);
90 for (
unsigned long m_neighbor : m_neighbors)
93 m_parent->m_map.getNodeByID(m_neighbor);
97 if (node->m_annotations.getElemental(
100 lstPoses[poseID_origin].getMean(originPose);
103 corner->setPose(originPose);
104 objs->insert(corner);
111 const CPose3D meanCurPose = lstPoses[m_currentRobotPose].getMeanVal();
114 cam->setZoomDistance(85);
115 cam->setAzimuthDegrees(45 +
RAD2DEG(meanCurPose.
yaw()));
116 cam->setElevationDegrees(45);
117 cam->setPointingAt(meanCurPose);
121 map<CHMHMapNode::TNodeID, CPoint3D>
123 map<CHMHMapNode::TNodeID, int> areas_howmany;
125 for (it = lstPoses.begin(); it != lstPoses.end(); it++)
128 std::make_shared<opengl::CEllipsoid3D>();
130 if (m_nodeIDmemberships.find(it->first)->second ==
131 m_nodeIDmemberships.find(m_currentRobotPose)->second)
132 ellip->setColor(0, 0, 1);
134 ellip->setColor(1, 0, 0);
143 pdf.
mean.z() + 0.005);
151 pdf.
cov(2, 2) < 1e-4f)
154 ellip->setCovMatrix(C);
156 ellip->enableDrawSolid3D(
false);
159 ellip->setName(
format(
"P%u", (
unsigned int)it->first));
160 ellip->enableShowName();
168 0, 0, 0, 0.20f, 0, 0, 0.25f, 0.005f, 0.02f);
169 obj->setColor(1, 0, 0);
170 obj->setPose(pdf.
mean);
175 if (it->first == m_currentRobotPose)
179 robot->setPose(pdf.
mean);
187 auto itAreaId = m_nodeIDmemberships.find(it->first);
188 ASSERT_(itAreaId != m_nodeIDmemberships.end());
190 areas_howmany[areaId]++;
191 areas_mean[areaId].x_incr(pdf.
mean.
x());
192 areas_mean[areaId].y_incr(pdf.
mean.
y());
193 areas_mean[areaId].z_incr(pdf.
mean.z());
198 map<CHMHMapNode::TNodeID, CPoint3D>::iterator itMeans;
199 map<CHMHMapNode::TNodeID, int>::iterator itHowMany;
200 ASSERT_(areas_howmany.size() == areas_mean.size());
201 for (itMeans = areas_mean.begin(), itHowMany = areas_howmany.begin();
202 itMeans != areas_mean.end(); itMeans++, itHowMany++)
204 ASSERT_(itHowMany->second > 0);
206 float f = 1.0f / itHowMany->second;
207 itMeans->second *= f;
213 for (it = lstPoses.begin(); it != lstPoses.end(); it++)
215 if (it->first != m_currentRobotPose)
218 areas_mean[m_nodeIDmemberships.find(it->first)->second]);
219 areaPnt.z_incr(m_parent->m_options.VIEW3D_AREA_SPHERES_HEIGHT);
226 std::make_shared<opengl::CSimpleLine>();
227 line->setColor(0.8, 0.8, 0.8, 0.3);
228 line->setLineWidth(2);
232 areaPnt.y(), areaPnt.z());
285 std::lock_guard<std::mutex> lock(
288 for (itMeans = areas_mean.begin(); itMeans != areas_mean.end();
293 if (itMeans->first ==
294 m_nodeIDmemberships.find(m_currentRobotPose)->second)
296 sphere->setColor(0.1, 0.1, 0.7);
300 sphere->setColor(0.7, 0, 0);
304 itMeans->second.x(), itMeans->second.y(),
305 itMeans->second.z() +
306 m_parent->m_options.VIEW3D_AREA_SPHERES_HEIGHT);
308 sphere->setRadius(m_parent->m_options.VIEW3D_AREA_SPHERES_RADIUS);
311 objs->insert(sphere);
315 txt->setColor(1, 1, 1);
318 m_parent->m_map.getNodeByID(itMeans->first);
322 itMeans->second.x(), itMeans->second.y(),
323 itMeans->second.z() +
324 m_parent->m_options.VIEW3D_AREA_SPHERES_HEIGHT);
327 txt->setString(
format(
"%li", (
long int)node->getID()));
337 std::lock_guard<std::mutex> lock(m_parent->m_map_cs);
339 for (itMeans = areas_mean.begin(); itMeans != areas_mean.end();
344 m_parent->m_map.getNodeByID(srcAreaID);
348 srcArea->getArcs(lstArcs);
349 for (
auto a = lstArcs.begin(); a != lstArcs.end(); ++a)
352 if ((*a)->getNodeFrom() == srcAreaID)
354 auto trgAreaPoseIt = areas_mean.find((*a)->getNodeTo());
355 if (trgAreaPoseIt != areas_mean.end())
359 std::make_shared<opengl::CSimpleLine>();
360 line->setColor(0.8, 0.8, 0);
361 line->setLineWidth(3);
364 areas_mean[srcAreaID].x(),
365 areas_mean[srcAreaID].y(),
366 areas_mean[srcAreaID].z() +
367 m_parent->m_options.VIEW3D_AREA_SPHERES_HEIGHT,
368 trgAreaPoseIt->second.x(),
369 trgAreaPoseIt->second.y(),
370 trgAreaPoseIt->second.z() +
371 m_parent->m_options.VIEW3D_AREA_SPHERES_HEIGHT);
383 void CLocalMetricHypothesis::prediction_and_update_pfAuxiliaryPFOptimal(
389 ASSERT_(m_parent->m_LSLAM_method);
390 m_parent->m_LSLAM_method->prediction_and_update_pfAuxiliaryPFOptimal(
391 this, action, observation, PF_options);
394 void CLocalMetricHypothesis::prediction_and_update_pfOptimalProposal(
400 ASSERT_(m_parent->m_LSLAM_method);
401 m_parent->m_LSLAM_method->prediction_and_update_pfOptimalProposal(
402 this, action, observation, PF_options);
417 std::map<TPoseID, CPose3DPDFParticles> parts;
418 getPathParticles(parts);
420 std::map<TPoseID, CPose3DPDFParticles>::iterator it;
422 for (it = parts.begin(); it != parts.end(); it++)
423 it->second.getMean(outList[it->first]);
431 void CLocalMetricHypothesis::getPathParticles(
432 std::map<TPoseID, CPose3DPDFParticles>& outList)
const 438 if (m_particles.empty())
return;
441 for (
auto itPoseID = m_particles.begin()->d->robotPoses.begin();
442 itPoseID != m_particles.begin()->d->robotPoses.end(); ++itPoseID)
445 CParticleList::const_iterator it;
446 CPose3DPDFParticles::CParticleList::iterator itP;
447 for (it = m_particles.begin(), itP = auxPDF.m_particles.begin();
448 it != m_particles.end(); it++, itP++)
450 itP->log_w = it->log_w;
451 itP->d = it->d->robotPoses.find(itPoseID->first)->second.asTPose();
455 outList[itPoseID->first] = auxPDF;
464 void CLocalMetricHypothesis::getPoseParticles(
471 CParticleList::const_iterator it;
473 CPose3DPDFParticles::CParticleList::iterator itP;
474 for (it = m_particles.begin(), itP = outPDF.
m_particles.begin();
475 it != m_particles.end(); it++, itP++)
477 itP->log_w = it->log_w;
478 auto itPose = it->d->robotPoses.find(poseID);
479 ASSERT_(itPose != it->d->robotPoses.end());
480 itP->d = itPose->second.asTPose();
489 void CLocalMetricHypothesis::clearRobotPoses()
492 m_particles.resize(m_parent->m_options.pf_options.sampleSize);
493 for (
auto& m_particle : m_particles)
496 m_particle.log_w = 0;
498 &m_parent->m_options.defaultMapsInitializers));
501 m_particle.d->robotPoses.clear();
508 const CPose3D* CLocalMetricHypothesis::getCurrentPose(
size_t particleIdx)
const 510 if (particleIdx >= m_particles.size())
513 auto it = m_particles[particleIdx].d->robotPoses.find(m_currentRobotPose);
514 ASSERT_(it != m_particles[particleIdx].d->robotPoses.end());
521 CPose3D* CLocalMetricHypothesis::getCurrentPose(
size_t particleIdx)
523 if (particleIdx >= m_particles.size())
526 auto it = m_particles[particleIdx].d->robotPoses.find(m_currentRobotPose);
527 ASSERT_(it != m_particles[particleIdx].d->robotPoses.end());
534 void CLocalMetricHypothesis::getRelativePose(
543 CParticleList::const_iterator it;
544 CPose3DPDFParticles::CParticleList::iterator itP;
545 for (it = m_particles.begin(), itP = outPDF.
m_particles.begin();
546 it != m_particles.end(); it++, itP++)
548 itP->log_w = it->log_w;
550 auto srcPose = it->d->robotPoses.find(reference);
551 auto trgPose = it->d->robotPoses.find(pose);
553 ASSERT_(srcPose != it->d->robotPoses.end());
554 ASSERT_(trgPose != it->d->robotPoses.end());
565 void CLocalMetricHypothesis::changeCoordinateOrigin(
const TPoseID& newOrigin)
569 CParticleList::iterator it;
570 CPose3DPDFParticles::CParticleList::iterator itOrgPDF;
572 for (it = m_particles.begin(), itOrgPDF = originPDF.m_particles.begin();
573 it != m_particles.end(); it++, itOrgPDF++)
575 auto refPoseIt = it->d->robotPoses.find(newOrigin);
576 ASSERT_(refPoseIt != it->d->robotPoses.end());
577 const CPose3D& refPose = refPoseIt->second;
580 itOrgPDF->d = refPose.
asTPose();
581 itOrgPDF->log_w = it->log_w;
583 auto End = it->d->robotPoses.end();
585 for (
auto itP = it->d->robotPoses.begin(); itP != End; ++itP)
586 if (itP != refPoseIt) itP->second = itP->second - refPose;
589 refPoseIt->second.setFromValues(0, 0, 0);
597 std::lock_guard<std::mutex> locker(m_robotPosesGraph.lock);
599 CSimpleMap* SFseq = m_robotPosesGraph.partitioner.getSequenceOfFrames();
600 for (
auto& p : m_robotPosesGraph.idx2pose)
604 SFseq->
get(p.first, pdf, sf);
609 getPoseParticles(p.second, *pdfParts);
617 void CLocalMetricHypothesis::rebuildMetricMaps()
619 for (
auto& m_particle : m_particles)
621 m_particle.d->metricMaps.clear();
624 auto End = m_particle.d->robotPoses.end();
625 for (
auto itP = m_particle.d->robotPoses.begin(); itP != End; ++itP)
630 auto SFit = m_SFs.find(itP->first);
632 SFit->second.insertObservationsInto(
633 &m_particle.d->metricMaps, &itP->second);
651 void CLocalMetricHypothesis::removeAreaFromLMH(
658 auto itNeig = m_neighbors.find(areaID);
659 if (itNeig != m_neighbors.end()) m_neighbors.erase(itNeig);
664 for (
auto& m_nodeIDmembership : m_nodeIDmemberships)
665 if (m_nodeIDmembership.second == areaID)
666 lstPoseIDs.
insert(m_nodeIDmembership.first);
674 updateAreaFromLMH(areaID,
true);
679 for (
auto it = lstPoseIDs.begin(); it != lstPoseIDs.end(); ++it)
680 for (
auto& m_particle : m_particles)
681 m_particle.d->robotPoses.erase(m_particle.d->robotPoses.find(*it));
687 CParticleList::iterator p;
688 vector<map<TPoseID, double>>::iterator ws_it;
689 ASSERT_(m_log_w_metric_history.size() == m_particles.size());
691 for (ws_it = m_log_w_metric_history.begin(), p = m_particles.begin();
692 p != m_particles.end(); ++p, ++ws_it)
694 for (
auto it = lstPoseIDs.begin(); it != lstPoseIDs.end(); ++it)
696 auto itW = ws_it->find(*it);
697 if (itW != ws_it->end())
701 p->log_w -= itW->second;
713 std::lock_guard<std::mutex> locker(m_robotPosesGraph.lock);
715 std::vector<uint32_t> indexesToRemove;
716 indexesToRemove.reserve(lstPoseIDs.size());
718 for (
auto it = m_robotPosesGraph.idx2pose.begin();
719 it != m_robotPosesGraph.idx2pose.end();)
721 if (lstPoseIDs.
find(it->second) != lstPoseIDs.end())
723 indexesToRemove.push_back(it->first);
729 m_robotPosesGraph.idx2pose.erase(it);
736 m_robotPosesGraph.partitioner.removeSetOfNodes(indexesToRemove);
741 map<uint32_t, TPoseID> newList;
742 for (
auto i = m_robotPosesGraph.idx2pose.begin();
743 i != m_robotPosesGraph.idx2pose.end(); ++i, idx++)
744 newList[idx] = i->second;
745 m_robotPosesGraph.idx2pose = newList;
756 for (
auto it = lstPoseIDs.begin(); it != lstPoseIDs.end(); ++it)
757 m_nodeIDmemberships.erase(m_nodeIDmemberships.find(*it));
759 double out_max_log_w;
760 normalizeWeights(&out_max_log_w);
768 unsigned int CLocalMetricHypothesis::TRobotPosesPartitioning::pose2idx(
771 for (
auto it : idx2pose)
772 if (it.second ==
id)
return it.first;
782 void CLocalMetricHypothesis::updateAreaFromLMH(
788 for (
auto it = m_nodeIDmemberships.begin(); it != m_nodeIDmemberships.end();
790 if (it->second == areaID) lstPoseIDs.
insert(it->first);
796 std::lock_guard<std::mutex> lock(m_parent->m_map_cs);
797 node = m_parent->m_map.getNodeByID(areaID);
799 ASSERT_(node->m_hypotheses.has(m_ID));
804 node->m_annotations.getElemental(
812 CSerializable::Ptr annot =
817 posesGraph = std::make_shared<CRobotPosesGraph>();
818 node->m_annotations.setMemoryReference(
830 bool pdfOrigin_ok =
false;
831 for (
auto it = lstPoseIDs.begin(); it != lstPoseIDs.end(); ++it)
833 TPoseInfo& poseInfo = (*posesGraph)[*it];
834 getPoseParticles(*it, poseInfo.
pdf);
837 if (*it == poseID_origin)
843 if (*it != m_currentRobotPose)
845 auto itSF = m_SFs.find(*it);
850 poseInfo.
sf = std::move(itSF->second);
855 poseInfo.
sf = itSF->second;
863 pdfOrigin.
inverse(pdfOriginInv);
864 for (
auto it = posesGraph->begin(); it != posesGraph->end(); ++it)
866 CPose3DPDFParticles::CParticleList::iterator orgIt, pdfIt;
867 ASSERT_(it->second.pdf.size() == pdfOriginInv.
size());
868 for (pdfIt = it->second.pdf.m_particles.begin(),
870 orgIt != pdfOriginInv.
m_particles.end(); orgIt++, pdfIt++)
880 posesGraph->insertIntoMetricMap(*metricMap);
886 void CLocalMetricHypothesis::dumpAsText(std::vector<std::string>& st)
const 889 st.emplace_back(
"LIST OF POSES IN LMH");
890 st.emplace_back(
"====================");
894 for (
unsigned long m_neighbor : m_neighbors)
895 s +=
format(
"%i ", (
int)m_neighbor);
901 for (
auto it = lst.begin(); it != lst.end(); ++it)
903 auto area = m_nodeIDmemberships.find(it->first);
905 " ID: %i \t AREA: %i \t %.03f,%.03f,%.03fdeg", (
int)it->first,
906 (
int)area->second, it->second.x(), it->second.y(),
914 void CLocalMetricHypothesis::serializeFrom(
921 in >> m_ID >> m_currentRobotPose >> m_neighbors >>
922 m_nodeIDmemberships >> m_SFs >> m_posesPendingAddPartitioner >>
923 m_areasPendingTBI >> m_log_w >> m_log_w_metric_history >>
924 m_robotPosesGraph.partitioner >> m_robotPosesGraph.idx2pose;
927 readParticlesFromStream(in);
935 uint8_t CLocalMetricHypothesis::serializeGetVersion()
const {
return 0; }
936 void CLocalMetricHypothesis::serializeTo(
939 out << m_ID << m_currentRobotPose << m_neighbors << m_nodeIDmemberships
940 << m_SFs << m_posesPendingAddPartitioner << m_areasPendingTBI << m_log_w
941 << m_log_w_metric_history << m_robotPosesGraph.partitioner
942 << m_robotPosesGraph.idx2pose;
945 writeParticlesToStream(
out);
948 void CLSLAMParticleData::serializeFrom(
955 in >> metricMaps >> robotPoses;
963 uint8_t CLSLAMParticleData::serializeGetVersion()
const {
return 0; }
966 out << metricMaps << robotPoses;
mrpt::math::TPose3D asTPose() const
CPose3D mean
The mean value.
std::list< T >::iterator find(const T &i)
#define THROW_EXCEPTION(msg)
void copyFrom(const CPose3DPDF &o) override
Copy operator, translating if necesary (for example, between particles and gaussian representations) ...
mrpt::graphs::TNodeID TNodeID
The type of the IDs of nodes.
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.
Classes related to the implementation of Hybrid Metric Topological (HMT) SLAM.
#define IMPLEMENTS_SERIALIZABLE(class_name, base, NameSpace)
To be added to all CSerializable-classes implementation files.
mrpt::poses::CPose3DPDFParticles pdf
The robot pose PDF.
uint64_t TPoseID
An integer number uniquely identifying each robot pose stored in HMT-SLAM.
double pitch() const
Get the PITCH angle (in radians)
double yaw() const
Get the YAW angle (in radians)
An implementation of Hybrid Metric Topological SLAM (HMT-SLAM).
Declares a class for storing a collection of robot actions.
#define MRPT_THROW_UNKNOWN_SERIALIZATION_VERSION(__V)
For use in CSerializable implementations.
#define ASSERT_(f)
Defines an assertion mechanism.
This base provides a set of functions for maths stuff.
#define CLASS_ID(T)
Access to runtime class ID for a defined class name.
static Ptr Create(Args &&... args)
#define MRPT_CHECK_NORMAL_NUMBER(v)
Throws an exception if the number is NaN, IND, or +/-INF, or return the same number otherwise...
std::map< TPoseID, mrpt::poses::CPose3D > TMapPoseID2Pose3D
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
Get the m_particles count (equivalent to "particlesCount")
Auxiliary class used in mrpt::slam::CLocalMetricHypothesis for HMT-SLAM; this class stores a set of r...
double x() const
Common members of all points & poses classes.
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'.
This class is used in HMT-SLAM to represent each of the Local Metric Hypotheses (LMHs).
#define NODE_ANNOTATION_METRIC_MAPS
A class used to store a 3D point.
Classes for 2D/3D geometry representation, both of single values and probability density distribution...
double roll() const
Get the ROLL angle (in radians)
CSetOfObjects::Ptr RobotPioneer()
Returns a representation of a Pioneer II mobile base.
Auxiliary class used in mrpt::slam::CLocalMetricHypothesis for HMT-SLAM; this class keeps the data re...
void copyFrom(const CPose3DPDF &o) override
Copy operator, translating if necesary (for example, between m_particles and gaussian representations...
mrpt::math::CMatrixDouble66 cov
The 6x6 covariance matrix.
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
constexpr std::size_t size() const
Virtual base class for "archives": classes abstracting I/O streams.
A class used to store a 3D pose (a 3D translation + a rotation in 3D).
mrpt::vision::TStereoCalibResults out
CSetOfObjects::Ptr CornerXYZ(float scale=1.0)
Returns three arrows representing a X,Y,Z 3D corner.
The configuration of a particle filter.
constexpr double RAD2DEG(const double x)
Radians to degrees.
void setSize(size_t row, size_t col, bool zeroNewElements=false)
Changes the size of matrix, maintaining the previous contents.
mrpt::obs::CSensoryFrame sf
The observations.
Lightweight 3D pose (three spatial coordinates, plus three angular coordinates).
The namespace for 3D scene representation and rendering.
#define NODE_ANNOTATION_REF_POSEID
Declares a class that represents a Probability Density function (PDF) of a 3D pose ...
Information kept for each robot pose used in CRobotPosesGraph.
void resetDeterministic(const mrpt::math::TPose3D &location, size_t particlesCount=0)
Reset the PDF to a single point: All m_particles will be set exactly to the supplied pose...
void inverse(CPose3DPDF &o) const override
Returns a new PDF such as: NEW_PDF = (0,0,0) - THIS_PDF.
This class stores any customizable set of metric maps.
#define NODE_ANNOTATION_POSES_GRAPH
#define THROW_EXCEPTION_FMT(_FORMAT_STRING,...)
A class for storing a sequence of arcs (a path).
Declares a class that represents a Probability Density function (PDF) of a 3D pose.
CMatrixDynamic< double > CMatrixDouble
Declares a matrix of double numbers (non serializable).