Files
contracts/docs/impl/plans/Z27AG-CAPTURES.md
T
mikkeli b52a7dcedb
/ crosscheck (push) Successful in 1s
Rust consumers (L4T) / Clippy, test, build, glibc for every service that compiles contracts in (push) Successful in 19s
Checklist v3: IMU calibration (level twice, straight pull-aways and stops); yukart/raw/imu
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DDwfd6Ki8UfG4hK6W5YpJz
2026-10-14 13:28:40 +09:00

121 lines
7.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
type: plan
status: ready
updated: 2026-10-14
---
# Z27AG decoding captures: what to do in the car
Recordings that let the broadcast frames be decoded: one thing changes at a time,
each change is marked from the app's **Captures** page, and OBD-II mode 01 values are recorded alongside as the
ground truth. Prior art and first candidates: [the prior-art report](../reports/Z27AG-CAN-PRIOR-ART.md).
## What records what
| In the session directory | From | Use |
|---|---|---|
| `can-*.log(.zst)` | the PEAK, every frame, kernel timestamps | what gets decoded (nothing transmits on CAN: OBD-II is on the K-line) |
| `vehicle.ndjson` | `decoder` and `obd-poller` via the bus | decoded CAN signals, and the `obd_*` references from the K-line through the ELM327 (rpm, speed, throttle, load, MAF, timing, O2 every round; coolant, intake air, trims every 5 s); `env.timestamp` is the reply's arrival at the Orin |
| `events.ndjson` | marks from the app | when each step happened |
| `gnss.ndjson` | gpsd (SIM7600) | speed and position for the drive |
| `imu.ndjson` | `imu` via the bus (`yukart/raw/imu`) | every IMU sample, raw module axes, Orin receive time: calibration (27–30) and, once calibrated, motion for the drive |
## Operating it from the app
- **Sessions start by themselves** when the PEAK sees traffic (ignition on) and end
15 s after it stops. There is no start/stop button; nothing to do.
- **Captures** (top bar) opens the checklist. Each step shows what to do and one big
button: **Start** as the action begins, **End** as it ends (a running timer shows
the suggested hold); a single moment is one **Mark**. When a step's actions are done
the button says **Next step**: a natural pause, about 3 s, before the next.
**Redo step** and **Skip step** say so in the recording; the step list (left, or
the list icon on a narrow screen) jumps anywhere. Leaving a step mid-action marks
that action aborted.
- **Check it landed:** under the button, the last mark and `✓`, or `✗ error: no
session` when there is no traffic yet (ignition on, PEAK plugged). A mark sent with
the link down waits (`unacked`) and goes when it is back, with its delay noted.
- The **Mark** button on the main screen is still there for anything off-plan.
- **OBD is working** when `obd_engine_rpm`, `obd_coolant_temp_c` and the rest appear
in the signal list and move (the ELM on the OBD port, through the Y harness beside
the PEAK). If they never appear, see *If OBD stays silent*.
## The steps
They are data: [`checklists/z27ag-captures.json`](../../../checklists/z27ag-captures.json),
bundled into the app as an exact copy (app-flutter `tool/sync-contracts.sh`;
crosscheck fails if the copy drifts). Edit them there; bump `version` when steps
change meaning, since every recording names the version it was made with. Before
starting: PEAK on the OBD port, Orin up, tablet connected, and `can_pcan` UP (the
recorder refuses marks with "no session" otherwise); engine off, doors shut.
- **Parked, ignition on, engine off, handbrake on** (1–13): baseline, pedals, steering, gears
(reverse likely shows as the reverse light: the diesel forfour carries it in
`423` byte 1 bit 3; no other gearbox signal expected), handbrake, indicators,
lights, doors, wipers, A/C, belt.
- **Engine running, parked** (14–18): start and idle, held revs in neutral (no OBD
on this car's CAN: the revs are approximate, read off the tacho), blips, A/C load, radiator fan.
- **Driving** (19–22): steady speeds, stops, corners, each gear. A passenger presses,
or skip the marks: GNSS speed is recorded continuously. The gear is not on CAN and
is not inferred (decode report).
- **On jack stands** (23–26, since v2): front wheels up, rears chocked, handbrake
off. Unpowered steering; speedometer readings held in 2nd and 3rd (fronts turn,
rears stay still, which tells the wheels apart); braking from speed with vacuum
assist; reverse. Stands replace the driving speeds where a drive is not practical.
- **IMU calibration** (27–30, since v3): once the IMU is fixed in its final place. Level
twice on the same spot, facing one way and then turned round (a rough 180° is fine:
the ground's slope reverses and cancels, the mounting's tilt does not); then three
firm pull-aways and three firm stops on a straight, flat section (forward, signed by
which kind of stretch it is). Any session holds raw IMU samples (`imu.ndjson`), so
these can go in their own short session or with anything else.
Version 3 (2026-10-14) adds the IMU calibration section. Version 2 (2026-10-13) adds the stands section and writes down the conditions the
first run showed matter: engine off and handbrake on for 1–13, foot brake held for
the handbrake step, neutral with the clutch up for the revs.
The parked steps can be split over several sessions; the drive is the important part.
## Marks, as recorded
`events.ndjson` holds each mark's text, stamped on arrival at the recorder:
| Text | Meaning |
|---|---|
| `checklist z27ag-captures v1` | before the first mark from the page: which steps these are |
| `3 brake #2 start` / `3 brake #2 end` | a span; `#n` only on repeated actions |
| `14 engine start` | a point |
| `3 brake #2 abort` | a span left open (redo, skip, another step) |
| `3 redo`, `3 skip` | the step is being done again / was skipped: use the last attempt |
## If OBD stays silent
`yukart/system/obd-poller` says why (visible in `mosquitto_sub -v -t 'yukart/system/#'`
on the Orin), and the signal list's `elm_connected` shows the Bluetooth link:
- `ELM …: … (unplugged, asleep or out of range)`: no Bluetooth link. The ELM in the
port? Its light on? A phone app holding it (it takes one connection)? Retried
every minute.
- `ECU not answering (…): ignition off?`: the ELM is there, the car is not. The
adapter's own words are in the brackets (`BUS INIT: ...ERROR`, `NO DATA`).
- `ECU silent for 60 s: adapter released`: ignition off for a minute; the poller let
go so the ELM can sleep, and tries again every minute.
- To see what answers, on the Orin: `sudo systemctl stop yukart-obd-poller`,
`yukart-obd-poller --elm $(. /etc/default/yukart-elm; echo $ELM_ADDR) --once`
(adapter, protocol, supported PIDs and one value each, with reply times), then
`sudo systemctl start yukart-obd-poller`.
## Afterwards
**IMU calibration**, on the car Orin, from the session that holds steps 27–30:
```bash
yukart-imu --calibrate /var/lib/yukart/recordings/<session> # print: down, forward, slope, spread
yukart-imu --calibrate /var/lib/yukart/recordings/<session> --write # and save /var/lib/yukart/imu/mount.json
```
The service picks the new mounting up within seconds; roll and pitch should then read
about 0 parked on level ground. Steps 27–28 alone also work: forward then stays the
`--forward` axis, laid flat, until a session with 29–30 is calibrated.
Sessions are in `/var/lib/yukart/recordings/` on the car Orin. Copy one off with
`rsync -a mikkeli-orin-nano:/var/lib/yukart/recordings/<session>/ …` into
`yukart-data`, with a line in its README of what was done.