[AZ-776] Open-loop ESKF composition profile via c4_pose.enabled

ADR-012: add c4_pose.enabled (default True) and enforce the
(c4_pose.enabled, c5_state.strategy) 2x2 pairing matrix at compose
time. When enabled=false, compose_root removes c4_pose from the
selection map and build_pre_constructed omits c5_isam2_graph_handle.
Replay protocol Invariant 13 owns the gate. Tier-2 conftest YAML
writes the open-loop profile; un-xfails AC-1/2/5 and both AC-6
variants in Derkachi (AC-3 stays xfailed for AZ-777). 319/319
runtime_root + c4_pose + c5_state tests green.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Oleksandr Bezdieniezhnykh
2026-05-21 13:40:01 +03:00
parent 6044a33197
commit 8de2716500
10 changed files with 687 additions and 83 deletions
@@ -27,6 +27,16 @@ class C4PoseConfig:
Fields per the C4 contract §"Config-load-time validation":
* ``enabled`` — AZ-776 composition-graph flag. When ``False`` the
composition root strips ``c4_pose`` from the airborne component
graph entirely (open-loop ESKF profile per ADR-012). Default
``True`` preserves the full GTSAM pipeline that ADR-003 mandates
as the steady-state airborne path. Forbidden pairings (rejected
by ``compose_root`` with :class:`CompositionError`):
``enabled=False`` + ``c5_state.strategy="gtsam_isam2"`` (iSAM2
requires a C4 anchor); ``enabled=True`` +
``c5_state.strategy="eskf"`` (ESKF has no iSAM2 graph for C4 to
anchor against).
* ``strategy`` — selects the concrete estimator. Currently only
``"opencv_gtsam"`` is defined.
* ``ransac_iterations`` — OpenCV ``solvePnPRansac`` iteration
@@ -56,6 +66,7 @@ class C4PoseConfig:
handling would land in a future config extension).
"""
enabled: bool = True
strategy: str = "opencv_gtsam"
ransac_iterations: int = 200
ransac_reprojection_threshold_px: float = 4.0