diff --git a/opendbc_repo/opendbc/car/hyundai/carcontroller.py b/opendbc_repo/opendbc/car/hyundai/carcontroller.py index 0f0485fa1..ed2ef129d 100644 --- a/opendbc_repo/opendbc/car/hyundai/carcontroller.py +++ b/opendbc_repo/opendbc/car/hyundai/carcontroller.py @@ -583,6 +583,11 @@ 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 + # PT bus so the radar keeps tracking. + if self.CP.carFingerprint == CAR.HYUNDAI_IONIQ_6: + can_sends.append(hyundaicanfd.create_accelerator_brake_alt_spoof(0, self.frame, 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)) if self.CP.carFingerprint == CAR.HYUNDAI_IONIQ_6 and self.frame % 5 == 0: diff --git a/opendbc_repo/opendbc/car/hyundai/hyundaicanfd.py b/opendbc_repo/opendbc/car/hyundai/hyundaicanfd.py index 48c84c6ba..396e311f2 100644 --- a/opendbc_repo/opendbc/car/hyundai/hyundaicanfd.py +++ b/opendbc_repo/opendbc/car/hyundai/hyundaicanfd.py @@ -702,3 +702,22 @@ def hkg_can_fd_checksum(address: int, sig, d: bytearray) -> int: elif len(d) == 32: crc ^= 0x9F5B return crc + + +# Ioniq 6 / HKG LKA-steering: ADAS_DRV broadcasts ACCELERATOR_BRAKE_ALT (0x100) at 100 Hz 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. +# Length is 24 bytes on Ioniq 6 (DBC declares 32 for ICE Hyundais, but EV firmware uses 24). +# Byte template captured from a real ADAS broadcast; bytes 6-23 appear static / config. +_ACCEL_BRAKE_ALT_TEMPLATE = bytes.fromhex("000000020000fcff000000000020000055ff000068000000") + +def create_accelerator_brake_alt_spoof(bus: int, counter: int, brake_pressed: bool, accelerator_pressed: bool) -> CanData: + d = bytearray(_ACCEL_BRAKE_ALT_TEMPLATE) + d[2] = counter & 0xFF # COUNTER (bit 16, 8-bit) + d[4] = (d[4] & ~0x01) | (0x01 if brake_pressed else 0x00) # BRAKE_PRESSED (bit 32) + d[22] = (d[22] & ~0x01) | (0x01 if accelerator_pressed else 0x00) # ACCELERATOR_PEDAL_PRESSED (bit 176) + crc = hkg_can_fd_checksum(0x100, None, d) + d[0] = crc & 0xFF + d[1] = (crc >> 8) & 0xFF + return CanData(0x100, bytes(d), bus) diff --git a/opendbc_repo/opendbc/safety/modes/hyundai_canfd.h b/opendbc_repo/opendbc/safety/modes/hyundai_canfd.h index 063f9de8f..2341191bf 100644 --- a/opendbc_repo/opendbc/safety/modes/hyundai_canfd.h +++ b/opendbc_repo/opendbc/safety/modes/hyundai_canfd.h @@ -306,6 +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 {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