feat(lidar): add ground segmentation diagnostic benchmark

This commit is contained in:
DCCONSTRUCTIONS
2026-07-25 02:09:27 +03:00
parent e4fdd9fa20
commit 75a3e669d9
14 changed files with 2235 additions and 15 deletions
@@ -6,8 +6,10 @@ import {
} from "@nodedc/ui-react";
import {
fetchLidarGroundBenchmarks,
fetchLidarReplayCatalog,
fetchLidarReplayDetail,
type LidarGroundBenchmark,
type LidarReplayCatalog,
type LidarReplayDetail,
type LidarStageReadiness,
@@ -53,6 +55,8 @@ export function LidarQualityWorkspace({
}) {
const [catalog, setCatalog] = useState<LidarReplayCatalog | null>(null);
const [detail, setDetail] = useState<LidarReplayDetail | null>(null);
const [groundBenchmark, setGroundBenchmark] =
useState<LidarGroundBenchmark | null>(null);
const [selectedPackId, setSelectedPackId] = useState<string | null>(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
@@ -72,17 +76,25 @@ export function LidarQualityWorkspace({
const target = selectedPackId ?? nextCatalog.items[0]?.packId ?? null;
if (!target) {
setDetail(null);
setGroundBenchmark(null);
return;
}
const nextDetail = await fetchLidarReplayDetail(target, {
signal: controller.signal,
});
const [nextDetail, groundCatalog] = await Promise.all([
fetchLidarReplayDetail(target, {
signal: controller.signal,
}),
fetchLidarGroundBenchmarks(target, {
signal: controller.signal,
}),
]);
if (controller.signal.aborted) return;
setSelectedPackId(target);
setDetail(nextDetail);
setGroundBenchmark(groundCatalog.items[0] ?? null);
} catch (loadError) {
if (controller.signal.aborted) return;
setDetail(null);
setGroundBenchmark(null);
setError(errorMessage(loadError));
} finally {
if (!controller.signal.aborted) setLoading(false);
@@ -226,6 +238,118 @@ export function LidarQualityWorkspace({
</GlassSurface>
</div>
<GlassSurface className="lidar-ground-benchmark" padding="lg">
<header className="panel-heading">
<div>
<span className="section-eyebrow">GROUND A/B · L2</span>
<h2>Текущий heuristic против Patchwork++</h2>
</div>
<StatusBadge tone={groundBenchmark ? "warning" : "neutral"}>
{groundBenchmark ? "Diagnostic only" : "Нет результата"}
</StatusBadge>
</header>
{groundBenchmark ? (
<>
<section
className="lidar-ground-metrics"
aria-label="Ground segmentation A/B"
>
<div>
<span>Текущий ground p50</span>
<strong>
{formatFraction(
groundBenchmark.current.groundFraction.p50,
)}
</strong>
<small>
{formatNumber(
groundBenchmark.current.latencyMs.p95,
2,
)}{" "}
мс p95
</small>
</div>
<div>
<span>Patchwork++ ground p50</span>
<strong>
{formatFraction(
groundBenchmark.candidate.groundFraction.p50,
)}
</strong>
<small>
{formatNumber(
groundBenchmark.candidate.latencyMs.p95,
2,
)}{" "}
мс p95
</small>
</div>
<div>
<span>Algorithm IoU p50</span>
<strong>
{formatFraction(
groundBenchmark.comparison.algorithmGroundIou.p50,
)}
</strong>
<small>Не является accuracy</small>
</div>
<div>
<span>Disagreement p50</span>
<strong>
{formatFraction(
groundBenchmark.comparison
.groundDisagreementFraction.p50,
)}
</strong>
<small>
{groundBenchmark.frames.toLocaleString("ru-RU")} кадров
</small>
</div>
</section>
<div className="lidar-ground-gates">
<div>
<StatusBadge tone="danger">
Входной контракт не принят
</StatusBadge>
<p>
Patchwork++ ожидает sensor-centric scan и физическую высоту
сенсора; текущий point feed является vendor-mapped increment.
</p>
</div>
<div>
<StatusBadge tone="warning">Разметка не принята</StatusBadge>
<p>
IoU, curb recall, low-obstacle recall и reflection-noise
rejection появятся только после независимого human review.
</p>
</div>
<div>
<StatusBadge tone="danger">Не продвигать</StatusBadge>
<p>
Следующий gate: human-reviewed annotation subset или
принятый raw sensor scan с физической высотой сенсора.
</p>
</div>
</div>
<footer className="lidar-ground-footer">
<span>
{groundBenchmark.current.provider.providerId}
</span>
<span>
{groundBenchmark.candidate.provider.providerId}
{groundBenchmark.candidate.provider.sourceCommit
? ` · ${groundBenchmark.candidate.provider.sourceCommit.slice(0, 12)}`
: ""}
</span>
</footer>
</>
) : (
<p className="lidar-ground-empty">
Для выбранного replay pack ещё нет проверенного ground benchmark.
</p>
)}
</GlassSurface>
<GlassSurface className="lidar-pack-catalog" padding="lg">
<header className="panel-heading">
<div>