29 #include "rtabmap/core/Version.h" 50 #include <pcl/search/kdtree.h> 51 #include <pcl/filters/crop_box.h> 52 #include <pcl/io/pcd_io.h> 53 #include <pcl/common/common.h> 54 #include <pcl/TextureMesh.h> 59 #define LOG_F "LogF.txt" 60 #define LOG_I "LogI.txt" 62 #define GRAPH_FILE_NAME "Graph.dot" 79 _publishStats(
Parameters::defaultRtabmapPublishStats()),
80 _publishLastSignatureData(
Parameters::defaultRtabmapPublishLastSignature()),
81 _publishPdf(
Parameters::defaultRtabmapPublishPdf()),
82 _publishLikelihood(
Parameters::defaultRtabmapPublishLikelihood()),
83 _publishRAMUsage(
Parameters::defaultRtabmapPublishRAMUsage()),
84 _computeRMSE(
Parameters::defaultRtabmapComputeRMSE()),
85 _saveWMState(
Parameters::defaultRtabmapSaveWMState()),
86 _maxTimeAllowed(
Parameters::defaultRtabmapTimeThr()),
87 _maxMemoryAllowed(
Parameters::defaultRtabmapMemoryThr()),
89 _loopRatio(
Parameters::defaultRtabmapLoopRatio()),
90 _verifyLoopClosureHypothesis(
Parameters::defaultVhEpEnabled()),
91 _maxRetrieved(
Parameters::defaultRtabmapMaxRetrieved()),
92 _maxLocalRetrieved(
Parameters::defaultRGBDMaxLocalRetrieved()),
93 _rawDataKept(
Parameters::defaultMemImageKept()),
94 _statisticLogsBufferedInRAM(
Parameters::defaultRtabmapStatisticLogsBufferedInRAM()),
95 _statisticLogged(
Parameters::defaultRtabmapStatisticLogged()),
96 _statisticLoggedHeaders(
Parameters::defaultRtabmapStatisticLoggedHeaders()),
97 _rgbdSlamMode(
Parameters::defaultRGBDEnabled()),
98 _rgbdLinearUpdate(
Parameters::defaultRGBDLinearUpdate()),
99 _rgbdAngularUpdate(
Parameters::defaultRGBDAngularUpdate()),
100 _rgbdLinearSpeedUpdate(
Parameters::defaultRGBDLinearSpeedUpdate()),
101 _rgbdAngularSpeedUpdate(
Parameters::defaultRGBDAngularSpeedUpdate()),
102 _newMapOdomChangeDistance(
Parameters::defaultRGBDNewMapOdomChangeDistance()),
103 _neighborLinkRefining(
Parameters::defaultRGBDNeighborLinkRefining()),
104 _proximityByTime(
Parameters::defaultRGBDProximityByTime()),
105 _proximityBySpace(
Parameters::defaultRGBDProximityBySpace()),
106 _scanMatchingIdsSavedInLinks(
Parameters::defaultRGBDScanMatchingIdsSavedInLinks()),
107 _localRadius(
Parameters::defaultRGBDLocalRadius()),
108 _localImmunizationRatio(
Parameters::defaultRGBDLocalImmunizationRatio()),
109 _proximityMaxGraphDepth(
Parameters::defaultRGBDProximityMaxGraphDepth()),
110 _proximityMaxPaths(
Parameters::defaultRGBDProximityMaxPaths()),
111 _proximityMaxNeighbors(
Parameters::defaultRGBDProximityPathMaxNeighbors()),
112 _proximityFilteringRadius(
Parameters::defaultRGBDProximityPathFilteringRadius()),
113 _proximityRawPosesUsed(
Parameters::defaultRGBDProximityPathRawPosesUsed()),
116 _optimizeFromGraphEnd(
Parameters::defaultRGBDOptimizeFromGraphEnd()),
117 _optimizationMaxError(
Parameters::defaultRGBDOptimizeMaxError()),
118 _startNewMapOnLoopClosure(
Parameters::defaultRtabmapStartNewMapOnLoopClosure()),
119 _startNewMapOnGoodSignature(
Parameters::defaultRtabmapStartNewMapOnGoodSignature()),
120 _goalReachedRadius(
Parameters::defaultRGBDGoalReachedRadius()),
121 _goalsSavedInUserData(
Parameters::defaultRGBDGoalsSavedInUserData()),
122 _pathStuckIterations(
Parameters::defaultRGBDPlanStuckIterations()),
123 _pathLinearVelocity(
Parameters::defaultRGBDPlanLinearVelocity()),
124 _pathAngularVelocity(
Parameters::defaultRGBDPlanAngularVelocity()),
125 _savedLocalizationIgnored(
Parameters::defaultRGBDSavedLocalizationIgnored()),
126 _loopClosureHypothesis(0,0.0
f),
127 _highestHypothesis(0,0.0
f),
128 _lastProcessTime(0.0),
129 _someNodesHaveBeenTransferred(
false),
130 _distanceTravelled(0.0
f),
131 _epipolarGeometry(0),
138 _mapCorrection(
Transform::getIdentity()),
139 _lastLocalizationNodeId(0),
141 _pathCurrentIndex(0),
143 _pathTransformToGoal(
Transform::getIdentity()),
145 _pathStuckDistance(0.0
f)
171 std::string attributes =
"a+";
193 fprintf(_foutFloat,
"Column headers:\n");
194 fprintf(_foutFloat,
" 1-Total iteration time (s)\n");
195 fprintf(_foutFloat,
" 2-Memory update time (s)\n");
196 fprintf(_foutFloat,
" 3-Retrieval time (s)\n");
197 fprintf(_foutFloat,
" 4-Likelihood time (s)\n");
198 fprintf(_foutFloat,
" 5-Posterior time (s)\n");
199 fprintf(_foutFloat,
" 6-Hypothesis selection time (s)\n");
200 fprintf(_foutFloat,
" 7-Hypothesis validation time (s)\n");
201 fprintf(_foutFloat,
" 8-Transfer time (s)\n");
202 fprintf(_foutFloat,
" 9-Statistics creation time (s)\n");
203 fprintf(_foutFloat,
" 10-Loop closure hypothesis value\n");
204 fprintf(_foutFloat,
" 11-NAN\n");
205 fprintf(_foutFloat,
" 12-NAN\n");
206 fprintf(_foutFloat,
" 13-NAN\n");
207 fprintf(_foutFloat,
" 14-NAN\n");
208 fprintf(_foutFloat,
" 15-NAN\n");
209 fprintf(_foutFloat,
" 16-Virtual place hypothesis\n");
210 fprintf(_foutFloat,
" 17-Join trash time (s)\n");
211 fprintf(_foutFloat,
" 18-Weight Update (rehearsal) similarity\n");
212 fprintf(_foutFloat,
" 19-Empty trash time (s)\n");
213 fprintf(_foutFloat,
" 20-Retrieval database access time (s)\n");
214 fprintf(_foutFloat,
" 21-Add loop closure link time (s)\n");
215 fprintf(_foutFloat,
" 22-Memory cleanup time (s)\n");
216 fprintf(_foutFloat,
" 23-Scan matching (odometry correction) time (s)\n");
217 fprintf(_foutFloat,
" 24-Local time loop closure detection time (s)\n");
218 fprintf(_foutFloat,
" 25-Local space loop closure detection time (s)\n");
219 fprintf(_foutFloat,
" 26-Map optimization (s)\n");
223 fprintf(_foutInt,
"Column headers:\n");
224 fprintf(_foutInt,
" 1-Loop closure ID\n");
225 fprintf(_foutInt,
" 2-Highest loop closure hypothesis\n");
226 fprintf(_foutInt,
" 3-Locations transferred\n");
227 fprintf(_foutInt,
" 4-NAN\n");
228 fprintf(_foutInt,
" 5-Words extracted from the last image\n");
229 fprintf(_foutInt,
" 6-Vocabulary size\n");
230 fprintf(_foutInt,
" 7-Working memory size\n");
231 fprintf(_foutInt,
" 8-Is loop closure hypothesis rejected?\n");
232 fprintf(_foutInt,
" 9-NAN\n");
233 fprintf(_foutInt,
" 10-NAN\n");
234 fprintf(_foutInt,
" 11-Locations retrieved\n");
235 fprintf(_foutInt,
" 12-Retrieval location ID\n");
236 fprintf(_foutInt,
" 13-Unique words extraced from last image\n");
237 fprintf(_foutInt,
" 14-Retrieval ID\n");
238 fprintf(_foutInt,
" 15-Non-null likelihood values\n");
239 fprintf(_foutInt,
" 16-Weight Update ID\n");
240 fprintf(_foutInt,
" 17-Is last location merged through Weight Update?\n");
241 fprintf(_foutInt,
" 18-Local graph size\n");
242 fprintf(_foutInt,
" 19-Sensor data id\n");
243 fprintf(_foutInt,
" 20-Indexed words\n");
244 fprintf(_foutInt,
" 21-Index memory usage (KB)\n");
254 UWARN(
"Working directory is not set, log disabled!");
276 fprintf(
_foutInt,
"%s", iter->c_str());
284 UDEBUG(
"path=%s", databasePath.c_str());
285 ParametersMap::const_iterator iter;
286 if((iter=parameters.find(Parameters::kRtabmapWorkingDirectory())) != parameters.end())
292 if(!_databasePath.empty())
295 UINFO(
"Using database \"%s\".", _databasePath.c_str());
299 UWARN(
"Using empty database. Mapping session will not be saved unless it is closed with an output database path.");
308 _memory->
init(_databasePath,
false, parameters,
true);
322 std::map<int, Transform> tmp;
327 if(_databasePath.empty())
334 void Rtabmap::init(
const std::string & configFile,
const std::string & databasePath)
339 if(!configFile.empty())
341 ULOGGER_DEBUG(
"Read parameters from = %s", configFile.c_str());
345 this->
init(param, databasePath);
350 UINFO(
"databaseSaved=%d", databaseSaved?1:0);
415 ParametersMap::const_iterator iter;
416 if((iter=parameters.find(Parameters::kRtabmapWorkingDirectory())) != parameters.end())
453 if(Parameters::parse(parameters, Parameters::kRGBDProximityAngle(),
_proximityAngle))
478 if((iter=parameters.find(Parameters::kOptimizerStrategy())) != parameters.end())
484 UDEBUG(
"new detector strategy %d",
int(optimizerType));
499 optimizerType = (
Optimizer::Type)Parameters::defaultOptimizerStrategy();
560 std::map<int, int> weights;
575 return std::set<int>();
610 return std::multimap<int, cv::KeyPoint>();
628 return Parameters::defaultMemGenerateIds();
680 UWARN(
"Initial pose can only be set in localization mode (%s=false), ignoring it...", Parameters::kMemIncrementalMemory().c_str());
690 std::map<int, int> reducedIds;
692 UINFO(
"New map triggered, new map = %d", mapId);
703 if(reducedIds.size() &&
_path.size())
705 for(
unsigned int i=0; i<
_path.size(); ++i)
707 std::map<int, int>::const_iterator iter = reducedIds.find(
_path[i].first);
708 if(iter!= reducedIds.end())
711 _path[i].first = iter->second;
733 UERROR(
"Last signature is null! Cannot set label \"%s\"", label.c_str());
753 UERROR(
"Last signature is null! Cannot set user data!");
771 ids.insert(std::pair<int,int>(
id, 0));
772 std::set<int> idsSet;
773 for(std::map<int, int>::iterator iter = ids.begin(); iter!=ids.end(); ++iter)
775 idsSet.insert(idsSet.end(), iter->first);
781 UERROR(
"No neighbors found for signature %d.",
id);
795 std::map<int, Transform> poses;
796 std::multimap<int, Link> constraints;
809 std::map<int, double> stamps;
812 for(std::map<int, Transform>::iterator iter=poses.begin(); iter!=poses.end(); ++iter)
818 std::vector<float> v;
821 stamps.insert(std::make_pair(iter->first, stamp));
860 UERROR(
"RTAB-Map is not initialized. No memory to reset...");
869 const cv::Mat & image,
871 const std::map<std::string, float> & externalStats)
878 float odomLinearVariance,
879 float odomAngularVariance,
880 const std::vector<float> & odomVelocity,
881 const std::map<std::string, float> & externalStats)
888 cv::Mat covariance = cv::Mat::eye(6,6,CV_64FC1);
889 covariance.at<
double>(0,0) = odomLinearVariance;
890 covariance.at<
double>(1,1) = odomLinearVariance;
891 covariance.at<
double>(2,2) = odomLinearVariance;
892 covariance.at<
double>(3,3) = odomAngularVariance;
893 covariance.at<
double>(4,4) = odomAngularVariance;
894 covariance.at<
double>(5,5) = odomAngularVariance;
895 return process(data, odomPose, covariance, odomVelocity, externalStats);
900 const cv::Mat & odomCovariance,
901 const std::vector<float> & odomVelocity,
902 const std::map<std::string, float> & externalStats)
911 double timeMemoryUpdate = 0;
912 double timeNeighborLinkRefining = 0;
913 double timeProximityByTimeDetection = 0;
914 double timeProximityBySpaceVisualDetection = 0;
915 double timeProximityBySpaceDetection = 0;
916 double timeCleaningNeighbors = 0;
917 double timeReactivations = 0;
918 double timeAddLoopClosureLink = 0;
919 double timeMapOptimization = 0;
920 double timeRetrievalDbAccess = 0;
921 double timeLikelihoodCalculation = 0;
922 double timePosteriorCalculation = 0;
923 double timeHypothesesCreation = 0;
924 double timeHypothesesValidation = 0;
925 double timeRealTimeLimitReachedProcess = 0;
926 double timeMemoryCleanup = 0;
927 double timeEmptyingTrash = 0;
928 double timeJoiningTrash = 0;
929 double timeStatsCreation = 0;
931 float hypothesisRatio = 0.0f;
932 bool rejectedHypothesis =
false;
934 std::map<int, float> rawLikelihood;
935 std::map<int, float> adjustedLikelihood;
936 std::map<int, float> likelihood;
937 std::map<int, int> weights;
938 std::map<int, float> posterior;
939 std::list<std::pair<int, float> > reactivateHypotheses;
941 std::map<int, int> childCount;
942 std::set<int> signaturesRetrieved;
943 int proximityDetectionsInTimeFound = 0;
952 std::set<int> immunizedLocations;
955 for(std::map<std::string, float>::const_iterator iter=externalStats.begin(); iter!=externalStats.end(); ++iter)
975 bool fakeOdom =
false;
990 UWARN(
"Update map correction based on last localization saved in database! correction = %s, nearest id = %d of last pose = %s, odom = %s",
1002 UERROR(
"RGB-D SLAM mode is enabled, memory is incremental but no odometry is provided. " 1003 "Image %d is ignored!", data.
id());
1027 UWARN(
"Odometry is reset (identity pose detected). Increment map id to %d!", mapId);
1038 UWARN(
"Odometry is reset (large odometry change detected > %f). A new map (%d) is created! Last pose = %s, new pose = %s",
1039 _newMapOdomChangeDistance,
1071 UFATAL(
"Not supposed to be here...last signature is null?!?");
1075 timeMemoryUpdate = timer.
ticks();
1076 ULOGGER_INFO(
"timeMemoryUpdate=%fs", timeMemoryUpdate);
1081 bool smallDisplacement =
false;
1082 bool tooFastMovement =
false;
1083 std::list<int> signaturesRemoved;
1086 statistics_.
addStatistic(Statistics::kMemoryOdometry_variance_lin(), odomCovariance.empty()?1.0f:(float)odomCovariance.at<
double>(0,0));
1087 statistics_.
addStatistic(Statistics::kMemoryOdometry_variance_ang(), odomCovariance.empty()?1.0f:(float)odomCovariance.at<
double>(5,5));
1102 const std::map<int, Link> & links = signature->
getLinks();
1111 links.begin()->second.transform().getTranslationAndEulerAngles(x,y,z, roll,pitch,yaw);
1125 smallDisplacement =
true;
1130 if(odomVelocity.size() == 6)
1148 int oldId = signature->
getLinks().begin()->first;
1156 if(smallDisplacement)
1158 if(signature->
getLinks().begin()->second.transVariance() == 1)
1161 UDEBUG(
"Set small variance. The robot is not moving.");
1175 UINFO(
"Odometry refining: update neighbor link (%d->%d, variance:lin=%f, ang=%f) from %s to %s",
1178 info.covariance.at<
double>(0,0),
1179 info.covariance.at<
double>(5,5),
1182 UASSERT(info.covariance.at<
double>(0,0) > 0.0 && info.covariance.at<
double>(5,5) > 0.0);
1191 std::map<int, Transform>::iterator jter =
_optimizedPoses.find(oldId);
1197 iter->second = mapCorrectionInv * up * iter->second;
1203 UINFO(
"Odometry refining rejected: %s", info.rejectedMsg.c_str());
1204 if(!info.covariance.empty() && info.covariance.at<
double>(0,0) > 0.0 && info.covariance.at<
double>(0,0) != 1.0 && info.covariance.at<
double>(5,5) > 0.0 && info.covariance.at<
double>(5,5) != 1.0)
1206 std::cout << info.covariance << std::endl;
1218 timeNeighborLinkRefining = timer.
ticks();
1219 ULOGGER_INFO(
"timeOdometryRefining=%fs", timeNeighborLinkRefining);
1230 UERROR(
"Map correction should be identity when optimizing from the last node. T=%s NewPose=%s OldPose=%s",
1238 UWARN(
"Neighbor link refining is activated but there are intermediate nodes, aborting refining...");
1255 "Only forward links should be added.");
1257 Link tmp = signature->
getLinks().begin()->second.inverse();
1269 tmp =
_constraints.rbegin()->second.merge(tmp, tmp.type());
1282 for(
unsigned int i=0; i<
_path.size(); ++i)
1288 _path[i].first = iter->second;
1301 if(jter->second.from() == iter->first || jter->second.to() == iter->first)
1323 for(std::set<int>::const_reverse_iterator iter = stm.rbegin(); iter!=stm.rend(); ++iter)
1325 if(*iter != signature->
id() &&
1330 std::string rejectedMsg;
1331 UDEBUG(
"Check local transform between %d and %d", signature->
id(), *iter);
1344 transform = transform.
inverse();
1345 UDEBUG(
"Add local loop closure in TIME (%d->%d) %s",
1350 UASSERT(info.covariance.at<
double>(0,0) > 0.0 && info.covariance.at<
double>(5,5) > 0.0);
1353 ++proximityDetectionsInTimeFound;
1354 UINFO(
"Local loop closure found between %d and %d with t=%s",
1355 *iter, signature->
id(), transform.prettyPrint().c_str());
1359 UWARN(
"Cannot add local loop closure between %d and %d ?!?",
1360 *iter, signature->
id());
1365 UINFO(
"Local loop closure (time) between %d and %d rejected: %s",
1366 *iter, signature->
id(), rejectedMsg.c_str());
1373 timeProximityByTimeDetection = timer.
ticks();
1374 UINFO(
"timeProximityByTimeDetection=%fs", timeProximityByTimeDetection);
1379 int previousId = signature->
getLinks().size() && signature->
getLinks().begin()->first!=signature->
id()?signature->
getLinks().begin()->first:0;
1395 std::list<int> signaturesToCompare;
1406 signaturesToCompare.push_back(iter->first);
1412 signaturesToCompare.push_back(iter->first);
1419 likelihood = rawLikelihood;
1422 timeLikelihoodCalculation = timer.
ticks();
1423 ULOGGER_INFO(
"timeLikelihoodCalculation=%fs",timeLikelihoodCalculation);
1433 timePosteriorCalculation = timer.
ticks();
1434 ULOGGER_INFO(
"timePosteriorCalculation=%fs",timePosteriorCalculation);
1446 if(posterior.size())
1448 for(std::map<int, float>::const_reverse_iterator iter = posterior.rbegin(); iter != posterior.rend(); ++iter)
1458 timeHypothesesCreation = timer.
ticks();
1481 rejectedHypothesis =
true;
1482 if(posterior.size() <= 2 && loopThr>0.0f)
1485 UDEBUG(
"rejected hypothesis: single hypothesis");
1489 UWARN(
"rejected hypothesis: by epipolar geometry");
1493 UWARN(
"rejected hypothesis: not satisfying hypothesis ratio (%f < %f * %f)",
1496 else if(
_loopRatio > 0.0
f && lastHighestHypothesis.second == 0)
1498 UWARN(
"rejected hypothesis: last closure hypothesis is null (loop ratio is on)");
1503 rejectedHypothesis =
false;
1506 timeHypothesesValidation = timer.
ticks();
1507 ULOGGER_INFO(
"timeHypothesesValidation=%fs",timeHypothesesValidation);
1514 rejectedHypothesis =
true;
1523 else if(!signature->
isBadSignature() && (smallDisplacement || tooFastMovement))
1533 timeJoiningTrash = timer.
ticks();
1534 ULOGGER_INFO(
"Time emptying memory trash = %fs, joining (actual overhead) = %fs", timeEmptyingTrash, timeJoiningTrash);
1540 std::list<int> reactivatedIds;
1541 double timeGetNeighborsTimeDb = 0.0;
1542 double timeGetNeighborsSpaceDb = 0.0;
1543 int immunizedGlobally = 0;
1544 int immunizedLocally = 0;
1545 if(retrievalId > 0 )
1548 ULOGGER_INFO(
"Retrieving locations... around id=%d", retrievalId);
1550 UASSERT(neighborhoodSize >= 0);
1554 unsigned int nbLoadedFromDb = 0;
1555 std::set<int> reactivatedIdsSet;
1556 std::map<int, int> neighbors;
1557 int nbDirectNeighborsInDb = 0;
1570 &timeGetNeighborsTimeDb);
1571 ULOGGER_DEBUG(
"neighbors of %d in time = %d", retrievalId, (
int)neighbors.size());
1573 bool firstPassDone =
false;
1575 while(m < neighborhoodSize)
1577 std::set<int> idsSorted;
1578 for(std::map<int, int>::iterator iter=neighbors.begin(); iter!=neighbors.end();)
1582 neighbors.erase(iter++);
1584 else if(iter->second == m)
1586 if(reactivatedIdsSet.find(iter->first) == reactivatedIdsSet.end())
1588 idsSorted.insert(iter->first);
1589 reactivatedIdsSet.insert(iter->first);
1593 ++nbDirectNeighborsInDb;
1597 if(immunizedLocations.insert(iter->first).second)
1599 ++immunizedGlobally;
1604 neighbors.erase(iter++);
1611 firstPassDone =
true;
1612 reactivatedIds.insert(reactivatedIds.end(), idsSorted.rbegin(), idsSorted.rend());
1626 &timeGetNeighborsSpaceDb);
1627 ULOGGER_DEBUG(
"neighbors of %d in space = %d", retrievalId, (
int)neighbors.size());
1628 firstPassDone =
false;
1630 while(m < neighborhoodSize)
1632 std::set<int> idsSorted;
1633 for(std::map<int, int>::iterator iter=neighbors.begin(); iter!=neighbors.end();)
1637 neighbors.erase(iter++);
1639 else if(iter->second == m)
1641 if(reactivatedIdsSet.find(iter->first) == reactivatedIdsSet.end())
1643 idsSorted.insert(iter->first);
1644 reactivatedIdsSet.insert(iter->first);
1648 ++nbDirectNeighborsInDb;
1652 neighbors.erase(iter++);
1659 firstPassDone =
true;
1660 reactivatedIds.insert(reactivatedIds.end(), idsSorted.rbegin(), idsSorted.rend());
1664 "reactivatedIds.size=%d, " 1665 "nbLoadedFromDb=%d, " 1666 "nbDirectNeighborsInDb=%d, " 1667 "time=%fs (%fs %fs)",
1669 reactivatedIds.size(),
1670 (int)nbLoadedFromDb,
1671 nbDirectNeighborsInDb,
1673 timeGetNeighborsTimeDb,
1674 timeGetNeighborsSpaceDb);
1681 std::list<int> retrievalLocalIds;
1690 float distanceSoFar = 0.0f;
1697 distanceSoFar +=
_path[i-1].second.getDistance(
_path[i].second);
1704 if(immunizedLocations.insert(
_path[i].first).second)
1708 UDEBUG(
"Path immunization: node %d (dist=%fm)",
_path[i].first, distanceSoFar);
1712 UINFO(
"retrieval of node %d on path (dist=%fm)",
_path[i].first, distanceSoFar);
1713 retrievalLocalIds.push_back(
_path[i].first);
1719 UDEBUG(
"Stop on node %d (dist=%fm > %fm)",
1727 if(immunizedLocally < maxLocalLocationsImmunized &&
1730 std::map<int ,Transform> poses;
1736 poses.insert(*iter);
1745 std::multimap<int, int> links;
1750 links.insert(std::make_pair(iter->second.from(), iter->second.to()));
1751 links.insert(std::make_pair(iter->second.to(), iter->second.from()));
1756 if(path.size() == 0)
1758 UWARN(
"Could not compute a path between %d and %d", nearestId, signature->
id());
1762 for(std::list<std::pair<int, Transform> >::iterator iter=path.begin();
1766 if(immunizedLocally >= maxLocalLocationsImmunized)
1771 UWARN(
"Could not immunize the whole local path (%d) between " 1772 "%d and %d (max location immunized=%d). You may want " 1773 "to increase RGBD/LocalImmunizationRatio (current=%f (%d of WM=%d)) " 1774 "to be able to immunize longer paths.",
1778 maxLocalLocationsImmunized,
1780 maxLocalLocationsImmunized,
1787 if(immunizedLocations.insert(iter->first).second)
1802 std::multimap<float, int> nearNodesByDist;
1803 for(std::map<int, float>::iterator iter=nearNodes.begin(); iter!=nearNodes.end(); ++iter)
1805 nearNodesByDist.insert(std::make_pair(iter->second, iter->first));
1807 UINFO(
"near nodes=%d, max local immunized=%d, ratio=%f WM=%d",
1808 (
int)nearNodesByDist.size(),
1809 maxLocalLocationsImmunized,
1812 for(std::multimap<float, int>::iterator iter=nearNodesByDist.begin();
1813 iter!=nearNodesByDist.end() && (retrievalLocalIds.size() <
_maxLocalRetrieved || immunizedLocally < maxLocalLocationsImmunized);
1821 const std::map<int, Link> & links = s->
getLinks();
1822 for(std::map<int, Link>::const_reverse_iterator jter=links.rbegin();
1828 UINFO(
"retrieval of node %d on local map", jter->first);
1829 retrievalLocalIds.push_back(jter->first);
1832 if(!
_memory->
isInSTM(s->
id()) && immunizedLocally < maxLocalLocationsImmunized)
1834 if(immunizedLocations.insert(s->
id()).second)
1845 std::set<int> retrievalLocalIdsSet(retrievalLocalIds.begin(), retrievalLocalIds.end());
1846 for(std::list<int>::iterator iter=retrievalLocalIds.begin();
1851 for(std::map<int, int>::reverse_iterator jter=ids.rbegin();
1856 retrievalLocalIdsSet.find(jter->first) == retrievalLocalIdsSet.end())
1858 UINFO(
"retrieval of node %d on local map", jter->first);
1859 retrievalLocalIds.push_back(jter->first);
1860 retrievalLocalIdsSet.insert(jter->first);
1867 for(std::multimap<float, int>::reverse_iterator iter=nearNodesByDist.rbegin(); iter!=nearNodesByDist.rend(); ++iter)
1873 reactivatedIds.insert(reactivatedIds.begin(), retrievalLocalIds.begin(), retrievalLocalIds.end());
1879 if(reactivatedIds.size())
1886 timeRetrievalDbAccess);
1888 ULOGGER_INFO(
"retrieval of %d (db time = %fs)", (
int)signaturesRetrieved.size(), timeRetrievalDbAccess);
1890 timeRetrievalDbAccess += timeGetNeighborsTimeDb + timeGetNeighborsSpaceDb;
1891 UINFO(
"total timeRetrievalDbAccess=%fs", timeRetrievalDbAccess);
1894 immunizedLocations.insert(signaturesRetrieved.begin(), signaturesRetrieved.end());
1896 timeReactivations = timer.
ticks();
1897 ULOGGER_INFO(
"timeReactivations=%fs", timeReactivations);
1903 std::list<std::pair<int, int> > loopClosureLinksAdded;
1904 int loopClosureVisualInliers = 0;
1905 int loopClosureVisualMatches = 0;
1906 float loopClosureLinearVariance = 0.0f;
1907 float loopClosureAngularVariance = 0.0f;
1913 info.
covariance = cv::Mat::eye(6,6,CV_64FC1);
1917 loopClosureVisualInliers = info.
inliers;
1918 loopClosureVisualMatches = info.
matches;
1921 loopClosureLinearVariance = info.
covariance.at<
double>(0,0);
1922 loopClosureAngularVariance = info.
covariance.at<
double>(3,3);
1924 rejectedHypothesis = transform.
isNull();
1925 if(rejectedHypothesis)
1927 UWARN(
"Rejected loop closure %d -> %d: %s",
1932 transform = transform.
inverse();
1935 if(!rejectedHypothesis)
1940 if(!rejectedHypothesis)
1946 if(rejectedHypothesis)
1952 timeAddLoopClosureLink = timer.
ticks();
1953 ULOGGER_INFO(
"timeAddLoopClosureLink=%fs", timeAddLoopClosureLink);
1955 int proximityDetectionsAddedVisually = 0;
1956 int proximityDetectionsAddedByICPOnly = 0;
1957 int lastProximitySpaceClosureId = 0;
1958 int proximitySpacePaths = 0;
1959 int localVisualPathsChecked = 0;
1960 int localScanPathsChecked = 0;
1968 UWARN(
"Cannot do local loop closure detection in space if graph optimization is disabled!");
1987 UDEBUG(
"Proximity detection (local loop closure in SPACE using matching images)");
1988 std::map<int, float> nearestIds;
1998 std::map<int, Transform> nearestPoses;
1999 for(std::map<int, float>::iterator iter=nearestIds.begin(); iter!=nearestIds.end(); ++iter)
2003 nearestPoses.insert(std::make_pair(iter->first,
_optimizedPoses.at(iter->first)));
2006 UDEBUG(
"nearestPoses=%d", (
int)nearestPoses.size());
2012 for(std::map<
int, std::map<int, Transform> >::const_reverse_iterator iter=nearestPaths.rbegin();
2013 iter!=nearestPaths.rend() &&
2018 std::map<int, Transform> path = iter->second;
2028 if(!signature->
hasLink(nearestId) &&
2032 ++localVisualPathsChecked;
2038 transform = transform.
inverse();
2041 UINFO(
"[Visual] Add local loop closure in SPACE (%d->%d) %s",
2047 loopClosureLinksAdded.push_back(std::make_pair(signature->
id(), nearestId));
2051 ++proximityDetectionsAddedVisually;
2052 lastProximitySpaceClosureId = nearestId;
2054 loopClosureVisualInliers = info.
inliers;
2055 loopClosureVisualMatches = info.
matches;
2058 loopClosureLinearVariance = info.
covariance.at<
double>(0,0);
2059 loopClosureAngularVariance = info.
covariance.at<
double>(3,3);
2065 UWARN(
"Ignoring local loop closure with %d because resulting " 2066 "transform is too large!? (%fm > %fm)",
2074 timeProximityBySpaceVisualDetection = timer.
ticks();
2075 ULOGGER_INFO(
"timeProximityBySpaceVisualDetection=%fs", timeProximityBySpaceVisualDetection);
2080 UDEBUG(
"Proximity detection (local loop closure in SPACE with scan matching)");
2083 UDEBUG(
"Proximity by scan matching is disabled (%s=%d).", Parameters::kRGBDProximityPathMaxNeighbors().c_str(),
_proximityMaxNeighbors);
2092 proximitySpacePaths = (int)nearestPaths.size();
2093 for(std::map<
int, std::map<int, Transform> >::const_reverse_iterator iter=nearestPaths.rbegin();
2094 iter!=nearestPaths.rend() &&
2099 std::map<int, Transform> path = iter->second;
2108 if(!signature->
hasLink(nearestId))
2112 std::map<int, Transform> filteredPath;
2114 std::map<int, Transform>::iterator nearestIdIter = path.find(nearestId);
2115 for(std::map<int, Transform>::iterator iter=nearestIdIter; iter!=path.end() && i<=
_proximityMaxNeighbors; ++iter, ++i)
2117 filteredPath.insert(*iter);
2120 for(std::map<int, Transform>::reverse_iterator iter(nearestIdIter); iter!=path.rend() && i<=
_proximityMaxNeighbors; ++iter, ++i)
2122 filteredPath.insert(*iter);
2124 path = filteredPath;
2136 for(std::map<int, Transform>::iterator jter=path.begin(); jter!=path.end(); ++jter)
2138 jter->second = t * jter->second;
2141 std::map<int, Transform> filteredPath = path;
2147 filteredPath.insert(*path.find(nearestId));
2150 if(filteredPath.size() > 0)
2153 filteredPath.insert(std::make_pair(signature->
id(),
_optimizedPoses.at(signature->
id())));
2157 ++localScanPathsChecked;
2162 UINFO(
"[Scan matching] Add local loop closure in SPACE (%d->%d) %s",
2167 cv::Mat scanMatchingIds;
2170 std::stringstream stream;
2172 for(std::map<int, Transform>::iterator iter=path.begin(); iter!=path.end(); ++iter)
2174 if(iter != path.begin())
2180 std::string scansStr = stream.str();
2181 scanMatchingIds = cv::Mat(1,
int(scansStr.size()+1), CV_8SC1, (
void *)scansStr.c_str());
2188 loopClosureLinksAdded.push_back(std::make_pair(signature->
id(), nearestId));
2190 ++proximityDetectionsAddedByICPOnly;
2195 lastProximitySpaceClosureId = nearestId;
2214 timeProximityBySpaceDetection = timer.
ticks();
2215 ULOGGER_INFO(
"timeProximityBySpaceDetection=%fs", timeProximityBySpaceDetection);
2236 UERROR(
"Virtual link larger than local radius (%fm > %fm). Aborting the plan!",
2246 float maxLinearError = 0.0f;
2247 float maxLinearErrorRatio = 0.0f;
2248 float maxAngularError = 0.0f;
2249 float maxAngularErrorRatio = 0.0f;
2250 double optimizationError = 0.0;
2251 int optimizationIterations = 0;
2252 cv::Mat localizationCovariance;
2255 lastProximitySpaceClosureId>0 ||
2258 proximityDetectionsInTimeFound>0 ||
2260 signaturesRetrieved.size())))
2273 signaturesRetrieved.size() == 0 &&
2274 localizationLinks.size() &&
2281 UINFO(
"Localization without map optimization");
2289 Transform u = signature->
getPose() * localizationLinks.begin()->second.transform();
2293 iter->second = mapCorrectionInv * up * iter->second;
2301 localizationCovariance = localizationLinks.begin()->second.infMatrix().inv();
2306 UINFO(
"Update map correction");
2318 UWARN(
"Optimization: clearing guess poses as %s may have changed state, now %s (normMapCorrection=%f)", Parameters::kRGBDOptimizeFromGraphEnd().c_str(),
_optimizeFromGraphEnd?
"true":
"false", normMapCorrection);
2325 std::multimap<int, Link> constraints;
2327 optimizeCurrentMap(signature->
id(),
false, poses, covariance, &constraints, &optimizationError, &optimizationIterations);
2331 bool updateConstraints =
true;
2334 UWARN(
"Graph optimization failed! Rejecting last loop closures added.");
2335 for(std::list<std::pair<int, int> >::iterator iter=loopClosureLinksAdded.begin(); iter!=loopClosureLinksAdded.end(); ++iter)
2338 UWARN(
"Loop closure %d->%d rejected!", iter->first, iter->second);
2340 updateConstraints =
false;
2342 lastProximitySpaceClosureId = 0;
2343 rejectedHypothesis =
true;
2347 loopClosureLinksAdded.size() &&
2348 optimizationIterations > 0 &&
2351 const Link * maxLinearLink = 0;
2352 const Link * maxAngularLink = 0;
2353 for(std::multimap<int, Link>::iterator iter=constraints.begin(); iter!=constraints.end(); ++iter)
2356 if(iter->second.transVariance() <= 1.0 && iter->second.from() != iter->second.to())
2361 float linearError =
uMax3(
2362 fabs(iter->second.transform().x() - t.x()),
2363 fabs(iter->second.transform().y() - t.y()),
2364 fabs(iter->second.transform().z() - t.z()));
2365 float opt_roll,opt__pitch,opt__yaw;
2366 float link_roll,link_pitch,link_yaw;
2367 t.getEulerAngles(opt_roll, opt__pitch, opt__yaw);
2368 iter->second.transform().getEulerAngles(link_roll, link_pitch, link_yaw);
2369 float angularError =
uMax3(
2370 fabs(opt_roll - link_roll),
2371 fabs(opt__pitch - link_pitch),
2372 fabs(opt__yaw - link_yaw));
2373 float stddevLinear =
sqrt(iter->second.transVariance());
2374 float linearErrorRatio = linearError/stddevLinear;
2375 if(linearErrorRatio > maxLinearErrorRatio)
2377 maxLinearError = linearError;
2378 maxLinearErrorRatio = linearErrorRatio;
2379 maxLinearLink = &iter->second;
2381 float stddevAngular =
sqrt(iter->second.rotVariance());
2382 float angularErrorRatio = angularError/stddevAngular;
2383 if(angularErrorRatio > maxAngularErrorRatio)
2385 maxAngularError = angularError;
2386 maxAngularErrorRatio = angularErrorRatio;
2387 maxAngularLink = &iter->second;
2391 bool reject =
false;
2394 UINFO(
"Max optimization linear error = %f m (link %d->%d, var=%f, ratio error/std=%f)", maxLinearError, maxLinearLink->
from(), maxLinearLink->
to(), maxLinearLink->
transVariance(), maxLinearError/
sqrt(maxLinearLink->
transVariance()));
2397 UWARN(
"Rejecting all added loop closures (%d) in this " 2398 "iteration because a wrong loop closure has been " 2399 "detected after graph optimization, resulting in " 2400 "a maximum graph error ratio of %f (edge %d->%d, type=%d, abs error=%f m, stddev=%f). The " 2401 "maximum error ratio parameter \"%s\" is %f of std deviation.",
2402 (
int)loopClosureLinksAdded.size(),
2403 maxLinearErrorRatio,
2404 maxLinearLink->
from(),
2405 maxLinearLink->
to(),
2406 maxLinearLink->
type(),
2409 Parameters::kRGBDOptimizeMaxError().c_str(),
2416 UINFO(
"Max optimization angular error = %f deg (link %d->%d, var=%f, ratio error/std=%f)", maxAngularError*180.0
f/CV_PI, maxAngularLink->
from(), maxAngularLink->
to(), maxAngularLink->
rotVariance(), maxAngularError/
sqrt(maxAngularLink->
rotVariance()));
2419 UWARN(
"Rejecting all added loop closures (%d) in this " 2420 "iteration because a wrong loop closure has been " 2421 "detected after graph optimization, resulting in " 2422 "a maximum graph error ratio of %f (edge %d->%d, type=%d, abs error=%f deg, stddev=%f). The " 2423 "maximum error ratio parameter \"%s\" is %f of std deviation.",
2424 (
int)loopClosureLinksAdded.size(),
2425 maxAngularErrorRatio,
2426 maxAngularLink->
from(),
2427 maxAngularLink->
to(),
2428 maxAngularLink->
type(),
2429 maxAngularError*180.0f/CV_PI,
2431 Parameters::kRGBDOptimizeMaxError().c_str(),
2439 for(std::list<std::pair<int, int> >::iterator iter=loopClosureLinksAdded.begin(); iter!=loopClosureLinksAdded.end(); ++iter)
2442 UWARN(
"Loop closure %d->%d rejected!", iter->first, iter->second);
2444 updateConstraints =
false;
2446 lastProximitySpaceClosureId = 0;
2447 rejectedHypothesis =
true;
2451 if(updateConstraints)
2453 UINFO(
"Updated local map (old size=%d, new size=%d)", (
int)
_optimizedPoses.size(), (int)poses.size());
2456 localizationCovariance = covariance;
2475 timeMapOptimization = timer.
ticks();
2476 ULOGGER_INFO(
"timeMapOptimization=%fs", timeMapOptimization);
2482 int dictionarySize = 0;
2483 int refWordsCount = 0;
2484 int refUniqueWordsCount = 0;
2485 int lcHypothesisReactivated = 0;
2491 lcHypothesisReactivated = sLoop->
isSaved()?1.0f:0.0f;
2494 refWordsCount = (int)signature->
getWords().size();
2534 statistics_.
addStatistic(Statistics::kProximitySpace_detections_added_visually(), proximityDetectionsAddedVisually);
2535 statistics_.
addStatistic(Statistics::kProximitySpace_detections_added_icp_only(), proximityDetectionsAddedByICPOnly);
2544 UINFO(
"Set loop closure transform = %s", sLoop->
getLinks().at(signature->
id()).transform().prettyPrint().c_str());
2555 statistics_.
addStatistic(Statistics::kTimingProximity_by_space_visual(), timeProximityBySpaceVisualDetection*1000);
2608 timeStatsCreation = timer.
ticks();
2609 ULOGGER_INFO(
"Time creating stats = %f...", timeStatsCreation);
2621 lastSignatureData = *signature;
2630 if(signatureRemoved)
2632 signaturesRemoved.push_back(signatureRemoved);
2639 if(signatureRemoved != lastSignatureData.id())
2646 UWARN(
"Ignoring location %d because a global loop closure is required before starting a new map!",
2648 signaturesRemoved.push_back(signature->
id());
2655 UWARN(
"Ignoring location %d because a good signature (with enough features) is required before starting a new map!",
2657 signaturesRemoved.push_back(signature->
id());
2660 else if((smallDisplacement || tooFastMovement) &&
_loopClosureHypothesis.first == 0 && lastProximitySpaceClosureId == 0)
2663 UINFO(
"Ignoring location %d because the displacement is too small! (d=%f a=%f)",
2666 signaturesRemoved.push_back(signature->
id());
2678 timeMemoryCleanup = timer.
ticks();
2679 ULOGGER_INFO(
"timeMemoryCleanup = %fs... %d signatures removed", timeMemoryCleanup, (
int)signaturesRemoved.size());
2691 double totalTime = timerTotal.
ticks();
2692 ULOGGER_INFO(
"Total time processing = %fs...", totalTime);
2697 immunizedLocations.insert(_lastLocalizationNodeId);
2698 std::list<int> transferred =
_memory->
forget(immunizedLocations);
2699 signaturesRemoved.insert(signaturesRemoved.end(), transferred.begin(), transferred.end());
2720 UDEBUG(
"Refresh local map from %d",
id);
2726 UDEBUG(
"Refresh local map from %d",
id);
2734 UDEBUG(
"Refresh local map from %d",
id);
2739 if(_lastLocalizationNodeId != 0)
2741 _lastLocalizationNodeId = id;
2749 UDEBUG(
"Removed %d from local map", iter->first);
2750 UASSERT(iter->first != _lastLocalizationNodeId);
2786 timeRealTimeLimitReachedProcess = timer.
ticks();
2787 ULOGGER_INFO(
"Time limit reached processing = %f...", timeRealTimeLimitReachedProcess);
2792 int localGraphSize = 0;
2813 std::map<int, Signature> signatures;
2816 UINFO(
"Adding data %d (rgb/left=%d depth/right=%d)", lastSignatureData.id(), lastSignatureData.sensorData().imageRaw().empty()?0:1, lastSignatureData.sensorData().depthOrRightRaw().empty()?0:1);
2817 signatures.insert(std::make_pair(lastSignatureData.id(), lastSignatureData));
2821 std::map<int, Transform> poses;
2822 std::multimap<int, Link> constraints;
2834 UDEBUG(
"Get all node infos...");
2835 std::map<int, Transform> groundTruths;
2836 for(std::map<int, Transform>::iterator iter=poses.begin(); iter!=poses.end(); ++iter)
2844 std::vector<float> velocity;
2846 _memory->
getNodeInfo(iter->first, odomPoseLocal, mapId, weight, label, stamp, groundTruth, velocity, gps,
false);
2847 signatures.insert(std::make_pair(iter->first,
2855 if(!velocity.empty())
2857 signatures.at(iter->first).setVelocity(velocity[0], velocity[1], velocity[2], velocity[3], velocity[4], velocity[5]);
2859 signatures.at(iter->first).sensorData().setGPS(gps);
2862 groundTruths.insert(std::make_pair(iter->first, groundTruth));
2865 localGraphSize = (int)poses.size();
2866 if(!lastSignatureLocalizedPose.isNull())
2868 poses.insert(std::make_pair(lastSignatureData.id(), lastSignatureLocalizedPose));
2877 float translational_rmse = 0.0f;
2878 float translational_mean = 0.0f;
2879 float translational_median = 0.0f;
2880 float translational_std = 0.0f;
2881 float translational_min = 0.0f;
2882 float translational_max = 0.0f;
2883 float rotational_rmse = 0.0f;
2884 float rotational_mean = 0.0f;
2885 float rotational_median = 0.0f;
2886 float rotational_std = 0.0f;
2887 float rotational_min = 0.0f;
2888 float rotational_max = 0.0f;
2895 translational_median,
2929 ids.push_back(*iter);
2944 UDEBUG(
"Empty trash...");
2952 std::string logF =
uFormat(
"%f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f\n",
2956 timeLikelihoodCalculation,
2957 timePosteriorCalculation,
2958 timeHypothesesCreation,
2959 timeHypothesesValidation,
2960 timeRealTimeLimitReachedProcess,
2972 timeRetrievalDbAccess,
2973 timeAddLoopClosureLink,
2975 timeNeighborLinkRefining,
2976 timeProximityByTimeDetection,
2977 timeProximityBySpaceDetection,
2978 timeMapOptimization);
2979 std::string logI =
uFormat(
"%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n",
2982 (
int)signaturesRemoved.size(),
2987 rejectedHypothesis?1:0,
2990 int(signaturesRetrieved.size()),
2991 lcHypothesisReactivated,
2992 refUniqueWordsCount,
2996 rehearsalMaxId>0?1:0,
3014 fprintf(
_foutInt,
"%s", logI.c_str());
3017 UINFO(
"Time logging = %f...", timer.
ticks());
3032 ULOGGER_WARN(
"maxTimeAllowed < 0, then setting it to 0 (inf).");
3045 ULOGGER_DEBUG(
"Comparing new working directory path \"%s\" with \"%s\"", path.c_str(),
_wDir.c_str());
3046 if(path.compare(
_wDir) != 0)
3050 UWARN(
"Working directory has been changed from \"%s\" with \"%s\", new log files will be created.",
3051 path.c_str(),
_wDir.c_str());
3057 else if(path.empty())
3064 ULOGGER_ERROR(
"Directory \"%s\" doesn't exist!", path.c_str());
3073 bool linksRemoved =
false;
3074 for(std::map<int, Link>::iterator iter = links.begin(); iter!=links.end(); ++iter)
3093 linksRemoved =
true;
3104 UINFO(
"Update graph");
3106 std::multimap<int, Link> constraints;
3112 UWARN(
"Graph optimization failed after removing loop closure links from last location!");
3116 UINFO(
"Updated local map (old size=%d, new size=%d)", (
int)
_optimizedPoses.size(), (int)poses.size());
3135 UINFO(
"Update graph");
3141 if(iter->second.from() == lastId || iter->second.to() == lastId)
3157 std::multimap<int, Link> constraints;
3163 UWARN(
"Graph optimization failed after deleting the last location!");
3188 UERROR(
"Working directory not set.");
3201 int maxNearestNeighbors,
3206 std::map<int, Transform> poses;
3214 pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(
new pcl::PointCloud<pcl::PointXYZ>);
3220 std::map<int, float> foundIds;
3230 float radiusSqrd = radius * radius;
3233 if(iter->first != fromId)
3235 if(stm.find(iter->first) == stm.end() &&
3237 (radiusSqrd==0 || foundIds.at(iter->first) <= radiusSqrd))
3239 (*cloud)[oi] = pcl::PointXYZ(iter->second.x(), iter->second.y(), iter->second.z());
3240 ids[oi++] = iter->first;
3262 pcl::CropBox<pcl::PointXYZ> cropbox;
3263 cropbox.setInputCloud(cloud);
3264 cropbox.setMin(Eigen::Vector4f(-1, -radius, -999999, 0));
3265 cropbox.setMax(Eigen::Vector4f(radius, radius, 999999, 0));
3266 cropbox.setRotation(Eigen::Vector3f(roll, pitch, yaw));
3267 cropbox.setTranslation(Eigen::Vector3f(x, y, z));
3268 cropbox.setRotation(Eigen::Vector3f(roll,pitch,yaw));
3269 pcl::IndicesPtr indices(
new std::vector<int>());
3270 cropbox.filter(*indices);
3280 pcl::search::KdTree<pcl::PointXYZ>::Ptr kdTree(
new pcl::search::KdTree<pcl::PointXYZ>);
3281 kdTree->setInputCloud(cloud, indices);
3282 std::vector<int> ind;
3283 std::vector<float> dist;
3284 pcl::PointXYZ pt(fromT.
x(), fromT.
y(), fromT.
z());
3285 kdTree->radiusSearch(pt, radius, ind, dist, maxNearestNeighbors);
3287 for(
unsigned int i=0; i<ind.size(); ++i)
3294 poses.insert(std::make_pair(ids[ind[i]], tmp));
3317 std::map<int, std::map<int, Transform> > paths;
3320 std::set<int> nodesSet =
uKeysSet(poses);
3324 std::map<int, Transform> path;
3329 UWARN(
"Nearest id of %s in %d poses is 0 !? Returning empty path.", target.
prettyPrint().c_str(), (int)poses.size());
3332 std::map<int, int> ids =
_memory->
getNeighborsId(nearestId, maxGraphDepth, 0,
true,
true,
true,
true, nodesSet);
3334 for(std::map<int, int>::iterator iter=ids.begin(); iter!=ids.end(); ++iter)
3336 std::map<int, Transform>::iterator jter = poses.find(iter->first);
3337 if(jter != poses.end())
3339 bool valid = path.empty();
3344 for(std::map<int, Link>::iterator kter=links.begin(); kter!=links.end() && !valid; ++kter)
3346 valid = path.find(kter->first) != path.end();
3362 UWARN(
"%s=Off but path(%d) > maxGraphDepth(%d)*2+1, nearestId=%d ids=%d. Is reduce graph activated before?",
3363 Parameters::kMemReduceGraph().c_str(), (
int)path.size(), maxGraphDepth, nearestId, (int)ids.size());
3365 paths.insert(std::make_pair(nearestId, path));
3369 UWARN(
uFormat(
"path.size()=0!? nearestId=%d ids=%d, aborting...", (
int)path.size(), nearestId, (int)ids.size()).c_str());
3380 bool lookInDatabase,
3381 std::map<int, Transform> & optimizedPoses,
3382 cv::Mat & covariance,
3383 std::multimap<int, Link> * constraints,
3385 int * iterationsDone)
const 3388 UINFO(
"Optimize map: around location %d",
id);
3395 id = ids.begin()->first;
3397 UINFO(
"get %d ids time %f s", (
int)ids.size(), timer.
ticks());
3399 std::map<int, Transform> poses =
Rtabmap::optimizeGraph(
id,
uKeysSet(ids), optimizedPoses, lookInDatabase, covariance, constraints, error, iterationsDone);
3404 optimizedPoses = poses;
3414 UERROR(
"Failed to optimize the graph! returning empty optimized poses...");
3415 optimizedPoses.clear();
3418 constraints->clear();
3426 const std::set<int> & ids,
3427 const std::map<int, Transform> & guessPoses,
3428 bool lookInDatabase,
3429 cv::Mat & covariance,
3430 std::multimap<int, Link> * constraints,
3432 int * iterationsDone)
const 3435 std::map<int, Transform> optimizedPoses;
3436 std::map<int, Transform> poses, posesOut;
3437 std::multimap<int, Link> edgeConstraints, linksOut;
3438 UDEBUG(
"ids=%d", (
int)ids.size());
3440 UINFO(
"get constraints (ids=%d, %d poses, %d edges) time %f s", (
int)ids.size(), (int)poses.size(), (int)edgeConstraints.size(), timer.
ticks());
3445 for(std::map<int, Transform>::const_iterator iter=guessPoses.begin(); iter!=guessPoses.end(); ++iter)
3447 std::map<int, Transform>::iterator foundPose = poses.find(iter->first);
3448 if(foundPose!=poses.end())
3450 foundPose->second = iter->second;
3459 if(poses.size() != posesOut.size())
3461 for(std::map<int, Transform>::iterator iter=poses.begin(); iter!=poses.end(); ++iter)
3463 if(posesOut.find(iter->first) == posesOut.end())
3465 UERROR(
"Not found %d in posesOut", iter->first);
3466 for(std::multimap<int, Link>::iterator jter=edgeConstraints.begin(); jter!=edgeConstraints.end(); ++jter)
3468 if(jter->second.from() == iter->first || jter->second.to()==iter->first)
3470 UERROR(
"Found link %d->%d", jter->second.from(), jter->second.to());
3476 int ignoredLinks = 0;
3477 if(edgeConstraints.size() != linksOut.size())
3479 for(std::multimap<int, Link>::iterator iter=edgeConstraints.begin(); iter!=edgeConstraints.end(); ++iter)
3481 if(
graph::findLink(linksOut, iter->second.from(), iter->second.to()) == linksOut.end())
3489 UERROR(
"Not found link %d->%d in linksOut", iter->second.from(), iter->second.to());
3494 UASSERT_MSG(poses.size() == posesOut.size() && edgeConstraints.size()-ignoredLinks == linksOut.size(),
3495 uFormat(
"nodes %d->%d, links %d->%d (ignored=%d)", poses.size(), posesOut.size(), edgeConstraints.size(), linksOut.size(), ignoredLinks).c_str());
3500 *constraints = edgeConstraints;
3507 optimizedPoses = poses;
3511 optimizedPoses =
_graphOptimizer->
optimize(fromId, poses, edgeConstraints, covariance, 0, error, iterationsDone);
3513 if(!poses.empty() && optimizedPoses.empty() && guessPoses.empty())
3515 UWARN(
"Optimization has failed, trying incremental optimization instead, this may take a while (poses=%d, links=%d)...", (
int)poses.size(), (int)edgeConstraints.size());
3518 if(optimizedPoses.empty())
3522 UWARN(
"Incremental optimization also failed. You may try changing parameters to %s=0 and %s=true.",
3523 Parameters::kOptimizerStrategy().c_str(), Parameters::kOptimizerVarianceIgnored().c_str());
3527 UWARN(
"Incremental optimization also failed.");
3532 UWARN(
"Incremental optimization succeeded!");
3536 UINFO(
"Optimization time %f s", timer.
ticks());
3538 return optimizedPoses;
3546 if(likelihood.size()==0)
3552 std::list<float> values;
3553 bool likelihoodNullValuesIgnored =
true;
3554 for(std::map<int, float>::iterator iter = ++likelihood.begin(); iter!=likelihood.end(); ++iter)
3556 if((iter->second >= 0 && !likelihoodNullValuesIgnored) ||
3557 (iter->second > 0 && likelihoodNullValuesIgnored))
3559 values.push_back(iter->second);
3562 UDEBUG(
"values.size=%d", values.size());
3564 float mean =
uMean(values);
3572 for(std::map<int, float>::iterator iter=++likelihood.begin(); iter!= likelihood.end(); ++iter)
3574 float value = iter->second;
3575 if(value > mean+stdDev && mean)
3577 iter->second = (value-(stdDev-epsilon))/mean;
3581 maxId = iter->first;
3584 else if(value == 1.0
f && stdDev == 0)
3586 iter->second = 1.0f;
3590 maxId = iter->first;
3595 iter->second = 1.0f;
3599 if(stdDev > epsilon && max)
3601 likelihood.begin()->second = mean/stdDev + 1.0f;
3605 likelihood.begin()->second = 2.0f;
3608 double time = timer.ticks();
3609 UDEBUG(
"mean=%f, stdDev=%f, max=%f, maxId=%d, time=%fs", mean, stdDev, max, maxId, time);
3618 UERROR(
"Working directory not set.");
3621 std::list<int> signaturesToCompare;
3632 signaturesToCompare.push_back(iter->first);
3638 signaturesToCompare.push_back(iter->first);
3644 std::string fileName = this->
getWorkingDir() +
"/DumpPrediction.txt";
3646 fopen_s(&fout, fileName.c_str(),
"w");
3648 fout = fopen(fileName.c_str(),
"w");
3653 for(
int i=0; i<prediction.rows; ++i)
3655 for(
int j=0; j<prediction.cols; ++j)
3657 fprintf(fout,
"%f ",((
float*)prediction.data)[j + i*prediction.cols]);
3659 fprintf(fout,
"\n");
3666 UWARN(
"Memory and/or the Bayes filter are not created");
3671 std::map<int, Signature> & signatures,
3672 std::map<int, Transform> & poses,
3673 std::multimap<int, Link> & constraints,
3713 for(std::set<int>::iterator iter = ids.begin(); iter!=ids.end(); ++iter)
3721 std::vector<float> velocity;
3723 _memory->
getNodeInfo(*iter, odomPoseLocal, mapId, weight, label, stamp, groundTruth, velocity, gps,
true);
3726 std::multimap<int, cv::KeyPoint> words;
3727 std::multimap<int, cv::Point3f> words3;
3728 std::multimap<int, cv::Mat> wordsDescriptors;
3730 signatures.insert(std::make_pair(*iter,
3739 signatures.at(*iter).setWords(words);
3740 signatures.at(*iter).setWords3(words3);
3741 signatures.at(*iter).setWordsDescriptors(wordsDescriptors);
3742 if(!velocity.empty())
3744 signatures.at(*iter).setVelocity(velocity[0], velocity[1], velocity[2], velocity[3], velocity[4], velocity[5]);
3746 signatures.at(*iter).sensorData().setGPS(gps);
3751 UERROR(
"Last working signature is null!?");
3755 UWARN(
"Memory not initialized...");
3760 std::map<int, Transform> & poses,
3761 std::multimap<int, Link> & constraints,
3764 std::map<int, Signature> * signatures)
3791 for(std::map<int, Transform>::iterator iter=poses.begin(); iter!=poses.end(); ++iter)
3799 std::vector<float> velocity;
3801 _memory->
getNodeInfo(iter->first, odomPoseLocal, mapId, weight, label, stamp, groundTruth, velocity, gps, global);
3802 signatures->insert(std::make_pair(iter->first,
3811 std::multimap<int, cv::KeyPoint> words;
3812 std::multimap<int, cv::Point3f> words3;
3813 std::multimap<int, cv::Mat> wordsDescriptors;
3815 signatures->at(iter->first).setWords(words);
3816 signatures->at(iter->first).setWords3(words3);
3817 signatures->at(iter->first).setWordsDescriptors(wordsDescriptors);
3819 std::vector<CameraModel> models;
3822 signatures->at(iter->first).sensorData().setCameraModels(models);
3823 signatures->at(iter->first).sensorData().setStereoCameraModel(stereoModel);
3825 if(!velocity.empty())
3827 signatures->at(iter->first).setVelocity(velocity[0], velocity[1], velocity[2], velocity[3], velocity[4], velocity[5]);
3829 signatures->at(iter->first).sensorData().setGPS(gps);
3835 UERROR(
"Last working signature is null!?");
3839 UWARN(
"Memory not initialized...");
3849 UERROR(
"Cannot detect more loop closures if graph optimization iterations = 0");
3854 UERROR(
"Detecting more loop closures can be done only in RGBD-SLAM mode.");
3858 std::list<Link> loopClosuresAdded;
3859 std::multimap<int, int> checkedLoopClosures;
3861 std::map<int, Transform> poses;
3862 std::multimap<int, Link> links;
3863 std::map<int, Signature> signatures;
3864 this->
getGraph(poses, links,
true,
true, &signatures);
3867 for(std::map<int, Transform>::iterator iter=poses.begin(); iter!=poses.end();)
3869 if(signatures.at(iter->first).getWeight() < 0)
3871 poses.erase(iter++);
3879 for(
int n=0; n<iterations; ++n)
3881 UINFO(
"Looking for more loop closures, clustering poses... (iteration=%d/%d, radius=%f m angle=%f rad)",
3882 n+1, iterations, clusterRadius, clusterAngle);
3889 UINFO(
"Looking for more loop closures, clustering poses... found %d clusters.", (
int)clusters.size());
3892 std::set<int> addedLinks;
3893 for(std::multimap<int, int>::iterator iter=clusters.begin(); iter!= clusters.end(); ++iter, ++i)
3895 if(processState && processState->
isCanceled())
3901 int from = iter->first;
3902 int to = iter->second;
3903 if(iter->first < iter->second)
3905 from = iter->second;
3912 if(addedLinks.find(from) == addedLinks.end() &&
3913 addedLinks.find(to) == addedLinks.end() &&
3916 checkedLoopClosures.insert(std::make_pair(from, to));
3918 UASSERT(signatures.find(from) != signatures.end());
3919 UASSERT(signatures.find(to) != signatures.end());
3927 bool updateConstraints =
true;
3933 int mapId = signatures.at(from).mapId();
3935 for(std::map<int, Signature>::iterator iter=signatures.begin(); iter!=signatures.end(); ++iter)
3937 if(iter->second.mapId() == mapId)
3939 fromId = iter->first;
3943 std::multimap<int, Link> linksIn = links;
3945 const Link * maxLinearLink = 0;
3946 const Link * maxAngularLink = 0;
3947 float maxLinearError = 0.0f;
3948 float maxAngularError = 0.0f;
3949 std::map<int, Transform> optimizedPoses;
3950 std::multimap<int, Link> links;
3951 UASSERT(poses.find(fromId) != poses.end());
3952 UASSERT_MSG(poses.find(from) != poses.end(),
uFormat(
"id=%d poses=%d links=%d", from, (
int)poses.size(), (int)links.size()).c_str());
3953 UASSERT_MSG(poses.find(to) != poses.end(),
uFormat(
"id=%d poses=%d links=%d", to, (
int)poses.size(), (int)links.size()).c_str());
3955 UASSERT(optimizedPoses.find(fromId) != optimizedPoses.end());
3956 UASSERT_MSG(optimizedPoses.find(from) != optimizedPoses.end(),
uFormat(
"id=%d poses=%d links=%d", from, (
int)optimizedPoses.size(), (int)links.size()).c_str());
3957 UASSERT_MSG(optimizedPoses.find(to) != optimizedPoses.end(),
uFormat(
"id=%d poses=%d links=%d", to, (
int)optimizedPoses.size(), (int)links.size()).c_str());
3961 if(optimizedPoses.size())
3963 for(std::multimap<int, Link>::iterator iter=links.begin(); iter!=links.end(); ++iter)
3966 if(iter->second.transVariance() <= 1.0 && iter->second.from() != iter->second.to())
3968 UASSERT(optimizedPoses.find(iter->second.from())!=optimizedPoses.end());
3969 UASSERT(optimizedPoses.find(iter->second.to())!=optimizedPoses.end());
3970 Transform t1 = optimizedPoses.at(iter->second.from());
3971 Transform t2 = optimizedPoses.at(iter->second.to());
3974 float linearError =
uMax3(
3975 fabs(iter->second.transform().x() - t.x()),
3976 fabs(iter->second.transform().y() - t.y()),
3977 fabs(iter->second.transform().z() - t.z()));
3978 Eigen::Vector3f vA = t1.toEigen3f().linear()*Eigen::Vector3f(1,0,0);
3979 Eigen::Vector3f vB = t2.
toEigen3f().linear()*Eigen::Vector3f(1,0,0);
3980 float angularError = pcl::getAngle3D(Eigen::Vector4f(vA[0], vA[1], vA[2], 0), Eigen::Vector4f(vB[0], vB[1], vB[2], 0));
3981 if(linearError > maxLinearError)
3983 maxLinearError = linearError;
3984 maxLinearLink = &iter->second;
3986 if(angularError > maxAngularError)
3988 maxAngularError = angularError;
3989 maxAngularLink = &iter->second;
3995 UINFO(
"Max optimization linear error = %f m (link %d->%d)", maxLinearError, maxLinearLink->
from(), maxLinearLink->
to());
3999 UINFO(
"Max optimization angular error = %f deg (link %d->%d)", maxAngularError*180.0
f/
M_PI, maxAngularLink->
from(), maxAngularLink->
to());
4004 msg =
uFormat(
"Rejecting edge %d->%d because " 4005 "graph error is too large after optimization (%f m for edge %d->%d, %f deg for edge %d->%d). " 4010 maxLinearLink->
from(),
4011 maxLinearLink->
to(),
4012 maxAngularError*180.0f/
M_PI,
4013 maxAngularLink?maxAngularLink->
from():0,
4014 maxAngularLink?maxAngularLink->
to():0,
4015 Parameters::kRGBDOptimizeMaxError().c_str(),
4021 msg =
uFormat(
"Rejecting edge %d->%d because graph optimization has failed!",
4027 UWARN(
"%s", msg.c_str());
4028 updateConstraints =
false;
4032 if(updateConstraints)
4034 UINFO(
"Added new loop closure between %d and %d.", from, to);
4035 addedLinks.insert(from);
4036 addedLinks.insert(to);
4037 cv::Mat inf = info.covariance.inv();
4040 UINFO(
"Detected loop closure %d->%d! (%d/%d)", from, to, i+1, (
int)clusters.size());
4049 std::string msg =
uFormat(
"Iteration %d/%d: Detected %d loop closures!", n+1, iterations, (
int)addedLinks.size()/2);
4058 UINFO(
"Iteration %d/%d: Detected %d loop closures!", n+1, iterations, (
int)addedLinks.size()/2);
4061 if(addedLinks.size() == 0)
4066 if(n+1 < iterations)
4068 UINFO(
"Optimizing graph with new links (%d nodes, %d constraints)...",
4069 (
int)poses.size(), (int)links.size());
4072 if(poses.size() == 0)
4074 UERROR(
"Optimization failed! Rejecting all loop closures...");
4075 loopClosuresAdded.clear();
4078 UINFO(
"Optimizing graph with new links... done!");
4081 UINFO(
"Total added %d loop closures.", (
int)loopClosuresAdded.size());
4083 if(loopClosuresAdded.size())
4085 for(std::list<Link>::iterator iter=loopClosuresAdded.begin(); iter!=loopClosuresAdded.end(); ++iter)
4090 return (
int)loopClosuresAdded.size();
4097 UERROR(
"Refining links can be done only in RGBD-SLAM mode.");
4101 std::list<Link> linksRefined;
4103 std::map<int, Transform> poses;
4104 std::multimap<int, Link> links;
4105 std::map<int, Signature> signatures;
4106 this->
getGraph(poses, links,
false,
true, &signatures);
4109 for(std::multimap<int, Link>::iterator iter=links.begin(); iter!= links.end(); ++iter)
4111 int from = iter->second.from();
4112 int to = iter->second.to();
4114 UASSERT(signatures.find(from) != signatures.end());
4115 UASSERT(signatures.find(to) != signatures.end());
4123 linksRefined.push_back(
Link(from, to, iter->second.type(), t, info.covariance.inv()));
4124 UINFO(
"Refined link %d->%d! (%d/%d)", from, to, ++i, (
int)links.size());
4127 UINFO(
"Total refined %d links.", (
int)linksRefined.size());
4129 if(linksRefined.size())
4131 for(std::list<Link>::iterator iter=linksRefined.begin(); iter!=linksRefined.end(); ++iter)
4136 return (
int)linksRefined.size();
4141 UINFO(
"status=%d", status);
4159 UINFO(
"Planning a path to node %d (global=%d)", targetNode, global?1:0);
4164 UWARN(
"A path can only be computed in RGBD-SLAM mode");
4174 int currentNode = 0;
4179 UWARN(
"Working memory is empty... cannot compute a path");
4188 UWARN(
"Last localization pose is null... cannot compute a path");
4193 if(currentNode && targetNode)
4206 _path.resize(path.size());
4208 for(std::list<std::pair<int, Transform> >::iterator iter=path.begin(); iter!=path.end();++iter)
4210 _path[oi].first = iter->first;
4211 _path[oi++].second = t * iter->second;
4214 else if(currentNode == 0)
4216 UWARN(
"We should be localized before planning.");
4221 if(
_path.size() == 0)
4224 UWARN(
"Cannot compute a path!");
4229 UINFO(
"Path generated! Size=%d", (
int)
_path.size());
4232 std::stringstream stream;
4233 for(
unsigned int i=0; i<
_path.size(); ++i)
4235 stream <<
_path[i].first;
4236 if(i+1 <
_path.size())
4241 UINFO(
"Path = [%s]", stream.str().c_str());
4246 std::string goalStr =
uFormat(
"GOAL:%d", targetNode);
4259 std::map<int, std::string>::iterator iter = labels.find(targetNode);
4260 if(iter != labels.end() && !iter->second.empty())
4262 goalStr = std::string(
"GOAL:")+labels.at(targetNode);
4265 setUserData(0, cv::Mat(1,
int(goalStr.size()+1), CV_8SC1, (
void *)goalStr.c_str()).clone());
4276 if(tolerance < 0.0
f)
4284 std::list<std::pair<int, Transform> > pathPoses;
4288 UWARN(
"This method can only be used in RGBD-SLAM mode");
4295 std::multimap<int, int> links;
4296 for(std::map<int, Transform>::iterator iter=nodes.begin(); iter!=nodes.end(); ++iter)
4300 for(std::map<int, Link>::const_iterator jter=s->
getLinks().begin(); jter!=s->
getLinks().end(); ++jter)
4303 if(jter->second.from() != jter->second.to() &&
uContains(nodes, jter->second.to()))
4305 links.insert(std::make_pair(jter->second.from(), jter->second.to()));
4310 UINFO(
"Time getting links = %fs", timer.
ticks());
4312 int currentNode = 0;
4317 UWARN(
"Working memory is empty... cannot compute a path");
4326 UWARN(
"Last localization pose is null... cannot compute a path");
4336 nearestId = currentNode;
4342 UINFO(
"Nearest node found=%d ,%fs", nearestId, timer.
ticks());
4345 if(tolerance != 0.0
f && targetPose.
getDistance(nodes.at(nearestId)) > tolerance)
4347 UWARN(
"Cannot plan farther than %f m from the graph! (distance=%f m from node %d)",
4348 tolerance, targetPose.
getDistance(nodes.at(nearestId)), nearestId);
4352 UINFO(
"Computing path from location %d to %d", currentNode, nearestId);
4357 if(
_path.size() == 0)
4359 UWARN(
"Cannot compute a path!");
4363 UINFO(
"Path generated! Size=%d", (
int)
_path.size());
4366 std::stringstream stream;
4367 for(
unsigned int i=0; i<
_path.size(); ++i)
4369 stream <<
_path[i].first;
4370 if(i+1 <
_path.size())
4375 UINFO(
"Path = [%s]", stream.str().c_str());
4389 UWARN(
"Nearest node not found in graph (size=%d) for pose %s", (
int)nodes.size(), targetPose.
prettyPrint().c_str());
4397 std::vector<std::pair<int, Transform> > poses;
4408 poses[oi++] = *iter;
4422 std::vector<int> ids;
4433 ids[oi++] = iter->first;
4459 UWARN(
"This method can on be used in RGBD-SLAM mode!");
4481 std::map<int, Link> links = currentIndexS->getLinks();
4482 bool latestVirtualLinkFound =
false;
4483 for(std::map<int, Link>::reverse_iterator iter=links.rbegin(); iter!=links.rend(); ++iter)
4487 if(latestVirtualLinkFound)
4493 latestVirtualLinkFound =
true;
4499 float distanceSoFar = 0.0f;
4508 distanceSoFar +=
_path[i-1].second.getDistance(
_path[i].second);
4521 UINFO(
"Added Virtual link between %d and %d",
_path[i-1].first,
_path[i].first);
4540 UERROR(
"Last node is null in memory or not in optimized poses. Aborting the plan...");
4550 UERROR(
"Last localization pose is null. Aborting the plan...");
4557 int goalId =
_path.back().first;
4564 UINFO(
"Goal %d reached!", goalId);
4573 float distanceFromCurrentNode = 0.0f;
4574 bool sameGoalIndex =
false;
4605 UINFO(
"Updated current goal from %d to %d (%d/%d)",
4611 sameGoalIndex =
true;
4615 unsigned int nearestNodeIndex = 0;
4617 bool sameCurrentIndex =
false;
4625 if(distance == -1.0
f || distance > d)
4628 nearestNodeIndex = i;
4634 UERROR(
"The nearest pose on the path not found! Aborting the plan...");
4639 UDEBUG(
"Nearest node = %d",
_path[nearestNodeIndex].first);
4648 sameCurrentIndex =
true;
4651 bool isStuck =
false;
4654 float distanceToCurrentGoal = 0.0f;
4669 if(distanceToCurrentGoal > 0.0
f)
4690 UWARN(
"Current goal %d not reached since %d iterations (\"RGBD/PlanStuckIterations\"=%d), mark that node as unreachable.",
4703 UERROR(
"No upcoming nodes on the path are reachable! Aborting the plan...");
Transform _mapCorrectionBackup
EpipolarGeometry * _epipolarGeometry
std::list< K > uUniqueKeys(const std::multimap< K, V > &mm)
GLM_FUNC_DECL T roll(detail::tquat< T, P > const &x)
T uVariance(const T *v, unsigned int size, T meanV)
static bool parse(const ParametersMap ¶meters, const std::string &key, bool &value)
void removeLink(int idA, int idB)
void get3DMap(std::map< int, Signature > &signatures, std::map< int, Transform > &poses, std::multimap< int, Link > &constraints, bool optimized, bool global) const
void flushStatisticLogs()
bool labelSignature(int id, const std::string &label)
unsigned int _maxLocalRetrieved
std::map< int, Transform > RTABMAP_EXP getPosesInRadius(int nodeId, const std::map< int, Transform > &nodes, float radius, float angle=0.0f)
std::vector< std::pair< int, Transform > > _path
void setupLogFiles(bool overwrite=false)
bool RTABMAP_EXP exportPoses(const std::string &filePath, int format, const std::map< int, Transform > &poses, const std::multimap< int, Link > &constraints=std::multimap< int, Link >(), const std::map< int, double > &stamps=std::map< int, double >(), bool g2oRobust=false)
T uMean(const T *v, unsigned int size)
std::map< int, Transform > RTABMAP_EXP radiusPosesFiltering(const std::map< int, Transform > &poses, float radius, float angle, bool keepLatest=true)
std::set< int > getSTM() const
std::map< int, Transform > getForwardWMPoses(int fromId, int maxNearestNeighbors, float radius, int maxDiffID) const
void clearPath(int status)
std::vector< K > uKeys(const std::multimap< K, V > &mm)
int getTotalMemSize() const
const LaserScan & laserScanCompressed() const
unsigned int getIndexMemoryUsed() const
std::list< int > getWM() const
Transform getPose(int locationId) const
void exportPoses(const std::string &path, bool optimized, bool global, int format)
const std::multimap< int, cv::KeyPoint > & getWords() const
std::map< int, Link > getLinks(int signatureId, bool lookInDatabase=false) const
void removeVirtualLinks(int signatureId)
#define ULOGGER_INFO(...)
bool isInSTM(int signatureId) const
void removeRawData(int id, bool image=true, bool scan=true, bool userData=true)
const Signature * getSignature(int id) const
bool computePath(int targetNode, bool global)
void setRefImageId(int refImageId)
GLM_FUNC_DECL vecType< T, P > sqrt(vecType< T, P > const &x)
virtual void parseParameters(const ParametersMap ¶meters)
int getMaxStMemSize() const
void setPosterior(const std::map< int, float > &posterior)
void setRawLikelihood(const std::map< int, float > &rawLikelihood)
bool _scanMatchingIdsSavedInLinks
void generateDOTGraph(const std::string &path, int id=0, int margin=5)
const std::string & getWorkingDir() const
void generateGraph(const std::string &fileName, const std::set< int > &ids=std::set< int >())
void setInitialPose(const Transform &initialPose)
bool labelLocation(int id, const std::string &label)
void setProximityDetectionId(int id)
std::set< K > uKeysSet(const std::map< K, V > &m)
SensorData getNodeData(int nodeId, bool uncompressedData=false) const
void parseParameters(const ParametersMap ¶meters)
double transVariance() const
float _rgbdAngularSpeedUpdate
std::map< std::string, std::string > ParametersMap
GLM_FUNC_DECL genType::value_type distance(genType const &p0, genType const &p1)
float _rgbdLinearSpeedUpdate
void close(bool databaseSaved=true, bool postInitClosingEvents=false, const std::string &ouputDatabasePath="")
bool isCovarianceIgnored() const
Basic mathematics functions.
unsigned int _maxMemoryAllowed
void setCurrentGoalId(int goal)
int _proximityMaxGraphDepth
double rotVariance() const
void setConstraints(const std::multimap< int, Link > &constraints)
Some conversion functions.
void getNodeCalibration(int nodeId, std::vector< CameraModel > &models, StereoCameraModel &stereoModel)
std::list< std::string > _bufferedLogsF
std::string getExtension()
const LaserScan & laserScanRaw() const
GLM_FUNC_DECL T pitch(detail::tquat< T, P > const &x)
void deleteLocation(int locationId, std::list< int > *deletedWords=0)
void adjustLikelihood(std::map< int, float > &likelihood) const
std::vector< std::pair< int, Transform > > getPathNextPoses() const
const std::map< int, int > & reducedIds() const
unsigned int getIndexedWordsCount() const
void getGraph(std::map< int, Transform > &poses, std::multimap< int, Link > &constraints, bool optimized, bool global, std::map< int, Signature > *signatures=0)
std::map< int, Link > getNeighborLinks(int signatureId, bool lookInDatabase=false) const
const std::set< int > & getStMem() const
float _newMapOdomChangeDistance
bool isIDsGenerated() const
void saveLocationData(int locationId)
float _pathLinearVelocity
Optimizer * _graphOptimizer
bool isInWM(int signatureId) const
bool init(const std::string &dbUrl, bool dbOverwritten=false, const ParametersMap ¶meters=ParametersMap(), bool postInitClosingEvents=false)
void getNodeWords(int nodeId, std::multimap< int, cv::KeyPoint > &words, std::multimap< int, cv::Point3f > &words3, std::multimap< int, cv::Mat > &wordsDescriptors)
cv::Mat generatePrediction(const Memory *memory, const std::vector< int > &ids)
const std::string & getLabel() const
bool _proximityRawPosesUsed
float _optimizationMaxError
#define UASSERT(condition)
BayesFilter * _bayesFilter
const std::map< std::string, float > & data() const
void setLocalPath(const std::vector< int > &localPath)
std::multimap< int, cv::KeyPoint > getWords(int locationId) const
std::map< int, std::map< int, Transform > > getPaths(std::map< int, Transform > poses, const Transform &target, int maxGraphDepth=0) const
std::map< int, Transform > optimizeIncremental(int rootId, const std::map< int, Transform > &poses, const std::multimap< int, Link > &constraints, std::list< std::map< int, Transform > > *intermediateGraphes=0, double *finalError=0, int *iterationsDone=0)
std::set< int > reactivateSignatures(const std::list< int > &ids, unsigned int maxLoaded, double &timeDbAccess)
virtual bool callback(const std::string &msg) const
void setLocalizationCovariance(const cv::Mat &covariance)
bool _statisticLoggedHeaders
std::map< int, Transform > optimizeGraph(int fromId, const std::set< int > &ids, const std::map< int, Transform > &guessPoses, bool lookInDatabase, cv::Mat &covariance, std::multimap< int, Link > *constraints=0, double *error=0, int *iterationsDone=0) const
const std::map< int, double > & getWorkingMem() const
bool _savedLocalizationIgnored
T uMax3(const T &a, const T &b, const T &c)
virtual void parseParameters(const ParametersMap ¶meters)
void close(bool databaseSaved=true, const std::string &ouputDatabasePath="")
std::map< int, Transform > loadOptimizedPoses(Transform *lastlocalizationPose) const
bool hasLink(int idTo) const
#define ULOGGER_DEBUG(...)
void setPoses(const std::map< int, Transform > &poses)
void setWorkingDirectory(std::string path)
void setExtended(bool extended)
virtual void dumpMemory(std::string directory) const
#define UASSERT_MSG(condition, msg_str)
bool isInSTM(int locationId) const
bool update(const SensorData &data, Statistics *stats=0)
void setOptimizedPoses(const std::map< int, Transform > &poses)
int getLastLocationId() const
void setLoopClosureId(int loopClosureId)
const std::vector< double > & getPredictionLC() const
std::map< int, Transform > optimize(int rootId, const std::map< int, Transform > &poses, const std::multimap< int, Link > &constraints, std::list< std::map< int, Transform > > *intermediateGraphes=0, double *finalError=0, int *iterationsDone=0)
Transform RTABMAP_EXP calcRMSE(const std::map< int, Transform > &groundTruth, const std::map< int, Transform > &poses, float &translational_rmse, float &translational_mean, float &translational_median, float &translational_std, float &translational_min, float &translational_max, float &rotational_rmse, float &rotational_mean, float &rotational_median, float &rotational_std, float &rotational_min, float &rotational_max)
const Statistics & getStatistics() const
bool _statisticLogsBufferedInRAM
void deleteLastLocation()
std::map< int, int > getWeights() const
bool process(const SensorData &data, Transform odomPose, const cv::Mat &odomCovariance=cv::Mat::eye(6, 6, CV_64FC1), const std::vector< float > &odomVelocity=std::vector< float >(), const std::map< std::string, float > &externalStats=std::map< std::string, float >())
Main loop of rtabmap.
Transform computeTransform(Signature &fromS, Signature &toS, Transform guess, RegistrationInfo *info=0, bool useKnownCorrespondencesIfPossible=false) const
bool isGraphReduced() const
bool check(const Signature *ssA, const Signature *ssB)
std::list< std::pair< int, Transform > > RTABMAP_EXP computePath(const std::map< int, rtabmap::Transform > &poses, const std::multimap< int, int > &links, int from, int to, bool updateNewCosts=false)
int RTABMAP_EXP findNearestNode(const std::map< int, rtabmap::Transform > &nodes, const rtabmap::Transform &targetPose)
Transform _lastLocalizationPose
std::list< int > forget(const std::set< int > &ignoredIds=std::set< int >())
cv::Mat RTABMAP_EXP compressData2(const cv::Mat &data)
unsigned int _pathCurrentIndex
static const int kIdInvalid
static ULogger::Level level()
std::map< int, int > getNeighborsId(int signatureId, int maxGraphDepth, int maxCheckedInDatabase=-1, bool incrementMarginOnLoop=false, bool ignoreLoopIds=false, bool ignoreIntermediateNodes=false, bool ignoreLocalSpaceLoopIds=false, const std::set< int > &nodesSet=std::set< int >(), double *dbAccessTime=0) const
float _pathAngularVelocity
void init(const ParametersMap ¶meters, const std::string &databasePath="")
bool uContains(const std::list< V > &list, const V &value)
std::multimap< int, int > RTABMAP_EXP radiusPosesClustering(const std::map< int, Transform > &poses, float radius, float angle)
std::pair< int, float > _highestHypothesis
int getLastGlobalLoopClosureId() const
void parseParameters(const ParametersMap ¶meters)
const VWDictionary * getVWDictionary() const
void setMapCorrection(const Transform &mapCorrection)
void setLikelihood(const std::map< int, float > &likelihood)
int incrementMapId(std::map< int, int > *reducedIds=0)
bool _startNewMapOnLoopClosure
int getLastSignatureId() const
void removeAllVirtualLinks()
void setSignatures(const std::map< int, Signature > &signatures)
std::vector< V > uListToVector(const std::list< V > &list)
bool _someNodesHaveBeenTransferred
static const ParametersMap & getDefaultParameters()
const std::map< int, Link > & getLinks() const
void setWmState(const std::vector< int > &state)
const Transform & getPose() const
virtual void parseParameters(const ParametersMap ¶meters)
void optimizeCurrentMap(int id, bool lookInDatabase, std::map< int, Transform > &optimizedPoses, cv::Mat &covariance, std::multimap< int, Link > *constraints=0, double *error=0, int *iterationsDone=0) const
virtual Type type() const =0
void getMetricConstraints(const std::set< int > &ids, std::map< int, Transform > &poses, std::multimap< int, Link > &links, bool lookInDatabase=false)
void setStamp(double stamp)
std::map< int, float > RTABMAP_EXP getNodesInRadius(int nodeId, const std::map< int, Transform > &nodes, float radius)
GLM_FUNC_DECL genType max(genType const &x, genType const &y)
static const int kIdVirtual
SensorData & sensorData()
void updateLink(const Link &link, bool updateInDatabase=false)
std::map< int, Link > getLoopClosureLinks(int signatureId, bool lookInDatabase=false) const
std::list< K > uKeysList(const std::multimap< K, V > &mm)
std::multimap< int, Link >::iterator RTABMAP_EXP findLink(std::multimap< int, Link > &links, int from, int to, bool checkBothWays=true)
float _proximityFilteringRadius
const Signature * getLastWorkingSignature() const
std::map< int, std::string > getAllLabels() const
void setWeights(const std::map< int, int > &weights)
bool getNodeInfo(int signatureId, Transform &odomPose, int &mapId, int &weight, std::string &label, double &stamp, Transform &groundTruth, std::vector< float > &velocity, GPS &gps, bool lookInDatabase=false) const
static long int getMemoryUsage()
std::map< int, float > getNeighborsIdRadius(int signatureId, float radius, const std::map< int, Transform > &optimizedPoses, int maxGraphDepth) const
unsigned int _pathGoalIndex
void saveStatistics(const Statistics &statistics)
bool setUserData(int id, const cv::Mat &data)
#define ULOGGER_WARN(...)
int detectMoreLoopClosures(float clusterRadius=0.5f, float clusterAngle=M_PI/6.0f, int iterations=1, const ProgressState *state=0)
void saveOptimizedPoses(const std::map< int, Transform > &optimizedPoses, const Transform &lastlocalizationPose) const
void dumpPrediction() const
ULogger class and convenient macros.
std::multimap< int, Link > _constraints
bool _optimizeFromGraphEnd
GLM_FUNC_DECL T yaw(detail::tquat< T, P > const &x)
bool _publishLastSignatureData
std::map< int, float > computeLikelihood(const Signature *signature, const std::list< int > &ids)
std::list< std::string > _bufferedLogsI
static bool exists(const std::string &dirPath)
std::map< int, int > getWeights() const
static void readINI(const std::string &configFile, ParametersMap ¶meters, bool modifiedOnly=false)
void setLoopClosureTransform(const Transform &loopClosureTransform)
bool _startNewMapOnGoodSignature
void setTimeThreshold(float maxTimeAllowed)
ParametersMap _parameters
int _lastLocalizationNodeId
std::set< int > getAllSignatureIds() const
bool isIncremental() const
static void getConnectedGraph(int fromId, const std::map< int, Transform > &posesIn, const std::multimap< int, Link > &linksIn, std::map< int, Transform > &posesOut, std::multimap< int, Link > &linksOut, int depth=0)
void updateAge(int signatureId)
bool _goalsSavedInUserData
std::pair< int, float > _loopClosureHypothesis
float _localImmunizationRatio
std::set< unsigned int > _pathUnreachableNodes
bool _neighborLinkRefining
#define ULOGGER_ERROR(...)
bool isBadSignature() const
bool _verifyLoopClosureHypothesis
static int newDatabase(BtShared *pBt)
Transform computeIcpTransformMulti(int newId, int oldId, const std::map< int, Transform > &poses, RegistrationInfo *info=0)
int getPathCurrentGoalId() const
std::map< int, Transform > _optimizedPoses
float RTABMAP_EXP computePathLength(const std::vector< std::pair< int, Transform > > &path, unsigned int fromIndex=0, unsigned int toIndex=0)
std::string UTILITE_EXP uFormat(const char *fmt,...)
std::string UTILITE_EXP uNumber2Str(unsigned int number)
void rejectLastLoopClosure()
bool setUserData(int id, const cv::Mat &data)
std::multimap< int, Link > RTABMAP_EXP filterLinks(const std::multimap< int, Link > &links, Link::Type filteredType)
std::vector< int > getPathNextNodes() const
static Optimizer * create(const ParametersMap ¶meters)
V uValue(const std::map< K, V > &m, const K &key, const V &defaultValue=V())
int _proximityMaxNeighbors
const std::map< int, float > & computePosterior(const Memory *memory, const std::map< int, float > &likelihood)
std::string _databasePath
double getDbSavingTime() const
bool addLink(const Link &link, bool addInDatabase=false)
const std::map< int, VisualWord * > & getVisualWords() const
bool isIDsGenerated() const
Transform _pathTransformToGoal
int getDatabaseMemoryUsed() const
void addStatistic(const std::string &name, float value)
void uInsert(std::map< K, V > &map, const std::pair< K, V > &pair)
unsigned int _maxRetrieved
GLM_FUNC_DECL matType< T, P > inverse(matType< T, P > const &m)