Main MRPT website > C++ reference for MRPT 1.9.9
CHMTSLAM_perform_TLC.cpp
Go to the documentation of this file.
1 /* +------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | http://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2017, Individual contributors, see AUTHORS file |
6  | See: http://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See details in http://www.mrpt.org/License |
8  +------------------------------------------------------------------------+ */
9 
10 #include "hmtslam-precomp.h" // Precomp header
11 
13 #include <mrpt/utils/CTicTac.h>
14 #include <mrpt/random.h>
15 #include <mrpt/utils/CFileStream.h>
17 #include <mrpt/system/os.h>
18 
19 using namespace mrpt::slam;
20 using namespace mrpt::hmtslam;
21 using namespace mrpt::utils;
22 using namespace mrpt::random;
23 using namespace mrpt::poses;
24 using namespace std;
25 
26 /*---------------------------------------------------------------
27 
28  perform_TLC
29 
30  Topological Loop Closure: Performs all the required operations
31  to close a loop between two areas which have been determined
32  to be the same.
33 
34  ---------------------------------------------------------------*/
35 void CHMTSLAM::perform_TLC(
37  const CHMHMapNode::TNodeID Ai, // areaInLMH,
38  const CHMHMapNode::TNodeID Ae, // areaLoopClosure,
39  const mrpt::poses::CPose3DPDFGaussian& pose_i_wrt_e)
40 {
42  ASSERT_(Ai != Ae)
43 
44  std::lock_guard<std::mutex> locker(LMH.m_robotPosesGraph.lock);
45 
46  logFmt(
47  mrpt::utils::LVL_DEBUG, "[perform_TLC] TLC of areas: %u <-> %u \n",
48  (unsigned)Ai, (unsigned)Ae);
49 
50  // * Verify a1 \in LMH & a2 \notin LMH
51  // ----------------------------------------------------------------------
52  ASSERT_(LMH.m_neighbors.count(Ai) == 1);
53  ASSERT_(LMH.m_neighbors.count(Ae) == 0);
54 
55  // * Get the old pose reference of the area which will desapear:
56  // ----------------------------------------------------------------------
57  TPoseID poseID_Ai_origin;
58  m_map.getNodeByID(Ai)->m_annotations.getElemental(
59  NODE_ANNOTATION_REF_POSEID, poseID_Ai_origin, LMH.m_ID, true);
60  // TPoseID poseID_new_origin;
61  // m_map.getNodeByID(Ae)->m_annotations.getElemental(
62  // NODE_ANNOTATION_REF_POSEID,poseID_new_origin, LMH.m_ID, true);
63 
64  // * Make a list Li of pose IDs in Ai, which need a change in coordinates:
65  // ----------------------------------------------------------------------------------------------
66  // TPoseIDSet Li;
67  // for (map<TPoseID,CHMHMapNode::TNodeID>::const_iterator
68  // it=LMH.m_nodeIDmemberships.begin();it!=LMH.m_nodeIDmemberships.end();++it)
69  // if(it->second==Ai)
70  // Li.insert(it->first);
71 
72  // * Change all poses in "Ai" from "p" to " 0 (-) pose1wrt2 (+) (p (-)
73  // oldRef )"
74  // ----------------------------------------------------------------------------------------------
75  // For all the particles
76  // for ( CLocalMetricHypothesis::CParticleList::const_iterator it =
77  // LMH.m_particles.begin(); it!=LMH.m_particles.end(); ++it)
78  //{
79  // // Touch only the affected poseIDs:
80  // for (TPoseIDSet::const_iterator n=Li.begin();n!=Li.end();++n)
81  // {
82  // map<TPoseID,CPose3D>::iterator itPos = it->d->robotPoses.find(*n);
83  // ASSERT_(itPos!=it->d->robotPoses.end());
84  // itPos->second = Apose_ei + (itPos->second - oldRef);
85  // }
86  //}
87 
88  // Change coords in incr. partitioning as well:
89  // CSimpleMap *SFseq =
90  // LMH.m_robotPosesGraph.partitioner.getSequenceOfFrames();
91  // for (std::map<uint32_t,TPoseID>::const_iterator
92  // it=LMH.m_robotPosesGraph.idx2pose.begin();it!=LMH.m_robotPosesGraph.idx2pose.end();++it)
93  //{
94  // // Only if the pose has been affected:
95  // if (Li.count(it->second)==0) continue;
96 
97  // CPose3DPDF::Ptr pdf;
98  // CSensoryFrame::Ptr sf;
99  // SFseq->get( it->first, pdf, sf);
100 
101  // // Copy from particles:
102  // CPose3DPDFParticles::Ptr pdfParts = CPose3DPDFParticles::Ptr(pdf);
103  // LMH.getPoseParticles( it->second, *pdfParts);
104  //}
105 
106  // * Mark all poses in LMH \in Ai as being of "Ae":
107  // ----------------------------------------------------------------------------------------------
109  LMH.m_nodeIDmemberships.begin();
110  it != LMH.m_nodeIDmemberships.end(); ++it)
111  if (it->second == Ai) it->second = Ae;
112 
113  // * Replace "Ai" by "Ae" in the list of neighbors areas:
114  // ----------------------------------------------------------------------------------------------
115  LMH.m_neighbors.erase(LMH.m_neighbors.find(Ai));
116  LMH.m_neighbors.insert(Ae);
117 
118  // * Reflect the change of coordinates in all existing arcs from/to "Ai",
119  // which are not part of the LMH (list of neighbors)
120  // "p" to " 0 (-) pose1wrt2 (+) (p (-) oldRef )"...
121  // NOTE: Arcs to "Ai" must be replaced by arcs to "Ae"
122  // ----------------------------------------------------------------------------------------------
123  {
124  TArcList lstArcs;
125  m_map.getNodeByID(Ai)->getArcs(lstArcs, LMH.m_ID);
126  for (TArcList::iterator arc = lstArcs.begin(); arc != lstArcs.end();
127  ++arc)
128  {
129  // TODO ...
130  }
131  }
132 
133  // * The node for "area Ai" must be deleted in the HMAP, and all its arcs.
134  // ----------------------------------------------------------------------------------------------
135  {
136  TArcList lstArcs;
137  m_map.getNodeByID(Ai)->getArcs(lstArcs);
138  for (TArcList::iterator arc = lstArcs.begin(); arc != lstArcs.end();
139  ++arc)
140  arc->reset(); // The "delete" will automatically remove the entry
141  // in "m_map". Other smrtpnts will be cleared too.
142 
143  m_map.getNodeByID(Ai).reset(); // The "delete" will automatically
144  // remove the entry in "m_map"
145  }
146 
147  // * Merge Ae into the LMH: This includes the change of coordinates to those
148  // used now in "Ai" and the rest of neighbors!
149  // ----------------------------------------------------------------------------------------------
150  CPose3DPDFParticles pdfAiRef;
151  LMH.getPoseParticles(poseID_Ai_origin, pdfAiRef);
152  CPose3D AiRef;
153  pdfAiRef.getMean(AiRef);
154  const CPose3D& Apose_ie = pose_i_wrt_e.mean;
155  // const CPose3D Apose_ei = -Apose_ie;
156  const CPose3D AeRefInLMH = AiRef + Apose_ie;
157 
158  CRobotPosesGraph::Ptr AePG =
159  m_map.getNodeByID(Ae)->m_annotations.getAs<CRobotPosesGraph>(
161 
162  // For each pose in Ae:
163  for (CRobotPosesGraph::const_iterator it = AePG->begin(); it != AePG->end();
164  ++it)
165  {
166  const TPoseID poseId = it->first;
167  const TPoseInfo& pi = it->second;
168 
169  // Insert the observations into the metric maps:
170  ASSERT_(LMH.m_poseParticles.m_particles.size() == pi.pdf.size());
171 
172  for (size_t i = 0; i < pi.pdf.size(); i++)
173  {
174  // Transport coordinates:
175  const CPose3D& p = *pi.pdf.m_particles[i].d;
176  LMH.m_poseParticles.m_particles[i].d->robotPoses[poseId] = AeRefInLMH + p;
177  // pi.sf.insertObservationsInto( &LMH.m_particles[i].d->metricMaps,
178  // pi.pdf.m_particles[i].d );
179  }
180 
181  // Add node membership:
182  LMH.m_nodeIDmemberships[poseId] = Ae;
183 
184  // Now, insert the SF
185  LMH.m_SFs[poseId] = pi.sf;
186 
187  // Also add to the list of poses pending to be evaluated by the AA:
188  LMH.m_posesPendingAddPartitioner.push_back(poseId);
189  }
190 
191  // * The current pose of the robot should be in the new coordinate system:
192  // ----------------------------------------------------------------------------------------------
193  // This is already done since the current pose is just another poseID and
194  // it's threaded like the others.
195 
196  // * Rebuild metric maps for consistency:
197  // ----------------------------------------------------------------------------------------------
198  LMH.rebuildMetricMaps();
199 
200  // * Update all the data in the node "Ae":
201  // ----------------------------------------------------------------------------------------------
202  LMH.updateAreaFromLMH(Ae);
203 
204  MRPT_END
205 }
std::shared_ptr< CRobotPosesGraph > Ptr
A namespace of pseudo-random numbers genrators of diferent distributions.
std::map< TPoseID, CHMHMapNode::TNodeID > m_nodeIDmemberships
The hybrid map node membership for each robot pose.
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values, timewatch, extensions to STL.
CPose3D mean
The mean value.
THypothesisID m_ID
The unique ID of the hypothesis (Used for accessing mrpt::slam::CHierarchicalMHMap).
Classes related to the implementation of Hybrid Metric Topological (HMT) SLAM.
mrpt::poses::CPose3DPDFParticles pdf
The robot pose PDF.
Scalar * iterator
Definition: eigen_plugins.h:26
STL namespace.
const Scalar * const_iterator
Definition: eigen_plugins.h:27
uint64_t TPoseID
An integer number uniquely identifying each robot pose stored in HMT-SLAM.
void getMean(CPose3D &mean_pose) const override
Returns an estimate of the pose, (the mean, or mathematical expectation of the PDF), computed as a weighted average over all m_particles.
CParticleList m_particles
The array of particles.
TPoseIDList m_posesPendingAddPartitioner
The list of poseIDs waiting to be added to the graph partitioner, what happens in the LSLAM thread ma...
#define MRPT_END
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...
This class is used in HMT-SLAM to represent each of the Local Metric Hypotheses (LMHs).
Classes for 2D/3D geometry representation, both of single values and probability density distribution...
Definition: CPoint.h:17
struct mrpt::hmtslam::CLocalMetricHypothesis::TRobotPosesPartitioning m_robotPosesGraph
std::map< TPoseID, mrpt::obs::CSensoryFrame > m_SFs
The SF gathered at each robot pose.
#define MRPT_START
void rebuildMetricMaps()
Rebuild the metric maps of all particles from the observations and their estimated poses...
A class used to store a 3D pose (a 3D translation + a rotation in 3D).
Definition: CPose3D.h:88
mrpt::obs::CSensoryFrame sf
The observations.
#define ASSERT_(f)
#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 updateAreaFromLMH(const CHMHMapNode::TNodeID areaID, bool eraseSFsFromLMH=false)
The corresponding node in the HMT map is updated with the robot poses & SFs in the LMH: the poses are ref...
#define NODE_ANNOTATION_POSES_GRAPH
CLSLAMParticleDataParticles m_poseParticles
GLfloat GLfloat p
Definition: glext.h:6305
A class for storing a sequence of arcs (a path).
void getPoseParticles(const TPoseID &poseID, mrpt::poses::CPose3DPDFParticles &outPDF) const
Returns the mean and covariance of each robot pose in this LMH, as computed from the set of particles...
TNodeIDSet m_neighbors
The list of all areas sourronding the current one (this includes the current area itself)...
Declares a class that represents a Probability Density function (PDF) of a 3D pose.
mrpt::utils::TNodeID TNodeID
The type of the IDs of nodes.
Definition: CHMHMapNode.h:47



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: ae4571287 Thu Nov 23 00:06:53 2017 +0100 at dom oct 27 23:51:55 CET 2019