diff --git a/opendbc_repo/opendbc/car/hyundai/interface.py b/opendbc_repo/opendbc/car/hyundai/interface.py index 9f9a4ae4f..bff4ae638 100644 --- a/opendbc_repo/opendbc/car/hyundai/interface.py +++ b/opendbc_repo/opendbc/car/hyundai/interface.py @@ -7,6 +7,7 @@ from opendbc.car.hyundai.values import HyundaiFlags, CAR, CarControllerParams, \ CANFD_RADAR_LIVE_LONGITUDINAL_CAR, \ RADAR_LIVE_LONGITUDINAL_CAR, \ UNSUPPORTED_LONGITUDINAL_CAR, HyundaiSafetyFlags, \ + LEGACY_LONGITUDINAL_CAR, \ HyundaiStarPilotSafetyFlags, \ hyundai_cancel_button_enables_cruise from opendbc.car.hyundai.radar_interface import get_radar_track_config, radar_tracks_available @@ -139,7 +140,7 @@ class CarInterface(CarInterfaceBase): else: # Shared configuration for non CAN-FD cars - ret.alphaLongitudinalAvailable = candidate not in UNSUPPORTED_LONGITUDINAL_CAR + ret.alphaLongitudinalAvailable = candidate not in UNSUPPORTED_LONGITUDINAL_CAR or candidate in LEGACY_LONGITUDINAL_CAR ret.enableBsm = 0x58b in fingerprint[CAN.ECAN] # Send LFA message on cars with HDA diff --git a/opendbc_repo/opendbc/car/hyundai/tests/test_hyundai.py b/opendbc_repo/opendbc/car/hyundai/tests/test_hyundai.py index 4d162997f..0b2de66b2 100644 --- a/opendbc_repo/opendbc/car/hyundai/tests/test_hyundai.py +++ b/opendbc_repo/opendbc/car/hyundai/tests/test_hyundai.py @@ -19,7 +19,7 @@ from opendbc.car.hyundai.radar_interface import MRREVO14F_RADAR_START_ADDR, MRR3 from opendbc.car.hyundai.values import CAMERA_SCC_CAR, CANFD_CAR, CAN_GEARS, CAR, CHECKSUM, DATE_FW_ECUS, \ HYBRID_CAR, EV_CAR, FW_QUERY_CONFIG, LEGACY_SAFETY_MODE_CAR, CANFD_FUZZY_WHITELIST, \ UNSUPPORTED_LONGITUDINAL_CAR, PLATFORM_CODE_ECUS, HYUNDAI_VERSION_REQUEST_LONG, \ - CarControllerParams, DBC, HyundaiFlags, get_platform_codes, HyundaiSafetyFlags, \ + LEGACY_LONGITUDINAL_CAR, CarControllerParams, DBC, HyundaiFlags, get_platform_codes, HyundaiSafetyFlags, \ HyundaiStarPilotSafetyFlags, Buttons LongCtrlState = CarControl.Actuators.LongControlState @@ -131,6 +131,7 @@ class TestHyundaiFingerprint: CAR.HYUNDAI_SANTA_FE_PHEV_2022, CAR.HYUNDAI_SONATA, CAR.HYUNDAI_SONATA_HYBRID, + CAR.KIA_XCEED_PHEV, CAR.KIA_K5_HEV_2020, CAR.KIA_NIRO_EV, CAR.KIA_NIRO_PHEV, @@ -152,7 +153,7 @@ class TestHyundaiFingerprint: fingerprint = gen_empty_fingerprint() fingerprint[1][RADAR_START_ADDR] = 8 - for candidate in (CAR.HYUNDAI_SONATA, CAR.HYUNDAI_SONATA_HYBRID, CAR.GENESIS_G90): + for candidate in (CAR.HYUNDAI_SONATA, CAR.HYUNDAI_SONATA_HYBRID, CAR.KIA_XCEED_PHEV, CAR.GENESIS_G90): CP = CarInterface.get_params(candidate, fingerprint, [], True, False, False, None) assert CP.openpilotLongitudinalControl assert not CP.radarUnavailable @@ -468,6 +469,54 @@ class TestHyundaiFingerprint: assert CP.pcmCruise assert not (CP.safetyConfigs[-1].safetyParam & HyundaiSafetyFlags.LONG) + def test_xceed_phev_alpha_long_is_isolated_legacy_experiment(self): + toggles = get_test_toggles() + + ceed = CarInterface.get_params(CAR.KIA_CEED, gen_empty_fingerprint(), [], True, False, False, toggles) + assert CAR.KIA_CEED not in LEGACY_LONGITUDINAL_CAR + assert not ceed.alphaLongitudinalAvailable + assert not ceed.openpilotLongitudinalControl + assert ceed.pcmCruise + assert ceed.safetyConfigs[-1].safetyModel == CarParams.SafetyModel.hyundaiLegacy + assert not (ceed.safetyConfigs[-1].safetyParam & HyundaiSafetyFlags.LONG) + + stock_xceed = CarInterface.get_params(CAR.KIA_XCEED_PHEV, gen_empty_fingerprint(), [], False, False, False, toggles) + assert CAR.KIA_XCEED_PHEV in LEGACY_LONGITUDINAL_CAR + assert stock_xceed.alphaLongitudinalAvailable + assert not stock_xceed.openpilotLongitudinalControl + assert stock_xceed.pcmCruise + assert stock_xceed.safetyConfigs[-1].safetyModel == CarParams.SafetyModel.hyundaiLegacy + assert stock_xceed.safetyConfigs[-1].safetyParam & HyundaiSafetyFlags.HYBRID_GAS + assert not (stock_xceed.safetyConfigs[-1].safetyParam & HyundaiSafetyFlags.LONG) + + long_xceed = CarInterface.get_params(CAR.KIA_XCEED_PHEV, gen_empty_fingerprint(), [], True, False, False, toggles) + assert long_xceed.alphaLongitudinalAvailable + assert long_xceed.openpilotLongitudinalControl + assert not long_xceed.pcmCruise + assert long_xceed.safetyConfigs[-1].safetyModel == CarParams.SafetyModel.hyundaiLegacy + assert long_xceed.safetyConfigs[-1].safetyParam & HyundaiSafetyFlags.HYBRID_GAS + assert long_xceed.safetyConfigs[-1].safetyParam & HyundaiSafetyFlags.LONG + + def test_xceed_phev_disable_failure_falls_back_to_stock_acc(self, monkeypatch): + toggles = get_test_toggles() + CP = CarInterface.get_params(CAR.KIA_XCEED_PHEV, gen_empty_fingerprint(), [], True, False, False, toggles) + + called = {} + + def fake_disable_ecu(*args, **kwargs): + called.update(kwargs) + return False + + monkeypatch.setattr("opendbc.car.hyundai.interface.disable_ecu", fake_disable_ecu) + CarInterface.init(CP, None, None) + + assert called["addr"] == 0x7d0 + assert called["bus"] == 0 + assert called["reset"] is False + assert not CP.openpilotLongitudinalControl + assert CP.pcmCruise + assert not (CP.safetyConfigs[-1].safetyParam & HyundaiSafetyFlags.LONG) + def test_canfd_longitudinal_params_match_family_tune(self): toggles = get_test_toggles() CP = CarInterface.get_params(CAR.KIA_EV6, gen_empty_fingerprint(), [], True, False, False, toggles) diff --git a/opendbc_repo/opendbc/car/hyundai/values.py b/opendbc_repo/opendbc/car/hyundai/values.py index 37a5b7636..c0aa73aec 100644 --- a/opendbc_repo/opendbc/car/hyundai/values.py +++ b/opendbc_repo/opendbc/car/hyundai/values.py @@ -728,7 +728,7 @@ class CAR(Platforms): KIA_XCEED_PHEV = HyundaiPlatformConfig( [HyundaiCarDocs("Kia XCeed Plug-in Hybrid 2021", car_parts=CarParts.common([CarHarness.hyundai_b]))], CarSpecs(mass=1650, wheelbase=2.65, steerRatio=13.75, tireStiffnessFactor=0.5), - flags=HyundaiFlags.LEGACY | HyundaiFlags.HYBRID, + flags=HyundaiFlags.LEGACY | HyundaiFlags.HYBRID | HyundaiFlags.MANDO_RADAR, ) KIA_EV6 = HyundaiCanFDPlatformConfig( [ @@ -1126,6 +1126,7 @@ RADAR_LIVE_LONGITUDINAL_CAR = CANFD_RADAR_LIVE_LONGITUDINAL_CAR | { CAR.HYUNDAI_SANTA_FE_PHEV_2022, CAR.HYUNDAI_SONATA, CAR.HYUNDAI_SONATA_HYBRID, + CAR.KIA_XCEED_PHEV, CAR.GENESIS_G90, } @@ -1143,4 +1144,6 @@ NON_SCC_CAR = CAR.with_flags(HyundaiFlags.NON_SCC) # HyundaiFlags.CANFD_RADAR_SCC | HyundaiFlags.CANFD_NO_RADAR_DISABLE | ) UNSUPPORTED_LONGITUDINAL_CAR = CAR.with_flags(HyundaiFlags.LEGACY) | CAR.with_flags(HyundaiFlags.UNSUPPORTED_LONGITUDINAL) +LEGACY_LONGITUDINAL_CAR = {CAR.KIA_XCEED_PHEV} + DBC = CAR.create_dbc_map() diff --git a/opendbc_repo/opendbc/safety/modes/hyundai.h b/opendbc_repo/opendbc/safety/modes/hyundai.h index f24ab60e3..3565f9645 100644 --- a/opendbc_repo/opendbc/safety/modes/hyundai.h +++ b/opendbc_repo/opendbc/safety/modes/hyundai.h @@ -70,6 +70,13 @@ static const CanMsg HYUNDAI_TX_MSGS[] = { HYUNDAI_COMMON_TX_MSGS(0) }; +static const CanMsg HYUNDAI_LONG_TX_MSGS[] = { + HYUNDAI_LONG_COMMON_TX_MSGS(0) + {0x38D, 0, 8, .check_relay = false}, // FCA11 Bus 0 + {0x483, 0, 8, .check_relay = false}, // FCA12 Bus 0 + {0x7D0, 0, 8, .check_relay = false}, // radar UDS TX addr Bus 0 (for radar disable) +}; + static bool hyundai_legacy = false; static uint8_t hyundai_get_counter(const CANPacket_t *msg) { @@ -322,13 +329,6 @@ static bool hyundai_tx_hook(const CANPacket_t *msg) { } static safety_config hyundai_init(uint16_t param) { - static const CanMsg HYUNDAI_LONG_TX_MSGS[] = { - HYUNDAI_LONG_COMMON_TX_MSGS(0) - {0x38D, 0, 8, .check_relay = false}, // FCA11 Bus 0 - {0x483, 0, 8, .check_relay = false}, // FCA12 Bus 0 - {0x7D0, 0, 8, .check_relay = false}, // radar UDS TX addr Bus 0 (for radar disable) - }; - static const CanMsg HYUNDAI_CAMERA_SCC_TX_MSGS[] = { HYUNDAI_COMMON_TX_MSGS(2) }; @@ -556,9 +556,9 @@ static safety_config hyundai_legacy_init(uint16_t param) { hyundai_common_init(param); hyundai_legacy = true; - hyundai_longitudinal = false; hyundai_camera_scc = false; - return BUILD_SAFETY_CFG(hyundai_legacy_rx_checks, HYUNDAI_TX_MSGS); + return hyundai_longitudinal ? BUILD_SAFETY_CFG(hyundai_legacy_rx_checks, HYUNDAI_LONG_TX_MSGS) : + BUILD_SAFETY_CFG(hyundai_legacy_rx_checks, HYUNDAI_TX_MSGS); } const safety_hooks hyundai_hooks = { diff --git a/opendbc_repo/opendbc/safety/tests/common.py b/opendbc_repo/opendbc/safety/tests/common.py index aa78a84bd..c5086c734 100644 --- a/opendbc_repo/opendbc/safety/tests/common.py +++ b/opendbc_repo/opendbc/safety/tests/common.py @@ -984,7 +984,8 @@ class SafetyTest(SafetyTestBase): continue if {attr, current_test}.issubset({'TestHyundaiLongitudinalSafety', 'TestHyundaiLongitudinalSafetyCameraSCC', 'TestHyundaiSafetyFCEVLong', 'TestHyundaiLongitudinalAolLkasOnEngageSafety', - 'TestHyundaiCanCanfdBlendedLongitudinalSafety'}): + 'TestHyundaiCanCanfdBlendedLongitudinalSafety', + 'TestHyundaiLegacyLongitudinalSafetyHEV'}): continue volkswagen_shared = ('TestVolkswagenMqb', 'TestVolkswagenMlb') if attr.startswith(volkswagen_shared) and current_test.startswith(volkswagen_shared): @@ -1017,7 +1018,8 @@ class SafetyTest(SafetyTestBase): if attr.startswith('TestHyundaiLongitudinal') or attr in ('TestHyundaiSafetyFCEVLong', 'TestHyundaiLongitudinalAolLkasOnEngageSafety', - 'TestHyundaiCanCanfdBlendedLongitudinalSafety'): + 'TestHyundaiCanCanfdBlendedLongitudinalSafety', + 'TestHyundaiLegacyLongitudinalSafetyHEV'): # exceptions for common msgs across different Hyundai CAN platforms tx = list(filter(lambda m: m[0] not in [0x420, 0x50A, 0x389, 0x4A2], tx)) all_tx.append([[m[0], m[1], attr] for m in tx]) diff --git a/opendbc_repo/opendbc/safety/tests/test_hyundai.py b/opendbc_repo/opendbc/safety/tests/test_hyundai.py index b4ade671f..7a7317f86 100755 --- a/opendbc_repo/opendbc/safety/tests/test_hyundai.py +++ b/opendbc_repo/opendbc/safety/tests/test_hyundai.py @@ -416,6 +416,14 @@ class TestHyundaiSafetyFCEVLong(TestHyundaiLongitudinalSafety, TestHyundaiSafety self.safety.init_tests() +class TestHyundaiLegacyLongitudinalSafetyHEV(TestHyundaiLongitudinalSafety, TestHyundaiLegacySafetyHEV): + def setUp(self): + self.packer = CANPackerSafety("hyundai_kia_generic") + self.safety = libsafety_py.libsafety + self.safety.set_safety_hooks(CarParams.SafetyModel.hyundaiLegacy, HyundaiSafetyFlags.HYBRID_GAS | HyundaiSafetyFlags.LONG) + self.safety.init_tests() + + class TestHyundaiLongitudinalAolLkasOnEngageSafety(HyundaiAolLkasOnEngageBase, TestHyundaiLongitudinalSafety): def setUp(self): self.packer = CANPackerSafety("hyundai_kia_generic")