feat(perception): integrate calibrated operator pipeline

Add calibrated K1 projection, recorded and near-live perception qualification, unified Rerun operator layers, bounded replay admission, audited viewer controls, worker experiments, and lab evidence.
This commit is contained in:
DCCONSTRUCTIONS
2026-07-23 00:23:28 +03:00
parent ada2a55ee6
commit b53d6d5a45
221 changed files with 55923 additions and 1357 deletions
+54 -3
View File
@@ -88,7 +88,22 @@ const paletteOptions: Array<{ value: PointPalette; label: string; description: s
{ value: "custom", label: "Свой цвет", description: "Один назначенный цвет" },
];
function toViewerSettings(settings: SceneSettings): ViewerSettings {
interface LivePerceptionLayers {
detections2d: boolean;
segmentation: boolean;
cuboids3d: boolean;
}
const defaultLivePerceptionLayers: LivePerceptionLayers = {
detections2d: false,
segmentation: false,
cuboids3d: false,
};
function toViewerSettings(
settings: SceneSettings,
perception: LivePerceptionLayers = defaultLivePerceptionLayers,
): ViewerSettings {
return {
point_size: settings.pointSize,
color_mode: settings.colorMode,
@@ -98,6 +113,9 @@ function toViewerSettings(settings: SceneSettings): ViewerSettings {
show_points: settings.showPoints,
show_trajectory: settings.showTrajectory,
show_grid: settings.showGrid,
show_detections_2d: perception.detections2d,
show_segmentation: perception.segmentation,
show_cuboids_3d: perception.cuboids3d,
};
}
@@ -149,6 +167,9 @@ export default function App() {
const [layoutSaveNotice, setLayoutSaveNotice] = useState<string | null>(null);
const [sceneSettings, setSceneSettings] = useState<SceneSettings>(defaultSceneSettings);
const [displayDraft, setDisplayDraft] = useState<SceneSettings>(defaultSceneSettings);
const [livePerceptionLayers, setLivePerceptionLayers] = useState<LivePerceptionLayers>(
defaultLivePerceptionLayers,
);
const sourceSwitchBlocked = isSpatialSourceSwitchBlocked(runtime.state);
const sourceSwitchBlockedReason = sourceSwitchBlocked
? SPATIAL_SOURCE_SWITCH_BLOCKED_REASON
@@ -161,6 +182,8 @@ export default function App() {
const confirmedSceneSettingsRef = useRef<SceneSettings>(defaultSceneSettings);
const viewerSettingsCommitTimerRef = useRef<number | null>(null);
const runtimeUpdateViewerSettingsRef = useRef(runtime.updateViewerSettings);
const livePerceptionLayersRef = useRef<LivePerceptionLayers>(defaultLivePerceptionLayers);
const livePerceptionRevisionRef = useRef(0);
const replayActiveRef = useRef(false);
const sceneSettingsCommitterActiveRef = useRef(true);
const sceneSettingsCommitterRef = useRef<LatestAsyncCommitter<SceneSettings> | null>(null);
@@ -197,7 +220,9 @@ export default function App() {
sceneSettingsCommitterRef.current = createLatestAsyncCommitter<SceneSettings>({
commit: (settings) => replayActiveRef.current
? Promise.resolve(true)
: runtimeUpdateViewerSettingsRef.current(toViewerSettings(settings)),
: runtimeUpdateViewerSettingsRef.current(
toViewerSettings(settings, livePerceptionLayersRef.current),
),
onSettled: ({ value, applied, superseded }) => {
if (!sceneSettingsCommitterActiveRef.current) return;
if (applied) confirmedSceneSettingsRef.current = value;
@@ -275,6 +300,13 @@ export default function App() {
sceneSettingsCommitterRef.current?.isBusy()
) return;
const merged = mergeViewerSettings(sceneSettingsRef.current, remote);
const remoteLayers = {
detections2d: remote.show_detections_2d ?? false,
segmentation: remote.show_segmentation ?? false,
cuboids3d: remote.show_cuboids_3d ?? false,
};
livePerceptionLayersRef.current = remoteLayers;
setLivePerceptionLayers(remoteLayers);
sceneSettingsRef.current = merged;
confirmedSceneSettingsRef.current = merged;
setSceneSettings(merged);
@@ -334,7 +366,9 @@ export default function App() {
return;
}
appliedProfileKeyRef.current = applicationKey;
void runtime.updateViewerSettings(toViewerSettings(profile.sceneSettings)).then((applied) => {
void runtime.updateViewerSettings(
toViewerSettings(profile.sceneSettings, livePerceptionLayersRef.current),
).then((applied) => {
if (!applied && appliedProfileKeyRef.current === applicationKey) {
appliedProfileKeyRef.current = null;
}
@@ -441,6 +475,21 @@ export default function App() {
activateSceneWindow("layers");
};
const changeLivePerceptionLayers = useCallback((next: LivePerceptionLayers) => {
const previous = livePerceptionLayersRef.current;
const revision = ++livePerceptionRevisionRef.current;
livePerceptionLayersRef.current = next;
setLivePerceptionLayers(next);
if (replayActiveRef.current) return;
void runtimeUpdateViewerSettingsRef.current(
toViewerSettings(sceneSettingsRef.current, next),
).then((applied) => {
if (applied || livePerceptionRevisionRef.current !== revision) return;
livePerceptionLayersRef.current = previous;
setLivePerceptionLayers(previous);
});
}, []);
const beginRecordedReplaySwitch = useCallback(async () => {
if (sourceSwitchBlockedRef.current) {
throw new Error(SPATIAL_SOURCE_SWITCH_BLOCKED_REASON);
@@ -706,6 +755,8 @@ export default function App() {
onAccumulationChange={(accumulationSeconds) =>
stageDisplayPatch({ accumulationSeconds })}
onAccumulationCommit={flushDisplaySettings}
livePerceptionLayers={livePerceptionLayers}
onLivePerceptionLayersChange={changeLivePerceptionLayers}
observationLayout={observationLayout}
spatialControls={selection?.SpatialControlsView
? {