feat(perception): integrate vegetation policy review
This commit is contained in:
@@ -2,6 +2,7 @@ from __future__ import annotations
|
||||
|
||||
import hashlib
|
||||
import json
|
||||
import shutil
|
||||
import zipfile
|
||||
from pathlib import Path
|
||||
from types import SimpleNamespace
|
||||
@@ -9,9 +10,11 @@ from types import SimpleNamespace
|
||||
from fastapi import FastAPI
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from k1link.laboratory import LaboratoryEvidenceRegistry
|
||||
import k1link.laboratory.vegetation_policy_review as policy_review_module
|
||||
import k1link.laboratory.vegetation_shadow_lab as vegetation_lab_module
|
||||
from k1link.laboratory import LaboratoryEvidenceRegistry
|
||||
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 build_vegetation_shadow_lab_router
|
||||
|
||||
@@ -229,3 +232,95 @@ def test_vegetation_shadow_lab_seals_autonomous_visual_evidence(
|
||||
client.get(f"/api/v1/laboratory/vegetation-shadow/{result_root.name}").status_code
|
||||
== 503
|
||||
)
|
||||
|
||||
|
||||
def test_policy_review_reuses_sealed_video_and_links_yolox_tgs(
|
||||
tmp_path: Path,
|
||||
monkeypatch,
|
||||
) -> None:
|
||||
roots = {}
|
||||
for candidate, vegetation_iou in (("ddrnet", 0.64), ("ppliteseg", 0.61)):
|
||||
for mode in ("goose", "ravnoves"):
|
||||
root = tmp_path / "worker" / f"{candidate}-{mode}"
|
||||
_worker_result(root, candidate=candidate, mode=mode, vegetation_iou=vegetation_iou)
|
||||
roots[(candidate, mode)] = root
|
||||
video_root = tmp_path / "worker" / "ddrnet-ravnoves-video"
|
||||
_video_worker_result(video_root)
|
||||
m47_root = tmp_path / f"m47-reference-graph-lab-{'a' * 64}"
|
||||
m47_root.mkdir()
|
||||
base_m4_result_id = f"m4-threat-replay-{'f' * 64}"
|
||||
monkeypatch.setattr(
|
||||
vegetation_lab_module,
|
||||
"read_m47_reference_graph_lab",
|
||||
lambda _root: SimpleNamespace(
|
||||
result_id=m47_root.name,
|
||||
report={
|
||||
"source": {"source_id": "RAVNOVES00"},
|
||||
"visual_evidence": {
|
||||
"linked_result_id": base_m4_result_id,
|
||||
"timeline_frames": 4489,
|
||||
},
|
||||
},
|
||||
),
|
||||
)
|
||||
base_root = seal_vegetation_shadow_lab(
|
||||
ddrnet_goose_root=roots[("ddrnet", "goose")],
|
||||
ppliteseg_goose_root=roots[("ppliteseg", "goose")],
|
||||
ddrnet_ravnoves_root=roots[("ddrnet", "ravnoves")],
|
||||
ppliteseg_ravnoves_root=roots[("ppliteseg", "ravnoves")],
|
||||
output_root=tmp_path / "results",
|
||||
ddrnet_ravnoves_video_root=video_root,
|
||||
m47_reference_graph_lab_root=m47_root,
|
||||
)
|
||||
tgs_result_id = f"m49-tgs-full-shadow-{'9' * 64}"
|
||||
monkeypatch.setattr(
|
||||
policy_review_module,
|
||||
"read_m49_tgs_full_shadow",
|
||||
lambda _root: SimpleNamespace(
|
||||
result_id=tgs_result_id,
|
||||
report={
|
||||
"source": {
|
||||
"source_id": "RAVNOVES00",
|
||||
"linked_visual_result_id": base_m4_result_id,
|
||||
},
|
||||
"timeline": {"frame_count": 4489},
|
||||
},
|
||||
),
|
||||
)
|
||||
|
||||
def fake_policy_archive(**kwargs) -> list[int]:
|
||||
shutil.copyfile(kwargs["source_archive"], kwargs["destination_archive"])
|
||||
return [4489 * 800 * 600, *([0] * 8)]
|
||||
|
||||
monkeypatch.setattr(policy_review_module, "build_policy_mask_archive", fake_policy_archive)
|
||||
result_root = seal_vegetation_policy_review(
|
||||
base_lab_root=base_root,
|
||||
mission_policy_path=REPOSITORY_ROOT
|
||||
/ "config/perception/lab-v1-vegetation-mission-policy-v1.json",
|
||||
provider_label_map_path=REPOSITORY_ROOT
|
||||
/ "config/perception/lab-v1-vegetation-provider-label-map-v1.json",
|
||||
m49_tgs_full_shadow_root=tmp_path / "sealed-tgs",
|
||||
output_root=tmp_path / "results",
|
||||
created_at_utc="2026-08-28T08:00:00+00:00",
|
||||
)
|
||||
manifest = json.loads((result_root / "result.json").read_text("utf-8"))
|
||||
route = manifest["route_video"]
|
||||
assert route["view_kind"] == "coarse-material-policy-review"
|
||||
assert route["linked_tgs_result_id"] == tgs_result_id
|
||||
assert route["fusion"]["pixel_raster_fusion"] is False
|
||||
assert route["fusion"]["camera_semantic_temporal_filter"] == "none"
|
||||
assert route["taxonomy"]["schema_version"] == (
|
||||
"missioncore.lab-v1-terrain-policy-taxonomy/v1"
|
||||
)
|
||||
assert len(route["taxonomy"]["classes"]) == 9
|
||||
assert len(manifest["artifacts"]) == 79
|
||||
assert manifest["authority"]["commands_enabled"] is False
|
||||
assert manifest["decision"]["multilayer_policy_review_ready"] is True
|
||||
|
||||
app = FastAPI()
|
||||
app.include_router(build_vegetation_shadow_lab_router(root_provider=lambda: result_root.parent))
|
||||
response = TestClient(app).get(
|
||||
f"/api/v1/laboratory/vegetation-shadow/{result_root.name}/masks/0"
|
||||
)
|
||||
assert response.status_code == 200
|
||||
assert response.content == b"\x89PNG\r\n\x1a\n"
|
||||
|
||||
Reference in New Issue
Block a user