Files
contracts/docs/impl/reports/Z27AG-DECODE-3.md
T
mikkeli e8ba581985
/ crosscheck (push) Successful in 1s
Rust consumers (L4T) / Clippy, test, build, glibc for every service that compiles contracts in (push) Successful in 25s
Z27AG decode pass 3: wheel positions from corners, odometer (570, 24-bit); layouts can be 24 bits
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DDwfd6Ki8UfG4hK6W5YpJz
2026-10-15 22:13:34 +09:00

3.6 KiB
Raw Blame History

type, date
type date
report 2026-10-15

Z27AG CAN: third pass, the drive back

Sessions 000011-20261015T212904 and 000013-20261015T214544 (the drive back, about 13 minutes, no marks) together with pass 2's 000008 and 000009: 20 km of driving with GNSS and the calibrated IMU, no OBD-II. Nothing was marked, so this pass uses what any drive has: corners and distance.

Confirmed

Signal Where Evidence Registered as
Wheel speeds 235 four words, little-endian (pass 2): bytes 0–1 front right, 2–3 front left, 4–5 rear right, 6–7 rear left from corners, below wheel_speed_fr_kph, _fl_, _rr_, _rl_
Odometer 570 bytes 4–6, little-endian, 1 km steps once per kilometre: 12 steps over 11.9 km (000009), 3 over 3.0 km (000011); 167966 on the 13th, 167988 at the end of the drive back; valid with the engine off too odometer_km (the layout format gained 24-bit fields)
Distance counter 14D bytes 6–7, little-endian, about 0.40 m per count tracks distance from the wheel speeds with correlation 1.0000 in both drives (103.2 and 103.6 m per step of byte 7); wraps every ~26 km not registered: the odometer covers whole kilometres; this is there if a trip meter needs finer steps

Which word is which wheel

In a corner the outer wheels run faster than the inner ones, by about half the track width times the curvature; and the fronts run on a wider arc than the rears, by about half the wheelbase squared times the curvature squared. Fitting each word's share of the four (its speed ÷ their mean) against the curvature from the steering angle (steering_angle_deg + 2.7° for the straight-ahead offset, ÷ 16.3, over a 2.5 m wheelbase), 74 476 frames above 15 km/h:

Word Linear term (track) Square term (wheelbase) So
0 +0.72 m +1.4 m² right, front
1 −0.72 m +1.4 m² left, front
2 +0.75 m −0.9 m² right, rear
3 −0.75 m −1.9 m² left, rear

Curvature is positive turning left, so a positive linear term is a wheel on the right (outside in a left turn). The size, ±0.72–0.75 m, is half the Colt's track (1.45–1.46 m). The square terms split the words into a pair above the mean and a pair below it, ±1.5 m² against an expected ±1.6 m² (2.5² ÷ 4). Medians by curvature agree: in left turns tighter than 20 m (κ > 0.05) the words read 1.068, 0.956, 1.044, 0.932 of their mean.

Straight ahead the fronts read 0.6 % more counts than the rears, matching pass 2's per-word scales (0.0578 against 0.0581 km/h per count). Driven wheels or tyre sizes, either is ordinary; each pair is registered with its own scale, so all four read GNSS speed when cruising.

Jack stands (checklist 23–26) would still confirm this, but are no longer needed to find it.

Candidates

  • 570 bytes 2 and 3 move together (byte 3 ≈ byte 2 + 48) and fall slowly: byte 2 read 87 on the 13th and 76 at the end of the drive back, 22 km later. Fuel level fits the fall, but byte 2 also rose by about 3 while parked between drives (78 → 81), which fuel would not do on level ground. It may be outside temperature instead, falling through the evening. Both read 7F with the engine off. A refuel settles it: fuel jumps, temperature does not. Not registered.

Notes on the recording

  • 000012 is a 25-second parked session in between; 000013 ends with the PEAK unplugged.
  • The recorder kept IMU samples as JSON lines (34 MB for 000009). From this pass on it packs them (imu.bin, svc-core imu/packed.rs): the same samples are 8.5 MB, and all of 000009's samples fit the packed form exactly.