Files
project-yukart/docs/ROADMAP.md
T

162 lines
8.7 KiB
Markdown
Raw Normal View History

---
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`).
2026-10-13: the Z27AG answers OBD-II only on the K-line (ISO 9141-2), so the
poller now goes through the Bluetooth ELM327 (classic serial, no pairing):
the `obd_*` signals, calibration references per decision 30
- [ ] 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
- [x] `gnss` — position/speed, useful as ground truth for validating decoded speed,
2026-10-13: svc-core `gnss`, the fix as `yukart/gnss/<signal>` (speed, heading,
position, altitude, satellites); `yukart/gnss/fix` for navigation still to come
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.
2026-09-04 14:52:50 +09:00
- [ ] 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
2026-09-04 14:52:50 +09:00
- [ ] `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