44 void CHMTSLAM::thread_LSLAM()
48 unsigned int nIter = 0;
51 if (
obj->m_options.random_seed)
65 while ( !
obj->m_terminateThreads )
67 if (
obj->m_options.random_seed)
75 recMsg =
obj->m_LSLAM_queue.get();
78 obj->LSLAM_process_message( *recMsg );
85 if (!
obj->isInputQueueEmpty() )
87 if (
obj->m_options.random_seed)
91 CSerializablePtr nextObject =
obj->getNextObjectFromInputQueue();
95 CActionCollectionPtr actions;
96 CSensoryFramePtr observations;
99 actions = CActionCollectionPtr( nextObject );
102 observations = CSensoryFramePtr( nextObject );
103 else THROW_EXCEPTION(
"Element in the queue is neither CActionCollection nor CSensoryFrame!!");
117 for (it=
obj->m_LMHs.begin();it!=
obj->m_LMHs.end();it++)
124 obj->m_LSLAM_method->processOneLMH(
133 if (it->second.m_posesPendingAddPartitioner.size()>5)
138 unsigned nPosesToInsert = it->second.m_posesPendingAddPartitioner.size();
139 TMessageLSLAMfromAAPtr msgFromAA = CHMTSLAM::areaAbstraction( &it->second, it->second.m_posesPendingAddPartitioner );
141 obj->logFmt(mrpt::utils::LVL_DEBUG,
"[AreaAbstraction] Took %.03fms to insert %u new poses. AA\n", 1000*tictac.
Tac(), nPosesToInsert );
144 it->second.m_posesPendingAddPartitioner.clear();
147 if (
obj->m_options.random_seed)
153 obj->LSLAM_process_message_from_AA( *msgFromAA);
159 if (!it->second.m_areasPendingTBI.empty())
166 if (
obj->m_options.random_seed)
173 obj->logFmt(mrpt::utils::LVL_DEBUG,
"[TBI] Took %.03fms TBI\n", 1000*tictac.
Tac() );
178 obj->LSLAM_process_message_from_TBI( *msgFromTBI);
182 it->second.m_areasPendingTBI.clear();
192 nextObject.clear_unique();
198 if (
obj->m_options.LOG_OUTPUT_DIR.size() && (nIter %
obj->m_options.LOG_FREQUENCY)==0)
199 obj->generateLogFiles(nIter);
213 time_t timCreat,timExit;
double timCPU=0;
215 obj->logFmt(mrpt::utils::LVL_DEBUG,
"[thread_LSLAM] Thread finished. CPU time used:%.06f secs \n",timCPU);
216 obj->m_terminationFlag_LSLAM =
true;
219 catch(std::exception &e)
221 obj->m_terminationFlag_LSLAM =
true;
225 if (e.what())
obj->logFmt(mrpt::utils::LVL_DEBUG,
"%s", e.what() );
228 obj->m_terminateThreads =
true;
234 obj->m_terminationFlag_LSLAM =
true;
236 obj->logFmt(mrpt::utils::LVL_DEBUG,
"\n---------------------- EXCEPTION CAUGHT! ---------------------\n");
237 obj->logFmt(mrpt::utils::LVL_DEBUG,
" In CHierarchicalMappingFramework::thread_LSLAM. Unexpected runtime error!!\n");
242 obj->m_terminateThreads =
true;
249 void CHMTSLAM::LSLAM_process_message(
const CMessage &msg )
284 logFmt(mrpt::utils::LVL_INFO,
"[LSLAM_proc_msg_AA] Beginning of Msg from AA processing... [\n" );
288 ASSERT_( itLMH!=m_LMHs.end() );
296 if (LMH->m_SFs.find( *itPose ) == LMH->m_SFs.end() )
303 if ( LMH->m_currentRobotPose != itA->first )
308 if ( itA->first == *itPose )
313 if (!found)
THROW_EXCEPTION_FMT(
"LMH's pose %i not found in AA's partitions.", (
int)itA->first );
319 TNodeIDSet neighbors_before( LMH->m_neighbors );
327 ASSERT_(itCur != LMH->m_nodeIDmemberships.end() );
341 map< unsigned int, map<CHMHMapNode::TNodeID, unsigned int> > votes;
344 static int DEBUG_STEP = 0;
346 logFmt(mrpt::utils::LVL_INFO,
"[LSLAM_proc_msg_AA] DEBUG_STEP=%i\n",DEBUG_STEP);
350 DEBUG_STEP = DEBUG_STEP + 0;
357 s.saveToFile(
format(
"%s/HMAP_txt/HMAP_%05i_before.txt",m_options.LOG_OUTPUT_DIR.c_str(), DEBUG_STEP ) );
358 logFmt(mrpt::utils::LVL_INFO,
"[LSLAM_proc_msg_AA] Saved HMAP_%05i_before.txt\n",DEBUG_STEP);
366 ASSERT_(itP != LMH->m_nodeIDmemberships.end() );
368 votes[i][ itP->second ]++;
374 map<CHMHMapNode::TNodeID, pair<size_t, unsigned int> > mostVotedFrom;
378 for (
size_t k=0;k<myMsg.
partitions.size();k++)
380 if (votes[k].
size()==1)
382 if (votes[k].
begin()->second>mostVotedFrom[ votes[k].begin()->first ].second)
384 mostVotedFrom[ votes[k].begin()->first ].first = k;
385 mostVotedFrom[ votes[k].begin()->first ].second = votes[k].begin()->second;
393 v->second.second = std::numeric_limits<unsigned int>::max();
397 for (
size_t k=0;k<myMsg.
partitions.size();k++)
404 map<CHMHMapNode::TNodeID, pair<size_t, unsigned int> >
::iterator mostVotesIt;
405 mostVotesIt = mostVotedFrom.find( it->first );
406 if (mostVotesIt == mostVotedFrom.end())
409 mostVotedFrom[it->first].first = k;
410 mostVotedFrom[it->first].second = it->second;
415 if ( it->second > mostVotesIt->second.second )
417 mostVotesIt->second.first = k;
418 mostVotesIt->second.second = it->second;
426 partIdx2Areas[ it->second.first ] = it->first;
430 for (i=0;i<partIdx2Areas.size();i++)
437 CHMHMapNodePtr newArea = CHMHMapNode::Create( &m_map );
440 newArea->m_hypotheses.insert( LMH->m_ID );
441 newArea->m_nodeType.setType(
"Area" );
442 newArea->m_label = generateUniqueAreaLabel();
447 CRobotPosesGraphPtr emptyPoseGraph = CRobotPosesGraph::Create();
451 partIdx2Areas[i] = newArea->getID();
457 logFmt(mrpt::utils::LVL_INFO,
"[LSLAM_proc_msg_AA] partIdx2Areas:\n");
458 for (
size_t i=0;i<partIdx2Areas.size();i++)
459 logFmt(mrpt::utils::LVL_INFO,
" Partition #%i -> AREA_ID %i ('%s')\n",(
int)i,(int)partIdx2Areas[i], m_map.getNodeByID(partIdx2Areas[i])->m_label.c_str() );
467 LMH->m_neighbors.clear();
468 for (i=0;i<partIdx2Areas.size();i++)
473 LMH->m_neighbors.insert(nodeId);
477 LMH->m_nodeIDmemberships[ *it ] = nodeId;
485 LMH->getMeans( lstPoses );
488 const CPose3D *curPoseMean = & lstPoses[ LMH->m_currentRobotPose ];
492 if ( it->first != LMH->m_currentRobotPose )
497 closestPose = it->first;
509 LMH->m_nodeIDmemberships[ LMH->m_currentRobotPose ] = LMH->m_nodeIDmemberships[closestPose];
514 if (curAreaID!=oldAreaID)
515 logFmt(mrpt::utils::LVL_INFO,
"[LSLAM_proc_msg_AA] Current area has changed: %i -> %i\n",(
int)oldAreaID,(
int)curAreaID );
523 if ( LMH->m_neighbors.find(*pBef) == LMH->m_neighbors.end() )
528 logFmt(mrpt::utils::LVL_INFO,
"[LSLAM_proc_msg_AA] Old neighbors: ");
530 logFmt(mrpt::utils::LVL_INFO,
"%i ",(
int)*it);
531 logFmt(mrpt::utils::LVL_INFO,
"\n");
534 logFmt(mrpt::utils::LVL_INFO,
"[LSLAM_proc_msg_AA] Cur. neighbors: ");
536 logFmt(mrpt::utils::LVL_INFO,
"%i ",(
int)*it);
537 logFmt(mrpt::utils::LVL_INFO,
"\n");
545 CHMHMapNodePtr node = m_map.getNodeByID( *pBef );
549 logFmt(mrpt::utils::LVL_INFO,
"[LSLAM_proc_msg_AA] Area %i has been removed from the neighbors & no longer exists in the HMAP.\n", (
int)*pBef);
553 logFmt(mrpt::utils::LVL_INFO,
"[LSLAM_proc_msg_AA] Deleting area %i\n", (
int)node->getID() );
559 node->getArcs( arcs );
562 typedef map<CHMHMapNodePtr,CHMHMapArcPtr> TListNodesArcs;
563 TListNodesArcs lstWithinLMH;
567 CHMHMapNodePtr nodeB;
569 if ( (*a)->getNodeFrom() == *pBef )
571 nodeB = m_map.getNodeByID( (*a)->getNodeTo() );
575 nodeB = m_map.getNodeByID( (*a)->getNodeFrom() );
578 bool inNeib = LMH->m_neighbors.
find( nodeB->getID() ) != LMH->m_neighbors.end();
579 bool inBefNeib = neighbors_before.find( nodeB->getID() ) != neighbors_before.end();
581 if ( inNeib && inBefNeib )
582 lstWithinLMH[nodeB] = *
a;
589 CHMHMapNodePtr nodeB;
592 CHMHMapArcPtr arc = *
a;
594 if ( arc->getNodeFrom() == *pBef )
596 nodeB = m_map.getNodeByID( (*a)->getNodeTo() );
601 nodeB = m_map.getNodeByID( (*a)->getNodeFrom() );
605 bool inNeib = LMH->m_neighbors.find( nodeB->getID() ) != LMH->m_neighbors.end();
606 bool inBefNeib = neighbors_before.find( nodeB->getID() ) != neighbors_before.end();
608 if ( inNeib && inBefNeib )
622 CHMHMapNodePtr node_c = na->first;
623 const CHMHMapArcPtr arc_c_a = na->second;
652 pdf->inverse( Delta_b_a );
661 ASSERT_(node_refPoseAt_b==refPoseAt_b);
665 ASSERT_(node_refPoseAt_a==refPoseAt_a);
674 if ( arc_c_a->getNodeTo()==node_c->getID() )
684 pdf->inverse( Delta_a_c );
693 ASSERT_(node_refPoseAt_c==refPoseAt_c);
697 ASSERT_(node_refPoseAt_a==refPoseAt_a);
703 Delta_b_c.
cov.zeros();
713 bool arcDeltaIsInverted;
714 CHMHMapArcPtr newArc = m_map.findArcOfTypeBetweenNodes(
719 arcDeltaIsInverted );
724 newArc = CHMHMapArc::Create(
730 newArc->m_arcType.setType(
"RelativePose");
731 arcDeltaIsInverted =
false;
734 if (!arcDeltaIsInverted)
737 MRPT_LOG_DEBUG_STREAM(
"[LSLAM_proc_msg_AA] Setting arc " << nodeB->getID() <<
" -> " << node_c->getID() <<
" : " << Delta_b_c.
mean <<
" cov = " << Delta_b_c.
cov.inMatlabFormat() << endl);
744 Delta_b_c.
inverse( Delta_b_c_inv );
746 MRPT_LOG_DEBUG_STREAM(
"[LSLAM_proc_msg_AA] Setting arc " << nodeB->getID() <<
" <- " << node_c->getID() <<
" : " << Delta_b_c_inv.
mean <<
" cov = " << Delta_b_c_inv.
cov.inMatlabFormat() << endl);
754 arc->m_annotations.removeAll( LMH->m_ID );
756 if (!arc->m_annotations.size())
785 if ( curAreaID != oldAreaID )
787 LMH->m_areasPendingTBI.
insert(curAreaID);
788 logFmt(mrpt::utils::LVL_INFO,
"[LSLAM_proc_msg_AA] Current area changed: enqueing area %i for TBI.\n", (
int)curAreaID );
792 static size_t cntAddTBI = 0;
796 LMH->m_areasPendingTBI.insert(curAreaID);
797 logFmt(mrpt::utils::LVL_INFO,
"[LSLAM_proc_msg_AA] Current area %i enqued for TBI (routine check).\n", (
int)curAreaID );
815 if (partIdx2Areas.size()>1)
820 set<CHMHMapNode::TNodeID> areasWithLink;
823 map<CHMHMapNode::TNodeID, pair< CHMHMapNode::TNodeID, float > > lstClosestDoubtfulNeigbors;
825 for (
size_t idx_area_a=0;idx_area_a<partIdx2Areas.size();idx_area_a++)
830 CHMHMapNodePtr area_a = m_map.getNodeByID(area_a_ID);
848 logFmt(mrpt::utils::LVL_INFO,
"[LSLAM_proc_msg_AA] Changing reference poseID of area '%i' to pose '%i'\n", (
int)area_a_ID,(
int)poseID_trg);
863 TPoseID poseID_trg_old = poseID_trg;
877 logFmt(mrpt::utils::LVL_INFO,
"[LSLAM_proc_msg_AA] Changing reference poseID of area '%i' to pose '%i'\n", (
int)area_a_ID,(
int)poseID_trg);
885 area_a->getArcs( arcs );
888 CHMHMapArcPtr theArc = *
a;
898 if (nodeFrom==area_a_ID)
901 if (LMH->m_neighbors.find( nodeTo )==LMH->m_neighbors.end())
905 LMH->getRelativePose(poseID_trg, poseID_trg_old, Anew_old_parts);
908 Anew_old.
copyFrom( Anew_old_parts );
913 newDelta = Anew_old + *oldDelta;
914 newDelta.
cov.zeros();
918 MRPT_LOG_DEBUG_STREAM(
"[LSLAM_proc_msg_AA] Updating arc " << nodeFrom <<
" -> " << nodeTo <<
" OLD: " << oldDelta->mean <<
" cov = " << oldDelta->cov.inMatlabFormat() << endl);
919 MRPT_LOG_DEBUG_STREAM(
"[LSLAM_proc_msg_AA] Updating arc " << nodeFrom <<
" -> " << nodeTo <<
" NEW: " << newDelta.
mean <<
" cov = " << newDelta.
cov.inMatlabFormat() << endl);
928 if (LMH->m_neighbors.find( nodeFrom )==LMH->m_neighbors.end())
932 LMH->getRelativePose(poseID_trg_old, poseID_trg, Aold_new_parts);
935 Aold_new.
copyFrom( Aold_new_parts );
940 newDelta = *oldDelta + Aold_new;
942 newDelta.
cov.zeros();
943 newDelta.cov(0,0)=newDelta.cov(1,1)=
square(0.04);
946 MRPT_LOG_DEBUG_STREAM(
"[LSLAM_proc_msg_AA] Updating arc " << nodeFrom <<
" <- " << nodeTo <<
" OLD: " << oldDelta->mean <<
" cov = " << oldDelta->cov.inMatlabFormat() << endl);
947 MRPT_LOG_DEBUG_STREAM(
"[LSLAM_proc_msg_AA] Updating arc " << nodeFrom <<
" <- " << nodeTo <<
" NEW: " << newDelta.mean <<
" cov = " << newDelta.cov.inMatlabFormat() << endl);
959 for (
size_t idx_area_b=0;idx_area_b<myMsg.
partitions.size();idx_area_b++)
961 if (idx_area_a==idx_area_b)
continue;
964 double closestDistPoseSrc=0;
969 const CPose3D &pose_trg= lstPoses[*itP0];
973 const CPose3D &otherPose = lstPoses[*itP];
977 poseID_closests = *itP;
978 closestDistPoseSrc =
dst;
988 if ( closestDistPoseSrc< 5*m_options.SLAM_MIN_DIST_BETWEEN_OBS )
990 CHMHMapNodePtr area_b = m_map.getNodeByID( area_b_ID );
998 poseID_src = poseID_closests;
999 logFmt(mrpt::utils::LVL_INFO,
"[LSLAM_proc_msg_AA] Changing reference poseID of area '%i' to pose '%i' (creat. annot)\n", (
int)area_b_ID,(
int)poseID_closests);
1004 if ( lstInternalArcsToCreate.end() == lstInternalArcsToCreate.
find(
TPairNodeIDs( area_b_ID,area_a_ID )) &&
1005 lstInternalArcsToCreate.end() == lstInternalArcsToCreate.
find(
TPairNodeIDs( area_a_ID, area_b_ID)) )
1008 areasWithLink.insert( area_a_ID );
1009 areasWithLink.insert( area_b_ID );
1014 if (lstClosestDoubtfulNeigbors.find(area_b_ID) == lstClosestDoubtfulNeigbors.end() ||
1015 closestDistPoseSrc < lstClosestDoubtfulNeigbors[area_b_ID].second )
1017 lstClosestDoubtfulNeigbors[area_b_ID].first = area_a_ID;
1018 lstClosestDoubtfulNeigbors[area_b_ID].second = closestDistPoseSrc ;
1030 for (
size_t idx_area=0;idx_area<myMsg.
partitions.size();idx_area++)
1033 if (areasWithLink.find(area_ID) == areasWithLink.end())
1036 if (lstClosestDoubtfulNeigbors.find(area_ID) != lstClosestDoubtfulNeigbors.end() )
1042 areasWithLink.insert( area_ID );
1043 areasWithLink.insert( lstClosestDoubtfulNeigbors[area_ID].
first );
1056 logFmt(mrpt::utils::LVL_INFO,
"[LSLAM_proc_msg_AA] lstInternalArcsToCreate contains %i entries:\n",(
int)lstInternalArcsToCreate.size());
1062 logFmt(mrpt::utils::LVL_INFO,
" AREA %i <-> AREA %i\n", (
int)closestAreaID, (
int)newAreaID );
1089 LMH->getRelativePose(area_a_poseID_src, area_b_poseID_trg, relPoseParts );
1093 relPoseGauss.
copyFrom(relPoseParts);
1095 relPoseGauss.
cov.zeros();
1096 relPoseGauss.
cov(0,0)=relPoseGauss.
cov(1,1)=
square(0.04);
1099 logFmt(mrpt::utils::LVL_INFO,
"[LSLAM_proc_msg_AA] Creating arc %i[ref:%i] -> %i[ref:%i] = (%.03f,%.03f,%.03fdeg)\n",
1100 (
int)area_a_ID,(
int)area_a_poseID_src,
1101 (
int)area_b_ID,(
int)area_b_poseID_trg,
1107 bool arcDeltaIsInverted;
1108 CHMHMapArcPtr newArc = m_map.findArcOfTypeBetweenNodes(
1113 arcDeltaIsInverted );
1118 newArc = CHMHMapArc::Create(
1124 newArc->m_arcType.setType(
"RelativePose");
1125 arcDeltaIsInverted =
false;
1129 if (!arcDeltaIsInverted)
1131 MRPT_LOG_DEBUG_STREAM(
"[LSLAM_proc_msg_AA] Updating int. arc " << area_a_ID <<
" -> " << area_b_ID <<
" : " << relPoseGauss.
mean <<
" cov = " << relPoseGauss.
cov.inMatlabFormat() << endl);
1139 relPoseGauss.
inverse(relPoseInv);
1141 MRPT_LOG_DEBUG_STREAM(
"[LSLAM_proc_msg_AA] Updating int. arc " << area_a_ID <<
" <- " << area_b_ID <<
" : " << relPoseInv.
mean <<
" cov = " << relPoseInv.
cov.inMatlabFormat() << endl);
1165 CHMHMapNodePtr nodeFrom=m_map.getNodeByID(nodeFromID);
1168 nodeFrom->getArcs( lstArcs,
"RelativePose", LMH->m_ID );
1174 const CHMHMapNode::TNodeID nodeToID = (*a)->getNodeFrom()==nodeFromID ? (*a)->getNodeTo():(*a)->getNodeFrom();
1176 if (LMH->m_neighbors.find( nodeToID )!=LMH->m_neighbors.end())
1178 CHMHMapArcPtr arc = *
a;
1181 if ( lstInternalArcsToCreate.end() == lstInternalArcsToCreate.
find(
TPairNodeIDs( nodeFromID,nodeToID )) &&
1182 lstInternalArcsToCreate.end() == lstInternalArcsToCreate.
find(
TPairNodeIDs( nodeToID, nodeFromID)) )
1186 logFmt(mrpt::utils::LVL_INFO,
"[LSLAM_proc_msg_AA] Deleting annotation of arc: %lu-%lu\n", (
long unsigned)nodeFromID, (
long unsigned) nodeToID);
1190 logFmt(mrpt::utils::LVL_INFO,
"[LSLAM_proc_msg_AA] Deleting empty arc: %lu-%lu\n", (
long unsigned)nodeFromID, (
long unsigned) nodeToID);
1204 m_map.dumpAsText(
s);
1205 s.saveToFile(
format(
"%s/HMAP_txt/HMAP_%05i_mid.txt",m_options.LOG_OUTPUT_DIR.c_str(), DEBUG_STEP ) );
1206 logFmt(mrpt::utils::LVL_INFO,
"[LSLAM_proc_msg_AA] Saved HMAP_%05i_mid.txt\n",DEBUG_STEP);
1218 if (*pNei1 != curAreaID )
1223 m_map.findArcsOfTypeBetweenNodes( *pNei1, curAreaID , LMH->m_ID,
"RelativePose", lstArcs);
1225 if (lstArcs.empty())
1227 logFmt(mrpt::utils::LVL_INFO,
"[LSLAM_proc_msg_AA] Getting area '%u' out of LMH\n", static_cast<unsigned>(*pNei1) );
1235 double ESS_bef = LMH->ESS();
1236 LMH->removeAreaFromLMH(
id );
1237 double ESS_aft = LMH->ESS();
1238 logFmt(mrpt::utils::LVL_INFO,
"[LSLAM_proc_msg_AA] ESS: %f -> %f\n", ESS_bef, ESS_aft );
1256 CHMHMapNodePtr currentArea;
1261 currentArea = m_map.getNodeByID( curAreaID );
1263 TPoseID refPoseCurArea_accordingAnnot;
1267 currentArea->getArcs(arcsToCurArea,
"RelativePose",LMH->m_ID);
1270 const CHMHMapArcPtr arc = (*a);
1271 const CHMHMapNode::TNodeID otherAreaID = arc->getNodeFrom()==curAreaID ? arc->getNodeTo():arc->getNodeFrom();
1274 if ( LMH->m_neighbors.find(otherAreaID)==LMH->m_neighbors.end() )
1276 logFmt(mrpt::utils::LVL_INFO,
"[LSLAM_proc_msg_AA] Bringing in LMH area %i\n",(
int)otherAreaID );
1278 CHMHMapNodePtr area = m_map.getNodeByID( otherAreaID );
1291 TPoseID refPoseIDAtOtherArea, refPoseIDAtCurArea;
1293 if (arc->getNodeTo()==curAreaID)
1296 logFmt(mrpt::utils::LVL_INFO,
"[LSLAM_proc_msg_AA] Arc is inverted: (%.03f,%.03f,%.03fdeg) -> ",
1297 Delta_c2a.x(),Delta_c2a.y(),
RAD2DEG(Delta_c2a.yaw()) );
1299 Delta_c2a =
CPose3D(0,0,0) - Delta_c2a;
1301 logFmt(mrpt::utils::LVL_INFO,
"(%.03f,%.03f,%.03fdeg)\n",
1302 Delta_c2a.x(),Delta_c2a.y(),
RAD2DEG(Delta_c2a.yaw()) );
1314 logFmt(mrpt::utils::LVL_INFO,
"[LSLAM_proc_msg_AA] Bringing in: refPoseCur=%i refPoseOther=%i -> Delta_c2a:(%.03f,%.03f,%.03fdeg)\n",
1315 (
int)refPoseIDAtCurArea, (
int)refPoseIDAtOtherArea,
1316 Delta_c2a.x(),Delta_c2a.y(),
RAD2DEG(Delta_c2a.yaw()) );
1319 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG) 1321 TPoseID refPoseOtherArea_accordingAnnot;
1323 ASSERT_( refPoseIDAtOtherArea == refPoseOtherArea_accordingAnnot );
1325 ASSERT_( refPoseIDAtCurArea == refPoseCurArea_accordingAnnot );
1334 lstNewPoseIDs.reserve( pg->size() );
1340 lstNewPoseIDs.push_back(poseID);
1348 for (itSrc=poseInfo.
pdf.
m_particles.begin(), itTrg=LMH->m_particles.begin(); itTrg!=LMH->m_particles.end(); itSrc++,itTrg++)
1351 itTrg->d->robotPoses[ poseID ] = itTrg->d->robotPoses[ refPoseIDAtCurArea ] + Delta_c2a + *itSrc->d;
1355 LMH->m_nodeIDmemberships[ poseID ] = otherAreaID;
1358 LMH->m_SFs[ poseID ] = poseInfo.
sf;
1361 LMH->m_neighbors.
insert( otherAreaID );
1367 LMH->m_posesPendingAddPartitioner.insert( LMH->m_posesPendingAddPartitioner.end(),lstNewPoseIDs.begin(),lstNewPoseIDs.end() );
1370 areasDelayedMetricMapsInsertion.insert( otherAreaID );
1381 s.saveToFile(
format(
"%s/HMAP_txt/HMAP_%05i_LMH_mid.txt",m_options.LOG_OUTPUT_DIR.c_str(), DEBUG_STEP ) );
1382 logFmt(mrpt::utils::LVL_INFO,
"[LSLAM_proc_msg_AA] Saved HMAP_%05i_LMH_mid.txt\n",DEBUG_STEP);
1389 maps3D->setName(
"metric-maps" );
1390 LMH->getMostLikelyParticle()->d->metricMaps.getAs3DObject( maps3D );
1391 sceneLSLAM.
insert( maps3D );
1395 LSLAM_3D->setName(
"LSLAM_3D");
1396 LMH->getAs3DScene( LSLAM_3D );
1397 sceneLSLAM.
insert( LSLAM_3D );
1401 string filLocalAreas =
format(
"%s/HMAP_txt/HMAP_%05i_LMH_mid.3Dscene",m_options.LOG_OUTPUT_DIR.c_str(), DEBUG_STEP );
1402 logFmt(mrpt::utils::LVL_INFO,
"[LOG] Saving %s\n", filLocalAreas.c_str());
1415 if ( new_poseID_origin != poseID_origin )
1419 LMH->changeCoordinateOrigin( new_poseID_origin );
1420 logFmt(mrpt::utils::LVL_INFO,
"[LSLAM_proc_msg_AA] LMH->changeCoordinateOrigin %lu->%lu took %f ms\n", poseID_origin,new_poseID_origin,tictac.
Tac()*1000 );
1422 else if (areasDelayedMetricMapsInsertion.size())
1427 for (
TNodeIDSet::iterator areaID=areasDelayedMetricMapsInsertion.begin();areaID!=areasDelayedMetricMapsInsertion.end();++areaID)
1432 if (pn->second==*areaID)
1435 const TPoseID & poseToAdd = pn->first;
1436 const CSensoryFrame &SF = LMH->m_SFs.find(poseToAdd)->second;
1442 ASSERT_(pose3D!=partIt->d->robotPoses.end());
1449 logFmt(mrpt::utils::LVL_INFO,
"[LSLAM_proc_msg_AA] areasDelayedMetricMapsInsertion took %f ms\n", tictac.
Tac()*1000 );
1456 m_map.dumpAsText(
s);
1457 s.saveToFile(
format(
"%s/HMAP_txt/HMAP_%05i_after.txt",m_options.LOG_OUTPUT_DIR.c_str(), DEBUG_STEP ) );
1458 logFmt(mrpt::utils::LVL_INFO,
"[LSLAM_proc_msg_AA] Saved HMAP_%05i_after.txt\n",DEBUG_STEP);
1464 s.saveToFile(
format(
"%s/HMAP_txt/HMAP_%05i_LMH_after.txt",m_options.LOG_OUTPUT_DIR.c_str(), DEBUG_STEP ) );
1465 logFmt(mrpt::utils::LVL_INFO,
"[LSLAM_proc_msg_AA] Saved HMAP_%05i_LMH_after.txt\n",DEBUG_STEP);
1468 logFmt(mrpt::utils::LVL_INFO,
"[LSLAM_proc_msg_AA] Msg from AA took %f ms ]\n", tictac.Tac()*1000 );
1483 logFmt(mrpt::utils::LVL_INFO,
"[LSLAM_proc_msg_TBI] Beginning of Msg from TBI processing... [\n" );
1486 std::map<CHMHMapNode::TNodeID,CHMHMapNode::TNodeID> alreadyClosedLoops;
1490 logFmt(mrpt::utils::LVL_INFO,
"[LSLAM_proc_msg_TBI] Processing TLC of areas: %u <-> %u... \n",(
unsigned)myMsg.
cur_area, (
unsigned)candidate->first );
1494 if (alreadyClosedLoops.find(myMsg.
cur_area)!=alreadyClosedLoops.end())
1496 currentArea = alreadyClosedLoops[myMsg.
cur_area];
1497 cout <<
"[LSLAM_proc_msg_TBI] Using " << myMsg.
cur_area <<
" -> " << currentArea <<
" due to area being already merged." << endl;
1503 m_map.computeCoordinatesTransformationBetweenNodes(
1513 pdfDeltaMap.
copyFrom(pdfPartsHMap);
1523 cout <<
"[LSLAM_proc_msg_TBI] HMap_delta=" << pdfDeltaMap.
mean <<
" std_x=" << sqrt(pdfDeltaMap.
cov(0,0)) <<
" std_y=" << sqrt(pdfDeltaMap.
cov(1,1)) << endl;
1529 ASSERT_(!candidate->second.delta_new_cur.empty());
1532 map<double,CPose3DPDFGaussian> lstModesAndCompats;
1538 cout <<
"[LSLAM_proc_msg_TBI] TLC_delta=" << pdfDelta.
mean <<
" std_x=" << sqrt(pdfDelta.
cov(0,0)) <<
" std_y=" << sqrt(pdfDelta.
cov(1,1)) <<
" std_phi=" <<
RAD2DEG(sqrt(pdfDelta.
cov(3,3))) << endl;
1543 cout <<
"[LSLAM_proc_msg_TBI] maha_dist = " << mahaDist2 << endl;
1545 if (mahaDist2<chi2_thres)
1547 const double log_lik = itSOG->log_w - 0.5*mahaDist2;
1548 lstModesAndCompats[ log_lik ] = itSOG->val;
1549 cout <<
"[LSLAM_proc_msg_TBI] Added to list of candidates: log(overall_lik)= " << log_lik << endl;
1554 if (!lstModesAndCompats.empty())
1566 logFmt(mrpt::utils::LVL_INFO,
"[LSLAM_proc_msg_TBI] Accepting TLC of areas: %u <-> %u with an overall log(lik)=%f \n",(
unsigned)currentArea, (
unsigned)candidate->first,lstModesAndCompats.rbegin()->first );
1574 logFmt(mrpt::utils::LVL_INFO,
"[LSLAM_proc_msg_TBI] TLC of areas %u <-> %u - DONE in %.03f ms\n",(
unsigned)currentArea, (
unsigned)candidate->first,1e3*tictac.
Tac() );
1577 alreadyClosedLoops[myMsg.
cur_area] = candidate->first;
1584 logFmt(mrpt::utils::LVL_INFO,
"[LSLAM_proc_msg_TBI] Msg from TBI took %f ms ]\n", tictac.Tac()*1000 );
A namespace of pseudo-random numbers genrators of diferent distributions.
double x() const
Common members of all points & poses classes.
std::pair< TNodeID, TNodeID > TPairNodeIDs
A pair of node IDs.
A class acquiring a CCriticalSection at its constructor, and releasing it at destructor.
This class implements a STL container with features of both, a std::set and a std::list.
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values, timewatch, extensions to STL.
CPose3D mean
The mean value.
unsigned long BASE_IMPEXP getCurrentThreadId() MRPT_NO_THROWS
Returns the ID of the current thread.
double distanceTo(const CPoseOrPoint< OTHERCLASS > &b) const
Returns the Euclidean distance to another pose/point:
void copyFrom(const CPose3DPDF &o) MRPT_OVERRIDE
Copy operator, translating if necesary (for example, between particles and gaussian representations) ...
double mahalanobisDistanceTo(const CPose3DPDFGaussian &theOther)
Computes the Mahalanobis distance between the centers of two Gaussians.
Classes related to the implementation of Hybrid Metric Topological (HMT) SLAM.
void BASE_IMPEXP pause(const std::string &msg=std::string("Press any key to continue...")) MRPT_NO_THROWS
Shows the message "Press any key to continue" (or other custom message) to the current standard outpu...
#define THROW_EXCEPTION(msg)
BASE_IMPEXP CRandomGenerator randomGenerator
A static instance of a CRandomGenerator class, for use in single-thread applications.
void randomize(const uint32_t seed)
Initialize the PRNG from the given random seed.
#define THROW_EXCEPTION_FMT(_FORMAT_STRING,...)
mrpt::poses::CPose3DPDFParticles pdf
The robot pose PDF.
EIGEN_STRONG_INLINE iterator begin()
double yaw() const
Get the YAW angle (in radians)
THypothesisID hypothesisID
The hypothesis ID (LMH) for these results.
const Scalar * const_iterator
uint64_t TPoseID
An integer number uniquely identifying each robot pose stored in HMT-SLAM.
void Tic()
Starts the stopwatch.
GLsizei GLsizei GLuint * obj
Helper types for STL containers with Eigen memory allocators.
An implementation of Hybrid Metric Topological SLAM (HMT-SLAM).
Declares a class for storing a collection of robot actions.
T square(const T x)
Inline function for the square of a number.
std::list< T >::iterator erase_return_next(std::list< T > &cont, typename std::list< T >::iterator &it)
Calls the standard "erase" method of a STL container, but also returns an iterator to the next elemen...
double distanceEuclidean6D(const CPose3D &o) const
The euclidean distance between two poses taken as two 6-length vectors (angles in radians)...
void BASE_IMPEXP getCurrentThreadTimes(time_t &creationTime, time_t &exitTime, double &cpuTime)
Returns the creation and exit times of the current thread and its CPU time consumed.
CHMHMapNode::TNodeID cur_area
The area for who the loop-closure has been computed.
A class for storing a list of text lines.
CParticleList m_particles
The array of particles.
This base provides a set of functions for maths stuff.
void insert(const CRenderizablePtr &newObject, const std::string &viewportName=std::string("main"))
Insert a new object into the scene, in the given viewport (by default, into the "main" viewport)...
A set of hypothesis IDs, used for arcs and nodes in multi-hypothesis hybrid maps. ...
#define MRPT_UNUSED_PARAM(a)
Can be used to avoid "not used parameters" warnings from the compiler.
This CStream derived class allow using a file as a write-only, binary stream.
void BASE_IMPEXP sleep(int time_ms) MRPT_NO_THROWS
An OS-independent method for sending the current thread to "sleep" for a given period of time...
void enableFollowCamera(bool enabled)
If disabled (default), the SceneViewer application will ignore the camera of the "main" viewport and ...
mrpt::maps::CMultiMetricMapPtr CMultiMetricMapPtr
Backward compatible typedef.
TModesList::const_iterator const_iterator
This class implements a high-performance stopwatch.
This namespace contains representation of robot actions and observations.
void insert(const CObservationPtr &obs)
Inserts a new observation to the list: The pointer to the objects is copied, thus DO NOT delete the p...
Declares a class for storing a "sensory frame", a set of "observations" taken by the robot approximat...
std::string BASE_IMPEXP format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
Auxiliary class used in mrpt::slam::CLocalMetricHypothesis for HMT-SLAM; this class stores a set of r...
THypothesisID hypothesisID
The hypothesis ID (LMH) for these results.
This namespace provides multitask, synchronization utilities.
This class is used in HMT-SLAM to represent each of the Local Metric Hypotheses (LMHs).
std::vector< TPoseIDList > partitions
#define NODE_ANNOTATION_METRIC_MAPS
Classes for 2D/3D geometry representation, both of single values and probability density distribution...
std::vector< TPoseID > TPoseIDList
std::map< CHMHMapNode::TNodeID, TBI_info > loopClosureData
The meat is here: only feasible loop closures from "cur_area" are included here, with associated data...
void getMean(CPose3D &mean_pose) const MRPT_OVERRIDE
Returns an estimate of the pose, (the mean, or mathematical expectation of the PDF).
mrpt::aligned_containers< TPoseID, mrpt::poses::CPose3D >::map_t TMapPoseID2Pose3D
mrpt::math::CMatrixDouble66 cov
The 6x6 covariance matrix.
#define CLASS_ID(class_name)
Access to runtime class ID for a defined class name.
mrpt::maps::CMultiMetricMap CMultiMetricMap
Backward compatible typedef.
double BASE_IMPEXP chi2inv(double P, unsigned int dim=1)
The "quantile" of the Chi-Square distribution, for dimension "dim" and probability 0<P<1 (the inverse...
#define ARC_ANNOTATION_DELTA_SRC_POSEID
A class used to store a 3D pose (a 3D translation + a rotation in 3D).
mrpt::obs::CSensoryFrame sf
The observations.
std::set< CHMHMapNode::TNodeID > TNodeIDSet
The namespace for 3D scene representation and rendering.
This class allows the user to create, load, save, and render 3D scenes using OpenGL primitives...
double Tac()
Stops the stopwatch.
#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.
This class is a "CSerializable" wrapper for "CMatrixFloat".
#define NODE_ANNOTATION_POSES_GRAPH
std::list< T >::iterator find(const T &i)
#define MRPT_LOG_DEBUG_STREAM(__CONTENTS)
#define ARC_ANNOTATION_DELTA_TRG_POSEID
GLubyte GLubyte GLubyte a
A class for storing a sequence of arcs (a path).
void inverse(CPose3DPDF &o) const MRPT_OVERRIDE
Returns a new PDF such as: NEW_PDF = (0,0,0) - THIS_PDF.
#define ARC_ANNOTATION_DELTA
A class that contain generic messages, that can be sent and received from a "CClientTCPSocket" object...
stlplus::smart_ptr< TMessageLSLAMfromAA > TMessageLSLAMfromAAPtr
bool insertObservationsInto(mrpt::maps::CMetricMap *theMap, const mrpt::poses::CPose3D *robotPose=NULL) 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 Probability Density function (PDF) of a 3D pose.
mrpt::utils::TNodeID TNodeID
The type of the IDs of nodes.
stlplus::smart_ptr< TMessageLSLAMfromTBI > TMessageLSLAMfromTBIPtr
static CSetOfObjectsPtr Create()