29 #include "rtabmap/core/Version.h" 60 #include <pcl/search/kdtree.h> 61 #include <pcl/filters/crop_box.h> 62 #include <pcl/io/pcd_io.h> 63 #include <pcl/common/common.h> 64 #include <pcl/TextureMesh.h> 69 #define LOG_F "LogF.txt" 70 #define LOG_I "LogI.txt" 72 #define GRAPH_FILE_NAME "Graph.dot" 89 _publishStats(
Parameters::defaultRtabmapPublishStats()),
90 _publishLastSignatureData(
Parameters::defaultRtabmapPublishLastSignature()),
91 _publishPdf(
Parameters::defaultRtabmapPublishPdf()),
92 _publishLikelihood(
Parameters::defaultRtabmapPublishLikelihood()),
93 _publishRAMUsage(
Parameters::defaultRtabmapPublishRAMUsage()),
94 _computeRMSE(
Parameters::defaultRtabmapComputeRMSE()),
95 _saveWMState(
Parameters::defaultRtabmapSaveWMState()),
96 _maxTimeAllowed(
Parameters::defaultRtabmapTimeThr()),
97 _maxMemoryAllowed(
Parameters::defaultRtabmapMemoryThr()),
99 _loopRatio(
Parameters::defaultRtabmapLoopRatio()),
100 _maxLoopClosureDistance(
Parameters::defaultRGBDMaxLoopClosureDistance()),
101 _verifyLoopClosureHypothesis(
Parameters::defaultVhEpEnabled()),
102 _maxRetrieved(
Parameters::defaultRtabmapMaxRetrieved()),
103 _maxLocalRetrieved(
Parameters::defaultRGBDMaxLocalRetrieved()),
104 _maxRepublished(
Parameters::defaultRtabmapMaxRepublished()),
105 _rawDataKept(
Parameters::defaultMemImageKept()),
106 _statisticLogsBufferedInRAM(
Parameters::defaultRtabmapStatisticLogsBufferedInRAM()),
107 _statisticLogged(
Parameters::defaultRtabmapStatisticLogged()),
108 _statisticLoggedHeaders(
Parameters::defaultRtabmapStatisticLoggedHeaders()),
109 _rgbdSlamMode(
Parameters::defaultRGBDEnabled()),
110 _rgbdLinearUpdate(
Parameters::defaultRGBDLinearUpdate()),
111 _rgbdAngularUpdate(
Parameters::defaultRGBDAngularUpdate()),
112 _rgbdLinearSpeedUpdate(
Parameters::defaultRGBDLinearSpeedUpdate()),
113 _rgbdAngularSpeedUpdate(
Parameters::defaultRGBDAngularSpeedUpdate()),
114 _newMapOdomChangeDistance(
Parameters::defaultRGBDNewMapOdomChangeDistance()),
115 _neighborLinkRefining(
Parameters::defaultRGBDNeighborLinkRefining()),
116 _proximityByTime(
Parameters::defaultRGBDProximityByTime()),
117 _proximityBySpace(
Parameters::defaultRGBDProximityBySpace()),
118 _scanMatchingIdsSavedInLinks(
Parameters::defaultRGBDScanMatchingIdsSavedInLinks()),
119 _loopClosureIdentityGuess(
Parameters::defaultRGBDLoopClosureIdentityGuess()),
120 _localRadius(
Parameters::defaultRGBDLocalRadius()),
121 _localImmunizationRatio(
Parameters::defaultRGBDLocalImmunizationRatio()),
122 _proximityMaxGraphDepth(
Parameters::defaultRGBDProximityMaxGraphDepth()),
123 _proximityMaxPaths(
Parameters::defaultRGBDProximityMaxPaths()),
124 _proximityMaxNeighbors(
Parameters::defaultRGBDProximityPathMaxNeighbors()),
125 _proximityFilteringRadius(
Parameters::defaultRGBDProximityPathFilteringRadius()),
126 _proximityRawPosesUsed(
Parameters::defaultRGBDProximityPathRawPosesUsed()),
128 _proximityOdomGuess(
Parameters::defaultRGBDProximityOdomGuess()),
129 _proximityMergedScanCovFactor(
Parameters::defaultRGBDProximityMergedScanCovFactor()),
131 _optimizeFromGraphEnd(
Parameters::defaultRGBDOptimizeFromGraphEnd()),
132 _optimizationMaxError(
Parameters::defaultRGBDOptimizeMaxError()),
133 _startNewMapOnLoopClosure(
Parameters::defaultRtabmapStartNewMapOnLoopClosure()),
134 _startNewMapOnGoodSignature(
Parameters::defaultRtabmapStartNewMapOnGoodSignature()),
135 _goalReachedRadius(
Parameters::defaultRGBDGoalReachedRadius()),
136 _goalsSavedInUserData(
Parameters::defaultRGBDGoalsSavedInUserData()),
137 _pathStuckIterations(
Parameters::defaultRGBDPlanStuckIterations()),
138 _pathLinearVelocity(
Parameters::defaultRGBDPlanLinearVelocity()),
139 _pathAngularVelocity(
Parameters::defaultRGBDPlanAngularVelocity()),
140 _restartAtOrigin(
Parameters::defaultRGBDStartAtOrigin()),
141 _loopCovLimited(
Parameters::defaultRGBDLoopCovLimited()),
142 _loopGPS(
Parameters::defaultRtabmapLoopGPS()),
143 _maxOdomCacheSize(
Parameters::defaultRGBDMaxOdomCacheSize()),
144 _createGlobalScanMap(
Parameters::defaultRGBDProximityGlobalScanMap()),
145 _markerPriorsLinearVariance(
Parameters::defaultMarkerPriorsVarianceLinear()),
146 _markerPriorsAngularVariance(
Parameters::defaultMarkerPriorsVarianceAngular()),
147 _loopClosureHypothesis(0,0.0
f),
148 _highestHypothesis(0,0.0
f),
149 _lastProcessTime(0.0),
150 _someNodesHaveBeenTransferred(
false),
151 _distanceTravelled(0.0
f),
152 _distanceTravelledSinceLastLocalization(0.0
f),
153 _optimizeFromGraphEndChanged(
false),
154 _epipolarGeometry(0),
161 _mapCorrection(
Transform::getIdentity()),
162 _lastLocalizationNodeId(0),
163 _currentSessionHasGPS(
false),
164 _odomCorrectionAcc(6,0),
166 _pathCurrentIndex(0),
168 _pathTransformToGoal(
Transform::getIdentity()),
170 _pathStuckDistance(0.0
f)
171 #ifdef RTABMAP_PYTHON
199 std::string attributes =
"a+";
221 fprintf(_foutFloat,
"Column headers:\n");
222 fprintf(_foutFloat,
" 1-Total iteration time (s)\n");
223 fprintf(_foutFloat,
" 2-Memory update time (s)\n");
224 fprintf(_foutFloat,
" 3-Retrieval time (s)\n");
225 fprintf(_foutFloat,
" 4-Likelihood time (s)\n");
226 fprintf(_foutFloat,
" 5-Posterior time (s)\n");
227 fprintf(_foutFloat,
" 6-Hypothesis selection time (s)\n");
228 fprintf(_foutFloat,
" 7-Hypothesis validation time (s)\n");
229 fprintf(_foutFloat,
" 8-Transfer time (s)\n");
230 fprintf(_foutFloat,
" 9-Statistics creation time (s)\n");
231 fprintf(_foutFloat,
" 10-Loop closure hypothesis value\n");
232 fprintf(_foutFloat,
" 11-NAN\n");
233 fprintf(_foutFloat,
" 12-NAN\n");
234 fprintf(_foutFloat,
" 13-NAN\n");
235 fprintf(_foutFloat,
" 14-NAN\n");
236 fprintf(_foutFloat,
" 15-NAN\n");
237 fprintf(_foutFloat,
" 16-Virtual place hypothesis\n");
238 fprintf(_foutFloat,
" 17-Join trash time (s)\n");
239 fprintf(_foutFloat,
" 18-Weight Update (rehearsal) similarity\n");
240 fprintf(_foutFloat,
" 19-Empty trash time (s)\n");
241 fprintf(_foutFloat,
" 20-Retrieval database access time (s)\n");
242 fprintf(_foutFloat,
" 21-Add loop closure link time (s)\n");
243 fprintf(_foutFloat,
" 22-Memory cleanup time (s)\n");
244 fprintf(_foutFloat,
" 23-Scan matching (odometry correction) time (s)\n");
245 fprintf(_foutFloat,
" 24-Local time loop closure detection time (s)\n");
246 fprintf(_foutFloat,
" 25-Local space loop closure detection time (s)\n");
247 fprintf(_foutFloat,
" 26-Map optimization (s)\n");
251 fprintf(_foutInt,
"Column headers:\n");
252 fprintf(_foutInt,
" 1-Loop closure ID\n");
253 fprintf(_foutInt,
" 2-Highest loop closure hypothesis\n");
254 fprintf(_foutInt,
" 3-Locations transferred\n");
255 fprintf(_foutInt,
" 4-NAN\n");
256 fprintf(_foutInt,
" 5-Words extracted from the last image\n");
257 fprintf(_foutInt,
" 6-Vocabulary size\n");
258 fprintf(_foutInt,
" 7-Working memory size\n");
259 fprintf(_foutInt,
" 8-Is loop closure hypothesis rejected?\n");
260 fprintf(_foutInt,
" 9-NAN\n");
261 fprintf(_foutInt,
" 10-NAN\n");
262 fprintf(_foutInt,
" 11-Locations retrieved\n");
263 fprintf(_foutInt,
" 12-Retrieval location ID\n");
264 fprintf(_foutInt,
" 13-Unique words extraced from last image\n");
265 fprintf(_foutInt,
" 14-Retrieval ID\n");
266 fprintf(_foutInt,
" 15-Non-null likelihood values\n");
267 fprintf(_foutInt,
" 16-Weight Update ID\n");
268 fprintf(_foutInt,
" 17-Is last location merged through Weight Update?\n");
269 fprintf(_foutInt,
" 18-Local graph size\n");
270 fprintf(_foutInt,
" 19-Sensor data id\n");
271 fprintf(_foutInt,
" 20-Indexed words\n");
272 fprintf(_foutInt,
" 21-Index memory usage (KB)\n");
282 UWARN(
"Working directory is not set, log disabled!");
304 fprintf(
_foutInt,
"%s", iter->c_str());
312 UDEBUG(
"path=%s", databasePath.c_str());
314 if(!_databasePath.empty())
317 UINFO(
"Using database \"%s\".", _databasePath.c_str());
321 UWARN(
"Using empty database. Mapping session will not be saved unless it is closed with an output database path.");
327 if(!newDatabase && loadDatabaseParameters)
334 allParameters.erase(Parameters::kRtabmapWorkingDirectory());
339 uInsert(allParameters, parameters);
340 ParametersMap::const_iterator iter;
341 if((iter=allParameters.find(Parameters::kRtabmapWorkingDirectory())) != allParameters.end())
350 _memory->
init(_databasePath,
false, allParameters,
true);
381 UWARN(
"last localization pose is ignored (%s=true), assuming we start at the origin of the map.", Parameters::kRGBDStartAtOrigin().c_str());
386 UINFO(
"Loaded optimizedPoses=%d firstPose %d=%s lastLocalizationPose=%s",
394 std::map<int, Transform> tmp;
401 std::map<int, float> likelihood;
407 likelihood.insert(std::make_pair(iter->first, 0));
418 UINFO(
"Loaded optimizedPoses=0, last localization pose is ignored!");
426 std::map<int, Transform> tmp;
432 if(_databasePath.empty())
439 void Rtabmap::init(
const std::string & configFile,
const std::string & databasePath,
bool loadDatabaseParameters)
444 if(!configFile.empty())
446 ULOGGER_DEBUG(
"Read parameters from = %s", configFile.c_str());
450 this->
init(param, databasePath, loadDatabaseParameters);
455 UINFO(
"databaseSaved=%d", databaseSaved?1:0);
504 std::map<int, int> reducedIds;
506 for(std::map<int, int>::iterator iter=reducedIds.begin(); iter!=reducedIds.end(); ++iter)
545 ParametersMap::const_iterator iter;
546 if((iter=parameters.find(Parameters::kRtabmapWorkingDirectory())) != parameters.end())
590 if(Parameters::parse(parameters, Parameters::kRGBDProximityAngle(),
_proximityAngle))
622 std::string markerPriorsStr;
623 if(Parameters::parse(parameters, Parameters::kMarkerPriors(), markerPriorsStr))
626 std::list<std::string> strList =
uSplit(markerPriorsStr,
'|');
627 for(std::list<std::string>::iterator iter=strList.begin(); iter!=strList.end(); ++iter)
629 std::string markerStr = *iter;
630 while(!markerStr.empty() && !
uIsDigit(markerStr[0]))
632 markerStr.erase(markerStr.begin());
634 if(!markerStr.empty())
639 if(!prior.
isNull() &&
id>0)
646 UERROR(
"Failed to parse element \"%s\" in parameter %s", markerStr.c_str(), Parameters::kMarkerPriors().c_str());
649 else if(!iter->empty())
651 UERROR(
"Failed to parse parameter %s, value=\"%s\"", Parameters::kMarkerPriors().c_str(), iter->c_str());
667 if((iter=parameters.find(Parameters::kOptimizerStrategy())) != parameters.end())
673 UDEBUG(
"new detector strategy %d",
int(optimizerType));
688 optimizerType = (
Optimizer::Type)Parameters::defaultOptimizerStrategy();
703 UWARN(
"Map is now incremental, clearing global scan map...");
772 std::map<int, int> weights;
787 return std::set<int>();
827 return Parameters::defaultMemGenerateIds();
863 UWARN(
"Initial pose can only be set in localization mode (%s=false), ignoring it...", Parameters::kMemIncrementalMemory().c_str());
889 std::map<int, int> reducedIds;
891 UINFO(
"New map triggered, new map = %d", mapId);
901 if(reducedIds.size() &&
_path.size())
903 for(
unsigned int i=0; i<
_path.size(); ++i)
905 std::map<int, int>::const_iterator iter = reducedIds.find(
_path[i].first);
906 if(iter!= reducedIds.end())
909 _path[i].first = iter->second;
932 if(!nearestNodes.empty())
938 UERROR(
"No nodes found inside %s=%fm of the current pose (%s). Cannot set label \"%s\"",
939 Parameters::kRGBDLocalRadius().c_str(),
947 UERROR(
"Last signature is null! Cannot set label \"%s\"", label.c_str());
967 UERROR(
"Last signature is null! Cannot set user data!");
985 ids.insert(std::pair<int,int>(
id, 0));
986 std::set<int> idsSet;
987 for(std::map<int, int>::iterator iter = ids.begin(); iter!=ids.end(); ++iter)
989 idsSet.insert(idsSet.end(), iter->first);
995 UERROR(
"No neighbors found for signature %d.",
id);
1009 std::map<int, Transform> poses;
1010 std::multimap<int, Link> constraints;
1023 std::map<int, double> stamps;
1024 if(format == 1 || format == 10 || format == 11)
1026 for(std::map<int, Transform>::iterator iter=poses.begin(); iter!=poses.end(); ++iter)
1032 std::vector<float> v;
1035 _memory->
getNodeInfo(iter->first, o, m, w, l, stamp, g, v, gps, sensors,
true);
1036 stamps.insert(std::make_pair(iter->first, stamp));
1083 UERROR(
"RTAB-Map is not initialized. No memory to reset...");
1123 const cv::Mat & image,
1125 const std::map<std::string, float> & externalStats)
1132 float odomLinearVariance,
1133 float odomAngularVariance,
1134 const std::vector<float> & odomVelocity,
1135 const std::map<std::string, float> & externalStats)
1142 cv::Mat covariance = cv::Mat::eye(6,6,CV_64FC1);
1143 covariance.at<
double>(0,0) = odomLinearVariance;
1144 covariance.at<
double>(1,1) = odomLinearVariance;
1145 covariance.at<
double>(2,2) = odomLinearVariance;
1146 covariance.at<
double>(3,3) = odomAngularVariance;
1147 covariance.at<
double>(4,4) = odomAngularVariance;
1148 covariance.at<
double>(5,5) = odomAngularVariance;
1149 return process(data, odomPose, covariance, odomVelocity, externalStats);
1154 const cv::Mat & odomCovariance,
1155 const std::vector<float> & odomVelocity,
1156 const std::map<std::string, float> & externalStats)
1165 double timeMemoryUpdate = 0;
1166 double timeNeighborLinkRefining = 0;
1167 double timeProximityByTimeDetection = 0;
1168 double timeProximityBySpaceVisualDetection = 0;
1169 double timeProximityBySpaceDetection = 0;
1170 double timeCleaningNeighbors = 0;
1171 double timeReactivations = 0;
1172 double timeAddLoopClosureLink = 0;
1173 double timeMapOptimization = 0;
1174 double timeRetrievalDbAccess = 0;
1175 double timeLikelihoodCalculation = 0;
1176 double timePosteriorCalculation = 0;
1177 double timeHypothesesCreation = 0;
1178 double timeHypothesesValidation = 0;
1179 double timeRealTimeLimitReachedProcess = 0;
1180 double timeMemoryCleanup = 0;
1181 double timeEmptyingTrash = 0;
1182 double timeFinalizingStatistics = 0;
1183 double timeJoiningTrash = 0;
1184 double timeStatsCreation = 0;
1186 float hypothesisRatio = 0.0f;
1187 bool rejectedGlobalLoopClosure =
false;
1189 std::map<int, float> rawLikelihood;
1190 std::map<int, float> adjustedLikelihood;
1191 std::map<int, float> likelihood;
1192 std::map<int, int> weights;
1193 std::map<int, float> posterior;
1194 std::list<std::pair<int, float> > reactivateHypotheses;
1196 std::map<int, int> childCount;
1197 std::set<int> signaturesRetrieved;
1198 int proximityDetectionsInTimeFound = 0;
1207 std::set<int> immunizedLocations;
1210 for(std::map<std::string, float>::const_iterator iter=externalStats.begin(); iter!=externalStats.end(); ++iter)
1230 bool fakeOdom =
false;
1238 UWARN(
"Input odometry is not invertible! pose = %s\n" 1243 "Trying to normalize rotation to see if it makes it invertible...",
1245 odomPose.
r11(), odomPose.
r12(), odomPose.
r13(), odomPose.
o14(),
1246 odomPose.
r21(), odomPose.
r22(), odomPose.
r23(), odomPose.
o24(),
1247 odomPose.
r31(), odomPose.
r32(), odomPose.
r33(), odomPose.
o34());
1254 odomPose.
r11(), odomPose.
r12(), odomPose.
r13(), odomPose.
o14(),
1255 odomPose.
r21(), odomPose.
r22(), odomPose.
r23(), odomPose.
o24(),
1256 odomPose.
r31(), odomPose.
r32(), odomPose.
r33(), odomPose.
o34()).c_str());
1257 UWARN(
"Normalizing rotation succeeded! fixed pose = %s\n" 1262 "If the resulting rotation is very different from original one, try to fix the odometry or TF.",
1264 odomPose.
r11(), odomPose.
r12(), odomPose.
r13(), odomPose.
o14(),
1265 odomPose.
r21(), odomPose.
r22(), odomPose.
r23(), odomPose.
o24(),
1266 odomPose.
r31(), odomPose.
r32(), odomPose.
r33(), odomPose.
o34());
1270 UDEBUG(
"incremental=%d odomPose=%s optimizedPoses=%d mapCorrection=%s lastLocalizationPose=%s lastLocalizationNodeId=%d",
1303 UWARN(
"Update map correction based on last localization saved in database! correction = %s, nearest id = %d of last pose = %s, odom = %s",
1327 iter->second = mapCorrectionInv * iter->second;
1336 UERROR(
"RGB-D SLAM mode is enabled, memory is incremental but no odometry is provided. " 1337 "Image %d is ignored!", data.
id());
1369 UWARN(
"Odometry is reset (identity pose detected). Increment map id to %d!", mapId);
1380 UWARN(
"Odometry is reset (large odometry change detected > %f). A new map (%d) is created! Last pose = %s, new pose = %s",
1381 _newMapOdomChangeDistance,
1414 UFATAL(
"Not supposed to be here...last signature is null?!?");
1418 timeMemoryUpdate = timer.
ticks();
1419 ULOGGER_INFO(
"timeMemoryUpdate=%fs", timeMemoryUpdate);
1424 bool smallDisplacement =
false;
1425 bool tooFastMovement =
false;
1426 std::list<int> signaturesRemoved;
1427 bool neighborLinkRefined =
false;
1428 bool addedNewLandmark =
false;
1431 statistics_.
addStatistic(Statistics::kMemoryOdometry_variance_lin(), odomCovariance.empty()?1.0f:(float)odomCovariance.at<
double>(0,0));
1432 statistics_.
addStatistic(Statistics::kMemoryOdometry_variance_ang(), odomCovariance.empty()?1.0f:(float)odomCovariance.at<
double>(5,5));
1451 const std::multimap<int, Link> & links = signature->
getLinks();
1459 t = links.begin()->second.transform();
1482 smallDisplacement =
true;
1483 UDEBUG(
"smallDisplacement: %f %f %f %f %f %f", x,y,z, roll,pitch,yaw);
1487 if(odomVelocity.size() == 6)
1499 bool intermediateNodeRefining =
false;
1507 int oldId = signature->
getLinks().begin()->first;
1515 if(smallDisplacement)
1517 if(signature->
getLinks().begin()->second.transVariance() == 1)
1520 UDEBUG(
"Set small variance. The robot is not moving.");
1534 UINFO(
"Odometry refining: update neighbor link (%d->%d, variance:lin=%f, ang=%f) from %s to %s",
1537 info.covariance.at<
double>(0,0),
1538 info.covariance.at<
double>(5,5),
1541 UASSERT(info.covariance.at<
double>(0,0) > 0.0 && info.covariance.at<
double>(5,5) > 0.0);
1550 std::map<int, Transform>::iterator jter =
_optimizedPoses.find(oldId);
1556 iter->second = mapCorrectionInv * up * iter->second;
1562 UINFO(
"Odometry refining rejected: %s", info.rejectedMsg.c_str());
1563 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)
1567 std::cout << info.covariance << std::endl;
1572 neighborLinkRefined = !t.
isNull();
1581 timeNeighborLinkRefining = timer.
ticks();
1582 ULOGGER_INFO(
"timeOdometryRefining=%fs", timeNeighborLinkRefining);
1593 UERROR(
"Map correction should be identity when optimizing from the last node. T=%s NewPose=%s OldPose=%s",
1602 intermediateNodeRefining =
true;
1615 for(std::map<int, Link>::const_iterator iter = signature->
getLandmarks().begin(); iter!=signature->
getLandmarks().end(); ++iter)
1619 _optimizedPoses.insert(std::make_pair(iter->first, newPose*iter->second.transform()));
1620 UDEBUG(
"Added landmark %d : %s", iter->first, (newPose*iter->second.transform()).prettyPrint().c_str());
1621 addedNewLandmark =
true;
1623 _constraints.insert(std::make_pair(iter->first, iter->second.inverse()));
1635 "Only forward links should be added.");
1637 Link tmp = signature->
getLinks().begin()->second.inverse();
1649 tmp =
_constraints.rbegin()->second.merge(tmp, tmp.type());
1677 odomCovariance.inv());
1679 UDEBUG(
"Added odom cov = %f %f", odomLink.transVariance(), odomLink.rotVariance());
1693 for(
unsigned int i=0; i<
_path.size(); ++i)
1699 _path[i].first = iter->second;
1712 if(jter->second.from() == iter->first || jter->second.to() == iter->first)
1734 for(std::set<int>::const_reverse_iterator iter = stm.rbegin(); iter!=stm.rend(); ++iter)
1736 if(*iter != signature->
id() &&
1741 std::string rejectedMsg;
1742 UDEBUG(
"Check local transform between %d and %d", signature->
id(), *iter);
1755 transform = transform.
inverse();
1756 UDEBUG(
"Add local loop closure in TIME (%d->%d) %s",
1761 UASSERT(info.covariance.at<
double>(0,0) > 0.0 && info.covariance.at<
double>(5,5) > 0.0);
1764 ++proximityDetectionsInTimeFound;
1765 UINFO(
"Local loop closure found between %d and %d with t=%s",
1766 *iter, signature->
id(), transform.prettyPrint().c_str());
1770 UWARN(
"Cannot add local loop closure between %d and %d ?!?",
1771 *iter, signature->
id());
1776 UINFO(
"Local loop closure (time) between %d and %d rejected: %s",
1777 *iter, signature->
id(), rejectedMsg.c_str());
1790 timeProximityByTimeDetection = timer.
ticks();
1791 UINFO(
"timeProximityByTimeDetection=%fs", timeProximityByTimeDetection);
1796 int previousId = signature->
getLinks().size() && signature->
getLinks().begin()->first!=signature->
id()?signature->
getLinks().begin()->first:0;
1812 std::list<int> signaturesToCompare;
1825 for(std::map<int, float>::reverse_iterator iter=nearestIds.rbegin(); iter!=nearestIds.rend() && iter->first>0; ++iter)
1843 if(originGPS.
stamp() > 0.0)
1861 if(originGPS.
stamp()>0.0)
1863 std::map<int, std::pair<cv::Point3d, Transform> >::iterator cacheIter =
_gpsGeocentricCache.find(s->
id());
1868 if(gps.
stamp()==0.0)
1872 if(gps.
stamp() > 0.0)
1875 std::make_pair(s->
id(),
1883 std::map<int, std::pair<cv::Point3d, Transform> >::iterator originIter =
_gpsGeocentricCache.find(signature->
id());
1886 const double & error = originGPS.
error();
1887 const Transform & offsetENU = cacheIter->second.second;
1888 relativePose.
x += offsetENU.
x() - originOffsetENU.
x();
1889 relativePose.y += offsetENU.
y() - originOffsetENU.
y();
1890 relativePose.z += offsetENU.
z() - originOffsetENU.
z();
1892 if(relativePose.z>error)
1894 relativePose.z -= error;
1896 else if(relativePose.z < -error)
1898 relativePose.z += error;
1910 signaturesToCompare.push_back(iter->first);
1917 signaturesToCompare.push_back(iter->first);
1924 likelihood = rawLikelihood;
1927 timeLikelihoodCalculation = timer.
ticks();
1928 ULOGGER_INFO(
"timeLikelihoodCalculation=%fs",timeLikelihoodCalculation);
1938 timePosteriorCalculation = timer.
ticks();
1939 ULOGGER_INFO(
"timePosteriorCalculation=%fs",timePosteriorCalculation);
1951 if(posterior.size())
1953 for(std::map<int, float>::const_reverse_iterator iter = posterior.rbegin(); iter != posterior.rend(); ++iter)
1963 timeHypothesesCreation = timer.
ticks();
1986 rejectedGlobalLoopClosure =
true;
1987 if(posterior.size() <= 2 && loopThr>0.0f)
1990 UDEBUG(
"rejected hypothesis: single hypothesis");
1994 UWARN(
"rejected hypothesis: by epipolar geometry");
1998 UWARN(
"rejected hypothesis: not satisfying hypothesis ratio (%f < %f * %f)",
2001 else if(
_loopRatio > 0.0
f && lastHighestHypothesis.second == 0)
2003 UWARN(
"rejected hypothesis: last closure hypothesis is null (loop ratio is on)");
2008 rejectedGlobalLoopClosure =
false;
2011 timeHypothesesValidation = timer.
ticks();
2012 ULOGGER_INFO(
"timeHypothesesValidation=%fs",timeHypothesesValidation);
2019 rejectedGlobalLoopClosure =
true;
2028 else if(!signature->
isBadSignature() && (smallDisplacement || tooFastMovement))
2031 UDEBUG(
"smallDisplacement=%d tooFastMovement=%d", smallDisplacement?1:0, tooFastMovement?1:0);
2035 UDEBUG(
"Ignoring likelihood and loop closure hypotheses as current signature doesn't have enough visual features.");
2043 timeJoiningTrash = timer.
ticks();
2044 ULOGGER_INFO(
"Time emptying memory trash = %fs, joining (actual overhead) = %fs", timeEmptyingTrash, timeJoiningTrash);
2050 std::list<int> reactivatedIds;
2051 double timeGetNeighborsTimeDb = 0.0;
2052 double timeGetNeighborsSpaceDb = 0.0;
2053 int immunizedGlobally = 0;
2054 int immunizedLocally = 0;
2055 int maxLocalLocationsImmunized = 0;
2068 ULOGGER_INFO(
"Retrieving locations... around id=%d", retrievalId);
2070 UASSERT(neighborhoodSize >= 0);
2074 unsigned int nbLoadedFromDb = 0;
2075 std::set<int> reactivatedIdsSet;
2076 std::map<int, int> neighbors;
2077 int nbDirectNeighborsInDb = 0;
2090 &timeGetNeighborsTimeDb);
2091 ULOGGER_DEBUG(
"neighbors of %d in time = %d", retrievalId, (
int)neighbors.size());
2093 bool firstPassDone =
false;
2095 while(m < neighborhoodSize)
2097 std::set<int> idsSorted;
2098 for(std::map<int, int>::iterator iter=neighbors.begin(); iter!=neighbors.end();)
2102 neighbors.erase(iter++);
2104 else if(iter->second == m)
2106 if(reactivatedIdsSet.find(iter->first) == reactivatedIdsSet.end())
2108 idsSorted.insert(iter->first);
2109 reactivatedIdsSet.insert(iter->first);
2113 ++nbDirectNeighborsInDb;
2117 if(immunizedLocations.insert(iter->first).second)
2119 ++immunizedGlobally;
2124 neighbors.erase(iter++);
2131 firstPassDone =
true;
2132 reactivatedIds.insert(reactivatedIds.end(), idsSorted.rbegin(), idsSorted.rend());
2146 &timeGetNeighborsSpaceDb);
2147 ULOGGER_DEBUG(
"neighbors of %d in space = %d", retrievalId, (
int)neighbors.size());
2148 firstPassDone =
false;
2150 while(m < neighborhoodSize)
2152 std::set<int> idsSorted;
2153 for(std::map<int, int>::iterator iter=neighbors.begin(); iter!=neighbors.end();)
2157 neighbors.erase(iter++);
2159 else if(iter->second == m)
2161 if(reactivatedIdsSet.find(iter->first) == reactivatedIdsSet.end())
2163 idsSorted.insert(iter->first);
2164 reactivatedIdsSet.insert(iter->first);
2168 ++nbDirectNeighborsInDb;
2172 neighbors.erase(iter++);
2179 firstPassDone =
true;
2180 reactivatedIds.insert(reactivatedIds.end(), idsSorted.rbegin(), idsSorted.rend());
2184 "reactivatedIds.size=%d, " 2185 "nbLoadedFromDb=%d, " 2186 "nbDirectNeighborsInDb=%d, " 2187 "time=%fs (%fs %fs)",
2189 reactivatedIds.size(),
2190 (int)nbLoadedFromDb,
2191 nbDirectNeighborsInDb,
2193 timeGetNeighborsTimeDb,
2194 timeGetNeighborsSpaceDb);
2202 std::list<int> retrievalLocalIds;
2210 float distanceSoFar = 0.0f;
2217 distanceSoFar +=
_path[i-1].second.getDistance(
_path[i].second);
2224 if(immunizedLocations.insert(
_path[i].first).second)
2228 UDEBUG(
"Path immunization: node %d (dist=%fm)",
_path[i].first, distanceSoFar);
2232 UINFO(
"retrieval of node %d on path (dist=%fm)",
_path[i].first, distanceSoFar);
2233 retrievalLocalIds.push_back(
_path[i].first);
2239 UDEBUG(
"Stop on node %d (dist=%fm > %fm)",
2249 if(immunizedLocally < maxLocalLocationsImmunized &&
2252 std::map<int ,Transform> poses;
2258 poses.insert(*iter);
2267 std::multimap<int, int> links;
2272 links.insert(std::make_pair(iter->second.from(), iter->second.to()));
2273 links.insert(std::make_pair(iter->second.to(), iter->second.from()));
2278 if(path.size() == 0)
2280 UWARN(
"Could not compute a path between %d and %d", nearestId, signature->
id());
2284 for(std::list<std::pair<int, Transform> >::iterator iter=path.begin();
2290 if(immunizedLocally >= maxLocalLocationsImmunized)
2295 UWARN(
"Could not immunize the whole local path (%d) between " 2296 "%d and %d (max location immunized=%d). You may want " 2297 "to increase RGBD/LocalImmunizationRatio (current=%f (%d of WM=%d)) " 2298 "to be able to immunize longer paths.",
2302 maxLocalLocationsImmunized,
2304 maxLocalLocationsImmunized,
2311 if(immunizedLocations.insert(iter->first).second)
2327 std::multimap<float, int> nearNodesByDist;
2328 for(std::map<int, float>::iterator iter=nearNodes.lower_bound(1); iter!=nearNodes.end(); ++iter)
2330 nearNodesByDist.insert(std::make_pair(iter->second, iter->first));
2332 UINFO(
"near nodes=%d, max local immunized=%d, ratio=%f WM=%d",
2333 (
int)nearNodesByDist.size(),
2334 maxLocalLocationsImmunized,
2337 for(std::multimap<float, int>::iterator iter=nearNodesByDist.begin();
2338 iter!=nearNodesByDist.end() && (retrievalLocalIds.size() <
_maxLocalRetrieved || immunizedLocally < maxLocalLocationsImmunized);
2346 const std::multimap<int, Link> & links = s->
getLinks();
2347 for(std::multimap<int, Link>::const_reverse_iterator jter=links.rbegin();
2353 UINFO(
"retrieval of node %d on local map", jter->first);
2354 retrievalLocalIds.push_back(jter->first);
2357 if(!
_memory->
isInSTM(s->
id()) && immunizedLocally < maxLocalLocationsImmunized)
2359 if(immunizedLocations.insert(s->
id()).second)
2370 std::set<int> retrievalLocalIdsSet(retrievalLocalIds.begin(), retrievalLocalIds.end());
2371 for(std::list<int>::iterator iter=retrievalLocalIds.begin();
2376 for(std::map<int, int>::reverse_iterator jter=ids.rbegin();
2381 retrievalLocalIdsSet.find(jter->first) == retrievalLocalIdsSet.end())
2383 UINFO(
"retrieval of node %d on local map", jter->first);
2384 retrievalLocalIds.push_back(jter->first);
2385 retrievalLocalIdsSet.insert(jter->first);
2392 for(std::multimap<float, int>::reverse_iterator iter=nearNodesByDist.rbegin(); iter!=nearNodesByDist.rend(); ++iter)
2398 reactivatedIds.insert(reactivatedIds.begin(), retrievalLocalIds.begin(), retrievalLocalIds.end());
2404 if(reactivatedIds.size())
2411 timeRetrievalDbAccess);
2413 ULOGGER_INFO(
"retrieval of %d (db time = %fs)", (
int)signaturesRetrieved.size(), timeRetrievalDbAccess);
2415 timeRetrievalDbAccess += timeGetNeighborsTimeDb + timeGetNeighborsSpaceDb;
2416 UINFO(
"total timeRetrievalDbAccess=%fs", timeRetrievalDbAccess);
2419 immunizedLocations.insert(signaturesRetrieved.begin(), signaturesRetrieved.end());
2423 UWARN(
"Some signatures have been retrieved from memory management, clearing global scan map...");
2428 timeReactivations = timer.
ticks();
2429 ULOGGER_INFO(
"timeReactivations=%fs", timeReactivations);
2435 std::list<std::pair<int, int> > loopClosureLinksAdded;
2436 int loopClosureVisualInliers = 0;
2437 float loopClosureVisualInliersRatio = 0.0f;
2438 int loopClosureVisualMatches = 0;
2439 float loopClosureLinearVariance = 0.0f;
2440 float loopClosureAngularVariance = 0.0f;
2441 float loopClosureVisualInliersMeanDist = 0;
2442 float loopClosureVisualInliersDistribution = 0;
2444 int proximityDetectionsAddedVisually = 0;
2445 int proximityDetectionsAddedByICPMulti = 0;
2446 int proximityDetectionsAddedByICPGlobal = 0;
2447 int lastProximitySpaceClosureId = 0;
2448 int proximitySpacePaths = 0;
2449 int localVisualPathsChecked = 0;
2450 int localScanPathsChecked = 0;
2451 int loopIdSuppressedByProximity = 0;
2462 UINFO(
"Proximity detection by space disabled as if we force to have a global loop " 2463 "closure with previous map before doing proximity detections (%s=true).",
2464 Parameters::kRtabmapStartNewMapOnLoopClosure().c_str());
2468 UWARN(
"Cannot do local loop closure detection in space if graph optimization is disabled!");
2487 UDEBUG(
"Proximity detection (local loop closure in SPACE using matching images, local radius=%fm)",
_localRadius);
2488 std::map<int, float> nearestIds;
2498 std::map<int, Transform> nearestPoses;
2499 for(std::map<int, float>::iterator iter=nearestIds.lower_bound(1); iter!=nearestIds.end(); ++iter)
2503 nearestPoses.insert(std::make_pair(iter->first,
_optimizedPoses.at(iter->first)));
2506 UDEBUG(
"nearestPoses=%d", (
int)nearestPoses.size());
2510 UDEBUG(
"got %d paths", (
int)nearestPathsNotSorted.size());
2512 std::map<NearestPathKey, std::map<int, Transform> > nearestPaths;
2514 for(std::map<
int, std::map<int, Transform> >::const_iterator iter=nearestPathsNotSorted.begin();iter!=nearestPathsNotSorted.end(); ++iter)
2516 const std::map<int, Transform> & path = iter->second;
2517 float highestLikelihood = 0.0f;
2518 int highestLikelihoodId = iter->first;
2519 float smallestDistanceSqr = -1;
2520 for(std::map<int, Transform>::const_iterator jter=path.begin(); jter!=path.end(); ++jter)
2522 float v =
uValue(likelihood, jter->first, 0.0f);
2523 float distance = (currentPoseInv * jter->second).getNormSquared();
2524 if(v > highestLikelihood || (v == highestLikelihood && (smallestDistanceSqr < 0 || distance < smallestDistanceSqr)))
2526 highestLikelihood = v;
2527 highestLikelihoodId = jter->first;
2531 nearestPaths.insert(std::make_pair(
NearestPathKey(highestLikelihood, highestLikelihoodId, smallestDistanceSqr), path));
2540 for(std::map<
NearestPathKey, std::map<int, Transform> >::const_reverse_iterator iter=nearestPaths.rbegin();
2541 iter!=nearestPaths.rend() &&
2545 std::map<int, Transform> path = iter->second;
2553 if(iter->first.likelihood > 0.0f &&
2554 path.find(iter->first.id)!=path.end())
2556 nearestId = iter->first.id;
2566 if(!signature->
hasLink(nearestId) &&
2567 (proximityFilteringRadius <= 0.0f ||
2570 ++localVisualPathsChecked;
2581 transform = transform.
inverse();
2582 if(proximityFilteringRadius <= 0 || transform.
getNormSquared() <= proximityFilteringRadius*proximityFilteringRadius)
2584 UINFO(
"[Visual] Add local loop closure in SPACE (%d->%d) %s",
2594 ++proximityDetectionsAddedVisually;
2595 lastProximitySpaceClosureId = nearestId;
2597 loopClosureVisualInliers = info.
inliers;
2599 loopClosureVisualMatches = info.
matches;
2602 loopClosureLinearVariance = 1.0/information.at<
double>(0,0);
2603 loopClosureAngularVariance = 1.0/information.at<
double>(5,5);
2611 UDEBUG(
"Proximity detection on %d is close to loop closure %d, ignoring loop closure transform estimation...",
2617 loopIdSuppressedByProximity = nearestId;
2619 else if(loopIdSuppressedByProximity == 0)
2621 loopIdSuppressedByProximity = nearestId;
2626 loopClosureLinksAdded.push_back(std::make_pair(signature->
id(), nearestId));
2630 UWARN(
"Ignoring local loop closure with %d because resulting " 2631 "transform is too large!? (%fm > %fm)",
2632 nearestId, transform.
getNorm(), proximityFilteringRadius);
2639 timeProximityBySpaceVisualDetection = timer.
ticks();
2640 ULOGGER_INFO(
"timeProximityBySpaceVisualDetection=%fs", timeProximityBySpaceVisualDetection);
2645 UDEBUG(
"Proximity detection (local loop closure in SPACE with scan matching)");
2648 UDEBUG(
"Proximity by scan matching is disabled (%s=%d).", Parameters::kRGBDProximityPathMaxNeighbors().c_str(),
_proximityMaxNeighbors);
2652 proximitySpacePaths = (int)nearestPaths.size();
2653 for(std::map<
NearestPathKey, std::map<int, Transform> >::const_reverse_iterator iter=nearestPaths.rbegin();
2654 iter!=nearestPaths.rend() &&
2658 std::map<int, Transform> path = iter->second;
2660 UASSERT(path.begin()->first > 0);
2668 if(!signature->
hasLink(nearestId))
2672 std::map<int, Transform> filteredPath;
2674 std::map<int, Transform>::iterator nearestIdIter = path.find(nearestId);
2678 for(std::map<int, Transform>::iterator iter=nearestIdIter; iter!=path.end() && i<=
_proximityMaxNeighbors-1; ++iter, ++i)
2680 filteredPath.insert(*iter);
2683 for(std::map<int, Transform>::reverse_iterator iter(nearestIdIter); iter!=path.rend() && i<=
_proximityMaxNeighbors-1; ++iter, ++i)
2685 filteredPath.insert(*iter);
2687 path = filteredPath;
2691 std::map<int, Transform> optimizedLocalPath;
2700 UERROR(
"Proximity path not containing nearest ID ?! Skipping this path.");
2705 for(std::map<int, Transform>::iterator jter=path.lower_bound(1); jter!=path.end(); ++jter)
2707 optimizedLocalPath.insert(std::make_pair(jter->first, t * jter->second));
2712 optimizedLocalPath = path;
2715 std::map<int, Transform> filteredPath;
2716 if(
_globalScanMap.
empty() && optimizedLocalPath.size() > 2 && proximityFilteringRadius > 0.0f)
2721 filteredPath.insert(*optimizedLocalPath.find(nearestId));
2725 filteredPath = optimizedLocalPath;
2728 if(filteredPath.size() > 0)
2731 filteredPath.insert(std::make_pair(signature->
id(),
_optimizedPoses.at(signature->
id())));
2735 ++localScanPathsChecked;
2738 bool icpMulti =
true;
2749 assembledData.
setId(nearestId);
2756 Transform guess = filteredPath.at(nearestId).
inverse() * filteredPath.at(signature->
id());
2760 transform = transform.
inverse();
2766 UINFO(
"[Scan matching] Add local loop closure in SPACE (%d->%d) %s",
2771 cv::Mat scanMatchingIds;
2774 std::stringstream stream;
2776 for(std::map<int, Transform>::iterator iter=optimizedLocalPath.begin(); iter!=optimizedLocalPath.end(); ++iter)
2778 if(iter != optimizedLocalPath.begin())
2784 std::string scansStr = stream.str();
2785 scanMatchingIds = cv::Mat(1,
int(scansStr.size()+1), CV_8SC1, (
void *)scansStr.c_str());
2792 loopClosureLinksAdded.push_back(std::make_pair(signature->
id(), nearestId));
2796 ++proximityDetectionsAddedByICPMulti;
2800 ++proximityDetectionsAddedByICPGlobal;
2804 if(proximityDetectionsAddedVisually == 0)
2806 lastProximitySpaceClosureId = nearestId;
2829 timeProximityBySpaceDetection = timer.
ticks();
2830 ULOGGER_INFO(
"timeProximityBySpaceDetection=%fs", timeProximityBySpaceDetection);
2838 if(loopIdSuppressedByProximity==0)
2843 info.
covariance = cv::Mat::eye(6,6,CV_64FC1);
2855 loopClosureVisualInliers = info.
inliers;
2857 loopClosureVisualMatches = info.
matches;
2858 rejectedGlobalLoopClosure = transform.
isNull();
2859 if(rejectedGlobalLoopClosure)
2861 UWARN(
"Rejected loop closure %d -> %d: %s",
2866 rejectedGlobalLoopClosure =
true;
2867 UWARN(
"Rejected localization %d -> %d because distance to map (%fm) is over %s=%fm.",
2872 transform = transform.
inverse();
2875 if(!rejectedGlobalLoopClosure)
2880 loopClosureLinearVariance = 1.0/information.at<
double>(0,0);
2881 loopClosureAngularVariance = 1.0/information.at<
double>(5,5);
2883 if(!rejectedGlobalLoopClosure)
2889 if(rejectedGlobalLoopClosure)
2900 timeAddLoopClosureLink = timer.
ticks();
2901 ULOGGER_INFO(
"timeAddLoopClosureLink=%fs", timeAddLoopClosureLink);
2906 std::map<int, std::set<int> > landmarksDetected;
2910 UDEBUG(
"hasGlobalLoopClosuresInOdomCache=%d", hasGlobalLoopClosuresInOdomCache?1:0);
2911 for(std::map<int, Link>::const_iterator iter=signature->
getLandmarks().begin(); iter!=signature->
getLandmarks().end(); ++iter)
2917 !hasGlobalLoopClosuresInOdomCache &&
2922 UWARN(
"Ignoring landmark %d for localization as it is too far (%fm > %s=%f) " 2923 "and odom cache doesn't contain global loop closure(s).",
2925 iter->second.transform().getNorm(),
2926 Parameters::kRGBDLocalRadius().c_str(),
2931 UINFO(
"Landmark %d observed again! Seen the first time by node %d.", -iter->first, *
_memory->
getLandmarksIndex().find(iter->first)->second.begin());
2933 rejectedGlobalLoopClosure =
false;
2958 UERROR(
"Virtual link larger than local radius (%fm > %fm). Aborting the plan!",
2968 float maxLinearError = 0.0f;
2969 float maxLinearErrorRatio = 0.0f;
2970 float maxAngularError = 0.0f;
2971 float maxAngularErrorRatio = 0.0f;
2972 double optimizationError = 0.0;
2973 int optimizationIterations = 0;
2974 cv::Mat localizationCovariance;
2976 bool rejectedLandmark =
false;
2977 bool delayedLocalization =
false;
2981 UDEBUG(
"Last prox: %d", lastProximitySpaceClosureId);
2986 UDEBUG(
"Prox Time: %d", proximityDetectionsInTimeFound);
2987 UDEBUG(
"Landmarks: %d", (
int)landmarksDetected.size());
2988 UDEBUG(
"Retrieved: %d", (
int)signaturesRetrieved.size());
2994 lastProximitySpaceClosureId>0 ||
2998 proximityDetectionsInTimeFound>0 ||
2999 !landmarksDetected.empty() ||
3000 signaturesRetrieved.size())
3005 !landmarksDetected.empty()))
3014 for(std::map<
int, std::set<int> >::iterator iter=landmarksDetected.begin(); iter!=landmarksDetected.end(); ++iter)
3019 localizationLinks.insert(std::make_pair(iter->first, signature->
getLandmarks().at(iter->first)));
3024 bool allLocalizationLinksInGraph = !localizationLinks.empty();
3025 for(std::multimap<int, Link>::iterator iter=localizationLinks.begin(); iter!=localizationLinks.end(); ++iter)
3029 allLocalizationLinksInGraph =
false;
3039 signaturesRetrieved.empty() &&
3040 !localizationLinks.empty() &&
3041 allLocalizationLinksInGraph)
3058 constraints.insert(selfLinks.begin(), selfLinks.end());
3059 for(std::multimap<int, Link>::iterator iter=localizationLinks.begin(); iter!=localizationLinks.end(); ++iter)
3061 constraints.insert(std::make_pair(iter->second.from(), iter->second));
3063 for(std::multimap<int, Link>::iterator iter=constraints.begin(); iter!=constraints.end(); ++iter)
3065 std::map<int, Transform>::iterator iterPose =
_optimizedPoses.find(iter->second.to());
3066 if(iterPose !=
_optimizedPoses.end() && poses.find(iterPose->first) == poses.end())
3068 poses.insert(*iterPose);
3070 constraints.insert(std::make_pair(iterPose->first,
Link(iterPose->first, iterPose->first,
Link::kPosePrior, iterPose->second, cv::Mat::eye(6,6, CV_64FC1)*1000000)));
3073 UDEBUG(
"Constraint %d->%d (type=%s, var = %f %f)", iter->second.from(), iter->second.to(), iter->second.typeName().c_str(), iter->second.transVariance(), iter->second.rotVariance());
3075 for(std::map<int, Transform>::iterator iter=poses.begin(); iter!=poses.end(); ++iter)
3077 UDEBUG(
"Pose %d %s", iter->first, iter->second.prettyPrint().c_str());
3081 std::map<int, Transform> posesOut;
3082 std::multimap<int, Link> edgeConstraintsOut;
3084 UDEBUG(
"priorsIgnored was %s", priorsIgnored?
"true":
"false");
3088 std::map<int, Transform> optPoses =
_graphOptimizer->
optimize(poses.begin()->first, posesOut, edgeConstraintsOut);
3090 for(std::map<int, Transform>::iterator iter=optPoses.begin(); iter!=optPoses.end(); ++iter)
3092 UDEBUG(
"Opt %d %s", iter->first, iter->second.prettyPrint().c_str());
3095 if(optPoses.empty())
3097 UWARN(
"Optimization failed, rejecting localization!");
3098 rejectLocalization =
true;
3102 UINFO(
"Compute max graph errors...");
3103 const Link * maxLinearLink = 0;
3104 const Link * maxAngularLink = 0;
3108 maxLinearErrorRatio,
3109 maxAngularErrorRatio,
3117 UWARN(
"Could not compute graph errors! Wrong loop closures could be accepted!");
3118 optPoses = posesOut;
3123 UINFO(
"Max optimization linear error = %f m (link %d->%d, var=%f, ratio error/std=%f, thr=%f)",
3125 maxLinearLink->
from(),
3126 maxLinearLink->
to(),
3132 UWARN(
"Rejecting localization (%d <-> %d) in this " 3133 "iteration because a wrong loop closure has been " 3134 "detected after graph optimization, resulting in " 3135 "a maximum graph error ratio of %f (edge %d->%d, type=%d, abs error=%f m, stddev=%f). The " 3136 "maximum error ratio parameter \"%s\" is %f of std deviation.",
3137 localizationLinks.rbegin()->second.from(),
3138 localizationLinks.rbegin()->second.to(),
3139 maxLinearErrorRatio,
3140 maxLinearLink->
from(),
3141 maxLinearLink->
to(),
3142 maxLinearLink->
type(),
3145 Parameters::kRGBDOptimizeMaxError().c_str(),
3147 rejectLocalization =
true;
3152 UINFO(
"Max optimization angular error = %f deg (link %d->%d, var=%f, ratio error/std=%f, thr=%f)",
3153 maxAngularError*180.0
f/CV_PI,
3154 maxAngularLink->
from(),
3155 maxAngularLink->
to(),
3161 UWARN(
"Rejecting localization (%d <-> %d) in this " 3162 "iteration because a wrong loop closure has been " 3163 "detected after graph optimization, resulting in " 3164 "a maximum graph error ratio of %f (edge %d->%d, type=%d, abs error=%f deg, stddev=%f). The " 3165 "maximum error ratio parameter \"%s\" is %f of std deviation.",
3166 localizationLinks.rbegin()->second.from(),
3167 localizationLinks.rbegin()->second.to(),
3168 maxAngularErrorRatio,
3169 maxAngularLink->
from(),
3170 maxAngularLink->
to(),
3171 maxAngularLink->
type(),
3172 maxAngularError*180.0f/CV_PI,
3174 Parameters::kRGBDOptimizeMaxError().c_str(),
3176 rejectLocalization =
true;
3181 bool hasGlobalLoopClosuresOrLandmarks =
false;
3187 for(std::multimap<int, Link>::iterator iter=constraints.begin(); iter!=constraints.end() && !hasGlobalLoopClosuresOrLandmarks; ++iter)
3189 hasGlobalLoopClosuresOrLandmarks =
3193 if(hasGlobalLoopClosuresOrLandmarks && !localizationLinks.empty())
3195 rejectLocalization =
false;
3196 UWARN(
"Global and loop closures seem not tallying together, try again to optimize without local loop closures...");
3198 UDEBUG(
"priorsIgnored was %s", priorsIgnored?
"true":
"false");
3204 for(std::map<int, Transform>::iterator iter=optPoses.begin(); iter!=optPoses.end(); ++iter)
3206 UDEBUG(
"Opt2 %d %s", iter->first, iter->second.prettyPrint().c_str());
3209 if(optPoses.empty())
3211 UWARN(
"Optimization failed, rejecting localization!");
3212 rejectLocalization =
true;
3216 UINFO(
"Compute max graph errors...");
3217 const Link * maxLinearLink = 0;
3218 const Link * maxAngularLink = 0;
3222 maxLinearErrorRatio,
3223 maxAngularErrorRatio,
3231 UWARN(
"Could not compute graph errors! Wrong loop closures could be accepted!");
3232 optPoses = posesOut;
3237 UINFO(
"Max optimization linear error = %f m (link %d->%d, var=%f, ratio error/std=%f, thr=%f)",
3239 maxLinearLink->
from(),
3240 maxLinearLink->
to(),
3246 UWARN(
"Rejecting localization (%d <-> %d) in this " 3247 "iteration because a wrong loop closure has been " 3248 "detected after graph optimization, resulting in " 3249 "a maximum graph error ratio of %f (edge %d->%d, type=%d, abs error=%f m, stddev=%f). The " 3250 "maximum error ratio parameter \"%s\" is %f of std deviation.",
3251 localizationLinks.rbegin()->second.from(),
3252 localizationLinks.rbegin()->second.to(),
3253 maxLinearErrorRatio,
3254 maxLinearLink->
from(),
3255 maxLinearLink->
to(),
3256 maxLinearLink->
type(),
3259 Parameters::kRGBDOptimizeMaxError().c_str(),
3261 rejectLocalization =
true;
3266 UINFO(
"Max optimization angular error = %f deg (link %d->%d, var=%f, ratio error/std=%f, thr=%f)",
3267 maxAngularError*180.0
f/CV_PI,
3268 maxAngularLink->
from(),
3269 maxAngularLink->
to(),
3275 UWARN(
"Rejecting localization (%d <-> %d) in this " 3276 "iteration because a wrong loop closure has been " 3277 "detected after graph optimization, resulting in " 3278 "a maximum graph error ratio of %f (edge %d->%d, type=%d, abs error=%f deg, stddev=%f). The " 3279 "maximum error ratio parameter \"%s\" is %f of std deviation.",
3280 localizationLinks.rbegin()->second.from(),
3281 localizationLinks.rbegin()->second.to(),
3282 maxAngularErrorRatio,
3283 maxAngularLink->
from(),
3284 maxAngularLink->
to(),
3285 maxAngularLink->
type(),
3286 maxAngularError*180.0f/CV_PI,
3288 Parameters::kRGBDOptimizeMaxError().c_str(),
3290 rejectLocalization =
true;
3297 if(!rejectLocalization)
3299 if(hasGlobalLoopClosuresOrLandmarks)
3307 UWARN(
"Successfully optimized without local loop closures! Clear them from local odometry cache. %ld/%ld have been removed.",
3312 UWARN(
"Successfully optimized without local loop closures!");
3317 bool hadAlreadyLocalizationLinks =
false;
3328 hadAlreadyLocalizationLinks =
true;
3335 for(std::multimap<int, Link>::iterator iter=localizationLinks.begin(); iter!=localizationLinks.end(); ++iter)
3337 Transform newT = newOptPoseInv * optPoses.at(iter->first);
3338 UDEBUG(
"Adjusted localization link %d->%d after optimization", iter->second.from(), iter->second.to());
3339 UDEBUG(
"from %s", iter->second.transform().prettyPrint().c_str());
3341 iter->second.setTransform(newT);
3355 UINFO(
"Update localization");
3363 Transform u = signature->
getPose() * localizationLinks.rbegin()->second.transform();
3367 Transform transform = localizationLinks.rbegin()->second.transform();
3368 int loopId = localizationLinks.rbegin()->first;
3374 landmarkId = loopId;
3375 UASSERT(landmarksDetected.find(landmarkId) != landmarksDetected.end() &&
3376 !landmarksDetected.at(landmarkId).empty());
3377 loopId = *landmarksDetected.at(landmarkId).begin();
3384 if(iterGravityLoop!=loopS->
getLinks().end() &&
3385 iterGravitySign!=signature->
getLinks().end())
3390 iterGravityLoop->second.transform().getEulerAngles(roll, pitch, yaw);
3395 (gravityCorr *
_optimizedPoses.at(landmarkId)).getEulerAngles(roll,pitch,yaw);
3399 iterGravityLoop->second.transform().getEulerAngles(roll, pitch, yaw);
3402 targetRotation =
Transform(0,0,0,roll,pitch,targetRotation.
theta());
3405 u = signature->
getPose() * transform;
3407 else if(iterGravityLoop!=loopS->
getLinks().end() ||
3408 iterGravitySign!=signature->
getLinks().end())
3410 UWARN(
"Gravity link not found for %d or %d, localization won't be corrected with gravity.", loopId, signature->
id());
3421 iter->second = mapCorrectionInv * up * iter->second;
3427 Transform newPose =
_optimizedPoses.at(localizationLinks.rbegin()->first) * localizationLinks.rbegin()->second.transform().inverse();
3432 newPose = newPose.
to3DoF();
3439 if(iterGravitySign!=signature->
getLinks().end())
3441 Transform transform = localizationLinks.rbegin()->second.transform();
3444 UDEBUG(
"Gravity link = %s", iterGravitySign->second.transform().prettyPrint().c_str());
3445 _optimizedPoses.at(localizationLinks.rbegin()->first).getEulerAngles(roll, pitch, yaw);
3447 targetRotation =
Transform(0,0,0,roll,pitch,targetRotation.
theta());
3451 iterGravitySign->second.transform().
getEulerAngles(roll, pitch, tmp1);
3456 else if(iterGravitySign!=signature->
getLinks().end())
3458 UWARN(
"Gravity link not found for %d, localization won't be corrected with gravity.", signature->
id());
3463 localizationCovariance = localizationLinks.rbegin()->second.infMatrix().inv();
3467 UWARN(
"Localization was good, but waiting for another one to be more accurate (%s>0)", Parameters::kRGBDMaxOdomCacheSize().c_str());
3468 delayedLocalization =
true;
3469 rejectLocalization =
true;
3474 if(rejectLocalization)
3477 lastProximitySpaceClosureId = 0;
3478 rejectedGlobalLoopClosure =
true;
3479 rejectedLandmark =
true;
3484 UINFO(
"Update map correction");
3490 UWARN(
"Optimization: clearing guess poses as %s has changed state, now %s",
3496 std::multimap<int, Link> constraints;
3498 optimizeCurrentMap(signature->
id(),
false, poses, covariance, &constraints, &optimizationError, &optimizationIterations);
3502 bool updateConstraints =
true;
3505 UWARN(
"Graph optimization failed! Rejecting last loop closures added.");
3506 for(std::list<std::pair<int, int> >::iterator iter=loopClosureLinksAdded.begin(); iter!=loopClosureLinksAdded.end(); ++iter)
3509 UWARN(
"Loop closure %d->%d rejected!", iter->first, iter->second);
3511 updateConstraints =
false;
3513 lastProximitySpaceClosureId = 0;
3514 rejectedGlobalLoopClosure =
true;
3515 rejectedLandmark =
true;
3519 loopClosureLinksAdded.size() &&
3520 optimizationIterations > 0 &&
3523 UINFO(
"Compute max graph errors...");
3524 const Link * maxLinearLink = 0;
3525 const Link * maxAngularLink = 0;
3529 maxLinearErrorRatio,
3530 maxAngularErrorRatio,
3535 if(maxLinearLink == 0 && maxAngularLink==0)
3537 UWARN(
"Could not compute graph errors! Wrong loop closures could be accepted!");
3540 bool reject =
false;
3543 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()));
3546 UWARN(
"Rejecting all added loop closures (%d, first is %d <-> %d) in this " 3547 "iteration because a wrong loop closure has been " 3548 "detected after graph optimization, resulting in " 3549 "a maximum graph error ratio of %f (edge %d->%d, type=%d, abs error=%f m, stddev=%f). The " 3550 "maximum error ratio parameter \"%s\" is %f of std deviation.",
3551 (
int)loopClosureLinksAdded.size(),
3552 loopClosureLinksAdded.front().first,
3553 loopClosureLinksAdded.front().second,
3554 maxLinearErrorRatio,
3555 maxLinearLink->
from(),
3556 maxLinearLink->
to(),
3557 maxLinearLink->
type(),
3560 Parameters::kRGBDOptimizeMaxError().c_str(),
3567 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()));
3570 UWARN(
"Rejecting all added loop closures (%d, first is %d <-> %d) in this " 3571 "iteration because a wrong loop closure has been " 3572 "detected after graph optimization, resulting in " 3573 "a maximum graph error ratio of %f (edge %d->%d, type=%d, abs error=%f deg, stddev=%f). The " 3574 "maximum error ratio parameter \"%s\" is %f of std deviation.",
3575 (
int)loopClosureLinksAdded.size(),
3576 loopClosureLinksAdded.front().first,
3577 loopClosureLinksAdded.front().second,
3578 maxAngularErrorRatio,
3579 maxAngularLink->
from(),
3580 maxAngularLink->
to(),
3581 maxAngularLink->
type(),
3582 maxAngularError*180.0f/CV_PI,
3584 Parameters::kRGBDOptimizeMaxError().c_str(),
3592 for(std::list<std::pair<int, int> >::iterator iter=loopClosureLinksAdded.begin(); iter!=loopClosureLinksAdded.end(); ++iter)
3595 UWARN(
"Loop closure %d->%d rejected!", iter->first, iter->second);
3597 updateConstraints =
false;
3599 lastProximitySpaceClosureId = 0;
3600 rejectedGlobalLoopClosure =
true;
3601 rejectedLandmark =
true;
3605 if(updateConstraints)
3607 UINFO(
"Updated local map (old size=%d, new size=%d)", (
int)
_optimizedPoses.size(), (int)poses.size());
3610 localizationCovariance = covariance;
3625 bool hasPrior = signature->
hasLink(signature->
id());
3628 for(std::multimap<int, Link>::reverse_iterator iter=
_constraints.rbegin(); !hasPrior && iter!=
_constraints.rend(); ++iter)
3644 if(newLocId==0 && !landmarksDetected.empty())
3646 std::map<int, std::set<int> >::const_iterator iter =
_memory->
getLandmarksIndex().find(landmarksDetected.begin()->first);
3649 if(iter->second.size() && *iter->second.begin()!=signature->
id())
3656 timeMapOptimization = timer.
ticks();
3657 ULOGGER_INFO(
"timeMapOptimization=%fs", timeMapOptimization);
3663 int dictionarySize = 0;
3664 int refWordsCount = 0;
3665 int refUniqueWordsCount = 0;
3666 int lcHypothesisReactivated = 0;
3672 lcHypothesisReactivated = sLoop->
isSaved()?1.0f:0.0f;
3675 refWordsCount = (int)signature->
getWords().size();
3721 statistics_.
addStatistic(Statistics::kLoopLandmark_detected(), landmarksDetected.empty()?0:-landmarksDetected.begin()->first);
3722 statistics_.
addStatistic(Statistics::kLoopLandmark_detected_node_ref(), landmarksDetected.empty() || landmarksDetected.begin()->second.empty()?0:*landmarksDetected.begin()->second.begin());
3724 statistics_.
addStatistic(Statistics::kLoopVisual_inliers_distribution(), loopClosureVisualInliersDistribution);
3727 statistics_.
addStatistic(Statistics::kProximitySpace_detections_added_visually(), proximityDetectionsAddedVisually);
3728 statistics_.
addStatistic(Statistics::kProximitySpace_detections_added_icp_multi(), proximityDetectionsAddedByICPMulti);
3729 statistics_.
addStatistic(Statistics::kProximitySpace_detections_added_icp_global(), proximityDetectionsAddedByICPGlobal);
3741 if(
_loopClosureHypothesis.first || lastProximitySpaceClosureId || (!rejectedLandmark && !landmarksDetected.empty()))
3747 std::multimap<int, Link>::const_iterator loopIter = sLoop->
getLinks().find(signature->
id());
3749 UINFO(
"Set loop closure transform = %s", loopIter->second.transform().prettyPrint().c_str());
3835 statistics_.
addStatistic(Statistics::kTimingProximity_by_space_visual(), timeProximityBySpaceVisualDetection*1000);
3867 long estimatedMemoryUsage =
sizeof(
Rtabmap);
3868 estimatedMemoryUsage +=
_optimizedPoses.size() * (
sizeof(int) +
sizeof(
Transform) + 12 *
sizeof(float) +
sizeof(std::map<int, Transform>::iterator)) +
sizeof(std::map<int, Transform>);
3869 estimatedMemoryUsage +=
_constraints.size() * (
sizeof(int) +
sizeof(
Transform) + 12 *
sizeof(float) +
sizeof(cv::Mat) + 36 *
sizeof(double) +
sizeof(std::map<int, Link>::iterator)) +
sizeof(std::map<int, Link>);
3872 estimatedMemoryUsage +=
_parameters.size()*(
sizeof(std::string)*2+
sizeof(ParametersMap::iterator)) +
sizeof(
ParametersMap);
3902 timeStatsCreation = timer.
ticks();
3903 ULOGGER_INFO(
"Time creating stats = %f...", timeStatsCreation);
3914 lastSignatureData = *signature;
3930 if(signatureRemoved)
3932 signaturesRemoved.push_back(signatureRemoved);
3939 if(signatureRemoved != lastSignatureData.id())
3944 (landmarksDetected.empty() || rejectedLandmark) &&
3947 UWARN(
"Ignoring location %d because a global loop closure is required before starting a new map!",
3949 signaturesRemoved.push_back(signature->
id());
3956 UWARN(
"Ignoring location %d because a good signature (with enough features or with a landmark detected) is required before starting a new map!",
3958 signaturesRemoved.push_back(signature->
id());
3961 else if((smallDisplacement || tooFastMovement) &&
3963 lastProximitySpaceClosureId == 0 &&
3964 (rejectedLandmark || landmarksDetected.empty()) &&
3968 UINFO(
"Ignoring location %d because the displacement is too small! (d=%f a=%f)",
3971 signaturesRemoved.push_back(signature->
id());
3980 (smallDisplacement || tooFastMovement) &&
3982 lastProximitySpaceClosureId == 0 &&
3983 !delayedLocalization &&
3984 (rejectedLandmark || landmarksDetected.empty()))
3989 if(iter->second.from() == signatureRemoved || iter->second.to() == signatureRemoved)
4003 timeMemoryCleanup = timer.
ticks();
4004 ULOGGER_INFO(
"timeMemoryCleanup = %fs... %d signatures removed", timeMemoryCleanup, (
int)signaturesRemoved.size());
4016 double totalTime = timerTotal.
ticks();
4017 ULOGGER_INFO(
"Total time processing = %fs...", totalTime);
4023 std::list<int> transferred =
_memory->
forget(immunizedLocations);
4024 signaturesRemoved.insert(signaturesRemoved.end(), transferred.begin(), transferred.end());
4033 for(std::list<int>::iterator iter=signaturesRemoved.begin(); iter!=signaturesRemoved.end() &&
_gpsGeocentricCache.size(); ++iter)
4051 UDEBUG(
"Refresh local map from %d",
id);
4058 UDEBUG(
"Refresh local map from %d",
id);
4071 UDEBUG(
"Refresh local map from %d",
id);
4082 if(signaturesRemoved.size() == 1 && signaturesRemoved.front() == lastSignatureData.id())
4084 int lastId = signaturesRemoved.front();
4085 UDEBUG(
"Detected that only last signature has been removed (lastId=%d)", lastId);
4087 for(std::multimap<int, Link>::iterator iter=
_constraints.find(lastId); iter!=
_constraints.end() && iter->first==lastId;++iter)
4089 if(iter->second.to() != iter->second.from())
4106 if(iter->first > 0 && !
uContains(ids, iter->first))
4108 UDEBUG(
"Removed %d from local map", iter->first);
4114 UWARN(
"optimized poses have been modified, clearing global scan map...");
4126 if(iter->first > 0 && (!
uContains(ids, iter->second.from()) || !
uContains(ids, iter->second.to())))
4140 UDEBUG(
"Optimized poses cleared!");
4155 timeRealTimeLimitReachedProcess = timer.
ticks();
4156 ULOGGER_INFO(
"Time limit reached processing = %f...", timeRealTimeLimitReachedProcess);
4161 int localGraphSize = 0;
4183 std::map<int, Transform> poses;
4184 std::multimap<int, Link> constraints;
4200 UINFO(
"Adding data %d [%d] (rgb/left=%d depth/right=%d)", lastSignatureData.id(), lastSignatureData.mapId(), lastSignatureData.sensorData().imageRaw().empty()?0:1, lastSignatureData.sensorData().depthOrRightRaw().empty()?0:1);
4205 std::multimap<int, int> missingIds;
4211 missingIds.insert(std::make_pair(-1, tmpId));
4222 for(std::map<int, int>::iterator iter=ids.begin(); iter!=ids.end(); ++iter)
4224 if(iter->first != loopId &&
4227 missingIds.insert(std::make_pair(iter->second, iter->first));
4236 if(ids.find(*iter) == ids.end())
4250 std::stringstream stream;
4251 for(std::multimap<int, int>::iterator iter=missingIds.begin(); iter!=missingIds.end() && loaded<(int)
_maxRepublished; ++iter)
4256 stream << iter->second <<
" ";
4260 UWARN(
"Republishing data of requested node(s) %s(%s=%d)",
4261 stream.str().c_str(),
4262 Parameters::kRtabmapMaxRepublished().c_str(),
4271 lastSignatureData.id(),
4272 lastSignatureData.mapId(),
4273 lastSignatureData.getWeight(),
4274 lastSignatureData.getStamp(),
4275 lastSignatureData.getLabel(),
4276 lastSignatureData.getPose(),
4277 lastSignatureData.getGroundTruthPose());
4278 const std::vector<float> & v = lastSignatureData.
getVelocity();
4281 nodeInfo.setVelocity(v[0], v[1], v[2], v[3], v[4], v[5]);
4283 nodeInfo.sensorData().setGPS(lastSignatureData.sensorData().gps());
4284 nodeInfo.sensorData().setEnvSensors(lastSignatureData.sensorData().envSensors());
4288 localGraphSize = (int)poses.size();
4289 if(!lastSignatureLocalizedPose.isNull())
4291 poses.insert(std::make_pair(lastSignatureData.id(), lastSignatureLocalizedPose));
4305 UDEBUG(
"Computing RMSE...");
4306 float translational_rmse = 0.0f;
4307 float translational_mean = 0.0f;
4308 float translational_median = 0.0f;
4309 float translational_std = 0.0f;
4310 float translational_min = 0.0f;
4311 float translational_max = 0.0f;
4312 float rotational_rmse = 0.0f;
4313 float rotational_mean = 0.0f;
4314 float rotational_median = 0.0f;
4315 float rotational_std = 0.0f;
4316 float rotational_min = 0.0f;
4317 float rotational_max = 0.0f;
4324 translational_median,
4347 UDEBUG(
"Computing RMSE...done!");
4350 std::vector<int> ids;
4354 ids.push_back(*iter);
4358 ids.push_back(iter->first);
4361 UDEBUG(
"wmState=%d", (
int)ids.size());
4371 UDEBUG(
"Empty trash...");
4379 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",
4383 timeLikelihoodCalculation,
4384 timePosteriorCalculation,
4385 timeHypothesesCreation,
4386 timeHypothesesValidation,
4387 timeRealTimeLimitReachedProcess,
4399 timeRetrievalDbAccess,
4400 timeAddLoopClosureLink,
4402 timeNeighborLinkRefining,
4403 timeProximityByTimeDetection,
4404 timeProximityBySpaceDetection,
4405 timeMapOptimization);
4406 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",
4409 (
int)signaturesRemoved.size(),
4414 rejectedGlobalLoopClosure?1:0,
4417 int(signaturesRetrieved.size()),
4418 lcHypothesisReactivated,
4419 refUniqueWordsCount,
4423 rehearsalMaxId>0?1:0,
4441 fprintf(
_foutInt,
"%s", logI.c_str());
4444 UINFO(
"Time logging = %f...", timer.
ticks());
4447 timeFinalizingStatistics = timer.
ticks();
4448 UDEBUG(
"End process, timeFinalizingStatistics=%fs", timeFinalizingStatistics);
4464 ULOGGER_WARN(
"maxTimeAllowed < 0, then setting it to 0 (inf).");
4478 ULOGGER_DEBUG(
"Comparing new working directory path \"%s\" with \"%s\"", path.c_str(),
_wDir.c_str());
4479 if(path.compare(
_wDir) != 0)
4483 UWARN(
"Working directory has been changed from \"%s\" with \"%s\", new log files will be created.",
4484 path.c_str(),
_wDir.c_str());
4490 else if(path.empty())
4497 ULOGGER_ERROR(
"Directory \"%s\" doesn't exist!", path.c_str());
4506 bool linksRemoved =
false;
4507 for(std::multimap<int, Link>::iterator iter = links.begin(); iter!=links.end(); ++iter)
4526 linksRemoved =
true;
4537 UINFO(
"Update graph");
4539 std::multimap<int, Link> constraints;
4545 UWARN(
"Graph optimization failed after removing loop closure links from last location!");
4549 UINFO(
"Updated local map (old size=%d, new size=%d)", (
int)
_optimizedPoses.size(), (int)poses.size());
4568 UINFO(
"Update graph");
4574 if(iter->second.from() == lastId || iter->second.to() == lastId)
4590 std::multimap<int, Link> constraints;
4596 UWARN(
"Graph optimization failed after deleting the last location!");
4622 UERROR(
"Working directory not set.");
4635 int maxNearestNeighbors,
4640 std::map<int, Transform> poses;
4648 pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(
new pcl::PointCloud<pcl::PointXYZ>);
4654 std::map<int, float> foundIds;
4664 float radiusSqrd = radius * radius;
4667 if(iter->first != fromId)
4669 if(stm.find(iter->first) == stm.end() &&
4671 (radiusSqrd==0 || foundIds.at(iter->first) <= radiusSqrd))
4673 (*cloud)[oi] = pcl::PointXYZ(iter->second.x(), iter->second.y(), iter->second.z());
4674 ids[oi++] = iter->first;
4696 pcl::CropBox<pcl::PointXYZ> cropbox;
4697 cropbox.setInputCloud(cloud);
4698 cropbox.setMin(Eigen::Vector4f(-1, -radius, -999999, 0));
4699 cropbox.setMax(Eigen::Vector4f(radius, radius, 999999, 0));
4700 cropbox.setRotation(Eigen::Vector3f(roll, pitch, yaw));
4701 cropbox.setTranslation(Eigen::Vector3f(x, y, z));
4702 cropbox.setRotation(Eigen::Vector3f(roll,pitch,yaw));
4703 pcl::IndicesPtr indices(
new std::vector<int>());
4704 cropbox.filter(*indices);
4714 pcl::search::KdTree<pcl::PointXYZ>::Ptr kdTree(
new pcl::search::KdTree<pcl::PointXYZ>);
4715 kdTree->setInputCloud(cloud, indices);
4716 std::vector<int> ind;
4717 std::vector<float>
dist;
4718 pcl::PointXYZ pt(fromT.
x(), fromT.
y(), fromT.
z());
4719 kdTree->radiusSearch(pt, radius, ind, dist, maxNearestNeighbors);
4721 for(
unsigned int i=0; i<ind.size(); ++i)
4728 poses.insert(std::make_pair(ids[ind[i]], tmp));
4749 std::map<int, std::map<int, Transform> >
Rtabmap::getPaths(
const std::map<int, Transform> & posesIn,
const Transform & target,
int maxGraphDepth)
const 4751 std::map<int, std::map<int, Transform> > paths;
4752 std::set<int> nodesSet;
4753 std::map<int, Transform> poses;
4754 for(std::map<int, Transform>::const_iterator iter=posesIn.lower_bound(1); iter!=posesIn.end(); ++iter)
4756 nodesSet.insert(iter->first);
4757 poses.insert(*iter);
4761 double e0=0,e1=0,e2=0,e3=0,e4=0;
4767 std::map<int, Transform> path;
4775 UWARN(
"Nearest id of %s in %d poses is 0 !? Returning empty path.", target.
prettyPrint().c_str(), (int)poses.size());
4778 std::map<int, int> ids =
_memory->
getNeighborsId(nearestId, maxGraphDepth, 0,
true,
true,
true,
true, nodesSet);
4782 for(std::map<int, int>::iterator iter=ids.begin(); iter!=ids.end(); ++iter)
4784 std::map<int, Transform>::iterator jter = poses.find(iter->first);
4785 if(jter != poses.end())
4787 bool valid = path.empty();
4792 for(std::multimap<int, Link>::iterator kter=links.begin(); kter!=links.end() && !valid; ++kter)
4794 valid = path.find(kter->first) != path.end();
4813 UWARN(
"%s=Off but path(%d) > maxGraphDepth(%d)*2+1, nearestId=%d ids=%d. Is reduce graph activated before?",
4814 Parameters::kMemReduceGraph().c_str(), (
int)path.size(), maxGraphDepth, nearestId, (int)ids.size());
4816 paths.insert(std::make_pair(nearestId, path));
4820 UWARN(
"path.size()=0!? nearestId=%d ids=%d, aborting...", nearestId, (
int)ids.size());
4826 UDEBUG(
"e0=%fs e1=%fs e2=%fs e3=%fs e4=%fs", e0, e1, e2, e3, e4);
4833 bool lookInDatabase,
4834 std::map<int, Transform> & optimizedPoses,
4835 cv::Mat & covariance,
4836 std::multimap<int, Link> * constraints,
4838 int * iterationsDone)
const 4841 UINFO(
"Optimize map: around location %d (lookInDatabase=%s)",
id, lookInDatabase?
"true":
"false");
4848 id = ids.begin()->first;
4850 UINFO(
"get %d ids time %f s", (
int)ids.size(), timer.
ticks());
4852 std::map<int, Transform> poses =
Rtabmap::optimizeGraph(
id,
uKeysSet(ids), optimizedPoses, lookInDatabase, covariance, constraints, error, iterationsDone);
4857 optimizedPoses = poses;
4867 UWARN(
"Failed to optimize the graph! returning empty optimized poses...");
4868 optimizedPoses.clear();
4871 constraints->clear();
4879 const std::set<int> & ids,
4880 const std::map<int, Transform> & guessPoses,
4881 bool lookInDatabase,
4882 cv::Mat & covariance,
4883 std::multimap<int, Link> * constraints,
4885 int * iterationsDone)
const 4888 std::map<int, Transform> optimizedPoses;
4889 std::map<int, Transform> poses;
4890 std::multimap<int, Link> edgeConstraints;
4891 UDEBUG(
"ids=%d", (
int)ids.size());
4893 UINFO(
"get constraints (ids=%d, %d poses, %d edges) time %f s", (
int)ids.size(), (int)poses.size(), (int)edgeConstraints.size(), timer.
ticks());
4896 for(std::map<int, Transform>::iterator iter=poses.begin(); iter!=poses.end() && iter->first < 0; ++iter)
4900 cv::Mat infMatrix = cv::Mat::eye(6, 6, CV_64FC1);
4904 UDEBUG(
"Added prior %d : %s (variance: lin=%f ang=%f)", iter->first,
_markerPriors.at(iter->first).prettyPrint().c_str(),
4911 for(std::map<int, Transform>::iterator iter=poses.begin(); iter!=poses.end(); ++iter)
4914 std::map<int, Transform>::const_iterator foundGuess = guessPoses.find(iter->first);
4915 if(foundGuess!=guessPoses.end() && iter->first != fromId)
4917 iter->second = foundGuess->second;
4927 optimizedPoses = poses;
4930 *constraints = edgeConstraints;
4935 bool hasLandmarks = !edgeConstraints.empty() && edgeConstraints.begin()->first < 0;
4936 if(poses.size() != guessPoses.size() || hasLandmarks)
4938 UDEBUG(
"recompute poses using only links (robust to multi-session)");
4939 std::map<int, Transform> posesOut;
4940 std::multimap<int, Link> edgeConstraintsOut;
4942 optimizedPoses =
_graphOptimizer->
optimize(fromId, posesOut, edgeConstraintsOut, covariance, 0, error, iterationsDone);
4945 *constraints = edgeConstraintsOut;
4950 UDEBUG(
"use input guess poses");
4951 optimizedPoses =
_graphOptimizer->
optimize(fromId, poses, edgeConstraints, covariance, 0, error, iterationsDone);
4954 *constraints = edgeConstraints;
4958 if(!poses.empty() && optimizedPoses.empty())
4960 UWARN(
"Optimization has failed (poses=%d, guess=%d, links=%d)...",
4961 (
int)poses.size(), (int)guessPoses.size(), (int)edgeConstraints.size());
4965 UINFO(
"Optimization time %f s", timer.
ticks());
4967 return optimizedPoses;
4975 if(likelihood.size()==0)
4981 std::list<float> values;
4982 bool likelihoodNullValuesIgnored =
true;
4983 for(std::map<int, float>::iterator iter = ++likelihood.begin(); iter!=likelihood.end(); ++iter)
4985 if((iter->second >= 0 && !likelihoodNullValuesIgnored) ||
4986 (iter->second > 0 && likelihoodNullValuesIgnored))
4988 values.push_back(iter->second);
4991 UDEBUG(
"values.size=%d", values.size());
4993 float mean =
uMean(values);
5001 for(std::map<int, float>::iterator iter=++likelihood.begin(); iter!= likelihood.end(); ++iter)
5003 float value = iter->second;
5004 if(value > mean+stdDev && mean)
5006 iter->second = (value-(stdDev-epsilon))/mean;
5010 maxId = iter->first;
5013 else if(value == 1.0
f && stdDev == 0)
5015 iter->second = 1.0f;
5019 maxId = iter->first;
5024 iter->second = 1.0f;
5028 if(stdDev > epsilon && max)
5030 likelihood.begin()->second = mean/stdDev + 1.0f;
5034 likelihood.begin()->second = 2.0f;
5037 double time = timer.ticks();
5038 UDEBUG(
"mean=%f, stdDev=%f, max=%f, maxId=%d, time=%fs", mean, stdDev, max, maxId, time);
5047 UERROR(
"Working directory not set.");
5050 std::list<int> signaturesToCompare;
5061 signaturesToCompare.push_back(iter->first);
5067 signaturesToCompare.push_back(iter->first);
5073 std::string fileName = this->
getWorkingDir() +
"/DumpPrediction.txt";
5075 fopen_s(&fout, fileName.c_str(),
"w");
5077 fout = fopen(fileName.c_str(),
"w");
5082 for(
int i=0; i<prediction.rows; ++i)
5084 for(
int j=0; j<prediction.cols; ++j)
5086 fprintf(fout,
"%f ",((
float*)prediction.data)[j + i*prediction.cols]);
5088 fprintf(fout,
"\n");
5095 UWARN(
"Memory and/or the Bayes filter are not created");
5110 std::vector<float> velocity;
5113 _memory->
getNodeInfo(
id, odomPoseLocal, mapId, weight, label, stamp, groundTruth, velocity, gps, sensors,
true);
5116 if(images || scan || userData || occupancyGrid)
5120 if(!images && withWords)
5122 std::vector<CameraModel> models;
5123 std::vector<StereoCameraModel> stereoModels;
5139 for(std::multimap<int, Link>::iterator iter=links.begin(); iter!=links.end(); ++iter)
5151 if(withWords || withGlobalDescriptors)
5153 std::multimap<int, int> words;
5154 std::vector<cv::KeyPoint> wordsKpts;
5155 std::vector<cv::Point3f> words3;
5156 cv::Mat wordsDescriptors;
5157 std::vector<rtabmap::GlobalDescriptor> globalDescriptors;
5161 s.
setWords(words, wordsKpts, words3, wordsDescriptors);
5163 if(withGlobalDescriptors)
5168 if(velocity.size()==6)
5170 s.
setVelocity(velocity[0], velocity[1], velocity[2], velocity[3], velocity[4], velocity[5]);
5178 void Rtabmap::get3DMap(
5179 std::map<int, Signature> & signatures,
5180 std::map<int, Transform> & poses,
5181 std::multimap<int, Link> & constraints,
5186 return getGraph(poses, constraints, optimized, global, &signatures,
true,
true,
true,
true);
5190 std::map<int, Transform> & poses,
5191 std::multimap<int, Link> & constraints,
5194 std::map<int, Signature> * signatures,
5200 bool withGlobalDescriptors)
const 5245 for(std::set<int>::iterator iter = ids.begin(); iter!=ids.end(); ++iter)
5247 signatures->insert(std::make_pair(*iter,
getSignatureCopy(*iter, withImages, withScan, withUserData, withGrid, withWords, withGlobalDescriptors)));
5253 UERROR(
"Last working signature is null!?");
5257 UWARN(
"Memory not initialized...");
5263 std::map<int, float> nearestNodesTmp;
5264 std::map<int, float> * nearestNodesPtr = distsSqr == 0? &nearestNodesTmp : distsSqr;
5266 std::map<int, Transform> nearestPoses;
5267 for(std::map<int, float>::iterator iter=nearestNodesPtr->begin(); iter!=nearestNodesPtr->end(); ++iter)
5271 return nearestPoses;
5276 UDEBUG(
"nodeId=%d, radius=%f", nodeId, radius);
5277 std::map<int, float> nearestNodesTmp;
5278 std::map<int, float> * nearestNodesPtr = distsSqr == 0? &nearestNodesTmp : distsSqr;
5296 std::map<int, Transform> nearestPoses;
5297 for(std::map<int, float>::iterator iter=nearestNodesPtr->begin(); iter!=nearestNodesPtr->end(); ++iter)
5302 return nearestPoses;
5306 float clusterRadiusMax,
5312 float clusterRadiusMin)
5318 UERROR(
"Cannot detect more loop closures if graph optimization iterations = 0");
5323 UERROR(
"Detecting more loop closures can be done only in RGBD-SLAM mode.");
5326 if(!intraSession && !interSession)
5328 UERROR(
"Intra and/or inter session argument should be true.");
5332 std::list<Link> loopClosuresAdded;
5333 std::multimap<int, int> checkedLoopClosures;
5335 std::map<int, Transform> posesToCheckLoopClosures;
5336 std::map<int, Transform> poses;
5337 std::multimap<int, Link> links;
5338 std::map<int, Signature> signatures;
5339 this->
getGraph(poses, links,
true,
true, &signatures);
5341 std::map<int, int> mapIds;
5342 UDEBUG(
"remove all invalid or intermediate nodes, fill mapIds");
5343 for(std::map<int, Transform>::iterator iter=poses.upper_bound(0); iter!=poses.end();++iter)
5345 if(signatures.at(iter->first).getWeight() >= 0)
5347 posesToCheckLoopClosures.insert(*iter);
5348 mapIds.insert(std::make_pair(iter->first, signatures.at(iter->first).mapId()));
5352 for(
int n=0; n<iterations; ++n)
5354 UINFO(
"Looking for more loop closures, clustering poses... (iteration=%d/%d, radius=%f m angle=%f rad)",
5355 n+1, iterations, clusterRadiusMax, clusterAngle);
5358 posesToCheckLoopClosures,
5362 UINFO(
"Looking for more loop closures, clustering poses... found %d clusters.", (
int)clusters.size());
5365 std::set<int> addedLinks;
5366 for(std::multimap<int, int>::iterator iter=clusters.begin(); iter!= clusters.end(); ++iter, ++i)
5368 if(processState && processState->
isCanceled())
5374 int from = iter->first;
5375 int to = iter->second;
5378 from = iter->second;
5382 int mapIdFrom =
uValue(mapIds, from, 0);
5383 int mapIdTo =
uValue(mapIds, to, 0);
5385 if((interSession && mapIdFrom != mapIdTo) ||
5386 (intraSession && mapIdFrom == mapIdTo))
5389 bool alreadyChecked =
false;
5390 for(std::multimap<int, int>::iterator jter = checkedLoopClosures.lower_bound(from);
5391 !alreadyChecked && jter!=checkedLoopClosures.end() && jter->first == from;
5394 if(to == jter->second)
5396 alreadyChecked =
true;
5403 if(addedLinks.find(from) == addedLinks.end() &&
5404 addedLinks.find(to) == addedLinks.end() &&
5409 if(delta.
getNorm() < clusterRadiusMax &&
5410 delta.
getNorm() >= clusterRadiusMin)
5412 checkedLoopClosures.insert(std::make_pair(from, to));
5414 UASSERT(signatures.find(from) != signatures.end());
5415 UASSERT(signatures.find(to) != signatures.end());
5420 guess = poses.at(from).
inverse() * poses.at(to);
5429 bool updateConstraints =
true;
5435 int mapId = signatures.at(from).mapId();
5437 for(std::map<int, Signature>::iterator ster=signatures.begin(); ster!=signatures.end(); ++ster)
5439 if(ster->second.mapId() == mapId)
5441 fromId = ster->first;
5445 std::multimap<int, Link> linksIn = links;
5447 const Link * maxLinearLink = 0;
5448 const Link * maxAngularLink = 0;
5449 float maxLinearError = 0.0f;
5450 float maxAngularError = 0.0f;
5451 float maxLinearErrorRatio = 0.0f;
5452 float maxAngularErrorRatio = 0.0f;
5453 std::map<int, Transform> optimizedPoses;
5454 std::multimap<int, Link> links;
5455 UASSERT(poses.find(fromId) != poses.end());
5456 UASSERT_MSG(poses.find(from) != poses.end(),
uFormat(
"id=%d poses=%d links=%d", from, (
int)poses.size(), (int)links.size()).c_str());
5457 UASSERT_MSG(poses.find(to) != poses.end(),
uFormat(
"id=%d poses=%d links=%d", to, (
int)poses.size(), (int)links.size()).c_str());
5459 UASSERT(optimizedPoses.find(fromId) != optimizedPoses.end());
5460 UASSERT_MSG(optimizedPoses.find(from) != optimizedPoses.end(),
uFormat(
"id=%d poses=%d links=%d", from, (
int)optimizedPoses.size(), (int)links.size()).c_str());
5461 UASSERT_MSG(optimizedPoses.find(to) != optimizedPoses.end(),
uFormat(
"id=%d poses=%d links=%d", to, (
int)optimizedPoses.size(), (int)links.size()).c_str());
5465 if(optimizedPoses.size())
5470 maxLinearErrorRatio,
5471 maxAngularErrorRatio,
5478 UINFO(
"Max optimization linear error = %f m (link %d->%d)", maxLinearError, maxLinearLink->
from(), maxLinearLink->
to());
5481 msg =
uFormat(
"Rejecting edge %d->%d because " 5482 "graph error is too large after optimization (%f m for edge %d->%d with ratio %f > std=%f m). " 5487 maxLinearLink->
from(),
5488 maxLinearLink->
to(),
5489 maxLinearErrorRatio,
5491 Parameters::kRGBDOptimizeMaxError().c_str(),
5495 else if(maxAngularLink)
5497 UINFO(
"Max optimization angular error = %f deg (link %d->%d)", maxAngularError*180.0
f/
M_PI, maxAngularLink->
from(), maxAngularLink->
to());
5500 msg =
uFormat(
"Rejecting edge %d->%d because " 5501 "graph error is too large after optimization (%f deg for edge %d->%d with ratio %f > std=%f deg). " 5505 maxAngularError*180.0
f/
M_PI,
5506 maxAngularLink->
from(),
5507 maxAngularLink->
to(),
5508 maxAngularErrorRatio,
5510 Parameters::kRGBDOptimizeMaxError().c_str(),
5517 msg =
uFormat(
"Rejecting edge %d->%d because graph optimization has failed!",
5523 UWARN(
"%s", msg.c_str());
5524 updateConstraints =
false;
5528 poses = optimizedPoses;
5532 if(updateConstraints)
5534 addedLinks.insert(from);
5535 addedLinks.insert(to);
5539 std::string msg =
uFormat(
"Iteration %d/%d: Added loop closure %d->%d! (%d/%d)", n+1, iterations, from, to, i+1, (
int)clusters.size());
5560 std::string msg =
uFormat(
"Iteration %d/%d: Detected %d total loop closures!", n+1, iterations, (
int)addedLinks.size()/2);
5569 UINFO(
"Iteration %d/%d: Detected %d total loop closures!", n+1, iterations, (
int)addedLinks.size()/2);
5572 if(addedLinks.size() == 0)
5577 UINFO(
"Optimizing graph with new links (%d nodes, %d constraints)...",
5578 (
int)poses.size(), (int)links.size());
5581 if(poses.size() == 0)
5583 UERROR(
"Optimization failed! Rejecting all loop closures...");
5584 loopClosuresAdded.clear();
5587 UINFO(
"Optimizing graph with new links... done!");
5589 UINFO(
"Total added %d loop closures.", (
int)loopClosuresAdded.size());
5591 if(loopClosuresAdded.size())
5593 for(std::list<Link>::iterator iter=loopClosuresAdded.begin(); iter!=loopClosuresAdded.end(); ++iter)
5600 std::map<int, Transform>::iterator jter = poses.find(iter->first);
5601 if(jter != poses.end())
5603 iter->second = jter->second;
5606 std::map<int, Transform> tmp;
5612 return (
int)loopClosuresAdded.size();
5617 bool rematchFeatures,
5619 float pixelVariance)
5623 int iterations = Parameters::defaultOptimizerIterations();
5624 float pixelVariance = Parameters::defaultg2oPixelVariance();
5632 if(pixelVariance > 0.0
f)
5637 std::map<int, Signature> signatures;
5647 std::map<int, Transform> poses = optimizer->
optimizeBA(
5657 UERROR(
"Optimization failed!");
5675 const std::map<int, Transform> & poses,
5676 const cv::Mat & map,
5701 UERROR(
"Refining links can be done only in RGBD-SLAM mode.");
5705 std::list<Link> linksRefined;
5707 std::map<int, Transform> poses;
5708 std::multimap<int, Link> links;
5709 std::map<int, Signature> signatures;
5710 this->
getGraph(poses, links,
false,
true, &signatures);
5713 for(std::multimap<int, Link>::iterator iter=links.lower_bound(1); iter!= links.end(); ++iter)
5715 int from = iter->second.from();
5716 int to = iter->second.to();
5718 UASSERT(signatures.find(from) != signatures.end());
5719 UASSERT(signatures.find(to) != signatures.end());
5727 linksRefined.push_back(
Link(from, to, iter->second.type(), t, info.covariance.inv()));
5728 UINFO(
"Refined link %d->%d! (%d/%d)", from, to, ++i, (
int)links.size());
5731 UINFO(
"Total refined %d links.", (
int)linksRefined.size());
5733 if(linksRefined.size())
5735 for(std::list<Link>::iterator iter=linksRefined.begin(); iter!=linksRefined.end(); ++iter)
5740 return (
int)linksRefined.size();
5748 UERROR(
"Adding new link can be done only in RGBD-SLAM mode.");
5753 UERROR(
"Memory is not initialized.");
5758 UERROR(
"Link's transform is null! (%d->%d type=%s)", link.
from(), link.
to(), link.
typeName().c_str());
5765 UERROR(
"Link's \"from id\" %d is not in working memory", link.
from());
5770 UERROR(
"Link's \"to id\" %d is not in working memory", link.
to());
5777 UERROR(
"Neither nodes %d or %d are in the local graph (size=%d). One of the 2 nodes should be in the local graph.", (
int)
_optimizedPoses.size(), link.
from(), link.
to());
5784 UERROR(
"Cannot add new link %d->%d to memory", link.
from(), link.
to());
5790 std::multimap<int, Link> links;
5794 if(poses.find(link.
from()) == poses.end())
5796 UERROR(
"Link's \"from id\" %d is not in the graph (size=%d)", link.
from(), (int)poses.size());
5800 if(poses.find(link.
to()) == poses.end())
5802 UERROR(
"Link's \"to id\" %d is not in the graph (size=%d)", link.
to(), (int)poses.size());
5810 msg =
uFormat(
"Rejecting edge %d->%d because graph optimization has failed!", link.
from(), link.
to());
5814 float maxLinearError = 0.0f;
5815 float maxLinearErrorRatio = 0.0f;
5816 float maxAngularError = 0.0f;
5817 float maxAngularErrorRatio = 0.0f;
5818 const Link * maxLinearLink = 0;
5819 const Link * maxAngularLink = 0;
5824 maxLinearErrorRatio,
5825 maxAngularErrorRatio,
5832 UINFO(
"Max optimization linear error = %f m (link %d->%d)", maxLinearError, maxLinearLink->
from(), maxLinearLink->
to());
5835 msg =
uFormat(
"Rejecting edge %d->%d because " 5836 "graph error is too large after optimization (%f m for edge %d->%d with ratio %f > std=%f m). " 5841 maxLinearLink->
from(),
5842 maxLinearLink->
to(),
5843 maxLinearErrorRatio,
5845 Parameters::kRGBDOptimizeMaxError().c_str(),
5849 else if(maxAngularLink)
5851 UINFO(
"Max optimization angular error = %f deg (link %d->%d)", maxAngularError*180.0
f/
M_PI, maxAngularLink->
from(), maxAngularLink->
to());
5854 msg =
uFormat(
"Rejecting edge %d->%d because " 5855 "graph error is too large after optimization (%f deg for edge %d->%d with ratio %f > std=%f deg). " 5859 maxAngularError*180.0f/
M_PI,
5860 maxAngularLink->
from(),
5861 maxAngularLink->
to(),
5862 maxAngularErrorRatio,
5864 Parameters::kRGBDOptimizeMaxError().c_str(),
5871 UERROR(
"%s", msg.c_str());
5879 std::map<int, Transform>::iterator jter = poses.find(iter->first);
5880 if(jter != poses.end())
5882 iter->second = jter->second;
5890 std::map<int, Transform> tmp;
5900 int oldestId = link.
from()>link.
to()?link.
to():link.
from();
5901 int newestId = link.
from()<link.
to()?link.
to():link.
from();
5905 UERROR(
"Link's id %d is not in working memory", oldestId);
5910 UERROR(
"Link's id %d is not in the optimized graph (_optimizedPoses=%d)", oldestId, (
int)
_optimizedPoses.size());
5915 UERROR(
"Adding link with %s=true in localization mode is not supported.", Parameters::kRGBDOptimizeFromGraphEnd().c_str());
5922 UERROR(
"Link's id %d is not in the odometry cache (oldest=%d, newest=%d, %s=%d)",
5926 Parameters::kRGBDMaxOdomCacheSize().c_str(),
5931 UERROR(
"Link's id %d is not in the odometry cache (%s=%d).",
5933 Parameters::kRGBDMaxOdomCacheSize().c_str(),
5945 constraints.insert(std::make_pair(link.
from(), link));
5946 for(std::multimap<int, Link>::iterator iter=constraints.begin(); iter!=constraints.end(); ++iter)
5948 std::map<int, Transform>::iterator iterPose =
_optimizedPoses.find(iter->second.to());
5949 if(iterPose !=
_optimizedPoses.end() && poses.find(iterPose->first) == poses.end())
5951 poses.insert(*iterPose);
5953 constraints.insert(std::make_pair(iterPose->first,
Link(iterPose->first, iterPose->first,
Link::kPosePrior, iterPose->second, cv::Mat::eye(6,6, CV_64FC1)*999999)));
5957 std::map<int, Transform> posesOut;
5958 std::multimap<int, Link> edgeConstraintsOut;
5962 std::map<int, Transform> optPoses =
_graphOptimizer->
optimize(poses.begin()->first, posesOut, edgeConstraintsOut);
5965 bool rejectLocalization =
false;
5966 if(optPoses.empty())
5968 UWARN(
"Optimization failed, rejecting localization!");
5969 rejectLocalization =
true;
5973 UINFO(
"Compute max graph errors...");
5974 float maxLinearError = 0.0f;
5975 float maxLinearErrorRatio = 0.0f;
5976 float maxAngularError = 0.0f;
5977 float maxAngularErrorRatio = 0.0f;
5978 const Link * maxLinearLink = 0;
5979 const Link * maxAngularLink = 0;
5983 maxLinearErrorRatio,
5984 maxAngularErrorRatio,
5990 if(maxLinearLink == 0 && maxAngularLink==0)
5992 UWARN(
"Could not compute graph errors! Wrong loop closures could be accepted!");
5997 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()));
6000 UWARN(
"Rejecting localization (%d <-> %d) in this " 6001 "iteration because a wrong loop closure has been " 6002 "detected after graph optimization, resulting in " 6003 "a maximum graph error ratio of %f (edge %d->%d, type=%d, abs error=%f m, stddev=%f). The " 6004 "maximum error ratio parameter \"%s\" is %f of std deviation.",
6007 maxLinearErrorRatio,
6008 maxLinearLink->
from(),
6009 maxLinearLink->
to(),
6010 maxLinearLink->
type(),
6013 Parameters::kRGBDOptimizeMaxError().c_str(),
6015 rejectLocalization =
true;
6020 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()));
6023 UWARN(
"Rejecting localization (%d <-> %d) in this " 6024 "iteration because a wrong loop closure has been " 6025 "detected after graph optimization, resulting in " 6026 "a maximum graph error ratio of %f (edge %d->%d, type=%d, abs error=%f deg, stddev=%f). The " 6027 "maximum error ratio parameter \"%s\" is %f of std deviation.",
6030 maxAngularErrorRatio,
6031 maxAngularLink->
from(),
6032 maxAngularLink->
to(),
6033 maxAngularLink->
type(),
6034 maxAngularError*180.0f/CV_PI,
6036 Parameters::kRGBDOptimizeMaxError().c_str(),
6038 rejectLocalization =
true;
6043 if(!rejectLocalization)
6046 Transform newT = newOptPoseInv * optPoses.at(link.
to());
6047 Link linkTmp = link;
6049 if(oldestId == link.
from())
6076 cv::Mat information = covariance.inv();
6080 if(odomMaxInf.size() == 6)
6082 for(
int i=0; i<6; ++i)
6084 if(information.at<
double>(i,i) > odomMaxInf[i])
6086 information.at<
double>(i,i) = odomMaxInf[i];
6106 UWARN(
"%s=0, so cannot republish the %d requested nodes.", Parameters::kRtabmapMaxRepublished().c_str(), (
int)ids.size());
6110 UWARN(
"%s=false, so cannot republish the %d requested nodes.", Parameters::kRtabmapPublishLastSignature().c_str(), (
int)ids.size());
6116 UINFO(
"status=%d", status);
6138 UINFO(
"Planning a path to node %d (global=%d)", targetNode, global?1:0);
6142 UINFO(
"Planning a path to landmark %d (global=%d)", -targetNode, global?1:0);
6147 UWARN(
"A path can only be computed in RGBD-SLAM mode");
6158 int currentNode = 0;
6163 UWARN(
"Working memory is empty... cannot compute a path");
6172 UWARN(
"Last localization pose is null or optimized graph is empty... cannot compute a path");
6185 if(currentNode && targetNode)
6198 _path.resize(path.size());
6200 for(std::list<std::pair<int, Transform> >::iterator iter=path.begin(); iter!=path.end();++iter)
6205 _path[oi].first = iter->first;
6206 _path[oi++].second = t * iter->second;
6210 if(!
_path.empty() && !path.empty() && path.rbegin()->first < 0)
6212 transformToLandmark =
_path.back().second.inverse() * t * path.rbegin()->second;
6215 else if(currentNode == 0)
6217 UWARN(
"We should be localized before planning.");
6222 if(
_path.size() == 0)
6225 UWARN(
"Cannot compute a path!");
6230 UINFO(
"Path generated! Size=%d", (
int)
_path.size());
6233 std::stringstream stream;
6234 for(
unsigned int i=0; i<
_path.size(); ++i)
6236 stream <<
_path[i].first;
6237 if(i+1 <
_path.size())
6242 UINFO(
"Path = [%s]", stream.str().c_str());
6247 std::string goalStr =
uFormat(
"GOAL:%d", targetNode);
6260 std::map<int, std::string>::iterator iter = labels.find(targetNode);
6261 if(iter != labels.end() && !iter->second.empty())
6263 goalStr = std::string(
"GOAL:")+labels.at(targetNode);
6266 setUserData(0, cv::Mat(1,
int(goalStr.size()+1), CV_8SC1, (
void *)goalStr.c_str()).clone());
6282 if(tolerance < 0.0
f)
6287 std::list<std::pair<int, Transform> > pathPoses;
6291 UWARN(
"This method can only be used in RGBD-SLAM mode");
6298 std::multimap<int, int> links;
6299 for(std::map<int, Transform>::iterator iter=nodes.upper_bound(0); iter!=nodes.end(); ++iter)
6303 for(std::map<int, Link>::const_iterator jter=s->
getLinks().begin(); jter!=s->
getLinks().end(); ++jter)
6306 if(jter->second.from() != jter->second.to() &&
uContains(nodes, jter->second.to()))
6308 links.insert(std::make_pair(jter->second.from(), jter->second.to()));
6313 UINFO(
"Time getting links = %fs", timer.
ticks());
6315 int currentNode = 0;
6320 UWARN(
"Working memory is empty... cannot compute a path");
6329 UWARN(
"Last localization pose is null... cannot compute a path");
6347 nearestId = currentNode;
6353 UINFO(
"Nearest node found=%d ,%fs", nearestId, timer.
ticks());
6356 if(tolerance != 0.0
f && targetPose.
getDistance(nodes.at(nearestId)) > tolerance)
6358 UWARN(
"Cannot plan farther than %f m from the graph! (distance=%f m from node %d)",
6359 tolerance, targetPose.
getDistance(nodes.at(nearestId)), nearestId);
6363 UINFO(
"Computing path from location %d to %d", currentNode, nearestId);
6368 if(
_path.size() == 0)
6370 UWARN(
"Cannot compute a path!");
6374 UINFO(
"Path generated! Size=%d", (
int)
_path.size());
6377 std::stringstream stream;
6378 for(
unsigned int i=0; i<
_path.size(); ++i)
6380 stream <<
_path[i].first;
6381 if(i+1 <
_path.size())
6386 UINFO(
"Path = [%s]", stream.str().c_str());
6400 UWARN(
"Nearest node not found in graph (size=%d) for pose %s", (
int)nodes.size(), targetPose.
prettyPrint().c_str());
6408 std::vector<std::pair<int, Transform> > poses;
6419 poses[oi++] = *iter;
6433 std::vector<int> ids;
6444 ids[oi++] = iter->first;
6470 UWARN(
"This method can on be used in RGBD-SLAM mode!");
6492 std::multimap<int, Link> links = currentIndexS->getLinks();
6493 bool latestVirtualLinkFound =
false;
6494 for(std::multimap<int, Link>::reverse_iterator iter=links.rbegin(); iter!=links.rend(); ++iter)
6498 if(latestVirtualLinkFound)
6504 latestVirtualLinkFound =
true;
6510 float distanceSoFar = 0.0f;
6519 distanceSoFar +=
_path[i-1].second.getDistance(
_path[i].second);
6532 UINFO(
"Added Virtual link between %d and %d",
_path[i-1].first,
_path[i].first);
6551 UERROR(
"Last node is null in memory or not in optimized poses. Aborting the plan...");
6561 UERROR(
"Last localization pose is null. Aborting the plan...");
6568 int goalId =
_path.back().first;
6575 UINFO(
"Goal %d reached!", goalId);
6584 float distanceFromCurrentNode = 0.0f;
6585 bool sameGoalIndex =
false;
6616 UINFO(
"Updated current goal from %d to %d (%d/%d)",
6622 sameGoalIndex =
true;
6626 unsigned int nearestNodeIndex = 0;
6628 bool sameCurrentIndex =
false;
6636 if(distance == -1.0
f || distance > d)
6639 nearestNodeIndex = i;
6645 UERROR(
"The nearest pose on the path not found! Aborting the plan...");
6650 UDEBUG(
"Nearest node = %d",
_path[nearestNodeIndex].first);
6659 sameCurrentIndex =
true;
6662 bool isStuck =
false;
6665 float distanceToCurrentGoal = 0.0f;
6680 if(distanceToCurrentGoal > 0.0
f)
6701 UWARN(
"Current goal %d not reached since %d iterations (\"RGBD/PlanStuckIterations\"=%d), mark that node as unreachable.",
6714 UERROR(
"No upcoming nodes on the path are reachable! Aborting the plan...");
6731 UDEBUG(
"Creating global scan map (if scans are available)");
6734 std::vector<int> scanIndices;
6735 std::map<int, Transform> scanViewpoints;
6745 UDEBUG(
"Adding scan %d (format=%s, points=%d)", iter->first, scan.
formatName().c_str(), scan.
size());
6751 scanViewpoints.insert(std::make_pair(iter->first, iter->second * scan.localTransform()));
6756 UWARN(
"Incompatible scan formats (%s vs %s), cannot create global scan map.",
6758 scan.formatName().c_str());
6766 UDEBUG(
"Ignored %d (scan is empty), pose still added.", iter->first);
6772 UDEBUG(
"Ignored %d (no scan), pose still added.", iter->first);
6778 float voxelSize = 0.0f;
6780 float normalRadius = 0.0f;
6785 if(voxelSize > 0.0
f)
6800 UINFO(
"Global scan map has been assembled (size=%d points, %d poses) " 6801 "for proximity detection (only in localization mode %s=false and with %s=true)",
6804 Parameters::kMemIncrementalMemory().c_str(),
6805 Parameters::kRGBDProximityGlobalScanMap().c_str());
6812 UWARN(
"Saving %s/rtabmap_global_scan_map.pcd (only saved when logger level is debug)",
_wDir.c_str());
6814 pcl::io::savePCDFile(
_wDir+
"/rtabmap_global_scan_map.pcd", *cloud2);
6818 UWARN(
"%s is enabled and logger is debug, but %s is not set, cannot save global scan map for debugging.",
6819 Parameters::kRGBDProximityGlobalScanMap().c_str(), Parameters::kRtabmapWorkingDirectory().c_str());
bool getNodeInfo(int signatureId, Transform &odomPose, int &mapId, int &weight, std::string &label, double &stamp, Transform &groundTruth, std::vector< float > &velocity, GPS &gps, EnvSensors &sensors, bool lookInDatabase=false) const
int UTILITE_EXP uStr2Int(const std::string &str)
Transform _mapCorrectionBackup
static std::string homeDir()
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)
std::map< int, Transform > _markerPriors
bool _currentSessionHasGPS
void flushStatisticLogs()
bool labelSignature(int id, const std::string &label)
int cleanupLocalGrids(const std::map< int, Transform > &poses, const cv::Mat &map, float xMin, float yMin, float cellSize, int cropRadius=1, bool filterScans=false)
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
unsigned int _maxLocalRetrieved
const double & error() const
const std::map< int, int > & reducedIds() const
std::vector< std::pair< int, Transform > > _path
void setupLogFiles(bool overwrite=false)
bool isIDsGenerated() const
bool operator<(const NearestPathKey &k) const
bool isInSTM(int locationId) const
T uMean(const T *v, unsigned int size)
double rotVariance(bool minimum=true) const
int getLastSignatureId() const
bool _optimizeFromGraphEndChanged
const double & stamp() const
std::map< int, Transform > RTABMAP_EXP radiusPosesFiltering(const std::map< int, Transform > &poses, float radius, float angle, bool keepLatest=true)
std::multimap< int, Link >::iterator RTABMAP_EXP findLink(std::multimap< int, Link > &links, int from, int to, bool checkBothWays=true, Link::Type type=Link::kUndef)
void RTABMAP_EXP computeMaxGraphErrors(const std::map< int, Transform > &poses, const std::multimap< int, Link > &links, float &maxLinearErrorRatio, float &maxAngularErrorRatio, float &maxLinearError, float &maxAngularError, const Link **maxLinearErrorLink=0, const Link **maxAngularErrorLink=0, bool for3DoF=false)
const Transform & getGroundTruthPose() const
void clearPath(int status)
bool allNodesInWM() const
bool uIsDigit(const char c)
std::map< int, int > getWeights() const
const std::vector< float > & getVelocity() const
void exportPoses(const std::string &path, bool optimized, bool global, int format)
void setLaserScan(const LaserScan &laserScan, bool clearPreviousData=true)
std::vector< std::pair< int, Transform > > getPathNextPoses() const
const LaserScan & laserScanCompressed() const
float _distanceTravelledSinceLastLocalization
const std::set< int > & getStMem() const
void removeVirtualLinks(int signatureId)
#define ULOGGER_INFO(...)
void removeRawData(int id, bool image=true, bool scan=true, bool userData=true)
bool computePath(int targetNode, bool global)
void createGlobalScanMap()
GLM_FUNC_DECL vecType< T, P > sqrt(vecType< T, P > const &x)
Signature getSignatureCopy(int id, bool images, bool scan, bool userData, bool occupancyGrid, bool withWords, bool withGlobalDescriptors) const
virtual void parseParameters(const ParametersMap ¶meters)
const Signature * getLastWorkingSignature() const
const Statistics & getStatistics() const
std::map< int, Transform > loadOptimizedPoses(Transform *lastlocalizationPose) const
void setLoopClosureId(int id)
void setStereoCameraModels(const std::vector< StereoCameraModel > &stereoCameraModels)
void setLabels(const std::map< int, std::string > &labels)
void setPosterior(const std::map< int, float > &posterior)
void dumpPrediction() const
std::pair< std::string, std::string > ParametersPair
void saveOptimizedPoses(const std::map< int, Transform > &optimizedPoses, const Transform &lastlocalizationPose) const
void setRawLikelihood(const std::map< int, float > &rawLikelihood)
bool _scanMatchingIdsSavedInLinks
void setLoopClosureMapId(int id)
bool isIncremental() const
void generateDOTGraph(const std::string &path, int id=0, int margin=5)
void setTransform(const Transform &transform)
int getPathCurrentGoalId() const
void generateGraph(const std::string &fileName, const std::set< int > &ids=std::set< int >())
void setInitialPose(const Transform &initialPose)
void setRefImageId(int id)
float inliersMeanDistance
int RTABMAP_EXP findNearestNode(const std::map< int, rtabmap::Transform > &poses, const rtabmap::Transform &targetPose, float *distance=0)
bool labelLocation(int id, const std::string &label)
void setProximityDetectionId(int id)
std::set< K > uKeysSet(const std::map< K, V > &m)
void getNodeCalibration(int nodeId, std::vector< CameraModel > &models, std::vector< StereoCameraModel > &stereoModels) const
pcl::PCLPointCloud2::Ptr RTABMAP_EXP laserScanToPointCloud2(const LaserScan &laserScan, const Transform &transform=Transform())
void getMetricConstraints(const std::set< int > &ids, std::map< int, Transform > &poses, std::multimap< int, Link > &links, bool lookInDatabase=false, bool landmarksAdded=false)
void parseParameters(const ParametersMap ¶meters)
float _rgbdAngularSpeedUpdate
std::map< std::string, std::string > ParametersMap
GLM_FUNC_DECL genType::value_type distance(genType const &p0, genType const &p1)
float _rgbdLinearSpeedUpdate
std::multimap< int, Link > RTABMAP_EXP filterLinks(const std::multimap< int, Link > &links, Link::Type filteredType, bool inverted=false)
void init(const ParametersMap ¶meters, const std::string &databasePath="", bool loadDatabaseParameters=false)
void close(bool databaseSaved=true, bool postInitClosingEvents=false, const std::string &ouputDatabasePath="")
void setCameraModels(const std::vector< CameraModel > &models)
Transform computeIcpTransform(const Signature &fromS, const Signature &toS, Transform guess, RegistrationInfo *info=0) const
int getLastLocationId() const
Basic mathematics functions.
float _markerPriorsAngularVariance
unsigned int _maxMemoryAllowed
void setCurrentGoalId(int goal)
void setGPS(const GPS &gps)
const std::map< int, VisualWord * > & getVisualWords() const
int _proximityMaxGraphDepth
void setConstraints(const std::multimap< int, Link > &constraints)
Some conversion functions.
double _proximityMergedScanCovFactor
bool globalBundleAdjustment(int optimizerType=1, bool rematchFeatures=true, int iterations=0, float pixelVariance=0.0f)
void setOdomCacheConstraints(const std::multimap< int, Link > &constraints)
void addSignatureData(const Signature &data)
std::list< std::string > _bufferedLogsF
void addNodesToRepublish(const std::vector< int > &ids)
const std::string & getLabel() const
std::string getExtension()
GLM_FUNC_DECL T pitch(detail::tquat< T, P > const &x)
void deleteLocation(int locationId, std::list< int > *deletedWords=0)
float _maxLoopClosureDistance
virtual std::map< int, Transform > optimizeBA(int rootId, const std::map< int, Transform > &poses, const std::multimap< int, Link > &links, const std::map< int, std::vector< CameraModel > > &models, std::map< int, cv::Point3f > &points3DMap, const std::map< int, std::map< int, FeatureBA > > &wordReferences, std::set< int > *outliers=0)
NearestPathKey(float l, int i, float d)
std::map< int, std::map< int, Transform > > getPaths(const std::map< int, Transform > &poses, const Transform &target, int maxGraphDepth=0) const
const std::vector< double > & getPredictionLC() const
std::map< int, Transform > _odomCachePoses
std::multimap< int, Link > getNeighborLinks(int signatureId, bool lookInDatabase=false) const
float _newMapOdomChangeDistance
float gravitySigma() const
double getDbSavingTime() const
void saveLocationData(int locationId)
const std::map< int, std::string > & getAllLabels() const
float _pathLinearVelocity
std::set< int > getSTM() const
bool isBadSignature() const
Optimizer * _graphOptimizer
const Signature * getSignature(int id) const
std::string typeName() const
std::set< int > _nodesToRepublish
const std::map< std::string, float > & data() const
bool init(const std::string &dbUrl, bool dbOverwritten=false, const ParametersMap ¶meters=ParametersMap(), bool postInitClosingEvents=false)
void getGPS(int id, GPS &gps, Transform &offsetENU, bool lookInDatabase, int maxGraphDepth=0) const
const std::map< int, Link > & getLandmarks() const
cv::Mat generatePrediction(const Memory *memory, const std::vector< int > &ids)
void adjustLikelihood(std::map< int, float > &likelihood) const
bool _proximityRawPosesUsed
bool openConnection(const std::string &url, bool overwritten=false)
float _optimizationMaxError
#define UASSERT(condition)
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
float _markerPriorsLinearVariance
BayesFilter * _bayesFilter
void setLocalPath(const std::vector< int > &localPath)
void saveStatistics(const Statistics &statistics, bool saveWMState)
std::list< std::string > uSplit(const std::string &str, char separator=' ')
const double & bearing() const
std::set< int > reactivateSignatures(const std::list< int > &ids, unsigned int maxLoaded, double &timeDbAccess)
std::map< int, Transform > getNodesInRadius(const Transform &pose, float radius, int k=0, std::map< int, float > *distsSqr=0)
void setLocalizationCovariance(const cv::Mat &covariance)
bool _statisticLoggedHeaders
LaserScan RTABMAP_EXP commonFiltering(const LaserScan &scan, int downsamplingStep, float rangeMin=0.0f, float rangeMax=0.0f, float voxelSize=0.0f, int normalK=0, float normalRadius=0.0f, float groundNormalsUp=0.0f)
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="")
Transform computeTransform(Signature &fromS, Signature &toS, Transform guess, RegistrationInfo *info=0, bool useKnownCorrespondencesIfPossible=false) const
void setPriorsIgnored(bool enabled)
const std::multimap< int, Link > & getLinks() const
bool landmarksIgnored() const
bool isOdomGravityUsed() const
virtual bool callback(const std::string &msg) const
#define ULOGGER_DEBUG(...)
void setPoses(const std::map< int, Transform > &poses)
void setWorkingDirectory(std::string path)
void addLandmark(const Link &landmark)
unsigned int _maxRepublished
void setExtended(bool extended)
void save2DMap(const cv::Mat &map, float xMin, float yMin, float cellSize) const
int detectMoreLoopClosures(float clusterRadiusMax=0.5f, float clusterAngle=M_PI/6.0f, int iterations=1, bool intraSession=true, bool interSession=true, const ProgressState *state=0, float clusterRadiusMin=0.0f)
std::vector< int > getPathNextNodes() const
#define UASSERT_MSG(condition, msg_str)
LaserScan RTABMAP_EXP transformLaserScan(const LaserScan &laserScan, const Transform &transform)
std::list< int > getWM() const
bool update(const SensorData &data, Statistics *stats=0)
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)
const std::string & getWorkingDir() const
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)
void setRefImageMapId(int id)
bool _statisticLogsBufferedInRAM
bool hasLink(int idTo, Link::Type type=Link::kUndef) const
void deleteLastLocation()
bool addLink(const Link &link)
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.
static cv::Point3d Geocentric_WGS84ToENU_WGS84(const cv::Point3d &geocentric_WGS84, const cv::Point3d &origin_geocentric_WGS84, const GeodeticCoords &origin)
void setVelocity(float vx, float vy, float vz, float vroll, float vpitch, float vyaw)
std::string UTILITE_EXP uReplaceChar(const std::string &str, char before, char after)
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)
bool isIDsGenerated() const
std::map< int, float > getNeighborsIdRadius(int signatureId, float radius, const std::map< int, Transform > &optimizedPoses, int maxGraphDepth) const
Transform _lastLocalizationPose
std::multimap< int, Link > _odomCacheConstraints
std::list< int > forget(const std::set< int > &ignoredIds=std::set< int >())
int getLastGlobalLoopClosureId() const
std::list< std::string > uSplitNumChar(const std::string &str)
cv::Mat RTABMAP_EXP compressData2(const cv::Mat &data)
const std::vector< double > & getOdomMaxInf() const
unsigned int _pathCurrentIndex
static const int kIdInvalid
static ULogger::Level level()
float _pathAngularVelocity
bool _loopClosureIdentityGuess
std::multimap< int, Link > getLoopClosureLinks(int signatureId, bool lookInDatabase=false) const
float inliersDistribution
std::map< int, int > getWeights() const
void setEnvSensors(const EnvSensors &sensors)
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, bool adjustPosesWithConstraints=true) const
GeodeticCoords toGeodeticCoords() const
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)
SensorData getNodeData(int locationId, bool images, bool scan, bool userData, bool occupancyGrid) const
int getDatabaseMemoryUsed() const
std::pair< int, float > _highestHypothesis
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 >(), const ParametersMap ¶meters=ParametersMap())
static DBDriver * create(const ParametersMap ¶meters=ParametersMap())
void parseParameters(const ParametersMap ¶meters)
const std::map< int, Transform > & getGroundTruths() const
void setMapCorrection(const Transform &mapCorrection)
void setLikelihood(const std::map< int, float > &likelihood)
cv::Mat getInformation(const cv::Mat &covariance) const
int incrementMapId(std::map< int, int > *reducedIds=0)
bool _startNewMapOnLoopClosure
virtual void dumpMemory(std::string directory) const
void removeAllVirtualLinks()
std::vector< V > uListToVector(const std::list< V > &list)
bool _someNodesHaveBeenTransferred
static const ParametersMap & getDefaultParameters()
void setWmState(const std::vector< int > &state)
virtual void parseParameters(const ParametersMap ¶meters)
const std::map< int, double > & getWorkingMem() const
std::map< int, Transform > getForwardWMPoses(int fromId, int maxNearestNeighbors, float radius, int maxDiffID) const
std::map< int, std::pair< cv::Point3d, Transform > > _gpsGeocentricCache
const LaserScan & laserScanRaw() const
void setStamp(double stamp)
void setGlobalDescriptors(const std::vector< GlobalDescriptor > &descriptors)
int cleanupLocalGrids(const std::map< int, Transform > &mapPoses, const cv::Mat &map, float xMin, float yMin, float cellSize, int cropRadius=1, bool filterScans=false)
GLM_FUNC_DECL genType max(genType const &x, genType const &y)
static const int kIdVirtual
SensorData & sensorData()
T uNormSquared(const std::vector< T > &v)
void updateLink(const Link &link, bool updateInDatabase=false)
std::list< K > uKeysList(const std::multimap< K, V > &mm)
float _proximityFilteringRadius
std::map< int, Transform > RTABMAP_EXP findNearestPoses(int nodeId, const std::map< int, Transform > &poses, float radius, float angle=0.0f, int k=0)
int getMapId(int id, bool lookInDatabase=false) const
void setWords(const std::multimap< int, int > &words, const std::vector< cv::KeyPoint > &keypoints, const std::vector< cv::Point3f > &words3, const cv::Mat &descriptors)
void setWeights(const std::map< int, int > &weights)
static long int getMemoryUsage()
unsigned int _pathGoalIndex
bool isGraphReduced() const
std::map< int, Transform > _globalScanMapPoses
unsigned int getIndexMemoryUsed() const
bool setUserData(int id, const cv::Mat &data)
#define ULOGGER_WARN(...)
const Transform & getPose() const
ULogger class and convenient macros.
std::vector< float > _odomCorrectionAcc
std::multimap< int, Link > _constraints
bool _optimizeFromGraphEnd
static std::string typeName(Type type)
void getGraph(std::map< int, Transform > &poses, std::multimap< int, Link > &constraints, bool optimized, bool global, std::map< int, Signature > *signatures=0, bool withImages=false, bool withScan=false, bool withUserData=false, bool withGrid=false, bool withWords=true, bool withGlobalDescriptors=true) const
ParametersMap getLastParameters() const
unsigned long getMemoryUsed() const
GLM_FUNC_DECL T yaw(detail::tquat< T, P > const &x)
bool isLocalizationDataSaved() const
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)
static void readINI(const std::string &configFile, ParametersMap ¶meters, bool modifiedOnly=false)
double transVariance(bool minimum=true) const
void setLoopClosureTransform(const Transform &loopClosureTransform)
void addLink(const Link &link)
bool _startNewMapOnGoodSignature
std::multimap< int, Link > getLinks(int signatureId, bool lookInDatabase=false, bool withLandmarks=false) const
void setTimeThreshold(float maxTimeAllowed)
Transform getPose(int locationId) const
ParametersMap _parameters
int getTotalMemSize() const
int _lastLocalizationNodeId
void setProximityDetectionMapId(int id)
void RTABMAP_EXP adjustNormalsToViewPoints(const std::map< int, Transform > &poses, const pcl::PointCloud< pcl::PointXYZ >::Ptr &rawCloud, const std::vector< int > &rawCameraIndices, pcl::PointCloud< pcl::PointNormal >::Ptr &cloud, float groundNormalsUp=0.0f)
std::map< EnvSensor::Type, EnvSensor > EnvSensors
static std::string formatName(const Format &format)
void updateAge(int signatureId)
bool _goalsSavedInUserData
const Transform & transform() const
std::pair< int, float > _loopClosureHypothesis
cv::Point3d toGeocentric_WGS84() const
float _localImmunizationRatio
std::set< unsigned int > _pathUnreachableNodes
unsigned long getMemoryUsed() const
bool _neighborLinkRefining
#define ULOGGER_ERROR(...)
const VWDictionary * getVWDictionary() const
bool _verifyLoopClosureHypothesis
static int newDatabase(BtShared *pBt)
std::set< int > getAllSignatureIds(bool ignoreChildren=true) const
Transform computeIcpTransformMulti(int newId, int oldId, const std::map< int, Transform > &poses, RegistrationInfo *info=0)
bool priorsIgnored() 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)
int getMaxStMemSize() const
void uncompressDataConst(cv::Mat *imageRaw, cv::Mat *depthOrRightRaw, LaserScan *laserScanRaw=0, cv::Mat *userDataRaw=0, cv::Mat *groundCellsRaw=0, cv::Mat *obstacleCellsRaw=0, cv::Mat *emptyCellsRaw=0) const
bool isInSTM(int signatureId) const
std::map< int, float > RTABMAP_EXP findNearestNodes(int nodeId, const std::map< int, Transform > &poses, float radius, float angle=0.0f, int k=0)
Transform localTransform() const
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
static Optimizer * create(const ParametersMap ¶meters)
V uValue(const std::map< K, V > &m, const K &key, const V &defaultValue=V())
void setOptimizedPoses(const std::map< int, Transform > &poses, const std::multimap< int, Link > &constraints)
int _proximityMaxNeighbors
const std::map< int, std::set< int > > & getLandmarksIndex() const
const std::map< int, float > & computePosterior(const Memory *memory, const std::map< int, float > &likelihood)
std::string _databasePath
void getNodeWordsAndGlobalDescriptors(int nodeId, std::multimap< int, int > &words, std::vector< cv::KeyPoint > &wordsKpts, std::vector< cv::Point3f > &words3, cv::Mat &wordsDescriptors, std::vector< GlobalDescriptor > &globalDescriptors) const
bool _createGlobalScanMap
bool addLink(const Link &link, bool addInDatabase=false)
Transform _pathTransformToGoal
unsigned int getIndexedWordsCount() const
void setOdomCachePoses(const std::map< int, Transform > &poses)
void addStatistic(const std::string &name, float value)
void uInsert(std::map< K, V > &map, const std::pair< K, V > &pair)
unsigned int _maxRetrieved
const std::multimap< int, int > & getWords() const
GLM_FUNC_DECL matType< T, P > inverse(matType< T, P > const &m)