feat(sim): simulate the AWD front drive unit (DIF + PMF) #26
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "feat/sim-dif-front-unit"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes step 3 of #25 — lets a single AWD rear drive unit run on the bench with a simulated front.
An AWD rear ("Master", usage digit 0) expects a front drive unit on the bus: it supervises the front's frames for MIA and raises
difMIA(DIR_a040) /frontUnitDisabled(DI_a138) without them. A RWD rear ("Single", usage 2) subscribes to none of them. Two new nodes stand the front in.The front is two nodes, not one
It is one physical unit running two cores, so both halves are needed:
0x186 DIF_torque,0x187,0x2D5 DIF_status,0x2E5 DIF_power0x1D5 PMF_state4Enumerated off the 2022.45.15 AWD DIR (
di/12804, 28-65-0) rx handlers and diffed against the RWDdi/12803(28-65-2) at the same revision, so the set is the AWD delta and nothing else. Full write-up indocs/private/awd-dir-dif-can-interface.md.Three things the DBC gets wrong, all firmware-read
0x2D5is DLC 7 on 2022.45.15, where every DBC says 8 (and it is 8 again on 2026.8.3).checkRxDlcis an exact match, so a DLC-8 frame is rejected outright and the frame goes MIA looking healthy on the wire. This is why the revision pin in the scenarios is load-bearing rather than cosmetic.0x1D5's counter is 3 bits at bit 53, not 4. A 4-bit counter there would run into the checksum byte. A test sends nine frames and asserts the ninth equals the first, so a silent widening fails.0x1D5also nearly shipped with the wrong comment: it looks 2026-only because the 2022 rear DIR does not subscribe to it — but the rear PMR does, and the PMR is real hardware on a drive bench. On a dual-core node, sweep both cores.absentis now separate fromrealDIF forced the issue: the same node is
realon a bench with a physical front and not-fitted-at-all on a RWD car. Both mean "don't simulate", sodrive.tomlwas overloadingrealto mean the opposite of what it says — and a bench with two physical units exists, so the two meanings collide on one lever.[nodes] absent = [...]drops a node because the car does not have that ECU;realkeeps its meaning. Listing a node in both raises rather than silently picking one, since the failure mode is the sim transmitting over a real inverter.Three drive profiles
drive.tomlgains an explicit RWD car config — already the GTW defaults, so no behaviour change; it just puts the one thing separating the profiles in the same visible place in each. All three use enum labels ("AWD","3_CHASSIS") rather than raw numbers so they survive a revision renumbering.A bench with both units physical needs nothing extra from the sim: all seven rear→front frames are in the rear's own TX descriptor tables, and
0x1D5comes from the physical front's own PMF.Verification
3211 tests pass, ruff clean. All three profiles were expanded against the real DBC and checked frame by frame (bus, DLC, counter/checksum placement). The golden inventory locks the new frames; separate tests pin the 2022-vs-2026 DLC split, the seed and counter placement, and the
real/absentexclusivity.Judgement calls worth a second opinion
number_hvil_nodesleft unset on the AWD profiles. A two-DU car really does have more HVIL nodes, but the 2022 images are not gated on it and it only feedsa144 configMismatch, so I matched the working RWD bench rather than guess. Flagged in-file to revisit if a144 appears.0x2D5at DLC 7. Unverified — no 2024 AWD DIR is imported, and the DBC is not evidence here since it says 8 for 2022 too. Called out indif.py.0x1D5; the PMF image has nocheckRxDlc-style helper to read a rate from. The error is one-sided — too fast cannot cause an MIA — so it is safe unless the true rate is faster.Not in scope
Payload content. Every frame is zeros, per the existing
zeros()contract: MIA gates on DLC + checksum/counter, not values. That is enough to cleardifMIA, but not enough for the rear's VDC cross-checks against the front (DI_a207 vdcPowertrainTorque_dif,DI_a211 vdcMotorSpeed_dif) — those compare the front's torque and speed to its own, and no amount of frame coverage substitutes for consistent content.🤖 Generated with Claude Code
An AWD ("Master") rear rx's four front-inverter frames and supervises all four for MIA, so a lone AWD rear on the bench flags difMIA. A RWD ("Single") rear rx's none of them. New DIF node sends exactly those four. Enumerated off the 2022.45.15 AWD DIR (di/12804, 28-65-0) rx handlers and diffed against the RWD di/12803 (28-65-2) at the same revision, so the set is the AWD delta and nothing else. Two details the DBC gets wrong, both firmware-read: - 0x2D5 is DLC 7 on 2022.45.15 (DBC says 8 at every revision), DLC 8 again on 2026.8.3. checkRxDlc is an exact match, so a DLC-8 frame is rejected outright. - Checksum in byte 0, counter in byte 1 low nibble, not byte7/byte6. Seeds are the plain id_lo+id_hi rule, so place_checksum needs no override. 0x2E5 is ungated and is the only one of the four on the vehicle bus. DIF is the first node authored past 2022, which the fw-versioning golden did not allow for; its varied-node set becomes a node -> revision map. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>drive-awd.toml benches an AWD rear ("Master") with the front unit simulated: car config declares drivetrainType=AWD and DIF stays out of `real` so the sim stands in for the front. Without that the rear raises difMIA (a040) + frontUnitDisabled (a138). drive.toml gains the matching explicit RWD car config. Both values were already the GTW defaults, so this is documentation rather than a behaviour change -- but it puts the one thing that separates the two profiles in the same visible place in each. drive.toml also lists DIF in `real`, for the opposite reason to the inverter: a RWD car has no front unit at all, and `real` is the only lever that takes a node out of the broadcast set. A RWD rear subscribes to none of the four DIF IDs, so simulating them would only add unhandled traffic. Worth a dedicated "absent" key later. The revision pin is load-bearing on the AWD side: DIF_status 0x2D5 is DLC 7 on 2022.45.15 where every DBC says 8, and the length check is an exact match. The golden stub DB gains value_description for the two carconfig signals so a scenario can name an enum label rather than a raw number. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>absentfromreal, and add the both-real AWD profile e87f611c19