feat(lidar): add RAVNOVES field review

This commit is contained in:
DCCONSTRUCTIONS
2026-07-25 10:26:07 +03:00
parent 2dfb34ef21
commit 3333e9ac0f
13 changed files with 2775 additions and 14 deletions
@@ -8,10 +8,14 @@ let parseLidarReplayCatalog;
let parseLidarReplayDetail;
let parseLidarGroundBenchmarkCatalog;
let parseLidarGroundFrame;
let parseLidarFieldReviewCatalog;
let parseLidarFieldReviewWindow;
let fetchLidarReplayCatalog;
let fetchLidarReplayDetail;
let fetchLidarGroundBenchmarks;
let fetchLidarGroundFrame;
let fetchLidarFieldReviews;
let fetchLidarFieldReviewWindow;
let LidarReplayContractError;
let workspaceById;
@@ -26,10 +30,14 @@ before(async () => {
parseLidarReplayDetail,
parseLidarGroundBenchmarkCatalog,
parseLidarGroundFrame,
parseLidarFieldReviewCatalog,
parseLidarFieldReviewWindow,
fetchLidarReplayCatalog,
fetchLidarReplayDetail,
fetchLidarGroundBenchmarks,
fetchLidarGroundFrame,
fetchLidarFieldReviews,
fetchLidarFieldReviewWindow,
LidarReplayContractError,
} = await server.ssrLoadModule("/src/core/lidar/replayQuality.ts"));
({ workspaceById } = await server.ssrLoadModule("/src/productModel.ts"));
@@ -40,6 +48,8 @@ after(async () => {
});
const packId = `lidar-replay-pack-${"a".repeat(64)}`;
const fieldReviewId = `lidar-field-review-${"d".repeat(64)}`;
const e10PackId = `e10-lidar-pack-${"e".repeat(64)}`;
function summary(overrides = {}) {
return {
@@ -267,6 +277,145 @@ function groundFrame(overrides = {}) {
};
}
function fieldReviewWindowSummary(overrides = {}) {
return {
index: 0,
key: "intersection-facades",
label: "Перекрёсток, дорога и фасады",
start_seconds: 145,
end_seconds: 151,
midpoint_seconds: 148,
source_lidar_samples: 56,
source_point_count: 98538,
display_point_count: 3,
source_frame_start: 1097,
source_frame_end: 1156,
preview_source_frame_index: 1120,
preview_session_seconds: 147.451857292,
...overrides,
};
}
function fieldReviewCatalog(overrides = {}) {
const provider = (providerId, sourceCommit = undefined) => ({
provider_id: providerId,
source_commit: sourceCommit,
});
const branch = (providerValue) => ({
provider: providerValue,
ground_fraction: distribution(),
latency_ms: distribution(),
});
return {
schema_version: "missioncore.lidar-field-review-catalog/v1",
configured: true,
valid_total: 1,
invalid_total: 0,
access: "read-only",
items: [{
review_id: fieldReviewId,
display_name: "RAVNOVES00 · центральный городской интервал",
session_id: "20260720T065719Z_viewer_live",
source_pack_id: e10PackId,
status: "diagnostic-only",
source: {
timeline_start_seconds: 135.365857292,
timeline_end_seconds: 195.334857292,
available_lidar_frames: 526,
point_count: 1182292,
representation: "legacy-e10-vendor-map-with-pose",
intensity_available: false,
raw_scan_accepted: false,
},
selection: {
purpose: "operator-readable-central-urban-field-review",
default_window_index: 0,
accumulation: "per-source-frame masks accumulated in map frame",
sampling: {
method: "uniform-point-index-per-window",
maximum_points_per_window: 80000,
},
},
windows: [fieldReviewWindowSummary()],
metrics: {
source_samples: 56,
current: branch(
provider("missioncore-local-percentile-ground/v1"),
),
candidate: branch(
provider(
"patchworkpp/v1.4.1",
"3e6903a1d5537a4cc2ace897b0bbb98a92d6014c",
),
),
comparison: {
algorithm_to_algorithm_ground_iou: distribution(),
ground_disagreement_fraction: distribution(),
is_accuracy_metric: false,
},
},
decision: {
status: "visual-review-only",
production_promotion: false,
reasons: ["legacy derivative does not retain intensity"],
},
created_at_utc: "2026-07-25T02:00:00Z",
ground_truth: false,
authority: {
commands_enabled: false,
navigation_or_safety_accepted: false,
},
}],
...overrides,
};
}
function fieldReviewWindow(overrides = {}) {
return {
schema_version: "missioncore.lidar-field-review-window/v1",
review_id: fieldReviewId,
display_name: "RAVNOVES00 · центральный городской интервал",
session_id: "20260720T065719Z_viewer_live",
source_pack_id: e10PackId,
window_index: 0,
window_count: 1,
window: fieldReviewWindowSummary(),
point_count: 3,
coordinate_frame: "map",
distance_unit: "m",
intensity: {
available: false,
reason: "E10 derivative did not retain rgbi/intensity",
},
points_xyz_m: [
[0, 0, 0],
[1, 0, 0.1],
[0, 1, 0.5],
],
masks: {
current_ground: [1, 1, 0],
current_assigned: [1, 1, 1],
candidate_ground: [1, 0, 0],
candidate_assigned: [1, 1, 1],
disagreement: [0, 1, 0],
},
counts: {
current_ground: 2,
candidate_ground: 1,
disagreement: 1,
},
preview_url:
`/api/v1/lidar/field-reviews/${fieldReviewId}/windows/0/preview`,
access: "read-only",
ground_truth: false,
authority: {
commands_enabled: false,
navigation_or_safety_accepted: false,
},
...overrides,
};
}
function jsonResponse(payload, status = 200) {
return new Response(JSON.stringify(payload), {
status,
@@ -359,6 +508,49 @@ test("ground frame stays point-aligned, bounded and path-free", () => {
);
});
test("field review identifies RAVNOVES00 source and stays visual-only", () => {
const parsedCatalog = parseLidarFieldReviewCatalog(fieldReviewCatalog());
const parsedWindow = parseLidarFieldReviewWindow(fieldReviewWindow());
assert.equal(parsedCatalog.items[0].sourcePackId, e10PackId);
assert.equal(parsedCatalog.items[0].source.availableLidarFrames, 526);
assert.equal(parsedCatalog.items[0].selection.defaultWindowIndex, 0);
assert.equal(parsedWindow.window.label, "Перекрёсток, дорога и фасады");
assert.equal(parsedWindow.intensity0To255, null);
assert.equal(parsedWindow.counts.disagreement, 1);
assert.equal("path" in parsedWindow, false);
const promoted = fieldReviewCatalog();
promoted.items[0].decision.production_promotion = true;
assert.throws(
() => parseLidarFieldReviewCatalog(promoted),
LidarReplayContractError,
);
});
test("field-review window refuses forged preview and point masks", () => {
assert.throws(
() => parseLidarFieldReviewWindow(fieldReviewWindow({
preview_url: "https://example.invalid/frame.jpg",
})),
LidarReplayContractError,
);
assert.throws(
() => parseLidarFieldReviewWindow(fieldReviewWindow({
masks: {
...fieldReviewWindow().masks,
disagreement: [0, 0, 0],
},
counts: {
current_ground: 2,
candidate_ground: 1,
disagreement: 0,
},
})),
LidarReplayContractError,
);
});
test("LiDAR fetchers use read-only endpoints and workspace is registered", async () => {
const calls = [];
const fetcher = async (input, init) => {
@@ -368,6 +560,11 @@ test("LiDAR fetchers use read-only endpoints and workspace is registered", async
? jsonResponse(groundFrame())
: jsonResponse(groundCatalog());
}
if (String(input).includes("field-reviews")) {
return String(input).includes("/windows/")
? jsonResponse(fieldReviewWindow())
: jsonResponse(fieldReviewCatalog());
}
return String(input).includes(packId)
? jsonResponse(detail())
: jsonResponse(catalog());
@@ -380,11 +577,19 @@ test("LiDAR fetchers use read-only endpoints and workspace is registered", async
0,
{ fetcher },
);
const fieldCatalog = await fetchLidarFieldReviews({ fetcher });
const fieldWindow = await fetchLidarFieldReviewWindow(
fieldReviewId,
0,
{ fetcher },
);
assert.equal(parsedCatalog.validTotal, 1);
assert.equal(parsedDetail.pack.packId, packId);
assert.equal(ground.validTotal, 1);
assert.equal(frame.pointCount, 3);
assert.equal(fieldCatalog.items[0].windows[0].sourceLidarSamples, 56);
assert.equal(fieldWindow.previewUrl.endsWith("/preview"), true);
assert.deepEqual(calls, [
{ input: "/api/v1/lidar/replay-packs?limit=50", method: "GET" },
{ input: `/api/v1/lidar/replay-packs/${packId}`, method: "GET" },
@@ -396,6 +601,14 @@ test("LiDAR fetchers use read-only endpoints and workspace is registered", async
input: `/api/v1/lidar/ground-benchmarks/ground-benchmark-${"c".repeat(64)}/frames/0`,
method: "GET",
},
{
input: "/api/v1/lidar/field-reviews?limit=10",
method: "GET",
},
{
input: `/api/v1/lidar/field-reviews/${fieldReviewId}/windows/0`,
method: "GET",
},
]);
assert.equal(workspaceById("lidar-quality").root, "data");
assert.equal(workspaceById("lidar-quality").kind, "lidar-quality");