From b535c0845e1ee34fec509459495da85895b30021 Mon Sep 17 00:00:00 2001 From: firestar5683 <168790843+firestar5683@users.noreply.github.com> Date: Wed, 27 May 2026 15:58:40 -0500 Subject: [PATCH] ioniq 5 radar --- .../opendbc/car/hyundai/carcontroller.py | 8 ++++---- .../opendbc/car/hyundai/hyundaicanfd.py | 2 +- opendbc_repo/opendbc/car/hyundai/interface.py | 5 +++-- .../opendbc/car/hyundai/radar_interface.py | 5 +++-- .../opendbc/car/hyundai/tests/test_hyundai.py | 19 ++++++++++++++++--- opendbc_repo/opendbc/car/hyundai/values.py | 6 ++++-- .../opendbc/safety/modes/hyundai_canfd.h | 2 +- 7 files changed, 32 insertions(+), 15 deletions(-) diff --git a/opendbc_repo/opendbc/car/hyundai/carcontroller.py b/opendbc_repo/opendbc/car/hyundai/carcontroller.py index 659dff533e..42cd4c7738 100644 --- a/opendbc_repo/opendbc/car/hyundai/carcontroller.py +++ b/opendbc_repo/opendbc/car/hyundai/carcontroller.py @@ -7,7 +7,7 @@ from opendbc.car.lateral import apply_driver_steer_torque_limits, apply_steer_an from opendbc.car.common.conversions import Conversions as CV from opendbc.car.hyundai import hyundaicanfd, hyundaican from opendbc.car.hyundai.hyundaicanfd import CanBus -from opendbc.car.hyundai.values import HyundaiFlags, Buttons, CarControllerParams, CAR +from opendbc.car.hyundai.values import HyundaiFlags, Buttons, CarControllerParams, CAR, CANFD_RADAR_LIVE_LONGITUDINAL_CAR from opendbc.car.interfaces import CarControllerBase from opendbc.car.vehicle_model import VehicleModel from openpilot.common.params import Params @@ -583,10 +583,10 @@ class CarController(CarControllerBase): if self.long_active_ecu: if lka_steering: can_sends.extend(hyundaicanfd.create_adrv_messages(self.packer, self.CAN, self.frame)) - # Ioniq 6: front radar treats ADAS_DRV's 0x100 broadcast as its host heartbeat - # and stops publishing object tracks when it disappears. Spoof it at 100 Hz on + # Ioniq 5/6: front radar treats ADAS_DRV's 0x100 broadcast as its host heartbeat + # and stops publishing object tracks when it disappears. Spoof it periodically on # PT bus so the radar keeps tracking. - if self.CP.carFingerprint == CAR.HYUNDAI_IONIQ_6 and self.frame % 4 == 0: + if self.CP.carFingerprint in CANFD_RADAR_LIVE_LONGITUDINAL_CAR and self.frame % 4 == 0: can_sends.append(hyundaicanfd.create_accelerator_brake_alt_spoof(0, self.frame // 4, CS.out.brakePressed, CS.out.gasPressed)) elif not ccnc_non_hda2: can_sends.extend(hyundaicanfd.create_fca_warning_light(self.packer, self.CAN, self.frame)) diff --git a/opendbc_repo/opendbc/car/hyundai/hyundaicanfd.py b/opendbc_repo/opendbc/car/hyundai/hyundaicanfd.py index 396e311f25..f1fec6c37c 100644 --- a/opendbc_repo/opendbc/car/hyundai/hyundaicanfd.py +++ b/opendbc_repo/opendbc/car/hyundai/hyundaicanfd.py @@ -704,7 +704,7 @@ def hkg_can_fd_checksum(address: int, sig, d: bytearray) -> int: return crc -# Ioniq 6 / HKG LKA-steering: ADAS_DRV broadcasts ACCELERATOR_BRAKE_ALT (0x100) at 100 Hz on bus 0. +# Ioniq 5/6 / HKG LKA-steering: ADAS_DRV broadcasts ACCELERATOR_BRAKE_ALT (0x100) on bus 0. # The front radar uses this as its "host alive" heartbeat. When we disable ADAS_DRV the # radar stops publishing real object tracks. Spoof this message ourselves with valid CRC # and current pedal state so the radar keeps tracking. diff --git a/opendbc_repo/opendbc/car/hyundai/interface.py b/opendbc_repo/opendbc/car/hyundai/interface.py index c20afb9726..85f38ef6b7 100644 --- a/opendbc_repo/opendbc/car/hyundai/interface.py +++ b/opendbc_repo/opendbc/car/hyundai/interface.py @@ -4,6 +4,7 @@ from opendbc.car.hyundai.hyundaicanfd import CanBus from opendbc.car.hyundai.values import HyundaiFlags, CAR, CarControllerParams, \ CANFD_UNSUPPORTED_LONGITUDINAL_CAR, \ CANFD_SECURITYACCESS_CAR, \ + CANFD_RADAR_LIVE_LONGITUDINAL_CAR, \ UNSUPPORTED_LONGITUDINAL_CAR, HyundaiSafetyFlags, \ hyundai_cancel_button_enables_cruise from opendbc.car.hyundai.radar_interface import get_radar_track_config @@ -177,7 +178,7 @@ class CarInterface(CarInterfaceBase): if ret.flags & HyundaiFlags.NON_SCC: ret.alphaLongitudinalAvailable = False ret.openpilotLongitudinalControl = alpha_long and ret.alphaLongitudinalAvailable - if ret.openpilotLongitudinalControl and not (candidate == CAR.HYUNDAI_IONIQ_6 and radar_tracks_available): + if ret.openpilotLongitudinalControl and not (candidate in CANFD_RADAR_LIVE_LONGITUDINAL_CAR and radar_tracks_available): ret.radarUnavailable = True ret.pcmCruise = not ret.openpilotLongitudinalControl apply_platform_longitudinal_params(ret) @@ -229,7 +230,7 @@ class CarInterface(CarInterfaceBase): params = Params() if communication_control is None: - if CP.carFingerprint == CAR.HYUNDAI_IONIQ_6: + if CP.carFingerprint in CANFD_RADAR_LIVE_LONGITUDINAL_CAR: # Don't use 0x80 suppress bit so we can read the ECU response. # Use ENABLE_RX_DISABLE_TX (0x01) so the ECU can still receive from rear radars for BSM # while blocking SCC TX. diff --git a/opendbc_repo/opendbc/car/hyundai/radar_interface.py b/opendbc_repo/opendbc/car/hyundai/radar_interface.py index bb50a74399..49a7646b36 100644 --- a/opendbc_repo/opendbc/car/hyundai/radar_interface.py +++ b/opendbc_repo/opendbc/car/hyundai/radar_interface.py @@ -22,12 +22,13 @@ class RadarTrackConfig: msg_count: int radar_type: str bus: int = 1 + frequency: int = 50 RADAR_TRACK_CONFIGS = { HYUNDAI_MANDO_FRONT_RADAR_DBC: RadarTrackConfig(RADAR_START_ADDR, RADAR_MSG_COUNT, "mando"), HYUNDAI_MRR30_RADAR_DBC: RadarTrackConfig(MRR30_RADAR_START_ADDR, MRR30_RADAR_MSG_COUNT, "mrr30"), - HYUNDAI_MRR35_RADAR_DBC: RadarTrackConfig(MRR35_RADAR_START_ADDR, MRR35_RADAR_MSG_COUNT, "mrr35", bus=0), + HYUNDAI_MRR35_RADAR_DBC: RadarTrackConfig(MRR35_RADAR_START_ADDR, MRR35_RADAR_MSG_COUNT, "mrr35", bus=0, frequency=20), } # POC for parsing corner radars: https://github.com/commaai/openpilot/pull/24221/ @@ -42,7 +43,7 @@ def get_radar_can_parser(CP, radar_config): if radar_config is None: return None - messages = [(f"RADAR_TRACK_{addr:x}", 50) for addr in range(radar_config.start_addr, radar_config.start_addr + radar_config.msg_count)] + messages = [(f"RADAR_TRACK_{addr:x}", radar_config.frequency) for addr in range(radar_config.start_addr, radar_config.start_addr + radar_config.msg_count)] return CANParser(DBC[CP.carFingerprint][Bus.radar], messages, radar_config.bus) diff --git a/opendbc_repo/opendbc/car/hyundai/tests/test_hyundai.py b/opendbc_repo/opendbc/car/hyundai/tests/test_hyundai.py index bdeebd58e6..cdaa5c00c8 100644 --- a/opendbc_repo/opendbc/car/hyundai/tests/test_hyundai.py +++ b/opendbc_repo/opendbc/car/hyundai/tests/test_hyundai.py @@ -127,16 +127,19 @@ class TestHyundaiFingerprint: assert CP.radarUnavailable != radar for candidate, radar_addr in ( + (CAR.HYUNDAI_IONIQ_5, MRR30_RADAR_START_ADDR), (CAR.HYUNDAI_IONIQ_5_N, MRR30_RADAR_START_ADDR), (CAR.KIA_EV6_2025, MRR30_RADAR_START_ADDR), (CAR.HYUNDAI_KONA_EV_2ND_GEN, MRR35_RADAR_START_ADDR), + (CAR.HYUNDAI_IONIQ_6, MRR35_RADAR_START_ADDR), (CAR.HYUNDAI_IONIQ_9, MRR35_RADAR_START_ADDR), ): - assert get_radar_track_config(candidate).start_addr == radar_addr + radar_config = get_radar_track_config(candidate) + assert radar_config.start_addr == radar_addr for radar in (True, False): fingerprint = gen_empty_fingerprint() if radar: - fingerprint[1][radar_addr] = 8 + fingerprint[radar_config.bus][radar_addr] = 8 CP = CarInterface.get_params(candidate, fingerprint, [], False, False, False, None) assert CP.radarUnavailable != radar @@ -151,9 +154,19 @@ class TestHyundaiFingerprint: assert CP.openpilotLongitudinalControl assert CP.radarUnavailable + fingerprint = gen_empty_fingerprint() + fingerprint[get_radar_track_config(CAR.HYUNDAI_IONIQ_6).bus][MRR35_RADAR_START_ADDR] = 24 CP = CarInterface.get_params(CAR.HYUNDAI_IONIQ_6, fingerprint, [], True, False, False, None) assert CP.openpilotLongitudinalControl - assert CP.radarUnavailable + assert not CP.radarUnavailable + assert get_radar_track_config(CAR.HYUNDAI_IONIQ_6).frequency == 20 + + fingerprint = gen_empty_fingerprint() + fingerprint[CanBus(None, fingerprint).CAM][0x50] = 32 + fingerprint[get_radar_track_config(CAR.HYUNDAI_IONIQ_5).bus][MRR30_RADAR_START_ADDR] = 32 + CP = CarInterface.get_params(CAR.HYUNDAI_IONIQ_5, fingerprint, [], True, False, False, None) + assert CP.openpilotLongitudinalControl + assert not CP.radarUnavailable for candidate in HYUNDAI_NON_SCC_CARS: CP = CarInterface.get_params(candidate, gen_empty_fingerprint(), [], True, False, False, None) diff --git a/opendbc_repo/opendbc/car/hyundai/values.py b/opendbc_repo/opendbc/car/hyundai/values.py index 875e4d3bcb..26fd9a6135 100644 --- a/opendbc_repo/opendbc/car/hyundai/values.py +++ b/opendbc_repo/opendbc/car/hyundai/values.py @@ -491,6 +491,7 @@ class CAR(Platforms): ], CarSpecs(mass=1948, wheelbase=2.97, steerRatio=14.26, tireStiffnessFactor=0.65), flags=HyundaiFlags.EV, + radar_dbc=HYUNDAI_MRR30_RADAR_DBC, ) HYUNDAI_IONIQ_5_PE = HyundaiCanFDPlatformConfig( [ @@ -1105,9 +1106,10 @@ CAN_GEARS = { CANFD_CAR = CAR.with_flags(HyundaiFlags.CANFD) CANFD_RADAR_SCC_CAR = CAR.with_flags(HyundaiFlags.RADAR_SCC) # TODO: merge with UNSUPPORTED_LONGITUDINAL_CAR -# Cars with CANFD_NO_RADAR_DISABLE that now work with SecurityAccess handshake -CANFD_SECURITYACCESS_CAR = {CAR.HYUNDAI_IONIQ_6, CAR.HYUNDAI_KONA_EV_2ND_GEN} +# CAN-FD cars with ADAS ECUs that work with the communication-control path. +CANFD_SECURITYACCESS_CAR = {CAR.HYUNDAI_IONIQ_5, CAR.HYUNDAI_IONIQ_6, CAR.HYUNDAI_KONA_EV_2ND_GEN} CANFD_UNSUPPORTED_LONGITUDINAL_CAR = CAR.with_flags(HyundaiFlags.CANFD_NO_RADAR_DISABLE) - CANFD_SECURITYACCESS_CAR # TODO: merge with UNSUPPORTED_LONGITUDINAL_CAR +CANFD_RADAR_LIVE_LONGITUDINAL_CAR = {CAR.HYUNDAI_IONIQ_5, CAR.HYUNDAI_IONIQ_6} CAMERA_SCC_CAR = CAR.with_flags(HyundaiFlags.CAMERA_SCC) diff --git a/opendbc_repo/opendbc/safety/modes/hyundai_canfd.h b/opendbc_repo/opendbc/safety/modes/hyundai_canfd.h index 2341191bf2..4d96fe9396 100644 --- a/opendbc_repo/opendbc/safety/modes/hyundai_canfd.h +++ b/opendbc_repo/opendbc/safety/modes/hyundai_canfd.h @@ -306,7 +306,7 @@ static safety_config hyundai_canfd_init(uint16_t param) { HYUNDAI_CANFD_SCC_CONTROL_COMMON_TX_MSGS(1, true) HYUNDAI_CANFD_BLINDSPOT_DASH_TX_MSGS(1) {0x51, 0, 32, .check_relay = false}, // ADRV_0x51 - {0x100, 0, 24, .check_relay = false}, // Ioniq 6: ACCELERATOR_BRAKE_ALT radar heartbeat spoof + {0x100, 0, 24, .check_relay = false}, // Ioniq 5/6: ACCELERATOR_BRAKE_ALT radar heartbeat spoof {0x730, 1, 8, .check_relay = false}, // tester present for ADAS ECU disable {0x160, 1, 16, .check_relay = false}, // ADRV_0x160 {0x1EA, 1, 32, .check_relay = false}, // ADRV_0x1ea