feat(lab): visualize semantic SLAM shadow
This commit is contained in:
@@ -0,0 +1,192 @@
|
||||
import assert from "node:assert/strict";
|
||||
import { after, before, test } from "node:test";
|
||||
|
||||
import { createServer } from "vite";
|
||||
|
||||
let server;
|
||||
let fetchE47SemanticSlamResult;
|
||||
let fetchE47SemanticTimelineChunk;
|
||||
let e47SemanticMaskUrl;
|
||||
|
||||
const resultId = `e47-semantic-slam-${"a".repeat(64)}`;
|
||||
const baseM4ResultId = `m4-threat-replay-${"b".repeat(64)}`;
|
||||
|
||||
before(async () => {
|
||||
server = await createServer({
|
||||
appType: "custom",
|
||||
logLevel: "silent",
|
||||
server: { middlewareMode: true },
|
||||
});
|
||||
({
|
||||
fetchE47SemanticSlamResult,
|
||||
fetchE47SemanticTimelineChunk,
|
||||
e47SemanticMaskUrl,
|
||||
} = await server.ssrLoadModule("/src/core/laboratory/e47SemanticSlam.ts"));
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await server?.close();
|
||||
});
|
||||
|
||||
function resultView(overrides = {}) {
|
||||
return {
|
||||
schema_version: "missioncore.e47-semantic-slam-view/v1",
|
||||
result_id: resultId,
|
||||
created_at_utc: "2026-08-06T10:00:00.000Z",
|
||||
status: "diagnostic-semantic-slam-shadow",
|
||||
profile_id: "ravnoves00-eomt-kb4-slam-shadow/v1",
|
||||
base_m4_result_id: baseM4ResultId,
|
||||
semantic_result_id: `result-${"c".repeat(64)}`,
|
||||
geometry_result_id: `m4-geometry-replay-${"d".repeat(64)}`,
|
||||
source_pack_id: `e10-lidar-pack-${"e".repeat(64)}`,
|
||||
calibration_content_sha256: "f".repeat(64),
|
||||
provider: {
|
||||
provider_id: "eomt-cityscapes-semantic-control/v1",
|
||||
model_id: "tue-mps/cityscapes_semantic_eomt_large_1024",
|
||||
model_revision: "revision-1",
|
||||
model_weights_sha256: "1".repeat(64),
|
||||
preprocess_id: "raw-kb4-valid-fov-semantic/v1",
|
||||
},
|
||||
temporal_binding: {
|
||||
semantic_to_camera: "exact-sequence-and-session-time",
|
||||
camera_to_lidar: "accepted-e6-nearest-host-arrival-best-effort",
|
||||
clock_basis: "recorded-host-monotonic-arrival",
|
||||
maximum_lidar_camera_delta_ms: 100,
|
||||
maximum_pose_point_delta_ms: 100,
|
||||
physical_synchronization_proven: false,
|
||||
},
|
||||
taxonomy: [
|
||||
{
|
||||
class_id: 0,
|
||||
label: "outside_valid_fov",
|
||||
disposition: "ambiguous",
|
||||
color_rgb: [0, 0, 0],
|
||||
},
|
||||
{
|
||||
class_id: 7,
|
||||
label: "paved_road",
|
||||
disposition: "labeled",
|
||||
color_rgb: [128, 64, 128],
|
||||
},
|
||||
],
|
||||
metrics: {
|
||||
frames: { total: 4489, mask_available: 4489, source_available: 4489 },
|
||||
points: {
|
||||
total: 4,
|
||||
projected: 2,
|
||||
labeled: 1,
|
||||
ambiguous: 1,
|
||||
unprojected: 2,
|
||||
absent: 0,
|
||||
},
|
||||
observations: {
|
||||
total: 2,
|
||||
labeled: 1,
|
||||
ambiguous: 0,
|
||||
unprojected: 1,
|
||||
absent: 0,
|
||||
},
|
||||
runtime: { elapsed_ms: 1000, frames_per_second: 4.489 },
|
||||
},
|
||||
acceptance: {
|
||||
artifact_contract_passed: true,
|
||||
frame_accounting_passed: true,
|
||||
point_accounting_passed: true,
|
||||
observation_binding_passed: true,
|
||||
temporal_binding_passed: true,
|
||||
independent_semantic_truth_passed: false,
|
||||
provider_promoted: false,
|
||||
},
|
||||
limitations: ["diagnostic only"],
|
||||
ground_truth: false,
|
||||
semantic_authority: "diagnostic-only",
|
||||
navigation_or_safety_accepted: false,
|
||||
actuation_allowed: false,
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
test("E47 accepts only a fully accounted diagnostic semantic/SLAM view", async () => {
|
||||
const result = await fetchE47SemanticSlamResult({
|
||||
fetcher: async () => new Response(JSON.stringify({
|
||||
schema_version: "missioncore.e47-semantic-slam-catalog/v1",
|
||||
items: [resultView()],
|
||||
})),
|
||||
});
|
||||
assert.equal(result.resultId, resultId);
|
||||
assert.equal(result.baseM4ResultId, baseM4ResultId);
|
||||
assert.equal(result.metrics.points.projected, 2);
|
||||
assert.equal(result.acceptance.independentSemanticTruthPassed, false);
|
||||
assert.equal(result.temporalBinding.physicalSynchronizationProven, false);
|
||||
assert.equal(result.temporalBinding.maximumLidarCameraDeltaMs, 100);
|
||||
assert.equal(result.acceptance.temporalBindingPassed, true);
|
||||
assert.equal(result.taxonomy[0].disposition, "ambiguous");
|
||||
assert.equal(
|
||||
e47SemanticMaskUrl(resultId, 14),
|
||||
`/api/v1/laboratory/e47-semantic-slam/results/${resultId}/masks/14`,
|
||||
);
|
||||
});
|
||||
|
||||
test("E47 rejects result-level point accounting drift", async () => {
|
||||
await assert.rejects(
|
||||
fetchE47SemanticSlamResult({
|
||||
fetcher: async () => new Response(JSON.stringify({
|
||||
schema_version: "missioncore.e47-semantic-slam-catalog/v1",
|
||||
items: [resultView({
|
||||
metrics: {
|
||||
...resultView().metrics,
|
||||
points: {
|
||||
...resultView().metrics.points,
|
||||
total: 5,
|
||||
},
|
||||
},
|
||||
})],
|
||||
})),
|
||||
}),
|
||||
/point accounting/,
|
||||
);
|
||||
});
|
||||
|
||||
test("E47 chunk preserves unavailable sentinel and verifies the status histogram", async () => {
|
||||
const validFrame = {
|
||||
schema_version: "missioncore.e47-semantic-slam-frame/v1",
|
||||
sequence: 14,
|
||||
source_point_count: 4,
|
||||
class_ids: [7, 0, -1, -1],
|
||||
status_codes: [3, 2, 1, 1],
|
||||
counts: { labeled: 1, ambiguous: 1, unprojected: 2, absent: 0 },
|
||||
};
|
||||
const chunk = await fetchE47SemanticTimelineChunk(resultId, 14, 1, {
|
||||
taxonomy: [
|
||||
{ classId: 0, label: "outside_valid_fov", disposition: "ambiguous", colorRgb: [0, 0, 0] },
|
||||
{ classId: 7, label: "paved_road", disposition: "labeled", colorRgb: [128, 64, 128] },
|
||||
],
|
||||
fetcher: async () => new Response(JSON.stringify({
|
||||
schema_version: "missioncore.e47-semantic-slam-chunk/v1",
|
||||
result_id: resultId,
|
||||
start_sequence: 14,
|
||||
frame_count: 1,
|
||||
next_sequence: 15,
|
||||
frames: [validFrame],
|
||||
})),
|
||||
});
|
||||
assert.deepEqual(chunk.frames[0].classIds, [7, 0, -1, -1]);
|
||||
|
||||
await assert.rejects(
|
||||
fetchE47SemanticTimelineChunk(resultId, 14, 1, {
|
||||
taxonomy: [
|
||||
{ classId: 0, label: "outside_valid_fov", disposition: "ambiguous", colorRgb: [0, 0, 0] },
|
||||
{ classId: 7, label: "paved_road", disposition: "labeled", colorRgb: [128, 64, 128] },
|
||||
],
|
||||
fetcher: async () => new Response(JSON.stringify({
|
||||
schema_version: "missioncore.e47-semantic-slam-chunk/v1",
|
||||
result_id: resultId,
|
||||
start_sequence: 14,
|
||||
frame_count: 1,
|
||||
next_sequence: 15,
|
||||
frames: [{ ...validFrame, class_ids: [7, 0, 7, -1] }],
|
||||
})),
|
||||
}),
|
||||
/class\/status binding/,
|
||||
);
|
||||
});
|
||||
@@ -0,0 +1,69 @@
|
||||
import assert from "node:assert/strict";
|
||||
import { readFile } from "node:fs/promises";
|
||||
import { test } from "node:test";
|
||||
|
||||
const component = (name) => new URL(`../src/components/laboratory/${name}`, import.meta.url);
|
||||
|
||||
test("semantic evidence mask is decoded, cached, cancelled and object-contained client-side", async () => {
|
||||
const source = await readFile(component("RecordedEvidenceSemanticMaskOverlay.tsx"), "utf8");
|
||||
assert.match(source, /decodedMaskCache/);
|
||||
assert.match(source, /pendingMaskCache/);
|
||||
assert.match(source, /AbortController/);
|
||||
assert.match(source, /getImageData/);
|
||||
assert.match(source, /8-bit grayscale class-id PNG/);
|
||||
assert.match(source, /ResizeObserver/);
|
||||
assert.match(source, /Math\.min\(width \/ imageWidth, height \/ imageHeight\)/);
|
||||
assert.match(source, /decoded\.key !== expectedKey/);
|
||||
assert.match(source, /mask\?\.key === expectedKey/);
|
||||
assert.match(source, /необъявленный class ID/);
|
||||
assert.match(source, /recorded-evidence-semantic-mask-overlay__error/);
|
||||
assert.match(source, /role="alert"/);
|
||||
});
|
||||
|
||||
test("shared recorded scenes place optional semantic masks beneath boxes", async () => {
|
||||
const [imageScene, videoScene] = await Promise.all([
|
||||
readFile(component("RecordedEvidenceImageScene.tsx"), "utf8"),
|
||||
readFile(component("RecordedEvidenceVideoScene.tsx"), "utf8"),
|
||||
]);
|
||||
for (const source of [imageScene, videoScene]) {
|
||||
assert.match(source, /semanticOverlay\?: RecordedEvidenceSemanticOverlay/);
|
||||
assert.ok(
|
||||
source.indexOf("<RecordedEvidenceSemanticMaskOverlay")
|
||||
< source.indexOf("<RecordedEvidenceBoxOverlay"),
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
test("metric evidence keeps missing semantic assignments as context and exposes a taxonomy legend", async () => {
|
||||
const source = await readFile(component("LaboratoryMetricEvidenceScene.tsx"), "utf8");
|
||||
assert.match(source, /pointSemanticClassIds\?: readonly \(number \| null\)\[\]/);
|
||||
assert.match(source, /pointSemanticClassIds\.length === pointCloudBodyXyzM\.length/);
|
||||
assert.match(source, /classId === null \? undefined : colorsByClassId\.get\(classId\)/);
|
||||
assert.match(source, /data-decision="semantic"/);
|
||||
assert.match(source, /recordedEvidenceSemanticCssColor/);
|
||||
});
|
||||
|
||||
test("semantic point alignment is enforced only when M4 exposes the exact spatial increment", async () => {
|
||||
const source = await readFile(
|
||||
new URL("../src/workspaces/laboratory/M4ReplayThreatVisual.tsx", import.meta.url),
|
||||
"utf8",
|
||||
);
|
||||
assert.match(source, /semantic && frame\?\.spatialAvailable && semanticFrame/);
|
||||
assert.match(source, /\|\| !frame\.spatialAvailable\s*\|\| !semanticFrame/);
|
||||
assert.match(source, /semanticFrame\.sourcePointCount !== frame\.pointCloudSourceCount/);
|
||||
});
|
||||
|
||||
test("M4 mounts semantic mask overlays only for the active VIDEO or CAMERA layer", async () => {
|
||||
const source = await readFile(
|
||||
new URL("../src/workspaces/laboratory/M4ReplayThreatVisual.tsx", import.meta.url),
|
||||
"utf8",
|
||||
);
|
||||
assert.match(
|
||||
source,
|
||||
/semanticOverlay=\{mode === "video" \? semanticOverlay : undefined\}/,
|
||||
);
|
||||
assert.match(
|
||||
source,
|
||||
/semanticOverlay=\{mode === "camera" \? semanticOverlay : undefined\}/,
|
||||
);
|
||||
});
|
||||
Reference in New Issue
Block a user