# Component Fit Matrix — C5: State estimator / sensor fusion

> Mode A Phase 2 — engine Step 7.5 (Component Applicability Gate, structured per-component candidate-selection table). Status vocabulary in [`00_summary.md`](00_summary.md). Backing fact cards: [`../02_fact_cards/C5_state_estimator.md`](../02_fact_cards/C5_state_estimator.md). Cross-cite [`../02_fact_cards/C4_pose_estimation.md`](../02_fact_cards/C4_pose_estimation.md) Fact #54 (GTSAM `Marginals` C4→C5 forward-cite via iSAM2 architectural extension).
>
> Index: [`00_summary.md`](00_summary.md). Sibling components: [C1 VIO](C1_vio.md), [C2 VPR](C2_vpr.md), [C3 Matchers](C3_matchers.md), [C4 Pose](C4_pose_estimation.md), [C6 Tile cache](C6_tile_cache_spatial_index.md), [C7 Inference runtime](C7_inference_runtime.md), [C8 FC adapter](C8_fc_adapter.md), [C10 Pre-flight provisioning](C10_preflight_provisioning.md). C9 dropped per 2026-05-08 restructure. Cross-component gates: [`99_cross_component_gates.md`](99_cross_component_gates.md).

---

## C5 — State estimator / sensor fusion

**Status**: **CLOSED at 2/N (batch 1 closed 2026-05-08)** at documentary level (mandatory simple-baseline role — Manual ESKF per Solà 2017 canonical aerial/quaternion reference [Fact #88]; modern-competitive-lead-factor-graph role — GTSAM iSAM2 + smart factors carrying forward C4 Fact #54 [Fact #89]). Five Plan-phase Choose blocks raised (D-C5-1 through D-C5-5) — see [`99_cross_component_gates.md`](99_cross_component_gates.md). Subsequent C5 candidates (e.g., MSCKF, classical EKF, Wolf framework, OpenVINS-as-state-estimator) deferable — current 2-candidate breadth satisfies engine Component Option Breadth rule for the user-picked B scope per session-start decision.

**Pinned mode** (frame-rate state estimator + multi-source fusion contract for the project's C5 row):

- inputs: `{C1 VIO output (6-DoF relative pose @ ≥3 Hz with σ_yaw ≤ 5° / σ_pitch ≤ 5° per Fact #24 contract; OKVIS2/OpenVINS/VINS-Mono per D-C1-1) + C4 satellite-anchor poses (6-DoF tile-frame absolute pose with 6×6 covariance, source label satellite_anchor, ~3 Hz when AC-2.1b registration succeeds, sparse otherwise) + FC IMU (high-rate via MAVLink ATTITUDE / RAW_IMU per SQ6 cross-cite to ArduPilot Plane current path) + FC attitude/airspeed/altitude (lower-rate; airspeed-derived velocity prior; barometer altitude prior) + optional operator re-loc hint via GCS (rare, AC-3.4)}` on `Jetson Orin Nano Super (8 GB shared, JetPack 6, ROS 2 Humble)`; per-frame compute = 1 estimator update at min-3-Hz when satellite anchor available + IMU propagation between anchors at high rate + dead-reckoning fallback when both VIO + anchor unavailable
- outputs: `{WGS84 position (lat, lon, alt) + 3D velocity in body or NED frame + attitude as quaternion + 6×6 honest pose covariance + source label one-of {satellite_anchored, visual_propagated, dead_reckoned} + last_satellite_anchor_age_ms + per-source residual diagnostic for debug + frame-rate output at min camera rate (3 Hz) with FC-IMU-driven propagation between camera updates}` per AC-NEW-3 (FDR), AC-NEW-4 (covariance honesty), AC-NEW-8 (blackout failsafe), AC-3.x (resilience), AC-1.x (accuracy)

**Locked-in research-time defaults** (carried forward from C1 + C2 + C3 + C4 — Fact #41):
- D-C1-1 = (c) **keep both license tracks open** through Plan; final license decision deferred to post-Jetson-MVE.
- D-C1-2 = (b) **defer Jetson Orin Nano Super hardware MVE to a dedicated bring-up phase** between research and Plan; research closes with documentary ranking + per-candidate `Verify` gates.

**Interactions with prior C-row closures**:
- **C4 Fact #54 forward-cite to C5 is the dominant architectural pull**: GTSAM's factor-graph paradigm scales naturally from C4 single-frame PnP to C5 multi-frame state estimation via `iSAM2` + `BetweenFactor<Pose3>` (between-pose temporal odometry factors) + `PriorFactorPose3` (prior on initial pose) + per-frame `GenericProjectionFactorCal3_S2` (per-correspondence projection factors at each frame) + IMU pre-integration via `ImuFactor` / `CombinedImuFactor` (Forster et al. RSS 2015). If C5 = GTSAM iSAM2 is Selected, C4 = GTSAM-as-primary becomes architecturally cleaner than C4 = OpenCV-as-primary + GTSAM-as-covariance-recovery hybrid (Fact #52 + Fact #54 D-C4-2 = (b) coupling).
- **AC-NEW-4 covariance-honesty contract**: C5 inherits C4's per-anchor 6×6 covariance and must propagate it forward through IMU integration without identity-matrix-placeholder degradation. Covariance honesty requires either (a) GTSAM `Marginals.marginalCovariance` posterior recovery (Fact #54-style) at every C5 update, or (b) ESKF analytic covariance propagation through state-transition Jacobian + process noise injection (Solà 2017 §6 canonical recipe).
- **C1 VIO contract σ_yaw ≤ 5° / σ_pitch ≤ 5°** (Fact #24): C5 must validate this contract at Jetson MVE phase via the C1 candidate's documented attitude-noise output; failure to meet σ ≤ 5° forces D-C5-N attitude-prior-strategy decision (eg use FC IMU directly via MAVLink ATTITUDE message instead of C1 VIO attitude).
- **AC-NEW-2 spoofing-promotion <3 s**: C5 owns the source-label state machine `{satellite_anchored → visual_propagated → dead_reckoned}` and the Mahalanobis outlier gates that decide when to demote/promote labels. The decision logic is in C5 even though the spoofing signal originates at C8 (FC adapter).
- **C8 MAVLink/MSP2 FC adapter contract**: C5 emits the fused estimate to C8 which encodes it as `GPS_INPUT` (ArduPilot Plane) or `MSP2_SENSOR_GPS` (iNav UBX-impersonation per SQ6 closure); C5 covariance honesty determines `eph` / `epv` fields in those messages.

| # | Candidate | License | Per-mode verification | Status | Lead reason / disqualifier | Sub-matrix cite |
|---|---|---|---|---|---|---|
| 1 | **Manual ESKF reference (Solà 2017 — "Quaternion kinematics for the error-state Kalman filter")** (canonical aerial/quaternion ESKF tutorial; mandatory simple-baseline; project-side custom implementation in NumPy/SciPy or hand-written C++17/Eigen3 following Solà 2017 §5+§6 equations directly) | **Public-domain canonical equations + project's Apache-2.0 implementation** — Source #88 academic preprint arXiv:1711.02508 (open-access at <https://arxiv.org/abs/1711.02508>; HAL mirror at <https://hal.science/hal-01122406v5>); 592 citations per Semantic Scholar; canonical equations not copyrightable; project's manual implementation gets project's chosen license, default Apache-2.0 per project tech-stack rule; **eligible on every D-C1-1 license-posture choice with the simplest license-compliance story** (no upstream library license to verify); reference open-source implementations (Source #89.a-e) used as documentary template only with D-C5-1 NEW license-verification gate | ✅ Mode enumeration via WebFetch direct on canonical paper — both §5 local-error-state ESKF (default) and §7 global-error-state ESKF formulations documented; 18-state nominal-state vector `[p, v, q, a_b, ω_b, g]` + 18×18 error-state covariance with `[δp, δv, δθ, δa_b, δω_b, δg]` minimal-parameter form; §5.4 discrete-time error-state Jacobians; §6.1 measurement update + §6.2 nominal-state injection + §6.3 covariance reset (with G≈I_18 default + non-trivial G per §6.3.1 option); ✅ runnable example via 5 reference open-source implementations (ludvigls/ESKF DIRECTLY MATCHING fixed-wing UAV + cggos/imu_x_fusion MATCHING multi-source pattern + EliaTarasov/ESKF based on PX4/ecl + koledickarlo/ESKF-ESP32 microcontroller + joansola/slamtb MATLAB); ✅ canonical Mahalanobis outlier gate (3-σ or χ²-test on innovation residual) standard Kalman-filter literature; ⚠️ **manual implementation effort** ~1-2 weeks (mitigation = ludvigls/ESKF documentary template); ⚠️ **observability requirement in long-cruise** (D-C5-2 NEW gate); ⚠️ **reset Jacobian approximation** (canonical `G≈I_18` default per §6.3) | **Mandatory simple-baseline reference** (engine Component Option Breadth rule role — structurally analogous to OpenCV `solvePnPRansac`'s role in C4 row + NetVLAD's role in C2 row + SuperGlue+SuperPoint's role in C3 row); deployment-ready under every D-C1-1 license-posture choice with **trivial memory footprint (2.6 KB) + ~5-15 ms per update on Jetson CPU = FASTEST C5 candidate by an order of magnitude**; final ranking deferred to Jetson MVE phase per D-C1-2 | **THREE CONVERGING POSITIVE structural advantages**: (i) **PUBLIC-DOMAIN CANONICAL EQUATIONS + PROJECT'S APACHE-2.0 IMPLEMENTATION LICENSE** — eligible on every D-C1-1 license-posture choice with the simplest license-compliance story (no upstream library license to verify); (ii) **NATIVE 6×6 POSE COVARIANCE via analytic Jacobian propagation** per §6.1 Kalman-update math — only C5 candidate to date that satisfies AC-NEW-4 NATIVELY without library-mediated posterior recovery; (iii) **TRIVIAL MEMORY + COMPUTE FOOTPRINT** — 2.6 KB for state + covariance, ~5-15 ms per update on Jetson CPU; **fastest C5 candidate by an order of magnitude** vs GTSAM iSAM2's ~50-150 ms per update extrapolation. **ONE NEGATIVE-BUT-MITIGABLE structural finding**: (iv) manual implementation effort ~1-2 weeks for an experienced engineer; mitigation = use Source #89.a ludvigls/ESKF as documentary template (fixed-wing UAV match) for ~30-50% of structural code with LICENSE verification at D-C5-1 NEW. **THREE MINOR CAVEATS**: (v) observability requirement in long-cruise — D-C5-2 NEW gate; mitigation = mission-profile-natural re-excitation via AC-3.1/AC-3.2 sharp turns; (vi) reset Jacobian approximation — canonical `G≈I_18` default per §6.3; non-trivial G per §6.3.1 available; (vii) NO JetPack 6 cross-compilation engineering required (vs GTSAM ~1-2 days) — pure-Python/NumPy or pure-C++/Eigen3 trivially deployable. **AC-4.5 LIMITATION**: Manual ESKF is recursive (forward-time only); cannot natively support look-back refinement of prior estimates — project workaround = small sliding-window buffer + delayed-measurement-replay (~1-2 days engineering) OR pivot to GTSAM iSAM2 (Candidate #2) for NATIVE AC-4.5 support | Fact #88 in [`../02_fact_cards/C5_state_estimator.md`](../02_fact_cards/C5_state_estimator.md) (per-mode entry + per-numbered-Restriction × per-numbered-AC sub-matrix block) |
| 2 | **GTSAM `iSAM2` + `PreintegratedCombinedMeasurements` + `CombinedImuFactor` (Forster et al. RSS 2015) + `BetweenFactorPose3` + `GenericProjectionFactorCal3DS2` + `PriorFactorPose3` + `Marginals.marginalCovariance` + `gtsam_unstable.IncrementalFixedLagSmoother`** (canonical `borglab/gtsam` library by Frank Dellaert et al. + Georgia Tech Borg Lab; modern-competitive-lead-factor-graph; **architecturally couples with C4 Fact #54 via shared GTSAM substrate**) | **BSD-3-Clause (clean throughout)** — cross-cite to Fact #54 Source #86 LICENSE.BSD direct WebFetch verified `Copyright (c) 2010, Georgia Tech Research Corporation` with 3 numbered redistribution conditions + non-endorsement clause; bundled deps clean (BSD-3 + Apache-2.0 + MPL2 file-level — all dual-use compatible); 3424 stars + last pushed **2026-05-08T13:00:22Z = TODAY at access time** (daily-active maintenance, fresher than OpenCV by 6 hours per Fact #54) | ✅ Mode enumeration via context7 INDEXED PASS at `/borglab/gtsam` version 4.3a1 with **1121 code snippets** (best context7 indexing of any C5 candidate evaluated; cross-cite to Fact #54) — `PreintegrationCombinedParams.MakeSharedU(9.81)` + `PreintegratedCombinedMeasurements(params, bias_hat)` + `pim.integrateMeasurement(acc, gyro, dt)` + `CombinedImuFactor(X(i), V(i), X(j), V(j), B(i), B(j), pim)` 6-key per-keyframe-pair IMU factor with bias evolution (Forster et al. RSS 2015 paradigm) + `BetweenFactorPose3` + `GenericProjectionFactorCal3DS2` + `PriorFactorPose3` + `ISAM2(ISAM2Params)` + `isam2.update(new_factors, new_initial_estimate)` + `Marginals(graph, isam2.calculateEstimate()).marginalCovariance(X(current))` + `noiseModel.Robust.Create(mEstimator.Huber.Create(1.345), gaussian_noise)` Huber M-estimator + `GncOptimizer` Graduated Non-Convexity (Yang et al. RAL 2020) + `gtsam_unstable.IncrementalFixedLagSmoother` sliding-window (D-C5-3 NEW gate) documented in Source #90 + Source #91; ✅ runnable example via canonical Python notebooks `CombinedImuFactor.ipynb` + `PreintegratedImuMeasurements.ipynb` + `ImuFactor.ipynb` + `GPSFactor.ipynb` + `ISAM.ipynb` + `PlanarSLAMExample.ipynb` + `Pose2SLAMExample.ipynb`; ✅ **NATIVE 6×6 POSE COVARIANCE via `Marginals.marginalCovariance` with iSAM2 results** — same NATIVE AC-NEW-4 satisfaction pathway as C4 Fact #54; ✅ **Forster et al. RSS 2015 IMU pre-integration paradigm** via CombinedImuFactor 6-key factor with bias evolution per random walk; ⚠️ **CombinedImuFactor requires CONTIGUOUS IMU samples** (D-C5-4 NEW gate); ⚠️ **per-update latency depends on factor-density** (D-C5-5 NEW gate); ⚠️ **`IncrementalFixedLagSmoother` is in `gtsam_unstable` namespace** (D-C5-3 NEW gate); ⚠️ **TIGHT AC-4.1 latency margin** (~50-150 ms per update extrapolated to Jetson Orin Nano Super; **comfortable AC-4.1 satisfaction at 3 Hz update rate** but **10-30× slower than Manual ESKF Fact #88**); ⚠️ **NO JetPack 6 canonical distribution** (~1-2 days cross-compilation engineering, same as Fact #54) | **Modern-competitive-lead-factor-graph** (engine Component Option Breadth rule role; **directly addresses AC-NEW-4-binding-constraint axis** via shared-substrate coupling with C4 Fact #54; **NATIVE AC-4.5 look-back-refinement satisfaction**; **architecturally couples with C4 Fact #54 via shared GTSAM substrate**); deployment-ready under every D-C1-1 license-posture choice; final ranking deferred to Jetson MVE phase per D-C1-2 | **THREE CONVERGING POSITIVE structural advantages**: (i) **NATIVE 6×6 POSE COVARIANCE via `Marginals.marginalCovariance` with iSAM2 results** — same NATIVE AC-NEW-4 satisfaction pathway as C4 Fact #54 (Marginals works on both batch optimizer results and `ISAM2.calculateEstimate()` results per Source #91); **directly addresses the AC-NEW-4-binding-constraint axis** via shared-substrate coupling with C4 Fact #54; (ii) **Forster et al. RSS 2015 IMU pre-integration paradigm** — `CombinedImuFactor` handles asynchronous IMU+camera fusion at ~100-200 Hz IMU + 3 Hz camera natively + bias evolution per random walk between keyframes; **canonical reference for modern factor-graph IMU integration** that classical EKF/ESKF cannot match in algorithmic accuracy at high IMU rates; (iii) **architectural coupling with C4 Fact #54 via shared GTSAM substrate** — if C4 = GTSAM-as-primary AND C5 = iSAM2, shared library substrate reduces cross-component implementation overhead AND enables joint optimization of C4 single-frame PnP + C5 multi-frame smoothing in one factor graph. **ONE ADDITIONAL POSITIVE structural advantage**: (iv) **NATIVE LOOK-BACK REFINEMENT VIA INCREMENTAL SMOOTHING** — iSAM2 incrementally updates the entire sliding-window posterior on every new measurement, naturally supporting AC-4.5 NATIVELY (UNIQUE C5 candidate to date that satisfies AC-4.5 NATIVELY). **ONE NEGATIVE-BUT-MITIGABLE structural finding**: (v) **TIGHT AC-4.1 LATENCY MARGIN** — Jetson Orin Nano Super extrapolated ~50-150 ms per update CPU-only (10-30× slower than Manual ESKF Fact #88); mitigation strategies include reduce K from 20 to 5-10 keyframes (D-C5-3) OR smart-projection-pose-factor (D-C5-5(b)) OR PriorFactorPose3-only with C4 GTSAM Marginals satellite-anchor 6×6 covariance (D-C5-5(c) — cleanest cross-component coupling). **THREE CAVEATS**: (vi) ~50-200 MB library footprint (heaviest C5 candidate but well within AC-4.2 budget); (vii) NO JetPack 6 canonical distribution (~1-2 days cross-compilation engineering); (viii) IncrementalFixedLagSmoother in gtsam_unstable namespace (D-C5-3 gate). **Recommended C5 architecture for the project**: **GTSAM iSAM2 as primary-substrate for AC-NEW-4 covariance-honest factor-graph state estimation + IncrementalFixedLagSmoother bounded sliding-window per D-C5-3 = (a) + adaptive PIM integration covariance inflation per D-C5-4 = (a) + PriorFactorPose3 only with C4 GTSAM Marginals satellite-anchor 6×6 covariance per D-C5-5 = (c) — couples C4 Fact #54 D-C4-2 = (b) with C5 Fact #89 architectural integration via shared GTSAM substrate** (canonical Plan-phase pathway for the GTSAM-as-shared-C4+C5-substrate hybrid path). **Manual ESKF Fact #88 as the mandatory-simple-baseline reference floor + Jetson MVE benchmark target** for AC-4.1-latency-headroom + AC-4.2-memory-headroom regression validation | Fact #89 in [`../02_fact_cards/C5_state_estimator.md`](../02_fact_cards/C5_state_estimator.md) (per-mode entry + per-numbered-Restriction × per-numbered-AC sub-matrix block) |

### C5 — Plan-phase deliverables raised by candidate closures (will compound as candidates close)

1. **D-C5-1 NEW (raised by Manual ESKF Solà 2017 closure 2026-05-08, Fact #88) — reference-implementation-license-verification** — if project elects to reuse Source #89.a `ludvigls/ESKF` (Python ESKF for fixed-wing UAVs DIRECTLY MATCHING project hardware family) OR Source #89.b `cggos/imu_x_fusion` (C++/ROS multi-source loosely-coupled fusion) OR Source #89.d `koledickarlo/ESKF-ESP32` (microcontroller-class with explicit Solà 2017 citation) at the source-code level (LICENSE not declared in front-page READMEs per Source #89), Plan-phase verification gate required: **(a)** counsel-review of repo for LICENSE file in subdirectory (~1 hour engineering) — RECOMMENDED first step, **(b)** treat as GPL/copyleft-equivalent and write project implementation from Solà 2017 paper directly without code reuse (~1-2 weeks engineering vs ~3-5 days with reference template), **(c)** contact author for LICENSE clarification (~1-3 weeks turnaround if author responsive). Source #89.c `EliaTarasov/ESKF` is PX4-derived (PX4 is dual BSD/Apache-2.0, ecl is BSD-3-Clause) so license-clearance is easier if project elects to reuse that template. Source #89.e `joansola/slamtb` is MATLAB-only and not deployable on JetPack 6 (algorithmic reference only). **Recommendation**: D-C5-1 = (b) write directly from canonical Solà 2017 paper for cleanest license-compliance story; reference implementations serve as documentary templates (read for understanding, not copy-paste). Final lock at Plan phase after counsel-review per D-C5-1 = (a).

2. **D-C5-2 NEW (raised by Manual ESKF Solà 2017 closure 2026-05-08, Fact #88) — long-cruise-observability-strategy** — Standard EKF/ESKF fusion of IMU + visual measurements requires sufficient excitation (non-pure-rotation, non-zero acceleration) for IMU bias observability per Solà §5.1 reference + classical observability literature. For a fixed-wing UAV in cruise (level flight at ~60 km/h with minimal acceleration), bias drift is the dominant error source; periodic accelerations (turns, climbs, level-to-bank transitions) re-excite observability. Plan-phase decision-maker MUST choose between: **(a)** accept observability degradation in long-cruise segments + monitor via covariance growth + alert operator if covariance > threshold (RECOMMENDED — matches AC-1.3 cumulative drift monitoring + AC-1.4 covariance + source-label output contract; covariance growth alert is consistent with AC-NEW-8 blackout failsafe escalation thresholds), **(b)** require operator to perform synthetic S-turns periodically (~every 30 min) to maintain bias observability, **(c)** tighten bias-stationarity prior (lower IMU bias random-walk noise) at the cost of accepting more bias drift between updates. **Recommendation**: D-C5-2 = (a) accept + monitor. Mitigation = project's pinned mission profile per restrictions.md provides natural re-excitation via sharp turns up to ±20° bank per AC-3.1 + sharp-turn frames may share <5% overlap per AC-3.2. **GTSAM iSAM2 Fact #89 partially mitigates** via incremental smoothing's look-back refinement of bias estimates over the entire sliding window (vs Manual ESKF's recursive forward-time-only bias estimation).

3. **D-C5-3 NEW (raised by GTSAM iSAM2 closure 2026-05-08, Fact #89) — sliding-window-primitive-choice** — `IncrementalFixedLagSmoother` is in `gtsam_unstable` namespace (Source #91 documents the class but it requires opt-in to gtsam_unstable APIs; not in stable `gtsam` namespace). Plan-phase decision between: **(a)** `gtsam_unstable.IncrementalFixedLagSmoother` (canonical fixed-lag smoother with bounded memory; requires opt-in to gtsam_unstable namespace; ~30 minutes engineering — RECOMMENDED), **(b)** custom marginalization via `ISAM2.marginalizeLeaves(keys_to_marginalize)` (more flexible; ~2-3 days engineering), **(c)** accept unbounded ISAM2 graph growth (simplest; risk = memory growth over 8-hour flight if not periodically restarted; ~0 minutes engineering but tested at Jetson MVE phase — likely fails AC-4.2 budget at K_total = 3 fps × 8 hr × 3600 s/hr = 86400 keyframes × ~1 KB per keyframe state = ~86 MB raw + factor-graph overhead). **Recommendation**: D-C5-3 = (a) IncrementalFixedLagSmoother with K=10-20 keyframes covering ~3-7 s of recent history. Applies only if D-C5-row final lock includes GTSAM iSAM2.

4. **D-C5-4 NEW (raised by GTSAM iSAM2 closure 2026-05-08, Fact #89) — IMU-gap-handling-strategy** — `CombinedImuFactor` requires CONTIGUOUS IMU samples between keyframes per Source #90 canonical pattern; if IMU samples are dropped mid-flight (network jitter, MAVLink frame loss), `pim.preintMeasCov()` 9×9 covariance becomes optimistic vs reality. Plan-phase decision between: **(a)** accept canonical pattern + monitor + adaptive integration covariance inflation (RECOMMENDED — track `last_imu_timestamp` and inflate `params.setIntegrationCovariance` adaptively if gap > expected; ~1 day engineering), **(b)** restart PIM on detected gaps with conservative initial covariance (more aggressive; ~3-5 days engineering), **(c)** buffer IMU samples in a queue with explicit gap-fill via interpolation (most aggressive; ~1 week engineering). **Recommendation**: D-C5-4 = (a) accept + monitor + adaptive inflation. Project's pinned MAVLink IMU pipeline at ~100-200 Hz Pixhawk-class is delivered over UART or USB serial — dropped samples are rare. Applies only if D-C5-row final lock includes GTSAM iSAM2.

5. **D-C5-5 NEW (raised by GTSAM iSAM2 closure 2026-05-08, Fact #89) — factor-density-choice** — iSAM2 per-update latency depends critically on factor density per keyframe. Plan-phase decision between: **(a)** per-correspondence `GenericProjectionFactorCal3DS2` (highest fidelity; 1000+ factors per keyframe at K=10 image pairs × 100 inliers per pair; ~50-150 ms per update on Jetson Orin Nano Super CPU; tight AC-4.1 satisfaction); **(b)** smart-projection-pose-factor (canonical landmark-marginalization-at-construction-time; 1 factor per landmark per keyframe; ~10× speedup at minimal accuracy loss; ~5-15 ms per update on Jetson Orin Nano Super CPU); **(c)** `PriorFactorPose3` only with C4 GTSAM Marginals satellite-anchor 6×6 covariance — couples C4 Fact #54 D-C4-2 = (b) with C5 Fact #89 architectural integration via shared GTSAM substrate; ~1 factor per keyframe; ~2-5 ms per update on Jetson Orin Nano Super CPU; **CLEANEST cross-component coupling** but reduces C5 to "carry forward C4 anchor + IMU between anchors" without per-correspondence smoothing benefit. **Recommendation**: D-C5-5 = (c) for the GTSAM-as-shared-C4+C5-substrate hybrid path (project's recommended C5 architecture per Fact #89 closure); D-C5-5 = (b) for the C5-as-secondary-with-smoothing path if Plan-phase Jetson MVE shows (c) accuracy is insufficient at AC-1.1/1.2 tail. Applies only if D-C5-row final lock includes GTSAM iSAM2.

---
