bb47ee5301
/ crosscheck (push) Successful in 1s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DDwfd6Ki8UfG4hK6W5YpJz
159 lines
8.4 KiB
Markdown
159 lines
8.4 KiB
Markdown
---
|
||
type: plan
|
||
status: active
|
||
updated: 2026-10-13
|
||
---
|
||
# Roadmap
|
||
|
||
Phases are ordered by dependency, not by date. Each phase should end with
|
||
something demonstrable in the car.
|
||
|
||
## Phase 0 — Host bring-up · *in progress*
|
||
|
||
Getting the Jetson to see the hardware at all.
|
||
|
||
- [x] PCAN-USB working as SocketCAN (out-of-tree `pcan.ko`, netdev build)
|
||
- [x] Stable CAN names by udev: `can_pcan`, `can_onboard` — `canN` order raced at boot
|
||
- [x] Z27AG OBD-port CAN measured: 500 kbps, not gatewayed, 27 periodic IDs at
|
||
~890 frames/s; `can_pcan` comes up at 500k on hot-plug (verified 2026-10-13;
|
||
boot not yet seen), acknowledging rather than listen-only
|
||
- [x] SIM7600G-H-M.2 specified and documented
|
||
- [x] SIM7600 LTE data path: QMI (self-built `qmi_wwan`), povo, metered, ranked
|
||
below Ethernet/WiFi; failover tested, Tailscale stays reachable over LTE
|
||
- [x] SIM7600 GNSS via gpsd (`/dev/sim7600-gps`): 3D fix in the car
|
||
- [x] Kernel-update procedure for the out-of-tree modules (`pcan`, `qmi_wwan`) —
|
||
documented, sources kept in `~/infra`; still manual, and breaks silently
|
||
if forgotten
|
||
- [x] Network time pinned to NICT; timezone `Asia/Tokyo`
|
||
- [x] USB camera (IMX662, Sunplus UVC bridge) recognised on the car unit with
|
||
in-tree drivers: MJPEG up to 1080p60, microphone; measured in
|
||
orin-nano-env-setup `docs/impl/reports/USB-CAMERA.md`
|
||
- [ ] Optional: RTC backup battery (CR2032) — without it the clock boots stale
|
||
until NTP or GPS corrects it
|
||
- [ ] Power and mounting in the car: clean shutdown on ignition off
|
||
(UPS module bench test 2026-10-09: carries the Orin ≥ 20 s across a PD
|
||
supply swap, enough to ride through cranking)
|
||
— plan in orin-nano-env-setup `docs/impl/plans/POWER.md`; open: the Orin
|
||
doesn't auto-start at ignition on while the UPS keeps it powered
|
||
|
||
Tracked in [orin-nano-env-setup](gitea:yukart/orin-nano-env-setup).
|
||
|
||
## Phase 1 — Capture
|
||
|
||
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
|
||
- [ ] Off-board retention: sessions roll off the car unit once copied to dedicated
|
||
storage (halogen over tailnet/WiFi, or object storage such as S3), instead of
|
||
living on board until the cap. Not urgent: first checklist session was 6.2 MB
|
||
for 16 min, 423 GB free (2026-10-13)
|
||
- [ ] `can-bridge` — listen-only, timestamped frames onto the bus
|
||
- [ ] Capture drive sessions across varied conditions (idle, cold start, moving,
|
||
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
|
||
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
|
||
|
||
- [ ] 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 signal set incrementally in `contracts` — in `signals.json`'s
|
||
`can` blocks, not a hand-kept DBC (one is generated if a tool needs it)
|
||
- [x] `decoder` — raw frames to named signals, 2026-10-13: svc-core `decoder`, laid out
|
||
only by the `can` blocks in contracts `signals.json` (rpm, accelerator, brake,
|
||
handbrake, indicators, side lights, dipped beam, doors, A/C compressor)
|
||
- [x] `obd-poller` — active OBD-II PIDs, single writer, 2026-10-12: mode 01, the
|
||
nine `obd2` signals (~10 Hz fast, 1 Hz slow), only while the bus is alive;
|
||
`can_pcan` out of listen-only. Recorded beside the frames (`vehicle.ndjson`).
|
||
**Disabled 2026-10-13:** the Z27AG doesn't answer OBD-II on CAN (likely
|
||
K-line, pin 7); kept for later active-send use
|
||
- [ ] OBD-II beyond mode 01: DTC scan (modes 03/07/0A) and MUT-III `21 xx`
|
||
requests, both needing multi-frame (ISO-TP) replies
|
||
- [ ] First decoding captures in the car, per contracts
|
||
`docs/impl/plans/Z27AG-CAPTURES.md` — first checklist session 2026-10-13
|
||
(117 marks, yukart-data `can-captures/`); jack-stands section still to do
|
||
- [ ] `gnss` — position/speed, useful as ground truth for validating decoded speed
|
||
|
||
OBD-II gives standardised signals quickly and is worth doing early; it also
|
||
provides a cross-check for reverse-engineered ones.
|
||
|
||
## Phase 3 — Bus and contracts
|
||
|
||
- [x] Stand up the broker, 2026-10-12: mosquitto 2.0.11 on the car Orin,
|
||
localhost only. First publisher `orin-status` (svc-core,
|
||
`yukart/host/*`); `svc-gw` subscribes and serves it to the tablet
|
||
- [x] Confirm MQTT holds up at real CAN rates (`yukart/can/raw`), 2026-10-12:
|
||
no loss at a saturated bus, per frame or in 10 ms batches; batched costs
|
||
the broker ~1 % of a core (svc-core `BUS-BENCH.md`)
|
||
- [ ] Freeze v1 of topic names and payload schemas
|
||
- [ ] `telemetry-gw` — external client access, including the serial bridge
|
||
|
||
## Phase 4 — Displays
|
||
|
||
Order chosen by feedback speed, not ambition.
|
||
|
||
- [ ] 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.
|
||
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
|
||
|
||
## Phase 5 — Camera, then inference
|
||
|
||
The camera is on the car unit (2026-10-11). Capturing and recording need no
|
||
model and no GPU, so they can come before inference, which stays deferred: it is
|
||
the reason the compute is a Jetson rather than a Pi, but it shares nothing with
|
||
the CAN work beyond the bus, and it competes with voice for memory.
|
||
|
||
What the hardware gives (USB camera report): MJPEG only, ~7.3 MB/s at 1080p30;
|
||
no hardware video encoder on the Orin Nano, so H.264 is software, ~1.3–2 of 6
|
||
cores at 1080p; frame rate falls with the light.
|
||
|
||
- [ ] Decide the camera's roles and mounting: dash recording, live view on the
|
||
tablet, inference input, or several
|
||
- [ ] Measure in the car: daylight and night frame rate and MJPEG size on a road
|
||
scene
|
||
- [ ] One capture process owns the camera (V4L2 is single-reader) and feeds
|
||
the others; sets UVC controls on open, since they reset on re-enumeration
|
||
- [ ] Recording: H.264 segments on the recorder's clock and session marks,
|
||
bounded like CAN sessions (~2.7 GB per hour at 6 Mbit/s)
|
||
- [x] Live view (decision 27, proposed), 2026-10-12: `svc-vision` serves 720p
|
||
MJPEG passthrough on `:7710` (`yukart-vision.service`, ~2% of a core),
|
||
paced per decision 28, camera-agnostic, says when there is no camera;
|
||
`app-flutter` shows it with exposure and gain controls
|
||
- [ ] Inference — deferred; plan for evicting voice, not for coexisting with it
|
||
([ORIN-RUNTIME.md](ORIN-RUNTIME.md))
|
||
|
||
## Navigation · *parallel workstream*
|
||
|
||
Not a phase — it runs alongside, and its early output feeds Phase 2. Design is
|
||
in [ARCHITECTURE.md](ARCHITECTURE.md#navigation); code in `svc-nav` (runtime)
|
||
and `tool-mapmint` (artifact builds).
|
||
|
||
- [x] Confirm Valhalla builds and runs on the Jetson (arm64) — done 2026-09-04,
|
||
full pipeline verified on the Orin including a served route
|
||
- [ ] Build the admin database with `valhalla_build_admins` **from the full Japan
|
||
extract** — a sub-region silently yields right-hand-traffic routing
|
||
- [ ] Build Valhalla routing tiles from a Geofabrik Japan extract, starting with
|
||
the region actually driven rather than all 2.3 GB of it
|
||
- [ ] Pull a Japan basemap extract from the Protomaps daily build with
|
||
`go-pmtiles`; static-serve it, with `localIdeographFontFamily` set for CJK
|
||
- [ ] MapLibre page rendering the basemap from a replayed GNSS trace
|
||
- [ ] Moving map live in the car (GNSS fix available on the car unit)
|
||
- [ ] Meili map matching over recorded sessions, as Phase 2 ground truth
|
||
- [ ] Routing and turn-by-turn guidance onto `yukart/nav/guidance`
|
||
|
||
The map-matching item is worth pulling forward: it validates decoded CAN speed
|
||
against OSM speed limits and road geometry, which is otherwise guesswork.
|
||
|
||
## Deferred
|
||
|
||
- Live off-board telemetry over LTE — hardware is present, but local logging
|
||
covers the current need
|
||
- Any CAN transmission beyond OBD-II diagnostics
|