refactor(lab): restore canonical RAV004 replay

This commit is contained in:
DCCONSTRUCTIONS
2026-08-30 01:22:44 +03:00
parent 74da6437e9
commit f1cbe0061a
21 changed files with 1181 additions and 719 deletions
+59 -1
View File
@@ -8,6 +8,8 @@ from k1link.sessions.canonical_lab_spatial import (
_TimedPoses,
_bounded_local_slam,
_estimate_sensor_height,
_estimate_local_sensor_height,
_gravity_stable_basis_map_from_body,
_ground_origin_map,
)
@@ -57,7 +59,7 @@ def test_local_slam_accumulates_source_increments_in_ground_body_frame() -> None
),
)
basis = np.eye(3)
ground_origin = _ground_origin_map(np.asarray([0.0, 0.0, 0.0]), basis, 0.32)
ground_origin = _ground_origin_map(np.asarray([0.0, 0.0, 0.0]), 0.32)
local, frame_count, source_count = _bounded_local_slam(
points,
@@ -69,3 +71,59 @@ def test_local_slam_accumulates_source_increments_in_ground_body_frame() -> None
assert frame_count == 3
assert source_count == 3
assert local[:, 2].tolist() == pytest.approx([0.0, 0.0, 0.0], abs=1e-6)
def test_gravity_stable_body_frame_converts_rfu_to_forward_left_up() -> None:
times = (0, 1_000_000_000, 2_000_000_000)
poses = _TimedPoses(
times_ns=times,
translations=(
np.asarray([0.0, 0.0, 0.4]),
np.asarray([0.0, 1.0, 0.5]),
np.asarray([0.0, 2.0, 0.3]),
),
quaternions_xyzw=tuple(
np.asarray([0.25, 0.0, 0.0, np.sqrt(1.0 - 0.25**2)]) for _ in times
),
)
basis, source = _gravity_stable_basis_map_from_body(poses, 1_000_000_000)
assert source == "smoothed-pose-trajectory-tangent"
assert basis[:, 0].tolist() == pytest.approx([0.0, 1.0, 0.0], abs=1e-7)
assert basis[:, 1].tolist() == pytest.approx([-1.0, 0.0, 0.0], abs=1e-7)
assert basis[:, 2].tolist() == pytest.approx([0.0, 0.0, 1.0], abs=1e-7)
assert np.linalg.det(basis) == pytest.approx(1.0, abs=1e-7)
def test_ground_origin_is_projected_only_along_map_gravity() -> None:
origin = _ground_origin_map(np.asarray([4.0, -2.0, 1.25]), 0.32)
assert origin.tolist() == pytest.approx([4.0, -2.0, 0.93], abs=1e-9)
def test_sensor_height_tracks_current_source_window_instead_of_fixed_mount() -> None:
times = tuple(index * 500_000_000 for index in range(8))
points = _TimedPoints(
times_ns=times,
values=tuple(
_calibration_cloud(0.18 if index < 4 else 1.05, index)
for index in range(8)
),
)
poses = _TimedPoses(
times_ns=times,
translations=tuple(np.zeros(3) for _ in times),
quaternions_xyzw=tuple(np.asarray([0.0, 0.0, 0.0, 1.0]) for _ in times),
)
low, low_samples, _, low_source = _estimate_local_sensor_height(
points, poses, 500_000_000, 0.5,
)
high, high_samples, _, high_source = _estimate_local_sensor_height(
points, poses, 3_000_000_000, 0.5,
)
assert low == pytest.approx(0.18, abs=0.03)
assert high == pytest.approx(1.05, abs=0.03)
assert low_samples >= 3 and high_samples >= 3
assert low_source == high_source == "local-source-cloud-ground-quantile-median"
+5 -5
View File
@@ -489,7 +489,7 @@ def test_canonical_lab_spatial_frame_uses_ready_immutable_recording(
assert resolved is not None and resolved.recording is not None
generation = hashlib.sha256(payload).hexdigest()
expected = {
"schema_version": "missioncore.canonical-recorded-lab-spatial-frame/v2",
"schema_version": "missioncore.canonical-recorded-lab-spatial-frame/v3",
"target_time_ns": 500_000_000,
"source_time_ns": 499_000_000,
"pose_time_ns": 499_000_000,
@@ -497,13 +497,13 @@ def test_canonical_lab_spatial_frame_uses_ready_immutable_recording(
"coordinate_frame": "body-ground",
"sensor_height": {
"meters": 0.32,
"source": "initial-source-cloud-lower-quantile-median",
"source": "local-source-cloud-ground-quantile-median",
"sample_count": 20,
"mad_m": 0.03,
"authority": "visual-derived",
},
"spatial_profile": {
"profile_id": "source-paced-ground-v2",
"profile_id": "source-paced-ground-v3",
"local_slam_history_seconds": 5.0,
"local_slam_radius_m": 30.0,
"local_slam_voxel_size_m": 0.12,
@@ -544,11 +544,11 @@ def test_canonical_lab_spatial_frame_uses_ready_immutable_recording(
session_id=session.name,
generation=generation,
time_ns=500_000_000,
profile="source-paced-ground-v2",
profile="source-paced-ground-v3",
))
assert json.loads(response.body) == expected
assert response.headers["etag"] == (
f'"{generation}:source-paced-ground-v2:499000000"'
f'"{generation}:source-paced-ground-v3:499000000"'
)
assert response.headers["cache-control"].endswith("immutable")
finally:
+13
View File
@@ -22,6 +22,7 @@ from k1link.laboratory.evidence_report import verify_laboratory_evidence_result
from k1link.laboratory.vegetation_policy_review import seal_vegetation_policy_review
from k1link.laboratory.vegetation_shadow_lab import seal_vegetation_shadow_lab
from k1link.web.vegetation_shadow_lab_api import (
_mask_component_boxes,
_route_tgs_anchor_payload,
build_vegetation_shadow_lab_router,
)
@@ -29,6 +30,18 @@ from k1link.web.vegetation_shadow_lab_api import (
REPOSITORY_ROOT = Path(__file__).resolve().parents[1]
def test_semantic_component_boxes_keep_distinct_objects_separate() -> None:
mask = np.zeros((20, 30), dtype=np.uint8)
mask[2:10, 3:8] = 4
mask[4:12, 18:24] = 4
mask[15:17, 3:5] = 4
assert _mask_component_boxes(mask, 4, minimum_pixels=20) == [
(18, 4, 24, 12, 48),
(3, 2, 8, 10, 40),
]
def test_route_tgs_anchor_payload_preserves_metric_evidence(tmp_path: Path) -> None:
path = tmp_path / "tgs-evidence.npz"
point_counts = np.arange(1, 11, dtype=np.int64)