diff --git a/opendbc/car/hyundai/carcontroller.py b/opendbc/car/hyundai/carcontroller.py index 6d6aa8ad947..28a84032e8e 100644 --- a/opendbc/car/hyundai/carcontroller.py +++ b/opendbc/car/hyundai/carcontroller.py @@ -165,6 +165,7 @@ def create_canfd_msgs(self, apply_steer_req, apply_torque, set_speed_in_units, a lka_steering = self.CP.flags & HyundaiFlags.CANFD_LKA_STEERING lka_steering_long = lka_steering and self.CP.openpilotLongitudinalControl + ccnc_non_hda2 = self.CP.flags & HyundaiFlags.CCNC and not lka_steering # steering control can_sends.extend(hyundaicanfd.create_steering_messages(self.packer, self.CP, self.CAN, CC.enabled, apply_steer_req, apply_torque)) @@ -176,7 +177,11 @@ def create_canfd_msgs(self, apply_steer_req, apply_torque, set_speed_in_units, a # LFA and HDA icons if self.frame % 5 == 0 and (not lka_steering or lka_steering_long): - can_sends.append(hyundaicanfd.create_lfahda_cluster(self.packer, self.CAN, CC.enabled)) + if ccnc_non_hda2: + can_sends.extend(hyundaicanfd.create_ccnc(self.packer, self.CAN, self.CP.openpilotLongitudinalControl, CC.enabled, CC.hudControl, + CC.leftBlinker, CC.rightBlinker, CS.msg_161, CS.msg_162, CS.msg_1b5, CS.is_metric, CS.out)) + else: + can_sends.append(hyundaicanfd.create_lfahda_cluster(self.packer, self.CAN, CC.enabled)) # blinkers if lka_steering and self.CP.flags & HyundaiFlags.ENABLE_BLINKERS: @@ -185,11 +190,11 @@ def create_canfd_msgs(self, apply_steer_req, apply_torque, set_speed_in_units, a if self.CP.openpilotLongitudinalControl: if lka_steering: can_sends.extend(hyundaicanfd.create_adrv_messages(self.packer, self.CAN, self.frame)) - else: + elif not ccnc_non_hda2: can_sends.extend(hyundaicanfd.create_fca_warning_light(self.packer, self.CAN, self.frame)) if self.frame % 2 == 0: can_sends.append(hyundaicanfd.create_acc_control(self.packer, self.CAN, CC.enabled, self.accel_last, accel, stopping, CC.cruiseControl.override, - set_speed_in_units, hud_control)) + set_speed_in_units, hud_control, CS.cruise_info if ccnc_non_hda2 else None)) self.accel_last = accel else: # button presses diff --git a/opendbc/car/hyundai/carstate.py b/opendbc/car/hyundai/carstate.py index 60978970ab2..04a83446492 100644 --- a/opendbc/car/hyundai/carstate.py +++ b/opendbc/car/hyundai/carstate.py @@ -56,6 +56,7 @@ def __init__(self, CP): self.buttons_counter = 0 self.cruise_info = {} + self.msg_161, self.msg_162, self.msg_1b5 = {}, {}, {} # On some cars, CLU15->CF_Clu_VehicleSpeed can oscillate faster than the dash updates. Sample at 5 Hz self.cluster_speed = 0 @@ -243,15 +244,16 @@ def update_canfd(self, can_parsers) -> structs.CarState: ret.steeringPressed = self.update_steering_pressed(abs(ret.steeringTorque) > self.params.STEER_THRESHOLD, 5) ret.steerFaultTemporary = cp.vl["MDPS"]["LKA_FAULT"] != 0 - # TODO: alt signal usage may be described by cp.vl['BLINKERS']['USE_ALT_LAMP'] - left_blinker_sig, right_blinker_sig = "LEFT_LAMP", "RIGHT_LAMP" - if self.CP.carFingerprint == CAR.HYUNDAI_KONA_EV_2ND_GEN: - left_blinker_sig, right_blinker_sig = "LEFT_LAMP_ALT", "RIGHT_LAMP_ALT" - ret.leftBlinker, ret.rightBlinker = self.update_blinker_from_lamp(50, cp.vl["BLINKERS"][left_blinker_sig], - cp.vl["BLINKERS"][right_blinker_sig]) + alt = "_ALT" if self.CP.carFingerprint == CAR.HYUNDAI_KONA_EV_2ND_GEN else "" + if self.CP.flags & HyundaiFlags.CCNC and not self.CP.flags & HyundaiFlags.CANFD_LKA_STEERING: + self.msg_161, self.msg_162, self.msg_1b5 = map(copy.copy, (cp_cam.vl["CCNC_0x161"], cp_cam.vl["CCNC_0x162"], cp_cam.vl["FR_CMR_03_50ms"])) + self.cruise_info = copy.copy((cp_cam if self.CP.flags & HyundaiFlags.CANFD_CAMERA_SCC else cp).vl["SCC_CONTROL"]) + alt = "_ALT" + ret.leftBlinker, ret.rightBlinker = self.update_blinker_from_lamp(50, cp.vl["BLINKERS"][f"LEFT_LAMP{alt}"], + cp.vl["BLINKERS"][f"RIGHT_LAMP{alt}"]) if self.CP.enableBsm: - ret.leftBlindspot = cp.vl["BLINDSPOTS_REAR_CORNERS"]["FL_INDICATOR"] != 0 - ret.rightBlindspot = cp.vl["BLINDSPOTS_REAR_CORNERS"]["FR_INDICATOR"] != 0 + ret.leftBlindspot = cp.vl["BLINDSPOTS_REAR_CORNERS"][f"FL_INDICATOR{alt}"] != 0 + ret.rightBlindspot = cp.vl["BLINDSPOTS_REAR_CORNERS"][f"FR_INDICATOR{alt}"] != 0 # cruise state # CAN FD cars enable on main button press, set available if no TCS faults preventing engagement diff --git a/opendbc/car/hyundai/fingerprints.py b/opendbc/car/hyundai/fingerprints.py index 4c59f92ebcb..d636b1e8408 100644 --- a/opendbc/car/hyundai/fingerprints.py +++ b/opendbc/car/hyundai/fingerprints.py @@ -213,6 +213,15 @@ b'\xf1\x00DN8 MFC AT USA LHD 1.00 1.07 99211-L1000 211223', ], }, + CAR.HYUNDAI_SONATA_2024: { + (Ecu.fwdCamera, 0x7c4, None): [ + b'\xf1\x00DN8 MFC AT KOR LHD 1.00 1.01 99211-L1800 230512', + b'\xf1\x00DN8 MFC AT USA LHD 1.00 1.01 99211-L1800 230512', + ], + (Ecu.fwdRadar, 0x7d0, None): [ + b'\xf1\x00DN8_ RDR ----- 1.00 1.00 99110-L1800 ', + ], + }, CAR.HYUNDAI_SONATA_LF: { (Ecu.fwdRadar, 0x7d0, None): [ b'\xf1\x00LF__ SCC F-CUP 1.00 1.00 96401-C2200 ', @@ -561,6 +570,16 @@ b'\xf1\x00OS9 LKAS AT USA LHD 1.00 1.00 95740-J9300 g21', ], }, + CAR.HYUNDAI_KONA_2ND_GEN: { + (Ecu.fwdCamera, 0x7c4, None): [ + b'\xf1\x00SX2 MFC AT USA LHD 1.00 1.03 99211-BE000 230517', + b'\xf1\x00SX2 MFC AT USA LHD 1.00 1.07 99211-BE000 240611', + ], + (Ecu.fwdRadar, 0x7d0, None): [ + b'\xf1\x00SX2_ RDR ----- 1.00 1.02 99110-BE000 ', + b'\xf1\x00SX2_ RDR ----- 1.00 1.02 99110-BE500 ', + ], + }, CAR.KIA_CEED: { (Ecu.fwdRadar, 0x7d0, None): [ b'\xf1\x00CD__ SCC F-CUP 1.00 1.00 99110-J7500 ', @@ -596,6 +615,14 @@ b'\xf1\x00BD__ SCC H-CUP 1.00 1.02 99110-M6000 ', ], }, + CAR.KIA_K4_2025: { + (Ecu.fwdCamera, 0x7c4, None): [ + b'\xf1\x00CL4 MFC AT USA LHD 1.00 1.02 99210-GG000 240708', + ], + (Ecu.fwdRadar, 0x7d0, None): [ + b'\xf1\x00CL4_ RDR ----- 1.00 1.01 99110-GG000 ', + ], + }, CAR.KIA_K5_2021: { (Ecu.fwdRadar, 0x7d0, None): [ b'\xf1\x00DL3_ SCC F-CUP 1.00 1.03 99110-L2100 ', @@ -628,6 +655,14 @@ b'\xf1\x00DL ESC \t 102"\x08\x10 58910-L3800', ], }, + CAR.KIA_K5_2025: { + (Ecu.fwdCamera, 0x7c4, None): [ + b'\xf1\x00DL3 MFC AT USA LHD 1.00 1.04 99210-L2500 240117', + ], + (Ecu.fwdRadar, 0x7d0, None): [ + b'\xf1\x00DL3_ RDR ----- 1.00 1.01 99110-L2500 ', + ], + }, CAR.KIA_K5_HEV_2020: { (Ecu.fwdRadar, 0x7d0, None): [ b'\xf1\x00DLhe SCC FHCUP 1.00 1.02 99110-L7000 ', @@ -711,6 +746,7 @@ ], (Ecu.fwdCamera, 0x7c4, None): [ b'\xf1\x00SX2EMFC AT KOR LHD 1.00 1.00 99211-BF000 230410', + b'\xf1\x00SX2EMFC AT USA LHD 1.00 1.02 99211-BF000 230823', ], }, CAR.KIA_NIRO_EV: { @@ -966,6 +1002,16 @@ b'\xf1\x00OSH LKAS AT KOR LHD 1.00 1.01 95740-CM000 l31', ], }, + CAR.HYUNDAI_KONA_HEV_2ND_GEN: { + (Ecu.fwdCamera, 0x7c4, None): [ + b'\xf1\x00SX2HMFC AT AUS RHD 1.00 1.00 99211-BE001 241015', + b'\xf1\x00SX2HMFC AT EUR RHD 1.00 1.04 99211-BE000 231010', + ], + (Ecu.fwdRadar, 0x7d0, None): [ + b'\xf1\x00SX2_ RDR ----- 1.00 1.02 99110-BE000 ', + b'\xf1\x00SX2_ RDR ----- 1.00 1.02 99110-BE500 ', + ], + }, CAR.HYUNDAI_SONATA_HYBRID: { (Ecu.fwdRadar, 0x7d0, None): [ b'\xf1\x00DNhe SCC F-CUP 1.00 1.02 99110-L5000 ', @@ -987,6 +1033,15 @@ b'\xf1\x00DN8HMFC AT USA LHD 1.00 1.07 99211-L1000 211223', ], }, + CAR.HYUNDAI_SONATA_HEV_2024: { + (Ecu.fwdCamera, 0x7c4, None): [ + b'\xf1\x00DN8HMFC AT KOR LHD 1.00 1.01 99211-L1800 230512', + b'\xf1\x00DN8HMFC AT USA LHD 1.00 1.01 99211-L1800 230512', + ], + (Ecu.fwdRadar, 0x7d0, None): [ + b'\xf1\x00DN8_ RDR ----- 1.00 1.00 99110-L1800 ', + ], + }, CAR.KIA_SORENTO: { (Ecu.fwdCamera, 0x7c4, None): [ b'\xf1\x00UMP LKAS AT AUS RHD 1.00 1.00 96400-C6550 S30', @@ -1089,6 +1144,16 @@ b'\xf1\x00NX4__ 1.01 1.00 99110-N9100 ', ], }, + CAR.HYUNDAI_TUCSON_HEV_2025: { + (Ecu.fwdCamera, 0x7c4, None): [ + b'\xf1\x00NX4 FR_CMR AT USA LHD 1.00 1.00 99211-N7030 C55', + b'\xf1\x00NX4 FR_CMR AT EUR LHD 1.00 1.00 99211-N7030 C55', + ], + (Ecu.fwdRadar, 0x7d0, None): [ + b'\xf1\x00NX4__ 1.00 1.02 99110N7000 ', + b'\xf1\x00NX4__ 1.00 1.02 99110N7100 ', + ], + }, CAR.HYUNDAI_SANTA_CRUZ_1ST_GEN: { (Ecu.fwdCamera, 0x7c4, None): [ b'\xf1\x00NX4 FR_CMR AT USA LHD 1.00 1.00 99211-CW000 14M', @@ -1100,6 +1165,14 @@ b'\xf1\x00NX4__ 1.01 1.00 99110-K5000 ', ], }, + CAR.HYUNDAI_SANTA_CRUZ_2025: { + (Ecu.fwdCamera, 0x7c4, None): [ + b'\xf1\x00NX4 FR_CMR AT USA LHD 1.00 1.00 99211-N7030 C55', + ], + (Ecu.fwdRadar, 0x7d0, None): [ + b'\xf1\x00NX4__ 1.00 1.00 99110K5500 ', + ], + }, CAR.KIA_SPORTAGE_5TH_GEN: { (Ecu.fwdCamera, 0x7c4, None): [ b'\xf1\x00NQ5 FR_CMR AT AUS RHD 1.00 1.00 99211-P1040 663', @@ -1171,6 +1244,14 @@ b'\xf1\x00MQ4_ SCC FHCUP 1.00 1.08 99110-P2000 ', ], }, + CAR.KIA_SORENTO_2024: { + (Ecu.fwdCamera, 0x7c4, None): [ + b'\xf1\x00MQ4 MFC AT AUS RHD 1.01 1.04 99210-P2550 231127', + ], + (Ecu.fwdRadar, 0x7d0, None): [ + b'\xf1\x00MQ4_ RDR ----- 1.00 1.01 99110-P2500 ', + ], + }, CAR.KIA_SORENTO_HEV_4TH_GEN: { (Ecu.fwdCamera, 0x7c4, None): [ b'\xf1\x00MQ4HMFC AT KOR LHD 1.00 1.04 99210-P2000 200330', diff --git a/opendbc/car/hyundai/hyundaicanfd.py b/opendbc/car/hyundai/hyundaicanfd.py index 1537bb4fdc0..47dc1a19dc7 100644 --- a/opendbc/car/hyundai/hyundaicanfd.py +++ b/opendbc/car/hyundai/hyundaicanfd.py @@ -1,6 +1,7 @@ import copy import numpy as np from opendbc.car import CanBusBase +from opendbc.car.common.conversions import Conversions as CV from opendbc.car.crc import CRC16_XMODEM from opendbc.car.hyundai.values import HyundaiFlags @@ -130,7 +131,108 @@ def create_lfahda_cluster(packer, CAN, enabled): return packer.make_can_msg("LFAHDA_CLUSTER", CAN.ECAN, values) -def create_acc_control(packer, CAN, enabled, accel_last, accel, stopping, gas_override, set_speed, hud_control): +def create_ccnc(packer, CAN, openpilotLongitudinalControl, enabled, hud, leftBlinker, rightBlinker, msg_161, msg_162, msg_1b5, is_metric, out): + for f in {"FAULT_LSS", "FAULT_HDA", "FAULT_DAS", "FAULT_LFA", "FAULT_DAW", "FAULT_ESS"}: + msg_162[f] = 0 + if msg_161["ALERTS_2"] == 5: + msg_161.update({"ALERTS_2": 0, "SOUNDS_2": 0}) + if msg_161["ALERTS_3"] == 17: + msg_161["ALERTS_3"] = 0 + if msg_161["ALERTS_5"] in (2, 5): + msg_161["ALERTS_5"] = 0 + if msg_161["SOUNDS_4"] == 2 and msg_161["LFA_ICON"] in (3, 0,): + msg_161["SOUNDS_4"] = 0 + + LANE_CHANGE_SPEED_MIN = 8.9408 + anyBlinker = leftBlinker or rightBlinker + curvature = {i: (31 if i == -1 else 13 - abs(i + 15)) if i < 0 else 15 + i for i in range(-15, 16)} + + lfa_icon = enabled + + msg_161.update({ + "DAW_ICON": 0, + "LKA_ICON": 0, + "LFA_ICON": 2 if lfa_icon else 0, + "CENTERLINE": 1 if lfa_icon else 0, + "LANELINE_CURVATURE": curvature.get(max(-15, min(int(out.steeringAngleDeg / 4.5), 15)), 14) if lfa_icon and not anyBlinker else 15, + "LANELINE_LEFT": (0 if not lfa_icon else 1 if not hud.leftLaneVisible else 4 if hud.leftLaneDepart else 6 if anyBlinker else 2), + "LANELINE_RIGHT": (0 if not lfa_icon else 1 if not hud.rightLaneVisible else 4 if hud.rightLaneDepart else 6 if anyBlinker else 2), + "LCA_LEFT_ICON": (0 if not lfa_icon or out.vEgo < LANE_CHANGE_SPEED_MIN else 1 if out.leftBlindspot else 2 if anyBlinker else 4), + "LCA_RIGHT_ICON": (0 if not lfa_icon or out.vEgo < LANE_CHANGE_SPEED_MIN else 1 if out.rightBlindspot else 2 if anyBlinker else 4), + "LCA_LEFT_ARROW": 2 if leftBlinker else 0, + "LCA_RIGHT_ARROW": 2 if rightBlinker else 0, + }) + + if lfa_icon and (leftBlinker or rightBlinker): + leftlaneraw, rightlaneraw = msg_1b5["Info_LftLnPosVal"], msg_1b5["Info_RtLnPosVal"] + + scale_per_m = 15 / 1.7 + leftlane = abs(int(round(15 + (leftlaneraw - 1.7) * scale_per_m))) + rightlane = abs(int(round(15 + (rightlaneraw - 1.7) * scale_per_m))) + + if msg_1b5["Info_LftLnQualSta"] not in (2, 3): + leftlane = 0 + if msg_1b5["Info_RtLnQualSta"] not in (2, 3): + rightlane = 0 + + if leftlaneraw == -2.0248375: + leftlane = 30 - rightlane + if rightlaneraw == 2.0248375: + rightlane = 30 - leftlane + + if leftlaneraw == rightlaneraw == 0: + leftlane = rightlane = 15 + elif leftlaneraw == 0: + leftlane = 30 - rightlane + elif rightlaneraw == 0: + rightlane = 30 - leftlane + + total = leftlane + rightlane + if total == 0: + leftlane = rightlane = 15 + else: + leftlane = round((leftlane / total) * 30) + rightlane = 30 - leftlane + + msg_161["LANELINE_LEFT_POSITION"] = leftlane + msg_161["LANELINE_RIGHT_POSITION"] = rightlane + + if hud.leftLaneDepart or hud.rightLaneDepart: + msg_162["VIBRATE"] = 1 + + if openpilotLongitudinalControl: + if msg_161["ALERTS_3"] in (1, 2, 3, 4, 7, 8, 9, 10): + msg_161["ALERTS_3"] = 0 + if msg_161["ALERTS_5"] == 4: + msg_161["ALERTS_5"] = 0 + if msg_161["SOUNDS_3"] == 5: + msg_161["SOUNDS_3"] = 0 + + main_cruise_enabled = out.cruiseState.available + + msg_161.update({ + "SETSPEED": 3 if enabled else 1, + "SETSPEED_HUD": 0 if not main_cruise_enabled else 2 if enabled else 1, + "SETSPEED_SPEED": ( + 255 if not main_cruise_enabled else + (40 if is_metric else 25) if (s := round(out.vCruiseCluster * (1 if is_metric else CV.KPH_TO_MPH))) > (145 if is_metric else 90) else s + ), + "DISTANCE": hud.leadDistanceBars, + "DISTANCE_SPACING": 0 if not main_cruise_enabled else 1 if enabled else 3, + "DISTANCE_LEAD": 0 if not main_cruise_enabled else 2 if enabled and hud.leadVisible else 1 if hud.leadVisible else 0, + "DISTANCE_CAR": 0 if not main_cruise_enabled else 2 if enabled else 1, + "SLA_ICON": 0, + "NAV_ICON": 0, + "TARGET": 0, + }) + + msg_162["LEAD"] = 0 if not main_cruise_enabled else 2 if enabled else 1 + msg_162["LEAD_DISTANCE"] = msg_1b5["Longitudinal_Distance"] + + return [packer.make_can_msg(msg, CAN.ECAN, data) for msg, data in [("CCNC_0x161", msg_161), ("CCNC_0x162", msg_162)]] + + +def create_acc_control(packer, CAN, enabled, accel_last, accel, stopping, gas_override, set_speed, hud_control, cruise_info=None): jerk = 5 jn = jerk / 50 if not enabled or gas_override: @@ -157,6 +259,8 @@ def create_acc_control(packer, CAN, enabled, accel_last, accel, stopping, gas_ov "SET_ME_TMP_64": 0x64, "DISTANCE_SETTING": hud_control.leadDistanceBars, } + if cruise_info: + values.update({s: cruise_info[s] for s in ["ACC_ObjDist", "ACC_ObjRelSpd"]}) return packer.make_can_msg("SCC_CONTROL", CAN.ECAN, values) diff --git a/opendbc/car/hyundai/interface.py b/opendbc/car/hyundai/interface.py index 1e058c4fce7..260ca6cbcdf 100644 --- a/opendbc/car/hyundai/interface.py +++ b/opendbc/car/hyundai/interface.py @@ -80,6 +80,8 @@ def _get_params(ret: structs.CarParams, candidate, fingerprint, car_fw, alpha_lo ret.safetyConfigs[-1].safetyParam |= HyundaiSafetyFlags.CANFD_ALT_BUTTONS.value if ret.flags & HyundaiFlags.CANFD_CAMERA_SCC: ret.safetyConfigs[-1].safetyParam |= HyundaiSafetyFlags.CAMERA_SCC.value + if ret.flags & HyundaiFlags.CCNC and not ret.flags & HyundaiFlags.CANFD_LKA_STEERING: + ret.safetyConfigs[-1].safetyParam |= HyundaiSafetyFlags.CCNC.value else: # Shared configuration for non CAN-FD cars diff --git a/opendbc/car/hyundai/tests/test_hyundai.py b/opendbc/car/hyundai/tests/test_hyundai.py index b798acaa1d0..b9663bd3064 100644 --- a/opendbc/car/hyundai/tests/test_hyundai.py +++ b/opendbc/car/hyundai/tests/test_hyundai.py @@ -22,7 +22,9 @@ # CAN FD CAR.KIA_SPORTAGE_5TH_GEN, CAR.HYUNDAI_SANTA_CRUZ_1ST_GEN, + CAR.HYUNDAI_SANTA_CRUZ_2025, CAR.HYUNDAI_TUCSON_4TH_GEN, + CAR.HYUNDAI_TUCSON_HEV_2025, # CAN CAR.HYUNDAI_ELANTRA, CAR.HYUNDAI_ELANTRA_GT_I30, diff --git a/opendbc/car/hyundai/values.py b/opendbc/car/hyundai/values.py index e239298a00b..adb8773083e 100644 --- a/opendbc/car/hyundai/values.py +++ b/opendbc/car/hyundai/values.py @@ -66,6 +66,7 @@ class HyundaiSafetyFlags(IntFlag): CANFD_LKA_STEERING_ALT = 128 FCEV_GAS = 256 ALT_LIMITS_2 = 512 + CCNC = 1024 class HyundaiFlags(IntFlag): @@ -126,6 +127,8 @@ class HyundaiFlags(IntFlag): ALT_LIMITS_2 = 2 ** 26 + CCNC = 2 ** 27 + @dataclass class HyundaiCarDocs(CarDocs): @@ -244,6 +247,16 @@ class CAR(Platforms): CarSpecs(mass=1491, wheelbase=2.6, steerRatio=13.42, tireStiffnessFactor=0.385), flags=HyundaiFlags.CAMERA_SCC | HyundaiFlags.ALT_LIMITS_2, ) + HYUNDAI_KONA_2ND_GEN = HyundaiCanFDPlatformConfig( + [HyundaiCarDocs("Hyundai Kona (without HDA II) 2024-25", car_parts=CarParts.common([CarHarness.hyundai_l]))], + CarSpecs(mass=1590, wheelbase=2.66, steerRatio=13.6, tireStiffnessFactor=0.385), + flags=HyundaiFlags.CCNC, + ) + HYUNDAI_KONA_HEV_2ND_GEN = HyundaiCanFDPlatformConfig( + [HyundaiCarDocs("Hyundai Kona Hybrid (without HDA II) 2024", car_parts=CarParts.common([CarHarness.hyundai_l]))], + CarSpecs(mass=1590, wheelbase=2.66, steerRatio=13.6, tireStiffnessFactor=0.385), + flags=HyundaiFlags.CCNC, + ) HYUNDAI_KONA_EV = HyundaiPlatformConfig( [HyundaiCarDocs("Hyundai Kona Electric 2018-21", car_parts=CarParts.common([CarHarness.hyundai_g]))], CarSpecs(mass=1685, wheelbase=2.6, steerRatio=13.42, tireStiffnessFactor=0.385), @@ -255,10 +268,13 @@ class CAR(Platforms): flags=HyundaiFlags.CAMERA_SCC | HyundaiFlags.EV | HyundaiFlags.ALT_LIMITS, ) HYUNDAI_KONA_EV_2ND_GEN = HyundaiCanFDPlatformConfig( - [HyundaiCarDocs("Hyundai Kona Electric (with HDA II, Korea only) 2023", video="https://www.youtube.com/watch?v=U2fOCmcQ8hw", - car_parts=CarParts.common([CarHarness.hyundai_r]))], + [ + HyundaiCarDocs("Hyundai Kona Electric (with HDA II, Korea only) 2023", video="https://www.youtube.com/watch?v=U2fOCmcQ8hw", + car_parts=CarParts.common([CarHarness.hyundai_r])), + HyundaiCarDocs("Hyundai Kona Electric (without HDA II) 2024", car_parts=CarParts.common([CarHarness.hyundai_a])), + ], CarSpecs(mass=1740, wheelbase=2.66, steerRatio=13.6, tireStiffnessFactor=0.385), - flags=HyundaiFlags.EV | HyundaiFlags.CANFD_NO_RADAR_DISABLE, + flags=HyundaiFlags.EV | HyundaiFlags.CANFD_NO_RADAR_DISABLE | HyundaiFlags.CCNC, ) HYUNDAI_KONA_HEV = HyundaiPlatformConfig( [HyundaiCarDocs("Hyundai Kona Hybrid 2020", car_parts=CarParts.common([CarHarness.hyundai_i]))], # TODO: check packages, @@ -298,6 +314,11 @@ class CAR(Platforms): CarSpecs(mass=1513, wheelbase=2.84, steerRatio=13.27 * 1.15, tireStiffnessFactor=0.65), # 15% higher at the center seems reasonable flags=HyundaiFlags.MANDO_RADAR | HyundaiFlags.CHECKSUM_CRC8, ) + HYUNDAI_SONATA_2024 = HyundaiCanFDPlatformConfig( + [HyundaiCarDocs("Hyundai Sonata (without HDA II) 2024-25", car_parts=CarParts.common([CarHarness.hyundai_a]))], + CarSpecs(mass=1556, wheelbase=2.84, steerRatio=12.81), + flags=HyundaiFlags.CCNC, + ) HYUNDAI_SONATA_LF = HyundaiPlatformConfig( [HyundaiCarDocs("Hyundai Sonata 2018-19", car_parts=CarParts.common([CarHarness.hyundai_e]))], CarSpecs(mass=1536, wheelbase=2.804, steerRatio=13.27 * 1.15), # 15% higher at the center seems reasonable @@ -333,6 +354,11 @@ class CAR(Platforms): HYUNDAI_SONATA.specs, flags=HyundaiFlags.MANDO_RADAR | HyundaiFlags.CHECKSUM_CRC8 | HyundaiFlags.HYBRID, ) + HYUNDAI_SONATA_HEV_2024 = HyundaiCanFDPlatformConfig( + [HyundaiCarDocs("Hyundai Sonata Hybrid (without HDA II) 2024-25", car_parts=CarParts.common([CarHarness.hyundai_a]))], + CarSpecs(mass=1616, wheelbase=2.84, steerRatio=13.27), + flags=HyundaiFlags.CCNC, + ) HYUNDAI_IONIQ_5 = HyundaiCanFDPlatformConfig( [ HyundaiCarDocs("Hyundai Ioniq 5 (Southeast Asia and Europe only) 2022-24", "All", car_parts=CarParts.common([CarHarness.hyundai_q])), @@ -356,11 +382,21 @@ class CAR(Platforms): ], CarSpecs(mass=1630, wheelbase=2.756, steerRatio=13.7, tireStiffnessFactor=0.385), ) + HYUNDAI_TUCSON_HEV_2025 = HyundaiCanFDPlatformConfig( + [HyundaiCarDocs("Hyundai Tucson Hybrid (without HDA II) 2025", car_parts=CarParts.common([CarHarness.hyundai_n]))], + CarSpecs(mass=1630, wheelbase=2.756, steerRatio=13.7, tireStiffnessFactor=0.385), + flags=HyundaiFlags.CCNC, + ) HYUNDAI_SANTA_CRUZ_1ST_GEN = HyundaiCanFDPlatformConfig( [HyundaiCarDocs("Hyundai Santa Cruz 2022-24", car_parts=CarParts.common([CarHarness.hyundai_n]))], # weight from Limited trim - the only supported trim, steering ratio according to Hyundai News https://www.hyundainews.com/assets/documents/original/48035-2022SantaCruzProductGuideSpecsv2081521.pdf CarSpecs(mass=1870, wheelbase=3, steerRatio=14.2), ) + HYUNDAI_SANTA_CRUZ_2025 = HyundaiCanFDPlatformConfig( + [HyundaiCarDocs("Hyundai Santa Cruz (without HDA II) 2025", car_parts=CarParts.common([CarHarness.hyundai_n]))], + CarSpecs(mass=1920, wheelbase=3, steerRatio=14.2), + flags=HyundaiFlags.CCNC, + ) HYUNDAI_CUSTIN_1ST_GEN = HyundaiPlatformConfig( [HyundaiCarDocs("Hyundai Custin 2023", "All", car_parts=CarParts.common([CarHarness.hyundai_k]))], CarSpecs(mass=1690, wheelbase=3.055, steerRatio=17), # mass: from https://www.hyundai-motor.com.tw/clicktobuy/custin#spec_0, steerRatio: from learner @@ -375,11 +411,21 @@ class CAR(Platforms): ], CarSpecs(mass=2878 * CV.LB_TO_KG, wheelbase=2.8, steerRatio=13.75, tireStiffnessFactor=0.5) ) + KIA_K4_2025 = HyundaiCanFDPlatformConfig( + [HyundaiCarDocs("Kia K4 (without HDA II) 2025", car_parts=CarParts.common([CarHarness.hyundai_a]))], + CarSpecs(mass=2987 * CV.LB_TO_KG, wheelbase=2.72, steerRatio=13.4), + flags=HyundaiFlags.CCNC, + ) KIA_K5_2021 = HyundaiPlatformConfig( [HyundaiCarDocs("Kia K5 2021-24", car_parts=CarParts.common([CarHarness.hyundai_a]))], CarSpecs(mass=3381 * CV.LB_TO_KG, wheelbase=2.85, steerRatio=13.27, tireStiffnessFactor=0.5), # 2021 Kia K5 Steering Ratio (all trims) flags=HyundaiFlags.CHECKSUM_CRC8, ) + KIA_K5_2025 = HyundaiCanFDPlatformConfig( + [HyundaiCarDocs("Kia K5 (without HDA II) 2025", car_parts=CarParts.common([CarHarness.hyundai_m]))], + CarSpecs(mass=3230 * CV.LB_TO_KG, wheelbase=2.85, steerRatio=13.27), + flags=HyundaiFlags.CCNC, + ) KIA_K5_HEV_2020 = HyundaiPlatformConfig( [HyundaiCarDocs("Kia K5 Hybrid 2020-22", car_parts=CarParts.common([CarHarness.hyundai_a]))], KIA_K5_2021.specs, @@ -486,6 +532,11 @@ class CAR(Platforms): CarSpecs(mass=3957 * CV.LB_TO_KG, wheelbase=2.81, steerRatio=13.5), # average of the platforms flags=HyundaiFlags.RADAR_SCC, ) + KIA_SORENTO_2024 = HyundaiCanFDPlatformConfig( + [HyundaiCarDocs("Kia Sorento (without HDA II) 2024-25", car_parts=CarParts.common([CarHarness.hyundai_a]))], + CarSpecs(mass=3957 * CV.LB_TO_KG, wheelbase=2.81, steerRatio=13.5), + flags=HyundaiFlags.CCNC, + ) KIA_SORENTO_HEV_4TH_GEN = HyundaiCanFDPlatformConfig( [ HyundaiCarDocs("Kia Sorento Hybrid 2021-23", "All", car_parts=CarParts.common([CarHarness.hyundai_a])), diff --git a/opendbc/car/tests/routes.py b/opendbc/car/tests/routes.py index 29df4d3e9e0..95e871b77d4 100644 --- a/opendbc/car/tests/routes.py +++ b/opendbc/car/tests/routes.py @@ -30,7 +30,8 @@ HONDA.ACURA_TLX_2G, HONDA.HONDA_NBOX_2G, HONDA.ACURA_MDX_4G_MMR, - HONDA.HONDA_CITY_7G + HONDA.HONDA_CITY_7G, + HYUNDAI.KIA_SORENTO_2024, ] @@ -133,6 +134,7 @@ class CarTestRoute(NamedTuple): CarTestRoute("66eaa6c3b6b2afc6/00000009--3a5199aabe", HYUNDAI.GENESIS_G80_2ND_GEN_FL), # LKA steering CarTestRoute("0bbe367c98fa1538/2023-09-16--00-16-49", HYUNDAI.HYUNDAI_CUSTIN_1ST_GEN), CarTestRoute("f0709d2bc6ca451f/2022-10-15--08-13-54", HYUNDAI.HYUNDAI_SANTA_CRUZ_1ST_GEN), + CarTestRoute("6e7904b03a4aafc2/00000010--31034184b6", HYUNDAI.HYUNDAI_SANTA_CRUZ_2025), CarTestRoute("4dbd55df87507948/2022-03-01--09-45-38", HYUNDAI.HYUNDAI_SANTA_FE), CarTestRoute("bf43d9df2b660eb0/2021-09-23--14-16-37", HYUNDAI.HYUNDAI_SANTA_FE_2022), CarTestRoute("37398f32561a23ad/2021-11-18--00-11-35", HYUNDAI.HYUNDAI_SANTA_FE_HEV_2022), @@ -146,11 +148,13 @@ class CarTestRoute(NamedTuple): CarTestRoute("6a42c1197b2a8179/2023-09-21--10-23-44", HYUNDAI.KIA_OPTIMA_H_G4_FL), CarTestRoute("c75a59efa0ecd502/2021-03-11--20-52-55", HYUNDAI.KIA_SELTOS), CarTestRoute("5b7c365c50084530/2020-04-15--16-13-24", HYUNDAI.HYUNDAI_SONATA), + CarTestRoute("4267ea8a353cdb36/00000262--8a427003c7", HYUNDAI.HYUNDAI_SONATA_2024, segment=34), CarTestRoute("b2a38c712dcf90bd/2020-05-18--18-12-48", HYUNDAI.HYUNDAI_SONATA_LF), CarTestRoute("c344fd2492c7a9d2/2023-12-11--09-03-23", HYUNDAI.HYUNDAI_STARIA_4TH_GEN), CarTestRoute("fb3fd42f0baaa2f8/2022-03-30--15-25-05", HYUNDAI.HYUNDAI_TUCSON), CarTestRoute("db68bbe12250812c/2022-12-05--00-54-12", HYUNDAI.HYUNDAI_TUCSON_4TH_GEN), # 2023 CarTestRoute("36e10531feea61a4/2022-07-25--13-37-42", HYUNDAI.HYUNDAI_TUCSON_4TH_GEN), # hybrid + CarTestRoute("22f9090014364a87/00000002--4cc739c0b2", HYUNDAI.HYUNDAI_TUCSON_HEV_2025), CarTestRoute("5875672fc1d4bf57/2020-07-23--21-33-28", HYUNDAI.KIA_SORENTO), CarTestRoute("1d0d000db3370fd0/2023-01-04--22-28-42", HYUNDAI.KIA_SORENTO_4TH_GEN, segment=5), CarTestRoute("fc19648042eb6896/2023-08-16--11-43-27", HYUNDAI.KIA_SORENTO_HEV_4TH_GEN, segment=14), @@ -168,6 +172,8 @@ class CarTestRoute(NamedTuple): CarTestRoute("ab59fe909f626921/2021-10-18--18-34-28", HYUNDAI.HYUNDAI_IONIQ_HEV_2022), CarTestRoute("22d955b2cd499c22/2020-08-10--19-58-21", HYUNDAI.HYUNDAI_KONA), CarTestRoute("0099bdb24d82951b/00000005--c38d940b04", HYUNDAI.HYUNDAI_KONA_2022), + CarTestRoute("32025f26789d8fab/00000022--a499e8ffa3", HYUNDAI.HYUNDAI_KONA_2ND_GEN), + CarTestRoute("97ca61196eb73e0d/00000052--4555329470", HYUNDAI.HYUNDAI_KONA_HEV_2ND_GEN), CarTestRoute("efc48acf44b1e64d/2021-05-28--21-05-04", HYUNDAI.HYUNDAI_KONA_EV), CarTestRoute("f90d3cd06caeb6fa/2023-09-06--17-15-47", HYUNDAI.HYUNDAI_KONA_EV), # openpilot longitudinal enabled CarTestRoute("ff973b941a69366f/2022-07-28--22-01-19", HYUNDAI.HYUNDAI_KONA_EV_2022, segment=11), @@ -181,7 +187,9 @@ class CarTestRoute(NamedTuple): CarTestRoute("d545129f3ca90f28/2022-10-19--09-22-54", HYUNDAI.KIA_EV6), # LKA steering CarTestRoute("68d6a96e703c00c9/2022-09-10--16-09-39", HYUNDAI.KIA_EV6), # LFA steering CarTestRoute("9b25e8c1484a1b67/2023-04-13--10-41-45", HYUNDAI.KIA_EV6), + CarTestRoute("baf39eeaba1217ca/00000002--b36e3fa031", HYUNDAI.KIA_K4_2025), CarTestRoute("007d5e4ad9f86d13/2021-09-30--15-09-23", HYUNDAI.KIA_K5_2021), + CarTestRoute("c4a804b067623789/0000007c--163f831540", HYUNDAI.KIA_K5_2025), CarTestRoute("c58dfc9fc16590e0/2023-01-14--13-51-48", HYUNDAI.KIA_K5_HEV_2020), CarTestRoute("78ad5150de133637/2023-09-13--16-15-57", HYUNDAI.KIA_K8_HEV_1ST_GEN), CarTestRoute("50c6c9b85fd1ff03/2020-10-26--17-56-06", HYUNDAI.KIA_NIRO_EV), @@ -199,6 +207,7 @@ class CarTestRoute(NamedTuple): CarTestRoute("82e9cdd3f43bf83e/2021-05-15--02-42-51", HYUNDAI.HYUNDAI_ELANTRA_2021), CarTestRoute("715ac05b594e9c59/2021-06-20--16-21-07", HYUNDAI.HYUNDAI_ELANTRA_HEV_2021), CarTestRoute("7120aa90bbc3add7/2021-08-02--07-12-31", HYUNDAI.HYUNDAI_SONATA_HYBRID), + CarTestRoute("bc40c72b728178f2/00000006--ee76ae8c42", HYUNDAI.HYUNDAI_SONATA_HEV_2024), CarTestRoute("715ac05b594e9c59/2021-10-27--23-24-56", HYUNDAI.GENESIS_G70_2020), CarTestRoute("6b0d44d22df18134/2023-05-06--10-36-55", HYUNDAI.GENESIS_GV80), diff --git a/opendbc/car/torque_data/override.toml b/opendbc/car/torque_data/override.toml index 69cc6048d66..e7c5f765a7f 100644 --- a/opendbc/car/torque_data/override.toml +++ b/opendbc/car/torque_data/override.toml @@ -92,6 +92,12 @@ legend = ["LAT_ACCEL_FACTOR", "MAX_LAT_ACCEL_MEASURED", "FRICTION"] "HONDA_NBOX_2G" = [1.2, 1.2, 0.2] "ACURA_TLX_2G" = [1.2, 1.2, 0.15] "PORSCHE_MACAN_MK1" = [2.0, 2.0, 0.2] +"HYUNDAI_KONA_2ND_GEN" = [2.5, 2.5, 0.1] +"HYUNDAI_KONA_HEV_2ND_GEN" = [2.5, 2.5, 0.1] +"KIA_SORENTO_2024" = [2.5, 2.5, 0.1] +"KIA_K5_2025" = [2.5, 2.5, 0.1] +"KIA_K4_2025" = [2.5, 2.5, 0.1] +"HYUNDAI_SANTA_CRUZ_2025" = [2.5, 2.5, 0.1] # Dashcam or fallback configured as ideal car "MOCK" = [10.0, 10, 0.0] diff --git a/opendbc/car/torque_data/substitute.toml b/opendbc/car/torque_data/substitute.toml index db26c1a01da..18b1c3bad1b 100644 --- a/opendbc/car/torque_data/substitute.toml +++ b/opendbc/car/torque_data/substitute.toml @@ -46,6 +46,9 @@ legend = ["LAT_ACCEL_FACTOR", "MAX_LAT_ACCEL_MEASURED", "FRICTION"] "GENESIS_G90" = "GENESIS_G70" "GENESIS_G80" = "GENESIS_G70" "GENESIS_G70_2020" = "HYUNDAI_SONATA" +"HYUNDAI_SONATA_2024" = "HYUNDAI_SONATA" +"HYUNDAI_SONATA_HEV_2024" = "HYUNDAI_SONATA_HYBRID" +"HYUNDAI_TUCSON_HEV_2025" = "HYUNDAI_TUCSON_4TH_GEN" "HONDA_FREED" = "HONDA_ODYSSEY" "HONDA_CRV_EU" = "HONDA_CRV" diff --git a/opendbc/safety/modes/hyundai_canfd.h b/opendbc/safety/modes/hyundai_canfd.h index f25e267707b..1e9429f8aa6 100644 --- a/opendbc/safety/modes/hyundai_canfd.h +++ b/opendbc/safety/modes/hyundai_canfd.h @@ -47,6 +47,11 @@ static bool hyundai_canfd_alt_buttons = false; static bool hyundai_canfd_lka_steering_alt = false; +static bool hyundai_ccnc = false; + +static bool get_hyundai_ccnc(void) { + return hyundai_ccnc; +} static unsigned int hyundai_canfd_get_lka_addr(void) { return hyundai_canfd_lka_steering_alt ? 0x110U : 0x50U; @@ -218,6 +223,7 @@ static bool hyundai_canfd_tx_hook(const CANPacket_t *msg) { static safety_config hyundai_canfd_init(uint16_t param) { const int HYUNDAI_PARAM_CANFD_LKA_STEERING_ALT = 128; const int HYUNDAI_PARAM_CANFD_ALT_BUTTONS = 32; + const int HYUNDAI_PARAM_CCNC = 1024; static const CanMsg HYUNDAI_CANFD_LKA_STEERING_TX_MSGS[] = { HYUNDAI_CANFD_LKA_STEERING_COMMON_TX_MSGS(0, 1) @@ -262,11 +268,21 @@ static safety_config hyundai_canfd_init(uint16_t param) { HYUNDAI_CANFD_SCC_CONTROL_COMMON_TX_MSGS(0, (longitudinal)) \ {0x160, 0, 16, .check_relay = (longitudinal)}, /* ADRV_0x160 */ \ +#define HYUNDAI_CANFD_LFA_STEERING_CAMERA_SCC_CCNC_TX_MSGS(longitudinal) \ + HYUNDAI_CANFD_CRUISE_BUTTON_TX_MSGS(2) \ + HYUNDAI_CANFD_LFA_STEERING_COMMON_TX_MSGS(0) \ + HYUNDAI_CANFD_SCC_CONTROL_COMMON_TX_MSGS(0, (longitudinal)) \ + {0x161, 0, 32, .check_relay = true}, /* CCNC_0x161 */ \ + {0x162, 0, 32, .check_relay = true}, /* CCNC_0x162 */ \ + {0x7C4, 2, 8, .check_relay = true}, /* 0x7C4 */ \ + {0xEA, 2, 24, .check_relay = true}, /* MDPS */ \ + hyundai_common_init(param); gen_crc_lookup_table_16(0x1021, hyundai_canfd_crc_lut); hyundai_canfd_alt_buttons = GET_FLAG(param, HYUNDAI_PARAM_CANFD_ALT_BUTTONS); hyundai_canfd_lka_steering_alt = GET_FLAG(param, HYUNDAI_PARAM_CANFD_LKA_STEERING_ALT); + hyundai_ccnc = GET_FLAG(param, HYUNDAI_PARAM_CCNC); safety_config ret; if (hyundai_longitudinal) { @@ -291,6 +307,10 @@ static safety_config hyundai_canfd_init(uint16_t param) { HYUNDAI_CANFD_LFA_STEERING_CAMERA_SCC_TX_MSGS(true) }; + static CanMsg hyundai_canfd_lfa_steering_camera_scc_ccnc_tx_msgs[] = { + HYUNDAI_CANFD_LFA_STEERING_CAMERA_SCC_CCNC_TX_MSGS(true) + }; + if (hyundai_canfd_alt_buttons) { SET_RX_CHECKS(hyundai_canfd_alt_buttons_long_rx_checks, ret); } else { @@ -298,7 +318,11 @@ static safety_config hyundai_canfd_init(uint16_t param) { } if (hyundai_camera_scc) { - SET_TX_MSGS(hyundai_canfd_lfa_steering_camera_scc_tx_msgs, ret); + if (get_hyundai_ccnc()) { + SET_TX_MSGS(hyundai_canfd_lfa_steering_camera_scc_ccnc_tx_msgs, ret); + } else { + SET_TX_MSGS(hyundai_canfd_lfa_steering_camera_scc_tx_msgs, ret); + } } else { SET_TX_MSGS(HYUNDAI_CANFD_LFA_STEERING_LONG_TX_MSGS, ret); } @@ -359,7 +383,15 @@ static safety_config hyundai_canfd_init(uint16_t param) { HYUNDAI_CANFD_LFA_STEERING_CAMERA_SCC_TX_MSGS(false) }; - SET_TX_MSGS(hyundai_canfd_lfa_steering_camera_scc_tx_msgs, ret); + static CanMsg hyundai_canfd_lfa_steering_camera_scc_ccnc_tx_msgs[] = { + HYUNDAI_CANFD_LFA_STEERING_CAMERA_SCC_CCNC_TX_MSGS(false) + }; + + if (get_hyundai_ccnc()) { + SET_TX_MSGS(hyundai_canfd_lfa_steering_camera_scc_ccnc_tx_msgs, ret); + } else { + SET_TX_MSGS(hyundai_canfd_lfa_steering_camera_scc_tx_msgs, ret); + } if (hyundai_canfd_alt_buttons) { SET_RX_CHECKS(hyundai_canfd_alt_buttons_rx_checks, ret); diff --git a/opendbc/safety/tests/test_hyundai_canfd.py b/opendbc/safety/tests/test_hyundai_canfd.py index dd992f33799..b12decc5495 100755 --- a/opendbc/safety/tests/test_hyundai_canfd.py +++ b/opendbc/safety/tests/test_hyundai_canfd.py @@ -21,6 +21,13 @@ {"GAS_MSG": ("ACCELERATOR_ALT", "ACCELERATOR_PEDAL"), "SCC_BUS": 2, "SAFETY_PARAM": HyundaiSafetyFlags.HYBRID_GAS | HyundaiSafetyFlags.CAMERA_SCC}, ] +ALL_GAS_EV_HYBRID_COMBOS_CCNC = [ + # Camera SCC + {"GAS_MSG": ("ACCELERATOR_BRAKE_ALT", "ACCELERATOR_PEDAL_PRESSED"), "SCC_BUS": 2, "SAFETY_PARAM": HyundaiSafetyFlags.CAMERA_SCC}, + {"GAS_MSG": ("ACCELERATOR", "ACCELERATOR_PEDAL"), "SCC_BUS": 2, "SAFETY_PARAM": HyundaiSafetyFlags.EV_GAS | HyundaiSafetyFlags.CAMERA_SCC}, + {"GAS_MSG": ("ACCELERATOR_ALT", "ACCELERATOR_PEDAL"), "SCC_BUS": 2, "SAFETY_PARAM": HyundaiSafetyFlags.HYBRID_GAS | HyundaiSafetyFlags.CAMERA_SCC}, +] + class TestHyundaiCanfdBase(HyundaiButtonBase, common.CarSafetyTest, common.DriverTorqueSteeringSafetyTest, common.SteerRequestCutSafetyTest): @@ -284,5 +291,73 @@ def test_acc_cancel(self): pass +@parameterized_class(ALL_GAS_EV_HYBRID_COMBOS_CCNC) +class TestHyundaiCanfdLFASteeringCCNC(TestHyundaiCanfdLFASteeringBase): + + TX_MSGS = [[0x12A, 0], [0x1E0, 0], [0x1CF, 2], [0x7C4, 2]] + RELAY_MALFUNCTION_ADDRS = {0: (0x12A, 0x1E0, 0x161, 0x162), 2: (0x7C4, 0xEA)} + FWD_BLACKLISTED_ADDRS = {2: [0x12A, 0x1E0, 0x161, 0x162], 0: [0x7C4, 0xEA]} + + @classmethod + def setUpClass(cls): + if cls.__name__ == "TestHyundaiCanfdLFASteeringCCNC": + cls.safety = None + raise unittest.SkipTest + + def setUp(self): + self.packer = CANPackerSafety("hyundai_canfd_generated") + self.safety = libsafety_py.libsafety + self.safety.set_safety_hooks(CarParams.SafetyModel.hyundaiCanfd, HyundaiSafetyFlags.CCNC | self.SAFETY_PARAM) + self.safety.init_tests() + + def test_ccnc(self): + self.assertTrue(self._tx(self.packer.make_can_msg_safety("CCNC_0x161", self.STEER_BUS, {}))) + self.assertTrue(self._tx(self.packer.make_can_msg_safety("CCNC_0x162", self.STEER_BUS, {}))) + + def test_tx_hook_on_wrong_safety_mode(self): + from opendbc.safety.tests.common import make_msg + import importlib + for test_name in ["TestElm327"]: + mod = importlib.import_module("opendbc.safety.tests.test_" + test_name.replace("Test", "").lower()) + tx_list = [m for m in getattr(mod, test_name).TX_MSGS if m[0] != 0x7C4] # skip overlapping 0x7C4 from Elm327 + for addr, bus in tx_list: + if [addr, bus] not in self.TX_MSGS: + self.assertFalse(self._tx(make_msg(bus, addr)), f"allowed TX {addr=:#x} {bus=}") + + +@parameterized_class(ALL_GAS_EV_HYBRID_COMBOS_CCNC) +class TestHyundaiCanfdLFASteeringLongCCNC(TestHyundaiCanfdLFASteeringLongBase): + + TX_MSGS = [[0x12A, 0], [0x1E0, 0], [0x1CF, 2], [0x7C4, 2], [0x1A0, 0]] + RELAY_MALFUNCTION_ADDRS = {0: (0x12A, 0x1E0, 0x161, 0x162, 0x1A0), 2: (0x7C4, 0xEA)} + FWD_BLACKLISTED_ADDRS = {2: [0x12A, 0x1E0, 0x161, 0x162, 0x1A0], 0: [0x7C4, 0xEA]} + + @classmethod + def setUpClass(cls): + if cls.__name__ == "TestHyundaiCanfdLFASteeringLongCCNC": + cls.safety = None + raise unittest.SkipTest + + def setUp(self): + self.packer = CANPackerSafety("hyundai_canfd_generated") + self.safety = libsafety_py.libsafety + self.safety.set_safety_hooks(CarParams.SafetyModel.hyundaiCanfd, HyundaiSafetyFlags.CCNC | HyundaiSafetyFlags.LONG | self.SAFETY_PARAM) + self.safety.init_tests() + + def test_ccnc(self): + self.assertTrue(self._tx(self.packer.make_can_msg_safety("CCNC_0x161", self.STEER_BUS, {}))) + self.assertTrue(self._tx(self.packer.make_can_msg_safety("CCNC_0x162", self.STEER_BUS, {}))) + + def test_tx_hook_on_wrong_safety_mode(self): + from opendbc.safety.tests.common import make_msg + import importlib + for test_name in ["TestElm327"]: + mod = importlib.import_module("opendbc.safety.tests.test_" + test_name.replace("Test", "").lower()) + tx_list = [m for m in getattr(mod, test_name).TX_MSGS if m[0] != 0x7C4] # skip overlapping 0x7C4 from Elm327 + for addr, bus in tx_list: + if [addr, bus] not in self.TX_MSGS: + self.assertFalse(self._tx(make_msg(bus, addr)), f"allowed TX {addr=:#x} {bus=}") + + if __name__ == "__main__": unittest.main()