feat(perception): complete E32 full replay
This commit is contained in:
@@ -0,0 +1,432 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from collections import Counter
|
||||
|
||||
import numpy as np
|
||||
import pytest
|
||||
|
||||
from k1link.compute.e32_track_geometry_replay import (
|
||||
E32TrackGeometryReplayError,
|
||||
_comparison_document,
|
||||
_CorrectionPlan,
|
||||
_require_exact_e29_reproduction,
|
||||
_translate_frame,
|
||||
)
|
||||
from k1link.compute.e32_track_geometry_storage import frame_from_record
|
||||
from k1link.compute.semantic_geometry_fusion import (
|
||||
CAMERA_GEOMETRY_FRAME_SCHEMA,
|
||||
_GeometryClusterSupport,
|
||||
_SemanticSupport,
|
||||
)
|
||||
from k1link.compute.sensor_representation import K1_LIO_PCL_CAPABILITIES
|
||||
from k1link.compute.track_geometry import (
|
||||
TrackGeometryCurrentness,
|
||||
TrackGeometryEvidenceState,
|
||||
TrackGeometryMetricBasis,
|
||||
TrackGeometrySourceBinding,
|
||||
)
|
||||
|
||||
|
||||
def _binding() -> TrackGeometrySourceBinding:
|
||||
return TrackGeometrySourceBinding(
|
||||
source_pack_id="e10-lidar-pack-" + "a" * 64,
|
||||
source_session_id="source-session",
|
||||
representation_profile_id=K1_LIO_PCL_CAPABILITIES.profile_id,
|
||||
e31_qualification_id="e31-source-qualification-" + "b" * 64,
|
||||
calibration_sha256="c" * 64,
|
||||
coordinate_frame="map",
|
||||
time_basis="nearest-host-arrival-best-effort",
|
||||
selected_offset_ms=0,
|
||||
)
|
||||
|
||||
|
||||
def _semantic(
|
||||
*,
|
||||
track_id: int,
|
||||
label: str,
|
||||
status: str,
|
||||
indices: list[int],
|
||||
bbox: list[float],
|
||||
current: bool = True,
|
||||
) -> _SemanticSupport:
|
||||
return _SemanticSupport(
|
||||
document={
|
||||
"source_track_id": track_id,
|
||||
"track_id": track_id,
|
||||
"label": label,
|
||||
"association_group": label,
|
||||
"score": 0.9,
|
||||
"bbox_xyxy": bbox,
|
||||
"semantic_current": current,
|
||||
"camera_motion_state": "unknown",
|
||||
"camera_motion_confidence": None,
|
||||
"motion_state": "unknown",
|
||||
"motion_status": "unknown",
|
||||
"unknown_is_occupied": True,
|
||||
"navigation_or_safety_accepted": False,
|
||||
"geometry_status": status,
|
||||
"geometry_reason": (
|
||||
"camera-semantic-with-connected-occupied-lidar-support"
|
||||
if status == "agree"
|
||||
else (
|
||||
"semantic-observation-not-current"
|
||||
if not current
|
||||
else "camera-semantic-without-qualified-occupied-lidar-support"
|
||||
)
|
||||
),
|
||||
"range_m": 4.0 if status == "agree" else None,
|
||||
"occupied_centroid_map_xyz_m": None,
|
||||
"occupied_height_range_m": None,
|
||||
"support": {
|
||||
"projected_points_in_bbox": len(indices),
|
||||
"classified_points_in_bbox": len(indices),
|
||||
"surface_points_in_bbox": 0,
|
||||
"occupied_points_in_bbox": len(indices),
|
||||
"below_surface_points_in_bbox": 0,
|
||||
"connected_occupied_points": len(indices),
|
||||
"connected_occupied_voxels": int(bool(indices)),
|
||||
},
|
||||
},
|
||||
occupied_source_indices=np.asarray(indices, dtype=np.int64),
|
||||
)
|
||||
|
||||
|
||||
def _geometry(indices: list[int], range_m: float) -> _GeometryClusterSupport:
|
||||
return _GeometryClusterSupport(
|
||||
document={
|
||||
"geometry_status": "single-source-geometry",
|
||||
"semantic_class": None,
|
||||
"point_count": len(indices),
|
||||
"voxel_count": 1,
|
||||
"centroid_map_xyz_m": [0.0, 0.0, 0.0],
|
||||
"bounds_map_xyz_m": [[0.0, 0.0, 0.0], [1.0, 1.0, 1.0]],
|
||||
"height_range_m": [0.2, 1.0],
|
||||
"nearest_range_m": range_m,
|
||||
"unknown_is_occupied": True,
|
||||
"navigation_or_safety_accepted": False,
|
||||
},
|
||||
occupied_source_indices=np.asarray(indices, dtype=np.int64),
|
||||
)
|
||||
|
||||
|
||||
def test_e32_translation_applies_only_bound_corrections_and_closes_point_ownership() -> None:
|
||||
points = np.asarray(
|
||||
[[float(index), 0.0, 1.0] for index in range(8)],
|
||||
dtype=np.float64,
|
||||
)
|
||||
semantic_supports = (
|
||||
_semantic(
|
||||
track_id=7,
|
||||
label="car",
|
||||
status="agree",
|
||||
indices=[0, 1],
|
||||
bbox=[10.0, 10.0, 100.0, 100.0],
|
||||
),
|
||||
_semantic(
|
||||
track_id=8,
|
||||
label="person",
|
||||
status="single-source-camera",
|
||||
indices=[2],
|
||||
bbox=[300.0, 500.0, 340.0, 580.0],
|
||||
),
|
||||
_semantic(
|
||||
track_id=9,
|
||||
label="car",
|
||||
status="unknown",
|
||||
indices=[],
|
||||
bbox=[200.0, 100.0, 250.0, 150.0],
|
||||
current=False,
|
||||
),
|
||||
)
|
||||
geometry_supports = (
|
||||
_geometry([3, 4], 3.0),
|
||||
_geometry([5], 4.0),
|
||||
_geometry([6, 7], 5.0),
|
||||
)
|
||||
corrections = _CorrectionPlan(
|
||||
semantic_rectangle_normalized_xyxy=(0.30, 0.75, 0.50, 1.0),
|
||||
semantic_class_allowlist=frozenset({"person"}),
|
||||
image_width=800,
|
||||
image_height=600,
|
||||
exact_geometry_corrections={(12, 0): "e30-review-item-" + "d" * 64},
|
||||
human_geometry_dispositions={
|
||||
(12, 1): ("background-or-noise", "e30-review-item-" + "e" * 64),
|
||||
(12, 2): ("object-present", "e30-review-item-" + "f" * 64),
|
||||
},
|
||||
)
|
||||
|
||||
translated = _translate_frame(
|
||||
frame_index=12,
|
||||
source_frame_index=120,
|
||||
session_seconds=42.0,
|
||||
source_available=True,
|
||||
frame_points=points,
|
||||
semantic_supports=semantic_supports,
|
||||
geometry_supports=geometry_supports,
|
||||
binding=_binding(),
|
||||
corrections=corrections,
|
||||
last_current_frame={},
|
||||
)
|
||||
|
||||
frame = translated.frame
|
||||
assert [geometry.owner_key for geometry in frame.geometries] == [
|
||||
"track:7",
|
||||
"geometry:2",
|
||||
]
|
||||
assert frame.point_slab.owner_keys == ("track:7", "geometry:2")
|
||||
assert frame.point_slab.source_indices.tolist() == [0, 1, 6, 7]
|
||||
assert frame.point_slab.owner_indices.tolist() == [0, 0, 1, 1]
|
||||
assert frame.geometries[1].reason_codes == (
|
||||
"e29-unassociated-occupied-component",
|
||||
"a3-human-object-present",
|
||||
)
|
||||
assert translated.semantic_published == 1
|
||||
assert translated.semantic_masked == 1
|
||||
assert translated.semantic_unpublishable_held == 1
|
||||
assert translated.geometry_published == 1
|
||||
assert translated.geometry_exact_excluded == 1
|
||||
assert translated.geometry_human_excluded == 1
|
||||
assert translated.baseline_qualified_points == 7
|
||||
assert translated.published_qualified_points == 4
|
||||
assert translated.excluded_qualified_points == 3
|
||||
assert translated.ownership_overlap_claims == 0
|
||||
assert translated.unqualified_semantic_support_points == 1
|
||||
assert [change["reason"] for change in translated.changes] == [
|
||||
"e31-semantic-self-mask",
|
||||
"held-without-prior-current-provenance",
|
||||
"e31-exact-geometry-correction",
|
||||
"a3-human-background-or-noise",
|
||||
]
|
||||
restored = frame_from_record(
|
||||
record_value=translated.record,
|
||||
binding=_binding(),
|
||||
frame_offsets=np.asarray([0] * 13 + [4], dtype="<i8"),
|
||||
source_indices=translated.point_source_indices,
|
||||
points=translated.point_coordinates,
|
||||
owner_indices=translated.point_owner_indices,
|
||||
)
|
||||
assert restored.to_dict() == translated.frame.to_dict()
|
||||
|
||||
|
||||
def test_e32_held_track_keeps_prior_current_provenance_without_current_points() -> None:
|
||||
held = _semantic(
|
||||
track_id=11,
|
||||
label="truck",
|
||||
status="unknown",
|
||||
indices=[],
|
||||
bbox=[20.0, 20.0, 60.0, 60.0],
|
||||
current=False,
|
||||
)
|
||||
translated = _translate_frame(
|
||||
frame_index=15,
|
||||
source_frame_index=150,
|
||||
session_seconds=45.0,
|
||||
source_available=False,
|
||||
frame_points=np.empty((0, 3), dtype=np.float64),
|
||||
semantic_supports=(held,),
|
||||
geometry_supports=(),
|
||||
binding=_binding(),
|
||||
corrections=_CorrectionPlan(
|
||||
semantic_rectangle_normalized_xyxy=(0.30, 0.75, 0.50, 1.0),
|
||||
semantic_class_allowlist=frozenset({"person"}),
|
||||
image_width=800,
|
||||
image_height=600,
|
||||
exact_geometry_corrections={},
|
||||
human_geometry_dispositions={},
|
||||
),
|
||||
last_current_frame={11: 13},
|
||||
)
|
||||
|
||||
geometry = translated.frame.geometries[0]
|
||||
assert geometry.currentness is TrackGeometryCurrentness.HELD
|
||||
assert geometry.evidence_state is TrackGeometryEvidenceState.UNKNOWN
|
||||
assert geometry.metric_basis is TrackGeometryMetricBasis.UNAVAILABLE
|
||||
assert geometry.held_from_frame_index == 13
|
||||
assert translated.frame.point_slab.row_count == 0
|
||||
|
||||
|
||||
def test_e32_arbitrates_overlapping_camera_claims_without_duplicate_points() -> None:
|
||||
larger = _semantic(
|
||||
track_id=20,
|
||||
label="car",
|
||||
status="agree",
|
||||
indices=[0, 1],
|
||||
bbox=[10.0, 10.0, 100.0, 100.0],
|
||||
)
|
||||
smaller = _semantic(
|
||||
track_id=21,
|
||||
label="person",
|
||||
status="agree",
|
||||
indices=[0, 1],
|
||||
bbox=[20.0, 20.0, 40.0, 70.0],
|
||||
)
|
||||
translated = _translate_frame(
|
||||
frame_index=20,
|
||||
source_frame_index=200,
|
||||
session_seconds=50.0,
|
||||
source_available=True,
|
||||
frame_points=np.asarray(
|
||||
[[1.0, 0.0, 1.0], [2.0, 0.0, 1.0]],
|
||||
dtype=np.float64,
|
||||
),
|
||||
semantic_supports=(larger, smaller),
|
||||
geometry_supports=(),
|
||||
binding=_binding(),
|
||||
corrections=_CorrectionPlan(
|
||||
semantic_rectangle_normalized_xyxy=(0.30, 0.75, 0.50, 1.0),
|
||||
semantic_class_allowlist=frozenset({"person"}),
|
||||
image_width=800,
|
||||
image_height=600,
|
||||
exact_geometry_corrections={},
|
||||
human_geometry_dispositions={},
|
||||
),
|
||||
last_current_frame={},
|
||||
)
|
||||
|
||||
assert translated.frame.point_slab.source_indices.tolist() == [0, 1]
|
||||
assert translated.frame.point_slab.owner_keys == ("track:21",)
|
||||
assert translated.frame.geometries[0].evidence_state is TrackGeometryEvidenceState.UNKNOWN
|
||||
assert translated.frame.geometries[0].reason_codes[-1] == (
|
||||
"e32-point-ownership-collision"
|
||||
)
|
||||
assert translated.frame.geometries[1].evidence_state is TrackGeometryEvidenceState.AGREE
|
||||
assert translated.baseline_qualified_points == 4
|
||||
assert translated.published_qualified_points == 2
|
||||
assert translated.ownership_overlap_claims == 2
|
||||
assert translated.excluded_qualified_points == 0
|
||||
assert translated.changes[0]["reason"] == "point-ownership-arbitration"
|
||||
|
||||
|
||||
def test_e32_withholds_unqualified_e29_range_and_retains_camera_state() -> None:
|
||||
camera_only = _semantic(
|
||||
track_id=30,
|
||||
label="car",
|
||||
status="single-source-camera",
|
||||
indices=[0],
|
||||
bbox=[10.0, 10.0, 100.0, 100.0],
|
||||
)
|
||||
camera_only.document["range_m"] = 6.0
|
||||
translated = _translate_frame(
|
||||
frame_index=30,
|
||||
source_frame_index=300,
|
||||
session_seconds=60.0,
|
||||
source_available=True,
|
||||
frame_points=np.asarray([[1.0, 0.0, 1.0]], dtype=np.float64),
|
||||
semantic_supports=(camera_only,),
|
||||
geometry_supports=(),
|
||||
binding=_binding(),
|
||||
corrections=_CorrectionPlan(
|
||||
semantic_rectangle_normalized_xyxy=(0.30, 0.75, 0.50, 1.0),
|
||||
semantic_class_allowlist=frozenset({"person"}),
|
||||
image_width=800,
|
||||
image_height=600,
|
||||
exact_geometry_corrections={},
|
||||
human_geometry_dispositions={},
|
||||
),
|
||||
last_current_frame={},
|
||||
)
|
||||
|
||||
geometry = translated.frame.geometries[0]
|
||||
assert geometry.evidence_state is TrackGeometryEvidenceState.CAMERA_ONLY
|
||||
assert geometry.metric_basis is TrackGeometryMetricBasis.UNAVAILABLE
|
||||
assert geometry.range_m is None
|
||||
assert geometry.reason_codes[-1] == "e32-unqualified-range-withheld"
|
||||
assert translated.unqualified_ranges_withheld == 1
|
||||
assert translated.changes[0]["reason"] == "unqualified-range-withheld"
|
||||
|
||||
|
||||
def test_e32_replay_rejects_any_e29_reproduction_drift() -> None:
|
||||
semantic = _semantic(
|
||||
track_id=1,
|
||||
label="car",
|
||||
status="single-source-camera",
|
||||
indices=[],
|
||||
bbox=[10.0, 10.0, 20.0, 20.0],
|
||||
)
|
||||
fusion_frame = {
|
||||
"source_frame_index": 10,
|
||||
"session_seconds": 3.0,
|
||||
}
|
||||
baseline = {
|
||||
"schema_version": CAMERA_GEOMETRY_FRAME_SCHEMA,
|
||||
"frame_index": 0,
|
||||
"source_frame_index": 10,
|
||||
"session_seconds": 3.0,
|
||||
"source_available": False,
|
||||
"local_surface_valid": False,
|
||||
"semantic_observations": [semantic.document],
|
||||
"geometry_only_occupied": [],
|
||||
"policy": {
|
||||
"camera_owns_semantics": True,
|
||||
"lidar_owns_metric_geometry": True,
|
||||
"absence_of_points_means_free": False,
|
||||
"unknown_is_occupied": True,
|
||||
},
|
||||
"authority": {
|
||||
"commands_enabled": False,
|
||||
"navigation_or_safety_accepted": False,
|
||||
},
|
||||
}
|
||||
_require_exact_e29_reproduction(
|
||||
e29_frame=baseline,
|
||||
frame_index=0,
|
||||
fusion_frame=fusion_frame,
|
||||
source_available=False,
|
||||
surface_valid=False,
|
||||
semantic_supports=(semantic,),
|
||||
geometry_supports=(),
|
||||
)
|
||||
baseline["semantic_observations"] = []
|
||||
with pytest.raises(E32TrackGeometryReplayError, match="exactly reproduce"):
|
||||
_require_exact_e29_reproduction(
|
||||
e29_frame=baseline,
|
||||
frame_index=0,
|
||||
fusion_frame=fusion_frame,
|
||||
source_available=False,
|
||||
surface_valid=False,
|
||||
semantic_supports=(semantic,),
|
||||
geometry_supports=(),
|
||||
)
|
||||
|
||||
|
||||
def test_e32_comparison_exposes_status_class_range_scene_and_cause_deltas() -> None:
|
||||
baseline = {
|
||||
(
|
||||
"agree",
|
||||
"car",
|
||||
"middle",
|
||||
"000-060s",
|
||||
"connected-support",
|
||||
): 2,
|
||||
(
|
||||
"single-source-geometry",
|
||||
"__geometry__",
|
||||
"near",
|
||||
"000-060s",
|
||||
"unassociated",
|
||||
): 1,
|
||||
}
|
||||
current = {
|
||||
(
|
||||
"agree",
|
||||
"car",
|
||||
"middle",
|
||||
"000-060s",
|
||||
"connected-support",
|
||||
): 1,
|
||||
}
|
||||
|
||||
comparison = _comparison_document(
|
||||
Counter(baseline),
|
||||
Counter(current),
|
||||
)
|
||||
|
||||
assert comparison["by_status"]["agree"] == {
|
||||
"e29": 2,
|
||||
"e32": 1,
|
||||
"delta": -1,
|
||||
}
|
||||
assert comparison["by_class"]["__geometry__"]["delta"] == -1
|
||||
assert comparison["by_range"]["near"]["delta"] == -1
|
||||
assert comparison["by_scene"]["000-060s"]["delta"] == -2
|
||||
assert comparison["by_cause"]["unassociated"]["delta"] == -1
|
||||
Reference in New Issue
Block a user