feat(ui): add M4.8S replay with LiDAR overlay
This commit is contained in:
@@ -0,0 +1,226 @@
|
||||
import assert from "node:assert/strict";
|
||||
import { after, before, test } from "node:test";
|
||||
import { createServer } from "vite";
|
||||
|
||||
let server;
|
||||
let fetchM48SFixedClassDetectorResult;
|
||||
let fetchM48SFixedClassDetectorFrame;
|
||||
|
||||
const resultId = `m48s-fixed-class-detector-lab-${"b".repeat(64)}`;
|
||||
const authority = {
|
||||
actuation_allowed: false,
|
||||
candidate_accepted: false,
|
||||
commands_enabled: false,
|
||||
ground_truth: false,
|
||||
navigation_or_safety_accepted: false,
|
||||
};
|
||||
|
||||
before(async () => {
|
||||
server = await createServer({
|
||||
appType: "custom",
|
||||
logLevel: "silent",
|
||||
server: { middlewareMode: true },
|
||||
});
|
||||
({
|
||||
fetchM48SFixedClassDetectorResult,
|
||||
fetchM48SFixedClassDetectorFrame,
|
||||
} = await server.ssrLoadModule("/src/core/laboratory/m48sFixedClassDetector.ts"));
|
||||
});
|
||||
|
||||
after(async () => server?.close());
|
||||
|
||||
function response(value) {
|
||||
return { ok: true, status: 200, json: async () => value };
|
||||
}
|
||||
|
||||
function resultPayload() {
|
||||
const candidate = (id, overrides = {}) => ({
|
||||
id,
|
||||
label: id,
|
||||
provider_id: `${id}/v1`,
|
||||
capacity_fps: 40,
|
||||
p95_ms: 35,
|
||||
frame_253_dog_detected: false,
|
||||
frame_253_dog_score: null,
|
||||
selected: false,
|
||||
...overrides,
|
||||
});
|
||||
return {
|
||||
schema_version: "missioncore.m48s-fixed-class-detector-result-view/v1",
|
||||
result_id: resultId,
|
||||
created_at_utc: "2026-08-25T11:06:28Z",
|
||||
status: "complete-reference-graph-shadow-passed-production-not-authorized",
|
||||
bounded_question_accepted: true,
|
||||
ground_truth: false,
|
||||
source: {
|
||||
source_session_id: "RAVNOVES00",
|
||||
camera_source_id: "sensor.camera.right",
|
||||
camera_raster: [800, 600],
|
||||
evidence_frame_count: 1,
|
||||
},
|
||||
configuration: {
|
||||
comparison_threshold: 0.5,
|
||||
display_modes: ["source", "yolox", "dfine", "rf-detr"],
|
||||
single_inference_per_frame: true,
|
||||
geometry_owns_static_occupancy: true,
|
||||
unknown_stationary_response: "route-around",
|
||||
unknown_moving_response: "conservative-risk",
|
||||
},
|
||||
method: {
|
||||
schema_version: "missioncore.laboratory-method/v1",
|
||||
completeness: "complete",
|
||||
execution_class: "ai-inference",
|
||||
pipeline_id: "raw-kb4-fixed-class-risk-detector-tournament/v1",
|
||||
components: [{
|
||||
kind: "model",
|
||||
name: "RF-DETR-L COCO",
|
||||
version: "trt11-fp16",
|
||||
role: "selected fixed-class risk detector",
|
||||
identity_sha256: "9".repeat(64),
|
||||
}],
|
||||
},
|
||||
metrics: {
|
||||
candidates: [
|
||||
candidate("yolox"),
|
||||
candidate("dfine"),
|
||||
candidate("rf-detr", {
|
||||
label: "RF-DETR-L",
|
||||
capacity_fps: 42.496232,
|
||||
frame_253_dog_detected: true,
|
||||
frame_253_dog_score: 0.741674,
|
||||
selected: true,
|
||||
}),
|
||||
],
|
||||
detector_load: {
|
||||
duration_seconds: 1800.019643,
|
||||
source_frames_consumed: 18008,
|
||||
source_frame_replacements: 0,
|
||||
effective_consumed_fps: 10.004444,
|
||||
end_to_end_p95_ms: 32.41534,
|
||||
completion_age_p95_ms: 40.620542,
|
||||
gpu_utilization_mean_percent: 51.407556,
|
||||
gpu_utilization_maximum_percent: 65,
|
||||
gpu_memory_maximum_mib: 9556,
|
||||
queue_maximum_depth: 1,
|
||||
queue_capacity: 2,
|
||||
failures: 0,
|
||||
},
|
||||
integrated_world_state: {
|
||||
duration_seconds: 458.900859,
|
||||
source_frames_admitted: 4489,
|
||||
delivered_world_states: 4481,
|
||||
superseded_frames: 8,
|
||||
effective_world_state_fps: 9.764636,
|
||||
world_state_completion_age_p95_ms: 74.733648,
|
||||
world_state_completion_age_p99_ms: 102.62048,
|
||||
world_state_completion_age_maximum_ms: 669.142137,
|
||||
local_obstacle_map_output_age_p95_ms: 70.635141,
|
||||
queue_high_watermarks: { detector: 2, geometry: 2, temporal: 2, rolling: 2, threat: 2 },
|
||||
queue_capacity: 2,
|
||||
gpu_utilization_mean_percent: 50.903371,
|
||||
gpu_utilization_maximum_percent: 60,
|
||||
gpu_memory_maximum_mib: 9576,
|
||||
gpu_power_maximum_w: 153.51,
|
||||
gpu_temperature_maximum_c: 39,
|
||||
unique_component_count: 44979,
|
||||
multi_frame_component_count: 15887,
|
||||
maximum_component_publications: 219,
|
||||
duplicate_component_ids_within_frame: 0,
|
||||
advisory_family_counts: {
|
||||
animal: 63,
|
||||
"generic-obstacle": 123919,
|
||||
"light-road-user": 329,
|
||||
person: 5600,
|
||||
vehicle: 55818,
|
||||
},
|
||||
semantic_hint_counts: { dog: 60, person: 5600, "geometry-only": 123919 },
|
||||
motion_counts: { moving: 12252, stationary: 1433, unknown: 172044 },
|
||||
additional_inference_passes: 0,
|
||||
failures: 0,
|
||||
},
|
||||
},
|
||||
decision: {
|
||||
selected_candidate: "rf-detr",
|
||||
ready_for_reference_graph_shadow: true,
|
||||
integrated_world_state_gate_evaluated: true,
|
||||
integrated_world_state_gate_passed: true,
|
||||
detector_replacement_authorized: false,
|
||||
production_accepted: false,
|
||||
},
|
||||
limitations: ["No independent semantic ground truth."],
|
||||
authority,
|
||||
frames: [{
|
||||
frame_id: "000253",
|
||||
source_sequence: 253,
|
||||
counts: { yolox: 4, dfine: 7, "rf-detr": 8 },
|
||||
}],
|
||||
access: "read-only",
|
||||
};
|
||||
}
|
||||
|
||||
test("M4.8S result exposes complete graph load without production authority", async () => {
|
||||
const result = await fetchM48SFixedClassDetectorResult(resultId, {
|
||||
fetcher: async (url) => {
|
||||
assert.equal(
|
||||
url,
|
||||
`/api/v1/laboratory/m48s/fixed-class-detector/${resultId}`,
|
||||
);
|
||||
return response(resultPayload());
|
||||
},
|
||||
});
|
||||
|
||||
assert.equal(result.metrics.detectorLoad.sourceFramesConsumed, 18008);
|
||||
assert.equal(result.metrics.detectorLoad.completionAgeP95Ms, 40.620542);
|
||||
assert.equal(result.metrics.candidates[2].frame253DogScore, 0.741674);
|
||||
assert.equal(result.metrics.integratedWorldState.deliveredWorldStates, 4481);
|
||||
assert.equal(result.metrics.integratedWorldState.worldStateCompletionAgeP95Ms, 74.733648);
|
||||
assert.equal(result.metrics.integratedWorldState.additionalInferencePasses, 0);
|
||||
assert.equal(result.decision.integratedWorldStateGatePassed, true);
|
||||
assert.equal(result.decision.productionAccepted, false);
|
||||
assert.equal(result.authority.navigationOrSafetyAccepted, false);
|
||||
});
|
||||
|
||||
test("M4.8S frame binds exact camera endpoint and risk-only boxes", async () => {
|
||||
const frame = await fetchM48SFixedClassDetectorFrame(resultId, "000253", {
|
||||
fetcher: async () => response({
|
||||
schema_version: "missioncore.m48s-fixed-class-detector-frame/v1",
|
||||
result_id: resultId,
|
||||
frame_id: "000253",
|
||||
source_sequence: 253,
|
||||
camera: {
|
||||
media_type: "image/jpeg",
|
||||
width: 800,
|
||||
height: 600,
|
||||
exact_source_frame: true,
|
||||
},
|
||||
comparison_threshold: 0.5,
|
||||
detections: {
|
||||
yolox: [],
|
||||
dfine: [{ label: "skateboard", score: 0.782227, bbox_xyxy: [236, 334, 274, 372] }],
|
||||
"rf-detr": [{ label: "dog", score: 0.741674, bbox_xyxy: [235, 336, 273, 376] }],
|
||||
},
|
||||
ground_truth_available: false,
|
||||
authority,
|
||||
access: "read-only",
|
||||
}),
|
||||
});
|
||||
|
||||
assert.equal(frame.detections["rf-detr"][0].label, "dog");
|
||||
assert.equal(
|
||||
frame.cameraUrl,
|
||||
`/api/v1/laboratory/m48s/fixed-class-detector/${resultId}/frames/000253/camera`,
|
||||
);
|
||||
assert.equal(frame.groundTruthAvailable, false);
|
||||
});
|
||||
|
||||
test("M4.8S adapter rejects any navigation authority escalation", async () => {
|
||||
await assert.rejects(
|
||||
fetchM48SFixedClassDetectorResult(resultId, {
|
||||
fetcher: async () => response({
|
||||
...resultPayload(),
|
||||
authority: { ...authority, navigation_or_safety_accepted: true },
|
||||
}),
|
||||
}),
|
||||
/navigation_or_safety_accepted/,
|
||||
);
|
||||
});
|
||||
@@ -326,6 +326,100 @@ test("M4.6 timeline keeps only a compact index and decodes bounded spatial chunk
|
||||
assert.equal(selectM4ThreatTimelineFrame(chunk.frames, 35.50).sequence, 1);
|
||||
});
|
||||
|
||||
test("M4.8S timeline binds factory-KB4 camera points through its exact endpoint", async () => {
|
||||
const replayResultId = `m48s-fixed-class-detector-lab-${"b".repeat(64)}`;
|
||||
const endpointRoot = "/api/v1/laboratory/m48s/fixed-class-detector";
|
||||
const frameTimesNs = Array.from(
|
||||
{ length: 4489 },
|
||||
(_, index) => 35_421_857_292 + index * 100_000_000,
|
||||
);
|
||||
let requested = "";
|
||||
const timeline = await fetchM4ThreatTimeline(replayResultId, {
|
||||
endpointRoot,
|
||||
fetcher: async (input) => {
|
||||
requested = String(input);
|
||||
return new Response(JSON.stringify({
|
||||
schema_version: "missioncore.recorded-spatial-evidence-timeline/v1",
|
||||
result_id: replayResultId,
|
||||
recorded_source: {
|
||||
session_id: "20260720T065719Z_viewer_live",
|
||||
source_id: "RAVNOVES00",
|
||||
representation_id: "registered-map-increment-v1",
|
||||
synchronization: "host-arrival-best-effort",
|
||||
},
|
||||
image_width: 800,
|
||||
image_height: 600,
|
||||
frame_count: 4489,
|
||||
frame_times_ns: frameTimesNs,
|
||||
timeline_start_seconds: 35.421857292,
|
||||
timeline_end_seconds: 484.221857292,
|
||||
nominal_frame_interval_seconds: 0.1,
|
||||
nominal_rate_hz: 10,
|
||||
max_chunk_frames: 24,
|
||||
point_sample_limit: 4096,
|
||||
maximum_source_points_per_frame: 3092,
|
||||
point_delivery: "exact-current-increment",
|
||||
camera_point_delivery: "factory-kb4-projected-current-increment",
|
||||
camera_point_sample_limit: 4096,
|
||||
world_state_delivery: "source-paced-latest-wins",
|
||||
world_state_frame_count: 4481,
|
||||
superseded_frame_count: 8,
|
||||
local_surface_visualization: {
|
||||
derivation: "bounded-registered-increment-accumulation",
|
||||
window_seconds: 2,
|
||||
voxel_size_m: 0.1,
|
||||
radius_m: 12,
|
||||
point_limit: 20000,
|
||||
authority: "visual-derived",
|
||||
},
|
||||
rig: { length_m: 1, width_m: 0.6, nominal_sensor_height_m: 1.25 },
|
||||
corridor: {
|
||||
forward_length_m: 8,
|
||||
rear_margin_m: 0.5,
|
||||
half_width_m: 0.5,
|
||||
occupied_voxel_size_m: 0.45,
|
||||
prediction_horizon_seconds: 5,
|
||||
},
|
||||
authority: "replay-simulated",
|
||||
}), { status: 200 });
|
||||
},
|
||||
});
|
||||
assert.equal(requested, `${endpointRoot}/${replayResultId}/timeline`);
|
||||
assert.equal(timeline.cameraPointDelivery, "factory-kb4-projected-current-increment");
|
||||
assert.equal(timeline.worldStateFrameCount, 4481);
|
||||
assert.equal(timeline.supersededFrameCount, 8);
|
||||
|
||||
const chunk = await fetchM4ThreatTimelineChunk(replayResultId, 1, 1, {
|
||||
endpointRoot,
|
||||
fetcher: async (input) => {
|
||||
requested = String(input);
|
||||
return new Response(JSON.stringify({
|
||||
schema_version: "missioncore.recorded-spatial-evidence-chunk/v1",
|
||||
result_id: replayResultId,
|
||||
start_sequence: 1,
|
||||
frame_count: 1,
|
||||
next_sequence: 2,
|
||||
frames: [timelineFrame(1, 35.521857292, {
|
||||
world_state_available: false,
|
||||
terminal_outcome: "superseded",
|
||||
camera_projected_points_xyd: [[100.5, 200.25, 3.75]],
|
||||
camera_projected_source_count: 847,
|
||||
camera_projected_point_count: 1,
|
||||
camera_projected_sample_count: 1,
|
||||
camera_projection: "factory-kb4-exact",
|
||||
camera_url: `${endpointRoot}/${replayResultId}/timeline/frames/1/camera`,
|
||||
})],
|
||||
authority: "replay-simulated",
|
||||
}), { status: 200 });
|
||||
},
|
||||
});
|
||||
assert.match(requested, new RegExp(`^${endpointRoot}/${replayResultId}/timeline/chunk`));
|
||||
assert.equal(chunk.frames[0].worldStateAvailable, false);
|
||||
assert.equal(chunk.frames[0].terminalOutcome, "superseded");
|
||||
assert.deepEqual(chunk.frames[0].cameraProjectedPointsXyd[0], [100.5, 200.25, 3.75]);
|
||||
assert.equal(chunk.frames[0].cameraProjection, "factory-kb4-exact");
|
||||
});
|
||||
|
||||
test("M4.6 local SLAM surface reprojects registered increments into the active body frame", () => {
|
||||
const frames = [
|
||||
timelineFrame(0, 10, {
|
||||
@@ -453,11 +547,12 @@ test("recorded VIDEO clock cannot reverse an explicit operator pause", () => {
|
||||
});
|
||||
|
||||
test("M4.6 viewer keeps media and spatial panes on one playback clock", async () => {
|
||||
const [visual, visualCss, imageScene, videoScene, metricScene] = await Promise.all([
|
||||
const [visual, visualCss, imageScene, videoScene, pointOverlay, metricScene] = await Promise.all([
|
||||
readFile(new URL("../src/workspaces/laboratory/M4ReplayThreatVisual.tsx", import.meta.url), "utf8"),
|
||||
readFile(new URL("../src/styles/m4-replay-threat.css", import.meta.url), "utf8"),
|
||||
readFile(new URL("../src/components/laboratory/RecordedEvidenceImageScene.tsx", import.meta.url), "utf8"),
|
||||
readFile(new URL("../src/components/laboratory/RecordedEvidenceVideoScene.tsx", import.meta.url), "utf8"),
|
||||
readFile(new URL("../src/components/laboratory/RecordedEvidencePointCloudOverlay.tsx", import.meta.url), "utf8"),
|
||||
readFile(new URL("../src/components/laboratory/LaboratoryMetricEvidenceScene.tsx", import.meta.url), "utf8"),
|
||||
]);
|
||||
assert.match(visual, /<RecordedEvidenceVideoScene/);
|
||||
@@ -474,6 +569,8 @@ test("M4.6 viewer keeps media and spatial panes on one playback clock", async ()
|
||||
assert.match(visual, /label: "CAMERA"/);
|
||||
assert.match(visual, /label: "3D"/);
|
||||
assert.match(visual, /label: "PLAN"/);
|
||||
assert.match(visual, />\s*POINTS\s*</);
|
||||
assert.match(visual, /pointCloudOverlay=/);
|
||||
assert.match(visual, /mediaMode/);
|
||||
assert.match(visual, /spatialMode/);
|
||||
assert.match(visual, /current === next \? null : next/);
|
||||
@@ -504,6 +601,9 @@ test("M4.6 viewer keeps media and spatial panes on one playback clock", async ()
|
||||
assert.match(visualCss, /bottom: auto/);
|
||||
assert.match(videoScene, /<RecordedFmp4Player/);
|
||||
assert.match(imageScene, /<RecordedEvidenceBoxOverlay/);
|
||||
assert.match(imageScene, /<RecordedEvidencePointCloudOverlay/);
|
||||
assert.match(videoScene, /<RecordedEvidencePointCloudOverlay/);
|
||||
assert.match(pointOverlay, /factory-kb4-exact/);
|
||||
assert.match(metricScene, /OrbitControls/);
|
||||
assert.match(visual, /LOCAL SLAM/);
|
||||
assert.match(visual, /showLocalSurface/);
|
||||
|
||||
Reference in New Issue
Block a user