From 688e0c3fc0bc0e036759db8b446b4096040d63ce Mon Sep 17 00:00:00 2001 From: firestar5683 <168790843+firestar5683@users.noreply.github.com> Date: Mon, 20 Apr 2026 00:33:13 -0500 Subject: [PATCH] Kia Forte non-acc Port --- opendbc_repo/opendbc/car/hyundai/carstate.py | 14 +++++++++++++- opendbc_repo/opendbc/car/hyundai/interface.py | 8 ++++++++ .../opendbc/car/hyundai/tests/test_hyundai.py | 12 ++++++++++++ opendbc_repo/opendbc/car/hyundai/values.py | 5 +++++ 4 files changed, 38 insertions(+), 1 deletion(-) diff --git a/opendbc_repo/opendbc/car/hyundai/carstate.py b/opendbc_repo/opendbc/car/hyundai/carstate.py index 2bff9b3b1..1c50199c2 100644 --- a/opendbc_repo/opendbc/car/hyundai/carstate.py +++ b/opendbc_repo/opendbc/car/hyundai/carstate.py @@ -130,12 +130,24 @@ class CarState(CarStateBase): ret.steerFaultTemporary = cp.vl["MDPS12"]["CF_Mdps_ToiUnavail"] != 0 or cp.vl["MDPS12"]["CF_Mdps_ToiFlt"] != 0 # cruise state + no_scc = bool(self.CP.flags & HyundaiFlags.NON_SCC) if self.CP.openpilotLongitudinalControl: # These are not used for engage/disengage since openpilot keeps track of state using the buttons ret.cruiseState.available = cp.vl["TCS13"]["ACCEnable"] == 0 ret.cruiseState.enabled = cp.vl["TCS13"]["ACC_REQ"] == 1 ret.cruiseState.standstill = False ret.cruiseState.nonAdaptive = False + elif no_scc: + cruise_enabled = cp.vl["TCS13"]["ACC_REQ"] == 1 + cruise_set_speed = cp.vl["LVR12"]["CF_Lvr_CruiseSet"] + + # Regular-cruise Forte trims don't publish SCC11/SCC12; use the stock cruise request and set speed. + ret.cruiseState.available = cruise_enabled or cp.vl["TCS13"]["ACCEnable"] == 0 + ret.cruiseState.enabled = cruise_enabled + ret.cruiseState.standstill = False + ret.cruiseState.nonAdaptive = False + if 0 < cruise_set_speed < 255: + ret.cruiseState.speed = cruise_set_speed * speed_conv else: ret.cruiseState.available = cp_cruise.vl["SCC11"]["MainMode_ACC"] == 1 ret.cruiseState.enabled = cp_cruise.vl["SCC12"]["ACCMode"] != 0 @@ -150,7 +162,7 @@ class CarState(CarStateBase): ret.parkingBrake = cp.vl["TCS13"]["PBRAKE_ACT"] == 1 ret.espDisabled = cp.vl["TCS11"]["TCS_PAS"] == 1 ret.espActive = cp.vl["TCS11"]["ABS_ACT"] == 1 - ret.accFaulted = cp.vl["TCS13"]["ACCEnable"] != 0 # 0 ACC CONTROL ENABLED, 1-3 ACC CONTROL DISABLED + ret.accFaulted = False if no_scc else cp.vl["TCS13"]["ACCEnable"] != 0 # 0 ACC CONTROL ENABLED, 1-3 ACC CONTROL DISABLED if self.CP.flags & (HyundaiFlags.HYBRID | HyundaiFlags.EV | HyundaiFlags.FCEV): if self.CP.flags & HyundaiFlags.FCEV: diff --git a/opendbc_repo/opendbc/car/hyundai/interface.py b/opendbc_repo/opendbc/car/hyundai/interface.py index 63e95ded7..d1e38df07 100644 --- a/opendbc_repo/opendbc/car/hyundai/interface.py +++ b/opendbc_repo/opendbc/car/hyundai/interface.py @@ -111,6 +111,12 @@ class CarInterface(CarInterfaceBase): if 0x391 in fingerprint[0]: ret.flags |= HyundaiFlags.HAS_LDA_BUTTON.value + if candidate == CAR.KIA_FORTE: + has_scc_fw = any(fw.ecu == Ecu.fwdRadar for fw in car_fw) + has_scc_can = any(addr in fingerprint[bus] for bus in (0, 2) for addr in (0x420, 0x421)) + if not (has_scc_fw or has_scc_can): + ret.flags |= HyundaiFlags.NON_SCC.value + # Common lateral control setup ret.centerToFront = ret.wheelbase * 0.4 @@ -130,6 +136,8 @@ class CarInterface(CarInterfaceBase): # Common longitudinal control setup ret.radarUnavailable = RADAR_START_ADDR not in fingerprint[1] or Bus.radar not in DBC[ret.carFingerprint] + if ret.flags & HyundaiFlags.NON_SCC: + ret.alphaLongitudinalAvailable = False ret.openpilotLongitudinalControl = alpha_long and ret.alphaLongitudinalAvailable ret.pcmCruise = not ret.openpilotLongitudinalControl ret.startingState = True diff --git a/opendbc_repo/opendbc/car/hyundai/tests/test_hyundai.py b/opendbc_repo/opendbc/car/hyundai/tests/test_hyundai.py index b798acaa1..1a9e5bfa6 100644 --- a/opendbc_repo/opendbc/car/hyundai/tests/test_hyundai.py +++ b/opendbc_repo/opendbc/car/hyundai/tests/test_hyundai.py @@ -62,6 +62,18 @@ class TestHyundaiFingerprint: CP = CarInterface.get_params(CAR.HYUNDAI_SONATA, fingerprint, [], False, False, False) assert CP.radarUnavailable != radar + forte_no_scc = CarInterface.get_params(CAR.KIA_FORTE, gen_empty_fingerprint(), [], True, False, False) + assert bool(forte_no_scc.flags & HyundaiFlags.NON_SCC) + assert not forte_no_scc.alphaLongitudinalAvailable + assert forte_no_scc.pcmCruise + + forte_with_scc = gen_empty_fingerprint() + forte_with_scc[0][0x420] = 8 + forte_with_scc[0][0x421] = 8 + CP = CarInterface.get_params(CAR.KIA_FORTE, forte_with_scc, [], True, False, False) + assert not bool(CP.flags & HyundaiFlags.NON_SCC) + assert CP.alphaLongitudinalAvailable + def test_alternate_limits(self): # Alternate lateral control limits, for high torque cars, verify Panda safety mode flag is set fingerprint = gen_empty_fingerprint() diff --git a/opendbc_repo/opendbc/car/hyundai/values.py b/opendbc_repo/opendbc/car/hyundai/values.py index dab54b2b1..09dcb28e5 100644 --- a/opendbc_repo/opendbc/car/hyundai/values.py +++ b/opendbc_repo/opendbc/car/hyundai/values.py @@ -135,6 +135,9 @@ class HyundaiFlags(IntFlag): ALT_LIMITS_2 = 2 ** 26 + # No SCC radar/camera cruise module. Stock longitudinal is regular cruise control only. + NON_SCC = 2 ** 27 + @dataclass class HyundaiCarDocs(CarDocs): @@ -758,6 +761,8 @@ FW_QUERY_CONFIG = FwQueryConfig( # We lose these ECUs without the comma power on these cars. # Note that we still attempt to match with them when they are present non_essential_ecus={ + # Some Forte trims are lateral-only and omit the SCC radar entirely. + Ecu.fwdRadar: [CAR.KIA_FORTE], Ecu.abs: [CAR.HYUNDAI_PALISADE, CAR.HYUNDAI_SONATA, CAR.HYUNDAI_SANTA_FE_2022, CAR.KIA_K5_2021, CAR.HYUNDAI_ELANTRA_2021, CAR.HYUNDAI_SANTA_FE, CAR.HYUNDAI_KONA_EV_2022, CAR.HYUNDAI_KONA_EV, CAR.HYUNDAI_CUSTIN_1ST_GEN, CAR.KIA_SORENTO, CAR.KIA_CEED, CAR.KIA_SELTOS],