Compare commits
2 Commits
140ad0d3ba
...
34140cc666
| Author | SHA1 | Date | |
|---|---|---|---|
| 34140cc666 | |||
| 77d6b79c6b |
@@ -17,11 +17,14 @@ definitions from here.
|
||||
|---|---|
|
||||
| [`schema/topics.json`](schema/topics.json) | Topic namespace: payload kind, retention, rate, publisher |
|
||||
| [`schema/envelope.json`](schema/envelope.json) | JSON Schema for the decoded-signal envelope |
|
||||
| [`schema/signals.json`](schema/signals.json) | Signal registry — the single source for name, unit, type and range |
|
||||
| [`schema/signals.json`](schema/signals.json) | Signal registry — the single source for name, unit, type and range, and for where each decoded Z27AG signal sits in its CAN frame (`can` block) |
|
||||
| [`docs/BOUNDARY.md`](docs/BOUNDARY.md) | Display boundary protocol: what crosses between `svc-gw` and the app |
|
||||
| [`checklists/`](checklists/) | Recording checklists as data; the app bundles exact copies (its **Captures** page) |
|
||||
|
||||
The Z27AG DBC lands here too, once Phase 2 produces one.
|
||||
Decoded Z27AG signals (source `z27ag`) carry their frame layout in `signals.json` itself,
|
||||
so name, unit and bits cannot drift apart. A DBC for tools like SavvyCAN or cantools,
|
||||
if one is wanted, is generated from it, never edited by hand. Findings behind each
|
||||
layout: [`docs/impl/reports/`](docs/impl/reports/).
|
||||
|
||||
- For implementation practice guidelines, refer to the [guidelines](docs/GUIDELINES.md);
|
||||
- For implementation plans and history, refer to [them](docs/impl/);
|
||||
|
||||
+11
-1
@@ -33,4 +33,14 @@ type: guidelines
|
||||
- There is no version in any topic or payload. A recorded session names the
|
||||
contracts tag it was captured under, which is what keeps old captures readable.
|
||||
|
||||
## 6. To be added
|
||||
## 6. A decoded signal's layout lives only in its registry entry
|
||||
- Every `source: z27ag` signal has a `can` block in `signals.json`: frame ID, byte,
|
||||
bit or length, byte order, scale and offset. The decoder reads those blocks and
|
||||
nothing else, so a correction lands in one file and every consumer sees it.
|
||||
- ⚠ **No CAN ID or bit position is written in any service's code.** A layout
|
||||
hard-coded downstream is a second source that silently disagrees the day the
|
||||
registry is corrected.
|
||||
- Each block names the report with its evidence (`evidence`). A layout without
|
||||
evidence is a guess and does not go in.
|
||||
|
||||
## 7. To be added
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
---
|
||||
type: report
|
||||
date: 2026-10-13
|
||||
---
|
||||
# Z27AG CAN: first decoding pass
|
||||
|
||||
Session `z27ag-20261013-170050-checklist` (yukart-data `can-captures/`), checklist v1,
|
||||
117 marks. Method: list every transition of every rarely-changing bit and read it
|
||||
against the marks; for blinking signals, count toggles inside each marked range
|
||||
against the seconds before it; for values, dump bytes across the marked range; for
|
||||
speed, correlate every 16-bit word with GNSS speed over the crawls. Marks lag the
|
||||
action by a fraction of a second to a few seconds (the operator presses after doing),
|
||||
so a change shortly *before* a start mark is normal.
|
||||
|
||||
Bit numbering: `ID.byte.bit`, byte 0 first, bit 7 the MSB.
|
||||
|
||||
## Found
|
||||
|
||||
| Signal | Where | Evidence | Confidence |
|
||||
|---|---|---|---|
|
||||
| Engine speed | `210` bytes 4–5, BE, 1 rpm | idle 740–870; holds at ~1410 and ~1900 for "1500" / "2000" (operator: revs not exact); blip peak 2887 | High |
|
||||
| Engine speed, finer | `13D` bytes 0–1, LE, ≈ rpm × 2.048 | moves in lockstep with `210` | High |
|
||||
| Accelerator pedal | `210` byte 0, 0x00 released … 0xFA full (÷2.5 → %) | engine-off sweep: 0 → 0xFA → 0 | High |
|
||||
| Accelerator sensors 1 and 2 | `139` bytes 0 and 1 (raw, 0x33 rest … 0xEE full, track each other) | same sweep | High |
|
||||
| Throttle-related | `139` byte 2 (0x21 … 0xD5) | same sweep; plate or target | Medium |
|
||||
| Pedal-pressed flag | `210` byte 3 bit 7 | set exactly while the pedal is off rest | Medium |
|
||||
| Brake pedal switch | `231.4.1` (1 = pressed) | 3/3 presses, plus the foot-brake holds around the handbrake step and the crawls | High |
|
||||
| Handbrake | `239.0.2` (1 = applied) | set through every engaged stretch, clear during the crawls and the handbrake releases | High |
|
||||
| Left indicator | `423.2.6` blinking | 2/2 | High |
|
||||
| Right indicator | `423.2.5` blinking | 2/2 | High |
|
||||
| Hazards | `423.2.6` only blinks, 2/2 | odd: `2.5` stays still. Maybe `2.6` is "left or hazard", maybe the hazard has its own bit elsewhere at a rate this method missed | Low |
|
||||
| Side lights | `423.2.2` and `570.7.3` (1 = on) | on/off and during dipped | High |
|
||||
| Dipped beam | `423.3.1` (1 = on) | 1/1 | Medium (one sample) |
|
||||
| Any door open | `423.2.1` | driver and passenger | Medium |
|
||||
| Driver door | `423.0.4` | driver only, not passenger | Medium |
|
||||
| Driver belt unbuckled | `573.5.7` (1 = unbuckled) | set at ignition on, cleared at buckle; no release seen | Low |
|
||||
| A/C request / blower | `443` bytes 1–2 and `711` bytes 5–6, multi-bit | change with A/C and blower; not separated yet | Low |
|
||||
| A/C compressor engaged | `13D.6.7` | engine running, A/C on; set ~0.5 s after the request, cleared with A/C off | Medium |
|
||||
| Four wheel speeds | `235` four 16-bit words (bytes 0–1, 2–3, 4–5, 6–7) | zero parked, all four move together in the crawls | High (signal), **scale open** |
|
||||
| Vehicle speed | `231` byte 6 (and probably byte 7) | tracks the wheel words | Medium |
|
||||
|
||||
**Wheel-speed scale.** Crawls topped out at ~6 km/h, and so far only the first byte of each word moved
|
||||
(0x4C at GNSS 3.5 km/h). Read as little-endian ×0.05 km/h (the forfour's `200`
|
||||
scale), that is 3.8 km/h, which is plausible given GNSS lag. Big-endian is not ruled out. The
|
||||
jack-stands session and a GNSS-matched drive settle both the byte order and the scale.
|
||||
|
||||
## Not on this bus (or not seen)
|
||||
|
||||
- **Clutch pedal:** nothing changed in 3 presses, engine off.
|
||||
- **Gear position:** nothing in 5 gears, reverse or neutral. Expected for a manual. The
|
||||
gear can be computed from rpm ÷ wheel speed once the scale is known.
|
||||
- **Reverse:** no reverse bit found. The reverse lamp is probably wired directly.
|
||||
- **Steering angle:** not analysed yet (step 5 was done with the engine on, at the end).
|
||||
|
||||
## Not analysed yet
|
||||
|
||||
- `312` (four noisy 16-bit words that follow the throttle: MAP/load/air candidates)
|
||||
- `449` temperatures (coolant candidate), `710`–`713` slow body/meter frames
|
||||
- `0C0`, `119`, `149`, `156` (counters/checksums; `149` inertial candidate)
|
||||
|
||||
## Scripts
|
||||
|
||||
Scratch analysis for now: a session loader, a transition timeline, a blink counter and a
|
||||
GNSS correlator, in Python with numpy. They become a tool once a DBC exists to check
|
||||
against.
|
||||
+147
-3
@@ -1,15 +1,24 @@
|
||||
{
|
||||
"$comment": "Single source for signal identity. Topic name and envelope unit are both derived from these entries and are never authored separately. source=obd2 is standardised; source=z27ag is reverse-engineered and lives in the DBC. source=host is the Orin itself (orin-status), not the car.",
|
||||
"$comment": "Single source for signal identity. Topic name and envelope unit are both derived from these entries and are never authored separately. source=obd2 is standardised; source=host is the Orin itself (orin-status), not the car. source=z27ag is reverse-engineered from the car's own broadcast frames, and its 'can' block is the only place its layout is written down: id (11-bit, hex string), byte (first data byte, 0-7), length in bits (1, 8 or 16), bit (length 1 only: 0 = LSB of that byte), order (length 16: big = byte first is most significant, little = the reverse), scale and offset (value = raw * scale + offset; booleans are raw != 0). 'evidence' names the contracts report that found it.",
|
||||
"signals": {
|
||||
"engine_rpm": {
|
||||
"unit": "rpm",
|
||||
"type": "number",
|
||||
"source": "obd2",
|
||||
"source": "z27ag",
|
||||
"description": "Engine speed",
|
||||
"range": [
|
||||
0,
|
||||
8000
|
||||
]
|
||||
],
|
||||
"can": {
|
||||
"id": "0x210",
|
||||
"byte": 4,
|
||||
"length": 16,
|
||||
"order": "big",
|
||||
"scale": 1,
|
||||
"offset": 0,
|
||||
"evidence": "Z27AG-DECODE-1"
|
||||
}
|
||||
},
|
||||
"vehicle_speed_kph": {
|
||||
"unit": "kph",
|
||||
@@ -91,6 +100,141 @@
|
||||
656
|
||||
]
|
||||
},
|
||||
"accel_pedal_pct": {
|
||||
"unit": "percent",
|
||||
"type": "number",
|
||||
"source": "z27ag",
|
||||
"description": "Accelerator pedal position (0x00 at rest, 0xFA flat)",
|
||||
"range": [
|
||||
0,
|
||||
100
|
||||
],
|
||||
"can": {
|
||||
"id": "0x210",
|
||||
"byte": 0,
|
||||
"length": 8,
|
||||
"scale": 0.4,
|
||||
"offset": 0,
|
||||
"evidence": "Z27AG-DECODE-1"
|
||||
}
|
||||
},
|
||||
"brake_pedal": {
|
||||
"unit": "",
|
||||
"type": "boolean",
|
||||
"source": "z27ag",
|
||||
"description": "Brake pedal switch: pressed",
|
||||
"can": {
|
||||
"id": "0x231",
|
||||
"byte": 4,
|
||||
"bit": 1,
|
||||
"length": 1,
|
||||
"evidence": "Z27AG-DECODE-1"
|
||||
}
|
||||
},
|
||||
"handbrake": {
|
||||
"unit": "",
|
||||
"type": "boolean",
|
||||
"source": "z27ag",
|
||||
"description": "Handbrake applied",
|
||||
"can": {
|
||||
"id": "0x239",
|
||||
"byte": 0,
|
||||
"bit": 2,
|
||||
"length": 1,
|
||||
"evidence": "Z27AG-DECODE-1"
|
||||
}
|
||||
},
|
||||
"indicator_left": {
|
||||
"unit": "",
|
||||
"type": "boolean",
|
||||
"source": "z27ag",
|
||||
"description": "Left indicator lamp, as it flashes (on and off at the flasher's rate)",
|
||||
"can": {
|
||||
"id": "0x423",
|
||||
"byte": 2,
|
||||
"bit": 6,
|
||||
"length": 1,
|
||||
"evidence": "Z27AG-DECODE-1"
|
||||
}
|
||||
},
|
||||
"indicator_right": {
|
||||
"unit": "",
|
||||
"type": "boolean",
|
||||
"source": "z27ag",
|
||||
"description": "Right indicator lamp, as it flashes. Hazards were seen on the left bit only: open",
|
||||
"can": {
|
||||
"id": "0x423",
|
||||
"byte": 2,
|
||||
"bit": 5,
|
||||
"length": 1,
|
||||
"evidence": "Z27AG-DECODE-1"
|
||||
}
|
||||
},
|
||||
"side_lights": {
|
||||
"unit": "",
|
||||
"type": "boolean",
|
||||
"source": "z27ag",
|
||||
"description": "Side (position) lights on; also on with dipped beam",
|
||||
"can": {
|
||||
"id": "0x423",
|
||||
"byte": 2,
|
||||
"bit": 2,
|
||||
"length": 1,
|
||||
"evidence": "Z27AG-DECODE-1"
|
||||
}
|
||||
},
|
||||
"dipped_beam": {
|
||||
"unit": "",
|
||||
"type": "boolean",
|
||||
"source": "z27ag",
|
||||
"description": "Dipped headlights on",
|
||||
"can": {
|
||||
"id": "0x423",
|
||||
"byte": 3,
|
||||
"bit": 1,
|
||||
"length": 1,
|
||||
"evidence": "Z27AG-DECODE-1"
|
||||
}
|
||||
},
|
||||
"door_open": {
|
||||
"unit": "",
|
||||
"type": "boolean",
|
||||
"source": "z27ag",
|
||||
"description": "Any door open",
|
||||
"can": {
|
||||
"id": "0x423",
|
||||
"byte": 2,
|
||||
"bit": 1,
|
||||
"length": 1,
|
||||
"evidence": "Z27AG-DECODE-1"
|
||||
}
|
||||
},
|
||||
"driver_door_open": {
|
||||
"unit": "",
|
||||
"type": "boolean",
|
||||
"source": "z27ag",
|
||||
"description": "Driver's door open",
|
||||
"can": {
|
||||
"id": "0x423",
|
||||
"byte": 0,
|
||||
"bit": 4,
|
||||
"length": 1,
|
||||
"evidence": "Z27AG-DECODE-1"
|
||||
}
|
||||
},
|
||||
"ac_compressor": {
|
||||
"unit": "",
|
||||
"type": "boolean",
|
||||
"source": "z27ag",
|
||||
"description": "A/C compressor engaged (engine running)",
|
||||
"can": {
|
||||
"id": "0x13D",
|
||||
"byte": 6,
|
||||
"bit": 7,
|
||||
"length": 1,
|
||||
"evidence": "Z27AG-DECODE-1"
|
||||
}
|
||||
},
|
||||
"orin_cpu_temp_c": {
|
||||
"unit": "celsius",
|
||||
"type": "number",
|
||||
|
||||
Reference in New Issue
Block a user