Improve GLIM three-LiDAR map quality - #15
Merged
learnwithallen merged 3 commits intoJul 27, 2026
Merged
Conversation
FieldDiTian
force-pushed
the
agent/glim-map-quality
branch
7 times, most recently
from
July 26, 2026 07:05
c80b6f0 to
e7f78dc
Compare
FieldDiTian
force-pushed
the
agent/glim-map-quality
branch
from
July 26, 2026 08:35
e7f78dc to
19c1537
Compare
FieldDiTian
marked this pull request as ready for review
July 26, 2026 20:41
Author
|
Addressed the requested P2 final-flush issue in
Validation:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This aligns the
ucb-roarGLIM path with the provenperception-wsthree-LiDAR mapping contract while keeping dataset-specific topics,
calibration, GNSS datum, output paths, and scratch paths injected per run.
The full Laguna Run1 regression identified two separate long-run failures:
one-scan mapping cadence;
0.001made the long chain muchtoo stiff in both translation and roll/pitch, so position-only GNSS plus
inlier-only repeated-track loops could deform the map orientation.
This PR keeps one scan per geometric submap, independently batches global
optimization, independently samples loop-registration nodes, uses honest
rotation/translation odometry covariance, adds an opt-in fused-INS body-Z
prior, deterministically bounds loop candidates, gates loop corrections, and
fully converges each loop batch before map-health callbacks.
It also retains the earlier PR15 fixes for three-LiDAR timing, bounded dense
map memory, fused-GNSS factor delivery and health, deterministic final drain,
true-EOF batch exit, and exact ENU-to-ENU map export.
No map, bag, log, generated config, report, PNG, build output, temporary
runner, QoS file, or process file is committed.
Root cause and repaired behavior
The earlier ten-keyframe map had an optimized-trajectory rotation P95 of
13.123 degand 2,637 frames above 10 degrees. The inherited0.001odometry sigma represented 1 mm and 0.057 degrees per step; over the long
multi-lap chain, it overruled the tested 0.5-degree gravity evidence.
Repeated Laguna geometry then allowed high-inlier loop registrations in the
wrong longitudinal phase. A loose 1 m/5-degree loop check was not sufficient,
and a single partially relinearized iSAM2 update could expose a transient
deformation to the GNSS health callback.
The repaired profile uses:
The shared GLIM JSON retains backward-compatible behavior: legacy odometry
defaults remain
0.001/0.001, gravity remains disabled, loop correction gatesremain disabled, loop cadence remains every submap, and extra loop updates
remain zero. The production generator injects the validated high-quality
profile explicitly.
File-by-file rationale
GLIM/glim/config/config_global_mapping_pose_graph.json: documents andexposes independent optimizer/loop cadence, odometry rotation/translation
sigmas, loop candidate/correction/synchronization controls, refinement
bounds, and dense-point offload with backward-compatible defaults.
GLIM/glim/include/glim/mapping/global_mapping_pose_graph.hpp: declares thenew cadence and covariance parameters, loop synchronization state, accepted
correction maxima, convergence telemetry, and dense-point bookkeeping.
GLIM/glim/include/glim/util/time_keeper.hpp: exposes a setter for theconfigured point timestamp offset instead of reaching into private state.
GLIM/glim/src/glim/mapping/global_mapping_pose_graph.cpp: preservesper-scan pose-graph nodes while batching iSAM2, retains only a bounded
loop-registration working set, applies anisotropic odometry noise,
deterministic candidate selection and correction gates, synchronizes loop
completion, converges loop batches, restores dense exports, and records
auditable telemetry.
GLIM/glim/src/glim/util/export_factors.cpp: registersPose3AttitudeFactorso the opt-in body-Z evidence is preserved when thefinal factor graph is serialized.
GLIM/glim/src/glim/util/time_keeper.cpp: implements the timestamp-offsetsetter.
GLIM/glim_ext/README.md: documents the opt-in gravity-direction factor andits validated-orientation requirement.
GLIM/glim_ext/config/config_gnss_global.json: exposes recent-window fit,covariance bounds, robust width, optimized-anchor health, persistent
failure, and disabled-by-default body-Z settings.
GLIM/glim_ext/modules/mapping/gnss_global/include/glim_ext/gnss_global_module.hpp:fits the newest trajectory segment spanning the requested baseline, carries
GNSS covariance through interpolation, inserts factors atomically, measures
post-iSAM2 anchor health, rejects only persistent divergence, and optionally
constrains body Z from a validated fused-INS quaternion without constraining
yaw.
GLIM/glim_ros2/include/glim_ros/glim_ros.hpp: exposes aggregate extensionhealth and stores the injected IMU input-vector rotation.
GLIM/glim_ros2/include/glim_ros/lidar_concat.hpp: makes relative-timeprimary clouds wait until each auxiliary stream crosses the primary header
before selecting the nearest sweep.
GLIM/glim_ros2/src/glim_pcap_rosbag.cpp: propagates mapping-quality failurestatus from the PCAP-backed runner.
GLIM/glim_ros2/src/glim_ros/glim_ros.cpp: rotates acceleration and gyrointo the calibrated IMU frame, throttles against the slowest mapping stage,
drains extension work before serialization, and exposes extension health.
GLIM/glim_ros2/src/glim_rosbag.cpp: supports bounded two-pass indexing,exact EOF accounting, strict three-LiDAR boundary handling, nonzero quality
failures, and
auto_quit=trueso a true EOF drains, saves, and exits withoutan interactive wait.
GLIM/glim_ros2/test/lidar_concat_point_time_test.cpp: adds the formalregression proving that a relative-time primary waits for the future
auxiliary sweep.
README.md: documents the mapping contract, every path/topic/parameterinjection point, independent geometric/optimizer/loop cadence, exact datum
conversion, root cause, and validated full-run profile.
scripts/export_glim_dump_to_pcd.py: separates input GNSS datum from outputmap datum and applies the exact WGS84 ENU-to-ENU transform without fitting a
second alignment.
scripts/generate_glim_mapping_config.py: creates a self-contained,dataset-independent profile with explicit topics, extrinsics, IMU
correction, GNSS gates, output/config/scratch paths, and validated
high-quality pose-graph parameters.
Build and focused tests
Base:
ucb-roarat69eb5742ebe7bb60f58e0a8525963f5800809262.lidar_concat_point_time_testpassed;Pose3AttitudeFactorfactors preserved in the saved graph;strict absolute scratch/output paths, independent cadence, loop gates,
odometry sigmas, and gravity prior;
git diff --checkpassed;Full Laguna Run1 mapping
Input: decoded three-LiDAR Run1,
/novatel_a/imu_body, and fused/gnss.Optimized trajectory versus fused GNSS/INS:
The final 0.15 m map has 140,235,636 points. Same-frame comparison against the
perception-ws references:
The earlier ten-keyframe map versus the 32.5M reference was 1.131 m median,
6.667 m P95, and 46% within 1 m.
Full PR14 GICP replay on the repaired map
The existing PR14 small_gicp path replayed all of Run1 at 1.0x:
1.284 / 3.786 / 9.973 m; zero over 20 m;1.920 / 5.150 / 7.346 / 19.990 deg;7.24 / 100.27 / 355.40 ms;top-down tool.
This passes the requested map/GICP gates and fixes the 10x orientation tail.
The position difference was reviewed and accepted for this result. Reset
frequency and P95 latency remain explicit localization-runtime watchpoints.
All reports, maps, logs, MCAP, and top-down images remain under the Laguna
dataset directories and are not PR content.