Skip to content

Odometry confidence tiers: capture-time signal + BA weighting - #71

Merged
kobejean merged 2 commits into
mainfrom
odometry-confidence-tiers
Jul 5, 2026
Merged

Odometry confidence tiers: capture-time signal + BA weighting#71
kobejean merged 2 commits into
mainfrom
odometry-confidence-tiers

Conversation

@kobejean

@kobejean kobejean commented Jul 5, 2026

Copy link
Copy Markdown
Owner

What & why

ARKit gives excellent relative pose but drifts globally, and its tracking quality varies across a capture (excessive motion, low texture, relocalization). Until now every ARKit-derived odometry constraint in bundle adjustment was trusted equally. This adds a coarse, capture-time confidence signal per between-snap odometry edge and uses it to weight those edges in BA — and it's the input the upcoming vision loop-closure work needs to decide where drift correction should land.

Design contract: the capture side makes no numeric decisions (it records only the platform's own categorical tracking label), and all tuning lives offline in the refiner. See docs/ODOMETRY_CONFIDENCE.md.

Changes

  • Frame::odom_state + OdometryConfidence enum (frame.h): a platform-neutral int = the worst tracking state observed over the interval into that frame (severity-ordered, so max() is the reduction). Serialized into frames.json via NLOHMANN_..._WITH_DEFAULT so older captures without the field parse as 0 (Normal) — no migration, no regression.
  • BA weighting (bundle_adjustment.cpp): addOdometry scales the odometry information matrix by odomConfidenceWeight(odom_state) — HIGH (Normal)=1.0, MEDIUM (Limited*)=0.25, LOW (Relocalizing/Unavailable)=0.02. These three constants are the only tunable knobs; unknown values fall back to full trust.

Platform-neutral (iOS today, Android-ready)

The on-disk enum is not ARKit-specific: iOS maps ARCamera.trackingState → the int; a future ARCore app maps TrackingState + TrackingFailureReason → the same values. Everything downstream is identical regardless of capture platform. (The capture-side accumulator + bridge lands in a companion lar-swift PR.)

Verification

  • JSON round-trip: odom_state:4 → 4; erasing the key → default 0.
  • make fast builds lar_refine_colmap + lar_create_map clean.

Not in this PR (by design)

  • Loop closure — the reason the tiers exist. BA now respects the tiers, but there's no vision loop-closure constraint yet; down-weighting a LOW edge just makes BA trust it less. Tiers tell loop closure where to absorb correction once it's built.
  • Weight values are placeholder defaults pending a sweep on real captures.

🤖 Generated with Claude Code

Trinh and others added 2 commits July 5, 2026 11:36
Record the worst ARKit/ARCore tracking state observed over each
between-snap interval as Frame::odom_state (see the new
OdometryConfidence enum), serialized into frames.json. Offline bundle
adjustment / loop closure will map these tiers to odometry-edge weights;
this commit only carries the signal, it does not consume it.

Uses NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT so older frames.json
without the field parse as 0 (Normal), preserving prior uniform-trust
behavior. Verified via JSON round-trip (4 -> 4) and legacy-default (0).

Spec: docs/ODOMETRY_CONFIDENCE.md

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Scale each odometry edge's information matrix in addOdometry by
odomConfidenceWeight(frame.odom_state): HIGH (Normal) = 1.0, MEDIUM
(Limited*) = 0.25, LOW (Relocalizing/Unavailable) = 0.02. A shaky or
relocalizing between-snap interval is now down-weighted rather than
trusted like a clean one, so bundle adjustment (and future loop closure)
lets drift correction land on the low-confidence edges.

These three constants are the only tunable knobs; the capture side emits
the categorical tier untouched (see docs/ODOMETRY_CONFIDENCE.md). Unknown
odom_state values fall back to full trust, so pre-signal captures behave
as before.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@kobejean
kobejean merged commit ada449f into main Jul 5, 2026
2 checks passed
@kobejean
kobejean deleted the odometry-confidence-tiers branch July 5, 2026 02:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant