4.8 KiB
ADR 0006: Vendor-neutral observation sources and live-only timeline
Status: accepted for the experimental Mission Core runtime, 2026-07-16.
Scope update, 2026-07-17: the live device descriptors in this ADR remain
live-only. ADR 0008 adds a separate host-owned recorded-source catalog,
seekable session_time playback and workspace layout; it does not retroactively
turn a live RTSP lease into recorded evidence.
Context
The spatial scene and camera workspace must accept one device, a custom rig or a future multi-sensor vehicle without adding vendor-specific branches to the host UI. The currently verified K1 profile exposes one spatial visualization path and two path-labelled H.264 camera preview producers. The direct physical gate showed that only one K1 preview producer can deliver frames at a time. A shared point-cloud/video clock and camera intrinsics/extrinsics remain unavailable.
Hard-coded camera slots, direct RTSP URLs in React components and an apparently seekable timeline would therefore create three false contracts: a fixed sensor count, browser ownership of device transport and replay that does not exist.
Decision
- A device plugin normalizes its capabilities into
ObservationSourceDescriptor[]. Mission Core consumes only these generic descriptors. ididentifies a runtime source instance;sourceIdidentifies the producer inside the plugin model;semanticChannelIddescribes the canonical channel. Transport addresses are not identities.- Provider metadata and device/session/acquisition binding are separate. A new acquisition may change layout context without changing the logical producer.
- The host owns visibility, z-order, position, resize and fullscreen. A plugin cannot inject global layout behavior.
- Direct device RTSP URLs do not cross into the generic UI. The read-only K1 adapter publishes an opaque, same-origin fMP4/WebSocket delivery lease.
- A descriptor may declare a generic activation group, capacity and selection
state. The K1 camera producers share one group with
maxActive=1; frontend layout enforces it for UX and the plugin remains the backend authority. - Until a bounded buffer and clock mapping exist, the shared timeline is
live-only,seekable=false,sessionRecording=falseand explicitly markedhost-arrival-best-effort. - Directional 3D camera frustums are not rendered until calibration and extrinsics are available and verified. An unresolved camera may be listed as a source, but its orientation must not be invented.
Current K1 mapping
| Producer | Canonical channel | Host representation |
|---|---|---|
sensor.lidar.primary |
spatial.point-cloud.live |
primary Rerun viewport |
sensor.camera.left |
camera.preview.live |
auxiliary media window / camera card |
sensor.camera.right |
camera.preview.live |
auxiliary media window / camera card |
Both camera producers share the proven canonical channel and remain distinct by
sourceId. The plugin publishes both catalog rows dynamically, but delivery is
present only on the selected producer. Selecting the peer tears down the old
RTSP/FFmpeg generation before a new browser lease is issued.
UI consequences
- The spatial scene source picker renders any number of plugin-published sources.
- Auxiliary media uses the design-system
WorkspaceWindow, constrained to the scene bounds, with controlled drag, resize, close and maximize state. - The Cameras workspace filters media modalities and renders 0, 1, 2 or N cards; only its grid scrolls when the source count exceeds available space.
- Point-cloud focus and camera focus stay inside the application panel rather than taking over the browser viewport.
- Empty and declared channels remain honest placeholders; no demo frames or synthetic sensor values are substituted.
Follow-up gate
The local laboratory adapter now terminates RTSP/RTP with FFmpeg, copy-remuxes H.264 High L4 without transcoding and publishes complete bounded fMP4 segments to a generic MSE player. ADR 0008 subsequently added acquisition-owned durable segments, a prepared recorded-media manifest and host-arrival-best-effort rewind on the saved-session timeline. This is not proof of a shared device clock or frame-accurate LiDAR/camera alignment. Portable FFmpeg packaging, multi-consumer fan-out and remote/WAN delivery remain open. See ADR 0007 and ADR 0008.
Code anchors
apps/control-station/src/core/runtime/contracts.tsapps/control-station/src/core/observation/useObservationLayout.tsapps/control-station/src/components/ObservationSources.tsxapps/control-station/src/components/ObservationTimeline.tsxapps/control-station/src/workspaces/Workspaces.tsxplugins/xgrids-k1/frontend/src/observationSources.tssrc/k1link/device_plugins/xgrids_k1/camera.py