feat(perception): add full camera-first shadow
This commit is contained in:
@@ -0,0 +1,96 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
|
||||
from k1link.compute.e53_camera_first_shadow import (
|
||||
_Profile,
|
||||
adjacent_family_matches,
|
||||
select_candidate_detections,
|
||||
)
|
||||
|
||||
|
||||
def _profile() -> _Profile:
|
||||
return _Profile(
|
||||
raw={},
|
||||
expected_source_pack_id="source",
|
||||
expected_local_surface_id="surface",
|
||||
expected_detector_result_id="detector",
|
||||
expected_baseline_e29_id="baseline",
|
||||
target_labels=frozenset({"person", "car", "truck"}),
|
||||
label_groups={
|
||||
"person": ("person",),
|
||||
"vehicle": ("car", "truck"),
|
||||
},
|
||||
minimum_detector_score=0.5,
|
||||
maximum_bbox_image_fraction=0.25,
|
||||
adjacent_family_iou=0.25,
|
||||
baseline_family_iou=0.25,
|
||||
maximum_latency_p95_ms=50.0,
|
||||
maximum_rss_growth_mib=512.0,
|
||||
)
|
||||
|
||||
|
||||
def test_candidate_filter_keeps_camera_semantics_and_rejects_large_box() -> None:
|
||||
selected, counts = select_candidate_detections(
|
||||
[
|
||||
{
|
||||
"instance_id": 1,
|
||||
"label": "person",
|
||||
"score": 0.99,
|
||||
"box_xyxy": [100.0, 100.0, 180.0, 300.0],
|
||||
"mask_pixels": 4000,
|
||||
},
|
||||
{
|
||||
"instance_id": 2,
|
||||
"label": "car",
|
||||
"score": 0.95,
|
||||
"box_xyxy": [0.0, 0.0, 800.0, 600.0],
|
||||
"mask_pixels": 480000,
|
||||
},
|
||||
{
|
||||
"instance_id": 3,
|
||||
"label": "laptop",
|
||||
"score": 0.98,
|
||||
"box_xyxy": [10.0, 10.0, 100.0, 100.0],
|
||||
},
|
||||
],
|
||||
width=800,
|
||||
height=600,
|
||||
profile=_profile(),
|
||||
)
|
||||
|
||||
assert len(selected) == 1
|
||||
assert selected[0]["label"] == "person"
|
||||
assert selected[0]["association_group"] == "person"
|
||||
assert selected[0]["cuboid_status"] == "camera-candidate-no-cuboid"
|
||||
assert counts["pathological_large_box"] == 1
|
||||
assert counts["non_target"] == 1
|
||||
|
||||
|
||||
def test_adjacent_matching_is_family_aware_and_one_to_one() -> None:
|
||||
previous: list[dict[str, Any]] = [
|
||||
{
|
||||
"association_group": "vehicle",
|
||||
"bbox_xyxy": [10.0, 10.0, 110.0, 110.0],
|
||||
},
|
||||
{
|
||||
"association_group": "person",
|
||||
"bbox_xyxy": [200.0, 20.0, 240.0, 120.0],
|
||||
},
|
||||
]
|
||||
current: list[dict[str, Any]] = [
|
||||
{
|
||||
"association_group": "vehicle",
|
||||
"bbox_xyxy": [12.0, 12.0, 112.0, 112.0],
|
||||
},
|
||||
{
|
||||
"association_group": "vehicle",
|
||||
"bbox_xyxy": [14.0, 14.0, 114.0, 114.0],
|
||||
},
|
||||
{
|
||||
"association_group": "person",
|
||||
"bbox_xyxy": [202.0, 22.0, 242.0, 122.0],
|
||||
},
|
||||
]
|
||||
|
||||
assert adjacent_family_matches(previous, current, minimum_iou=0.25) == 2
|
||||
@@ -0,0 +1,95 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import pytest
|
||||
|
||||
from k1link.compute.rig_geometry import (
|
||||
RIG_GEOMETRY_SCHEMA,
|
||||
RigGeometryError,
|
||||
parse_rig_geometry,
|
||||
)
|
||||
|
||||
|
||||
def _unbound() -> dict[str, object]:
|
||||
return {
|
||||
"schema_version": RIG_GEOMETRY_SCHEMA,
|
||||
"profile_id": "portable-k1/unbound-v1",
|
||||
"rig_kind": "portable",
|
||||
"qualification": {
|
||||
"state": "unbound",
|
||||
"reason": "no measured mount",
|
||||
"evidence_sha256": [],
|
||||
},
|
||||
"coordinate_frames": {
|
||||
"lidar_frame": "k1-lidar",
|
||||
"body_frame": None,
|
||||
"body_from_lidar": None,
|
||||
},
|
||||
"vehicle_body": None,
|
||||
"authority": {
|
||||
"commands_enabled": False,
|
||||
"navigation_or_safety_accepted": False,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
def test_unbound_portable_rig_fails_closed_without_inventing_geometry() -> None:
|
||||
geometry = parse_rig_geometry(_unbound())
|
||||
|
||||
assert geometry.metric_body_geometry_available is False
|
||||
assert geometry.collision_geometry_qualified is False
|
||||
assert geometry.collision_contract()["state"] == "unavailable"
|
||||
assert geometry.collision_contract()["recent_collision_publishable"] is False
|
||||
|
||||
|
||||
def test_unbound_rig_rejects_hidden_physical_values() -> None:
|
||||
value = _unbound()
|
||||
value["coordinate_frames"] = {
|
||||
"lidar_frame": "k1-lidar",
|
||||
"body_frame": "vehicle-body",
|
||||
"body_from_lidar": None,
|
||||
}
|
||||
|
||||
with pytest.raises(RigGeometryError, match="must not contain physical values"):
|
||||
parse_rig_geometry(value)
|
||||
|
||||
|
||||
def test_measured_mount_does_not_grant_collision_authority() -> None:
|
||||
value = _unbound()
|
||||
value.update(
|
||||
{
|
||||
"profile_id": "measured-rig/v1",
|
||||
"rig_kind": "vehicle-mounted",
|
||||
"qualification": {
|
||||
"state": "measured",
|
||||
"reason": "bench measurement only",
|
||||
"evidence_sha256": ["a" * 64],
|
||||
"uncertainty": {
|
||||
"translation_1sigma_m": 0.01,
|
||||
"rotation_1sigma_deg": 0.2,
|
||||
"body_dimension_1sigma_m": 0.01,
|
||||
},
|
||||
},
|
||||
"coordinate_frames": {
|
||||
"lidar_frame": "k1-lidar",
|
||||
"body_frame": "vehicle-body",
|
||||
"body_from_lidar": {
|
||||
"from_frame": "k1-lidar",
|
||||
"to_frame": "vehicle-body",
|
||||
"translation_m": [0.0, 0.0, 1.0],
|
||||
"quaternion_xyzw": [0.0, 0.0, 0.0, 1.0],
|
||||
},
|
||||
},
|
||||
"vehicle_body": {
|
||||
"frame": "vehicle-body",
|
||||
"shape": "axis-aligned-box",
|
||||
"minimum_xyz_m": [-1.0, -0.5, -0.2],
|
||||
"maximum_xyz_m": [1.0, 0.5, 1.2],
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
geometry = parse_rig_geometry(value)
|
||||
|
||||
assert geometry.metric_body_geometry_available is True
|
||||
assert geometry.collision_geometry_qualified is False
|
||||
assert geometry.collision_contract()["state"] == "unavailable"
|
||||
Reference in New Issue
Block a user