MCPcopy Create free account
hub / github.com/PJLab-ADG/Livox-Mapping / detectLoopClosureID

Method detectLoopClosureID

SC-PGO/include/scancontext/Scancontext.cpp:336–427  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

334
335
336std::pair<int, float> SCManager::detectLoopClosureID ( void )
337{
338 int loop_id { -1 }; // init with -1, -1 means no loop (== LeGO-LOAM's variable "closestHistoryFrameID")
339
340 auto curr_key = polarcontext_invkeys_mat_.back(); // current observation (query)
341 auto curr_desc = polarcontexts_.back(); // current observation (query)
342
343 /*
344 * step 1: candidates from ringkey tree_
345 */
346 if( (int)polarcontext_invkeys_mat_.size() < NUM_EXCLUDE_RECENT + 1)
347 {
348 std::pair<int, float> result {loop_id, 0.0};
349 return result; // Early return
350 }
351
352 // tree_ reconstruction (not mandatory to make everytime)
353 if( tree_making_period_conter % TREE_MAKING_PERIOD_ == 0) // to save computation cost
354 {
355 TicTocV2 t_tree_construction;
356
357 polarcontext_invkeys_to_search_.clear();
358 polarcontext_invkeys_to_search_.assign( polarcontext_invkeys_mat_.begin(), polarcontext_invkeys_mat_.end() - NUM_EXCLUDE_RECENT ) ;
359
360 polarcontext_tree_.reset();
361 polarcontext_tree_ = std::make_unique<InvKeyTree>(PC_NUM_RING /* dim */, polarcontext_invkeys_to_search_, 10 /* max leaf */ );
362 // tree_ptr_->index->buildIndex(); // inernally called in the constructor of InvKeyTree (for detail, refer the nanoflann and KDtreeVectorOfVectorsAdaptor)
363 t_tree_construction.toc("Tree construction");
364 }
365 tree_making_period_conter = tree_making_period_conter + 1;
366
367 double min_dist = 10000000; // init with somthing large
368 int nn_align = 0;
369 int nn_idx = 0;
370
371 // knn search
372 std::vector<size_t> candidate_indexes( NUM_CANDIDATES_FROM_TREE );
373 std::vector<float> out_dists_sqr( NUM_CANDIDATES_FROM_TREE );
374
375 TicTocV2 t_tree_search;
376 nanoflann::KNNResultSet<float> knnsearch_result( NUM_CANDIDATES_FROM_TREE );
377 knnsearch_result.init( &candidate_indexes[0], &out_dists_sqr[0] );
378 polarcontext_tree_->index->findNeighbors( knnsearch_result, &curr_key[0] /* query */, nanoflann::SearchParams(10) );
379 t_tree_search.toc("Tree search");
380
381 /*
382 * step 2: pairwise distance (find optimal columnwise best-fit using cosine distance)
383 */
384 TicTocV2 t_calc_dist;
385 for ( int candidate_iter_idx = 0; candidate_iter_idx < NUM_CANDIDATES_FROM_TREE; candidate_iter_idx++ )
386 {
387 MatrixXd polarcontext_candidate = polarcontexts_[ candidate_indexes[candidate_iter_idx] ];
388 std::pair<double, int> sc_dist_result = distanceBtnScanContext( curr_desc, polarcontext_candidate );
389
390 double candidate_dist = sc_dist_result.first;
391 int candidate_align = sc_dist_result.second;
392
393 if( candidate_dist < min_dist )

Callers 1

performSCLoopClosureFunction · 0.80

Calls 7

SearchParamsClass · 0.85
clearMethod · 0.80
deg2radFunction · 0.70
sizeMethod · 0.45
tocMethod · 0.45
initMethod · 0.45
findNeighborsMethod · 0.45

Tested by

no test coverage detected