69 int optimizerTypeInt = Parameters::defaultOptimizerStrategy();
70 Parameters::parse(parameters, Parameters::kOptimizerStrategy(), optimizerTypeInt);
77 "RTAB-Map is not built with any graph optimization approach!");
83 UWARN(
"TORO optimizer not available. GTSAM will be used instead.");
88 UWARN(
"TORO optimizer not available. g2o will be used instead.");
96 UWARN(
"g2o optimizer not available. TORO will be used instead.");
101 UWARN(
"g2o optimizer not available. GTSAM will be used instead.");
109 UWARN(
"GTSAM optimizer not available. TORO will be used instead.");
114 UWARN(
"GTSAM optimizer not available. g2o will be used instead.");
122 UWARN(
"CVSBA optimizer not available. TORO will be used instead.");
127 UWARN(
"CVSBA optimizer not available. GTSAM will be used instead.");
132 UWARN(
"CVSBA optimizer not available. g2o will be used instead.");
159 const std::map<int, Transform> & posesIn,
160 const std::multimap<int, Link> & linksIn,
161 std::map<int, Transform> & posesOut,
162 std::multimap<int, Link> & linksOut,
173 std::set<int> curentDepth;
174 std::set<int> nextDepth;
175 nextDepth.insert(fromId);
177 std::multimap<int, int> biLinks;
178 for(std::multimap<int, Link>::const_iterator iter=linksIn.begin(); iter!=linksIn.end(); ++iter)
181 uFormat(
"Input links should be unique between two poses (%d->%d).",
182 iter->second.from(), iter->second.to()).c_str());
183 biLinks.insert(std::make_pair(iter->second.from(), iter->second.to()));
184 if(iter->second.from() != iter->second.to())
186 biLinks.insert(std::make_pair(iter->second.to(), iter->second.from()));
190 while((depth == 0 || d < depth) && nextDepth.size())
192 curentDepth = nextDepth;
195 for(std::set<int>::iterator jter = curentDepth.begin(); jter!=curentDepth.end(); ++jter)
197 if(ids.find(*jter) == ids.end())
200 posesOut.insert(*posesIn.find(*jter));
202 for(std::multimap<int, int>::const_iterator iter=biLinks.find(*jter); iter!=biLinks.end() && iter->first==*jter; ++iter)
204 int nextId = iter->second;
207 if(ids.find(nextId) == ids.end())
209 nextDepth.insert(nextId);
211 std::multimap<int, Link>::const_iterator kter =
graph::findLink(linksIn, *jter, nextId);
212 if(depth == 0 || d < depth-1)
214 linksOut.insert(*kter);
216 else if(curentDepth.find(nextId) != curentDepth.end() ||
217 ids.find(nextId) != ids.end())
219 linksOut.insert(*kter);
222 else if(*jter == nextId)
224 std::multimap<int, Link>::const_iterator kter =
graph::findLink(linksIn, *jter, nextId);
225 linksOut.insert(*kter);
268 const std::map<int, Transform> & poses,
269 const std::multimap<int, Link> & constraints,
270 std::list<std::map<int, Transform> > * intermediateGraphes,
272 int * iterationsDone)
274 std::map<int, Transform> incGraph;
275 std::multimap<int, Link> incGraphLinks;
276 incGraph.insert(*poses.begin());
278 std::multimap<int, Link> constraintsCpy = constraints;
279 UDEBUG(
"Incremental optimization... poses=%d comstraints=%d", (
int)poses.size(), (int)constraints.size());
280 for(std::map<int, Transform>::const_iterator iter=poses.begin(); iter!=poses.end(); ++iter)
282 incGraph.insert(*iter);
283 bool hasLoopClosure =
false;
284 for(std::multimap<int, Link>::iterator jter=constraintsCpy.lower_bound(iter->first); jter!=constraintsCpy.end() && jter->first==iter->first; ++jter)
286 UDEBUG(
"%d: %d -> %d type=%d", iter->first, jter->second.from(), jter->second.to(), jter->second.type());
290 incGraph.insert(std::make_pair(jter->second.to(), incGraph.at(iter->first) * jter->second.transform()));
291 incGraphLinks.insert(*jter);
295 if(!
uContains(incGraph, jter->second.to()) && jter->second.to() > iter->first)
298 constraintsCpy.insert(std::make_pair(jter->second.to(), jter->second.inverse()));
303 incGraphLinks.insert(*jter);
304 hasLoopClosure =
true;
310 incGraph = this->
optimize(incGraph.begin()->first, incGraph, incGraphLinks);
313 UWARN(
"Failed incremental optimization...");
317 UDEBUG(
"Iteration %d/%d %s", ++i, (
int)poses.size(), hasLoopClosure?
"*":
"");
319 if(!incGraph.empty() && incGraph.size() == poses.size())
321 UASSERT(incGraphLinks.size() == constraints.size());
323 incGraph.at(rootId) = poses.at(rootId);
324 return this->
optimize(rootId, incGraph, incGraphLinks, intermediateGraphes, finalError, iterationsDone);
327 UDEBUG(
"Failed incremental optimization");
328 return std::map<int, Transform>();
333 const std::map<int, Transform> & poses,
334 const std::multimap<int, Link> & edgeConstraints,
335 std::list<std::map<int, Transform> > * intermediateGraphes,
337 int * iterationsDone)
351 const std::map<int, Transform> & poses,
352 const std::multimap<int, Link> & constraints,
353 cv::Mat & outputCovariance,
354 std::list<std::map<int, Transform> > * intermediateGraphes,
356 int * iterationsDone)
358 UERROR(
"Optimizer %d doesn't implement optimize() method.", (
int)this->
type());
359 return std::map<int, Transform>();
364 const std::map<int, Transform> & poses,
365 const std::multimap<int, Link> & links,
366 const std::map<int, CameraModel> & models,
367 std::map<int, cv::Point3f> & points3DMap,
368 const std::map<
int, std::map<int, cv::Point3f> > & wordReferences,
369 std::set<int> * outliers)
371 UERROR(
"Optimizer %d doesn't implement optimizeBA() method.", (
int)this->
type());
372 return std::map<int, Transform>();
377 const std::map<int, Transform> & poses,
378 const std::multimap<int, Link> & links,
379 const std::map<int, Signature> & signatures)
382 std::map<int, CameraModel> models;
383 for(std::map<int, Transform>::const_iterator iter=poses.begin(); iter!=poses.end(); ++iter)
389 if(signatures.at(iter->first).sensorData().cameraModels().size() == 1 && signatures.at(iter->first).sensorData().cameraModels().at(0).isValidForProjection())
391 model = signatures.at(iter->first).sensorData().cameraModels()[0];
393 else if(signatures.at(iter->first).sensorData().stereoCameraModel().isValidForProjection())
395 model = signatures.at(iter->first).sensorData().stereoCameraModel().left();
404 -signatures.at(iter->first).sensorData().stereoCameraModel().baseline()*model.
fx());
408 UERROR(
"Missing calibration for node %d", iter->first);
409 return std::map<int, Transform>();
414 UERROR(
"Did not find node %d in cache", iter->first);
415 return std::map<int, Transform>();
420 models.insert(std::make_pair(iter->first, model));
424 std::map<int, cv::Point3f> points3DMap;
425 std::map<int, std::map<int, cv::Point3f> > wordReferences;
428 return optimizeBA(rootId, poses, links, models, points3DMap, wordReferences);
434 std::map<int, cv::Point3f> & points3DMap,
435 const std::map<
int, std::map<int, cv::Point3f> > & wordReferences,
436 std::set<int> * outliers)
438 std::map<int, Transform> poses;
440 poses.insert(std::make_pair(link.
to(), link.
transform()));
441 std::multimap<int, Link> links;
442 links.insert(std::make_pair(link.
from(), link));
443 std::map<int, CameraModel> models;
444 models.insert(std::make_pair(link.
from(), model));
445 models.insert(std::make_pair(link.
to(), model));
446 poses =
optimizeBA(link.
from(), poses, links, models, points3DMap, wordReferences, outliers);
447 if(poses.size() == 2)
449 return poses.rbegin()->second;
458 const std::map<int, Transform> & poses,
459 const std::multimap<int, Link> & links,
460 const std::map<int, Signature> & signatures,
461 std::map<int, cv::Point3f> & points3DMap,
462 std::map<
int, std::map<int, cv::Point3f> > & wordReferences)
466 int edgeWithWordsAdded = 0;
467 for(std::multimap<int, Link>::const_iterator iter=links.begin(); iter!=links.end(); ++iter)
469 Link link = iter->second;
470 if(link.
to() < link.
from())
484 for(std::multimap<int, Link>::const_iterator jter=links.find(sTo.
id());
488 sTo = signatures.at(jter->second.to());
497 regParam.insert(
ParametersPair(Parameters::kVisEstimationType(),
"1"));
498 regParam.insert(
ParametersPair(Parameters::kVisPnPReprojError(),
"5"));
499 regParam.insert(
ParametersPair(Parameters::kVisMinInliers(),
"5"));
500 regParam.insert(
ParametersPair(Parameters::kVisCorNNDR(),
"0.6"));
515 for(
unsigned int i=0; i<info.
inliersIDs.size(); ++i)
520 int wordId = ++wordCount;
522 wordReferences.insert(std::make_pair(wordId, std::map<int, cv::Point3f>()));
525 wordReferences.at(wordId).insert(std::make_pair(sFrom.
id(), cv::Point3f(pt.x, pt.y, p.x)));
530 std::multimap<int, cv::Point3f>::const_iterator iterTo = sTo.
getWords3().lower_bound(info.
inliersIDs[i]);
532 iterTo->second.x > 0)
534 depth = iterTo->second.x;
536 wordReferences.at(wordId).insert(std::make_pair(sTo.
id(), cv::Point3f(pt.x, pt.y, depth)));
539 points3DMap.insert(std::make_pair(wordId, p));
542 ++edgeWithWordsAdded;
546 UWARN(
"Not enough inliers (%d) between %d and %d", info.
inliersIDs.size(), sFrom.
id(), sTo.
id());
552 UDEBUG(
"Added %d words (edges with words=%d/%d)", wordCount, edgeWithWordsAdded, links.size());
const std::multimap< int, cv::Point3f > & getWords3() const
bool priorsIgnored() const
static bool parse(const ParametersMap ¶meters, const std::string &key, bool &value)
void computeBACorrespondences(const std::map< int, Transform > &poses, const std::multimap< int, Link > &links, const std::map< int, Signature > &signatures, std::map< int, cv::Point3f > &points3DMap, std::map< int, std::map< int, cv::Point3f > > &wordReferences)
cv::Point3f RTABMAP_EXP transformPoint(const cv::Point3f &pt, const Transform &transform)
const std::multimap< int, cv::KeyPoint > & getWords() const
Transform computeTransformationMod(Signature &from, Signature &to, Transform guess=Transform::getIdentity(), RegistrationInfo *info=0) const
std::pair< std::string, std::string > ParametersPair
std::map< std::string, std::string > ParametersMap
Basic mathematics functions.
std::vector< int > inliersIDs
Some conversion functions.
static bool isAvailable(Optimizer::Type type)
const Transform & transform() const
#define UASSERT(condition)
Wrappers of STL for convenient functions.
std::map< int, Transform > optimizeIncremental(int rootId, const std::map< int, Transform > &poses, const std::multimap< int, Link > &constraints, std::list< std::map< int, Transform > > *intermediateGraphes=0, double *finalError=0, int *iterationsDone=0)
Optimizer(int iterations=Parameters::defaultOptimizerIterations(), bool slam2d=Parameters::defaultRegForce3DoF(), bool covarianceIgnored=Parameters::defaultOptimizerVarianceIgnored(), double epsilon=Parameters::defaultOptimizerEpsilon(), bool robust=Parameters::defaultOptimizerRobust(), bool priorsIgnored=Parameters::defaultOptimizerPriorsIgnored())
virtual void parseParameters(const ParametersMap ¶meters)
#define UASSERT_MSG(condition, msg_str)
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)
bool uContains(const std::list< V > &list, const V &value)
bool isValidForProjection() const
virtual Type type() const =0
virtual std::map< int, Transform > optimizeBA(int rootId, const std::map< int, Transform > &poses, const std::multimap< int, Link > &links, const std::map< int, CameraModel > &models, std::map< int, cv::Point3f > &points3DMap, const std::map< int, std::map< int, cv::Point3f > > &wordReferences, std::set< int > *outliers=0)
std::multimap< int, Link >::iterator RTABMAP_EXP findLink(std::multimap< int, Link > &links, int from, int to, bool checkBothWays=true)
ULogger class and convenient macros.
static void getConnectedGraph(int fromId, const std::map< int, Transform > &posesIn, const std::multimap< int, Link > &linksIn, std::map< int, Transform > &posesOut, std::multimap< int, Link > &linksOut, int depth=0)
std::string UTILITE_EXP uFormat(const char *fmt,...)
static Optimizer * create(const ParametersMap ¶meters)
const Transform & localTransform() const