feat: add passive K1 local surface replay
This commit is contained in:
@@ -0,0 +1,212 @@
|
||||
import assert from "node:assert/strict";
|
||||
import { after, before, test } from "node:test";
|
||||
|
||||
import { createServer } from "vite";
|
||||
|
||||
let server;
|
||||
let parseLidarLocalSurfaceCatalog;
|
||||
let parseLidarLocalSurfaceFrame;
|
||||
let LidarLocalSurfaceContractError;
|
||||
|
||||
const modelId = `k1-local-surface-${"a".repeat(64)}`;
|
||||
const sourcePackId = `e10-lidar-pack-${"b".repeat(64)}`;
|
||||
|
||||
function distribution(value) {
|
||||
return {
|
||||
sample_count: 10,
|
||||
minimum: value,
|
||||
mean: value,
|
||||
p50: value,
|
||||
p95: value,
|
||||
maximum: value,
|
||||
};
|
||||
}
|
||||
|
||||
function policy(overrides = {}) {
|
||||
return {
|
||||
observed_surface_class: 1,
|
||||
observed_occupied_class: 2,
|
||||
below_surface_or_negative_outlier_class: 3,
|
||||
absence_of_points_means_free: false,
|
||||
unknown_is_traversable: false,
|
||||
persistent_reconstruction_mutated: false,
|
||||
dynamic_object_layer_available: false,
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
function model(overrides = {}) {
|
||||
return {
|
||||
model_id: modelId,
|
||||
display_name: "RAVNOVES00 · динамическая локальная поверхность K1",
|
||||
session_id: "20260720T065719Z_viewer_live",
|
||||
source_pack_id: sourcePackId,
|
||||
status: "diagnostic-only",
|
||||
source: {
|
||||
representation: "legacy-e10-vendor-map-with-pose",
|
||||
immutable: true,
|
||||
passive_processing_only: true,
|
||||
firmware_or_device_commands_used: false,
|
||||
frame_count: 12,
|
||||
available_lidar_frames: 10,
|
||||
point_count: 100,
|
||||
timeline_start_seconds: 1,
|
||||
timeline_end_seconds: 2,
|
||||
},
|
||||
surface_model: {},
|
||||
occupancy_policy: policy(),
|
||||
metrics: {
|
||||
frames: {
|
||||
total: 12,
|
||||
source_available: 10,
|
||||
valid: 10,
|
||||
source_unavailable: 2,
|
||||
pose_stale: 0,
|
||||
insufficient_surface: 0,
|
||||
fit_failed: 0,
|
||||
},
|
||||
sensor_height_m: distribution(1.3),
|
||||
slope_deg: distribution(2),
|
||||
roughness_m: distribution(0.04),
|
||||
confidence: distribution(0.8),
|
||||
pose_binding_age_ms: distribution(7),
|
||||
surface_max_age_ms: distribution(1000),
|
||||
build_elapsed_ms: 20,
|
||||
},
|
||||
anchors: [{
|
||||
key: "long-street",
|
||||
label: "Длинная улица",
|
||||
frame_index: 2,
|
||||
source_frame_index: 1350,
|
||||
session_seconds: 1.5,
|
||||
valid: true,
|
||||
}],
|
||||
decision: {
|
||||
status: "replay-experiment-only",
|
||||
production_promotion: false,
|
||||
next_gate: "shadow",
|
||||
},
|
||||
created_at_utc: "2026-07-25T00:00:00Z",
|
||||
ground_truth: false,
|
||||
authority: {
|
||||
commands_enabled: false,
|
||||
navigation_or_safety_accepted: false,
|
||||
},
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
function catalog(overrides = {}) {
|
||||
return {
|
||||
schema_version: "missioncore.k1-local-surface-catalog/v1",
|
||||
configured: true,
|
||||
items: [model()],
|
||||
valid_total: 1,
|
||||
invalid_total: 0,
|
||||
access: "read-only",
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
function frame(overrides = {}) {
|
||||
return {
|
||||
schema_version: "missioncore.k1-local-surface-frame/v1",
|
||||
model_id: modelId,
|
||||
source_pack_id: sourcePackId,
|
||||
session_id: "20260720T065719Z_viewer_live",
|
||||
frame_index: 2,
|
||||
frame_count: 12,
|
||||
source_frame_index: 1350,
|
||||
session_seconds: 1.5,
|
||||
source_available: true,
|
||||
valid: true,
|
||||
failure_code: 0,
|
||||
point_count: 4,
|
||||
coordinate_frame: "map",
|
||||
distance_unit: "m",
|
||||
points_xyz_m: [[0, 0, 0], [1, 0, 0], [1, 1, 0.7], [2, 0, -0.3]],
|
||||
point_class: [1, 1, 2, 3],
|
||||
point_height_m: [0, 0.02, 0.7, -0.3],
|
||||
pose: {
|
||||
position_xyz_m: [0, 0, 1.3],
|
||||
orientation_xyzw: [0, 0, 0, 1],
|
||||
binding_age_ms: 7,
|
||||
},
|
||||
surface: {
|
||||
plane_coefficients_map: [0, 0, 1, 0],
|
||||
sensor_height_m: 1.3,
|
||||
slope_deg: 0,
|
||||
roughness_m: 0.02,
|
||||
confidence: 0.8,
|
||||
surface_max_age_ms: 1000,
|
||||
cell_count: 40,
|
||||
inlier_cell_count: 35,
|
||||
},
|
||||
counts: {
|
||||
classified: 4,
|
||||
surface: 2,
|
||||
occupied: 1,
|
||||
below_surface: 1,
|
||||
},
|
||||
classes: {},
|
||||
occupancy_policy: policy(),
|
||||
ground_truth: false,
|
||||
access: "read-only",
|
||||
authority: {
|
||||
commands_enabled: false,
|
||||
navigation_or_safety_accepted: false,
|
||||
},
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
before(async () => {
|
||||
server = await createServer({
|
||||
appType: "custom",
|
||||
logLevel: "silent",
|
||||
server: { middlewareMode: true },
|
||||
});
|
||||
({
|
||||
parseLidarLocalSurfaceCatalog,
|
||||
parseLidarLocalSurfaceFrame,
|
||||
LidarLocalSurfaceContractError,
|
||||
} = await server.ssrLoadModule("/src/core/lidar/localSurface.ts"));
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await server?.close();
|
||||
});
|
||||
|
||||
test("decodes passive local-surface evidence", () => {
|
||||
const decoded = parseLidarLocalSurfaceCatalog(catalog());
|
||||
assert.equal(decoded.items[0].source.passiveProcessingOnly, true);
|
||||
assert.equal(decoded.items[0].metrics.sensorHeightM.p50, 1.3);
|
||||
assert.equal(decoded.items[0].anchors[0].sourceFrameIndex, 1350);
|
||||
|
||||
const decodedFrame = parseLidarLocalSurfaceFrame(frame());
|
||||
assert.equal(decodedFrame.counts.occupied, 1);
|
||||
assert.equal(decodedFrame.surface.sensorHeightM, 1.3);
|
||||
});
|
||||
|
||||
test("rejects inferred free space", () => {
|
||||
assert.throws(
|
||||
() => parseLidarLocalSurfaceCatalog(catalog({
|
||||
items: [model({
|
||||
occupancy_policy: policy({ absence_of_points_means_free: true }),
|
||||
})],
|
||||
})),
|
||||
LidarLocalSurfaceContractError,
|
||||
);
|
||||
});
|
||||
|
||||
test("rejects command authority", () => {
|
||||
assert.throws(
|
||||
() => parseLidarLocalSurfaceFrame(frame({
|
||||
authority: {
|
||||
commands_enabled: true,
|
||||
navigation_or_safety_accepted: false,
|
||||
},
|
||||
})),
|
||||
LidarLocalSurfaceContractError,
|
||||
);
|
||||
});
|
||||
Reference in New Issue
Block a user