diff --git a/opendbc_repo/opendbc/car/hyundai/carstate.py b/opendbc_repo/opendbc/car/hyundai/carstate.py index 2b30b8308..bcf174058 100644 --- a/opendbc_repo/opendbc/car/hyundai/carstate.py +++ b/opendbc_repo/opendbc/car/hyundai/carstate.py @@ -76,6 +76,7 @@ class CarState(CarStateBase): self.main_buttons: deque = deque([Buttons.NONE] * PREV_BUTTON_SAMPLES, maxlen=PREV_BUTTON_SAMPLES) self.lda_button = 0 self.lda_button_raw = 0 + self.lda_button_raw_initialized = False self.lda_button_last_raw_rise_ts_nanos = 0 self.left_paddle = 0 self.mode_button = 0 @@ -174,15 +175,20 @@ class CarState(CarStateBase): return False - def create_alt_bus_lda_button_events(self, cp_source: CANParser) -> list[structs.CarState.ButtonEvent]: + def get_alt_bus_lda_button_raw_state(self, cp_source: CANParser) -> tuple[int, int]: if self.CP.carFingerprint in ALT_BUS_LDA_BUTTON_SWL_STAT_CARS: - raw_lda_button = int(cp_source.vl["CLU13"]["CF_Clu_SWL_Stat"] == 4) - raw_lda_button_ts_nanos = cp_source.ts_nanos["CLU13"]["CF_Clu_SWL_Stat"] - else: - raw_lda_button = int(cp_source.vl["CLU13"]["CF_Clu_LdwsLkasSW"]) - raw_lda_button_ts_nanos = cp_source.ts_nanos["CLU13"]["CF_Clu_LdwsLkasSW"] + return int(cp_source.vl["CLU13"]["CF_Clu_SWL_Stat"] == 4), cp_source.ts_nanos["CLU13"]["CF_Clu_SWL_Stat"] + return int(cp_source.vl["CLU13"]["CF_Clu_LdwsLkasSW"]), cp_source.ts_nanos["CLU13"]["CF_Clu_LdwsLkasSW"] + + def create_alt_bus_lda_button_events(self, cp_source: CANParser) -> list[structs.CarState.ButtonEvent]: + raw_lda_button, raw_lda_button_ts_nanos = self.get_alt_bus_lda_button_raw_state(cp_source) button_events: list[structs.CarState.ButtonEvent] = [] + if not self.lda_button_raw_initialized: + self.lda_button_raw_initialized = True + self.lda_button_raw = raw_lda_button + return button_events + # Some alt-bus LKAS button layouts pulse several times per physical press burst. # Collapse each burst into a single synthetic press/release pair. if raw_lda_button and not self.lda_button_raw: @@ -348,7 +354,7 @@ class CarState(CarStateBase): lkas_button_events = [] self.cruise_buttons.extend(cp.vl_all["CLU11"]["CF_Clu_CruiseSwState"]) self.main_buttons.extend(cp.vl_all["CLU11"]["CF_Clu_CruiseSwMain"]) - if self.CP.carFingerprint in ALT_BUS_LDA_BUTTON_CARS and cp_alt is not None and cp_alt.ts_nanos["CLU13"]["CF_Clu_LdwsLkasSW"] > 0: + if self.CP.carFingerprint in ALT_BUS_LDA_BUTTON_CARS and cp_alt is not None and self.get_alt_bus_lda_button_raw_state(cp_alt)[1] > 0: lkas_button_events = self.create_alt_bus_lda_button_events(cp_alt) else: lkas_button_events = self.create_lkas_button_events(cp, prev_lda_button) diff --git a/opendbc_repo/opendbc/car/hyundai/tests/test_hyundai.py b/opendbc_repo/opendbc/car/hyundai/tests/test_hyundai.py index 017cc85aa..773e94ac2 100644 --- a/opendbc_repo/opendbc/car/hyundai/tests/test_hyundai.py +++ b/opendbc_repo/opendbc/car/hyundai/tests/test_hyundai.py @@ -719,6 +719,35 @@ class TestHyundaiFingerprint: assert any(be.type == ButtonType.lkas and be.pressed for be in ret.buttonEvents) assert any(be.type == ButtonType.lkas and not be.pressed for be in ret.buttonEvents) + def test_sonata_hybrid_alt_bus_initial_high_does_not_emit_lkas_button_event(self): + toggles = get_test_toggles() + fingerprint = gen_empty_fingerprint() + fingerprint[0][0x391] = 8 + fingerprint[1][0x50C] = 8 + CP = CarInterface.get_params(CAR.HYUNDAI_SONATA_HYBRID, fingerprint, [], False, False, False, toggles) + FPCP = CarInterface.get_starpilot_params(CAR.HYUNDAI_SONATA_HYBRID, fingerprint, [], CP, toggles) + + car_state = CarState(CP, FPCP) + can_parsers = car_state.get_can_parsers(CP) + packer = CANPacker(DBC[CP.carFingerprint][Bus.pt]) + + def update(lkas_button: int, frame: int): + msg = packer.make_can_msg("CLU13", 1, { + "CF_Clu_SWL_Stat": lkas_button, + }) + can_parsers[Bus.alt].update([(frame, [msg])]) + return car_state.update(can_parsers, toggles)[0] + + ret = update(4, 1) + assert not any(be.type == ButtonType.lkas for be in ret.buttonEvents) + + ret = update(0, 2) + assert not any(be.type == ButtonType.lkas for be in ret.buttonEvents) + + ret = update(4, 3) + assert any(be.type == ButtonType.lkas and be.pressed for be in ret.buttonEvents) + assert any(be.type == ButtonType.lkas and not be.pressed for be in ret.buttonEvents) + def test_genesis_g90_does_not_use_alt_bus_lkas_parser(self): toggles = get_test_toggles() CP = CarInterface.get_params(CAR.GENESIS_G90, gen_empty_fingerprint(), [], False, False, False, toggles)