42 : m_parent(parent), m_log_w_metric_history()
46 m_accumRobotMovementIsValid =
false;
52 CLocalMetricHypothesis::~CLocalMetricHypothesis() { clearParticles(); }
60 void CLocalMetricHypothesis::getAs3DScene(
70 mrpt::make_aligned_shared<opengl::CGridPlaneXY>(
71 -100, 100, -100, 100, 0, 5);
72 obj->setColor(0.4, 0.4, 0.4);
81 std::map<TPoseID, CPose3DPDFParticles> lstPoses;
83 getPathParticles(lstPoses);
89 std::lock_guard<std::mutex> lock(m_parent->m_map_cs);
92 n != m_neighbors.end(); ++
n)
98 if (node->m_annotations.getElemental(
101 lstPoses[poseID_origin].getMean(originPose);
104 corner->setPose(originPose);
105 objs->insert(corner);
112 const CPose3D meanCurPose = lstPoses[m_currentRobotPose].getMeanVal();
115 cam->setZoomDistance(85);
116 cam->setAzimuthDegrees(45 +
RAD2DEG(meanCurPose.
yaw()));
117 cam->setElevationDegrees(45);
118 cam->setPointingAt(meanCurPose);
122 map<CHMHMapNode::TNodeID, CPoint3D>
124 map<CHMHMapNode::TNodeID, int> areas_howmany;
126 for (it = lstPoses.begin(); it != lstPoses.end(); it++)
129 mrpt::make_aligned_shared<opengl::CEllipsoid>();
131 if (m_nodeIDmemberships.find(it->first)->second ==
132 m_nodeIDmemberships.find(m_currentRobotPose)->second)
133 ellip->setColor(0, 0, 1);
135 ellip->setColor(1, 0, 0);
144 pdf.
mean.z() + 0.005);
152 pdf.
cov(2, 2) < 1e-4f)
155 ellip->setCovMatrix(C);
157 ellip->enableDrawSolid3D(
false);
160 ellip->setName(
format(
"P%u", (
unsigned int)it->first));
161 ellip->enableShowName();
169 0, 0, 0, 0.20f, 0, 0, 0.25f, 0.005f, 0.02f);
170 obj->setColor(1, 0, 0);
176 if (it->first == m_currentRobotPose)
180 robot->setPose(pdf.
mean);
189 m_nodeIDmemberships.find(it->first);
190 ASSERT_(itAreaId != m_nodeIDmemberships.end());
192 areas_howmany[areaId]++;
193 areas_mean[areaId].x_incr(pdf.
mean.
x());
194 areas_mean[areaId].y_incr(pdf.
mean.
y());
195 areas_mean[areaId].z_incr(pdf.
mean.z());
202 ASSERT_(areas_howmany.size() == areas_mean.size());
203 for (itMeans = areas_mean.begin(), itHowMany = areas_howmany.begin();
204 itMeans != areas_mean.end(); itMeans++, itHowMany++)
206 ASSERT_(itHowMany->second > 0);
208 float f = 1.0f / itHowMany->second;
209 itMeans->second *= f;
215 for (it = lstPoses.begin(); it != lstPoses.end(); it++)
217 if (it->first != m_currentRobotPose)
220 areas_mean[m_nodeIDmemberships.find(it->first)->second]);
221 areaPnt.z_incr(m_parent->m_options.VIEW3D_AREA_SPHERES_HEIGHT);
228 mrpt::make_aligned_shared<opengl::CSimpleLine>();
229 line->setColor(0.8, 0.8, 0.8, 0.3);
230 line->setLineWidth(2);
234 areaPnt.
y(), areaPnt.z());
287 std::lock_guard<std::mutex> lock(
290 for (itMeans = areas_mean.begin(); itMeans != areas_mean.end();
294 mrpt::make_aligned_shared<opengl::CSphere>();
296 if (itMeans->first ==
297 m_nodeIDmemberships.find(m_currentRobotPose)->second)
299 sphere->setColor(0.1, 0.1, 0.7);
303 sphere->setColor(0.7, 0, 0);
307 itMeans->second.x(), itMeans->second.y(),
308 itMeans->second.z() +
309 m_parent->m_options.VIEW3D_AREA_SPHERES_HEIGHT);
311 sphere->setRadius(m_parent->m_options.VIEW3D_AREA_SPHERES_RADIUS);
314 objs->insert(sphere);
318 txt->setColor(1, 1, 1);
321 m_parent->m_map.getNodeByID(itMeans->first);
325 itMeans->second.x(), itMeans->second.y(),
326 itMeans->second.z() +
327 m_parent->m_options.VIEW3D_AREA_SPHERES_HEIGHT);
330 txt->setString(
format(
"%li", (
long int)node->getID()));
340 std::lock_guard<std::mutex> lock(m_parent->m_map_cs);
342 for (itMeans = areas_mean.begin(); itMeans != areas_mean.end();
347 m_parent->m_map.getNodeByID(srcAreaID);
351 srcArea->getArcs(lstArcs);
353 a != lstArcs.end(); ++
a)
356 if ((*a)->getNodeFrom() == srcAreaID)
359 trgAreaPoseIt = areas_mean.find((*a)->getNodeTo());
360 if (trgAreaPoseIt != areas_mean.end())
364 mrpt::make_aligned_shared<opengl::CSimpleLine>();
365 line->setColor(0.8, 0.8, 0);
366 line->setLineWidth(3);
369 areas_mean[srcAreaID].
x(),
370 areas_mean[srcAreaID].
y(),
371 areas_mean[srcAreaID].
z() +
372 m_parent->m_options.VIEW3D_AREA_SPHERES_HEIGHT,
373 trgAreaPoseIt->second.x(),
374 trgAreaPoseIt->second.y(),
375 trgAreaPoseIt->second.z() +
376 m_parent->m_options.VIEW3D_AREA_SPHERES_HEIGHT);
388 void CLocalMetricHypothesis::prediction_and_update_pfAuxiliaryPFOptimal(
394 ASSERT_(m_parent->m_LSLAM_method);
395 m_parent->m_LSLAM_method->prediction_and_update_pfAuxiliaryPFOptimal(
396 this, action, observation, PF_options);
399 void CLocalMetricHypothesis::prediction_and_update_pfOptimalProposal(
405 ASSERT_(m_parent->m_LSLAM_method);
406 m_parent->m_LSLAM_method->prediction_and_update_pfOptimalProposal(
407 this, action, observation, PF_options);
422 std::map<TPoseID, CPose3DPDFParticles> parts;
423 getPathParticles(parts);
427 for (it = parts.begin(); it != parts.end(); it++)
428 it->second.getMean(outList[it->first]);
436 void CLocalMetricHypothesis::getPathParticles(
437 std::map<TPoseID, CPose3DPDFParticles>& outList)
const
443 if (m_particles.empty())
return;
447 m_particles.begin()->d->robotPoses.begin();
448 itPoseID != m_particles.begin()->d->robotPoses.end(); ++itPoseID)
453 for (it = m_particles.begin(), itP = auxPDF.
m_particles.begin();
454 it != m_particles.end(); it++, itP++)
456 itP->log_w = it->log_w;
457 itP->d = it->d->robotPoses.find(itPoseID->first)->second.asTPose();
461 outList[itPoseID->first] = auxPDF;
470 void CLocalMetricHypothesis::getPoseParticles(
480 for (it = m_particles.begin(), itP = outPDF.
m_particles.begin();
481 it != m_particles.end(); it++, itP++)
483 itP->log_w = it->log_w;
485 it->d->robotPoses.find(poseID);
486 ASSERT_(itPose != it->d->robotPoses.end());
487 itP->d = itPose->second.asTPose();
496 void CLocalMetricHypothesis::clearRobotPoses()
499 m_particles.resize(m_parent->m_options.pf_options.sampleSize);
501 it != m_particles.end(); ++it)
506 &m_parent->m_options.defaultMapsInitializers));
509 it->d->robotPoses.clear();
516 const CPose3D* CLocalMetricHypothesis::getCurrentPose(
517 const size_t& particleIdx)
const
519 if (particleIdx >= m_particles.size())
523 m_particles[particleIdx].d->robotPoses.find(m_currentRobotPose);
524 ASSERT_(it != m_particles[particleIdx].d->robotPoses.end());
531 CPose3D* CLocalMetricHypothesis::getCurrentPose(
const size_t& particleIdx)
533 if (particleIdx >= m_particles.size())
537 m_particles[particleIdx].d->robotPoses.find(m_currentRobotPose);
538 ASSERT_(it != m_particles[particleIdx].d->robotPoses.end());
545 void CLocalMetricHypothesis::getRelativePose(
556 for (it = m_particles.begin(), itP = outPDF.
m_particles.begin();
557 it != m_particles.end(); it++, itP++)
559 itP->log_w = it->log_w;
561 auto srcPose = it->d->robotPoses.find(reference);
562 auto trgPose = it->d->robotPoses.find(pose);
564 ASSERT_(srcPose != it->d->robotPoses.end());
565 ASSERT_(trgPose != it->d->robotPoses.end());
576 void CLocalMetricHypothesis::changeCoordinateOrigin(
const TPoseID& newOrigin)
583 for (it = m_particles.begin(), itOrgPDF = originPDF.
m_particles.begin();
584 it != m_particles.end(); it++, itOrgPDF++)
586 auto refPoseIt = it->d->robotPoses.find(newOrigin);
587 ASSERT_(refPoseIt != it->d->robotPoses.end());
588 const CPose3D& refPose = refPoseIt->second;
591 itOrgPDF->d = refPose.
asTPose();
592 itOrgPDF->log_w = it->log_w;
598 if (itP != refPoseIt) itP->second = itP->second - refPose;
609 std::lock_guard<std::mutex> locker(m_robotPosesGraph.lock);
611 CSimpleMap* SFseq = m_robotPosesGraph.partitioner.getSequenceOfFrames();
613 m_robotPosesGraph.idx2pose.begin();
614 it != m_robotPosesGraph.idx2pose.end(); ++it)
618 SFseq->
get(it->first, pdf, sf);
623 std::dynamic_pointer_cast<CPose3DPDFParticles>(pdf);
624 getPoseParticles(it->second, *pdfParts);
632 void CLocalMetricHypothesis::rebuildMetricMaps()
635 it != m_particles.end(); ++it)
637 it->d->metricMaps.clear();
648 m_SFs.find(itP->first);
650 SFit->second.insertObservationsInto(
651 &it->d->metricMaps, &itP->second);
669 void CLocalMetricHypothesis::removeAreaFromLMH(
677 if (itNeig != m_neighbors.end()) m_neighbors.erase(itNeig);
683 m_nodeIDmemberships.begin();
684 it != m_nodeIDmemberships.end(); ++it)
685 if (it->second == areaID) lstPoseIDs.
insert(it->first);
693 updateAreaFromLMH(areaID,
true);
699 it != lstPoseIDs.end(); ++it)
701 p != m_particles.end(); ++
p)
702 p->d->robotPoses.erase(
p->d->robotPoses.find(*it));
710 ASSERT_(m_log_w_metric_history.size() == m_particles.size());
712 for (ws_it = m_log_w_metric_history.begin(),
p = m_particles.begin();
713 p != m_particles.end(); ++
p, ++ws_it)
716 it != lstPoseIDs.end(); ++it)
719 if (itW != ws_it->end())
723 p->log_w -= itW->second;
735 std::lock_guard<std::mutex> locker(m_robotPosesGraph.lock);
737 std::vector<uint32_t> indexesToRemove;
738 indexesToRemove.reserve(lstPoseIDs.size());
741 m_robotPosesGraph.idx2pose.begin();
742 it != m_robotPosesGraph.idx2pose.end();)
744 if (lstPoseIDs.
find(it->second) != lstPoseIDs.end())
746 indexesToRemove.push_back(it->first);
752 m_robotPosesGraph.idx2pose.erase(it);
759 m_robotPosesGraph.partitioner.removeSetOfNodes(indexesToRemove);
764 map<uint32_t, TPoseID> newList;
766 m_robotPosesGraph.idx2pose.begin();
767 i != m_robotPosesGraph.idx2pose.end(); ++i, idx++)
768 newList[idx] = i->second;
769 m_robotPosesGraph.idx2pose = newList;
781 it != lstPoseIDs.end(); ++it)
782 m_nodeIDmemberships.erase(m_nodeIDmemberships.find(*it));
784 double out_max_log_w;
785 normalizeWeights(&out_max_log_w);
793 unsigned int CLocalMetricHypothesis::TRobotPosesPartitioning::pose2idx(
797 it != idx2pose.end(); ++it)
798 if (it->second ==
id)
return it->first;
808 void CLocalMetricHypothesis::updateAreaFromLMH(
815 m_nodeIDmemberships.begin();
816 it != m_nodeIDmemberships.end(); ++it)
817 if (it->second == areaID) lstPoseIDs.
insert(it->first);
823 std::lock_guard<std::mutex>(m_parent->m_map_cs);
824 node = m_parent->m_map.getNodeByID(areaID);
826 ASSERT_(node->m_hypotheses.has(m_ID));
831 node->m_annotations.getElemental(
839 CSerializable::Ptr annot =
844 posesGraph = mrpt::make_aligned_shared<CRobotPosesGraph>();
845 node->m_annotations.setMemoryReference(
850 posesGraph = std::dynamic_pointer_cast<CRobotPosesGraph>(annot);
857 bool pdfOrigin_ok =
false;
859 it != lstPoseIDs.end(); ++it)
861 TPoseInfo& poseInfo = (*posesGraph)[*it];
862 getPoseParticles(*it, poseInfo.
pdf);
865 if (*it == poseID_origin)
871 if (*it != m_currentRobotPose)
886 poseInfo.
sf = itSF->second;
894 pdfOrigin.
inverse(pdfOriginInv);
896 it != posesGraph->end(); ++it)
899 ASSERT_(it->second.pdf.size() == pdfOriginInv.
size());
900 for (pdfIt = it->second.pdf.m_particles.begin(),
902 orgIt != pdfOriginInv.
m_particles.end(); orgIt++, pdfIt++)
912 posesGraph->insertIntoMetricMap(*metricMap);
918 void CLocalMetricHypothesis::dumpAsText(std::vector<std::string>& st)
const
921 st.push_back(
"LIST OF POSES IN LMH");
922 st.push_back(
"====================");
927 it != m_neighbors.end(); ++it)
938 m_nodeIDmemberships.find(it->first);
941 " ID: %i \t AREA: %i \t %.03f,%.03f,%.03fdeg", (
int)it->first,
942 (
int)area->second, it->second.x(), it->second.y(),
951 void CLocalMetricHypothesis::serializeFrom(
958 in >> m_ID >> m_currentRobotPose >> m_neighbors >>
959 m_nodeIDmemberships >> m_SFs >> m_posesPendingAddPartitioner >>
960 m_areasPendingTBI >> m_log_w >> m_log_w_metric_history >>
961 m_robotPosesGraph.partitioner >> m_robotPosesGraph.idx2pose;
964 readParticlesFromStream(
in);
972 uint8_t CLocalMetricHypothesis::serializeGetVersion()
const {
return 0; }
973 void CLocalMetricHypothesis::serializeTo(
976 out << m_ID << m_currentRobotPose << m_neighbors << m_nodeIDmemberships
977 << m_SFs << m_posesPendingAddPartitioner << m_areasPendingTBI << m_log_w
978 << m_log_w_metric_history << m_robotPosesGraph.partitioner
979 << m_robotPosesGraph.idx2pose;
982 writeParticlesToStream(out);
985 void CLSLAMParticleData::serializeFrom(
992 in >> metricMaps >> robotPoses;
1000 uint8_t CLSLAMParticleData::serializeGetVersion()
const {
return 0; }
1003 out << metricMaps << robotPoses;
#define CLASS_ID(T)
Access to runtime class ID for a defined class name.
#define IMPLEMENTS_SERIALIZABLE(class_name, base, NameSpace)
This must be inserted in all CSerializable classes implementation files.
#define NODE_ANNOTATION_METRIC_MAPS
#define NODE_ANNOTATION_REF_POSEID
#define NODE_ANNOTATION_POSES_GRAPH
CParticleList m_particles
The array of particles.
std::list< T >::iterator find(const T &i)
std::shared_ptr< CHMHMapNode > Ptr
mrpt::graphs::TNodeID TNodeID
The type of the IDs of nodes.
An implementation of Hybrid Metric Topological SLAM (HMT-SLAM).
Auxiliary class used in mrpt::slam::CLocalMetricHypothesis for HMT-SLAM; this class keeps the data re...
This class is used in HMT-SLAM to represent each of the Local Metric Hypotheses (LMHs).
std::shared_ptr< CRobotPosesGraph > Ptr
A class for storing a sequence of arcs (a path).
void clear()
Erase all the contents of the map.
This class stores any customizable set of metric maps.
std::shared_ptr< CMultiMetricMap > Ptr
This class stores a sequence of <Probabilistic Pose,SensoryFrame> pairs, thus a "metric map" can be t...
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'.
Declares a class for storing a collection of robot actions.
Declares a class for storing a "sensory frame", a set of "observations" taken by the robot approximat...
void moveFrom(CSensoryFrame &sf)
Copies all the observation from another object, then erase them from the origin object (this method i...
std::shared_ptr< CSensoryFrame > Ptr
static Ptr Create(Args &&... args)
std::shared_ptr< CArrow > Ptr
std::shared_ptr< CCamera > Ptr
std::shared_ptr< CEllipsoid > Ptr
std::shared_ptr< CGridPlaneXY > Ptr
std::shared_ptr< CSetOfObjects > Ptr
std::shared_ptr< CSimpleLine > Ptr
std::shared_ptr< CSphere > Ptr
std::shared_ptr< CText > Ptr
A class used to store a 3D point.
A class used to store a 3D pose (a 3D translation + a rotation in 3D).
double pitch() const
Get the PITCH angle (in radians)
double roll() const
Get the ROLL angle (in radians)
void setFromValues(const double x0, const double y0, const double z0, const double yaw=0, const double pitch=0, const double roll=0)
Set the pose from a 3D position (meters) and yaw/pitch/roll angles (radians) - This method recomputes...
mrpt::math::TPose3D asTPose() const
double yaw() const
Get the YAW angle (in radians)
Declares a class that represents a Probability Density function (PDF) of a 3D pose .
CPose3D mean
The mean value.
void copyFrom(const CPose3DPDF &o) override
Copy operator, translating if necesary (for example, between particles and gaussian representations)
mrpt::math::CMatrixDouble66 cov
The 6x6 covariance matrix.
std::shared_ptr< CPose3DPDF > Ptr
Declares a class that represents a Probability Density function (PDF) of a 3D pose.
std::shared_ptr< CPose3DPDFParticles > Ptr
void copyFrom(const CPose3DPDF &o) override
Copy operator, translating if necesary (for example, between m_particles and gaussian representations...
size_t size() const
Get the m_particles count (equivalent to "particlesCount")
void inverse(CPose3DPDF &o) const override
Returns a new PDF such as: NEW_PDF = (0,0,0) - THIS_PDF.
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.
double x() const
Common members of all points & poses classes.
Virtual base class for "archives": classes abstracting I/O streams.
const Scalar * const_iterator
#define ASSERT_(f)
Defines an assertion mechanism.
#define MRPT_THROW_UNKNOWN_SERIALIZATION_VERSION(__V)
For use in CSerializable implementations.
#define THROW_EXCEPTION(msg)
#define MRPT_CHECK_NORMAL_NUMBER(v)
Throws an exception if the number is NaN, IND, or +/-INF, or return the same number otherwise.
#define THROW_EXCEPTION_FMT(_FORMAT_STRING,...)
GLsizei GLsizei GLuint * obj
GLubyte GLubyte GLubyte a
std::string format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
Classes related to the implementation of Hybrid Metric Topological (HMT) SLAM.
uint64_t TPoseID
An integer number uniquely identifying each robot pose stored in HMT-SLAM.
mrpt::aligned_std_map< TPoseID, mrpt::poses::CPose3D > TMapPoseID2Pose3D
This base provides a set of functions for maths stuff.
CMatrixTemplateNumeric< double > CMatrixDouble
Declares a matrix of double numbers (non serializable).
This namespace contains representation of robot actions and observations.
CSetOfObjects::Ptr RobotPioneer()
Returns a representation of a Pioneer II mobile base.
CSetOfObjects::Ptr CornerXYZ(float scale=1.0)
Returns three arrows representing a X,Y,Z 3D corner.
The namespace for 3D scene representation and rendering.
Classes for 2D/3D geometry representation, both of single values and probability density distribution...
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
double RAD2DEG(const double x)
Radians to degrees.
The configuration of a particle filter.
Information kept for each robot pose used in CRobotPosesGraph.
mrpt::obs::CSensoryFrame sf
The observations.
mrpt::poses::CPose3DPDFParticles pdf
The robot pose PDF.
Lightweight 3D pose (three spatial coordinates, plus three angular coordinates).