byd: fix canError ("Unknown Vehicle Variant") from strict parser alive checks

Explicit parser frequencies made canValid=False when state-dependent
messages are absent (PCM_BUTTONS is event-driven; MPC_LKAS_CMD/ACC_CMD
only flow when stock ADAS is active), tripping EventName.canError.

- Alive-check only control-critical messages, at a conservative 10Hz
  (1s timeout): ESC, BRAKE_APPLIED, PEDAL, STEER_MODULE, STEERING_TORQUE,
  DRIVE_STATE, ACC_HUD_ADAS
- Parse-but-don't-alive-check (nan) the rest: STALKS, METER_CLUSTER,
  MPC_LKAS_CMD, ACC_CMD
- PCM_BUTTONS is parsed on both pt and cam parsers (bus assignment is
  harness dependent); MADS reads LKAS_ON_BTN from whichever bus sees it

Verified: canValid=True with idle stock ADAS, LKAS button events work
from either bus, canValid stays True throughout.
This commit is contained in:
Quintine committed 2026-07-25 17:37:52 +10:00
1 parent 1a4f296aa8
commit bd58431b9b
4 files changed
+195 -13

No files matched your search

+19 -12
View File
@@ -100,23 +100,30 @@ class CarState(CarStateBase, MadsCarState):
@staticmethod
def get_can_parsers(CP, CP_SP):
# Frequencies are deliberately conservative (10x timeout forgiveness):
# only messages required for control are alive-checked, everything
# optional/state-dependent is parsed but not alive-checked (nan).
pt_messages = [
# sig_address, frequency
("ESC", 50),
("BRAKE_APPLIED", 50),
("PEDAL", 50),
("STEER_MODULE", 100),
("STEERING_TORQUE", 50),
("DRIVE_STATE", 50),
("STALKS", 20),
("METER_CLUSTER", 20),
("PCM_BUTTONS", 20),
("ESC", 10),
("BRAKE_APPLIED", 10),
("PEDAL", 10),
("STEER_MODULE", 10),
("STEERING_TORQUE", 10),
("DRIVE_STATE", 10),
("STALKS", float('nan')),
("METER_CLUSTER", float('nan')),
# steering wheel buttons; bus assignment is harness dependent
("PCM_BUTTONS", float('nan')),
]
cam_messages = [
("ACC_HUD_ADAS", 50),
("MPC_LKAS_CMD", 50),
("ACC_CMD", 25),
("ACC_HUD_ADAS", 10),
# stock camera command echoes, only present when stock ADAS is active
("MPC_LKAS_CMD", float('nan')),
("ACC_CMD", float('nan')),
# PCM_BUTTONS may be forwarded on the camera bus on some harnesses
("PCM_BUTTONS", float('nan')),
]
return {
@@ -19,6 +19,12 @@ class MadsCarState(MadsCarStateBase):
def update_mads(self, ret: structs.CarState, can_parsers: dict[StrEnum, CANParser]) -> None:
cp = can_parsers[Bus.pt]
cp_cam = can_parsers[Bus.cam]
# PCM_BUTTONS bus assignment is harness dependent; read from whichever bus sees it
lkas_button = cp.vl["PCM_BUTTONS"]["LKAS_ON_BTN"]
if not cp.vl_all["PCM_BUTTONS"]["LKAS_ON_BTN"] and cp_cam.vl_all["PCM_BUTTONS"]["LKAS_ON_BTN"]:
lkas_button = cp_cam.vl["PCM_BUTTONS"]["LKAS_ON_BTN"]
self.prev_lkas_button = self.lkas_button
self.lkas_button = cp.vl["PCM_BUTTONS"]["LKAS_ON_BTN"]
self.lkas_button = lkas_button