Checklist v3: IMU calibration (level twice, straight pull-aways and stops); yukart/raw/imu
/ crosscheck (push) Successful in 1s
Rust consumers (L4T) / Clippy, test, build, glibc for every service that compiles contracts in (push) Successful in 19s

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-14 13:28:40 +09:00
parent 4cbac36fbe
commit b52a7dcedb
3 changed files with 83 additions and 5 deletions
+54 -1
View File
@@ -1,6 +1,6 @@
{ {
"id": "z27ag-captures", "id": "z27ag-captures",
"version": 2, "version": 3,
"title": "Z27AG decoding captures", "title": "Z27AG decoding captures",
"about": "docs/impl/plans/Z27AG-CAPTURES.md", "about": "docs/impl/plans/Z27AG-CAPTURES.md",
"mark_format": "<step> <action>[ #<n>] start|end for a span, <step> <action>[ #<n>] for a point", "mark_format": "<step> <action>[ #<n>] start|end for a span, <step> <action>[ #<n>] for a point",
@@ -447,6 +447,59 @@
] ]
} }
] ]
},
{
"title": "IMU calibration (module fixed in its final place)",
"steps": [
{
"id": "27",
"title": "IMU level, facing one way",
"do": "Parked on the flattest ground at hand, engine off or idling, nobody moving inside. Start, keep still 15 s, end.",
"finds": "which way is down for the IMU (with step 28, cancelling the ground's slope)",
"actions": [
{
"label": "imu level A",
"hold_s": 15
}
]
},
{
"id": "28",
"title": "IMU level, turned round",
"do": "The same spot, nose the other way: a rough 180° will do. Still again, 15 s.",
"finds": "the second half of the level: the slope's tilt reverses, the mounting's does not",
"actions": [
{
"label": "imu level B",
"hold_s": 15
}
]
},
{
"id": "29",
"title": "IMU pull-away, straight",
"do": "A straight, flat section. From standstill, a firm pull-away in 1st to about 30. Start as the clutch bites, end as you lift.",
"finds": "which way is forward for the IMU",
"actions": [
{
"label": "imu pull away",
"repeat": 3
}
]
},
{
"id": "30",
"title": "IMU braking, straight",
"do": "The same section. From about 40, a firm (not emergency) stop. Start as you brake, end when stopped.",
"finds": "forward again, from the other side; also braking g",
"actions": [
{
"label": "imu brake",
"repeat": 3
}
]
}
]
} }
] ]
} }
+22 -4
View File
@@ -1,7 +1,7 @@
--- ---
type: plan type: plan
status: ready status: ready
updated: 2026-10-13 updated: 2026-10-14
--- ---
# Z27AG decoding captures: what to do in the car # Z27AG decoding captures: what to do in the car
@@ -17,6 +17,7 @@ ground truth. Prior art and first candidates: [the prior-art report](../reports/
| `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 | | `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 | | `events.ndjson` | marks from the app | when each step happened |
| `gnss.ndjson` | gpsd (SIM7600) | speed and position for the drive | | `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 ## Operating it from the app
@@ -53,14 +54,20 @@ recorder refuses marks with "no session" otherwise); engine off, doors shut.
- **Engine running, parked** (14–18): start and idle, held revs in neutral (no OBD - **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. 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, - **Driving** (19–22): steady speeds, stops, corners, each gear. A passenger presses,
or skip the marks: GNSS speed is recorded continuously, and gear comes from or skip the marks: GNSS speed is recorded continuously. The gear is not on CAN and
rpm ÷ speed. is not inferred (decode report).
- **On jack stands** (23–26, since v2): front wheels up, rears chocked, handbrake - **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, 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 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. 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 2 (2026-10-13) adds the stands section and writes down the conditions the 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 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 handbrake step, neutral with the clutch up for the revs.
@@ -97,6 +104,17 @@ on the Orin), and the signal list's `elm_connected` shows the Bluetooth link:
## Afterwards ## 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 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 `rsync -a mikkeli-orin-nano:/var/lib/yukart/recordings/<session>/ …` into
`yukart-data`, with a line in its README of what was done. `yukart-data`, with a line in its README of what was done.
+7
View File
@@ -36,6 +36,13 @@
"publisher": "imu", "publisher": "imu",
"description": "The IMU (WT61) in the car's frame: attitude, gravity-free acceleration, yaw rate; one topic per signal, named exactly as in signals.json (source=imu)." "description": "The IMU (WT61) in the car's frame: attitude, gravity-free acceleration, yaw rate; one topic per signal, named exactly as in signals.json (source=imu)."
}, },
"yukart/raw/imu": {
"payload": "json",
"retained": false,
"rate": "10-100/s",
"publisher": "imu",
"description": "Every IMU sample, raw: module axes, not calibrated. {mono (ns, CLOCK_MONOTONIC), t (µs, realtime), accel [x,y,z] g, gyro [x,y,z] deg/s, angle [roll,pitch,yaw] deg (the module's own)}. Not an envelope; for the recorder (imu.ndjson), so a later calibration can reprocess a session. Displays use yukart/imu/<signal>."
},
"yukart/host/<signal>": { "yukart/host/<signal>": {
"payload": "envelope", "payload": "envelope",
"retained": true, "retained": true,