feat(lidar): add point-aligned ground review
This commit is contained in:
@@ -7,9 +7,11 @@ let server;
|
||||
let parseLidarReplayCatalog;
|
||||
let parseLidarReplayDetail;
|
||||
let parseLidarGroundBenchmarkCatalog;
|
||||
let parseLidarGroundFrame;
|
||||
let fetchLidarReplayCatalog;
|
||||
let fetchLidarReplayDetail;
|
||||
let fetchLidarGroundBenchmarks;
|
||||
let fetchLidarGroundFrame;
|
||||
let LidarReplayContractError;
|
||||
let workspaceById;
|
||||
|
||||
@@ -23,9 +25,11 @@ before(async () => {
|
||||
parseLidarReplayCatalog,
|
||||
parseLidarReplayDetail,
|
||||
parseLidarGroundBenchmarkCatalog,
|
||||
parseLidarGroundFrame,
|
||||
fetchLidarReplayCatalog,
|
||||
fetchLidarReplayDetail,
|
||||
fetchLidarGroundBenchmarks,
|
||||
fetchLidarGroundFrame,
|
||||
LidarReplayContractError,
|
||||
} = await server.ssrLoadModule("/src/core/lidar/replayQuality.ts"));
|
||||
({ workspaceById } = await server.ssrLoadModule("/src/productModel.ts"));
|
||||
@@ -176,6 +180,11 @@ function groundCatalog(overrides = {}) {
|
||||
representation: "vendor-map-increment",
|
||||
physical_sensor_height_known: false,
|
||||
sensor_scan_geometry_known: false,
|
||||
normalization: {
|
||||
sensor_height_m: 1.27,
|
||||
map_vertical_origin_offset_m: 1.27,
|
||||
height_evidence: "operator-estimated",
|
||||
},
|
||||
reason: "Patchwork++ expects sensor-centric scans.",
|
||||
},
|
||||
labels: {
|
||||
@@ -218,6 +227,46 @@ function groundCatalog(overrides = {}) {
|
||||
};
|
||||
}
|
||||
|
||||
function groundFrame(overrides = {}) {
|
||||
return {
|
||||
schema_version: "missioncore.lidar-ground-frame/v1",
|
||||
benchmark_id: `ground-benchmark-${"c".repeat(64)}`,
|
||||
replay_pack_id: packId,
|
||||
session_id: "20260719T220917Z_viewer_live",
|
||||
frame_index: 0,
|
||||
frame_count: 2,
|
||||
capture_sequence: 42,
|
||||
point_count: 3,
|
||||
coordinate_frame: "map",
|
||||
distance_unit: "m",
|
||||
points_xyz_m: [
|
||||
[0, 0, 0],
|
||||
[1, 0, 0.1],
|
||||
[0, 1, 0.5],
|
||||
],
|
||||
intensity_0_255: [10, 120, 255],
|
||||
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,
|
||||
},
|
||||
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,
|
||||
@@ -252,6 +301,10 @@ test("ground benchmark stays diagnostic until input and labels are accepted", ()
|
||||
assert.equal(parsed.items[0].inputDomain.accepted, false);
|
||||
assert.equal(parsed.items[0].labels.metricsAvailable, false);
|
||||
assert.equal(parsed.items[0].candidate.groundFraction.p50, 0.005);
|
||||
assert.equal(
|
||||
parsed.items[0].inputDomain.normalization.heightEvidence,
|
||||
"operator-estimated",
|
||||
);
|
||||
assert.equal(parsed.items[0].decision.productionPromotion, false);
|
||||
|
||||
const promoted = groundCatalog();
|
||||
@@ -262,12 +315,58 @@ test("ground benchmark stays diagnostic until input and labels are accepted", ()
|
||||
);
|
||||
});
|
||||
|
||||
test("ground frame stays point-aligned, bounded and path-free", () => {
|
||||
const parsed = parseLidarGroundFrame(groundFrame());
|
||||
|
||||
assert.equal(parsed.pointCount, 3);
|
||||
assert.deepEqual(parsed.pointsXyzM[1], [1, 0, 0.1]);
|
||||
assert.deepEqual(parsed.masks.disagreement, [0, 1, 0]);
|
||||
assert.equal(parsed.counts.currentGround, 2);
|
||||
assert.equal("path" in parsed, false);
|
||||
|
||||
assert.throws(
|
||||
() => parseLidarGroundFrame(groundFrame({
|
||||
masks: {
|
||||
...groundFrame().masks,
|
||||
disagreement: [0, 1],
|
||||
},
|
||||
})),
|
||||
LidarReplayContractError,
|
||||
);
|
||||
assert.throws(
|
||||
() => parseLidarGroundFrame(groundFrame({
|
||||
counts: {
|
||||
current_ground: 1,
|
||||
candidate_ground: 1,
|
||||
disagreement: 1,
|
||||
},
|
||||
})),
|
||||
LidarReplayContractError,
|
||||
);
|
||||
assert.throws(
|
||||
() => parseLidarGroundFrame(groundFrame({
|
||||
masks: {
|
||||
...groundFrame().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) => {
|
||||
calls.push({ input: String(input), method: init?.method });
|
||||
if (String(input).includes("ground-benchmarks")) {
|
||||
return jsonResponse(groundCatalog());
|
||||
return String(input).includes("/frames/")
|
||||
? jsonResponse(groundFrame())
|
||||
: jsonResponse(groundCatalog());
|
||||
}
|
||||
return String(input).includes(packId)
|
||||
? jsonResponse(detail())
|
||||
@@ -276,10 +375,16 @@ test("LiDAR fetchers use read-only endpoints and workspace is registered", async
|
||||
const parsedCatalog = await fetchLidarReplayCatalog({ fetcher });
|
||||
const parsedDetail = await fetchLidarReplayDetail(packId, { fetcher });
|
||||
const ground = await fetchLidarGroundBenchmarks(packId, { fetcher });
|
||||
const frame = await fetchLidarGroundFrame(
|
||||
`ground-benchmark-${"c".repeat(64)}`,
|
||||
0,
|
||||
{ fetcher },
|
||||
);
|
||||
|
||||
assert.equal(parsedCatalog.validTotal, 1);
|
||||
assert.equal(parsedDetail.pack.packId, packId);
|
||||
assert.equal(ground.validTotal, 1);
|
||||
assert.equal(frame.pointCount, 3);
|
||||
assert.deepEqual(calls, [
|
||||
{ input: "/api/v1/lidar/replay-packs?limit=50", method: "GET" },
|
||||
{ input: `/api/v1/lidar/replay-packs/${packId}`, method: "GET" },
|
||||
@@ -287,6 +392,10 @@ test("LiDAR fetchers use read-only endpoints and workspace is registered", async
|
||||
input: `/api/v1/lidar/ground-benchmarks?pack_id=${packId}&limit=20`,
|
||||
method: "GET",
|
||||
},
|
||||
{
|
||||
input: `/api/v1/lidar/ground-benchmarks/ground-benchmark-${"c".repeat(64)}/frames/0`,
|
||||
method: "GET",
|
||||
},
|
||||
]);
|
||||
assert.equal(workspaceById("lidar-quality").root, "data");
|
||||
assert.equal(workspaceById("lidar-quality").kind, "lidar-quality");
|
||||
|
||||
Reference in New Issue
Block a user