feat(perception): add autonomous vegetation shadow lab
This commit is contained in:
@@ -0,0 +1,125 @@
|
||||
import assert from "node:assert/strict";
|
||||
import { after, before, test } from "node:test";
|
||||
|
||||
import { createServer } from "vite";
|
||||
|
||||
let server;
|
||||
let fetchVegetationShadowResult;
|
||||
|
||||
before(async () => {
|
||||
server = await createServer({
|
||||
appType: "custom",
|
||||
logLevel: "silent",
|
||||
server: { middlewareMode: true },
|
||||
});
|
||||
({ fetchVegetationShadowResult } = await server.ssrLoadModule(
|
||||
"/src/core/laboratory/vegetationShadow.ts",
|
||||
));
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await server?.close();
|
||||
});
|
||||
|
||||
const resultId = `lab-v1-vegetation-shadow-${"a".repeat(64)}`;
|
||||
|
||||
function candidate(candidateKey, vegetationIou) {
|
||||
return {
|
||||
loaded_model_name: candidateKey === "ddrnet" ? "ddrnet_39" : "pp_lite_t_seg",
|
||||
checkpoint_sha256: (candidateKey === "ddrnet" ? "b" : "c").repeat(64),
|
||||
validation_metrics: {
|
||||
mean_iou_percent: 44.2,
|
||||
published_mean_iou_percent: 46.53,
|
||||
vegetation_mean_iou: vegetationIou,
|
||||
},
|
||||
validation_timing: {
|
||||
latency_ms_p95: 22.4,
|
||||
throughput_fps_from_mean_inference: 48.1,
|
||||
},
|
||||
shadow_timing: {
|
||||
prewarm_latency_ms: 612.4,
|
||||
latency_ms_p95: 21.8,
|
||||
throughput_fps_from_mean_inference: 49.2,
|
||||
},
|
||||
resource: {
|
||||
peak_reserved_vram_bytes: 2_000_000_000,
|
||||
gpu_name: "NVIDIA GeForce RTX 4090",
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function visualCase(sourceKind, index) {
|
||||
const caseId = `case-${index}`;
|
||||
const keys = sourceKind === "goose"
|
||||
? ["source", "truth", "ddrnet", "ppliteseg"]
|
||||
: ["source", "ddrnet", "ppliteseg", "urban", "rural", "offroad"];
|
||||
return {
|
||||
case_id: caseId,
|
||||
source_kind: sourceKind,
|
||||
width: sourceKind === "goose" ? 512 : 800,
|
||||
height: sourceKind === "goose" ? 512 : 600,
|
||||
center_crop_xyxy: sourceKind === "goose" ? [0, 0, 512, 512] : [100, 0, 700, 600],
|
||||
outside_crop_state: sourceKind === "goose" ? "not-applicable" : "undefined",
|
||||
assets: Object.fromEntries(keys.map((key) => [key, {
|
||||
path: `visual/${sourceKind}/${caseId}/${key}.png`,
|
||||
sha256: "d".repeat(64),
|
||||
}])),
|
||||
};
|
||||
}
|
||||
|
||||
test("vegetation LAB keeps autonomous assets and fail-closed authority", async () => {
|
||||
let requestedUrl = "";
|
||||
const result = await fetchVegetationShadowResult(resultId, {
|
||||
fetcher: async (url) => {
|
||||
requestedUrl = String(url);
|
||||
return new Response(JSON.stringify({
|
||||
schema_version: "missioncore.lab-v1-vegetation-shadow/v1",
|
||||
result_id: resultId,
|
||||
created_at_utc: "2026-08-27T20:00:00Z",
|
||||
status: "visual-shadow-ready-policy-not-authorized",
|
||||
ground_truth: false,
|
||||
identity: { selected_candidate: "ddrnet" },
|
||||
metrics: {
|
||||
candidates: {
|
||||
ddrnet: candidate("ddrnet", 0.64),
|
||||
ppliteseg: candidate("ppliteseg", 0.61),
|
||||
},
|
||||
},
|
||||
decision: {
|
||||
selected_candidate: "ddrnet",
|
||||
visual_shadow_ready: true,
|
||||
mission_policy_ready_for_configuration: true,
|
||||
navigation_accepted: false,
|
||||
production_accepted: false,
|
||||
},
|
||||
limitations: ["shadow only"],
|
||||
authority: {
|
||||
commands_enabled: false,
|
||||
navigation_or_safety_accepted: false,
|
||||
actuation_accepted: false,
|
||||
camera_semantics_can_clear_rigid_geometry: false,
|
||||
},
|
||||
catalogs: {
|
||||
goose: Array.from({ length: 12 }, (_, index) => visualCase("goose", index)),
|
||||
ravnoves: Array.from({ length: 12 }, (_, index) => visualCase("ravnoves", index)),
|
||||
},
|
||||
access: "read-only",
|
||||
}), { status: 200, headers: { "Content-Type": "application/json" } });
|
||||
},
|
||||
});
|
||||
assert.equal(
|
||||
requestedUrl,
|
||||
`/api/v1/laboratory/vegetation-shadow/${resultId}`,
|
||||
);
|
||||
assert.equal(result.selectedCandidate, "ddrnet");
|
||||
assert.equal(result.candidates[0].vegetationMeanIouPercent, 64);
|
||||
assert.equal(result.routeCases.length, 12);
|
||||
assert.equal(result.validationCases.length, 12);
|
||||
assert.match(result.routeCases[0].assets.offroad, /\/assets\/visual\/ravnoves\//);
|
||||
assert.deepEqual(result.authority, {
|
||||
commandsEnabled: false,
|
||||
navigationOrSafetyAccepted: false,
|
||||
actuationAccepted: false,
|
||||
cameraSemanticsCanClearRigidGeometry: false,
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user