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;
601 refPoseIt->second.setFromValues(0, 0, 0);
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);
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(
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;
mrpt::math::TPose3D asTPose() const
double x() const
Common members of all points & poses classes.
CPose3D mean
The mean value.
double RAD2DEG(const double x)
Radians to degrees.
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.
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.
void moveFrom(CSensoryFrame &sf)
Copies all the observation from another object, then erase them from the origin object (this method i...
#define IMPLEMENTS_SERIALIZABLE(class_name, base, NameSpace)
This must be inserted in 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)
GLsizei GLsizei GLuint * obj
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.
mrpt::aligned_std_map< TPoseID, mrpt::poses::CPose3D > TMapPoseID2Pose3D
#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...
CMatrixTemplateNumeric< double > CMatrixDouble
Declares a matrix of double numbers (non serializable).
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...
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.
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).
CSetOfObjects::Ptr CornerXYZ(float scale=1.0)
Returns three arrows representing a X,Y,Z 3D corner.
std::string format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
The configuration of a particle filter.
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,...)
GLubyte GLubyte GLubyte a
const Scalar * const_iterator
A class for storing a sequence of arcs (a path).
Declares a class that represents a Probability Density function (PDF) of a 3D pose.