mirror of
https://github.com/azaion/gps-denied-onboard.git
synced 2026-06-22 12:51:12 +00:00
[AZ-240] [AZ-241] [AZ-242] Add native retrieval remediation
Implement the product remediation paths required before greenfield code testability revision: native VIO backend selection, local VPR descriptor index retrieval, and computed anchor matching gates. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
from anchor_verification import AnchorFrame, GeometryGatedAnchorVerifier, MatchEvidence
|
||||
from anchor_verification import AnchorFrame, CandidateTile, GeometryGatedAnchorVerifier, MatchEvidence
|
||||
from shared.contracts import VprCandidate
|
||||
|
||||
|
||||
@@ -26,6 +26,29 @@ def _evidence(**overrides: object) -> MatchEvidence:
|
||||
return MatchEvidence.model_validate(payload)
|
||||
|
||||
|
||||
def _frame_with_keypoints() -> AnchorFrame:
|
||||
keypoints = tuple((float(x * 10), float(y * 10)) for x in range(5) for y in range(5))
|
||||
return AnchorFrame(
|
||||
frame_id="frame-1",
|
||||
image_ref="replay/frame-1.jpg",
|
||||
keypoints=keypoints,
|
||||
)
|
||||
|
||||
|
||||
def _tile_with_keypoints(**overrides: object) -> CandidateTile:
|
||||
keypoints = tuple(
|
||||
(float(x * 10 + 2), float(y * 10 + 3)) for x in range(5) for y in range(5)
|
||||
)
|
||||
payload: dict[str, object] = {
|
||||
"candidate": _candidate(),
|
||||
"image_ref": "cache/tile-1.tif",
|
||||
"keypoints": keypoints,
|
||||
"provenance_trusted": True,
|
||||
}
|
||||
payload.update(overrides)
|
||||
return CandidateTile.model_validate(payload)
|
||||
|
||||
|
||||
def test_candidate_verification_emits_acceptance_evidence() -> None:
|
||||
# Arrange
|
||||
verifier = GeometryGatedAnchorVerifier()
|
||||
@@ -42,6 +65,25 @@ def test_candidate_verification_emits_acceptance_evidence() -> None:
|
||||
assert result.homography == {"h00": 1.0, "h11": 1.0, "h22": 1.0}
|
||||
|
||||
|
||||
def test_matching_path_computes_evidence_from_frame_and_tile_inputs() -> None:
|
||||
# Arrange
|
||||
verifier = GeometryGatedAnchorVerifier()
|
||||
frame = _frame_with_keypoints()
|
||||
tile = _tile_with_keypoints()
|
||||
|
||||
# Act
|
||||
result = verifier.verify_candidate(frame, tile, matcher_profile="sift_orb")
|
||||
|
||||
# Assert
|
||||
assert result.decision.accepted is True
|
||||
assert result.decision.inliers == 25
|
||||
assert result.reason == "accepted_geometry"
|
||||
assert result.matcher_profile == "sift_orb"
|
||||
assert result.homography is not None
|
||||
assert result.homography["h02"] == 2.0
|
||||
assert result.homography["h12"] == 3.0
|
||||
|
||||
|
||||
def test_unsafe_candidate_is_rejected_with_reason() -> None:
|
||||
# Arrange
|
||||
verifier = GeometryGatedAnchorVerifier()
|
||||
@@ -62,6 +104,23 @@ def test_unsafe_candidate_is_rejected_with_reason() -> None:
|
||||
assert result.reason == "stale_or_untrusted_provenance"
|
||||
|
||||
|
||||
def test_computed_matching_rejects_low_inlier_geometry() -> None:
|
||||
# Arrange
|
||||
verifier = GeometryGatedAnchorVerifier()
|
||||
frame = _frame_with_keypoints()
|
||||
tile = _tile_with_keypoints(
|
||||
keypoints=((100.0, 100.0), (12.0, 3.0), (99.0, 88.0), (50.0, 40.0), (6.0, 9.0))
|
||||
)
|
||||
|
||||
# Act
|
||||
result = verifier.verify_candidate(frame, tile, matcher_profile="sift_orb")
|
||||
|
||||
# Assert
|
||||
assert result.decision.accepted is False
|
||||
assert result.reason == "low_inliers"
|
||||
assert result.decision.rejection_reason == "low_inliers"
|
||||
|
||||
|
||||
def test_matcher_benchmark_reports_profile_runtime_and_quality_metrics() -> None:
|
||||
# Arrange
|
||||
verifier = GeometryGatedAnchorVerifier()
|
||||
@@ -85,3 +144,27 @@ def test_matcher_benchmark_reports_profile_runtime_and_quality_metrics() -> None
|
||||
assert report.results[0].runtime_ms == 72.5
|
||||
assert report.results[1].accepted is False
|
||||
assert report.results[1].reason == "low_inliers"
|
||||
|
||||
|
||||
def test_matcher_benchmark_can_run_computed_paths() -> None:
|
||||
# Arrange
|
||||
verifier = GeometryGatedAnchorVerifier()
|
||||
frame = _frame_with_keypoints()
|
||||
|
||||
# Act
|
||||
report = verifier.benchmark_candidates(
|
||||
frame,
|
||||
(
|
||||
_tile_with_keypoints(),
|
||||
_tile_with_keypoints(
|
||||
keypoints=((2.0, 3.0), (2.0, 13.0), (2.0, 23.0), (2.0, 33.0), (2.0, 43.0))
|
||||
),
|
||||
),
|
||||
matcher_profile="sift_orb",
|
||||
)
|
||||
|
||||
# Assert
|
||||
assert report.results[0].accepted is True
|
||||
assert report.results[0].runtime_ms >= 0.0
|
||||
assert report.results[1].accepted is False
|
||||
assert report.results[1].reason == "low_inliers"
|
||||
|
||||
Reference in New Issue
Block a user