Populate design, architecture and repo layout docs
project-yukart becomes the code-free hub: overview, roadmap and cross-cutting design only. Each app or app cluster gets its own repo, indexed from here. - ARCHITECTURE.md: separate services over a message bus, with displays as bus subscribers so the directly-driven screen, Android client and ESP32 panel share one contract. Records CAN scope (listen-only + OBD-II as sole writer) and a decisions table for choices still in flux. - REPOS.md: repo splitting rule, planned repos, naming, and Gitea template-repo policy (scaffolding only — no upstream link after instantiation). - ROADMAP.md: phases 0-5, capture and decode before displays. Bus choice (MQTT) is marked proposed pending a check against real CAN rates; implementation language is still open. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,119 @@
|
||||
# Architecture
|
||||
|
||||
## The one rule
|
||||
|
||||
**Everything is a bus participant.** Acquisition services publish; displays,
|
||||
loggers and analysis tools subscribe. No service knows which display exists, and
|
||||
no display talks to hardware.
|
||||
|
||||
This is what lets the three display options coexist without forking the system,
|
||||
and what lets a service be restarted or replaced mid-drive without taking the
|
||||
rest down.
|
||||
|
||||
## Shape
|
||||
|
||||
```
|
||||
CAN (can1) ──▶ can-bridge ──┐
|
||||
OBD-II ──▶ obd-poller ─┤
|
||||
GNSS ──▶ gnss ├──▶ message bus ──┬──▶ recorder (disk)
|
||||
camera ──▶ vision* ─┘ ├──▶ hud (local video out)
|
||||
└──▶ telemetry-gw ──▶ remote displays
|
||||
* later phase, separate task
|
||||
```
|
||||
|
||||
## Services
|
||||
|
||||
| Service | Responsibility | Transmits on CAN |
|
||||
|---|---|---|
|
||||
| `can-bridge` | Read SocketCAN frames, timestamp, publish raw | No |
|
||||
| `obd-poller` | Active OBD-II PID request/response | **Yes** |
|
||||
| `gnss` | gpsd client → position, speed, time fix | No |
|
||||
| `decoder` | Raw frames → named signals via DBC | No |
|
||||
| `recorder` | Persist raw + decoded sessions to disk | No |
|
||||
| `telemetry-gw` | Serve external display clients | No |
|
||||
| `vision` | Camera capture and on-device inference (later) | No |
|
||||
|
||||
Each ships as a systemd unit. The host-level prerequisites they depend on
|
||||
(kernel modules, device permissions, gpsd) are the environment repo's job, not
|
||||
theirs.
|
||||
|
||||
## CAN bus scope
|
||||
|
||||
Passive sniffing **plus** active OBD-II queries. OBD-II is a request/response
|
||||
protocol, so it necessarily transmits onto a 2008 car's bus. Constraints that
|
||||
follow:
|
||||
|
||||
- `can-bridge` runs listen-only and must never transmit.
|
||||
- `obd-poller` is the **single writer**. No other service opens a TX-capable socket.
|
||||
- Transmission is rate-limited and restricted to standard OBD-II diagnostic IDs.
|
||||
- TX is a distinct, explicitly enabled mode — not the default state on boot.
|
||||
|
||||
Reverse-engineering of Z27AG-specific frame IDs proceeds purely from observed
|
||||
traffic; discovered signals are recorded as a DBC rather than as code.
|
||||
|
||||
## Message bus
|
||||
|
||||
**Proposed: MQTT (mosquitto) on the Jetson.** Rationale:
|
||||
|
||||
- First-class client libraries on every display target — ESP32 (Arduino
|
||||
`PubSubClient` / ESP-IDF) and Android (Paho) — which is the deciding factor.
|
||||
- Broker handles fan-out and retained "last known value", so a display that
|
||||
connects mid-drive immediately has state to render.
|
||||
- Trivially inspectable with `mosquitto_sub` while debugging in a car.
|
||||
|
||||
Rejected: NNG/ZeroMQ (lower latency, no broker, but a poor ESP32 story and no
|
||||
retained values); DDS (capable, disproportionate).
|
||||
|
||||
### Topics
|
||||
|
||||
```
|
||||
yukart/can/raw high-rate raw frames, not retained
|
||||
yukart/vehicle/<signal> decoded signals (rpm, speed, coolant, …), retained
|
||||
yukart/gnss/fix position/speed/time, retained
|
||||
yukart/system/<service> health and status, retained
|
||||
```
|
||||
|
||||
Payloads: JSON for low-rate signals (readable, debuggable); compact binary or
|
||||
CBOR for `can/raw`, since a 500 kbps bus produces far more traffic than JSON
|
||||
should carry.
|
||||
|
||||
Topic names and payload schemas are a **contract shared across repos** — Android
|
||||
and ESP32 clients depend on them — so they are versioned in their own repo
|
||||
rather than duplicated per client.
|
||||
|
||||
## Display contract
|
||||
|
||||
Three display paths, in two classes:
|
||||
|
||||
**Class A — video out.** A screen driven directly by the Orin over SPI/DP/HDMI.
|
||||
The renderer is a local process subscribing to the bus over loopback.
|
||||
|
||||
**Class B — data only.** The Orin sends no video, only data; the device renders
|
||||
itself.
|
||||
|
||||
| Path | Transport | Notes |
|
||||
|---|---|---|
|
||||
| Android app | WiFi, or USB (RNDIS) | Full-featured client, richest UI |
|
||||
| ESP32 + RLCD/e-ink | WiFi, or USB/BT serial | Low-rate, glanceable subset of signals |
|
||||
|
||||
Class B devices reaching the bus over IP connect to the broker directly. For
|
||||
transports without IP (BT SPP, plain USB serial), `telemetry-gw` bridges
|
||||
serial ↔ bus rather than each device inventing its own protocol.
|
||||
|
||||
Because both classes are bus subscribers, adding, removing or swapping a display
|
||||
touches no acquisition code.
|
||||
|
||||
## Decisions
|
||||
|
||||
Recorded here so fast-moving choices stay visible. Flip a row rather than
|
||||
rewriting the document.
|
||||
|
||||
| # | Decision | Status | Date |
|
||||
|---|---|---|---|
|
||||
| 1 | Separate services over a message bus, not one process | Accepted | 2026-08-14 |
|
||||
| 2 | Displays are bus subscribers; no display-specific logic upstream | Accepted | 2026-08-14 |
|
||||
| 3 | Listen-only sniffing + active OBD-II, single writer | Accepted | 2026-08-14 |
|
||||
| 4 | MQTT as the bus | **Proposed** | 2026-08-14 |
|
||||
| 5 | Implementation language(s) per service | **Open** | — |
|
||||
| 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 |
|
||||
Reference in New Issue
Block a user