feat(lab): canonize versioned report template
This commit is contained in:
@@ -219,6 +219,16 @@ function SpatialWorkspace({
|
||||
const pointCloudFocused = Boolean(
|
||||
pointCloudSource && observationLayout.focusedSourceId === pointCloudSource.id,
|
||||
);
|
||||
useEffect(() => {
|
||||
if (!pointCloudFocused) return;
|
||||
const onKeyDown = (event: KeyboardEvent) => {
|
||||
if (event.key !== "Escape") return;
|
||||
event.preventDefault();
|
||||
observationLayout.setFocusedSourceId(null);
|
||||
};
|
||||
window.addEventListener("keydown", onKeyDown);
|
||||
return () => window.removeEventListener("keydown", onKeyDown);
|
||||
}, [observationLayout.setFocusedSourceId, pointCloudFocused]);
|
||||
const floatingSourceMaximized = !unifiedPerception &&
|
||||
Boolean(observationLayout.maximizedFloatingSourceId);
|
||||
const timeline = state?.observationTimeline;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import type { ReactNode } from "react";
|
||||
import { StatusBadge } from "@nodedc/ui-react";
|
||||
|
||||
import {
|
||||
LaboratoryEvidence,
|
||||
LaboratoryResultSummary,
|
||||
LaboratorySummary,
|
||||
LaboratoryWorkTemplate,
|
||||
} from "../../components/laboratory/LaboratoryPresentation";
|
||||
@@ -36,6 +36,12 @@ export function E31Result({
|
||||
},
|
||||
{ label: "Контур", value: "Source-scoped · read-only" },
|
||||
]}
|
||||
brief={{
|
||||
question: "Можно ли однозначно связать camera, LiDAR и pose всей записи RAVNOVES00 без подбора соответствий вручную?",
|
||||
approach: "Для каждого кадра проверены временная привязка, чувствительность к offset, доступность pose и self-mask на одном неизменяемом источнике.",
|
||||
principalResult: `${formatNumber(metrics.availableBindingCount, 0)} из ${formatNumber(metrics.frameCount, 0)} кадров получили воспроизводимую source-scoped привязку.`,
|
||||
limitation: "Время основано на host-arrival, профиль действителен только для этой записи и этого монтажа сенсоров.",
|
||||
}}
|
||||
method={{
|
||||
completeness: "complete",
|
||||
executionClass: "deterministic",
|
||||
@@ -70,38 +76,38 @@ export function E31Result({
|
||||
</LaboratoryEvidence>
|
||||
)}
|
||||
result={(
|
||||
<section className="laboratory-result-summary">
|
||||
<header>
|
||||
<div>
|
||||
<span className="section-eyebrow">РЕЗУЛЬТАТ И ВЫВОД</span>
|
||||
<h2>Привязка воспроизводима в границах этого источника</h2>
|
||||
</div>
|
||||
<StatusBadge tone="success">Source profile принят</StatusBadge>
|
||||
</header>
|
||||
<div className="laboratory-result-metrics">
|
||||
<div>
|
||||
<span>Camera ↔ LiDAR p95</span>
|
||||
<strong>{metrics.lidarCameraP95Ms.toLocaleString("ru-RU", { maximumFractionDigits: 2 })} мс</strong>
|
||||
<small>host-arrival binding</small>
|
||||
</div>
|
||||
<div>
|
||||
<span>Pose ↔ point p95</span>
|
||||
<strong>{metrics.posePointP95Ms.toLocaleString("ru-RU", { maximumFractionDigits: 2 })} мс</strong>
|
||||
<small>по доступным кадрам</small>
|
||||
</div>
|
||||
<div>
|
||||
<span>Поддержка соответствий</span>
|
||||
<strong>{(metrics.supportedFraction * 100).toLocaleString("ru-RU", { maximumFractionDigits: 1 })}%</strong>
|
||||
<small>{formatNumber(metrics.correspondenceCount, 0)} соответствий</small>
|
||||
</div>
|
||||
<div>
|
||||
<span>Self-mask</span>
|
||||
<strong>{formatNumber(metrics.semanticSelfSampleCount, 0)} образцов</strong>
|
||||
<small>{formatNumber(metrics.semanticSelfCollateralCount, 0)} collateral</small>
|
||||
</div>
|
||||
</div>
|
||||
<p>Результат диагностический: он не переносится на другой монтаж сенсоров и не выдаёт командных полномочий.</p>
|
||||
</section>
|
||||
<LaboratoryResultSummary
|
||||
title="Привязка воспроизводима в границах этого источника"
|
||||
status="Source profile принят"
|
||||
statusTone="success"
|
||||
metrics={[
|
||||
{
|
||||
label: "Camera ↔ LiDAR p95",
|
||||
value: `${metrics.lidarCameraP95Ms.toLocaleString("ru-RU", { maximumFractionDigits: 2 })} мс`,
|
||||
hint: "host-arrival binding",
|
||||
},
|
||||
{
|
||||
label: "Pose ↔ point p95",
|
||||
value: `${metrics.posePointP95Ms.toLocaleString("ru-RU", { maximumFractionDigits: 2 })} мс`,
|
||||
hint: "по доступным кадрам",
|
||||
},
|
||||
{
|
||||
label: "Поддержка соответствий",
|
||||
value: `${(metrics.supportedFraction * 100).toLocaleString("ru-RU", { maximumFractionDigits: 1 })}%`,
|
||||
hint: `${formatNumber(metrics.correspondenceCount, 0)} соответствий`,
|
||||
},
|
||||
{
|
||||
label: "Self-mask",
|
||||
value: `${formatNumber(metrics.semanticSelfSampleCount, 0)} образцов`,
|
||||
hint: `${formatNumber(metrics.semanticSelfCollateralCount, 0)} collateral`,
|
||||
},
|
||||
]}
|
||||
conclusion={{
|
||||
proved: "Camera, LiDAR и pose воспроизводимо связаны для неизменяемой записи RAVNOVES00 в заявленных границах source profile.",
|
||||
notProved: "Не доказаны аппаратная синхронизация, переносимость профиля на другую запись или другой монтаж и пригодность результата для управления.",
|
||||
decision: "Принять source-scoped профиль как диагностический вход E32; команды, навигация и safety остаются запрещены.",
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import type { ReactNode } from "react";
|
||||
import { StatusBadge } from "@nodedc/ui-react";
|
||||
|
||||
import {
|
||||
LaboratoryEvidence,
|
||||
LaboratoryResultSummary,
|
||||
LaboratorySummary,
|
||||
LaboratoryWorkTemplate,
|
||||
} from "../../components/laboratory/LaboratoryPresentation";
|
||||
@@ -33,6 +33,12 @@ export function E32Result({
|
||||
{ label: "Кадры", value: formatNumber(metrics.framesTotal, 0) },
|
||||
{ label: "Контур", value: "Diagnostic replay · read-only" },
|
||||
]}
|
||||
brief={{
|
||||
question: "Можно ли детерминированно превратить полную принятую запись E29/E31 в покадровый TrackGeometry без повторной настройки порогов?",
|
||||
approach: "Для каждого кадра применены один source profile, единый арбитраж перекрывающихся наблюдений, self-mask и запрет публикации диапазонов без квалифицированного источника.",
|
||||
principalResult: `TrackGeometry построен для ${formatNumber(metrics.framesTotal, 0)} кадров; опубликовано ${formatNumber(metrics.qualifiedPointsPublished, 0)} квалифицированных точек.`,
|
||||
limitation: "Результат наследует качество входных наблюдений и не считает отсутствие LiDAR-точек доказательством свободного пространства.",
|
||||
}}
|
||||
method={{
|
||||
completeness: "complete",
|
||||
executionClass: "deterministic",
|
||||
@@ -67,38 +73,38 @@ export function E32Result({
|
||||
</LaboratoryEvidence>
|
||||
)}
|
||||
result={(
|
||||
<section className="laboratory-result-summary">
|
||||
<header>
|
||||
<div>
|
||||
<span className="section-eyebrow">РЕЗУЛЬТАТ И ВЫВОД</span>
|
||||
<h2>TrackGeometry построен без повторной настройки порогов</h2>
|
||||
</div>
|
||||
<StatusBadge tone="success">Детерминированный replay</StatusBadge>
|
||||
</header>
|
||||
<div className="laboratory-result-metrics">
|
||||
<div>
|
||||
<span>Опубликовано точек</span>
|
||||
<strong>{formatNumber(metrics.qualifiedPointsPublished, 0)}</strong>
|
||||
<small>{formatNumber(metrics.qualifiedPointsWithheld, 0)} withheld</small>
|
||||
</div>
|
||||
<div>
|
||||
<span>Арбитраж наблюдений</span>
|
||||
<strong>{formatNumber(metrics.observationsArbitrated, 0)}</strong>
|
||||
<small>{formatNumber(metrics.overlappingClaimsRemoved, 0)} overlap снято</small>
|
||||
</div>
|
||||
<div>
|
||||
<span>Semantic</span>
|
||||
<strong>{formatNumber(metrics.semanticPublished, 0)}</strong>
|
||||
<small>{formatNumber(metrics.semanticMasked, 0)} self-mask</small>
|
||||
</div>
|
||||
<div>
|
||||
<span>Frame processing p95</span>
|
||||
<strong>{metrics.frameProcessingP95Ms.toLocaleString("ru-RU", { maximumFractionDigits: 3 })} мс</strong>
|
||||
<small>{(metrics.buildElapsedMs / 1000).toLocaleString("ru-RU", { maximumFractionDigits: 2 })} с build</small>
|
||||
</div>
|
||||
</div>
|
||||
<p>Отсутствие LiDAR-точек по-прежнему не трактуется как свободное пространство; результат не является навигационным ground truth.</p>
|
||||
</section>
|
||||
<LaboratoryResultSummary
|
||||
title="TrackGeometry построен без повторной настройки порогов"
|
||||
status="Детерминированный replay"
|
||||
statusTone="success"
|
||||
metrics={[
|
||||
{
|
||||
label: "Опубликовано точек",
|
||||
value: formatNumber(metrics.qualifiedPointsPublished, 0),
|
||||
hint: `${formatNumber(metrics.qualifiedPointsWithheld, 0)} withheld`,
|
||||
},
|
||||
{
|
||||
label: "Арбитраж наблюдений",
|
||||
value: formatNumber(metrics.observationsArbitrated, 0),
|
||||
hint: `${formatNumber(metrics.overlappingClaimsRemoved, 0)} overlap снято`,
|
||||
},
|
||||
{
|
||||
label: "Semantic",
|
||||
value: formatNumber(metrics.semanticPublished, 0),
|
||||
hint: `${formatNumber(metrics.semanticMasked, 0)} self-mask`,
|
||||
},
|
||||
{
|
||||
label: "Frame processing p95",
|
||||
value: `${metrics.frameProcessingP95Ms.toLocaleString("ru-RU", { maximumFractionDigits: 3 })} мс`,
|
||||
hint: `${(metrics.buildElapsedMs / 1000).toLocaleString("ru-RU", { maximumFractionDigits: 2 })} с build`,
|
||||
},
|
||||
]}
|
||||
conclusion={{
|
||||
proved: "Принятый source profile воспроизводимо материализует покадровый TrackGeometry с единственным владельцем перекрывающихся LiDAR-точек.",
|
||||
notProved: "Не доказаны полнота препятствий, свободное пространство при отсутствии точек и навигационная точность геометрии.",
|
||||
decision: "Принять TrackGeometry как неизменяемый диагностический вход worker shadow; не использовать как navigation ground truth.",
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import type { ReactNode } from "react";
|
||||
import { StatusBadge } from "@nodedc/ui-react";
|
||||
|
||||
import {
|
||||
LaboratoryEvidence,
|
||||
LaboratoryResultSummary,
|
||||
LaboratorySummary,
|
||||
LaboratoryWorkTemplate,
|
||||
} from "../../components/laboratory/LaboratoryPresentation";
|
||||
@@ -23,33 +23,52 @@ export function E33Result({
|
||||
<LaboratoryWorkTemplate
|
||||
summary={(
|
||||
<LaboratorySummary
|
||||
title="LAB E33 · worker shadow 1×"
|
||||
description="Полная запись TrackGeometry выполнена отдельным bounded worker в темпе исходника 1×. Проверены очереди, доставка каждого кадра, задержка результата и ресурсы без подключения командного канала."
|
||||
status="Worker gate пройден"
|
||||
title="LAB E33 · проверка TrackGeometry worker в реальном темпе"
|
||||
description="Проверяли не качество распознавания объектов, а способность отдельного worker принять уже готовый TrackGeometry и вернуть явный результат по каждому кадру без накопления задержки и скрытых потерь."
|
||||
status="Принят как worker shadow"
|
||||
statusTone="success"
|
||||
facts={[
|
||||
{ label: "Конфигурация", value: `${rigLabel} · worker shadow` },
|
||||
{ label: "Worker", value: result.worker.node },
|
||||
{ label: "Доставка", value: `${formatNumber(metrics.deliveredFrames, 0)} / ${formatNumber(metrics.sourceFrames, 0)} кадров` },
|
||||
{ label: "Контур", value: "Recorded-source-paced · 1×" },
|
||||
{ label: "Источник", value: `${rigLabel} · RAVNOVES00` },
|
||||
{
|
||||
label: "Объём проверки",
|
||||
value: `${formatNumber(metrics.sourceFrames, 0)} кадров · ${metrics.sourceSpanSeconds.toLocaleString("ru-RU", { maximumFractionDigits: 1 })} с`,
|
||||
},
|
||||
{
|
||||
label: "Геометрия доступна",
|
||||
value: `${formatNumber(metrics.sourceAvailableFrames, 0)} / ${formatNumber(metrics.sourceFrames, 0)} кадров`,
|
||||
},
|
||||
{ label: "Полномочия", value: "Read-only · команды и safety выключены" },
|
||||
]}
|
||||
brief={{
|
||||
question: "Сможет ли отдельный worker обработать всю запись в исходном темпе 1×, не теряя кадры и не раздувая очереди?",
|
||||
approach: "Готовый TrackGeometry из E32 выпускался по исходным временным меткам через отдельные work/result очереди ёмкостью 2. Для каждого кадра фиксировался один терминальный исход, задержка и использование памяти.",
|
||||
principalResult: `Да. Доставлены все ${formatNumber(metrics.deliveredFrames, 0)} исходов, замен и deadline miss не было; p95 возраста результата — ${metrics.resultAgeP95Ms.toLocaleString("ru-RU", { maximumFractionDigits: 3 })} мс.`,
|
||||
limitation: `Детектор, semantic-модели и качество геометрии здесь не пересчитывались. В ${formatNumber(metrics.sourceUnavailableFrames, 0)} кадрах источник уже не содержал квалифицированной геометрии.`,
|
||||
}}
|
||||
method={{
|
||||
completeness: "complete",
|
||||
executionClass: "deterministic",
|
||||
pipelineId: result.pipelineId,
|
||||
pipelineId: "TrackGeometry → recorded-paced bounded worker",
|
||||
components: [
|
||||
{
|
||||
kind: "source",
|
||||
name: result.e32ResultId,
|
||||
version: "accepted TrackGeometry replay",
|
||||
role: "immutable frame stream",
|
||||
identitySha256: result.e32ResultId.split("-").at(-1) ?? null,
|
||||
name: "Принятый TrackGeometry из LAB E32",
|
||||
version: `${formatNumber(metrics.sourceFrames, 0)} кадров · неизменяемая запись`,
|
||||
role: "готовый вход; detector и semantic inference не запускались повторно",
|
||||
identitySha256: null,
|
||||
},
|
||||
{
|
||||
kind: "algorithm",
|
||||
name: "Recorded pacing + bounded latest-wins queues",
|
||||
version: `1× · очереди ${metrics.workQueueCapacity}/${metrics.resultQueueCapacity}`,
|
||||
role: "выпуск по исходному времени, закрытый учёт исходов и deadline-контроль",
|
||||
identitySha256: null,
|
||||
},
|
||||
{
|
||||
kind: "runtime",
|
||||
name: result.worker.node,
|
||||
version: `${result.worker.python} · NumPy ${result.worker.numpy}`,
|
||||
role: "bounded worker, work/result queues 2/2",
|
||||
name: "Изолированный worker",
|
||||
version: `${result.worker.node} · Python ${result.worker.python} · NumPy ${result.worker.numpy}`,
|
||||
role: "проверка структуры TrackGeometry, SHA-256 диапазонов PointSlab и публикация результата",
|
||||
identitySha256: null,
|
||||
},
|
||||
],
|
||||
@@ -59,7 +78,7 @@ export function E33Result({
|
||||
evidence={(
|
||||
<LaboratoryEvidence
|
||||
eyebrow="ИСХОДНОЕ ДОКАЗАТЕЛЬСТВО"
|
||||
title="Запись, доставленная worker без потерь"
|
||||
title="Контрольная запись: кадры и TrackGeometry, которые доставлял worker"
|
||||
kind="recorded-replay"
|
||||
resizable
|
||||
>
|
||||
@@ -67,40 +86,38 @@ export function E33Result({
|
||||
</LaboratoryEvidence>
|
||||
)}
|
||||
result={(
|
||||
<section className="laboratory-result-summary">
|
||||
<header>
|
||||
<div>
|
||||
<span className="section-eyebrow">РЕЗУЛЬТАТ И ВЫВОД</span>
|
||||
<h2>Полный replay выдержан в темпе источника</h2>
|
||||
</div>
|
||||
<StatusBadge tone="success">
|
||||
{formatNumber(metrics.deliveredFrames, 0)} / {formatNumber(metrics.sourceFrames, 0)}
|
||||
</StatusBadge>
|
||||
</header>
|
||||
<div className="laboratory-result-metrics">
|
||||
<div>
|
||||
<span>Эффективная частота</span>
|
||||
<strong>{metrics.effectiveDeliveryFps.toLocaleString("ru-RU", { maximumFractionDigits: 3 })} FPS</strong>
|
||||
<small>скорость источника 1×</small>
|
||||
</div>
|
||||
<div>
|
||||
<span>Result age p95</span>
|
||||
<strong>{metrics.resultAgeP95Ms.toLocaleString("ru-RU", { maximumFractionDigits: 3 })} мс</strong>
|
||||
<small>{(metrics.deadlineMissFraction * 100).toLocaleString("ru-RU", { maximumFractionDigits: 2 })}% deadline miss</small>
|
||||
</div>
|
||||
<div>
|
||||
<span>Processing p95</span>
|
||||
<strong>{metrics.processingP95Ms.toLocaleString("ru-RU", { maximumFractionDigits: 3 })} мс</strong>
|
||||
<small>{metrics.releaseLagP95Ms.toLocaleString("ru-RU", { maximumFractionDigits: 3 })} мс release lag</small>
|
||||
</div>
|
||||
<div>
|
||||
<span>Ресурсы p95</span>
|
||||
<strong>{metrics.processRssP95Mib.toLocaleString("ru-RU", { maximumFractionDigits: 1 })} MiB</strong>
|
||||
<small>GPU {metrics.gpuUtilizationP95Percent.toLocaleString("ru-RU", { maximumFractionDigits: 1 })}%</small>
|
||||
</div>
|
||||
</div>
|
||||
<p>Очереди остались bounded, пропусков нет. Результат подтверждает только worker shadow и не даёт навигационных или safety-полномочий.</p>
|
||||
</section>
|
||||
<LaboratoryResultSummary
|
||||
title="Worker выдержал запись; качество восприятия этим прогоном не проверялось"
|
||||
status="Worker shadow принят"
|
||||
statusTone="success"
|
||||
metrics={[
|
||||
{
|
||||
label: "Доставка исходов",
|
||||
value: `${formatNumber(metrics.deliveredFrames, 0)} / ${formatNumber(metrics.sourceFrames, 0)}`,
|
||||
hint: "0 замен · 0 пропусков",
|
||||
},
|
||||
{
|
||||
label: "Темп обработки",
|
||||
value: `${metrics.effectiveDeliveryFps.toLocaleString("ru-RU", { maximumFractionDigits: 3 })} FPS`,
|
||||
hint: "исходная скорость 10 FPS · 1×",
|
||||
},
|
||||
{
|
||||
label: "Возраст результата",
|
||||
value: `${metrics.resultAgeP95Ms.toLocaleString("ru-RU", { maximumFractionDigits: 3 })} мс p95`,
|
||||
hint: `${metrics.resultAgeMaxMs.toLocaleString("ru-RU", { maximumFractionDigits: 3 })} мс max · лимит ${formatNumber(metrics.resultDeadlineMs, 0)} мс`,
|
||||
},
|
||||
{
|
||||
label: "Память процесса",
|
||||
value: `${metrics.processRssMaxMib.toLocaleString("ru-RU", { maximumFractionDigits: 1 })} MiB max`,
|
||||
hint: `лимит ${formatNumber(metrics.processRssLimitMib, 0)} MiB`,
|
||||
},
|
||||
]}
|
||||
conclusion={{
|
||||
proved: "Финальная стадия публикации TrackGeometry на этом worker успевает за данной записью: очереди ограничены, каждый кадр учтён, задержка остаётся ниже заявленного deadline.",
|
||||
notProved: "Прогон не измеряет точность машин, кубов или сегментации, не запускает заново detector/semantic pipeline и не доказывает переносимость на другую запись или монтаж сенсоров.",
|
||||
decision: "Результат принимается только как диагностический worker shadow. Он допускает дальнейшие лабораторные испытания временного occupied/unknown слоя, но не включает команды, навигацию или safety.",
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -44,8 +44,11 @@ import type { WorkspaceRendererProps } from "../contracts";
|
||||
import { E31Result } from "./E31Result";
|
||||
import { E32Result } from "./E32Result";
|
||||
import { E33Result } from "./E33Result";
|
||||
import {
|
||||
e28LaboratoryBrief, e29LaboratoryBrief,
|
||||
e30LaboratoryBrief, PUBLISHED_LABORATORY_BRIEF,
|
||||
} from "./laboratoryArchiveBriefs";
|
||||
import { RecordedReplayEvidence } from "./RecordedReplayEvidence";
|
||||
|
||||
type LaboratoryWorkspaceProps = WorkspaceRendererProps & {
|
||||
SpatialView: ComponentType<WorkspaceRendererProps>;
|
||||
};
|
||||
@@ -227,6 +230,7 @@ function E29LaboratoryResult({
|
||||
value: "Read-only · hash verified",
|
||||
},
|
||||
]}
|
||||
brief={e29LaboratoryBrief(formatNumber(semantic.total, 0))}
|
||||
method={{
|
||||
completeness: "complete",
|
||||
executionClass: "hybrid",
|
||||
@@ -411,6 +415,7 @@ function E30LaboratoryResult({
|
||||
{ label: "Кейсов", value: formatNumber(result.itemCount, 0) },
|
||||
{ label: "Контур", value: "Read-only · без LAB publish" },
|
||||
]}
|
||||
brief={e30LaboratoryBrief(formatNumber(result.itemCount, 0))}
|
||||
/>
|
||||
)}
|
||||
evidence={(
|
||||
@@ -483,6 +488,7 @@ function PublishedLaboratoryResult({
|
||||
{ label: "Конфигурация", value: lab?.configSha256?.slice(0, 16) ?? "Не зафиксирована" },
|
||||
{ label: "Контур", value: "Диагностика · без команд" },
|
||||
]}
|
||||
brief={PUBLISHED_LABORATORY_BRIEF}
|
||||
method={publishedLaboratoryMethod(session)}
|
||||
/>
|
||||
)}
|
||||
@@ -867,6 +873,10 @@ export function LaboratoryArchiveWorkspace(props: LaboratoryWorkspaceProps) {
|
||||
{ label: "Режим", value: "Recorded-source-paced shadow" },
|
||||
{ label: "Контур", value: "Read-only · hash verified" },
|
||||
]}
|
||||
brief={e28LaboratoryBrief(
|
||||
formatNumber(e28Model?.metrics.frames.valid ?? 0, 0),
|
||||
formatNumber(e28Model?.metrics.frames.total ?? 0, 0),
|
||||
)}
|
||||
method={{
|
||||
completeness: "complete",
|
||||
executionClass: e28Model?.method.executionClass ?? "deterministic",
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
import type {
|
||||
LaboratoryBrief,
|
||||
} from "../../components/laboratory/LaboratoryPresentation";
|
||||
|
||||
export function e28LaboratoryBrief(
|
||||
validFrames: string,
|
||||
totalFrames: string,
|
||||
): LaboratoryBrief {
|
||||
return {
|
||||
question: "Можно ли устойчиво оценивать локальную поверхность и временные остатки на полной записи без изменения источника?",
|
||||
approach: "LiDAR и pose воспроизводятся через bounded recorded-source-paced shadow; rolling local plane оценивает поверхность, препятствия и temporal residuals.",
|
||||
principalResult: `${validFrames} из ${totalFrames} кадров прошли диагностическую обработку L2.6.`,
|
||||
limitation: "Модель проверена только на RAVNOVES00 и не получает командных, навигационных или safety-полномочий.",
|
||||
};
|
||||
}
|
||||
|
||||
export function e29LaboratoryBrief(
|
||||
observationCount: string,
|
||||
): LaboratoryBrief {
|
||||
return {
|
||||
question: "Совпадают ли camera-семантика объекта и независимая LiDAR-геометрия в одном точном кадре?",
|
||||
approach: "Camera сохраняет класс и идентичность, а локальная поверхность L2.6 отдельно проверяет дальность, occupied support и конфликт принадлежности точек.",
|
||||
principalResult: `${observationCount} наблюдений разложены по согласованию camera и geometry без объявления пустого LiDAR свободным пространством.`,
|
||||
limitation: "Результат зависит от точности исходной camera-семантики и локальной поверхности; он остаётся диагностическим и read-only.",
|
||||
};
|
||||
}
|
||||
|
||||
export function e30LaboratoryBrief(
|
||||
itemCount: string,
|
||||
): LaboratoryBrief {
|
||||
return {
|
||||
question: "Можно ли человеку проверить спорный camera/LiDAR-кейс по понятному совмещённому доказательству, а не по изолированному облаку точек?",
|
||||
approach: "Каждый кейс связан с точным camera frame, переключаемой LiDAR-проекцией, frame-local индексами и синхронным 3D в одном viewer.",
|
||||
principalResult: `${itemCount} кейсов доступны для camera-first проверки и отдельного разбора только неоднозначных исключений.`,
|
||||
limitation: "Рабочее место не меняет исходный A2 и не превращает решение оператора в navigation или safety ground truth.",
|
||||
};
|
||||
}
|
||||
|
||||
export const PUBLISHED_LABORATORY_BRIEF: LaboratoryBrief = {
|
||||
question: "Что было зафиксировано опубликованной лабораторной работой на её неизменяемом источнике?",
|
||||
approach: "Mission Core открывает связанный source replay и проецирует только опубликованные method/provenance и метрики без реконструкции отсутствующих данных.",
|
||||
principalResult: "Оператор получает исходное визуальное доказательство и зафиксированный результат одного LAB run в общей продуктовой форме.",
|
||||
limitation: "Для legacy-результатов часть идентичностей и метрик могла не публиковаться; приложение их не выдумывает задним числом.",
|
||||
};
|
||||
Reference in New Issue
Block a user