feat(observation): add dynamic camera sources
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
# ADR 0006: Vendor-neutral observation sources and live-only timeline
|
||||
|
||||
Status: accepted for the experimental Mission Core runtime, 2026-07-16.
|
||||
|
||||
## 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 independent H.264 camera preview producers. The browser does not yet have a
|
||||
camera delivery adapter, a shared point-cloud/video clock or confirmed camera
|
||||
intrinsics/extrinsics.
|
||||
|
||||
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
|
||||
|
||||
1. A device plugin normalizes its capabilities into
|
||||
`ObservationSourceDescriptor[]`. Mission Core consumes only these generic
|
||||
descriptors.
|
||||
2. `id` identifies a runtime source instance; `sourceId` identifies the producer
|
||||
inside the plugin model; `semanticChannelId` describes the canonical channel.
|
||||
Transport addresses are not identities.
|
||||
3. Provider metadata and device/session/acquisition binding are separate. A new
|
||||
acquisition may change layout context without changing the logical producer.
|
||||
4. The host owns visibility, z-order, position, resize and fullscreen. A plugin
|
||||
cannot inject global layout behavior.
|
||||
5. Direct device RTSP URLs do not cross into the generic UI. A future read-only
|
||||
camera adapter must publish a browser-decodable local delivery URL.
|
||||
6. Until a bounded buffer and clock mapping exist, the shared timeline is
|
||||
`live-only`, `seekable=false`, `sessionRecording=false` and explicitly marked
|
||||
`host-arrival-best-effort`.
|
||||
7. 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`. Their current state is `declared`: the compatibility profile proves
|
||||
the channels, but no browser preview URL is advertised yet.
|
||||
|
||||
## 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 next implementation step is a plugin-owned, read-only H.264 adapter that
|
||||
terminates RTSP/RTP locally and exposes a browser-supported stream plus measured
|
||||
per-source metrics. Synchronized rewind becomes eligible only after the adapter
|
||||
provides bounded buffering and an evidenced mapping between the RTP 90 kHz clock
|
||||
and the spatial stream clock.
|
||||
|
||||
## Code anchors
|
||||
|
||||
- `apps/control-station/src/core/runtime/contracts.ts`
|
||||
- `apps/control-station/src/core/observation/useObservationLayout.ts`
|
||||
- `apps/control-station/src/components/ObservationSources.tsx`
|
||||
- `apps/control-station/src/components/ObservationTimeline.tsx`
|
||||
- `apps/control-station/src/workspaces/Workspaces.tsx`
|
||||
- `apps/control-station/src/device-plugins/xgrids-k1/observationSources.ts`
|
||||
Reference in New Issue
Block a user