feat(sim): fix three ESP/VCFRONT signal bugs, and give ESP/IBST/VCFRONT/GTW real node state #17

Merged
outlandnish merged 3 commits from feat/sim-node-state into main 2026-09-11 09:04:12 -05:00
Owner

Bench work from trying to get a real rear drive unit into Drive. Three sim signal
bugs, and the node state to control what they exposed.

ESP / IBST / VCFRONT (cherry-picked from the public tree, 01d2f49)

  • ESP 0x145 set bit 23 and bit 48 instead of the four QF bits 24-27. Bit 23 is
    the HIGH BIT of ESP_absBrakeEvent2 (@22 w2), so the sim continuously told the
    DI ACTIVE_FRONT; bit 48 is ESP_ebrStandstillSkid. Both were bench-observed.
    Two QF signals were reading UNDEFINABLE_ACCURACY as a result.
    stabilityControlSts2 now defaults to ON, bench-confirmed as required.
  • VCFRONT 12vStatusForDrive was bundled into the hv_charge_enable branch, so it
    only read READY while HV charging was on -- but it is the drive-start LV gate the
    DI checks, which is what produced "Not ok to start drive / DI a174". Now
    independent, defaults READY.
  • VCFRONT 0x3C2 was sent as zeros(8). It is VCLEFT_switchStatus and the DI
    cross-checks its brake bits against its own GPIO, so the node sources the physical
    switch line now.

GTW car config

GTW sent GTW_carConfig with two signals set and no way to reach the rest; the DIR
reads fifteen. All fifteen are now scenario parameters with setters and
configure().

Firmware variance shaped the design: nine of the fifteen moved between 2020,
2022 and 2026 (tpmsType m2@11|1 -> m7@49|2, cabinPTCHeaterType m2@31|1 ->
m1@10|1, brakeHWType m2@59|2 -> m1@43|4 -> m1@43|5), so encoding stays by name
through the loaded database. Parameters take enum labels, because the same number
means different things per revision (performancePackage 4 is BASE_PLUS_AWD in 2020
and BASE_2022 after). Signals a revision lacks -- 2020 has no compressorType,
diBurnInType, packPerformanceDeviation or cabinPTCHeaterType -- land in
unsupported and are skipped; setting one explicitly warns rather than killing the
bench.

Defaults hold the same value on every revision (all zero but chassisType), so the
idle frame is byte-identical to before, verified across a full mux cycle on the 2022
and 2026 databases.

Worth knowing: the loaded DB must match the bench's firmware. TM3_ROOT selects
it, and nothing warns on a mismatch -- a 2026 DB against a 2022 DIR cycles nine mux
pages instead of six and puts five of these signals in the wrong bits.

3153 passed, ruff clean.

🤖 Generated with Claude Code

Bench work from trying to get a real rear drive unit into Drive. Three sim signal bugs, and the node state to control what they exposed. **ESP / IBST / VCFRONT** (cherry-picked from the public tree, `01d2f49`) - ESP `0x145` set bit 23 and bit 48 instead of the four QF bits 24-27. Bit 23 is the HIGH BIT of `ESP_absBrakeEvent2` (@22 w2), so the sim continuously told the DI `ACTIVE_FRONT`; bit 48 is `ESP_ebrStandstillSkid`. Both were bench-observed. Two QF signals were reading `UNDEFINABLE_ACCURACY` as a result. `stabilityControlSts2` now defaults to ON, bench-confirmed as required. - VCFRONT `12vStatusForDrive` was bundled into the `hv_charge_enable` branch, so it only read READY while HV charging was on -- but it is the drive-start LV gate the DI checks, which is what produced "Not ok to start drive / DI a174". Now independent, defaults READY. - VCFRONT `0x3C2` was sent as `zeros(8)`. It is `VCLEFT_switchStatus` and the DI cross-checks its brake bits against its own GPIO, so the node sources the physical switch line now. **GTW car config** GTW sent `GTW_carConfig` with two signals set and no way to reach the rest; the DIR reads fifteen. All fifteen are now scenario parameters with setters and `configure()`. Firmware variance shaped the design: **nine of the fifteen moved** between 2020, 2022 and 2026 (`tpmsType` m2@11|1 -> m7@49|2, `cabinPTCHeaterType` m2@31|1 -> m1@10|1, `brakeHWType` m2@59|2 -> m1@43|4 -> m1@43|5), so encoding stays by name through the loaded database. Parameters take enum labels, because the same number means different things per revision (`performancePackage` 4 is BASE_PLUS_AWD in 2020 and BASE_2022 after). Signals a revision lacks -- 2020 has no `compressorType`, `diBurnInType`, `packPerformanceDeviation` or `cabinPTCHeaterType` -- land in `unsupported` and are skipped; setting one explicitly warns rather than killing the bench. Defaults hold the same value on every revision (all zero but `chassisType`), so the idle frame is byte-identical to before, verified across a full mux cycle on the 2022 and 2026 databases. > Worth knowing: the loaded DB must match the bench's firmware. `TM3_ROOT` selects > it, and nothing warns on a mismatch -- a 2026 DB against a 2022 DIR cycles nine mux > pages instead of six and puts five of these signals in the wrong bits. 3153 passed, ruff clean. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
ESP 0x145: replace the hardcoded payload with brake/abs_event/stability state.
The old builder set bit23 (high bit of absBrakeEvent2 -> ACTIVE_FRONT) and bit48
(ebrStandstillSkid) instead of the four QF bits 24-27, so the sim reported an ABS
event and a standstill skid with two QF signals reading UNDEFINABLE_ACCURACY.
stabilityControlSts2 now defaults to ON (bench-confirmed requirement).

IBST 0x39D: brake posture drives both copies (party + the 2022 vehicle-bus one),
adding internalState and rod travel alongside driverBrakeApply.

VCFRONT: 12vStatusForDrive was bundled into the hv_charge_enable branch, so it
only read READY while HV charging was on -- the drive-start LV gate the DI checks.
It is now independent and defaults READY. 0x3C2 was sent as zeros(8); it is
VCLEFT_switchStatus and the DI cross-checks its brake bits (4 and 60) against its
own GPIO, so the node now sources the physical switch line.

Released/idle defaults stay byte-identical to the previous builders.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
(cherry picked from commit 01d2f490a7)
feat(sim): give the GTW node real car-config state instead of two defaults
Some checks failed
Tests / test (pull_request) Has been cancelled
0e13d857f9
GTW sent GTW_carConfig with exactly two signals set (chassisType, drivetrainType)
and no way to reach the rest. The DIR reads fifteen. The node now names all of
them as scenario parameters with setters and a configure() override, matching the
idiom the ESP/IBST/HVP nodes already use.

Firmware variance is the whole difficulty here, so the state is shaped around it:

- Nine of the fifteen signals MOVED between 2020, 2022 and 2026 (tpmsType m2@11|1
  -> m7@49|2, cabinPTCHeaterType m2@31|1 -> m1@10|1, brakeHWType m2@59|2 ->
  m1@43|4 -> m1@43|5). Encoding by name through the loaded database picks the
  right layout up for free -- but the loaded DB must match the bench's firmware.
- Parameters take enum LABELS, because the same number means different things per
  revision: performancePackage 4 is BASE_PLUS_AWD in 2020 and BASE_2022 after,
  chassisType 3 is undefined in 2020 and Y_CHASSIS after. Where a label was
  renamed with the value kept (packEnergy 50_KWH/74_KWH/62_KWH vs SR/LR/MR; 2026
  prefixing brakeHWType with the caliper vendor) the encoder's error names what
  the loaded DB accepts.
- Signals a revision lacks (2020 has no compressorType, diBurnInType,
  packPerformanceDeviation or cabinPTCHeaterType) are collected in `unsupported`
  and skipped; setting one explicitly warns rather than killing the bench.

Defaults are the values that hold on every revision -- all zero but chassisType --
so the idle frame is byte-identical to before, verified across a full mux cycle.
They are not a considered bench profile: numberHVILNodes 0 and brakeHWType 0 are
worth setting deliberately.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
feat(sim): dashboard brake-pedal control across ESP/IBST/VCLEFT
Some checks failed
Tests / test (pull_request) Has been cancelled
f317e92c2e
Split VCLEFT into its own node (VCLEFT_switchStatus 0x3C2 moved out of VCFRONT)
and add a dash brake toggle that fans a press out to every brake reporter: ESP
0x145 + IBST 0x39D CAN posture and the VCLEFT 0x3C2 physical switch line.

0x38D ESP_party3 now carries the master-cyl pressure (measured + virtual,
QF=NORMAL) driven by an optional 0-100% pressure, surfaced as a dash slider;
J1850Frame gained an optional payload builder so the frame can carry signal
data alongside its CRC + rolling counter. Pressure is stored on ESP/IBST and
plumbed through /api/brake -> control server -> node setters.

Also recognize GTW_brakeLineSwitchType (2022+) in the GTW car-config.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
outlandnish/tm3diag!17
No description provided.