feat(perception): integrate vegetation policy review
This commit is contained in:
@@ -108,7 +108,9 @@ test("M4.9T5 viewer prefers autonomous chunks and keeps a sealed legacy fallback
|
||||
assert.doesNotMatch(source, /centersXyM\.map\(/);
|
||||
assert.match(source, /fetchE47SemanticSlamResult/);
|
||||
assert.match(source, /next\.baseM4ResultId !== result\.source\.linkedVisualResultId/);
|
||||
assert.match(source, /semantic=\{semantic \? \{/);
|
||||
assert.match(source, /semantic=\{semanticOverride \?\? \(semantic \? \{/);
|
||||
assert.match(source, /semanticOverride/);
|
||||
assert.doesNotMatch(visual, /classifiedSpatialLayer \|\| !showReferenceMediaLayers \? \[\]/);
|
||||
assert.match(
|
||||
visual,
|
||||
/classifiedSpatialFrame\s*&&\s*classifiedSpatialFrame\.sampleAvailable !== false/,
|
||||
|
||||
@@ -104,45 +104,89 @@ function routeVideo() {
|
||||
};
|
||||
}
|
||||
|
||||
function coarseRouteVideo() {
|
||||
return {
|
||||
...routeVideo(),
|
||||
view_kind: "coarse-material-policy-review",
|
||||
linked_tgs_result_id: `m49-tgs-full-shadow-${"2".repeat(64)}`,
|
||||
taxonomy: {
|
||||
schema_version: "missioncore.lab-v1-terrain-policy-taxonomy/v1",
|
||||
classes: Array.from({ length: 9 }, (_, classId) => ({
|
||||
class_id: classId,
|
||||
label: `policy-${classId}`,
|
||||
color_rgb: [classId, classId, classId],
|
||||
disposition: classId === 0 ? "ambiguous" : "prediction",
|
||||
material_class: classId === 0 ? null : "grass",
|
||||
evidence_state: classId === 0 ? "UNOBSERVED" : "SUPPORTED_GROUND",
|
||||
})),
|
||||
},
|
||||
aggregate_prediction_pixels: Array(9).fill(0),
|
||||
mask_archive: {
|
||||
path: "video/coarse-material-policy-masks.zip",
|
||||
sha256: "8".repeat(64),
|
||||
byte_length: 2048,
|
||||
},
|
||||
policy: {
|
||||
presets: {
|
||||
urban: { grass: "NO_GO" },
|
||||
rural: { grass: "HIGH_COST" },
|
||||
offroad: { grass: "HIGH_COST" },
|
||||
},
|
||||
},
|
||||
fusion: {
|
||||
mode: "synchronised-multilayer-review",
|
||||
pixel_raster_fusion: false,
|
||||
camera_semantic_temporal_filter: "none",
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function labPayload(route = routeVideo()) {
|
||||
return {
|
||||
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: [],
|
||||
},
|
||||
route_video: route,
|
||||
access: "read-only",
|
||||
};
|
||||
}
|
||||
|
||||
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: [],
|
||||
},
|
||||
route_video: routeVideo(),
|
||||
access: "read-only",
|
||||
}), { status: 200, headers: { "Content-Type": "application/json" } });
|
||||
return new Response(JSON.stringify(labPayload()), {
|
||||
status: 200,
|
||||
headers: { "Content-Type": "application/json" },
|
||||
});
|
||||
},
|
||||
});
|
||||
assert.equal(
|
||||
@@ -154,6 +198,8 @@ test("vegetation LAB keeps autonomous assets and fail-closed authority", async (
|
||||
assert.equal(result.routeCases.length, 0);
|
||||
assert.equal(result.validationCases.length, 12);
|
||||
assert.equal(result.routeVideo.frameCount, 4489);
|
||||
assert.equal(result.routeVideo.viewKind, "fine-semantic-prediction");
|
||||
assert.equal(result.routeVideo.linkedTgsResultId, null);
|
||||
assert.equal(result.routeVideo.taxonomy[0].disposition, "undefined");
|
||||
assert.equal(result.validationCases[0].focus.className, "high_grass");
|
||||
assert.match(result.validationCases[0].assets.ddrnet_error, /\/assets\/visual\/goose\//);
|
||||
@@ -165,6 +211,21 @@ test("vegetation LAB keeps autonomous assets and fail-closed authority", async (
|
||||
});
|
||||
});
|
||||
|
||||
test("vegetation LAB parses coarse material policy and sealed TGS binding", async () => {
|
||||
const result = await fetchVegetationShadowResult(resultId, {
|
||||
fetcher: async () => new Response(JSON.stringify(labPayload(coarseRouteVideo())), {
|
||||
status: 200,
|
||||
headers: { "Content-Type": "application/json" },
|
||||
}),
|
||||
});
|
||||
assert.equal(result.routeVideo.viewKind, "coarse-material-policy-review");
|
||||
assert.match(result.routeVideo.linkedTgsResultId, /^m49-tgs-full-shadow-/);
|
||||
assert.equal(result.routeVideo.taxonomy.length, 9);
|
||||
assert.equal(result.routeVideo.taxonomy[0].evidenceState, "UNOBSERVED");
|
||||
assert.equal(result.routeVideo.policyPresets.urban.grass, "NO_GO");
|
||||
assert.equal(result.routeVideo.fusionMode, "synchronised-multilayer-review");
|
||||
});
|
||||
|
||||
test("vegetation LAB reuses the admitted M4.8 and M4.7 instruments", async () => {
|
||||
const resultSource = await readFile(
|
||||
new URL("../src/workspaces/laboratory/VegetationShadowResult.tsx", import.meta.url),
|
||||
@@ -172,8 +233,10 @@ test("vegetation LAB reuses the admitted M4.8 and M4.7 instruments", async () =>
|
||||
);
|
||||
assert.match(resultSource, /M48MaskComparisonVisual/);
|
||||
assert.match(resultSource, /M4ReplayThreatVisual/);
|
||||
assert.match(resultSource, /M49TgsFullShadowEvidence/);
|
||||
assert.match(resultSource, /semanticOverride/);
|
||||
assert.equal(resultSource.match(/<LaboratoryEvidence\b/g)?.length, 2);
|
||||
assert.match(resultSource, /showReferenceMediaLayers=\{false\}/);
|
||||
assert.match(resultSource, /linkedTgsResultId/);
|
||||
assert.doesNotMatch(resultSource, /VegetationRouteVisual|urban\/rural\/off-road presets/);
|
||||
await assert.rejects(
|
||||
access(new URL("../src/workspaces/laboratory/VegetationShadowVisual.tsx", import.meta.url)),
|
||||
|
||||
Reference in New Issue
Block a user