[AZ-334] C1 KLT/RANSAC strategy — engine-rule simple-baseline VIO

Implement KltRansacStrategy, the ADR-002 engine-rule mandatory
simple-baseline VioStrategy for E-C1. Pure-Python facade over
OpenCV's cv2.goodFeaturesToTrack / calcOpticalFlowPyrLK /
findEssentialMat / recoverPose pipeline — no C++/pybind11 binding
by design so a Tier-0 workstation runs the strategy with
`pip install opencv-python` and the BUILD_KLT_RANSAC=ON gate alone.
Constructor + state machine + FDR transition spine mirror
Okvis2Strategy + VinsMonoStrategy so the AZ-331 factory + IT-12
comparative harness treat all three as drop-in substitutable; the
duplication is the consolidation target now formally in scope for
the next cumulative review (batches 52-54).

AC coverage: AC-1..AC-11 + NFR-perf mapped to passing tests
(25 tests, 23 pass + 2 tier-2 skipped on dev/CI runners; all 25
pass under GPS_DENIED_TIER=2). Honest-covariance invariant (AC-9)
implemented as residual-scatter / (N_inliers - 5) with an inlier-
count penalty — no client-side floor or smoother; cov Frobenius
grows monotonically across DEGRADED. Camera-agnostic source
(AC-11) enforced by CI-grep gate that excludes docstring text.

Test-Run Cadence: focused suite tests/unit/c1_vio/ green (95 passed,
6 skipped); config-loader + compose-root suites green; full-suite
gate deferred to Step 16 per implement skill.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Oleksandr Bezdieniezhnykh
2026-05-14 02:40:01 +03:00
parent 4815dd6aa1
commit ceb24b5a62
10 changed files with 2371 additions and 14 deletions
+30 -11
View File
@@ -250,13 +250,21 @@ def test_ac5_build_vio_strategy_flag_off_no_import(
# Which strategies still have NO concrete Python module on disk?
# Once an AZ-332 / AZ-333 / AZ-334 implementation lands, the
# `flag_on_but_module_missing` semantic shifts: the factory's import
# succeeds, the constructor fails on missing native binding or other
# prerequisite. We assert the meaningful-error-before-first-frame
# property holds for BOTH cases — the exception class differs by
# strategy.
_STRATEGIES_WITHOUT_PY_MODULE: tuple[str, ...] = ("klt_ransac",)
# All three strategies (AZ-332 / AZ-333 / AZ-334) have landed; tuple
# remains as a tombstone for git-blame archaeology of the build-time
# gating evolution. Once removed, the parametrisation below collapses
# to two branches (native-binding vs pure-Python).
_STRATEGIES_WITHOUT_PY_MODULE: tuple[str, ...] = ()
# Strategies whose concrete implementation has NO native binding —
# the AZ-334 KLT/RANSAC simple-baseline is pure-Python over OpenCV.
# When ``BUILD_KLT_RANSAC=ON`` and the module is on disk, the
# constructor succeeds end-to-end (no native ``.so`` to be missing).
# The AC-5 spirit (meaningful error before first frame) is still
# satisfied: the only way construction fails for klt_ransac is the
# ``BUILD_*=OFF`` path which is already covered by
# :func:`test_ac5_build_vio_strategy_flag_off_no_import`.
_STRATEGIES_WITHOUT_NATIVE_BINDING: tuple[str, ...] = ("klt_ransac",)
@pytest.mark.parametrize("strategy", sorted(_STRATEGY_MODULES))
@@ -272,11 +280,22 @@ def test_ac5_build_vio_strategy_flag_on_but_module_missing(
with pytest.raises(StrategyNotAvailableError) as exc_info:
build_vio_strategy(config, fdr_client=object())
assert strategy in str(exc_info.value)
elif strategy in _STRATEGIES_WITHOUT_NATIVE_BINDING:
# Module IS implemented AND has no native binding (AZ-334
# KLT/RANSAC). Constructor succeeds without raising; the
# only failure mode the AC-5 test guards against does not
# apply to a pure-Python strategy. We assert the construction
# produces a real :class:`VioStrategy` instance to keep the
# test branch non-trivial.
instance = build_vio_strategy(config, fdr_client=object())
assert isinstance(instance, VioStrategy)
assert instance.current_strategy_label() == strategy
else:
# Module IS implemented (AZ-332). Factory import succeeds, then
# the strategy constructor fails on missing native binding —
# which the strategy MUST surface as VioFatalError BEFORE any
# frame is processed (the AC-5 spirit: no silent fall-through).
# Module IS implemented (AZ-332 / AZ-333). Factory import
# succeeds, then the strategy constructor fails on missing
# native binding — which the strategy MUST surface as
# VioFatalError BEFORE any frame is processed (the AC-5
# spirit: no silent fall-through).
with pytest.raises(VioFatalError) as exc_info:
build_vio_strategy(config, fdr_client=object())
assert "native binding" in str(exc_info.value)