Skip to content

Commit 3f6b098

Browse files
committed
Added error log on Kp/NNStrategy not compatible with huge vocabulary. ReduceGraph/DetectMoreLoopClosures: Make sure original parameters are saved back on closing. g2o: fixing optimizer to Levenberg for SBA to avoid [SetJac] infinite jac fatal error.
1 parent c0b0488 commit 3f6b098

File tree

5 files changed

+37
-7
lines changed

5 files changed

+37
-7
lines changed

corelib/src/FlannIndex.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ std::vector<unsigned char> FlannIndex::serializeIndex(bool computeChecksum) cons
9696
#else
9797
UTimer timer;
9898
const int headerSizeBytes = sizeof(int)*FLANN_INDEX_HEADER_SIZE;
99-
std::vector<unsigned char> indexData(1024*1024*100 + headerSizeBytes); // Max 100 MB
99+
std::vector<unsigned char> indexData(1024*1024*1024 + headerSizeBytes); // Max 1 GB
100100
FILE* indexDataPtr = fmemopen(indexData.data()+headerSizeBytes, indexData.size() - headerSizeBytes, "wb");
101101
long bytes_written = 0;
102102
if (indexDataPtr) {

corelib/src/VWDictionary.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -573,6 +573,15 @@ void VWDictionary::update()
573573
_removedIndexedWords.size() == 0 &&
574574
_visualWords.size())
575575
{
576+
const int IMGIDX_SHIFT = 18;
577+
const int IMGIDX_ONE = (1 << IMGIDX_SHIFT); // a limit defined in https://github.com/opencv/opencv/blob/4.x/modules/features2d/src/matchers.cpp
578+
if(_dataTree.rows >= IMGIDX_ONE)
579+
{
580+
UWARN("%s=%d is not a FLANN strategy and the number of words in the vocabulary (%d) is over %d (IMGIDX_ONE), so opencv may "
581+
"assert on an IMGIDX_ONE check when adding new words. Use a FLANN strategy instead (%s<%d).",
582+
Parameters::kKpNNStrategy().c_str(), _strategy, _dataTree.rows, IMGIDX_ONE, Parameters::kKpNNStrategy().c_str(), kNNBruteForce);
583+
}
584+
576585
//just add not indexed words
577586
int i = _dataTree.rows;
578587
if(!_dataTree.empty()) {
@@ -1006,7 +1015,7 @@ std::list<int> VWDictionary::addNewWords(
10061015
if(_flannIndex->isBuilt() || (!_dataTree.empty() && _dataTree.rows >= (int)k))
10071016
{
10081017
//Find nearest neighbors
1009-
UDEBUG("newPts.total()=%d ", descriptors.rows);
1018+
UDEBUG("newPts.total()=%d _strategy=%d", descriptors.rows, _strategy);
10101019

10111020
if(_strategy == kNNFlannNaive || _strategy == kNNFlannKdTree || _strategy == kNNFlannLSH)
10121021
{

corelib/src/optimizer/OptimizerG2O.cpp

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1559,7 +1559,13 @@ std::map<int, Transform> OptimizerG2O::optimizeBA(
15591559
#endif // RTABMAP_ORB_SLAM
15601560

15611561
#ifndef RTABMAP_ORB_SLAM
1562-
if(optimizer_ == 1)
1562+
// ISSUE: It seems the fatal error
1563+
// "[SetJac] infinite jac" happens relatively
1564+
// easily with GaussNewton on SBA problem,
1565+
// ignore optimizer_ and always use Levenberg for SBA.
1566+
// TODO: Note that g2o/RobustKernelDelta parameter could be
1567+
// potentially tuned to avoid that error with GaussNewton.
1568+
if(0)//optimizer_ == 1)
15631569
{
15641570
#ifdef RTABMAP_G2O_CPP11
15651571
optimizer.setAlgorithm(new g2o::OptimizationAlgorithmGaussNewton(
@@ -1944,7 +1950,8 @@ std::map<int, Transform> OptimizerG2O::optimizeBA(
19441950

19451951
if(uIsNan(chi2))
19461952
{
1947-
UERROR("Optimization generated NANs, aborting optimization! Try another g2o's optimizer (current=%d).", optimizer_);
1953+
UERROR("Optimization generated NANs, aborting optimization! Try another g2o's optimizer (current %s=%d) or solver (current %s=%d).",
1954+
Parameters::kg2oOptimizer().c_str(), optimizer_, Parameters::kg2oSolver().c_str(), solver_);
19481955
return optimizedPoses;
19491956
}
19501957
UDEBUG("iteration %d: %d nodes, %d edges, chi2: %f", i, (int)optimizer.vertices().size(), (int)optimizer.edges().size(), chi2);
@@ -1978,15 +1985,18 @@ std::map<int, Transform> OptimizerG2O::optimizeBA(
19781985
//UDEBUG("Ignoring edge (%d<->%d) d=%f var=%f kernel=%f chi2=%f", (*iter)->vertex(0)->id()-stepVertexId, (*iter)->vertex(1)->id(), d, 1.0/((g2o::EdgeProjectP2SC*)(*iter))->information()(0,0), (*iter)->robustKernel()->delta(), (*iter)->chi2());
19791986
#endif
19801987

1981-
cv::Point3f pt3d;
1988+
int id=-1;
19821989
if((*iter)->vertex(0)->id() > negVertexOffset)
19831990
{
1984-
pt3d = points3DMap.at(negVertexOffset - (*iter)->vertex(0)->id());
1991+
id = negVertexOffset - (*iter)->vertex(0)->id();
19851992
}
19861993
else
19871994
{
1988-
pt3d = points3DMap.at((*iter)->vertex(0)->id()-stepVertexId);
1995+
id = (*iter)->vertex(0)->id() - stepVertexId;
19891996
}
1997+
UASSERT_MSG(points3DMap.find(id) != points3DMap.end(), uFormat("word id=%d points3DMap=%ld vertex id=%d (negVertexOffset=%d stepVertexId=%d)",
1998+
id, points3DMap.size(), (*iter)->vertex(0)->id(), negVertexOffset, stepVertexId).c_str());
1999+
cv::Point3f pt3d = points3DMap.at(id);
19902000
((g2o::VertexSBAPointXYZ*)(*iter)->vertex(0))->setEstimate(Eigen::Vector3d(pt3d.x, pt3d.y, pt3d.z));
19912001

19922002
if(outliers)

tools/DetectMoreLoopClosures/main.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,7 @@ int main(int argc, char * argv[])
198198
// Add some optimizations (soft set, can be overriden by arguments)
199199
inputParams.insert(ParametersPair(Parameters::kMemLoadVisualLocalFeaturesOnInit(), "false")); // don't need features already loaded in RAM
200200
inputParams.insert(ParametersPair(Parameters::kKpNNStrategy(), "3")); // don't need flann index
201+
inputParams.insert(ParametersPair(Parameters::kMemIncrementalMemory(), "true")); // should be incremental to update links
201202

202203
std::string dbPath = argv[argc-1];
203204
if(!UFile::exists(dbPath))
@@ -247,6 +248,7 @@ int main(int argc, char * argv[])
247248
Rtabmap rtabmap;
248249
printf("Initialization...\n");
249250
UTimer timer;
251+
ParametersMap originalParameters = parameters;
250252
uInsert(parameters, inputParams);
251253
rtabmap.init(parameters, dbPath);
252254
printf("Initialization... done! (%f sec)\n", timer.ticks());
@@ -307,6 +309,9 @@ int main(int argc, char * argv[])
307309
}
308310
}
309311

312+
// Restore original parameters before saving back the database
313+
rtabmap.parseParameters(originalParameters);
314+
310315
rtabmap.close();
311316

312317
return 0;

tools/ReduceGraph/main.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,8 @@ int main(int argc, char * argv[])
106106
}
107107
printf("Parameters:\n");
108108
printf(" radius = %f m\n", radius);
109+
printf(" keep_latest = %s\n", keepLatest?"true":"false");
110+
printf(" keep_linked = %s\n", keepLinked?"true":"false");
109111

110112
// Just parse logging options
111113
Parameters::parseArguments(argc, argv);
@@ -142,6 +144,7 @@ int main(int argc, char * argv[])
142144
Memory memory;
143145
printf("Initialization...\n");
144146
UTimer timer;
147+
ParametersMap originalParameters = parameters;
145148
uInsert(parameters, inputParams);
146149
if(!memory.init(dbPath, false, parameters))
147150
{
@@ -232,6 +235,9 @@ int main(int argc, char * argv[])
232235
printf("Saved the new global occupancy grid!\n");
233236
}
234237
}
238+
239+
// Restore original parameters before saving back the database
240+
memory.parseParameters(originalParameters);
235241

236242
memory.close(true);
237243

0 commit comments

Comments
 (0)