Skip to content

Commit

Permalink
Merge remote-tracking branch 'commaai/opendbc/master' into gv70-2022-…
Browse files Browse the repository at this point in the history
…hda2
  • Loading branch information
sunnyhaibin committed Sep 28, 2024
2 parents 097f8c5 + 4e64728 commit d15118e
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 39 deletions.
4 changes: 2 additions & 2 deletions opendbc/car/hyundai/carcontroller.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from opendbc.car.hyundai import hyundaicanfd, hyundaican
from opendbc.car.hyundai.carstate import CarState
from opendbc.car.hyundai.hyundaicanfd import CanBus
from opendbc.car.hyundai.values import HyundaiFlags, Buttons, CarControllerParams, CANFD_CAR, CAR
from opendbc.car.hyundai.values import HyundaiFlags, Buttons, CarControllerParams, CAR
from opendbc.car.interfaces import CarControllerBase

VisualAlert = structs.CarControl.HUDControl.VisualAlert
Expand Down Expand Up @@ -103,7 +103,7 @@ def update(self, CC, CS, now_nanos):
can_sends.append(make_tester_present_msg(0x7b1, self.CAN.ECAN, suppress_response=True))

# CAN-FD platforms
if self.CP.carFingerprint in CANFD_CAR:
if self.CP.flags & HyundaiFlags.CANFD:
hda2 = self.CP.flags & HyundaiFlags.CANFD_HDA2
hda2_long = hda2 and self.CP.openpilotLongitudinalControl

Expand Down
29 changes: 14 additions & 15 deletions opendbc/car/hyundai/carstate.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@
from opendbc.car import create_button_events, structs
from opendbc.car.common.conversions import Conversions as CV
from opendbc.car.hyundai.hyundaicanfd import CanBus
from opendbc.car.hyundai.values import HyundaiFlags, CAR, DBC, CAN_GEARS, CAMERA_SCC_CAR, \
CANFD_CAR, Buttons, CarControllerParams
from opendbc.car.hyundai.values import HyundaiFlags, CAR, DBC, Buttons, CarControllerParams
from opendbc.car.interfaces import CarStateBase

ButtonType = structs.CarState.ButtonEvent.Type
Expand All @@ -33,11 +32,11 @@ def __init__(self, CP):
"GEAR_ALT" if CP.flags & HyundaiFlags.CANFD_ALT_GEARS else \
"GEAR_ALT_2" if CP.flags & HyundaiFlags.CANFD_ALT_GEARS_2 else \
"GEAR_SHIFTER"
if CP.carFingerprint in CANFD_CAR:
if CP.flags & HyundaiFlags.CANFD:
self.shifter_values = can_define.dv[self.gear_msg_canfd]["GEAR"]
elif self.CP.carFingerprint in CAN_GEARS["use_cluster_gears"]:
elif self.CP.flags & HyundaiFlags.CLUSTER_GEARS:
self.shifter_values = can_define.dv["CLU15"]["CF_Clu_Gear"]
elif self.CP.carFingerprint in CAN_GEARS["use_tcu_gears"]:
elif self.CP.flags & HyundaiFlags.TCU_GEARS:
self.shifter_values = can_define.dv["TCU12"]["CUR_GR"]
else: # preferred and elect gear methods use same definition
self.shifter_values = can_define.dv["LVR12"]["CF_Lvr_Gear"]
Expand All @@ -59,11 +58,11 @@ def __init__(self, CP):
self.params = CarControllerParams(CP)

def update(self, cp, cp_cam, *_) -> structs.CarState:
if self.CP.carFingerprint in CANFD_CAR:
if self.CP.flags & HyundaiFlags.CANFD:
return self.update_canfd(cp, cp_cam)

ret = structs.CarState()
cp_cruise = cp_cam if self.CP.carFingerprint in CAMERA_SCC_CAR else cp
cp_cruise = cp_cam if self.CP.flags & HyundaiFlags.CAMERA_SCC else cp
self.is_metric = cp.vl["CLU11"]["CF_Clu_SPEED_UNIT"] == 0
speed_conv = CV.KPH_TO_MS if self.is_metric else CV.MPH_TO_MS

Expand Down Expand Up @@ -142,9 +141,9 @@ def update(self, cp, cp_cam, *_) -> structs.CarState:
# as this seems to be standard over all cars, but is not the preferred method.
if self.CP.flags & (HyundaiFlags.HYBRID | HyundaiFlags.EV):
gear = cp.vl["ELECT_GEAR"]["Elect_Gear_Shifter"]
elif self.CP.carFingerprint in CAN_GEARS["use_cluster_gears"]:
elif self.CP.flags & HyundaiFlags.CLUSTER_GEARS:
gear = cp.vl["CLU15"]["CF_Clu_Gear"]
elif self.CP.carFingerprint in CAN_GEARS["use_tcu_gears"]:
elif self.CP.flags & HyundaiFlags.TCU_GEARS:
gear = cp.vl["TCU12"]["CUR_GR"]
else:
gear = cp.vl["LVR12"]["CF_Lvr_Gear"]
Expand Down Expand Up @@ -263,7 +262,7 @@ def update_canfd(self, cp, cp_cam) -> structs.CarState:
return ret

def get_can_parser(self, CP):
if CP.carFingerprint in CANFD_CAR:
if CP.flags & HyundaiFlags.CANFD:
return self.get_can_parser_canfd(CP)

messages = [
Expand All @@ -282,7 +281,7 @@ def get_can_parser(self, CP):
("SAS11", 100),
]

if not CP.openpilotLongitudinalControl and CP.carFingerprint not in CAMERA_SCC_CAR:
if not CP.openpilotLongitudinalControl and not (CP.flags & HyundaiFlags.CAMERA_SCC):
messages += [
("SCC11", 50),
("SCC12", 50),
Expand All @@ -303,9 +302,9 @@ def get_can_parser(self, CP):

if CP.flags & (HyundaiFlags.HYBRID | HyundaiFlags.EV):
messages.append(("ELECT_GEAR", 20))
elif CP.carFingerprint in CAN_GEARS["use_cluster_gears"]:
elif CP.flags & HyundaiFlags.CLUSTER_GEARS:
pass
elif CP.carFingerprint in CAN_GEARS["use_tcu_gears"]:
elif CP.flags & HyundaiFlags.TCU_GEARS:
messages.append(("TCU12", 100))
else:
messages.append(("LVR12", 100))
Expand All @@ -314,14 +313,14 @@ def get_can_parser(self, CP):

@staticmethod
def get_cam_can_parser(CP):
if CP.carFingerprint in CANFD_CAR:
if CP.flags & HyundaiFlags.CANFD:
return CarState.get_cam_can_parser_canfd(CP)

messages = [
("LKAS11", 100)
]

if not CP.openpilotLongitudinalControl and CP.carFingerprint in CAMERA_SCC_CAR:
if not CP.openpilotLongitudinalControl and CP.flags & HyundaiFlags.CAMERA_SCC:
messages += [
("SCC11", 50),
("SCC12", 50),
Expand Down
1 change: 1 addition & 0 deletions opendbc/car/hyundai/fingerprints.py
Original file line number Diff line number Diff line change
Expand Up @@ -1075,6 +1075,7 @@
b'\xf1\x00JW1 MFC AT USA LHD 1.00 1.02 99211-CU000 211215',
b'\xf1\x00JW1 MFC AT USA LHD 1.00 1.02 99211-CU100 211215',
b'\xf1\x00JW1 MFC AT USA LHD 1.00 1.03 99211-CU000 221118',
b'\xf1\x00JW1 MFC AT AUS RHD 1.00 1.03 99211-CU100 221118',
],
(Ecu.fwdRadar, 0x7d0, None): [
b'\xf1\x00JW1_ RDR ----- 1.00 1.00 99110-CU000 ',
Expand Down
19 changes: 9 additions & 10 deletions opendbc/car/hyundai/interface.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from panda import Panda
from opendbc.car import get_safety_config, structs
from opendbc.car.hyundai.hyundaicanfd import CanBus
from opendbc.car.hyundai.values import HyundaiFlags, CAR, DBC, CANFD_CAR, CAMERA_SCC_CAR, CANFD_RADAR_SCC_CAR, \
CANFD_UNSUPPORTED_LONGITUDINAL_CAR, LEGACY_SAFETY_MODE_CAR, \
from opendbc.car.hyundai.values import HyundaiFlags, CAR, DBC, CAMERA_SCC_CAR, CANFD_RADAR_SCC_CAR, \
CANFD_UNSUPPORTED_LONGITUDINAL_CAR, \
UNSUPPORTED_LONGITUDINAL_CAR, Buttons
from opendbc.car.hyundai.radar_interface import RADAR_START_ADDR
from opendbc.car.interfaces import CarInterfaceBase
Expand All @@ -22,7 +22,7 @@ def _get_params(ret: structs.CarParams, candidate, fingerprint, car_fw, experime
hda2 = 0x50 in fingerprint[cam_can] or 0x110 in fingerprint[cam_can]
CAN = CanBus(None, fingerprint, hda2)

if candidate in CANFD_CAR:
if ret.flags & HyundaiFlags.CANFD:
# Shared configuration for CAN-FD cars
ret.experimentalLongitudinalAvailable = candidate not in (CANFD_UNSUPPORTED_LONGITUDINAL_CAR | CANFD_RADAR_SCC_CAR)
ret.enableBsm = 0x1e5 in fingerprint[CAN.ECAN]
Expand All @@ -39,7 +39,7 @@ def _get_params(ret: structs.CarParams, candidate, fingerprint, car_fw, experime
# non-HDA2
if 0x1cf not in fingerprint[CAN.ECAN]:
ret.flags |= HyundaiFlags.CANFD_ALT_BUTTONS.value
if candidate not in CANFD_RADAR_SCC_CAR:
if not ret.flags & HyundaiFlags.RADAR_SCC:
ret.flags |= HyundaiFlags.CANFD_CAMERA_SCC.value

# Some HDA2 cars have alternative messages for gear checks
Expand Down Expand Up @@ -77,13 +77,13 @@ def _get_params(ret: structs.CarParams, candidate, fingerprint, car_fw, experime
if 0x38d in fingerprint[0] or 0x38d in fingerprint[2]:
ret.flags |= HyundaiFlags.USE_FCA.value

if candidate in LEGACY_SAFETY_MODE_CAR:
if ret.flags & HyundaiFlags.LEGACY:
# these cars require a special panda safety mode due to missing counters and checksums in the messages
ret.safetyConfigs = [get_safety_config(structs.CarParams.SafetyModel.hyundaiLegacy)]
else:
ret.safetyConfigs = [get_safety_config(structs.CarParams.SafetyModel.hyundai, 0)]

if candidate in CAMERA_SCC_CAR:
if ret.flags & HyundaiFlags.CAMERA_SCC:
ret.safetyConfigs[0].safetyParam |= Panda.FLAG_HYUNDAI_CAMERA_SCC

# Common lateral control setup
Expand All @@ -93,6 +93,9 @@ def _get_params(ret: structs.CarParams, candidate, fingerprint, car_fw, experime
ret.steerLimitTimer = 0.4
CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning)

if ret.flags & HyundaiFlags.ALT_LIMITS:
ret.safetyConfigs[-1].safetyParam |= Panda.FLAG_HYUNDAI_ALT_LIMITS

# Common longitudinal control setup

ret.radarUnavailable = RADAR_START_ADDR not in fingerprint[1] or DBC[ret.carFingerprint]["radar"] is None
Expand All @@ -116,10 +119,6 @@ def _get_params(ret: structs.CarParams, candidate, fingerprint, car_fw, experime
if candidate == CAR.KIA_OPTIMA_G4_FL:
ret.steerActuatorDelay = 0.2

if candidate in (CAR.HYUNDAI_KONA, CAR.HYUNDAI_KONA_EV, CAR.HYUNDAI_KONA_HEV, CAR.HYUNDAI_KONA_EV_2022):
ret.flags |= HyundaiFlags.ALT_LIMITS.value
ret.safetyConfigs[-1].safetyParam |= Panda.FLAG_HYUNDAI_ALT_LIMITS

# Dashcam cars are missing a test route, or otherwise need validation
# TODO: Optima Hybrid 2017 uses a different SCC12 checksum
ret.dashcamOnly = candidate in {CAR.KIA_OPTIMA_H, }
Expand Down
8 changes: 8 additions & 0 deletions opendbc/car/hyundai/tests/test_hyundai.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import pytest

from panda import Panda
from opendbc.car import gen_empty_fingerprint
from opendbc.car.structs import CarParams
from opendbc.car.fw_versions import build_fw_dict
Expand Down Expand Up @@ -61,6 +62,13 @@ def test_feature_detection(self):
CP = CarInterface.get_params(CAR.HYUNDAI_SONATA, fingerprint, [], False, False)
assert CP.radarUnavailable != radar

def test_alternate_limits(self):
# Alternate lateral control limits, for high torque cars, verify Panda safety mode flag is set
fingerprint = gen_empty_fingerprint()
for car_model in CAR:
CP = CarInterface.get_params(car_model, fingerprint, [], False, False)
assert bool(CP.flags & HyundaiFlags.ALT_LIMITS) == bool(CP.safetyConfigs[-1].safetyParam & Panda.FLAG_HYUNDAI_ALT_LIMITS)

def test_can_features(self):
# Test no EV/HEV in any gear lists (should all use ELECT_GEAR)
assert set.union(*CAN_GEARS.values()) & (HYBRID_CAR | EV_CAR) == set()
Expand Down
26 changes: 14 additions & 12 deletions opendbc/car/hyundai/values.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ def __init__(self, CP):
self.STEER_THRESHOLD = 150
self.STEER_STEP = 1 # 100 Hz

if CP.carFingerprint in CANFD_CAR:
if CP.flags & HyundaiFlags.CANFD:
self.STEER_MAX = 270
self.STEER_DRIVER_ALLOWANCE = 250
self.STEER_DRIVER_MULTIPLIER = 2
Expand Down Expand Up @@ -78,6 +78,7 @@ class HyundaiFlags(IntFlag):

# The radar does SCC on these cars when HDA I, rather than the camera
RADAR_SCC = 2 ** 14
# The camera does SCC on these cars, rather than the radar
CAMERA_SCC = 2 ** 15
CHECKSUM_CRC8 = 2 ** 16
CHECKSUM_6B = 2 ** 17
Expand All @@ -88,6 +89,8 @@ class HyundaiFlags(IntFlag):
# these cars have not been verified to work with longitudinal yet - radar disable, sending correct messages, etc.
UNSUPPORTED_LONGITUDINAL = 2 ** 19

# These CAN FD cars do not accept communication control to disable the ADAS ECU,
# responds with 0x7F2822 - 'conditions not correct'
CANFD_NO_RADAR_DISABLE = 2 ** 20

CLUSTER_GEARS = 2 ** 21
Expand Down Expand Up @@ -217,17 +220,17 @@ class CAR(Platforms):
HYUNDAI_KONA = HyundaiPlatformConfig(
[HyundaiCarDocs("Hyundai Kona 2020", min_enable_speed=6 * CV.MPH_TO_MS, car_parts=CarParts.common([CarHarness.hyundai_b]))],
CarSpecs(mass=1275, wheelbase=2.6, steerRatio=13.42, tireStiffnessFactor=0.385),
flags=HyundaiFlags.CLUSTER_GEARS,
flags=HyundaiFlags.CLUSTER_GEARS | HyundaiFlags.ALT_LIMITS,
)
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),
flags=HyundaiFlags.EV,
flags=HyundaiFlags.EV | HyundaiFlags.ALT_LIMITS,
)
HYUNDAI_KONA_EV_2022 = HyundaiPlatformConfig(
[HyundaiCarDocs("Hyundai Kona Electric 2022-23", car_parts=CarParts.common([CarHarness.hyundai_o]))],
CarSpecs(mass=1743, wheelbase=2.6, steerRatio=13.42, tireStiffnessFactor=0.385),
flags=HyundaiFlags.CAMERA_SCC | HyundaiFlags.EV,
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_link="https://www.youtube.com/watch?v=U2fOCmcQ8hw",
Expand All @@ -238,7 +241,7 @@ class CAR(Platforms):
HYUNDAI_KONA_HEV = HyundaiPlatformConfig(
[HyundaiCarDocs("Hyundai Kona Hybrid 2020", car_parts=CarParts.common([CarHarness.hyundai_i]))], # TODO: check packages,
CarSpecs(mass=1425, wheelbase=2.6, steerRatio=13.42, tireStiffnessFactor=0.385),
flags=HyundaiFlags.HYBRID,
flags=HyundaiFlags.HYBRID | HyundaiFlags.ALT_LIMITS,
)
HYUNDAI_SANTA_FE = HyundaiPlatformConfig(
[HyundaiCarDocs("Hyundai Santa Fe 2019-20", "All", video_link="https://youtu.be/bjDR0YjM__s",
Expand Down Expand Up @@ -498,9 +501,9 @@ class CAR(Platforms):
GENESIS_GV60_EV_1ST_GEN = HyundaiCanFDPlatformConfig(
[
HyundaiCarDocs("Genesis GV60 (Advanced Trim) 2023", "All", car_parts=CarParts.common([CarHarness.hyundai_a])),
HyundaiCarDocs("Genesis GV60 (Performance Trim) 2023", "All", car_parts=CarParts.common([CarHarness.hyundai_k])),
HyundaiCarDocs("Genesis GV60 (Performance Trim) 2022-23", "All", car_parts=CarParts.common([CarHarness.hyundai_k])),
],
CarSpecs(mass=2205, wheelbase=2.9, steerRatio=12.6), # steerRatio: https://www.motor1.com/reviews/586376/2023-genesis-gv60-first-drive/#:~:text=Relative%20to%20the%20related%20Ioniq,5%2FEV6%27s%2014.3%3A1.
CarSpecs(mass=2205, wheelbase=2.9, steerRatio=17.6),
flags=HyundaiFlags.EV,
)
GENESIS_G70 = HyundaiPlatformConfig(
Expand Down Expand Up @@ -745,13 +748,10 @@ def match_fw_to_car_fuzzy(live_fw_versions, vin, offline_fw_versions) -> set[str
}

CANFD_CAR = CAR.with_flags(HyundaiFlags.CANFD)
CANFD_RADAR_SCC_CAR = CAR.with_flags(HyundaiFlags.RADAR_SCC)
CANFD_RADAR_SCC_CAR = CAR.with_flags(HyundaiFlags.RADAR_SCC) # TODO: merge with UNSUPPORTED_LONGITUDINAL_CAR

# These CAN FD cars do not accept communication control to disable the ADAS ECU,
# responds with 0x7F2822 - 'conditions not correct'
CANFD_UNSUPPORTED_LONGITUDINAL_CAR = CAR.with_flags(HyundaiFlags.CANFD_NO_RADAR_DISABLE)
CANFD_UNSUPPORTED_LONGITUDINAL_CAR = CAR.with_flags(HyundaiFlags.CANFD_NO_RADAR_DISABLE) # TODO: merge with UNSUPPORTED_LONGITUDINAL_CAR

# The camera does SCC on these cars, rather than the radar
CAMERA_SCC_CAR = CAR.with_flags(HyundaiFlags.CAMERA_SCC)

HYBRID_CAR = CAR.with_flags(HyundaiFlags.HYBRID)
Expand All @@ -760,6 +760,8 @@ def match_fw_to_car_fuzzy(live_fw_versions, vin, offline_fw_versions) -> set[str

LEGACY_SAFETY_MODE_CAR = CAR.with_flags(HyundaiFlags.LEGACY)

# TODO: another PR with (HyundaiFlags.LEGACY | HyundaiFlags.UNSUPPORTED_LONGITUDINAL | HyundaiFlags.CAMERA_SCC |
# HyundaiFlags.CANFD_RADAR_SCC | HyundaiFlags.CANFD_NO_RADAR_DISABLE | )
UNSUPPORTED_LONGITUDINAL_CAR = CAR.with_flags(HyundaiFlags.LEGACY) | CAR.with_flags(HyundaiFlags.UNSUPPORTED_LONGITUDINAL)

DBC = CAR.create_dbc_map()

0 comments on commit d15118e

Please sign in to comment.