diff --git a/opendbc_repo/opendbc/car/hyundai/carcontroller.py b/opendbc_repo/opendbc/car/hyundai/carcontroller.py index 73526bfaf..252466602 100644 --- a/opendbc_repo/opendbc/car/hyundai/carcontroller.py +++ b/opendbc_repo/opendbc/car/hyundai/carcontroller.py @@ -216,8 +216,12 @@ class CarController(CarControllerBase): # prevent LFA from activating on LKA steering cars by sending "no lane lines detected" to ADAS ECU if self.frame % 5 == 0 and lka_steering: + show_ioniq_6_lane_change_ui = self.CP.carFingerprint == CAR.HYUNDAI_IONIQ_6 and \ + bool(self.CP.flags & HyundaiFlags.CANFD_LKA_STEERING_ALT) and CC.enabled can_sends.append(hyundaicanfd.create_suppress_lfa(self.packer, self.CAN, CS.lfa_block_msg, - self.CP.flags & HyundaiFlags.CANFD_LKA_STEERING_ALT)) + self.CP.flags & HyundaiFlags.CANFD_LKA_STEERING_ALT, + left_lane_change=show_ioniq_6_lane_change_ui and CC.leftBlinker and not CC.rightBlinker, + right_lane_change=show_ioniq_6_lane_change_ui and CC.rightBlinker and not CC.leftBlinker)) # LFA and HDA icons if self.frame % 5 == 0 and (not lka_steering or lka_steering_long): diff --git a/opendbc_repo/opendbc/car/hyundai/hyundaicanfd.py b/opendbc_repo/opendbc/car/hyundai/hyundaicanfd.py index d78202f43..ff027bd30 100644 --- a/opendbc_repo/opendbc/car/hyundai/hyundaicanfd.py +++ b/opendbc_repo/opendbc/car/hyundai/hyundaicanfd.py @@ -4,6 +4,23 @@ from opendbc.car import CanBusBase from opendbc.car.crc import CRC16_XMODEM from opendbc.car.hyundai.values import HyundaiFlags +IONIQ_6_LANE_CHANGE_CAM_0X362 = { + "left": { + "LEFT_LANE_LINE": 3, + "RIGHT_LANE_LINE": 3, + "BYTE5": 0, + "BYTE6": 17, + "BYTE8": 17, + }, + "right": { + "LEFT_LANE_LINE": 3, + "RIGHT_LANE_LINE": 3, + "BYTE5": 1, + "BYTE6": 18, + "BYTE8": 8, + }, +} + def _set_value(msg: bytearray, sig, ival: int) -> None: i = sig.lsb // 8 @@ -133,7 +150,7 @@ def create_steering_messages(packer, CP, CAN, enabled, lat_active, apply_torque, return ret -def create_suppress_lfa(packer, CAN, lfa_block_msg, lka_steering_alt): +def create_suppress_lfa(packer, CAN, lfa_block_msg, lka_steering_alt, left_lane_change=False, right_lane_change=False): suppress_msg = "CAM_0x362" if lka_steering_alt else "CAM_0x2a4" msg_bytes = 32 if lka_steering_alt else 24 @@ -143,6 +160,10 @@ def create_suppress_lfa(packer, CAN, lfa_block_msg, lka_steering_alt): values["SET_ME_0_2"] = 0 values["LEFT_LANE_LINE"] = 0 values["RIGHT_LANE_LINE"] = 0 + if lka_steering_alt and left_lane_change ^ right_lane_change: + direction = "left" if left_lane_change else "right" + # These fields are the stable stock lane-change markers from the Ioniq 6 camera message. + values.update(IONIQ_6_LANE_CHANGE_CAM_0X362[direction]) return packer.make_can_msg(suppress_msg, CAN.ACAN, values) diff --git a/opendbc_repo/opendbc/car/hyundai/tests/test_hyundai.py b/opendbc_repo/opendbc/car/hyundai/tests/test_hyundai.py index d2d222f7e..c1b997934 100644 --- a/opendbc_repo/opendbc/car/hyundai/tests/test_hyundai.py +++ b/opendbc_repo/opendbc/car/hyundai/tests/test_hyundai.py @@ -286,6 +286,43 @@ class TestHyundaiFingerprint: assert decode_ioniq_6_blindspot_radar_state(0x1A) == (True, True) assert decode_ioniq_6_blindspot_radar_state(10.0) == (False, True) + def test_ioniq_6_lane_change_suppress_lfa_uses_stock_camera_markers(self): + CP = CarParams.new_message() + CP.carFingerprint = CAR.HYUNDAI_IONIQ_6 + CP.flags = int(HyundaiFlags.CANFD | HyundaiFlags.CANFD_LKA_STEERING | HyundaiFlags.CANFD_LKA_STEERING_ALT) + + packer = CANPacker(DBC[CP.carFingerprint][Bus.pt]) + can_bus = CanBus(CP) + parser = CANParser(DBC[CP.carFingerprint][Bus.pt], [("CAM_0x362", 0)], can_bus.ACAN) + + lfa_block_msg = { + "COUNTER": 9, + **{f"BYTE{i}": i for i in range(3, 32) if i != 7}, + } + + parser.update([(1, [hyundaicanfd.create_suppress_lfa(packer, can_bus, lfa_block_msg, True)])]) + assert parser.vl["CAM_0x362"]["LEFT_LANE_LINE"] == 0 + assert parser.vl["CAM_0x362"]["RIGHT_LANE_LINE"] == 0 + assert parser.vl["CAM_0x362"]["BYTE5"] == 5 + assert parser.vl["CAM_0x362"]["BYTE6"] == 6 + assert parser.vl["CAM_0x362"]["BYTE8"] == 8 + + parser.update([(2, [hyundaicanfd.create_suppress_lfa(packer, can_bus, lfa_block_msg, True, right_lane_change=True)])]) + assert parser.vl["CAM_0x362"]["LEFT_LANE_LINE"] == 3 + assert parser.vl["CAM_0x362"]["RIGHT_LANE_LINE"] == 3 + assert parser.vl["CAM_0x362"]["BYTE5"] == 1 + assert parser.vl["CAM_0x362"]["BYTE6"] == 18 + assert parser.vl["CAM_0x362"]["BYTE8"] == 8 + assert parser.vl["CAM_0x362"]["BYTE10"] == 10 + + parser.update([(3, [hyundaicanfd.create_suppress_lfa(packer, can_bus, lfa_block_msg, True, left_lane_change=True)])]) + assert parser.vl["CAM_0x362"]["LEFT_LANE_LINE"] == 3 + assert parser.vl["CAM_0x362"]["RIGHT_LANE_LINE"] == 3 + assert parser.vl["CAM_0x362"]["BYTE5"] == 0 + assert parser.vl["CAM_0x362"]["BYTE6"] == 17 + assert parser.vl["CAM_0x362"]["BYTE8"] == 17 + assert parser.vl["CAM_0x362"]["BYTE10"] == 10 + def test_sportage_angle_jerk_override_is_scoped(self): sportage = CarParams.new_message() sportage.carFingerprint = CAR.KIA_SPORTAGE_HEV_2026