CHANGELOG
Changelog for package mola_sm_loop_closure
1.2.0 (2026-05-11)
f2f pipeline: switch to multi-objective as default strategy
Merge pull request #15 from MOLAorg/simplify-ci CI: simplify clang-format helpers and use ros: docker images for stable builds
fix: wrap find -iname predicates in parentheses to scope them to listed dirs Without grouping, the -o operators apply at top level and -print0 only attaches to the last alternative, so files outside the intended directories can be matched.
CI: simplify clang-format helpers and use ros: docker images for stable builds - Replace complex Python-based clang_git_format with a simple scripts/formatter.sh supporting –check - Standardize formatter to scripts/formatter.sh (moved from root formatter.sh) - Simplify check-clang-format.yml to just apt-install clang-format-14 and run the script - Use ros:humble / ros:jazzy pre-built images for stable CI builds (faster, no setup-ros needed)
fix:as libflann as build_depend as needed for kiss-matcher
CI: sensible job names
bump min req cmake version to 3.22
feat: live gui, show GNSS data points
update package.xml build deps
Merge pull request #14 from MOLAorg/improve-lc-hypothesis-coverage Improve lc hypothesis coverage
fix: deduplicate candidates by block-pair ID before selection in find_loop_candidates Multiple (i,j) frame pairs can round to the same (frameGroup_i, frameGroup_j) block and all pass the alreadyChecked filter (which only holds pairs from previous rounds). All of them survived into the scored candidate list, so max_lc_candidates were returned but the evaluation loop in process() silently skipped all but the first occurrence of each block pair – causing far fewer ICP evaluations than expected. Fix: after scoring (step 1) and before selection (step 2), deduplicate each candidate container by block-pair ID, keeping only the highest-scored entry per block. This is applied to both the flat candidates vector (PROXIMITY_ONLY, MULTI_OBJECTIVE) and each distance bin (DISTANCE_STRATIFIED), so max_lc_candidates now matches the number of candidates that will actually be evaluated. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
fix: MULTI_OBJECTIVE coverage term now uses spatial midpoints instead of sin formula The old coverage score used abs(sin(pi * topologicalMidpoint / totalFrames)), which only rewards candidates near the center of the frame index range and ignores actual map geometry. This caused clustering in the same physical region on non-linear trajectories (U-shapes, figure-8s, long straights). New approach: - Add LoopCandidate::spatialMidpoint ((pose_i + pose_j) / 2, computed once per candidate in find_loop_candidates()). - Track selectedMidpoints alongside selectedDistances in the greedy selection loop. - Coverage score penalizes candidates whose spatial midpoint is within ~20 m of an already-selected midpoint, forcing the selected set to cover different map areas regardless of trajectory shape. - Refactor score_multi_objective() to accept a MultiObjectiveArgs struct instead of a long flat parameter list, making call sites self-documenting. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
fix: MULTI_OBJECTIVE diversity scoring is now actually applied during selection selectedDistances was declared but never populated, so score_multi_objective() always computed diversity against an empty set (score = 1.0 always). The fix replaces the simple sort+truncate step 2 path for MULTI_OBJECTIVE with a greedy selection loop: pick the best candidate, record its distance, re-score the rest with the updated selectedDistances, repeat. This makes the diversity term a real participant in selection instead of a no-op. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
fix: live preview GNC stats no longer reset to zero at each LC round start liveStats was zero-initialized at the top of every lcRound loop, causing the 3Dscene caption to show “0 inliers, 0 outliers” until the first GNC optimization ran in that round. Carry lastGncInliers / lastGncOutliers forward so the caption always reflects the most recent optimizer result. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
feat: show better inliers/outliers stats
feat: manual LC now has an optional bypass for inliers
Merge pull request #13 from MOLAorg/feat/live-gui-3dscene-file feat: show ‘live’ progress via 3Dscene file updates
feat: show ‘live’ progress via 3Dscene file updates
add new mp2p_icp flags: force_final_pairings_for_quality
Add Codecov badge to README
Merge pull request #12 from MOLAorg/feat/f2f-integrate-kiss-matcher feat: Incorporate KISS-Matcher as optional seeder for initial ICP poses
fix: CI code coverage
chore: add more INFO traces
Fixes: cmake gating, don’t expose kiss-matcher headers, manual LC should be inlier
feat: Incorporate KISS-Matcher as optional seeder for initial ICP poses
FIX: crashes due to missing noise model and different gtsam symbols
feat: add gnss filter by max uncertainty
Merge pull request #11 from MOLAorg/refactor-common-code refactor: unify common code between the two LC algorithms
CI: Fix for new ROS2 rolling, add codecov upload
refactor: unify common code between the two LC algorithms
Contributors: Jose Luis Blanco-Claraco
1.1.0 (2026-04-29)
Merge pull request #10 from MOLAorg/refactor/lc-common-helpers refactor: extract lc_common helpers; port planar-world annealing + GNC to SM
refactor: replace two-pass LM with single GNC pass in SimplemapLoopClosure
refactor: extract lc_common helpers; port planar-world annealing + GNC to SM
Merge pull request #9 from MOLAorg/feat/planar-world-in-f2f feat: optional f2f planar world soft-constraints
feat: optional f2f planar world soft-constraints
Merge pull request #8 from MOLAorg/feat/manual-lc Support for optional manual hints for LC
Support for optional manual hints for LC
Merge pull request #7 from MOLAorg/feat/more-flexible-icp-sigmas-and-logging Expose more env vars
Expose more env vars
f2f pipeline file: add env var MOLA_DESKEW_IGNORE_ACCELEROMETER
Contributors: Jose Luis Blanco-Claraco
1.0.0 (2026-04-14)
package.xml: add missing test-dep
add unit tests
cli: use output directory as default for debug output files, not input
Install pipelines so they are accessible under ‘share’
Make the package discoverage by ament
Merge pull request #6 from MOLAorg/save-ram F2F algorithm: save ram in offline runs
More memory efficient loop
Bump minimum cmake version to 3.7
Reuse mp2p_icp::update_velocity_buffer_from_obs() from mp2p_icp Removes duplicated code in this repo now that mp2p_icp>=2.5.0 is available in all distributions
Fix build against mp2p_icp <2.6.0
icp debug log files: save only good edges
F2F algorithm: save ram in offline runs
sm2mm pipeline yaml: expose more params via env vars
Expose more parameters for F2F algorithm
Debug feature: enable saving 3Dscene files per optimization round
Use Graduated Non-Convexity (GNC) optimizer for superior outlier rejection
FIX: Reverted logic in formula for adaptive threshold
Add formal CLA
Merge pull request #5 from MOLAorg/feat/smart-ram-lazy-unload Lazy unload keyframe clouds to keep RAM usage bounded
Contributors: Jose Luis Blanco-Claraco
0.2.0 (2026-03-03)
Fix build against different gtsam versions
Add optional generation of .3Dscene files with loop-closure visualizations
Tolerate missing external files without throwing
Better logging and expose more env var params
Add GNSS uncertainty multiplier
Use debug files prefix
Add more frame-to-frame LC selection algorithms
Merge pull request #4 from MOLAorg/feat/f2f-fixes Add more parameters to f2f method
Add new params for f2f method
pipeline file: expose more params and fix reversed sigma logic
Fix: prior should be weak for GNSS to transform to ENU frame
fix copyright headers
Merge pull request #3 from MOLAorg/feat/new-f2f-algo Add alternative frame-to-frame LC algorithm
Provide virtual LoopClosureInterface to select the algorithm from a CLI argument
Add alternative frame-to-frame LC algorithm
Merge pull request #2 from MOLAorg/feat/add-ci-and-badges Add CI workflows and clang-format linting infrastructure
package.xml: add FILE tag
Merge pull request #1 from MOLAorg/feature/refactor-pkg-mola-gtsam-factors Progress moving code to new package mola_gtsam_factors
Update dependencies after refactorization into mola_georeferencing
Progress moving code to new package mola_gtsam_factors
Protect against invalid GPS cov entries
Add param gnss_minimum_uncertainty_xyz; dump trajectories as TUM files.
simplify: remove obsolete parameters not used anymore here
Remove unused parameter (GPS observations are automatically detected anyway)
Fix: ensure minimum uncertainty in edges
Fix deskewing generating sm2mm for local maps
Implement missing loading of new LocalVelocityBuffer while doing submaps “sm2mm”
Don’t use absolute paths for debug icplog files
FIX: Detect the error case of no GNSS observations in sm-georeference-cli
Add gicp pipeline
bump minimum cmake version to 3.5
add .clang-tidy rules and better vscode integration
Expose more env vars in the pipeline
robust kernels; optional horizontality
progress with submaps
implement submaps
use new mrpt enu covariance field
done georeferencing cli
progress
progress cli app interface
initial structure
Initial commit
Contributors: Jose Luis Blanco Claraco, Jose Luis Blanco-Claraco