diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile
index a24c524047..36bb6aa840 100644
--- a/.devcontainer/Dockerfile
+++ b/.devcontainer/Dockerfile
@@ -1,6 +1,6 @@
FROM ghcr.io/commaai/openpilot-base:latest
-RUN apt update && apt install -y vim net-tools usbutils htop ripgrep tmux wget mesa-utils xvfb libxtst6 libxv1 libglu1-mesa libegl1-mesa
+RUN apt update && apt install -y vim net-tools usbutils htop ripgrep tmux wget mesa-utils xvfb libxtst6 libxv1 libglu1-mesa libegl1-mesa gdb
RUN pip install ipython jupyter jupyterlab
RUN cd /tmp && \
diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json
index a7a63658ed..f1cfc82159 100644
--- a/.devcontainer/devcontainer.json
+++ b/.devcontainer/devcontainer.json
@@ -18,7 +18,6 @@
"--volume=${localWorkspaceFolder}/.devcontainer/.host/.Xauthority:/home/batman/.Xauthority",
"--volume=${localEnv:HOME}/.comma:/home/batman/.comma",
"--volume=/tmp/comma_download_cache:/tmp/comma_download_cache",
- "--volume=/tmp/devcontainer_scons_cache:/tmp/scons_cache",
"--shm-size=1G",
"--add-host=host.docker.internal:host-gateway", // required to use host.docker.internal on linux
"--publish=0.0.0.0:8070-8079:8070-8079" // body ZMQ services
@@ -43,5 +42,8 @@
"lharri73.dbc"
]
}
- }
+ },
+ "mounts": [
+ "type=volume,source=scons_cache,target=/tmp/scons_cache"
+ ]
}
\ No newline at end of file
diff --git a/SConstruct b/SConstruct
index dac3529892..c08fe48f66 100644
--- a/SConstruct
+++ b/SConstruct
@@ -386,7 +386,7 @@ SConscript(['third_party/SConscript'])
SConscript(['selfdrive/SConscript'])
-if arch in ['x86_64', 'aarch64', 'Darwin'] and Dir('#tools/cabana/').exists() and GetOption('extras'):
+if Dir('#tools/cabana/').exists() and GetOption('extras'):
SConscript(['tools/replay/SConscript'])
SConscript(['tools/cabana/SConscript'])
diff --git a/selfdrive/car/__init__.py b/selfdrive/car/__init__.py
index a5909f71af..27d320bb41 100644
--- a/selfdrive/car/__init__.py
+++ b/selfdrive/car/__init__.py
@@ -1,5 +1,5 @@
# functions common among cars
-from collections import namedtuple
+from collections import defaultdict, namedtuple
from dataclasses import dataclass
from enum import IntFlag, ReprEnum
from dataclasses import replace
@@ -245,17 +245,17 @@ class CanSignalRateCalculator:
return self.rate
-CarInfos = CarInfo | list[CarInfo]
+CarInfos = CarInfo | list[CarInfo] | None
@dataclass(frozen=True, kw_only=True)
class CarSpecs:
mass: float # kg, curb weight
- wheelbase: float
+ wheelbase: float # meters
steerRatio: float
centerToFrontRatio: float = 0.5
- minSteerSpeed: float = 0.0
- minEnableSpeed: float = -1.0
+ minSteerSpeed: float = 0.0 # m/s
+ minEnableSpeed: float = -1.0 # m/s
tireStiffnessFactor: float = 1.0
@@ -302,3 +302,15 @@ class Platforms(str, ReprEnum):
@classmethod
def with_flags(cls, flags: IntFlag) -> set['Platforms']:
return {p for p in cls if p.config.flags & flags}
+
+ @classmethod
+ def print_debug(cls, flags):
+ platforms_with_flag = defaultdict(list)
+ for flag in flags:
+ for platform in cls:
+ if platform.config.flags & flag:
+ assert flag.name is not None
+ platforms_with_flag[flag.name].append(platform)
+
+ for flag, platforms in platforms_with_flag.items():
+ print(f"{flag:32s}: {', '.join(p.name for p in platforms)}")
diff --git a/selfdrive/car/chrysler/values.py b/selfdrive/car/chrysler/values.py
index 8fa7664b66..d6bfd4e0cb 100644
--- a/selfdrive/car/chrysler/values.py
+++ b/selfdrive/car/chrysler/values.py
@@ -11,6 +11,7 @@ Ecu = car.CarParams.Ecu
class ChryslerFlags(IntFlag):
+ # Detected flags
HIGHER_MIN_STEERING_SPEED = 1
@dataclass
@@ -21,7 +22,7 @@ class ChryslerCarInfo(CarInfo):
@dataclass
class ChryslerPlatformConfig(PlatformConfig):
- dbc_dict: DbcDict = field(default_factory=lambda: dbc_dict('chrysler_pacifica_2017_hybrid_generated', None))
+ dbc_dict: DbcDict = field(default_factory=lambda: dbc_dict('chrysler_pacifica_2017_hybrid_generated', 'chrysler_pacifica_2017_hybrid_private_fusion'))
@dataclass(frozen=True)
diff --git a/selfdrive/car/honda/interface.py b/selfdrive/car/honda/interface.py
index a4cf647c0f..71008e5001 100755
--- a/selfdrive/car/honda/interface.py
+++ b/selfdrive/car/honda/interface.py
@@ -92,10 +92,6 @@ class CarInterface(CarInterfaceBase):
eps_modified = True
if candidate == CAR.CIVIC:
- ret.mass = 1326.
- ret.wheelbase = 2.70
- ret.centerToFront = ret.wheelbase * 0.4
- ret.steerRatio = 15.38 # 10.93 is end-to-end spec
if eps_modified:
# stock request input values: 0x0000, 0x00DE, 0x014D, 0x01EF, 0x0290, 0x0377, 0x0454, 0x0610, 0x06EE
# stock request output values: 0x0000, 0x0917, 0x0DC5, 0x1017, 0x119F, 0x140B, 0x1680, 0x1680, 0x1680
@@ -110,18 +106,10 @@ class CarInterface(CarInterfaceBase):
ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[1.1], [0.33]]
elif candidate in (CAR.CIVIC_BOSCH, CAR.CIVIC_BOSCH_DIESEL, CAR.CIVIC_2022):
- ret.mass = 1326.
- ret.wheelbase = 2.70
- ret.centerToFront = ret.wheelbase * 0.4
- ret.steerRatio = 15.38 # 10.93 is end-to-end spec
ret.lateralParams.torqueBP, ret.lateralParams.torqueV = [[0, 4096], [0, 4096]] # TODO: determine if there is a dead zone at the top end
ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.8], [0.24]]
elif candidate == CAR.ACCORD:
- ret.mass = 3279. * CV.LB_TO_KG
- ret.wheelbase = 2.83
- ret.centerToFront = ret.wheelbase * 0.39
- ret.steerRatio = 16.33 # 11.82 is spec end-to-end
ret.lateralParams.torqueBP, ret.lateralParams.torqueV = [[0, 4096], [0, 4096]] # TODO: determine if there is a dead zone at the top end
ret.tireStiffnessFactor = 0.8467
@@ -131,29 +119,17 @@ class CarInterface(CarInterfaceBase):
ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.6], [0.18]]
elif candidate == CAR.ACURA_ILX:
- ret.mass = 3095. * CV.LB_TO_KG
- ret.wheelbase = 2.67
- ret.centerToFront = ret.wheelbase * 0.37
- ret.steerRatio = 18.61 # 15.3 is spec end-to-end
ret.lateralParams.torqueBP, ret.lateralParams.torqueV = [[0, 3840], [0, 3840]] # TODO: determine if there is a dead zone at the top end
ret.tireStiffnessFactor = 0.72
ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.8], [0.24]]
elif candidate in (CAR.CRV, CAR.CRV_EU):
- ret.mass = 3572. * CV.LB_TO_KG
- ret.wheelbase = 2.62
- ret.centerToFront = ret.wheelbase * 0.41
- ret.steerRatio = 16.89 # as spec
ret.lateralParams.torqueBP, ret.lateralParams.torqueV = [[0, 1000], [0, 1000]] # TODO: determine if there is a dead zone at the top end
ret.tireStiffnessFactor = 0.444
ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.8], [0.24]]
ret.wheelSpeedFactor = 1.025
elif candidate == CAR.CRV_5G:
- ret.mass = 3410. * CV.LB_TO_KG
- ret.wheelbase = 2.66
- ret.centerToFront = ret.wheelbase * 0.41
- ret.steerRatio = 16.0 # 12.3 is spec end-to-end
if eps_modified:
# stock request input values: 0x0000, 0x00DB, 0x01BB, 0x0296, 0x0377, 0x0454, 0x0532, 0x0610, 0x067F
# stock request output values: 0x0000, 0x0500, 0x0A15, 0x0E6D, 0x1100, 0x1200, 0x129A, 0x134D, 0x1400
@@ -167,39 +143,22 @@ class CarInterface(CarInterfaceBase):
ret.wheelSpeedFactor = 1.025
elif candidate == CAR.CRV_HYBRID:
- ret.mass = 1667. # mean of 4 models in kg
- ret.wheelbase = 2.66
- ret.centerToFront = ret.wheelbase * 0.41
- ret.steerRatio = 16.0 # 12.3 is spec end-to-end
ret.lateralParams.torqueBP, ret.lateralParams.torqueV = [[0, 4096], [0, 4096]] # TODO: determine if there is a dead zone at the top end
ret.tireStiffnessFactor = 0.677
ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.6], [0.18]]
ret.wheelSpeedFactor = 1.025
elif candidate == CAR.FIT:
- ret.mass = 2644. * CV.LB_TO_KG
- ret.wheelbase = 2.53
- ret.centerToFront = ret.wheelbase * 0.39
- ret.steerRatio = 13.06
ret.lateralParams.torqueBP, ret.lateralParams.torqueV = [[0, 4096], [0, 4096]] # TODO: determine if there is a dead zone at the top end
ret.tireStiffnessFactor = 0.75
ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.2], [0.05]]
elif candidate == CAR.FREED:
- ret.mass = 3086. * CV.LB_TO_KG
- ret.wheelbase = 2.74
- # the remaining parameters were copied from FIT
- ret.centerToFront = ret.wheelbase * 0.39
- ret.steerRatio = 13.06
ret.lateralParams.torqueBP, ret.lateralParams.torqueV = [[0, 4096], [0, 4096]]
ret.tireStiffnessFactor = 0.75
ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.2], [0.05]]
elif candidate in (CAR.HRV, CAR.HRV_3G):
- ret.mass = 3125 * CV.LB_TO_KG
- ret.wheelbase = 2.61
- ret.centerToFront = ret.wheelbase * 0.41
- ret.steerRatio = 15.2
ret.lateralParams.torqueBP, ret.lateralParams.torqueV = [[0, 4096], [0, 4096]]
ret.tireStiffnessFactor = 0.5
if candidate == CAR.HRV:
@@ -209,28 +168,16 @@ class CarInterface(CarInterfaceBase):
ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.8], [0.24]] # TODO: can probably use some tuning
elif candidate == CAR.ACURA_RDX:
- ret.mass = 3935. * CV.LB_TO_KG
- ret.wheelbase = 2.68
- ret.centerToFront = ret.wheelbase * 0.38
- ret.steerRatio = 15.0 # as spec
ret.tireStiffnessFactor = 0.444
ret.lateralParams.torqueBP, ret.lateralParams.torqueV = [[0, 1000], [0, 1000]] # TODO: determine if there is a dead zone at the top end
ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.8], [0.24]]
elif candidate == CAR.ACURA_RDX_3G:
- ret.mass = 4068. * CV.LB_TO_KG
- ret.wheelbase = 2.75
- ret.centerToFront = ret.wheelbase * 0.41
- ret.steerRatio = 11.95 # as spec
ret.lateralParams.torqueBP, ret.lateralParams.torqueV = [[0, 3840], [0, 3840]]
ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.2], [0.06]]
ret.tireStiffnessFactor = 0.677
elif candidate in (CAR.ODYSSEY, CAR.ODYSSEY_CHN):
- ret.mass = 1900.
- ret.wheelbase = 3.00
- ret.centerToFront = ret.wheelbase * 0.41
- ret.steerRatio = 14.35 # as spec
ret.tireStiffnessFactor = 0.82
ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.28], [0.08]]
if candidate == CAR.ODYSSEY_CHN:
@@ -239,37 +186,21 @@ class CarInterface(CarInterfaceBase):
ret.lateralParams.torqueBP, ret.lateralParams.torqueV = [[0, 4096], [0, 4096]] # TODO: determine if there is a dead zone at the top end
elif candidate == CAR.PILOT:
- ret.mass = 4278. * CV.LB_TO_KG # average weight
- ret.wheelbase = 2.86
- ret.centerToFront = ret.wheelbase * 0.428
- ret.steerRatio = 16.0 # as spec
ret.lateralParams.torqueBP, ret.lateralParams.torqueV = [[0, 4096], [0, 4096]] # TODO: determine if there is a dead zone at the top end
ret.tireStiffnessFactor = 0.444
ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.38], [0.11]]
elif candidate == CAR.RIDGELINE:
- ret.mass = 4515. * CV.LB_TO_KG
- ret.wheelbase = 3.18
- ret.centerToFront = ret.wheelbase * 0.41
- ret.steerRatio = 15.59 # as spec
ret.lateralParams.torqueBP, ret.lateralParams.torqueV = [[0, 4096], [0, 4096]] # TODO: determine if there is a dead zone at the top end
ret.tireStiffnessFactor = 0.444
ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.38], [0.11]]
elif candidate == CAR.INSIGHT:
- ret.mass = 2987. * CV.LB_TO_KG
- ret.wheelbase = 2.7
- ret.centerToFront = ret.wheelbase * 0.39
- ret.steerRatio = 15.0 # 12.58 is spec end-to-end
ret.lateralParams.torqueBP, ret.lateralParams.torqueV = [[0, 4096], [0, 4096]] # TODO: determine if there is a dead zone at the top end
ret.tireStiffnessFactor = 0.82
ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.6], [0.18]]
elif candidate == CAR.HONDA_E:
- ret.mass = 3338.8 * CV.LB_TO_KG
- ret.wheelbase = 2.5
- ret.centerToFront = ret.wheelbase * 0.5
- ret.steerRatio = 16.71
ret.lateralParams.torqueBP, ret.lateralParams.torqueV = [[0, 4096], [0, 4096]] # TODO: determine if there is a dead zone at the top end
ret.tireStiffnessFactor = 0.82
ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.6], [0.18]] # TODO: can probably use some tuning
diff --git a/selfdrive/car/honda/values.py b/selfdrive/car/honda/values.py
index ce4a531d01..abe710528c 100644
--- a/selfdrive/car/honda/values.py
+++ b/selfdrive/car/honda/values.py
@@ -1,10 +1,10 @@
from dataclasses import dataclass
-from enum import Enum, IntFlag, StrEnum
+from enum import Enum, IntFlag
from cereal import car
from openpilot.common.conversions import Conversions as CV
from panda.python import uds
-from openpilot.selfdrive.car import dbc_dict
+from openpilot.selfdrive.car import CarSpecs, PlatformConfig, Platforms, dbc_dict
from openpilot.selfdrive.car.docs_definitions import CarFootnote, CarHarness, CarInfo, CarParts, Column
from openpilot.selfdrive.car.fw_query_definitions import FwQueryConfig, Request, StdQueries, p16
@@ -46,10 +46,21 @@ class CarControllerParams:
class HondaFlags(IntFlag):
+ # Detected flags
# Bosch models with alternate set of LKAS_HUD messages
BOSCH_EXT_HUD = 1
BOSCH_ALT_BRAKE = 2
+ # Static flags
+ BOSCH = 4
+ BOSCH_RADARLESS = 8
+
+ NIDEC = 16
+ NIDEC_ALT_PCM_ACCEL = 32
+ NIDEC_ALT_SCM_MESSAGES = 64
+
+ AUTORESUME_SNG = 128
+ ELECTRIC_PARKING_BRAKE = 256
# Car button codes
class CruiseButtons:
@@ -72,86 +83,203 @@ VISUAL_HUD = {
}
-class CAR(StrEnum):
- ACCORD = "HONDA ACCORD 2018"
- CIVIC = "HONDA CIVIC 2016"
- CIVIC_BOSCH = "HONDA CIVIC (BOSCH) 2019"
- CIVIC_BOSCH_DIESEL = "HONDA CIVIC SEDAN 1.6 DIESEL 2019"
- CIVIC_2022 = "HONDA CIVIC 2022"
- ACURA_ILX = "ACURA ILX 2016"
- CRV = "HONDA CR-V 2016"
- CRV_5G = "HONDA CR-V 2017"
- CRV_EU = "HONDA CR-V EU 2016"
- CRV_HYBRID = "HONDA CR-V HYBRID 2019"
- FIT = "HONDA FIT 2018"
- FREED = "HONDA FREED 2020"
- HRV = "HONDA HRV 2019"
- HRV_3G = "HONDA HR-V 2023"
- ODYSSEY = "HONDA ODYSSEY 2018"
- ODYSSEY_CHN = "HONDA ODYSSEY CHN 2019"
- ACURA_RDX = "ACURA RDX 2018"
- ACURA_RDX_3G = "ACURA RDX 2020"
- PILOT = "HONDA PILOT 2017"
- RIDGELINE = "HONDA RIDGELINE 2017"
- INSIGHT = "HONDA INSIGHT 2019"
- HONDA_E = "HONDA E 2020"
-
-
-class Footnote(Enum):
- CIVIC_DIESEL = CarFootnote(
- "2019 Honda Civic 1.6L Diesel Sedan does not have ALC below 12mph.",
- Column.FSR_STEERING)
-
-
@dataclass
class HondaCarInfo(CarInfo):
package: str = "Honda Sensing"
def init_make(self, CP: car.CarParams):
- if CP.carFingerprint in HONDA_BOSCH:
- self.car_parts = CarParts.common([CarHarness.bosch_b]) if CP.carFingerprint in HONDA_BOSCH_RADARLESS else CarParts.common([CarHarness.bosch_a])
+ if CP.flags & HondaFlags.BOSCH:
+ self.car_parts = CarParts.common([CarHarness.bosch_b]) if CP.flags & HondaFlags.BOSCH_RADARLESS else CarParts.common([CarHarness.bosch_a])
else:
self.car_parts = CarParts.common([CarHarness.nidec])
-CAR_INFO: dict[str, HondaCarInfo | list[HondaCarInfo] | None] = {
- CAR.ACCORD: [
- HondaCarInfo("Honda Accord 2018-22", "All", video_link="https://www.youtube.com/watch?v=mrUwlj3Mi58", min_steer_speed=3. * CV.MPH_TO_MS),
- HondaCarInfo("Honda Inspire 2018", "All", min_steer_speed=3. * CV.MPH_TO_MS),
- HondaCarInfo("Honda Accord Hybrid 2018-22", "All", min_steer_speed=3. * CV.MPH_TO_MS),
- ],
- CAR.CIVIC: HondaCarInfo("Honda Civic 2016-18", min_steer_speed=12. * CV.MPH_TO_MS, video_link="https://youtu.be/-IkImTe1NYE"),
- CAR.CIVIC_BOSCH: [
- HondaCarInfo("Honda Civic 2019-21", "All", video_link="https://www.youtube.com/watch?v=4Iz1Mz5LGF8",
- footnotes=[Footnote.CIVIC_DIESEL], min_steer_speed=2. * CV.MPH_TO_MS),
- HondaCarInfo("Honda Civic Hatchback 2017-21", min_steer_speed=12. * CV.MPH_TO_MS),
- ],
- CAR.CIVIC_BOSCH_DIESEL: None, # same platform
- CAR.CIVIC_2022: [
- HondaCarInfo("Honda Civic 2022-23", "All", video_link="https://youtu.be/ytiOT5lcp6Q"),
- HondaCarInfo("Honda Civic Hatchback 2022-23", "All", video_link="https://youtu.be/ytiOT5lcp6Q"),
- ],
- CAR.ACURA_ILX: HondaCarInfo("Acura ILX 2016-19", "AcuraWatch Plus", min_steer_speed=25. * CV.MPH_TO_MS),
- CAR.CRV: HondaCarInfo("Honda CR-V 2015-16", "Touring Trim", min_steer_speed=12. * CV.MPH_TO_MS),
- CAR.CRV_5G: HondaCarInfo("Honda CR-V 2017-22", min_steer_speed=12. * CV.MPH_TO_MS),
- CAR.CRV_EU: None, # HondaCarInfo("Honda CR-V EU", "Touring"), # Euro version of CRV Touring
- CAR.CRV_HYBRID: HondaCarInfo("Honda CR-V Hybrid 2017-20", min_steer_speed=12. * CV.MPH_TO_MS),
- CAR.FIT: HondaCarInfo("Honda Fit 2018-20", min_steer_speed=12. * CV.MPH_TO_MS),
- CAR.FREED: HondaCarInfo("Honda Freed 2020", min_steer_speed=12. * CV.MPH_TO_MS),
- CAR.HRV: HondaCarInfo("Honda HR-V 2019-22", min_steer_speed=12. * CV.MPH_TO_MS),
- CAR.HRV_3G: HondaCarInfo("Honda HR-V 2023", "All"),
- CAR.ODYSSEY: HondaCarInfo("Honda Odyssey 2018-20"),
- CAR.ODYSSEY_CHN: None, # Chinese version of Odyssey
- CAR.ACURA_RDX: HondaCarInfo("Acura RDX 2016-18", "AcuraWatch Plus", min_steer_speed=12. * CV.MPH_TO_MS),
- CAR.ACURA_RDX_3G: HondaCarInfo("Acura RDX 2019-22", "All", min_steer_speed=3. * CV.MPH_TO_MS),
- CAR.PILOT: [
- HondaCarInfo("Honda Pilot 2016-22", min_steer_speed=12. * CV.MPH_TO_MS),
- HondaCarInfo("Honda Passport 2019-23", "All", min_steer_speed=12. * CV.MPH_TO_MS),
- ],
- CAR.RIDGELINE: HondaCarInfo("Honda Ridgeline 2017-24", min_steer_speed=12. * CV.MPH_TO_MS),
- CAR.INSIGHT: HondaCarInfo("Honda Insight 2019-22", "All", min_steer_speed=3. * CV.MPH_TO_MS),
- CAR.HONDA_E: HondaCarInfo("Honda e 2020", "All", min_steer_speed=3. * CV.MPH_TO_MS),
-}
+class Footnote(Enum):
+ CIVIC_DIESEL = CarFootnote(
+ "2019 Honda Civic 1.6L Diesel Sedan does not have ALC below 12mph.",
+ Column.FSR_STEERING)
+
+
+class HondaPlatformConfig(PlatformConfig):
+ def init(self):
+ if self.flags & HondaFlags.BOSCH:
+ self.flags |= HondaFlags.AUTORESUME_SNG
+ self.flags |= HondaFlags.ELECTRIC_PARKING_BRAKE
+
+
+class CAR(Platforms):
+ # Bosch Cars
+ ACCORD = HondaPlatformConfig(
+ "HONDA ACCORD 2018",
+ [
+ HondaCarInfo("Honda Accord 2018-22", "All", video_link="https://www.youtube.com/watch?v=mrUwlj3Mi58", min_steer_speed=3. * CV.MPH_TO_MS),
+ HondaCarInfo("Honda Inspire 2018", "All", min_steer_speed=3. * CV.MPH_TO_MS),
+ HondaCarInfo("Honda Accord Hybrid 2018-22", "All", min_steer_speed=3. * CV.MPH_TO_MS),
+ ],
+ dbc_dict('honda_accord_2018_can_generated', None),
+ specs=CarSpecs(mass=3279 * CV.LB_TO_KG, wheelbase=2.83, steerRatio=16.33, centerToFrontRatio=0.39), # steerRatio: 11.82 is spec end-to-end
+ flags=HondaFlags.BOSCH,
+ )
+ CIVIC_BOSCH = HondaPlatformConfig(
+ "HONDA CIVIC (BOSCH) 2019",
+ [
+ HondaCarInfo("Honda Civic 2019-21", "All", video_link="https://www.youtube.com/watch?v=4Iz1Mz5LGF8",
+ footnotes=[Footnote.CIVIC_DIESEL], min_steer_speed=2. * CV.MPH_TO_MS),
+ HondaCarInfo("Honda Civic Hatchback 2017-21", min_steer_speed=12. * CV.MPH_TO_MS),
+ ],
+ dbc_dict('honda_civic_hatchback_ex_2017_can_generated', None),
+ specs=CarSpecs(mass=1326, wheelbase=2.7, steerRatio=15.38, centerToFrontRatio=0.4), # steerRatio: 10.93 is end-to-end spec
+ flags=HondaFlags.BOSCH
+ )
+ CIVIC_BOSCH_DIESEL = HondaPlatformConfig(
+ "HONDA CIVIC SEDAN 1.6 DIESEL 2019",
+ None, # don't show in docs
+ dbc_dict('honda_accord_2018_can_generated', None),
+ specs=CIVIC_BOSCH.specs,
+ flags=HondaFlags.BOSCH
+ )
+ CIVIC_2022 = HondaPlatformConfig(
+ "HONDA CIVIC 2022",
+ [
+ HondaCarInfo("Honda Civic 2022-23", "All", video_link="https://youtu.be/ytiOT5lcp6Q"),
+ HondaCarInfo("Honda Civic Hatchback 2022-23", "All", video_link="https://youtu.be/ytiOT5lcp6Q"),
+ ],
+ dbc_dict('honda_civic_ex_2022_can_generated', None),
+ specs=CIVIC_BOSCH.specs,
+ flags=HondaFlags.BOSCH | HondaFlags.BOSCH_RADARLESS,
+ )
+ CRV_5G = HondaPlatformConfig(
+ "HONDA CR-V 2017",
+ HondaCarInfo("Honda CR-V 2017-22", min_steer_speed=12. * CV.MPH_TO_MS),
+ dbc_dict('honda_crv_ex_2017_can_generated', None, body_dbc='honda_crv_ex_2017_body_generated'),
+ specs=CarSpecs(mass=3410 * CV.LB_TO_KG, wheelbase=2.66, steerRatio=16.0, centerToFrontRatio=0.41), # steerRatio: 12.3 is spec end-to-end
+ flags=HondaFlags.BOSCH,
+ )
+ CRV_HYBRID = HondaPlatformConfig(
+ "HONDA CR-V HYBRID 2019",
+ HondaCarInfo("Honda CR-V Hybrid 2017-20", min_steer_speed=12. * CV.MPH_TO_MS),
+ dbc_dict('honda_accord_2018_can_generated', None),
+ specs=CarSpecs(mass=1667, wheelbase=2.66, steerRatio=16, centerToFrontRatio=0.41), # mass: mean of 4 models in kg, steerRatio: 12.3 is spec end-to-end
+ flags=HondaFlags.BOSCH
+ )
+ HRV_3G = HondaPlatformConfig(
+ "HONDA HR-V 2023",
+ HondaCarInfo("Honda HR-V 2023", "All"),
+ dbc_dict('honda_civic_ex_2022_can_generated', None),
+ specs=CarSpecs(mass=3125 * CV.LB_TO_KG, wheelbase=2.61, steerRatio=15.2, centerToFrontRatio=0.41),
+ flags=HondaFlags.BOSCH | HondaFlags.BOSCH_RADARLESS
+ )
+ ACURA_RDX_3G = HondaPlatformConfig(
+ "ACURA RDX 2020",
+ HondaCarInfo("Acura RDX 2019-22", "All", min_steer_speed=3. * CV.MPH_TO_MS),
+ dbc_dict('acura_rdx_2020_can_generated', None),
+ specs=CarSpecs(mass=4068 * CV.LB_TO_KG, wheelbase=2.75, steerRatio=11.95, centerToFrontRatio=0.41), # as spec
+ flags=HondaFlags.BOSCH
+ )
+ INSIGHT = HondaPlatformConfig(
+ "HONDA INSIGHT 2019",
+ HondaCarInfo("Honda Insight 2019-22", "All", min_steer_speed=3. * CV.MPH_TO_MS),
+ dbc_dict('honda_insight_ex_2019_can_generated', None),
+ specs=CarSpecs(mass=2987 * CV.LB_TO_KG, wheelbase=2.7, steerRatio=15.0, centerToFrontRatio=0.39), # as spec
+ flags=HondaFlags.BOSCH
+ )
+ HONDA_E = HondaPlatformConfig(
+ "HONDA E 2020",
+ HondaCarInfo("Honda e 2020", "All", min_steer_speed=3. * CV.MPH_TO_MS),
+ dbc_dict('acura_rdx_2020_can_generated', None),
+ specs=CarSpecs(mass=3338.8 * CV.LB_TO_KG, wheelbase=2.5, centerToFrontRatio=0.5, steerRatio=16.71),
+ flags=HondaFlags.BOSCH
+ )
+
+ # Nidec Cars
+ ACURA_ILX = HondaPlatformConfig(
+ "ACURA ILX 2016",
+ HondaCarInfo("Acura ILX 2016-19", "AcuraWatch Plus", min_steer_speed=25. * CV.MPH_TO_MS),
+ dbc_dict('acura_ilx_2016_can_generated', 'acura_ilx_2016_nidec'),
+ specs=CarSpecs(mass=3095 * CV.LB_TO_KG, wheelbase=2.67, steerRatio=18.61, centerToFrontRatio=0.37), # 15.3 is spec end-to-end
+ flags=HondaFlags.NIDEC | HondaFlags.NIDEC_ALT_SCM_MESSAGES,
+ )
+ CRV = HondaPlatformConfig(
+ "HONDA CR-V 2016",
+ HondaCarInfo("Honda CR-V 2015-16", "Touring Trim", min_steer_speed=12. * CV.MPH_TO_MS),
+ dbc_dict('honda_crv_touring_2016_can_generated', 'acura_ilx_2016_nidec'),
+ specs=CarSpecs(mass=3572 * CV.LB_TO_KG, wheelbase=2.62, steerRatio=16.89, centerToFrontRatio=0.41), # as spec
+ flags=HondaFlags.NIDEC | HondaFlags.NIDEC_ALT_SCM_MESSAGES,
+ )
+ CRV_EU = HondaPlatformConfig(
+ "HONDA CR-V EU 2016",
+ None, # Euro version of CRV Touring, don't show in docs
+ dbc_dict('honda_crv_executive_2016_can_generated', 'acura_ilx_2016_nidec'),
+ specs=CRV.specs,
+ flags=HondaFlags.NIDEC | HondaFlags.NIDEC_ALT_SCM_MESSAGES,
+ )
+ FIT = HondaPlatformConfig(
+ "HONDA FIT 2018",
+ HondaCarInfo("Honda Fit 2018-20", min_steer_speed=12. * CV.MPH_TO_MS),
+ dbc_dict('honda_fit_ex_2018_can_generated', 'acura_ilx_2016_nidec'),
+ specs=CarSpecs(mass=2644 * CV.LB_TO_KG, wheelbase=2.53, steerRatio=13.06, centerToFrontRatio=0.39),
+ flags=HondaFlags.NIDEC | HondaFlags.NIDEC_ALT_SCM_MESSAGES,
+ )
+ FREED = HondaPlatformConfig(
+ "HONDA FREED 2020",
+ HondaCarInfo("Honda Freed 2020", min_steer_speed=12. * CV.MPH_TO_MS),
+ dbc_dict('honda_fit_ex_2018_can_generated', 'acura_ilx_2016_nidec'),
+ specs=CarSpecs(mass=3086. * CV.LB_TO_KG, wheelbase=2.74, steerRatio=13.06, centerToFrontRatio=0.39), # mostly copied from FIT
+ flags=HondaFlags.NIDEC | HondaFlags.NIDEC_ALT_SCM_MESSAGES,
+ )
+ HRV = HondaPlatformConfig(
+ "HONDA HRV 2019",
+ HondaCarInfo("Honda HR-V 2019-22", min_steer_speed=12. * CV.MPH_TO_MS),
+ dbc_dict('honda_fit_ex_2018_can_generated', 'acura_ilx_2016_nidec'),
+ specs=HRV_3G.specs,
+ flags=HondaFlags.NIDEC | HondaFlags.NIDEC_ALT_SCM_MESSAGES,
+ )
+ ODYSSEY = HondaPlatformConfig(
+ "HONDA ODYSSEY 2018",
+ HondaCarInfo("Honda Odyssey 2018-20"),
+ dbc_dict('honda_odyssey_exl_2018_generated', 'acura_ilx_2016_nidec'),
+ specs=CarSpecs(mass=1900, wheelbase=3.0, steerRatio=14.35, centerToFrontRatio=0.41),
+ flags=HondaFlags.NIDEC | HondaFlags.NIDEC_ALT_PCM_ACCEL
+ )
+ ODYSSEY_CHN = HondaPlatformConfig(
+ "HONDA ODYSSEY CHN 2019",
+ None, # Chinese version of Odyssey, don't show in docs
+ dbc_dict('honda_odyssey_extreme_edition_2018_china_can_generated', 'acura_ilx_2016_nidec'),
+ specs=ODYSSEY.specs,
+ flags=HondaFlags.NIDEC | HondaFlags.NIDEC_ALT_SCM_MESSAGES
+ )
+ ACURA_RDX = HondaPlatformConfig(
+ "ACURA RDX 2018",
+ HondaCarInfo("Acura RDX 2016-18", "AcuraWatch Plus", min_steer_speed=12. * CV.MPH_TO_MS),
+ dbc_dict('acura_rdx_2018_can_generated', 'acura_ilx_2016_nidec'),
+ specs=CarSpecs(mass=3925 * CV.LB_TO_KG, wheelbase=2.68, steerRatio=15.0, centerToFrontRatio=0.38), # as spec
+ flags=HondaFlags.NIDEC | HondaFlags.NIDEC_ALT_SCM_MESSAGES,
+ )
+ PILOT = HondaPlatformConfig(
+ "HONDA PILOT 2017",
+ [
+ HondaCarInfo("Honda Pilot 2016-22", min_steer_speed=12. * CV.MPH_TO_MS),
+ HondaCarInfo("Honda Passport 2019-23", "All", min_steer_speed=12. * CV.MPH_TO_MS),
+ ],
+ dbc_dict('acura_ilx_2016_can_generated', 'acura_ilx_2016_nidec'),
+ specs=CarSpecs(mass=4278 * CV.LB_TO_KG, wheelbase=2.86, centerToFrontRatio=0.428, steerRatio=16.0), # as spec
+ flags=HondaFlags.NIDEC | HondaFlags.NIDEC_ALT_SCM_MESSAGES,
+ )
+ RIDGELINE = HondaPlatformConfig(
+ "HONDA RIDGELINE 2017",
+ HondaCarInfo("Honda Ridgeline 2017-24", min_steer_speed=12. * CV.MPH_TO_MS),
+ dbc_dict('acura_ilx_2016_can_generated', 'acura_ilx_2016_nidec'),
+ specs=CarSpecs(mass=4515 * CV.LB_TO_KG, wheelbase=3.18, centerToFrontRatio=0.41, steerRatio=15.59), # as spec
+ flags=HondaFlags.NIDEC | HondaFlags.NIDEC_ALT_SCM_MESSAGES,
+ )
+ CIVIC = HondaPlatformConfig(
+ "HONDA CIVIC 2016",
+ HondaCarInfo("Honda Civic 2016-18", min_steer_speed=12. * CV.MPH_TO_MS, video_link="https://youtu.be/-IkImTe1NYE"),
+ dbc_dict('honda_civic_touring_2016_can_generated', 'acura_ilx_2016_nidec'),
+ specs=CarSpecs(mass=1326, wheelbase=2.70, centerToFrontRatio=0.4, steerRatio=15.38), # 10.93 is end-to-end spec
+ flags=HondaFlags.NIDEC | HondaFlags.AUTORESUME_SNG | HondaFlags.ELECTRIC_PARKING_BRAKE,
+ )
+
HONDA_VERSION_REQUEST = bytes([uds.SERVICE_TYPE.READ_DATA_BY_IDENTIFIER]) + \
p16(0xF112)
@@ -217,40 +345,16 @@ FW_QUERY_CONFIG = FwQueryConfig(
)
-DBC = {
- CAR.ACCORD: dbc_dict('honda_accord_2018_can_generated', None),
- CAR.ACURA_ILX: dbc_dict('acura_ilx_2016_can_generated', 'acura_ilx_2016_nidec'),
- CAR.ACURA_RDX: dbc_dict('acura_rdx_2018_can_generated', 'acura_ilx_2016_nidec'),
- CAR.ACURA_RDX_3G: dbc_dict('acura_rdx_2020_can_generated', None),
- CAR.CIVIC: dbc_dict('honda_civic_touring_2016_can_generated', 'acura_ilx_2016_nidec'),
- CAR.CIVIC_BOSCH: dbc_dict('honda_civic_hatchback_ex_2017_can_generated', None),
- CAR.CIVIC_BOSCH_DIESEL: dbc_dict('honda_accord_2018_can_generated', None),
- CAR.CRV: dbc_dict('honda_crv_touring_2016_can_generated', 'acura_ilx_2016_nidec'),
- CAR.CRV_5G: dbc_dict('honda_crv_ex_2017_can_generated', None, body_dbc='honda_crv_ex_2017_body_generated'),
- CAR.CRV_EU: dbc_dict('honda_crv_executive_2016_can_generated', 'acura_ilx_2016_nidec'),
- CAR.CRV_HYBRID: dbc_dict('honda_accord_2018_can_generated', None),
- CAR.FIT: dbc_dict('honda_fit_ex_2018_can_generated', 'acura_ilx_2016_nidec'),
- CAR.FREED: dbc_dict('honda_fit_ex_2018_can_generated', 'acura_ilx_2016_nidec'),
- CAR.HRV: dbc_dict('honda_fit_ex_2018_can_generated', 'acura_ilx_2016_nidec'),
- CAR.HRV_3G: dbc_dict('honda_civic_ex_2022_can_generated', None),
- CAR.ODYSSEY: dbc_dict('honda_odyssey_exl_2018_generated', 'acura_ilx_2016_nidec'),
- CAR.ODYSSEY_CHN: dbc_dict('honda_odyssey_extreme_edition_2018_china_can_generated', 'acura_ilx_2016_nidec'),
- CAR.PILOT: dbc_dict('acura_ilx_2016_can_generated', 'acura_ilx_2016_nidec'),
- CAR.RIDGELINE: dbc_dict('acura_ilx_2016_can_generated', 'acura_ilx_2016_nidec'),
- CAR.INSIGHT: dbc_dict('honda_insight_ex_2019_can_generated', None),
- CAR.HONDA_E: dbc_dict('acura_rdx_2020_can_generated', None),
- CAR.CIVIC_2022: dbc_dict('honda_civic_ex_2022_can_generated', None),
-}
-
STEER_THRESHOLD = {
# default is 1200, overrides go here
CAR.ACURA_RDX: 400,
CAR.CRV_EU: 400,
}
-HONDA_NIDEC_ALT_PCM_ACCEL = {CAR.ODYSSEY}
-HONDA_NIDEC_ALT_SCM_MESSAGES = {CAR.ACURA_ILX, CAR.ACURA_RDX, CAR.CRV, CAR.CRV_EU, CAR.FIT, CAR.FREED, CAR.HRV, CAR.ODYSSEY_CHN,
- CAR.PILOT, CAR.RIDGELINE}
-HONDA_BOSCH = {CAR.ACCORD, CAR.CIVIC_BOSCH, CAR.CIVIC_BOSCH_DIESEL, CAR.CRV_5G,
- CAR.CRV_HYBRID, CAR.INSIGHT, CAR.ACURA_RDX_3G, CAR.HONDA_E, CAR.CIVIC_2022, CAR.HRV_3G}
-HONDA_BOSCH_RADARLESS = {CAR.CIVIC_2022, CAR.HRV_3G}
+HONDA_NIDEC_ALT_PCM_ACCEL = CAR.with_flags(HondaFlags.NIDEC_ALT_PCM_ACCEL)
+HONDA_NIDEC_ALT_SCM_MESSAGES = CAR.with_flags(HondaFlags.NIDEC_ALT_SCM_MESSAGES)
+HONDA_BOSCH = CAR.with_flags(HondaFlags.BOSCH)
+HONDA_BOSCH_RADARLESS = CAR.with_flags(HondaFlags.BOSCH_RADARLESS)
+
+CAR_INFO = CAR.create_carinfo_map()
+DBC = CAR.create_dbc_map()
diff --git a/selfdrive/car/hyundai/carcontroller.py b/selfdrive/car/hyundai/carcontroller.py
index b0851abf55..ee7f441227 100644
--- a/selfdrive/car/hyundai/carcontroller.py
+++ b/selfdrive/car/hyundai/carcontroller.py
@@ -135,7 +135,7 @@ class CarController(CarControllerBase):
# button presses
can_sends.extend(self.create_button_messages(CC, CS, use_clu11=False))
else:
- can_sends.append(hyundaican.create_lkas11(self.packer, self.frame, self.car_fingerprint, apply_steer, apply_steer_req,
+ can_sends.append(hyundaican.create_lkas11(self.packer, self.frame, self.CP, apply_steer, apply_steer_req,
torque_fault, CS.lkas11, sys_warning, sys_state, CC.enabled,
hud_control.leftLaneVisible, hud_control.rightLaneVisible,
left_lane_warning, right_lane_warning))
@@ -175,12 +175,12 @@ class CarController(CarControllerBase):
can_sends = []
if use_clu11:
if CC.cruiseControl.cancel:
- can_sends.append(hyundaican.create_clu11(self.packer, self.frame, CS.clu11, Buttons.CANCEL, self.CP.carFingerprint))
+ can_sends.append(hyundaican.create_clu11(self.packer, self.frame, CS.clu11, Buttons.CANCEL, self.CP))
elif CC.cruiseControl.resume:
# send resume at a max freq of 10Hz
if (self.frame - self.last_button_frame) * DT_CTRL > 0.1:
# send 25 messages at a time to increases the likelihood of resume being accepted
- can_sends.extend([hyundaican.create_clu11(self.packer, self.frame, CS.clu11, Buttons.RES_ACCEL, self.CP.carFingerprint)] * 25)
+ can_sends.extend([hyundaican.create_clu11(self.packer, self.frame, CS.clu11, Buttons.RES_ACCEL, self.CP)] * 25)
if (self.frame - self.last_button_frame) * DT_CTRL >= 0.15:
self.last_button_frame = self.frame
else:
diff --git a/selfdrive/car/hyundai/hyundaican.py b/selfdrive/car/hyundai/hyundaican.py
index bc29aeb985..0bf29664e8 100644
--- a/selfdrive/car/hyundai/hyundaican.py
+++ b/selfdrive/car/hyundai/hyundaican.py
@@ -1,9 +1,9 @@
import crcmod
-from openpilot.selfdrive.car.hyundai.values import CAR, CHECKSUM, CAMERA_SCC_CAR
+from openpilot.selfdrive.car.hyundai.values import CAR, HyundaiFlags
hyundai_checksum = crcmod.mkCrcFun(0x11D, initCrc=0xFD, rev=False, xorOut=0xdf)
-def create_lkas11(packer, frame, car_fingerprint, apply_steer, steer_req,
+def create_lkas11(packer, frame, CP, apply_steer, steer_req,
torque_fault, lkas11, sys_warning, sys_state, enabled,
left_lane, right_lane,
left_lane_depart, right_lane_depart):
@@ -33,12 +33,12 @@ def create_lkas11(packer, frame, car_fingerprint, apply_steer, steer_req,
values["CF_Lkas_ToiFlt"] = torque_fault # seems to allow actuation on CR_Lkas_StrToqReq
values["CF_Lkas_MsgCount"] = frame % 0x10
- if car_fingerprint in (CAR.SONATA, CAR.PALISADE, CAR.KIA_NIRO_EV, CAR.KIA_NIRO_HEV_2021, CAR.SANTA_FE,
- CAR.IONIQ_EV_2020, CAR.IONIQ_PHEV, CAR.KIA_SELTOS, CAR.ELANTRA_2021, CAR.GENESIS_G70_2020,
- CAR.ELANTRA_HEV_2021, CAR.SONATA_HYBRID, CAR.KONA_EV, CAR.KONA_HEV, CAR.KONA_EV_2022,
- CAR.SANTA_FE_2022, CAR.KIA_K5_2021, CAR.IONIQ_HEV_2022, CAR.SANTA_FE_HEV_2022,
- CAR.SANTA_FE_PHEV_2022, CAR.KIA_STINGER_2022, CAR.KIA_K5_HEV_2020, CAR.KIA_CEED,
- CAR.AZERA_6TH_GEN, CAR.AZERA_HEV_6TH_GEN, CAR.CUSTIN_1ST_GEN):
+ if CP.carFingerprint in (CAR.SONATA, CAR.PALISADE, CAR.KIA_NIRO_EV, CAR.KIA_NIRO_HEV_2021, CAR.SANTA_FE,
+ CAR.IONIQ_EV_2020, CAR.IONIQ_PHEV, CAR.KIA_SELTOS, CAR.ELANTRA_2021, CAR.GENESIS_G70_2020,
+ CAR.ELANTRA_HEV_2021, CAR.SONATA_HYBRID, CAR.KONA_EV, CAR.KONA_HEV, CAR.KONA_EV_2022,
+ CAR.SANTA_FE_2022, CAR.KIA_K5_2021, CAR.IONIQ_HEV_2022, CAR.SANTA_FE_HEV_2022,
+ CAR.SANTA_FE_PHEV_2022, CAR.KIA_STINGER_2022, CAR.KIA_K5_HEV_2020, CAR.KIA_CEED,
+ CAR.AZERA_6TH_GEN, CAR.AZERA_HEV_6TH_GEN, CAR.CUSTIN_1ST_GEN):
values["CF_Lkas_LdwsActivemode"] = int(left_lane) + (int(right_lane) << 1)
values["CF_Lkas_LdwsOpt_USM"] = 2
@@ -57,7 +57,7 @@ def create_lkas11(packer, frame, car_fingerprint, apply_steer, steer_req,
values["CF_Lkas_SysWarning"] = 4 if sys_warning else 0
# Likely cars lacking the ability to show individual lane lines in the dash
- elif car_fingerprint in (CAR.KIA_OPTIMA_G4, CAR.KIA_OPTIMA_G4_FL):
+ elif CP.carFingerprint in (CAR.KIA_OPTIMA_G4, CAR.KIA_OPTIMA_G4_FL):
# SysWarning 4 = keep hands on wheel + beep
values["CF_Lkas_SysWarning"] = 4 if sys_warning else 0
@@ -72,18 +72,18 @@ def create_lkas11(packer, frame, car_fingerprint, apply_steer, steer_req,
values["CF_Lkas_LdwsActivemode"] = 0
values["CF_Lkas_FcwOpt_USM"] = 0
- elif car_fingerprint == CAR.HYUNDAI_GENESIS:
+ elif CP.carFingerprint == CAR.HYUNDAI_GENESIS:
# This field is actually LdwsActivemode
# Genesis and Optima fault when forwarding while engaged
values["CF_Lkas_LdwsActivemode"] = 2
dat = packer.make_can_msg("LKAS11", 0, values)[2]
- if car_fingerprint in CHECKSUM["crc8"]:
+ if CP.flags & HyundaiFlags.CHECKSUM_CRC8:
# CRC Checksum as seen on 2019 Hyundai Santa Fe
dat = dat[:6] + dat[7:8]
checksum = hyundai_checksum(dat)
- elif car_fingerprint in CHECKSUM["6B"]:
+ elif CP.flags & HyundaiFlags.CHECKSUM_6B:
# Checksum of first 6 Bytes, as seen on 2018 Kia Sorento
checksum = sum(dat[:6]) % 256
else:
@@ -95,7 +95,7 @@ def create_lkas11(packer, frame, car_fingerprint, apply_steer, steer_req,
return packer.make_can_msg("LKAS11", 0, values)
-def create_clu11(packer, frame, clu11, button, car_fingerprint):
+def create_clu11(packer, frame, clu11, button, CP):
values = {s: clu11[s] for s in [
"CF_Clu_CruiseSwState",
"CF_Clu_CruiseSwMain",
@@ -113,7 +113,7 @@ def create_clu11(packer, frame, clu11, button, car_fingerprint):
values["CF_Clu_CruiseSwState"] = button
values["CF_Clu_AliveCnt1"] = frame % 0x10
# send buttons to camera on camera-scc based cars
- bus = 2 if car_fingerprint in CAMERA_SCC_CAR else 0
+ bus = 2 if CP.flags & HyundaiFlags.CAMERA_SCC else 0
return packer.make_can_msg("CLU11", bus, values)
diff --git a/selfdrive/car/hyundai/values.py b/selfdrive/car/hyundai/values.py
index 76ff0b39ce..d23d3a0a75 100644
--- a/selfdrive/car/hyundai/values.py
+++ b/selfdrive/car/hyundai/values.py
@@ -1,11 +1,11 @@
import re
-from dataclasses import dataclass
-from enum import Enum, IntFlag, StrEnum
+from dataclasses import dataclass, field
+from enum import Enum, IntFlag
from cereal import car
from panda.python import uds
from openpilot.common.conversions import Conversions as CV
-from openpilot.selfdrive.car import dbc_dict
+from openpilot.selfdrive.car import DbcDict, PlatformConfig, Platforms, dbc_dict
from openpilot.selfdrive.car.docs_definitions import CarFootnote, CarHarness, CarInfo, CarParts, Column
from openpilot.selfdrive.car.fw_query_definitions import FwQueryConfig, Request, p16
@@ -52,92 +52,46 @@ class CarControllerParams:
class HyundaiFlags(IntFlag):
+ # Dynamic Flags
CANFD_HDA2 = 1
CANFD_ALT_BUTTONS = 2
- CANFD_ALT_GEARS = 4
- CANFD_CAMERA_SCC = 8
+ CANFD_ALT_GEARS = 2 ** 2
+ CANFD_CAMERA_SCC = 2 ** 3
- ALT_LIMITS = 16
- ENABLE_BLINKERS = 32
- CANFD_ALT_GEARS_2 = 64
- SEND_LFA = 128
- USE_FCA = 256
- CANFD_HDA2_ALT_STEERING = 512
- HYBRID = 1024
- EV = 2048
+ ALT_LIMITS = 2 ** 4
+ ENABLE_BLINKERS = 2 ** 5
+ CANFD_ALT_GEARS_2 = 2 ** 6
+ SEND_LFA = 2 ** 7
+ USE_FCA = 2 ** 8
+ CANFD_HDA2_ALT_STEERING = 2 ** 9
+ # these cars use a different gas signal
+ HYBRID = 2 ** 10
+ EV = 2 ** 11
-class CAR(StrEnum):
- # Hyundai
- AZERA_6TH_GEN = "HYUNDAI AZERA 6TH GEN"
- AZERA_HEV_6TH_GEN = "HYUNDAI AZERA HYBRID 6TH GEN"
- ELANTRA = "HYUNDAI ELANTRA 2017"
- ELANTRA_GT_I30 = "HYUNDAI I30 N LINE 2019 & GT 2018 DCT"
- ELANTRA_2021 = "HYUNDAI ELANTRA 2021"
- ELANTRA_HEV_2021 = "HYUNDAI ELANTRA HYBRID 2021"
- HYUNDAI_GENESIS = "HYUNDAI GENESIS 2015-2016"
- IONIQ = "HYUNDAI IONIQ HYBRID 2017-2019"
- IONIQ_HEV_2022 = "HYUNDAI IONIQ HYBRID 2020-2022"
- IONIQ_EV_LTD = "HYUNDAI IONIQ ELECTRIC LIMITED 2019"
- IONIQ_EV_2020 = "HYUNDAI IONIQ ELECTRIC 2020"
- IONIQ_PHEV_2019 = "HYUNDAI IONIQ PLUG-IN HYBRID 2019"
- IONIQ_PHEV = "HYUNDAI IONIQ PHEV 2020"
- KONA = "HYUNDAI KONA 2020"
- KONA_EV = "HYUNDAI KONA ELECTRIC 2019"
- KONA_EV_2022 = "HYUNDAI KONA ELECTRIC 2022"
- KONA_EV_2ND_GEN = "HYUNDAI KONA ELECTRIC 2ND GEN"
- KONA_HEV = "HYUNDAI KONA HYBRID 2020"
- SANTA_FE = "HYUNDAI SANTA FE 2019"
- SANTA_FE_2022 = "HYUNDAI SANTA FE 2022"
- SANTA_FE_HEV_2022 = "HYUNDAI SANTA FE HYBRID 2022"
- SANTA_FE_PHEV_2022 = "HYUNDAI SANTA FE PlUG-IN HYBRID 2022"
- SONATA = "HYUNDAI SONATA 2020"
- SONATA_LF = "HYUNDAI SONATA 2019"
- STARIA_4TH_GEN = "HYUNDAI STARIA 4TH GEN"
- TUCSON = "HYUNDAI TUCSON 2019"
- PALISADE = "HYUNDAI PALISADE 2020"
- VELOSTER = "HYUNDAI VELOSTER 2019"
- SONATA_HYBRID = "HYUNDAI SONATA HYBRID 2021"
- IONIQ_5 = "HYUNDAI IONIQ 5 2022"
- IONIQ_6 = "HYUNDAI IONIQ 6 2023"
- TUCSON_4TH_GEN = "HYUNDAI TUCSON 4TH GEN"
- SANTA_CRUZ_1ST_GEN = "HYUNDAI SANTA CRUZ 1ST GEN"
- CUSTIN_1ST_GEN = "HYUNDAI CUSTIN 1ST GEN"
+ # Static Flags
- # Kia
- KIA_FORTE = "KIA FORTE E 2018 & GT 2021"
- KIA_K5_2021 = "KIA K5 2021"
- KIA_K5_HEV_2020 = "KIA K5 HYBRID 2020"
- KIA_K8_HEV_1ST_GEN = "KIA K8 HYBRID 1ST GEN"
- KIA_NIRO_EV = "KIA NIRO EV 2020"
- KIA_NIRO_EV_2ND_GEN = "KIA NIRO EV 2ND GEN"
- KIA_NIRO_PHEV = "KIA NIRO HYBRID 2019"
- KIA_NIRO_PHEV_2022 = "KIA NIRO PLUG-IN HYBRID 2022"
- KIA_NIRO_HEV_2021 = "KIA NIRO HYBRID 2021"
- KIA_NIRO_HEV_2ND_GEN = "KIA NIRO HYBRID 2ND GEN"
- KIA_OPTIMA_G4 = "KIA OPTIMA 4TH GEN"
- KIA_OPTIMA_G4_FL = "KIA OPTIMA 4TH GEN FACELIFT"
- KIA_OPTIMA_H = "KIA OPTIMA HYBRID 2017 & SPORTS 2019"
- KIA_OPTIMA_H_G4_FL = "KIA OPTIMA HYBRID 4TH GEN FACELIFT"
- KIA_SELTOS = "KIA SELTOS 2021"
- KIA_SPORTAGE_5TH_GEN = "KIA SPORTAGE 5TH GEN"
- KIA_SORENTO = "KIA SORENTO GT LINE 2018"
- KIA_SORENTO_4TH_GEN = "KIA SORENTO 4TH GEN"
- KIA_SORENTO_HEV_4TH_GEN = "KIA SORENTO HYBRID 4TH GEN"
- KIA_STINGER = "KIA STINGER GT2 2018"
- KIA_STINGER_2022 = "KIA STINGER 2022"
- KIA_CEED = "KIA CEED INTRO ED 2019"
- KIA_EV6 = "KIA EV6 2022"
- KIA_CARNIVAL_4TH_GEN = "KIA CARNIVAL 4TH GEN"
+ # If 0x500 is present on bus 1 it probably has a Mando radar outputting radar points.
+ # If no points are outputted by default it might be possible to turn it on using selfdrive/debug/hyundai_enable_radar_points.py
+ MANDO_RADAR = 2 ** 12
+ CANFD = 2 ** 13
- # Genesis
- GENESIS_GV60_EV_1ST_GEN = "GENESIS GV60 ELECTRIC 1ST GEN"
- GENESIS_G70 = "GENESIS G70 2018"
- GENESIS_G70_2020 = "GENESIS G70 2020"
- GENESIS_GV70_1ST_GEN = "GENESIS GV70 1ST GEN"
- GENESIS_G80 = "GENESIS G80 2017"
- GENESIS_G90 = "GENESIS G90 2017"
- GENESIS_GV80 = "GENESIS GV80 2023"
+ # The radar does SCC on these cars when HDA I, rather than the camera
+ RADAR_SCC = 2 ** 14
+ CAMERA_SCC = 2 ** 15
+ CHECKSUM_CRC8 = 2 ** 16
+ CHECKSUM_6B = 2 ** 17
+
+ # these cars require a special panda safety mode due to missing counters and checksums in the messages
+ LEGACY = 2 ** 18
+
+ # these cars have not been verified to work with longitudinal yet - radar disable, sending correct messages, etc.
+ UNSUPPORTED_LONGITUDINAL = 2 ** 19
+
+ CANFD_NO_RADAR_DISABLE = 2 ** 20
+
+ CLUSTER_GEARS = 2 ** 21
+ TCU_GEARS = 2 ** 22
class Footnote(Enum):
@@ -152,160 +106,425 @@ class HyundaiCarInfo(CarInfo):
package: str = "Smart Cruise Control (SCC)"
def init_make(self, CP: car.CarParams):
- if CP.carFingerprint in CANFD_CAR:
+ if CP.flags & HyundaiFlags.CANFD:
self.footnotes.insert(0, Footnote.CANFD)
-CAR_INFO: dict[str, HyundaiCarInfo | list[HyundaiCarInfo] | None] = {
- CAR.AZERA_6TH_GEN: HyundaiCarInfo("Hyundai Azera 2022", "All", car_parts=CarParts.common([CarHarness.hyundai_k])),
- CAR.AZERA_HEV_6TH_GEN: [
- HyundaiCarInfo("Hyundai Azera Hybrid 2019", "All", car_parts=CarParts.common([CarHarness.hyundai_c])),
- HyundaiCarInfo("Hyundai Azera Hybrid 2020", "All", car_parts=CarParts.common([CarHarness.hyundai_k])),
- ],
- CAR.ELANTRA: [
- # TODO: 2017-18 could be Hyundai G
- HyundaiCarInfo("Hyundai Elantra 2017-18", min_enable_speed=19 * CV.MPH_TO_MS, car_parts=CarParts.common([CarHarness.hyundai_b])),
- HyundaiCarInfo("Hyundai Elantra 2019", min_enable_speed=19 * CV.MPH_TO_MS, car_parts=CarParts.common([CarHarness.hyundai_g])),
- ],
- CAR.ELANTRA_GT_I30: [
- HyundaiCarInfo("Hyundai Elantra GT 2017-19", car_parts=CarParts.common([CarHarness.hyundai_e])),
- HyundaiCarInfo("Hyundai i30 2017-19", car_parts=CarParts.common([CarHarness.hyundai_e])),
- ],
- CAR.ELANTRA_2021: HyundaiCarInfo("Hyundai Elantra 2021-23", video_link="https://youtu.be/_EdYQtV52-c", car_parts=CarParts.common([CarHarness.hyundai_k])),
- CAR.ELANTRA_HEV_2021: HyundaiCarInfo("Hyundai Elantra Hybrid 2021-23", video_link="https://youtu.be/_EdYQtV52-c",
+@dataclass
+class HyundaiPlatformConfig(PlatformConfig):
+ dbc_dict: DbcDict = field(default_factory=lambda: dbc_dict("hyundai_kia_generic", None))
+
+ def init(self):
+ if self.flags & HyundaiFlags.MANDO_RADAR:
+ self.dbc_dict = dbc_dict('hyundai_kia_generic', 'hyundai_kia_mando_front_radar_generated')
+
+
+@dataclass
+class HyundaiCanFDPlatformConfig(HyundaiPlatformConfig):
+ dbc_dict: DbcDict = field(default_factory=lambda: dbc_dict("hyundai_canfd", None))
+
+ def init(self):
+ super().init()
+ self.flags |= HyundaiFlags.CANFD
+
+
+class CAR(Platforms):
+ # Hyundai
+ AZERA_6TH_GEN = HyundaiPlatformConfig(
+ "HYUNDAI AZERA 6TH GEN",
+ HyundaiCarInfo("Hyundai Azera 2022", "All", car_parts=CarParts.common([CarHarness.hyundai_k])),
+ )
+ AZERA_HEV_6TH_GEN = HyundaiPlatformConfig(
+ "HYUNDAI AZERA HYBRID 6TH GEN",
+ [
+ HyundaiCarInfo("Hyundai Azera Hybrid 2019", "All", car_parts=CarParts.common([CarHarness.hyundai_c])),
+ HyundaiCarInfo("Hyundai Azera Hybrid 2020", "All", car_parts=CarParts.common([CarHarness.hyundai_k])),
+ ],
+ flags=HyundaiFlags.HYBRID
+ )
+ ELANTRA = HyundaiPlatformConfig(
+ "HYUNDAI ELANTRA 2017",
+ [
+ # TODO: 2017-18 could be Hyundai G
+ HyundaiCarInfo("Hyundai Elantra 2017-18", min_enable_speed=19 * CV.MPH_TO_MS, car_parts=CarParts.common([CarHarness.hyundai_b])),
+ HyundaiCarInfo("Hyundai Elantra 2019", min_enable_speed=19 * CV.MPH_TO_MS, car_parts=CarParts.common([CarHarness.hyundai_g])),
+ ],
+ flags=HyundaiFlags.LEGACY | HyundaiFlags.CLUSTER_GEARS
+ )
+ ELANTRA_GT_I30 = HyundaiPlatformConfig(
+ "HYUNDAI I30 N LINE 2019 & GT 2018 DCT",
+ [
+ HyundaiCarInfo("Hyundai Elantra GT 2017-19", car_parts=CarParts.common([CarHarness.hyundai_e])),
+ HyundaiCarInfo("Hyundai i30 2017-19", car_parts=CarParts.common([CarHarness.hyundai_e])),
+ ],
+ flags=HyundaiFlags.LEGACY | HyundaiFlags.CLUSTER_GEARS
+ )
+ ELANTRA_2021 = HyundaiPlatformConfig(
+ "HYUNDAI ELANTRA 2021",
+ HyundaiCarInfo("Hyundai Elantra 2021-23", video_link="https://youtu.be/_EdYQtV52-c", car_parts=CarParts.common([CarHarness.hyundai_k])),
+ flags=HyundaiFlags.CHECKSUM_CRC8
+ )
+ ELANTRA_HEV_2021 = HyundaiPlatformConfig(
+ "HYUNDAI ELANTRA HYBRID 2021",
+ HyundaiCarInfo("Hyundai Elantra Hybrid 2021-23", video_link="https://youtu.be/_EdYQtV52-c",
car_parts=CarParts.common([CarHarness.hyundai_k])),
- CAR.HYUNDAI_GENESIS: [
- # TODO: check 2015 packages
- HyundaiCarInfo("Hyundai Genesis 2015-16", min_enable_speed=19 * CV.MPH_TO_MS, car_parts=CarParts.common([CarHarness.hyundai_j])),
- HyundaiCarInfo("Genesis G80 2017", "All", min_enable_speed=19 * CV.MPH_TO_MS, car_parts=CarParts.common([CarHarness.hyundai_j])),
- ],
- CAR.IONIQ: HyundaiCarInfo("Hyundai Ioniq Hybrid 2017-19", car_parts=CarParts.common([CarHarness.hyundai_c])),
- CAR.IONIQ_HEV_2022: HyundaiCarInfo("Hyundai Ioniq Hybrid 2020-22", car_parts=CarParts.common([CarHarness.hyundai_h])), # TODO: confirm 2020-21 harness
- CAR.IONIQ_EV_LTD: HyundaiCarInfo("Hyundai Ioniq Electric 2019", car_parts=CarParts.common([CarHarness.hyundai_c])),
- CAR.IONIQ_EV_2020: HyundaiCarInfo("Hyundai Ioniq Electric 2020", "All", car_parts=CarParts.common([CarHarness.hyundai_h])),
- CAR.IONIQ_PHEV_2019: HyundaiCarInfo("Hyundai Ioniq Plug-in Hybrid 2019", car_parts=CarParts.common([CarHarness.hyundai_c])),
- CAR.IONIQ_PHEV: HyundaiCarInfo("Hyundai Ioniq Plug-in Hybrid 2020-22", "All", car_parts=CarParts.common([CarHarness.hyundai_h])),
- CAR.KONA: HyundaiCarInfo("Hyundai Kona 2020", car_parts=CarParts.common([CarHarness.hyundai_b])),
- CAR.KONA_EV: HyundaiCarInfo("Hyundai Kona Electric 2018-21", car_parts=CarParts.common([CarHarness.hyundai_g])),
- CAR.KONA_EV_2022: HyundaiCarInfo("Hyundai Kona Electric 2022-23", car_parts=CarParts.common([CarHarness.hyundai_o])),
- CAR.KONA_HEV: HyundaiCarInfo("Hyundai Kona Hybrid 2020", car_parts=CarParts.common([CarHarness.hyundai_i])), # TODO: check packages
- # TODO: this is the 2024 US MY, not yet released
- CAR.KONA_EV_2ND_GEN: HyundaiCarInfo("Hyundai Kona Electric (with HDA II, Korea only) 2023", video_link="https://www.youtube.com/watch?v=U2fOCmcQ8hw",
+ flags=HyundaiFlags.CHECKSUM_CRC8 | HyundaiFlags.HYBRID
+ )
+ HYUNDAI_GENESIS = HyundaiPlatformConfig(
+ "HYUNDAI GENESIS 2015-2016",
+ [
+ # TODO: check 2015 packages
+ HyundaiCarInfo("Hyundai Genesis 2015-16", min_enable_speed=19 * CV.MPH_TO_MS, car_parts=CarParts.common([CarHarness.hyundai_j])),
+ HyundaiCarInfo("Genesis G80 2017", "All", min_enable_speed=19 * CV.MPH_TO_MS, car_parts=CarParts.common([CarHarness.hyundai_j])),
+ ],
+ flags=HyundaiFlags.CHECKSUM_6B | HyundaiFlags.LEGACY
+ )
+ IONIQ = HyundaiPlatformConfig(
+ "HYUNDAI IONIQ HYBRID 2017-2019",
+ HyundaiCarInfo("Hyundai Ioniq Hybrid 2017-19", car_parts=CarParts.common([CarHarness.hyundai_c])),
+ flags=HyundaiFlags.HYBRID
+ )
+ IONIQ_HEV_2022 = HyundaiPlatformConfig(
+ "HYUNDAI IONIQ HYBRID 2020-2022",
+ HyundaiCarInfo("Hyundai Ioniq Hybrid 2020-22", car_parts=CarParts.common([CarHarness.hyundai_h])), # TODO: confirm 2020-21 harness,
+ flags=HyundaiFlags.HYBRID | HyundaiFlags.LEGACY
+ )
+ IONIQ_EV_LTD = HyundaiPlatformConfig(
+ "HYUNDAI IONIQ ELECTRIC LIMITED 2019",
+ HyundaiCarInfo("Hyundai Ioniq Electric 2019", car_parts=CarParts.common([CarHarness.hyundai_c])),
+ flags=HyundaiFlags.MANDO_RADAR | HyundaiFlags.EV | HyundaiFlags.LEGACY
+ )
+ IONIQ_EV_2020 = HyundaiPlatformConfig(
+ "HYUNDAI IONIQ ELECTRIC 2020",
+ HyundaiCarInfo("Hyundai Ioniq Electric 2020", "All", car_parts=CarParts.common([CarHarness.hyundai_h])),
+ flags=HyundaiFlags.EV
+ )
+ IONIQ_PHEV_2019 = HyundaiPlatformConfig(
+ "HYUNDAI IONIQ PLUG-IN HYBRID 2019",
+ HyundaiCarInfo("Hyundai Ioniq Plug-in Hybrid 2019", car_parts=CarParts.common([CarHarness.hyundai_c])),
+ flags=HyundaiFlags.HYBRID
+ )
+ IONIQ_PHEV = HyundaiPlatformConfig(
+ "HYUNDAI IONIQ PHEV 2020",
+ HyundaiCarInfo("Hyundai Ioniq Plug-in Hybrid 2020-22", "All", car_parts=CarParts.common([CarHarness.hyundai_h])),
+ flags=HyundaiFlags.HYBRID
+ )
+ KONA = HyundaiPlatformConfig(
+ "HYUNDAI KONA 2020",
+ HyundaiCarInfo("Hyundai Kona 2020", car_parts=CarParts.common([CarHarness.hyundai_b])),
+ flags=HyundaiFlags.CLUSTER_GEARS
+ )
+ KONA_EV = HyundaiPlatformConfig(
+ "HYUNDAI KONA ELECTRIC 2019",
+ HyundaiCarInfo("Hyundai Kona Electric 2018-21", car_parts=CarParts.common([CarHarness.hyundai_g])),
+ flags=HyundaiFlags.EV
+ )
+ KONA_EV_2022 = HyundaiPlatformConfig(
+ "HYUNDAI KONA ELECTRIC 2022",
+ HyundaiCarInfo("Hyundai Kona Electric 2022-23", car_parts=CarParts.common([CarHarness.hyundai_o])),
+ flags=HyundaiFlags.CAMERA_SCC | HyundaiFlags.EV
+ )
+ KONA_EV_2ND_GEN = HyundaiCanFDPlatformConfig(
+ "HYUNDAI KONA ELECTRIC 2ND GEN",
+ HyundaiCarInfo("Hyundai Kona Electric (with HDA II, Korea only) 2023", video_link="https://www.youtube.com/watch?v=U2fOCmcQ8hw",
car_parts=CarParts.common([CarHarness.hyundai_r])),
- CAR.SANTA_FE: HyundaiCarInfo("Hyundai Santa Fe 2019-20", "All", video_link="https://youtu.be/bjDR0YjM__s",
+ flags=HyundaiFlags.EV | HyundaiFlags.CANFD_NO_RADAR_DISABLE
+ )
+ KONA_HEV = HyundaiPlatformConfig(
+ "HYUNDAI KONA HYBRID 2020",
+ HyundaiCarInfo("Hyundai Kona Hybrid 2020", car_parts=CarParts.common([CarHarness.hyundai_i])), # TODO: check packages,
+ flags=HyundaiFlags.HYBRID
+ )
+ SANTA_FE = HyundaiPlatformConfig(
+ "HYUNDAI SANTA FE 2019",
+ HyundaiCarInfo("Hyundai Santa Fe 2019-20", "All", video_link="https://youtu.be/bjDR0YjM__s",
car_parts=CarParts.common([CarHarness.hyundai_d])),
- CAR.SANTA_FE_2022: HyundaiCarInfo("Hyundai Santa Fe 2021-23", "All", video_link="https://youtu.be/VnHzSTygTS4",
+ flags=HyundaiFlags.MANDO_RADAR | HyundaiFlags.CHECKSUM_CRC8
+ )
+ SANTA_FE_2022 = HyundaiPlatformConfig(
+ "HYUNDAI SANTA FE 2022",
+ HyundaiCarInfo("Hyundai Santa Fe 2021-23", "All", video_link="https://youtu.be/VnHzSTygTS4",
car_parts=CarParts.common([CarHarness.hyundai_l])),
- CAR.SANTA_FE_HEV_2022: HyundaiCarInfo("Hyundai Santa Fe Hybrid 2022-23", "All", car_parts=CarParts.common([CarHarness.hyundai_l])),
- CAR.SANTA_FE_PHEV_2022: HyundaiCarInfo("Hyundai Santa Fe Plug-in Hybrid 2022-23", "All", car_parts=CarParts.common([CarHarness.hyundai_l])),
- CAR.SONATA: HyundaiCarInfo("Hyundai Sonata 2020-23", "All", video_link="https://www.youtube.com/watch?v=ix63r9kE3Fw",
+ flags=HyundaiFlags.CHECKSUM_CRC8
+ )
+ SANTA_FE_HEV_2022 = HyundaiPlatformConfig(
+ "HYUNDAI SANTA FE HYBRID 2022",
+ HyundaiCarInfo("Hyundai Santa Fe Hybrid 2022-23", "All", car_parts=CarParts.common([CarHarness.hyundai_l])),
+ flags=HyundaiFlags.CHECKSUM_CRC8 | HyundaiFlags.HYBRID
+ )
+ SANTA_FE_PHEV_2022 = HyundaiPlatformConfig(
+ "HYUNDAI SANTA FE PlUG-IN HYBRID 2022",
+ HyundaiCarInfo("Hyundai Santa Fe Plug-in Hybrid 2022-23", "All", car_parts=CarParts.common([CarHarness.hyundai_l])),
+ flags=HyundaiFlags.CHECKSUM_CRC8 | HyundaiFlags.HYBRID
+ )
+ SONATA = HyundaiPlatformConfig(
+ "HYUNDAI SONATA 2020",
+ HyundaiCarInfo("Hyundai Sonata 2020-23", "All", video_link="https://www.youtube.com/watch?v=ix63r9kE3Fw",
car_parts=CarParts.common([CarHarness.hyundai_a])),
- CAR.STARIA_4TH_GEN: HyundaiCarInfo("Hyundai Staria 2023", "All", car_parts=CarParts.common([CarHarness.hyundai_k])),
- CAR.SONATA_LF: HyundaiCarInfo("Hyundai Sonata 2018-19", car_parts=CarParts.common([CarHarness.hyundai_e])),
- CAR.TUCSON: [
- HyundaiCarInfo("Hyundai Tucson 2021", min_enable_speed=19 * CV.MPH_TO_MS, car_parts=CarParts.common([CarHarness.hyundai_l])),
- HyundaiCarInfo("Hyundai Tucson Diesel 2019", car_parts=CarParts.common([CarHarness.hyundai_l])),
- ],
- CAR.PALISADE: [
- HyundaiCarInfo("Hyundai Palisade 2020-22", "All", video_link="https://youtu.be/TAnDqjF4fDY?t=456", car_parts=CarParts.common([CarHarness.hyundai_h])),
- HyundaiCarInfo("Kia Telluride 2020-22", "All", car_parts=CarParts.common([CarHarness.hyundai_h])),
- ],
- CAR.VELOSTER: HyundaiCarInfo("Hyundai Veloster 2019-20", min_enable_speed=5. * CV.MPH_TO_MS, car_parts=CarParts.common([CarHarness.hyundai_e])),
- CAR.SONATA_HYBRID: HyundaiCarInfo("Hyundai Sonata Hybrid 2020-23", "All", car_parts=CarParts.common([CarHarness.hyundai_a])),
- CAR.IONIQ_5: [
- HyundaiCarInfo("Hyundai Ioniq 5 (Southeast Asia only) 2022-23", "All", car_parts=CarParts.common([CarHarness.hyundai_q])),
- HyundaiCarInfo("Hyundai Ioniq 5 (without HDA II) 2022-23", "Highway Driving Assist", car_parts=CarParts.common([CarHarness.hyundai_k])),
- HyundaiCarInfo("Hyundai Ioniq 5 (with HDA II) 2022-23", "Highway Driving Assist II", car_parts=CarParts.common([CarHarness.hyundai_q])),
- ],
- CAR.IONIQ_6: [
+ flags=HyundaiFlags.MANDO_RADAR | HyundaiFlags.CHECKSUM_CRC8
+ )
+ SONATA_LF = HyundaiPlatformConfig(
+ "HYUNDAI SONATA 2019",
+ HyundaiCarInfo("Hyundai Sonata 2018-19", car_parts=CarParts.common([CarHarness.hyundai_e])),
+ flags=HyundaiFlags.UNSUPPORTED_LONGITUDINAL | HyundaiFlags.TCU_GEARS
+ )
+ STARIA_4TH_GEN = HyundaiCanFDPlatformConfig(
+ "HYUNDAI STARIA 4TH GEN",
+ HyundaiCarInfo("Hyundai Staria 2023", "All", car_parts=CarParts.common([CarHarness.hyundai_k])),
+ )
+ TUCSON = HyundaiPlatformConfig(
+ "HYUNDAI TUCSON 2019",
+ [
+ HyundaiCarInfo("Hyundai Tucson 2021", min_enable_speed=19 * CV.MPH_TO_MS, car_parts=CarParts.common([CarHarness.hyundai_l])),
+ HyundaiCarInfo("Hyundai Tucson Diesel 2019", car_parts=CarParts.common([CarHarness.hyundai_l])),
+ ],
+ flags=HyundaiFlags.TCU_GEARS
+ )
+ PALISADE = HyundaiPlatformConfig(
+ "HYUNDAI PALISADE 2020",
+ [
+ HyundaiCarInfo("Hyundai Palisade 2020-22", "All", video_link="https://youtu.be/TAnDqjF4fDY?t=456", car_parts=CarParts.common([CarHarness.hyundai_h])),
+ HyundaiCarInfo("Kia Telluride 2020-22", "All", car_parts=CarParts.common([CarHarness.hyundai_h])),
+ ],
+ flags=HyundaiFlags.MANDO_RADAR | HyundaiFlags.CHECKSUM_CRC8
+ )
+ VELOSTER = HyundaiPlatformConfig(
+ "HYUNDAI VELOSTER 2019",
+ HyundaiCarInfo("Hyundai Veloster 2019-20", min_enable_speed=5. * CV.MPH_TO_MS, car_parts=CarParts.common([CarHarness.hyundai_e])),
+ flags=HyundaiFlags.LEGACY | HyundaiFlags.TCU_GEARS
+ )
+ SONATA_HYBRID = HyundaiPlatformConfig(
+ "HYUNDAI SONATA HYBRID 2021",
+ HyundaiCarInfo("Hyundai Sonata Hybrid 2020-23", "All", car_parts=CarParts.common([CarHarness.hyundai_a])),
+ flags=HyundaiFlags.MANDO_RADAR | HyundaiFlags.CHECKSUM_CRC8 | HyundaiFlags.HYBRID
+ )
+ IONIQ_5 = HyundaiCanFDPlatformConfig(
+ "HYUNDAI IONIQ 5 2022",
+ [
+ HyundaiCarInfo("Hyundai Ioniq 5 (Southeast Asia only) 2022-23", "All", car_parts=CarParts.common([CarHarness.hyundai_q])),
+ HyundaiCarInfo("Hyundai Ioniq 5 (without HDA II) 2022-23", "Highway Driving Assist", car_parts=CarParts.common([CarHarness.hyundai_k])),
+ HyundaiCarInfo("Hyundai Ioniq 5 (with HDA II) 2022-23", "Highway Driving Assist II", car_parts=CarParts.common([CarHarness.hyundai_q])),
+ ],
+ flags=HyundaiFlags.EV
+ )
+ IONIQ_6 = HyundaiCanFDPlatformConfig(
+ "HYUNDAI IONIQ 6 2023",
HyundaiCarInfo("Hyundai Ioniq 6 (with HDA II) 2023", "Highway Driving Assist II", car_parts=CarParts.common([CarHarness.hyundai_p])),
- ],
- CAR.TUCSON_4TH_GEN: [
- HyundaiCarInfo("Hyundai Tucson 2022", car_parts=CarParts.common([CarHarness.hyundai_n])),
- HyundaiCarInfo("Hyundai Tucson 2023", "All", car_parts=CarParts.common([CarHarness.hyundai_n])),
- HyundaiCarInfo("Hyundai Tucson Hybrid 2022-24", "All", car_parts=CarParts.common([CarHarness.hyundai_n])),
- ],
- CAR.SANTA_CRUZ_1ST_GEN: HyundaiCarInfo("Hyundai Santa Cruz 2022-23", car_parts=CarParts.common([CarHarness.hyundai_n])),
- CAR.CUSTIN_1ST_GEN: HyundaiCarInfo("Hyundai Custin 2023", "All", car_parts=CarParts.common([CarHarness.hyundai_k])),
+ flags=HyundaiFlags.EV | HyundaiFlags.CANFD_NO_RADAR_DISABLE
+ )
+ TUCSON_4TH_GEN = HyundaiCanFDPlatformConfig(
+ "HYUNDAI TUCSON 4TH GEN",
+ [
+ HyundaiCarInfo("Hyundai Tucson 2022", car_parts=CarParts.common([CarHarness.hyundai_n])),
+ HyundaiCarInfo("Hyundai Tucson 2023", "All", car_parts=CarParts.common([CarHarness.hyundai_n])),
+ HyundaiCarInfo("Hyundai Tucson Hybrid 2022-24", "All", car_parts=CarParts.common([CarHarness.hyundai_n])),
+ ],
+ )
+ SANTA_CRUZ_1ST_GEN = HyundaiCanFDPlatformConfig(
+ "HYUNDAI SANTA CRUZ 1ST GEN",
+ HyundaiCarInfo("Hyundai Santa Cruz 2022-23", car_parts=CarParts.common([CarHarness.hyundai_n])),
+ )
+ CUSTIN_1ST_GEN = HyundaiPlatformConfig(
+ "HYUNDAI CUSTIN 1ST GEN",
+ HyundaiCarInfo("Hyundai Custin 2023", "All", car_parts=CarParts.common([CarHarness.hyundai_k])),
+ flags=HyundaiFlags.CHECKSUM_CRC8
+ )
# Kia
- CAR.KIA_FORTE: [
+ KIA_FORTE = HyundaiPlatformConfig(
+ "KIA FORTE E 2018 & GT 2021",
+ [
HyundaiCarInfo("Kia Forte 2019-21", car_parts=CarParts.common([CarHarness.hyundai_g])),
HyundaiCarInfo("Kia Forte 2023", car_parts=CarParts.common([CarHarness.hyundai_e])),
- ],
- CAR.KIA_K5_2021: HyundaiCarInfo("Kia K5 2021-24", car_parts=CarParts.common([CarHarness.hyundai_a])),
- CAR.KIA_K5_HEV_2020: HyundaiCarInfo("Kia K5 Hybrid 2020-22", car_parts=CarParts.common([CarHarness.hyundai_a])),
- CAR.KIA_K8_HEV_1ST_GEN: HyundaiCarInfo("Kia K8 Hybrid (with HDA II) 2023", "Highway Driving Assist II", car_parts=CarParts.common([CarHarness.hyundai_q])),
- CAR.KIA_NIRO_EV: [
- HyundaiCarInfo("Kia Niro EV 2019", "All", video_link="https://www.youtube.com/watch?v=lT7zcG6ZpGo", car_parts=CarParts.common([CarHarness.hyundai_h])),
- HyundaiCarInfo("Kia Niro EV 2020", "All", video_link="https://www.youtube.com/watch?v=lT7zcG6ZpGo", car_parts=CarParts.common([CarHarness.hyundai_f])),
- HyundaiCarInfo("Kia Niro EV 2021", "All", video_link="https://www.youtube.com/watch?v=lT7zcG6ZpGo", car_parts=CarParts.common([CarHarness.hyundai_c])),
- HyundaiCarInfo("Kia Niro EV 2022", "All", video_link="https://www.youtube.com/watch?v=lT7zcG6ZpGo", car_parts=CarParts.common([CarHarness.hyundai_h])),
- ],
- CAR.KIA_NIRO_EV_2ND_GEN: HyundaiCarInfo("Kia Niro EV 2023", "All", car_parts=CarParts.common([CarHarness.hyundai_a])),
- CAR.KIA_NIRO_PHEV: [
- HyundaiCarInfo("Kia Niro Plug-in Hybrid 2018-19", "All", min_enable_speed=10. * CV.MPH_TO_MS, car_parts=CarParts.common([CarHarness.hyundai_c])),
- HyundaiCarInfo("Kia Niro Plug-in Hybrid 2020", "All", car_parts=CarParts.common([CarHarness.hyundai_d])),
- ],
- CAR.KIA_NIRO_PHEV_2022: [
- HyundaiCarInfo("Kia Niro Plug-in Hybrid 2021", "All", car_parts=CarParts.common([CarHarness.hyundai_d])),
- HyundaiCarInfo("Kia Niro Plug-in Hybrid 2022", "All", car_parts=CarParts.common([CarHarness.hyundai_f])),
- ],
- CAR.KIA_NIRO_HEV_2021: [
- HyundaiCarInfo("Kia Niro Hybrid 2021", car_parts=CarParts.common([CarHarness.hyundai_d])),
- HyundaiCarInfo("Kia Niro Hybrid 2022", car_parts=CarParts.common([CarHarness.hyundai_f])),
- ],
- CAR.KIA_NIRO_HEV_2ND_GEN: HyundaiCarInfo("Kia Niro Hybrid 2023", car_parts=CarParts.common([CarHarness.hyundai_a])),
- CAR.KIA_OPTIMA_G4: HyundaiCarInfo("Kia Optima 2017", "Advanced Smart Cruise Control",
+ ]
+ )
+ KIA_K5_2021 = HyundaiPlatformConfig(
+ "KIA K5 2021",
+ HyundaiCarInfo("Kia K5 2021-24", car_parts=CarParts.common([CarHarness.hyundai_a])),
+ flags=HyundaiFlags.CHECKSUM_CRC8
+ )
+ KIA_K5_HEV_2020 = HyundaiPlatformConfig(
+ "KIA K5 HYBRID 2020",
+ HyundaiCarInfo("Kia K5 Hybrid 2020-22", car_parts=CarParts.common([CarHarness.hyundai_a])),
+ flags=HyundaiFlags.MANDO_RADAR | HyundaiFlags.CHECKSUM_CRC8 | HyundaiFlags.HYBRID
+ )
+ KIA_K8_HEV_1ST_GEN = HyundaiCanFDPlatformConfig(
+ "KIA K8 HYBRID 1ST GEN",
+ HyundaiCarInfo("Kia K8 Hybrid (with HDA II) 2023", "Highway Driving Assist II", car_parts=CarParts.common([CarHarness.hyundai_q])),
+ )
+ KIA_NIRO_EV = HyundaiPlatformConfig(
+ "KIA NIRO EV 2020",
+ [
+ HyundaiCarInfo("Kia Niro EV 2019", "All", video_link="https://www.youtube.com/watch?v=lT7zcG6ZpGo", car_parts=CarParts.common([CarHarness.hyundai_h])),
+ HyundaiCarInfo("Kia Niro EV 2020", "All", video_link="https://www.youtube.com/watch?v=lT7zcG6ZpGo", car_parts=CarParts.common([CarHarness.hyundai_f])),
+ HyundaiCarInfo("Kia Niro EV 2021", "All", video_link="https://www.youtube.com/watch?v=lT7zcG6ZpGo", car_parts=CarParts.common([CarHarness.hyundai_c])),
+ HyundaiCarInfo("Kia Niro EV 2022", "All", video_link="https://www.youtube.com/watch?v=lT7zcG6ZpGo", car_parts=CarParts.common([CarHarness.hyundai_h])),
+ ],
+ flags=HyundaiFlags.MANDO_RADAR | HyundaiFlags.EV
+ )
+ KIA_NIRO_EV_2ND_GEN = HyundaiCanFDPlatformConfig(
+ "KIA NIRO EV 2ND GEN",
+ HyundaiCarInfo("Kia Niro EV 2023", "All", car_parts=CarParts.common([CarHarness.hyundai_a])),
+ flags=HyundaiFlags.EV
+ )
+ KIA_NIRO_PHEV = HyundaiPlatformConfig(
+ "KIA NIRO HYBRID 2019",
+ [
+ HyundaiCarInfo("Kia Niro Plug-in Hybrid 2018-19", "All", min_enable_speed=10. * CV.MPH_TO_MS, car_parts=CarParts.common([CarHarness.hyundai_c])),
+ HyundaiCarInfo("Kia Niro Plug-in Hybrid 2020", "All", car_parts=CarParts.common([CarHarness.hyundai_d])),
+ ],
+ flags=HyundaiFlags.MANDO_RADAR | HyundaiFlags.HYBRID | HyundaiFlags.UNSUPPORTED_LONGITUDINAL
+ )
+ KIA_NIRO_PHEV_2022 = HyundaiPlatformConfig(
+ "KIA NIRO PLUG-IN HYBRID 2022",
+ [
+ HyundaiCarInfo("Kia Niro Plug-in Hybrid 2021", "All", car_parts=CarParts.common([CarHarness.hyundai_d])),
+ HyundaiCarInfo("Kia Niro Plug-in Hybrid 2022", "All", car_parts=CarParts.common([CarHarness.hyundai_f])),
+ ],
+ flags=HyundaiFlags.HYBRID | HyundaiFlags.MANDO_RADAR
+ )
+ KIA_NIRO_HEV_2021 = HyundaiPlatformConfig(
+ "KIA NIRO HYBRID 2021",
+ [
+ HyundaiCarInfo("Kia Niro Hybrid 2021", car_parts=CarParts.common([CarHarness.hyundai_d])),
+ HyundaiCarInfo("Kia Niro Hybrid 2022", car_parts=CarParts.common([CarHarness.hyundai_f])),
+ ],
+ flags=HyundaiFlags.HYBRID
+ )
+ KIA_NIRO_HEV_2ND_GEN = HyundaiCanFDPlatformConfig(
+ "KIA NIRO HYBRID 2ND GEN",
+ HyundaiCarInfo("Kia Niro Hybrid 2023", car_parts=CarParts.common([CarHarness.hyundai_a])),
+ )
+ KIA_OPTIMA_G4 = HyundaiPlatformConfig(
+ "KIA OPTIMA 4TH GEN",
+ HyundaiCarInfo("Kia Optima 2017", "Advanced Smart Cruise Control",
car_parts=CarParts.common([CarHarness.hyundai_b])), # TODO: may support 2016, 2018
- CAR.KIA_OPTIMA_G4_FL: HyundaiCarInfo("Kia Optima 2019-20", car_parts=CarParts.common([CarHarness.hyundai_g])),
+ flags=HyundaiFlags.LEGACY | HyundaiFlags.TCU_GEARS
+ )
+ KIA_OPTIMA_G4_FL = HyundaiPlatformConfig(
+ "KIA OPTIMA 4TH GEN FACELIFT",
+ HyundaiCarInfo("Kia Optima 2019-20", car_parts=CarParts.common([CarHarness.hyundai_g])),
+ flags=HyundaiFlags.UNSUPPORTED_LONGITUDINAL | HyundaiFlags.TCU_GEARS
+ )
# TODO: may support adjacent years. may have a non-zero minimum steering speed
- CAR.KIA_OPTIMA_H: HyundaiCarInfo("Kia Optima Hybrid 2017", "Advanced Smart Cruise Control", car_parts=CarParts.common([CarHarness.hyundai_c])),
- CAR.KIA_OPTIMA_H_G4_FL: HyundaiCarInfo("Kia Optima Hybrid 2019", car_parts=CarParts.common([CarHarness.hyundai_h])),
- CAR.KIA_SELTOS: HyundaiCarInfo("Kia Seltos 2021", car_parts=CarParts.common([CarHarness.hyundai_a])),
- CAR.KIA_SPORTAGE_5TH_GEN: [
- HyundaiCarInfo("Kia Sportage 2023", car_parts=CarParts.common([CarHarness.hyundai_n])),
- HyundaiCarInfo("Kia Sportage Hybrid 2023", car_parts=CarParts.common([CarHarness.hyundai_n])),
- ],
- CAR.KIA_SORENTO: [
- HyundaiCarInfo("Kia Sorento 2018", "Advanced Smart Cruise Control & LKAS", video_link="https://www.youtube.com/watch?v=Fkh3s6WHJz8",
+ KIA_OPTIMA_H = HyundaiPlatformConfig(
+ "KIA OPTIMA HYBRID 2017 & SPORTS 2019",
+ HyundaiCarInfo("Kia Optima Hybrid 2017", "Advanced Smart Cruise Control", car_parts=CarParts.common([CarHarness.hyundai_c])),
+ flags=HyundaiFlags.HYBRID | HyundaiFlags.LEGACY
+ )
+ KIA_OPTIMA_H_G4_FL = HyundaiPlatformConfig(
+ "KIA OPTIMA HYBRID 4TH GEN FACELIFT",
+ HyundaiCarInfo("Kia Optima Hybrid 2019", car_parts=CarParts.common([CarHarness.hyundai_h])),
+ flags=HyundaiFlags.HYBRID | HyundaiFlags.UNSUPPORTED_LONGITUDINAL
+ )
+ KIA_SELTOS = HyundaiPlatformConfig(
+ "KIA SELTOS 2021",
+ HyundaiCarInfo("Kia Seltos 2021", car_parts=CarParts.common([CarHarness.hyundai_a])),
+ flags=HyundaiFlags.CHECKSUM_CRC8
+ )
+ KIA_SPORTAGE_5TH_GEN = HyundaiCanFDPlatformConfig(
+ "KIA SPORTAGE 5TH GEN",
+ [
+ HyundaiCarInfo("Kia Sportage 2023", car_parts=CarParts.common([CarHarness.hyundai_n])),
+ HyundaiCarInfo("Kia Sportage Hybrid 2023", car_parts=CarParts.common([CarHarness.hyundai_n])),
+ ],
+ )
+ KIA_SORENTO = HyundaiPlatformConfig(
+ "KIA SORENTO GT LINE 2018",
+ [
+ HyundaiCarInfo("Kia Sorento 2018", "Advanced Smart Cruise Control & LKAS", video_link="https://www.youtube.com/watch?v=Fkh3s6WHJz8",
car_parts=CarParts.common([CarHarness.hyundai_e])),
- HyundaiCarInfo("Kia Sorento 2019", video_link="https://www.youtube.com/watch?v=Fkh3s6WHJz8", car_parts=CarParts.common([CarHarness.hyundai_e])),
- ],
- CAR.KIA_SORENTO_4TH_GEN: HyundaiCarInfo("Kia Sorento 2021-23", car_parts=CarParts.common([CarHarness.hyundai_k])),
- CAR.KIA_SORENTO_HEV_4TH_GEN: [
- HyundaiCarInfo("Kia Sorento Hybrid 2021-23", "All", car_parts=CarParts.common([CarHarness.hyundai_a])),
- HyundaiCarInfo("Kia Sorento Plug-in Hybrid 2022-23", "All", car_parts=CarParts.common([CarHarness.hyundai_a])),
- ],
- CAR.KIA_STINGER: HyundaiCarInfo("Kia Stinger 2018-20", video_link="https://www.youtube.com/watch?v=MJ94qoofYw0",
- car_parts=CarParts.common([CarHarness.hyundai_c])),
- CAR.KIA_STINGER_2022: HyundaiCarInfo("Kia Stinger 2022-23", "All", car_parts=CarParts.common([CarHarness.hyundai_k])),
- CAR.KIA_CEED: HyundaiCarInfo("Kia Ceed 2019", car_parts=CarParts.common([CarHarness.hyundai_e])),
- CAR.KIA_EV6: [
- HyundaiCarInfo("Kia EV6 (Southeast Asia only) 2022-23", "All", car_parts=CarParts.common([CarHarness.hyundai_p])),
- HyundaiCarInfo("Kia EV6 (without HDA II) 2022-23", "Highway Driving Assist", car_parts=CarParts.common([CarHarness.hyundai_l])),
- HyundaiCarInfo("Kia EV6 (with HDA II) 2022-23", "Highway Driving Assist II", car_parts=CarParts.common([CarHarness.hyundai_p]))
- ],
- CAR.KIA_CARNIVAL_4TH_GEN: [
- HyundaiCarInfo("Kia Carnival 2022-24", car_parts=CarParts.common([CarHarness.hyundai_a])),
- HyundaiCarInfo("Kia Carnival (China only) 2023", car_parts=CarParts.common([CarHarness.hyundai_k]))
- ],
+ HyundaiCarInfo("Kia Sorento 2019", video_link="https://www.youtube.com/watch?v=Fkh3s6WHJz8", car_parts=CarParts.common([CarHarness.hyundai_e])),
+ ],
+ flags=HyundaiFlags.CHECKSUM_6B | HyundaiFlags.UNSUPPORTED_LONGITUDINAL
+ )
+ KIA_SORENTO_4TH_GEN = HyundaiCanFDPlatformConfig(
+ "KIA SORENTO 4TH GEN",
+ HyundaiCarInfo("Kia Sorento 2021-23", car_parts=CarParts.common([CarHarness.hyundai_k])),
+ flags=HyundaiFlags.RADAR_SCC
+ )
+ KIA_SORENTO_HEV_4TH_GEN = HyundaiCanFDPlatformConfig(
+ "KIA SORENTO HYBRID 4TH GEN",
+ [
+ HyundaiCarInfo("Kia Sorento Hybrid 2021-23", "All", car_parts=CarParts.common([CarHarness.hyundai_a])),
+ HyundaiCarInfo("Kia Sorento Plug-in Hybrid 2022-23", "All", car_parts=CarParts.common([CarHarness.hyundai_a])),
+ ],
+ flags=HyundaiFlags.RADAR_SCC
+ )
+ KIA_STINGER = HyundaiPlatformConfig(
+ "KIA STINGER GT2 2018",
+ HyundaiCarInfo("Kia Stinger 2018-20", video_link="https://www.youtube.com/watch?v=MJ94qoofYw0",
+ car_parts=CarParts.common([CarHarness.hyundai_c]))
+ )
+ KIA_STINGER_2022 = HyundaiPlatformConfig(
+ "KIA STINGER 2022",
+ HyundaiCarInfo("Kia Stinger 2022-23", "All", car_parts=CarParts.common([CarHarness.hyundai_k])),
+ )
+ KIA_CEED = HyundaiPlatformConfig(
+ "KIA CEED INTRO ED 2019",
+ HyundaiCarInfo("Kia Ceed 2019", car_parts=CarParts.common([CarHarness.hyundai_e])),
+ flags=HyundaiFlags.LEGACY
+ )
+ KIA_EV6 = HyundaiCanFDPlatformConfig(
+ "KIA EV6 2022",
+ [
+ HyundaiCarInfo("Kia EV6 (Southeast Asia only) 2022-23", "All", car_parts=CarParts.common([CarHarness.hyundai_p])),
+ HyundaiCarInfo("Kia EV6 (without HDA II) 2022-23", "Highway Driving Assist", car_parts=CarParts.common([CarHarness.hyundai_l])),
+ HyundaiCarInfo("Kia EV6 (with HDA II) 2022-23", "Highway Driving Assist II", car_parts=CarParts.common([CarHarness.hyundai_p]))
+ ],
+ flags=HyundaiFlags.EV
+ )
+ KIA_CARNIVAL_4TH_GEN = HyundaiCanFDPlatformConfig(
+ "KIA CARNIVAL 4TH GEN",
+ [
+ HyundaiCarInfo("Kia Carnival 2022-24", car_parts=CarParts.common([CarHarness.hyundai_a])),
+ HyundaiCarInfo("Kia Carnival (China only) 2023", car_parts=CarParts.common([CarHarness.hyundai_k]))
+ ],
+ flags=HyundaiFlags.RADAR_SCC
+ )
# Genesis
- CAR.GENESIS_GV60_EV_1ST_GEN: [
- HyundaiCarInfo("Genesis GV60 (Advanced Trim) 2023", "All", car_parts=CarParts.common([CarHarness.hyundai_a])),
- HyundaiCarInfo("Genesis GV60 (Performance Trim) 2023", "All", car_parts=CarParts.common([CarHarness.hyundai_k])),
- ],
- CAR.GENESIS_G70: HyundaiCarInfo("Genesis G70 2018-19", "All", car_parts=CarParts.common([CarHarness.hyundai_f])),
- CAR.GENESIS_G70_2020: HyundaiCarInfo("Genesis G70 2020", "All", car_parts=CarParts.common([CarHarness.hyundai_f])),
- CAR.GENESIS_GV70_1ST_GEN: [
- HyundaiCarInfo("Genesis GV70 (2.5T Trim) 2022-23", "All", car_parts=CarParts.common([CarHarness.hyundai_l])),
- HyundaiCarInfo("Genesis GV70 (3.5T Trim) 2022-23", "All", car_parts=CarParts.common([CarHarness.hyundai_m])),
- ],
- CAR.GENESIS_G80: HyundaiCarInfo("Genesis G80 2018-19", "All", car_parts=CarParts.common([CarHarness.hyundai_h])),
- CAR.GENESIS_G90: HyundaiCarInfo("Genesis G90 2017-18", "All", car_parts=CarParts.common([CarHarness.hyundai_c])),
- CAR.GENESIS_GV80: HyundaiCarInfo("Genesis GV80 2023", "All", car_parts=CarParts.common([CarHarness.hyundai_m])),
-}
+ GENESIS_GV60_EV_1ST_GEN = HyundaiCanFDPlatformConfig(
+ "GENESIS GV60 ELECTRIC 1ST GEN",
+ [
+ HyundaiCarInfo("Genesis GV60 (Advanced Trim) 2023", "All", car_parts=CarParts.common([CarHarness.hyundai_a])),
+ HyundaiCarInfo("Genesis GV60 (Performance Trim) 2023", "All", car_parts=CarParts.common([CarHarness.hyundai_k])),
+ ],
+ flags=HyundaiFlags.EV
+ )
+ GENESIS_G70 = HyundaiPlatformConfig(
+ "GENESIS G70 2018",
+ HyundaiCarInfo("Genesis G70 2018-19", "All", car_parts=CarParts.common([CarHarness.hyundai_f])),
+ flags=HyundaiFlags.LEGACY
+ )
+ GENESIS_G70_2020 = HyundaiPlatformConfig(
+ "GENESIS G70 2020",
+ HyundaiCarInfo("Genesis G70 2020", "All", car_parts=CarParts.common([CarHarness.hyundai_f])),
+ flags=HyundaiFlags.MANDO_RADAR
+ )
+ GENESIS_GV70_1ST_GEN = HyundaiCanFDPlatformConfig(
+ "GENESIS GV70 1ST GEN",
+ [
+ HyundaiCarInfo("Genesis GV70 (2.5T Trim) 2022-23", "All", car_parts=CarParts.common([CarHarness.hyundai_l])),
+ HyundaiCarInfo("Genesis GV70 (3.5T Trim) 2022-23", "All", car_parts=CarParts.common([CarHarness.hyundai_m])),
+ ],
+ flags=HyundaiFlags.RADAR_SCC
+ )
+ GENESIS_G80 = HyundaiPlatformConfig(
+ "GENESIS G80 2017",
+ HyundaiCarInfo("Genesis G80 2018-19", "All", car_parts=CarParts.common([CarHarness.hyundai_h])),
+ flags=HyundaiFlags.LEGACY
+ )
+ GENESIS_G90 = HyundaiPlatformConfig(
+ "GENESIS G90 2017",
+ HyundaiCarInfo("Genesis G90 2017-18", "All", car_parts=CarParts.common([CarHarness.hyundai_c])),
+ )
+ GENESIS_GV80 = HyundaiCanFDPlatformConfig(
+ "GENESIS GV80 2023",
+ HyundaiCarInfo("Genesis GV80 2023", "All", car_parts=CarParts.common([CarHarness.hyundai_m])),
+ flags=HyundaiFlags.RADAR_SCC
+ )
+
class Buttons:
NONE = 0
@@ -518,118 +737,37 @@ FW_QUERY_CONFIG = FwQueryConfig(
match_fw_to_car_fuzzy=match_fw_to_car_fuzzy,
)
-
CHECKSUM = {
- "crc8": [CAR.SANTA_FE, CAR.SONATA, CAR.PALISADE, CAR.KIA_SELTOS, CAR.ELANTRA_2021, CAR.ELANTRA_HEV_2021,
- CAR.SONATA_HYBRID, CAR.SANTA_FE_2022, CAR.KIA_K5_2021, CAR.SANTA_FE_HEV_2022, CAR.SANTA_FE_PHEV_2022,
- CAR.KIA_K5_HEV_2020, CAR.CUSTIN_1ST_GEN],
- "6B": [CAR.KIA_SORENTO, CAR.HYUNDAI_GENESIS],
+ "crc8": CAR.with_flags(HyundaiFlags.CHECKSUM_CRC8),
+ "6B": CAR.with_flags(HyundaiFlags.CHECKSUM_6B),
}
CAN_GEARS = {
# which message has the gear. hybrid and EV use ELECT_GEAR
- "use_cluster_gears": {CAR.ELANTRA, CAR.ELANTRA_GT_I30, CAR.KONA},
- "use_tcu_gears": {CAR.KIA_OPTIMA_G4, CAR.KIA_OPTIMA_G4_FL, CAR.SONATA_LF, CAR.VELOSTER, CAR.TUCSON},
+ "use_cluster_gears": CAR.with_flags(HyundaiFlags.CLUSTER_GEARS),
+ "use_tcu_gears": CAR.with_flags(HyundaiFlags.TCU_GEARS),
}
-CANFD_CAR = {CAR.KIA_EV6, CAR.IONIQ_5, CAR.IONIQ_6, CAR.TUCSON_4TH_GEN, CAR.SANTA_CRUZ_1ST_GEN, CAR.KIA_SPORTAGE_5TH_GEN, CAR.GENESIS_GV70_1ST_GEN,
- CAR.GENESIS_GV60_EV_1ST_GEN, CAR.KIA_SORENTO_4TH_GEN, CAR.KIA_NIRO_HEV_2ND_GEN, CAR.KIA_NIRO_EV_2ND_GEN,
- CAR.GENESIS_GV80, CAR.KIA_CARNIVAL_4TH_GEN, CAR.KIA_SORENTO_HEV_4TH_GEN, CAR.KONA_EV_2ND_GEN, CAR.KIA_K8_HEV_1ST_GEN,
- CAR.STARIA_4TH_GEN}
-
-# The radar does SCC on these cars when HDA I, rather than the camera
-CANFD_RADAR_SCC_CAR = {CAR.GENESIS_GV70_1ST_GEN, CAR.KIA_SORENTO_4TH_GEN, CAR.GENESIS_GV80, CAR.KIA_CARNIVAL_4TH_GEN, CAR.KIA_SORENTO_HEV_4TH_GEN}
+CANFD_CAR = CAR.with_flags(HyundaiFlags.CANFD)
+CANFD_RADAR_SCC_CAR = CAR.with_flags(HyundaiFlags.RADAR_SCC)
# 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.IONIQ_6, CAR.KONA_EV_2ND_GEN}
+CANFD_UNSUPPORTED_LONGITUDINAL_CAR = CAR.with_flags(HyundaiFlags.CANFD_NO_RADAR_DISABLE)
# The camera does SCC on these cars, rather than the radar
-CAMERA_SCC_CAR = {CAR.KONA_EV_2022, }
-
-# these cars use a different gas signal
-HYBRID_CAR = {CAR.IONIQ_PHEV, CAR.ELANTRA_HEV_2021, CAR.KIA_NIRO_PHEV, CAR.KIA_NIRO_HEV_2021, CAR.SONATA_HYBRID, CAR.KONA_HEV, CAR.IONIQ,
- CAR.IONIQ_HEV_2022, CAR.SANTA_FE_HEV_2022, CAR.SANTA_FE_PHEV_2022, CAR.IONIQ_PHEV_2019, CAR.KIA_K5_HEV_2020,
- CAR.KIA_OPTIMA_H, CAR.KIA_OPTIMA_H_G4_FL, CAR.AZERA_HEV_6TH_GEN, CAR.KIA_NIRO_PHEV_2022}
-
-EV_CAR = {CAR.IONIQ_EV_2020, CAR.IONIQ_EV_LTD, CAR.KONA_EV, CAR.KIA_NIRO_EV, CAR.KIA_NIRO_EV_2ND_GEN, CAR.KONA_EV_2022,
- CAR.KIA_EV6, CAR.IONIQ_5, CAR.IONIQ_6, CAR.GENESIS_GV60_EV_1ST_GEN, CAR.KONA_EV_2ND_GEN}
-
-# these cars require a special panda safety mode due to missing counters and checksums in the messages
-LEGACY_SAFETY_MODE_CAR = {CAR.HYUNDAI_GENESIS, CAR.IONIQ_EV_LTD, CAR.KIA_OPTIMA_G4,
- CAR.VELOSTER, CAR.GENESIS_G70, CAR.GENESIS_G80, CAR.KIA_CEED, CAR.ELANTRA, CAR.IONIQ_HEV_2022,
- CAR.KIA_OPTIMA_H, CAR.ELANTRA_GT_I30}
-
-# these cars have not been verified to work with longitudinal yet - radar disable, sending correct messages, etc.
-UNSUPPORTED_LONGITUDINAL_CAR = LEGACY_SAFETY_MODE_CAR | {CAR.KIA_NIRO_PHEV, CAR.KIA_SORENTO, CAR.SONATA_LF, CAR.KIA_OPTIMA_G4_FL,
- CAR.KIA_OPTIMA_H_G4_FL}
-
-# If 0x500 is present on bus 1 it probably has a Mando radar outputting radar points.
-# If no points are outputted by default it might be possible to turn it on using selfdrive/debug/hyundai_enable_radar_points.py
-DBC = {
- CAR.AZERA_6TH_GEN: dbc_dict('hyundai_kia_generic', None),
- CAR.AZERA_HEV_6TH_GEN: dbc_dict('hyundai_kia_generic', None),
- CAR.ELANTRA: dbc_dict('hyundai_kia_generic', None),
- CAR.ELANTRA_GT_I30: dbc_dict('hyundai_kia_generic', None),
- CAR.ELANTRA_2021: dbc_dict('hyundai_kia_generic', None),
- CAR.ELANTRA_HEV_2021: dbc_dict('hyundai_kia_generic', None),
- CAR.GENESIS_G70: dbc_dict('hyundai_kia_generic', None),
- CAR.GENESIS_G70_2020: dbc_dict('hyundai_kia_generic', 'hyundai_kia_mando_front_radar_generated'),
- CAR.GENESIS_G80: dbc_dict('hyundai_kia_generic', None),
- CAR.GENESIS_G90: dbc_dict('hyundai_kia_generic', None),
- CAR.HYUNDAI_GENESIS: dbc_dict('hyundai_kia_generic', None),
- CAR.IONIQ_PHEV_2019: dbc_dict('hyundai_kia_generic', None),
- CAR.IONIQ_PHEV: dbc_dict('hyundai_kia_generic', None),
- CAR.IONIQ_EV_2020: dbc_dict('hyundai_kia_generic', None),
- CAR.IONIQ_EV_LTD: dbc_dict('hyundai_kia_generic', 'hyundai_kia_mando_front_radar_generated'),
- CAR.IONIQ: dbc_dict('hyundai_kia_generic', None),
- CAR.IONIQ_HEV_2022: dbc_dict('hyundai_kia_generic', None),
- CAR.KIA_FORTE: dbc_dict('hyundai_kia_generic', None),
- CAR.KIA_K5_2021: dbc_dict('hyundai_kia_generic', None),
- CAR.KIA_K5_HEV_2020: dbc_dict('hyundai_kia_generic', 'hyundai_kia_mando_front_radar_generated'),
- CAR.KIA_NIRO_EV: dbc_dict('hyundai_kia_generic', 'hyundai_kia_mando_front_radar_generated'),
- CAR.KIA_NIRO_PHEV: dbc_dict('hyundai_kia_generic', 'hyundai_kia_mando_front_radar_generated'),
- CAR.KIA_NIRO_HEV_2021: dbc_dict('hyundai_kia_generic', None),
- CAR.KIA_OPTIMA_G4: dbc_dict('hyundai_kia_generic', None),
- CAR.KIA_OPTIMA_G4_FL: dbc_dict('hyundai_kia_generic', None),
- CAR.KIA_OPTIMA_H: dbc_dict('hyundai_kia_generic', None),
- CAR.KIA_OPTIMA_H_G4_FL: dbc_dict('hyundai_kia_generic', None),
- CAR.KIA_SELTOS: dbc_dict('hyundai_kia_generic', None),
- CAR.KIA_SORENTO: dbc_dict('hyundai_kia_generic', None), # Has 0x5XX messages, but different format
- CAR.KIA_STINGER: dbc_dict('hyundai_kia_generic', None),
- CAR.KIA_STINGER_2022: dbc_dict('hyundai_kia_generic', None),
- CAR.KONA: dbc_dict('hyundai_kia_generic', None),
- CAR.KONA_EV: dbc_dict('hyundai_kia_generic', None),
- CAR.KONA_EV_2022: dbc_dict('hyundai_kia_generic', None),
- CAR.KONA_HEV: dbc_dict('hyundai_kia_generic', None),
- CAR.SANTA_FE: dbc_dict('hyundai_kia_generic', 'hyundai_kia_mando_front_radar_generated'),
- CAR.SANTA_FE_2022: dbc_dict('hyundai_kia_generic', None),
- CAR.SANTA_FE_HEV_2022: dbc_dict('hyundai_kia_generic', None),
- CAR.SANTA_FE_PHEV_2022: dbc_dict('hyundai_kia_generic', None),
- CAR.SONATA: dbc_dict('hyundai_kia_generic', 'hyundai_kia_mando_front_radar_generated'),
- CAR.SONATA_LF: dbc_dict('hyundai_kia_generic', None), # Has 0x5XX messages, but different format
- CAR.TUCSON: dbc_dict('hyundai_kia_generic', None),
- CAR.PALISADE: dbc_dict('hyundai_kia_generic', 'hyundai_kia_mando_front_radar_generated'),
- CAR.VELOSTER: dbc_dict('hyundai_kia_generic', None),
- CAR.KIA_CEED: dbc_dict('hyundai_kia_generic', None),
- CAR.KIA_EV6: dbc_dict('hyundai_canfd', None),
- CAR.SONATA_HYBRID: dbc_dict('hyundai_kia_generic', 'hyundai_kia_mando_front_radar_generated'),
- CAR.TUCSON_4TH_GEN: dbc_dict('hyundai_canfd', None),
- CAR.IONIQ_5: dbc_dict('hyundai_canfd', None),
- CAR.IONIQ_6: dbc_dict('hyundai_canfd', None),
- CAR.SANTA_CRUZ_1ST_GEN: dbc_dict('hyundai_canfd', None),
- CAR.KIA_SPORTAGE_5TH_GEN: dbc_dict('hyundai_canfd', None),
- CAR.GENESIS_GV70_1ST_GEN: dbc_dict('hyundai_canfd', None),
- CAR.GENESIS_GV60_EV_1ST_GEN: dbc_dict('hyundai_canfd', None),
- CAR.KIA_SORENTO_4TH_GEN: dbc_dict('hyundai_canfd', None),
- CAR.KIA_NIRO_HEV_2ND_GEN: dbc_dict('hyundai_canfd', None),
- CAR.KIA_NIRO_EV_2ND_GEN: dbc_dict('hyundai_canfd', None),
- CAR.GENESIS_GV80: dbc_dict('hyundai_canfd', None),
- CAR.KIA_CARNIVAL_4TH_GEN: dbc_dict('hyundai_canfd', None),
- CAR.KIA_SORENTO_HEV_4TH_GEN: dbc_dict('hyundai_canfd', None),
- CAR.KONA_EV_2ND_GEN: dbc_dict('hyundai_canfd', None),
- CAR.KIA_K8_HEV_1ST_GEN: dbc_dict('hyundai_canfd', None),
- CAR.CUSTIN_1ST_GEN: dbc_dict('hyundai_kia_generic', None),
- CAR.KIA_NIRO_PHEV_2022: dbc_dict('hyundai_kia_generic', 'hyundai_kia_mando_front_radar_generated'),
- CAR.STARIA_4TH_GEN: dbc_dict('hyundai_canfd', None),
-}
+CAMERA_SCC_CAR = CAR.with_flags(HyundaiFlags.CAMERA_SCC)
+
+HYBRID_CAR = CAR.with_flags(HyundaiFlags.HYBRID)
+
+EV_CAR = CAR.with_flags(HyundaiFlags.EV)
+
+LEGACY_SAFETY_MODE_CAR = CAR.with_flags(HyundaiFlags.LEGACY)
+
+UNSUPPORTED_LONGITUDINAL_CAR = CAR.with_flags(HyundaiFlags.LEGACY) | CAR.with_flags(HyundaiFlags.UNSUPPORTED_LONGITUDINAL)
+
+CAR_INFO = CAR.create_carinfo_map()
+DBC = CAR.create_dbc_map()
+
+if __name__ == "__main__":
+ CAR.print_debug(HyundaiFlags)
diff --git a/selfdrive/car/mazda/carcontroller.py b/selfdrive/car/mazda/carcontroller.py
index 3f3b7a9494..8d3a59b4ea 100644
--- a/selfdrive/car/mazda/carcontroller.py
+++ b/selfdrive/car/mazda/carcontroller.py
@@ -36,13 +36,13 @@ class CarController(CarControllerBase):
if self.frame % 10 == 0 and not (CS.out.brakePressed and self.brake_counter < 7):
# Cancel Stock ACC if it's enabled while OP is disengaged
# Send at a rate of 10hz until we sync with stock ACC state
- can_sends.append(mazdacan.create_button_cmd(self.packer, self.CP.carFingerprint, CS.crz_btns_counter, Buttons.CANCEL))
+ can_sends.append(mazdacan.create_button_cmd(self.packer, self.CP, CS.crz_btns_counter, Buttons.CANCEL))
else:
self.brake_counter = 0
if CC.cruiseControl.resume and self.frame % 5 == 0:
# Mazda Stop and Go requires a RES button (or gas) press if the car stops more than 3 seconds
# Send Resume button when planner wants car to move
- can_sends.append(mazdacan.create_button_cmd(self.packer, self.CP.carFingerprint, CS.crz_btns_counter, Buttons.RESUME))
+ can_sends.append(mazdacan.create_button_cmd(self.packer, self.CP, CS.crz_btns_counter, Buttons.RESUME))
self.apply_steer_last = apply_steer
@@ -55,7 +55,7 @@ class CarController(CarControllerBase):
can_sends.append(mazdacan.create_alert_command(self.packer, CS.cam_laneinfo, ldw, steer_required))
# send steering command
- can_sends.append(mazdacan.create_steering_control(self.packer, self.CP.carFingerprint,
+ can_sends.append(mazdacan.create_steering_control(self.packer, self.CP,
self.frame, apply_steer, CS.cam_lkas))
new_actuators = CC.actuators.copy()
diff --git a/selfdrive/car/mazda/carstate.py b/selfdrive/car/mazda/carstate.py
index c0819592d4..37a67ecd93 100644
--- a/selfdrive/car/mazda/carstate.py
+++ b/selfdrive/car/mazda/carstate.py
@@ -3,7 +3,7 @@ from openpilot.common.conversions import Conversions as CV
from opendbc.can.can_define import CANDefine
from opendbc.can.parser import CANParser
from openpilot.selfdrive.car.interfaces import CarStateBase
-from openpilot.selfdrive.car.mazda.values import DBC, LKAS_LIMITS, GEN1
+from openpilot.selfdrive.car.mazda.values import DBC, LKAS_LIMITS, MazdaFlags
class CarState(CarStateBase):
def __init__(self, CP):
@@ -116,7 +116,7 @@ class CarState(CarStateBase):
("WHEEL_SPEEDS", 100),
]
- if CP.carFingerprint in GEN1:
+ if CP.flags & MazdaFlags.GEN1:
messages += [
("ENGINE_DATA", 100),
("CRZ_CTRL", 50),
@@ -136,7 +136,7 @@ class CarState(CarStateBase):
def get_cam_can_parser(CP):
messages = []
- if CP.carFingerprint in GEN1:
+ if CP.flags & MazdaFlags.GEN1:
messages += [
# sig_address, frequency
("CAM_LANEINFO", 2),
diff --git a/selfdrive/car/mazda/interface.py b/selfdrive/car/mazda/interface.py
index 7ac93d9dee..a138318b1a 100755
--- a/selfdrive/car/mazda/interface.py
+++ b/selfdrive/car/mazda/interface.py
@@ -24,23 +24,6 @@ class CarInterface(CarInterfaceBase):
CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning)
- if candidate in (CAR.CX5, CAR.CX5_2022):
- ret.mass = 3655 * CV.LB_TO_KG
- ret.wheelbase = 2.7
- ret.steerRatio = 15.5
- elif candidate in (CAR.CX9, CAR.CX9_2021):
- ret.mass = 4217 * CV.LB_TO_KG
- ret.wheelbase = 3.1
- ret.steerRatio = 17.6
- elif candidate == CAR.MAZDA3:
- ret.mass = 2875 * CV.LB_TO_KG
- ret.wheelbase = 2.7
- ret.steerRatio = 14.0
- elif candidate == CAR.MAZDA6:
- ret.mass = 3443 * CV.LB_TO_KG
- ret.wheelbase = 2.83
- ret.steerRatio = 15.5
-
if candidate not in (CAR.CX5_2022, ):
ret.minSteerSpeed = LKAS_LIMITS.DISABLE_SPEED * CV.KPH_TO_MS
diff --git a/selfdrive/car/mazda/mazdacan.py b/selfdrive/car/mazda/mazdacan.py
index e350c5587f..74f6af04c5 100644
--- a/selfdrive/car/mazda/mazdacan.py
+++ b/selfdrive/car/mazda/mazdacan.py
@@ -1,7 +1,7 @@
-from openpilot.selfdrive.car.mazda.values import GEN1, Buttons
+from openpilot.selfdrive.car.mazda.values import Buttons, MazdaFlags
-def create_steering_control(packer, car_fingerprint, frame, apply_steer, lkas):
+def create_steering_control(packer, CP, frame, apply_steer, lkas):
tmp = apply_steer + 2048
@@ -45,7 +45,7 @@ def create_steering_control(packer, car_fingerprint, frame, apply_steer, lkas):
csum = csum % 256
values = {}
- if car_fingerprint in GEN1:
+ if CP.flags & MazdaFlags.GEN1:
values = {
"LKAS_REQUEST": apply_steer,
"CTR": ctr,
@@ -88,12 +88,12 @@ def create_alert_command(packer, cam_msg: dict, ldw: bool, steer_required: bool)
return packer.make_can_msg("CAM_LANEINFO", 0, values)
-def create_button_cmd(packer, car_fingerprint, counter, button):
+def create_button_cmd(packer, CP, counter, button):
can = int(button == Buttons.CANCEL)
res = int(button == Buttons.RESUME)
- if car_fingerprint in GEN1:
+ if CP.flags & MazdaFlags.GEN1:
values = {
"CAN_OFF": can,
"CAN_OFF_INV": (can + 1) % 2,
diff --git a/selfdrive/car/mazda/values.py b/selfdrive/car/mazda/values.py
index eaf76d6a72..5597e9f52f 100644
--- a/selfdrive/car/mazda/values.py
+++ b/selfdrive/car/mazda/values.py
@@ -1,8 +1,9 @@
from dataclasses import dataclass, field
-from enum import StrEnum
+from enum import IntFlag
from cereal import car
-from openpilot.selfdrive.car import dbc_dict
+from openpilot.common.conversions import Conversions as CV
+from openpilot.selfdrive.car import CarSpecs, DbcDict, PlatformConfig, Platforms, dbc_dict
from openpilot.selfdrive.car.docs_definitions import CarHarness, CarInfo, CarParts
from openpilot.selfdrive.car.fw_query_definitions import FwQueryConfig, Request, StdQueries
@@ -25,29 +26,55 @@ class CarControllerParams:
pass
-class CAR(StrEnum):
- CX5 = "MAZDA CX-5"
- CX9 = "MAZDA CX-9"
- MAZDA3 = "MAZDA 3"
- MAZDA6 = "MAZDA 6"
- CX9_2021 = "MAZDA CX-9 2021"
- CX5_2022 = "MAZDA CX-5 2022"
-
-
@dataclass
class MazdaCarInfo(CarInfo):
package: str = "All"
car_parts: CarParts = field(default_factory=CarParts.common([CarHarness.mazda]))
-CAR_INFO: dict[str, MazdaCarInfo | list[MazdaCarInfo]] = {
- CAR.CX5: MazdaCarInfo("Mazda CX-5 2017-21"),
- CAR.CX9: MazdaCarInfo("Mazda CX-9 2016-20"),
- CAR.MAZDA3: MazdaCarInfo("Mazda 3 2017-18"),
- CAR.MAZDA6: MazdaCarInfo("Mazda 6 2017-20"),
- CAR.CX9_2021: MazdaCarInfo("Mazda CX-9 2021-23", video_link="https://youtu.be/dA3duO4a0O4"),
- CAR.CX5_2022: MazdaCarInfo("Mazda CX-5 2022-24"),
-}
+class MazdaFlags(IntFlag):
+ # Static flags
+ # Gen 1 hardware: same CAN messages and same camera
+ GEN1 = 1
+
+
+@dataclass
+class MazdaPlatformConfig(PlatformConfig):
+ dbc_dict: DbcDict = field(default_factory=lambda: dbc_dict('mazda_2017', None))
+ flags: int = MazdaFlags.GEN1
+
+
+class CAR(Platforms):
+ CX5 = MazdaPlatformConfig(
+ "MAZDA CX-5",
+ MazdaCarInfo("Mazda CX-5 2017-21"),
+ specs=CarSpecs(mass=3655 * CV.LB_TO_KG, wheelbase=2.7, steerRatio=15.5)
+ )
+ CX9 = MazdaPlatformConfig(
+ "MAZDA CX-9",
+ MazdaCarInfo("Mazda CX-9 2016-20"),
+ specs=CarSpecs(mass=4217 * CV.LB_TO_KG, wheelbase=3.1, steerRatio=17.6)
+ )
+ MAZDA3 = MazdaPlatformConfig(
+ "MAZDA 3",
+ MazdaCarInfo("Mazda 3 2017-18"),
+ specs=CarSpecs(mass=2875 * CV.LB_TO_KG, wheelbase=2.7, steerRatio=14.0)
+ )
+ MAZDA6 = MazdaPlatformConfig(
+ "MAZDA 6",
+ MazdaCarInfo("Mazda 6 2017-20"),
+ specs=CarSpecs(mass=3443 * CV.LB_TO_KG, wheelbase=2.83, steerRatio=15.5)
+ )
+ CX9_2021 = MazdaPlatformConfig(
+ "MAZDA CX-9 2021",
+ MazdaCarInfo("Mazda CX-9 2021-23", video_link="https://youtu.be/dA3duO4a0O4"),
+ specs=CX9.specs
+ )
+ CX5_2022 = MazdaPlatformConfig(
+ "MAZDA CX-5 2022",
+ MazdaCarInfo("Mazda CX-5 2022-24"),
+ specs=CX5.specs,
+ )
class LKAS_LIMITS:
@@ -76,14 +103,5 @@ FW_QUERY_CONFIG = FwQueryConfig(
)
-DBC = {
- CAR.CX5: dbc_dict('mazda_2017', None),
- CAR.CX9: dbc_dict('mazda_2017', None),
- CAR.MAZDA3: dbc_dict('mazda_2017', None),
- CAR.MAZDA6: dbc_dict('mazda_2017', None),
- CAR.CX9_2021: dbc_dict('mazda_2017', None),
- CAR.CX5_2022: dbc_dict('mazda_2017', None),
-}
-
-# Gen 1 hardware: same CAN messages and same camera
-GEN1 = {CAR.CX5, CAR.CX9, CAR.CX9_2021, CAR.MAZDA3, CAR.MAZDA6, CAR.CX5_2022}
+CAR_INFO = CAR.create_carinfo_map()
+DBC = CAR.create_dbc_map()
diff --git a/selfdrive/car/subaru/interface.py b/selfdrive/car/subaru/interface.py
index ecf718bb3a..30e186bd09 100644
--- a/selfdrive/car/subaru/interface.py
+++ b/selfdrive/car/subaru/interface.py
@@ -10,47 +10,45 @@ class CarInterface(CarInterfaceBase):
@staticmethod
def _get_params(ret, candidate: CAR, fingerprint, car_fw, experimental_long, docs):
- platform_flags = candidate.config.flags
-
ret.carName = "subaru"
ret.radarUnavailable = True
# for HYBRID CARS to be upstreamed, we need:
# - replacement for ES_Distance so we can cancel the cruise control
# - to find the Cruise_Activated bit from the car
# - proper panda safety setup (use the correct cruise_activated bit, throttle from Throttle_Hybrid, etc)
- ret.dashcamOnly = bool(platform_flags & (SubaruFlags.PREGLOBAL | SubaruFlags.LKAS_ANGLE | SubaruFlags.HYBRID))
+ ret.dashcamOnly = bool(ret.flags & (SubaruFlags.PREGLOBAL | SubaruFlags.LKAS_ANGLE | SubaruFlags.HYBRID))
ret.autoResumeSng = False
# Detect infotainment message sent from the camera
- if not (platform_flags & SubaruFlags.PREGLOBAL) and 0x323 in fingerprint[2]:
+ if not (ret.flags & SubaruFlags.PREGLOBAL) and 0x323 in fingerprint[2]:
ret.flags |= SubaruFlags.SEND_INFOTAINMENT.value
- if platform_flags & SubaruFlags.PREGLOBAL:
+ if ret.flags & SubaruFlags.PREGLOBAL:
ret.enableBsm = 0x25c in fingerprint[0]
ret.safetyConfigs = [get_safety_config(car.CarParams.SafetyModel.subaruPreglobal)]
else:
ret.enableBsm = 0x228 in fingerprint[0]
ret.safetyConfigs = [get_safety_config(car.CarParams.SafetyModel.subaru)]
- if platform_flags & SubaruFlags.GLOBAL_GEN2:
+ if ret.flags & SubaruFlags.GLOBAL_GEN2:
ret.safetyConfigs[0].safetyParam |= Panda.FLAG_SUBARU_GEN2
ret.steerLimitTimer = 0.4
ret.steerActuatorDelay = 0.1
- if platform_flags & SubaruFlags.LKAS_ANGLE:
+ if ret.flags & SubaruFlags.LKAS_ANGLE:
ret.steerControlType = car.CarParams.SteerControlType.angle
else:
CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning)
if candidate in (CAR.ASCENT, CAR.ASCENT_2023):
- ret.steerActuatorDelay = 0.3 # end-to-end angle controller
+ ret.steerActuatorDelay = 0.3 # end-to-end angle controller
ret.lateralTuning.init('pid')
ret.lateralTuning.pid.kf = 0.00003
ret.lateralTuning.pid.kiBP, ret.lateralTuning.pid.kpBP = [[0., 20.], [0., 20.]]
ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.0025, 0.1], [0.00025, 0.01]]
elif candidate == CAR.IMPREZA:
- ret.steerActuatorDelay = 0.4 # end-to-end angle controller
+ ret.steerActuatorDelay = 0.4 # end-to-end angle controller
ret.lateralTuning.init('pid')
ret.lateralTuning.pid.kf = 0.00005
ret.lateralTuning.pid.kiBP, ret.lateralTuning.pid.kpBP = [[0., 20.], [0., 20.]]
@@ -85,12 +83,11 @@ class CarInterface(CarInterfaceBase):
else:
raise ValueError(f"unknown car: {candidate}")
- LONG_UNAVAILABLE = SubaruFlags.GLOBAL_GEN2 | SubaruFlags.PREGLOBAL| SubaruFlags.LKAS_ANGLE | SubaruFlags.HYBRID
-
- ret.experimentalLongitudinalAvailable = not (platform_flags & LONG_UNAVAILABLE)
+ ret.experimentalLongitudinalAvailable = not (ret.flags & (SubaruFlags.GLOBAL_GEN2 | SubaruFlags.PREGLOBAL |
+ SubaruFlags.LKAS_ANGLE | SubaruFlags.HYBRID))
ret.openpilotLongitudinalControl = experimental_long and ret.experimentalLongitudinalAvailable
- if platform_flags & SubaruFlags.GLOBAL_GEN2 and ret.openpilotLongitudinalControl:
+ if ret.flags & SubaruFlags.GLOBAL_GEN2 and ret.openpilotLongitudinalControl:
ret.flags |= SubaruFlags.DISABLE_EYESIGHT.value
if ret.openpilotLongitudinalControl:
diff --git a/selfdrive/car/subaru/values.py b/selfdrive/car/subaru/values.py
index a7c9a22e2c..c2b2d16d7f 100644
--- a/selfdrive/car/subaru/values.py
+++ b/selfdrive/car/subaru/values.py
@@ -53,8 +53,11 @@ class CarControllerParams:
class SubaruFlags(IntFlag):
+ # Detected flags
SEND_INFOTAINMENT = 1
DISABLE_EYESIGHT = 2
+
+ # Static flags
GLOBAL_GEN2 = 4
# Cars that temporarily fault when steering angle rate is greater than some threshold.
@@ -106,6 +109,15 @@ class SubaruPlatformConfig(PlatformConfig):
self.dbc_dict = dbc_dict('subaru_global_2020_hybrid_generated', None)
+@dataclass
+class SubaruGen2PlatformConfig(SubaruPlatformConfig):
+ def init(self):
+ super().init()
+ self.flags |= SubaruFlags.GLOBAL_GEN2
+ if not (self.flags & SubaruFlags.LKAS_ANGLE):
+ self.flags |= SubaruFlags.STEER_RATE_LIMITED
+
+
class CAR(Platforms):
# Global platform
ASCENT = SubaruPlatformConfig(
@@ -113,17 +125,15 @@ class CAR(Platforms):
SubaruCarInfo("Subaru Ascent 2019-21", "All"),
specs=CarSpecs(mass=2031, wheelbase=2.89, steerRatio=13.5),
)
- OUTBACK = SubaruPlatformConfig(
+ OUTBACK = SubaruGen2PlatformConfig(
"SUBARU OUTBACK 6TH GEN",
SubaruCarInfo("Subaru Outback 2020-22", "All", car_parts=CarParts.common([CarHarness.subaru_b])),
specs=CarSpecs(mass=1568, wheelbase=2.67, steerRatio=17),
- flags=SubaruFlags.GLOBAL_GEN2 | SubaruFlags.STEER_RATE_LIMITED,
)
- LEGACY = SubaruPlatformConfig(
+ LEGACY = SubaruGen2PlatformConfig(
"SUBARU LEGACY 7TH GEN",
SubaruCarInfo("Subaru Legacy 2020-22", "All", car_parts=CarParts.common([CarHarness.subaru_b])),
specs=OUTBACK.specs,
- flags=SubaruFlags.GLOBAL_GEN2 | SubaruFlags.STEER_RATE_LIMITED,
)
IMPREZA = SubaruPlatformConfig(
"SUBARU IMPREZA LIMITED 2019",
@@ -199,17 +209,17 @@ class CAR(Platforms):
specs=FORESTER.specs,
flags=SubaruFlags.LKAS_ANGLE,
)
- OUTBACK_2023 = SubaruPlatformConfig(
+ OUTBACK_2023 = SubaruGen2PlatformConfig(
"SUBARU OUTBACK 7TH GEN",
SubaruCarInfo("Subaru Outback 2023", "All", car_parts=CarParts.common([CarHarness.subaru_d])),
specs=OUTBACK.specs,
- flags=SubaruFlags.GLOBAL_GEN2 | SubaruFlags.LKAS_ANGLE,
+ flags=SubaruFlags.LKAS_ANGLE,
)
- ASCENT_2023 = SubaruPlatformConfig(
+ ASCENT_2023 = SubaruGen2PlatformConfig(
"SUBARU ASCENT 2023",
SubaruCarInfo("Subaru Ascent 2023", "All", car_parts=CarParts.common([CarHarness.subaru_d])),
specs=ASCENT.specs,
- flags=SubaruFlags.GLOBAL_GEN2 | SubaruFlags.LKAS_ANGLE,
+ flags=SubaruFlags.LKAS_ANGLE,
)
@@ -255,3 +265,7 @@ FW_QUERY_CONFIG = FwQueryConfig(
CAR_INFO = CAR.create_carinfo_map()
DBC = CAR.create_dbc_map()
+
+
+if __name__ == "__main__":
+ CAR.print_debug(SubaruFlags)
diff --git a/selfdrive/car/tesla/interface.py b/selfdrive/car/tesla/interface.py
index e06139729c..537433a350 100755
--- a/selfdrive/car/tesla/interface.py
+++ b/selfdrive/car/tesla/interface.py
@@ -1,7 +1,7 @@
#!/usr/bin/env python3
from cereal import car
from panda import Panda
-from openpilot.selfdrive.car.tesla.values import CANBUS, CAR
+from openpilot.selfdrive.car.tesla.values import CANBUS
from openpilot.selfdrive.car import get_safety_config
from openpilot.selfdrive.car.interfaces import CarInterfaceBase
@@ -41,14 +41,6 @@ class CarInterface(CarInterfaceBase):
ret.steerLimitTimer = 1.0
ret.steerActuatorDelay = 0.25
- if candidate in (CAR.AP2_MODELS, CAR.AP1_MODELS):
- ret.mass = 2100.
- ret.wheelbase = 2.959
- ret.centerToFront = ret.wheelbase * 0.5
- ret.steerRatio = 15.0
- else:
- raise ValueError(f"Unsupported car: {candidate}")
-
return ret
def _update(self, c):
diff --git a/selfdrive/car/tesla/values.py b/selfdrive/car/tesla/values.py
index 2a51d15da8..74d2debe1f 100644
--- a/selfdrive/car/tesla/values.py
+++ b/selfdrive/car/tesla/values.py
@@ -1,8 +1,8 @@
from collections import namedtuple
-from enum import StrEnum
+from dataclasses import dataclass, field
from cereal import car
-from openpilot.selfdrive.car import AngleRateLimit, dbc_dict
+from openpilot.selfdrive.car import AngleRateLimit, CarSpecs, DbcDict, PlatformConfig, Platforms, dbc_dict
from openpilot.selfdrive.car.docs_definitions import CarInfo
from openpilot.selfdrive.car.fw_query_definitions import FwQueryConfig, Request, StdQueries
@@ -11,21 +11,23 @@ Ecu = car.CarParams.Ecu
Button = namedtuple('Button', ['event_type', 'can_addr', 'can_msg', 'values'])
-class CAR(StrEnum):
- AP1_MODELS = 'TESLA AP1 MODEL S'
- AP2_MODELS = 'TESLA AP2 MODEL S'
+@dataclass
+class TeslaPlatformConfig(PlatformConfig):
+ dbc_dict: DbcDict = field(default_factory=lambda: dbc_dict('tesla_powertrain', 'tesla_radar', chassis_dbc='tesla_can'))
-CAR_INFO: dict[str, CarInfo | list[CarInfo]] = {
- CAR.AP1_MODELS: CarInfo("Tesla AP1 Model S", "All"),
- CAR.AP2_MODELS: CarInfo("Tesla AP2 Model S", "All"),
-}
-
+class CAR(Platforms):
+ AP1_MODELS = TeslaPlatformConfig(
+ 'TESLA AP1 MODEL S',
+ CarInfo("Tesla AP1 Model S", "All"),
+ specs=CarSpecs(mass=2100., wheelbase=2.959, steerRatio=15.0)
+ )
+ AP2_MODELS = TeslaPlatformConfig(
+ 'TESLA AP2 MODEL S',
+ CarInfo("Tesla AP2 Model S", "All"),
+ specs=AP1_MODELS.specs
+ )
-DBC = {
- CAR.AP2_MODELS: dbc_dict('tesla_powertrain', 'tesla_radar', chassis_dbc='tesla_can'),
- CAR.AP1_MODELS: dbc_dict('tesla_powertrain', 'tesla_radar', chassis_dbc='tesla_can'),
-}
FW_QUERY_CONFIG = FwQueryConfig(
requests=[
@@ -88,3 +90,7 @@ class CarControllerParams:
def __init__(self, CP):
pass
+
+
+CAR_INFO = CAR.create_carinfo_map()
+DBC = CAR.create_dbc_map()
diff --git a/selfdrive/car/tests/test_models.py b/selfdrive/car/tests/test_models.py
index 2b29c14f72..b7d20e5a83 100755
--- a/selfdrive/car/tests/test_models.py
+++ b/selfdrive/car/tests/test_models.py
@@ -17,7 +17,7 @@ from openpilot.common.realtime import DT_CTRL
from openpilot.selfdrive.car import gen_empty_fingerprint
from openpilot.selfdrive.car.fingerprints import all_known_cars
from openpilot.selfdrive.car.car_helpers import FRAME_FINGERPRINT, interfaces
-from openpilot.selfdrive.car.honda.values import CAR as HONDA, HONDA_BOSCH
+from openpilot.selfdrive.car.honda.values import CAR as HONDA, HondaFlags
from openpilot.selfdrive.car.tests.routes import non_tested_cars, routes, CarTestRoute
from openpilot.selfdrive.controls.controlsd import Controls
from openpilot.selfdrive.test.helpers import read_segment_list
@@ -381,7 +381,7 @@ class TestCarModelBase(unittest.TestCase):
if self.safety.get_vehicle_moving() != prev_panda_vehicle_moving:
self.assertEqual(not CS.standstill, self.safety.get_vehicle_moving())
- if not (self.CP.carName == "honda" and self.CP.carFingerprint not in HONDA_BOSCH):
+ if not (self.CP.carName == "honda" and not (self.CP.flags & HondaFlags.BOSCH)):
if self.safety.get_cruise_engaged_prev() != prev_panda_cruise_engaged:
self.assertEqual(CS.cruiseState.enabled, self.safety.get_cruise_engaged_prev())
@@ -442,7 +442,7 @@ class TestCarModelBase(unittest.TestCase):
# On most pcmCruise cars, openpilot's state is always tied to the PCM's cruise state.
# On Honda Nidec, we always engage on the rising edge of the PCM cruise state, but
# openpilot brakes to zero even if the min ACC speed is non-zero (i.e. the PCM disengages).
- if self.CP.carName == "honda" and self.CP.carFingerprint not in HONDA_BOSCH:
+ if self.CP.carName == "honda" and not (self.CP.flags & HondaFlags.BOSCH):
# only the rising edges are expected to match
if CS.cruiseState.enabled and not CS_prev.cruiseState.enabled:
checks['controlsAllowed'] += not self.safety.get_controls_allowed()
diff --git a/selfdrive/car/tests/test_platform_configs.py b/selfdrive/car/tests/test_platform_configs.py
new file mode 100755
index 0000000000..931780963f
--- /dev/null
+++ b/selfdrive/car/tests/test_platform_configs.py
@@ -0,0 +1,24 @@
+#!/usr/bin/env python3
+
+import unittest
+
+from openpilot.selfdrive.car.values import PLATFORMS
+
+
+class TestPlatformConfigs(unittest.TestCase):
+ def test_configs(self):
+
+ for platform in PLATFORMS.values():
+ with self.subTest(platform=str(platform)):
+ if hasattr(platform, "config"):
+
+ self.assertTrue(platform.config._frozen)
+ self.assertIn("pt", platform.config.dbc_dict)
+ self.assertTrue(len(platform.config.platform_str) > 0)
+
+ # enable when all cars have specs
+ #self.assertIsNotNone(platform.config.specs)
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/selfdrive/car/volkswagen/carcontroller.py b/selfdrive/car/volkswagen/carcontroller.py
index f99e87d5d3..1b1858703d 100644
--- a/selfdrive/car/volkswagen/carcontroller.py
+++ b/selfdrive/car/volkswagen/carcontroller.py
@@ -6,7 +6,7 @@ from openpilot.common.realtime import DT_CTRL
from openpilot.selfdrive.car import apply_driver_steer_torque_limits
from openpilot.selfdrive.car.interfaces import CarControllerBase
from openpilot.selfdrive.car.volkswagen import mqbcan, pqcan
-from openpilot.selfdrive.car.volkswagen.values import CANBUS, PQ_CARS, CarControllerParams, VolkswagenFlags
+from openpilot.selfdrive.car.volkswagen.values import CANBUS, CarControllerParams, VolkswagenFlags
VisualAlert = car.CarControl.HUDControl.VisualAlert
LongCtrlState = car.CarControl.Actuators.LongControlState
@@ -16,7 +16,7 @@ class CarController(CarControllerBase):
def __init__(self, dbc_name, CP, VM):
self.CP = CP
self.CCP = CarControllerParams(CP)
- self.CCS = pqcan if CP.carFingerprint in PQ_CARS else mqbcan
+ self.CCS = pqcan if CP.flags & VolkswagenFlags.PQ else mqbcan
self.packer_pt = CANPacker(dbc_name)
self.apply_steer_last = 0
diff --git a/selfdrive/car/volkswagen/carstate.py b/selfdrive/car/volkswagen/carstate.py
index 25c5bc04bc..48e9ed37d6 100644
--- a/selfdrive/car/volkswagen/carstate.py
+++ b/selfdrive/car/volkswagen/carstate.py
@@ -3,7 +3,7 @@ from cereal import car
from openpilot.common.conversions import Conversions as CV
from openpilot.selfdrive.car.interfaces import CarStateBase
from opendbc.can.parser import CANParser
-from openpilot.selfdrive.car.volkswagen.values import DBC, CANBUS, PQ_CARS, NetworkLocation, TransmissionType, GearShifter, \
+from openpilot.selfdrive.car.volkswagen.values import DBC, CANBUS, NetworkLocation, TransmissionType, GearShifter, \
CarControllerParams, VolkswagenFlags
@@ -31,7 +31,7 @@ class CarState(CarStateBase):
return button_events
def update(self, pt_cp, cam_cp, ext_cp, trans_type):
- if self.CP.carFingerprint in PQ_CARS:
+ if self.CP.flags & VolkswagenFlags.PQ:
return self.update_pq(pt_cp, cam_cp, ext_cp, trans_type)
ret = car.CarState.new_message()
@@ -257,7 +257,7 @@ class CarState(CarStateBase):
@staticmethod
def get_can_parser(CP):
- if CP.carFingerprint in PQ_CARS:
+ if CP.flags & VolkswagenFlags.PQ:
return CarState.get_can_parser_pq(CP)
messages = [
@@ -294,7 +294,7 @@ class CarState(CarStateBase):
@staticmethod
def get_cam_can_parser(CP):
- if CP.carFingerprint in PQ_CARS:
+ if CP.flags & VolkswagenFlags.PQ:
return CarState.get_cam_can_parser_pq(CP)
messages = []
diff --git a/selfdrive/car/volkswagen/interface.py b/selfdrive/car/volkswagen/interface.py
index fa68e81d0d..374b657512 100644
--- a/selfdrive/car/volkswagen/interface.py
+++ b/selfdrive/car/volkswagen/interface.py
@@ -2,7 +2,7 @@ from cereal import car
from panda import Panda
from openpilot.selfdrive.car import get_safety_config
from openpilot.selfdrive.car.interfaces import CarInterfaceBase
-from openpilot.selfdrive.car.volkswagen.values import PQ_CARS, CANBUS, NetworkLocation, TransmissionType, GearShifter, VolkswagenFlags
+from openpilot.selfdrive.car.volkswagen.values import CAR, CANBUS, NetworkLocation, TransmissionType, GearShifter, VolkswagenFlags
ButtonType = car.CarState.ButtonEvent.Type
EventName = car.CarEvent.EventName
@@ -22,11 +22,11 @@ class CarInterface(CarInterfaceBase):
self.eps_timer_soft_disable_alert = False
@staticmethod
- def _get_params(ret, candidate, fingerprint, car_fw, experimental_long, docs):
+ def _get_params(ret, candidate: CAR, fingerprint, car_fw, experimental_long, docs):
ret.carName = "volkswagen"
ret.radarUnavailable = True
- if candidate in PQ_CARS:
+ if ret.flags & VolkswagenFlags.PQ:
# Set global PQ35/PQ46/NMS parameters
ret.safetyConfigs = [get_safety_config(car.CarParams.SafetyModel.volkswagenPq)]
ret.enableBsm = 0x3BA in fingerprint[0] # SWA_1
@@ -72,7 +72,7 @@ class CarInterface(CarInterfaceBase):
# Global lateral tuning defaults, can be overridden per-vehicle
ret.steerLimitTimer = 0.4
- if candidate in PQ_CARS:
+ if ret.flags & VolkswagenFlags.PQ:
ret.steerActuatorDelay = 0.2
CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning)
else:
diff --git a/selfdrive/car/volkswagen/values.py b/selfdrive/car/volkswagen/values.py
index 065a340928..86788dcf64 100644
--- a/selfdrive/car/volkswagen/values.py
+++ b/selfdrive/car/volkswagen/values.py
@@ -40,7 +40,7 @@ class CarControllerParams:
def __init__(self, CP):
can_define = CANDefine(DBC[CP.carFingerprint]["pt"])
- if CP.carFingerprint in PQ_CARS:
+ if CP.flags & VolkswagenFlags.PQ:
self.LDW_STEP = 5 # LDW_1 message frequency 20Hz
self.ACC_HUD_STEP = 4 # ACC_GRA_Anzeige frequency 25Hz
self.STEER_DRIVER_ALLOWANCE = 80 # Driver intervention threshold 0.8 Nm
@@ -110,8 +110,12 @@ class CANBUS:
class VolkswagenFlags(IntFlag):
+ # Detected flags
STOCK_HCA_PRESENT = 1
+ # Static Flags
+ PQ = 2
+
@dataclass
class VolkswagenMQBPlatformConfig(PlatformConfig):
@@ -122,6 +126,9 @@ class VolkswagenMQBPlatformConfig(PlatformConfig):
class VolkswagenPQPlatformConfig(PlatformConfig):
dbc_dict: DbcDict = field(default_factory=lambda: dbc_dict('vw_golf_mk4', None))
+ def init(self):
+ self.flags |= VolkswagenFlags.PQ
+
@dataclass(frozen=True, kw_only=True)
class VolkswagenCarSpecs(CarSpecs):
@@ -359,8 +366,6 @@ class CAR(Platforms):
)
-PQ_CARS = {CAR.PASSAT_NMS, CAR.SHARAN_MK2}
-
# All supported cars should return FW from the engine, srs, eps, and fwdRadar. Cars
# with a manual trans won't return transmission firmware, but all other cars will.
#
diff --git a/selfdrive/test/process_replay/ref_commit b/selfdrive/test/process_replay/ref_commit
index 13f776fbad..015f941261 100644
--- a/selfdrive/test/process_replay/ref_commit
+++ b/selfdrive/test/process_replay/ref_commit
@@ -1 +1 @@
-b9d29ac9402cfc04bf3e48867415efa70c144029
+de322b3898f8fedb57036b6cf4a0605968138929
diff --git a/selfdrive/test/process_replay/test_processes.py b/selfdrive/test/process_replay/test_processes.py
index 2b917b0f61..88e46abb06 100755
--- a/selfdrive/test/process_replay/test_processes.py
+++ b/selfdrive/test/process_replay/test_processes.py
@@ -156,7 +156,8 @@ if __name__ == "__main__":
assert full_test, "Need to run full test when updating refs"
try:
- ref_commit = open(REF_COMMIT_FN).read().strip()
+ with open(REF_COMMIT_FN) as f:
+ ref_commit = f.read().strip()
except FileNotFoundError:
print("Couldn't find reference commit")
sys.exit(1)
diff --git a/selfdrive/ui/translations/main_zh-CHS.ts b/selfdrive/ui/translations/main_zh-CHS.ts
index a27dc18bd2..59d6874035 100644
--- a/selfdrive/ui/translations/main_zh-CHS.ts
+++ b/selfdrive/ui/translations/main_zh-CHS.ts
@@ -68,23 +68,23 @@
Hidden Network
-
+ 隐藏的网络
CONNECT
- CONNECT
+ 连线
Enter SSID
- 输入SSID
+ 输入 SSID
Enter password
- 输入密码
+ 输入密码
for "%1"
- 网络名称:"%1"
+ 网络名称:"%1"
@@ -634,7 +634,7 @@ This may take up to a minute.
System reset triggered. Press confirm to erase all content and settings. Press cancel to resume boot.
-
+ 系统重置已触发。按下“确认”以清除所有内容和设置,按下“取消”以继续启动。
@@ -744,15 +744,15 @@ This may take up to a minute.
Choose Software to Install
-
+ 选择要安装的软件
openpilot
- openpilot
+ openpilot
Custom Software
-
+ 定制软件
diff --git a/selfdrive/ui/translations/main_zh-CHT.ts b/selfdrive/ui/translations/main_zh-CHT.ts
index 1e7f1a614b..0079b47f7f 100644
--- a/selfdrive/ui/translations/main_zh-CHT.ts
+++ b/selfdrive/ui/translations/main_zh-CHT.ts
@@ -68,23 +68,23 @@
Hidden Network
-
+ 隱藏的網路
CONNECT
- 雲端服務
+ 連線
Enter SSID
- 輸入 SSID
+ 輸入 SSID
Enter password
- 輸入密碼
+ 輸入密碼
for "%1"
- 給 "%1"
+ 給 "%1"
@@ -634,7 +634,7 @@ This may take up to a minute.
System reset triggered. Press confirm to erase all content and settings. Press cancel to resume boot.
-
+ 系統重設已啟動。按下「確認」以清除所有內容和設定,或按下「取消」以繼續開機。
@@ -744,15 +744,15 @@ This may take up to a minute.
Choose Software to Install
-
+ 選擇要安裝的軟體
openpilot
- openpilot
+ openpilot
Custom Software
-
+ 自訂軟體
diff --git a/selfdrive/ui/ui.py b/selfdrive/ui/ui.py
new file mode 100755
index 0000000000..ea2ee51a45
--- /dev/null
+++ b/selfdrive/ui/ui.py
@@ -0,0 +1,77 @@
+#!/usr/bin/env python3
+import os
+import signal
+
+signal.signal(signal.SIGINT, signal.SIG_DFL)
+
+import cereal.messaging as messaging
+from openpilot.system.hardware import HARDWARE
+
+from PyQt5.QtCore import Qt, QTimer
+from PyQt5.QtWidgets import QLabel, QWidget, QVBoxLayout, QStackedLayout, QApplication
+from openpilot.selfdrive.ui.qt.python_helpers import set_main_window
+
+
+if __name__ == "__main__":
+ app = QApplication([])
+ win = QWidget()
+ set_main_window(win)
+
+ bg = QLabel("", alignment=Qt.AlignCenter)
+
+ alert1 = QLabel()
+ alert2 = QLabel()
+ vlayout = QVBoxLayout()
+ vlayout.addWidget(alert1, alignment=Qt.AlignCenter)
+ vlayout.addWidget(alert2, alignment=Qt.AlignCenter)
+
+ tmp = QWidget()
+ tmp.setLayout(vlayout)
+
+ stack = QStackedLayout(win)
+ stack.addWidget(tmp)
+ stack.addWidget(bg)
+ stack.setStackingMode(QStackedLayout.StackAll)
+
+ win.setObjectName("win")
+ win.setStyleSheet("""
+ #win {
+ background-color: black;
+ }
+ QLabel {
+ color: white;
+ font-size: 40px;
+ }
+ """)
+
+ sm = messaging.SubMaster(['deviceState', 'controlsState'])
+
+ def update():
+ sm.update(0)
+
+ onroad = sm.all_checks(['deviceState']) and sm['deviceState'].started
+ if onroad:
+ cs = sm['controlsState']
+ color = ("grey" if str(cs.status) in ("overriding", "preEnabled") else "green") if cs.enabled else "blue"
+ bg.setText("\U0001F44D" if cs.engageable else "\U0001F6D1")
+ bg.setStyleSheet(f"font-size: 100px; background-color: {color};")
+ bg.show()
+
+ alert1.setText(cs.alertText1)
+ alert2.setText(cs.alertText2)
+
+ if not sm.alive['controlsState']:
+ alert1.setText("waiting for controls...")
+ else:
+ bg.hide()
+ alert1.setText("")
+ alert2.setText("offroad")
+
+ HARDWARE.set_screen_brightness(100 if onroad else 40)
+ os.system("echo 0 > /sys/class/backlight/panel0-backlight/bl_power")
+
+ timer = QTimer()
+ timer.timeout.connect(update)
+ timer.start(50)
+
+ app.exec_()