feat(lidar): add ground segmentation diagnostic benchmark
This commit is contained in:
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user