Phase 1 recorder running; svc-core current; boundary v0 started

The recorder runs on the car unit and reads SocketCAN and gpsd directly
(decision 25, proposed). svc-gw and app-flutter talk boundary v0, both
channels on one WebSocket with their own semantics (decision 26, proposed).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DDwfd6Ki8UfG4hK6W5YpJz
This commit is contained in:
2026-10-09 20:24:32 +09:00
parent 9a1512793d
commit e6ca835992
3 changed files with 16 additions and 7 deletions
+3 -1
View File
@@ -33,7 +33,7 @@ The Orin runs headless: no local video out. The tablet app is the display.
| `obd-poller` | Active OBD-II PID request/response | **Yes** | | `obd-poller` | Active OBD-II PID request/response | **Yes** |
| `gnss` | gpsd client → position, speed, time fix | No | | `gnss` | gpsd client → position, speed, time fix | No |
| `decoder` | Raw frames → named signals via DBC | No | | `decoder` | Raw frames → named signals via DBC | No |
| `recorder` | Persist raw + decoded sessions to disk | No | | `recorder` | Persist raw + decoded sessions to disk; raw CAN and GNSS read directly, not via the bus (decision 25) | No |
| `telemetry-gw` | Serve external display clients | No | | `telemetry-gw` | Serve external display clients | No |
| `vision` | Camera capture and on-device inference (later) | No | | `vision` | Camera capture and on-device inference (later) | No |
@@ -354,6 +354,8 @@ rewriting the document.
| 22 | `signals.json` is the single source for signal name and unit; both are derived, never authored twice | Accepted | 2026-09-05 | | 22 | `signals.json` is the single source for signal name and unit; both are derived, never authored twice | Accepted | 2026-09-05 |
| 23 | Services build natively on the development Orin; both units stay on the same L4T release | Accepted | 2026-09-05 | | 23 | Services build natively on the development Orin; both units stay on the same L4T release | Accepted | 2026-09-05 |
| 24 | Link drops are routine: `svc-gw` detects dead clients by heartbeat and redelivers or expires pending reliable traffic; upstream commands are idempotent | **Proposed** | 2026-10-09 | | 24 | Link drops are routine: `svc-gw` detects dead clients by heartbeat and redelivers or expires pending reliable traffic; upstream commands are idempotent | **Proposed** | 2026-10-09 |
| 25 | The recorder reads SocketCAN and gpsd directly; raw capture never depends on the broker | **Proposed** | 2026-10-09 |
| 26 | Boundary v0 carries both channels of decision 15 on one WebSocket, each keeping its own semantics (drop-oldest down, acked and idempotent up) | **Proposed** | 2026-10-09 |
| 6 | Local logging first; off-board LTE telemetry deferred | Accepted | 2026-08-14 | | 6 | Local logging first; off-board LTE telemetry deferred | Accepted | 2026-08-14 |
| 7 | Camera/AI inference is a later, separate task | Accepted | 2026-08-14 | | 7 | Camera/AI inference is a later, separate task | Accepted | 2026-08-14 |
| 8 | Self-hosted offline navigation (MapLibre GL + Valhalla + PMTiles) over a cloud maps SDK | Accepted | 2026-09-03 | | 8 | Self-hosted offline navigation (MapLibre GL + Valhalla + PMTiles) over a cloud maps SDK | Accepted | 2026-09-03 |
+2 -2
View File
@@ -24,7 +24,8 @@ contracts repo, not copied into each consumer.
| [orin-nano-env-setup](gitea:yukart/orin-nano-env-setup) | Jetson host bring-up | | [orin-nano-env-setup](gitea:yukart/orin-nano-env-setup) | Jetson host bring-up |
| [app-flutter](gitea:yukart/app-flutter) | Flutter display client | | [app-flutter](gitea:yukart/app-flutter) | Flutter display client |
| [contracts](gitea:yukart/contracts) | Topic namespace, payload schemas, signal registry | | [contracts](gitea:yukart/contracts) | Topic namespace, payload schemas, signal registry |
| [svc-gw](gitea:yukart/svc-gw) | Telemetry gateway — aggregation and the HTTP surface | | [svc-core](gitea:yukart/svc-core) | Acquisition + processing cluster: `recorder` now; `can-bridge`, `obd-poller`, `gnss`, `decoder` to come |
| [svc-gw](gitea:yukart/svc-gw) | Telemetry gateway — aggregation and the display boundary |
| [svc-nav](gitea:yukart/svc-nav) | Navigation service — routing and guidance | | [svc-nav](gitea:yukart/svc-nav) | Navigation service — routing and guidance |
| [tool-mapmint](gitea:yukart/tool-mapmint) | Map artifact minting, workstation-side | | [tool-mapmint](gitea:yukart/tool-mapmint) | Map artifact minting, workstation-side |
| [tool-mock](gitea:yukart/tool-mock) | Mocks and fixtures — a fake car on a workstation | | [tool-mock](gitea:yukart/tool-mock) | Mocks and fixtures — a fake car on a workstation |
@@ -33,7 +34,6 @@ contracts repo, not copied into each consumer.
| Repository | Role | Why separate | | Repository | Role | Why separate |
|---|---|---| |---|---|---|
| `svc-core` | Acquisition + processing cluster: `can-bridge`, `obd-poller`, `gnss`, `decoder`, `recorder` | Developed and deployed as one unit on the Orin |
| `app-esp32` | ESP32 RLCD/e-ink display firmware (Class B) | Embedded toolchain, flashed not deployed | | `app-esp32` | ESP32 RLCD/e-ink display firmware (Class B) | Embedded toolchain, flashed not deployed |
| `tool-analysis` | Offline session analysis, reverse-engineering notebooks | Runs off-car, no runtime coupling | | `tool-analysis` | Offline session analysis, reverse-engineering notebooks | Runs off-car, no runtime coupling |
+11 -4
View File
@@ -38,17 +38,22 @@ Tracked in [orin-nano-env-setup](gitea:yukart/orin-nano-env-setup).
Get real Z27AG traffic onto disk before designing anything around it. Get real Z27AG traffic onto disk before designing anything around it.
- [x] `recorder` — raw CAN + GNSS sessions on the car unit (`yukart-recorder.service`):
starts on traffic or `ctl start`, ends after 15 s idle, marks via `ctl mark` or
the app; fsync'd every second, bounded at 50 GB, ~20 MB per hour of driving
- [ ] `can-bridge` — listen-only, timestamped frames onto the bus - [ ] `can-bridge` — listen-only, timestamped frames onto the bus
- [ ] `recorder` — persist raw sessions
- [ ] Capture drive sessions across varied conditions (idle, cold start, moving, - [ ] Capture drive sessions across varied conditions (idle, cold start, moving,
lights/indicators/windows actuated) with a written log of what was done when lights/indicators/windows actuated) with a written log of what was done when
The manual event log matters more than it sounds: it is what makes the raw The manual event log matters more than it sounds: it is what makes the raw
capture decodable later. capture decodable later. Marks go into the session itself (`yukart-recorder ctl
mark …`, or the app's Mark button), on the same clock as the frames.
## Phase 2 — Decode ## Phase 2 — Decode
- [ ] Correlate captures against the event log; identify recurring frame IDs - [ ] Correlate captures against the event log; identify recurring frame IDs —
prior art and first candidates (engine speed in `0x210` / `0x13D`) in contracts
`docs/impl/reports/Z27AG-CAN-PRIOR-ART.md`
- [ ] Build the Z27AG DBC incrementally in `contracts` - [ ] Build the Z27AG DBC incrementally in `contracts`
- [ ] `decoder` — raw frames to named signals - [ ] `decoder` — raw frames to named signals
- [ ] `obd-poller` — active OBD-II PIDs, single writer, rate-limited - [ ] `obd-poller` — active OBD-II PIDs, single writer, rate-limited
@@ -69,7 +74,9 @@ provides a cross-check for reverse-engineered ones.
Order chosen by feedback speed, not ambition. Order chosen by feedback speed, not ambition.
- [ ] One display end-to-end first, proving the contract — `app-flutter` is the - [ ] One display end-to-end first, proving the contract — `app-flutter` is the
quickest to iterate on, and is the only display in current scope quickest to iterate on, and is the only display in current scope.
Started: boundary v0 (contracts `docs/BOUNDARY.md`) between `svc-gw` on the
car unit and a text-readout starter app; not yet run on the tablet
- [ ] `app-esp32` — RLCD/e-ink glanceable subset. Deferred, no hardware in scope - [ ] `app-esp32` — RLCD/e-ink glanceable subset. Deferred, no hardware in scope
## Phase 5 — Camera and inference · *separate task* ## Phase 5 — Camera and inference · *separate task*