diff --git a/release/files_common b/release/files_common index 34d8f009732f15..d31da836b7742a 100644 --- a/release/files_common +++ b/release/files_common @@ -517,6 +517,7 @@ opendbc/honda_odyssey_extreme_edition_2018_china_can_generated.dbc opendbc/honda_insight_ex_2019_can_generated.dbc opendbc/acura_ilx_2016_nidec.dbc opendbc/honda_civic_ex_2022_can_generated.dbc +opendbc/honda_pilot_2023_can_generated.dbc opendbc/hyundai_canfd.dbc opendbc/hyundai_kia_generic.dbc diff --git a/selfdrive/car/honda/carstate.py b/selfdrive/car/honda/carstate.py index c98d1a72d3cc15..06807fde6ef06c 100644 --- a/selfdrive/car/honda/carstate.py +++ b/selfdrive/car/honda/carstate.py @@ -65,7 +65,7 @@ def get_can_messages(CP, gearbox_msg): # TODO: clean this up if CP.carFingerprint in (CAR.HONDA_ACCORD, CAR.HONDA_CIVIC_BOSCH, CAR.HONDA_CIVIC_BOSCH_DIESEL, CAR.HONDA_CRV_HYBRID, CAR.HONDA_INSIGHT, - CAR.ACURA_RDX_3G, CAR.HONDA_E, CAR.HONDA_CIVIC_2022, CAR.HONDA_HRV_3G): + CAR.ACURA_RDX_3G, CAR.HONDA_E, CAR.HONDA_CIVIC_2022, CAR.HONDA_HRV_3G, CAR.HONDA_CRV_HYBRID_6G): pass elif CP.carFingerprint in (CAR.HONDA_ODYSSEY_CHN, CAR.HONDA_FREED, CAR.HONDA_HRV): pass @@ -126,7 +126,7 @@ def update(self, cp, cp_cam, cp_body): ret.standstill = cp.vl["ENGINE_DATA"]["XMISSION_SPEED"] < 1e-5 # TODO: find a common signal across all cars if self.CP.carFingerprint in (CAR.HONDA_ACCORD, CAR.HONDA_CIVIC_BOSCH, CAR.HONDA_CIVIC_BOSCH_DIESEL, CAR.HONDA_CRV_HYBRID, CAR.HONDA_INSIGHT, - CAR.ACURA_RDX_3G, CAR.HONDA_E, CAR.HONDA_CIVIC_2022, CAR.HONDA_HRV_3G): + CAR.ACURA_RDX_3G, CAR.HONDA_E, CAR.HONDA_CIVIC_2022, CAR.HONDA_HRV_3G, CAR.HONDA_CRV_HYBRID_6G): ret.doorOpen = bool(cp.vl["SCM_FEEDBACK"]["DRIVERS_DOOR_OPEN"]) elif self.CP.carFingerprint in (CAR.HONDA_ODYSSEY_CHN, CAR.HONDA_FREED, CAR.HONDA_HRV): ret.doorOpen = bool(cp.vl["SCM_BUTTONS"]["DRIVERS_DOOR_OPEN"]) diff --git a/selfdrive/car/honda/fingerprints.py b/selfdrive/car/honda/fingerprints.py index 052b4b60a3ac27..20fc42486ce317 100644 --- a/selfdrive/car/honda/fingerprints.py +++ b/selfdrive/car/honda/fingerprints.py @@ -1140,4 +1140,13 @@ b'37805-64S-AA10\x00\x00', ], }, + CAR.HONDA_CRV_HYBRID_6G: { + (Ecu.fwdRadar, 0x18dab0f1, None): [ + b'8S302-3D4-A050\x00\x00', + ], + (Ecu.fwdCamera, 0x18dab5f1, None): [ + b'8S102-3D4-A060\x00\x00', + b'8S102-3D4-A080\x00\x00', + ], + }, } diff --git a/selfdrive/car/honda/hondacan.py b/selfdrive/car/honda/hondacan.py index 1be496d9511612..4257c1529eb91e 100644 --- a/selfdrive/car/honda/hondacan.py +++ b/selfdrive/car/honda/hondacan.py @@ -1,6 +1,6 @@ from openpilot.common.conversions import Conversions as CV from openpilot.selfdrive.car import CanBusBase -from openpilot.selfdrive.car.honda.values import HondaFlags, HONDA_BOSCH, HONDA_BOSCH_RADARLESS, CAR, CarControllerParams +from openpilot.selfdrive.car.honda.values import HondaFlags, HONDA_BOSCH, HONDA_BOSCH_RADARLESS, HONDA_CANFD_CAR, CAR, CarControllerParams # CAN bus layout with relay # 0 = ACC-CAN - radar side @@ -14,7 +14,7 @@ def __init__(self, CP=None, fingerprint=None) -> None: # use fingerprint if specified super().__init__(CP if fingerprint is None else None, fingerprint) - if CP.carFingerprint in (HONDA_BOSCH - HONDA_BOSCH_RADARLESS): + if CP.carFingerprint in (HONDA_BOSCH - HONDA_BOSCH_RADARLESS - HONDA_CANFD_CAR): self._pt, self._radar = self.offset + 1, self.offset else: self._pt, self._radar = self.offset, self.offset + 1 @@ -34,7 +34,7 @@ def camera(self) -> int: def get_lkas_cmd_bus(CAN, car_fingerprint, radar_disabled=False): no_radar = car_fingerprint in HONDA_BOSCH_RADARLESS - if radar_disabled or no_radar: + if radar_disabled or no_radar or car_fingerprint in HONDA_CANFD_CAR: # when radar is disabled, steering commands are sent directly to powertrain bus return CAN.pt # normally steering commands are sent to radar, which forwards them to powertrain bus @@ -43,7 +43,7 @@ def get_lkas_cmd_bus(CAN, car_fingerprint, radar_disabled=False): def get_cruise_speed_conversion(car_fingerprint: str, is_metric: bool) -> float: # on certain cars, CRUISE_SPEED changes to imperial with car's unit setting - return CV.MPH_TO_MS if car_fingerprint in HONDA_BOSCH_RADARLESS and not is_metric else CV.KPH_TO_MS + return CV.MPH_TO_MS if car_fingerprint in (HONDA_BOSCH_RADARLESS | HONDA_CANFD_CAR) and not is_metric else CV.KPH_TO_MS def create_brake_command(packer, CAN, apply_brake, pump_on, pcm_override, pcm_cancel_cmd, fcw, car_fingerprint, stock_brake): @@ -179,6 +179,11 @@ def create_ui_commands(packer, CAN, CP, enabled, pcm_speed, hud, is_metric, acc_ # car likely needs to see LKAS_PROBLEM fall within a specific time frame, so forward from camera lkas_hud_values['LKAS_PROBLEM'] = lkas_hud['LKAS_PROBLEM'] + if CP.carFingerprint in HONDA_CANFD_CAR: + lkas_hud_values['LANE_LINES'] = 3 + lkas_hud_values['SOLID_LANES'] = hud.lanes_visible + lkas_hud_values['DASHED_LANES'] = hud.lanes_visible + if not (CP.flags & HondaFlags.BOSCH_EXT_HUD): lkas_hud_values['SET_ME_X48'] = 0x48 diff --git a/selfdrive/car/honda/interface.py b/selfdrive/car/honda/interface.py index 2026c385c24a7c..53b2acdcaa4419 100755 --- a/selfdrive/car/honda/interface.py +++ b/selfdrive/car/honda/interface.py @@ -5,7 +5,7 @@ from openpilot.common.numpy_fast import interp from openpilot.selfdrive.car.honda.hondacan import CanBus from openpilot.selfdrive.car.honda.values import CarControllerParams, CruiseButtons, CruiseSettings, HondaFlags, CAR, HONDA_BOSCH, \ - HONDA_NIDEC_ALT_SCM_MESSAGES, HONDA_BOSCH_RADARLESS + HONDA_NIDEC_ALT_SCM_MESSAGES, HONDA_BOSCH_RADARLESS, HONDA_CANFD_CAR from openpilot.selfdrive.car import create_button_events, get_safety_config from openpilot.selfdrive.car.interfaces import CarInterfaceBase from openpilot.selfdrive.car.disable_ecu import disable_ecu @@ -37,7 +37,14 @@ def _get_params(ret, candidate, fingerprint, car_fw, experimental_long, docs): CAN = CanBus(ret, fingerprint) - if candidate in HONDA_BOSCH: + if candidate in HONDA_CANFD_CAR: + cfgs = [get_safety_config(car.CarParams.SafetyModel.hondaBosch)] + if CAN.pt >= 4: + cfgs.insert(0, get_safety_config(car.CarParams.SafetyModel.noOutput)) + ret.safetyConfigs = cfgs + ret.radarUnavailable = True + ret.openpilotLongitudinalControl = False + elif candidate in HONDA_BOSCH: ret.safetyConfigs = [get_safety_config(car.CarParams.SafetyModel.hondaBosch)] ret.radarUnavailable = True # Disable the radar and let openpilot control longitudinal @@ -136,7 +143,7 @@ def _get_params(ret, candidate, fingerprint, car_fw, experimental_long, docs): ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.64], [0.192]] ret.wheelSpeedFactor = 1.025 - elif candidate == CAR.HONDA_CRV_HYBRID: + elif candidate in (CAR.HONDA_CRV_HYBRID, CAR.HONDA_CRV_HYBRID_6G): 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.6], [0.18]] ret.wheelSpeedFactor = 1.025 @@ -206,7 +213,7 @@ def _get_params(ret, candidate, fingerprint, car_fw, experimental_long, docs): if ret.openpilotLongitudinalControl and candidate in HONDA_BOSCH: ret.safetyConfigs[0].safetyParam |= Panda.FLAG_HONDA_BOSCH_LONG - if candidate in HONDA_BOSCH_RADARLESS: + if candidate in (HONDA_BOSCH_RADARLESS | HONDA_CANFD_CAR): ret.safetyConfigs[0].safetyParam |= Panda.FLAG_HONDA_RADARLESS # min speed to enable ACC. if car can do stop and go, then set enabling speed diff --git a/selfdrive/car/honda/values.py b/selfdrive/car/honda/values.py index 1b0da8d7de6ce4..5d7e994ef81263 100644 --- a/selfdrive/car/honda/values.py +++ b/selfdrive/car/honda/values.py @@ -59,6 +59,8 @@ class HondaFlags(IntFlag): NIDEC_ALT_PCM_ACCEL = 32 NIDEC_ALT_SCM_MESSAGES = 64 + CANFD_CAR = 128 + # Car button codes class CruiseButtons: @@ -183,6 +185,13 @@ class CAR(Platforms): CarSpecs(mass=3338.8 * CV.LB_TO_KG, wheelbase=2.5, centerToFrontRatio=0.5, steerRatio=16.71, tireStiffnessFactor=0.82), dbc_dict('acura_rdx_2020_can_generated', None), ) + HONDA_CRV_HYBRID_6G = HondaBoschPlatformConfig( + [HondaCarDocs("Honda CR-V Hybrid 2024", "All")], + # mass: mean of 4 models in kg, steerRatio: 12.3 is spec end-to-end + CarSpecs(mass=1667, wheelbase=2.66, steerRatio=16, centerToFrontRatio=0.41, tireStiffnessFactor=0.677), + dbc_dict('honda_pilot_2023_can_generated', None), + flags=HondaFlags.CANFD_CAR, + ) # Nidec Cars ACURA_ILX = HondaNidecPlatformConfig( @@ -300,9 +309,9 @@ class CAR(Platforms): # We lose these ECUs without the comma power on these cars. # Note that we still attempt to match with them when they are present non_essential_ecus={ - Ecu.eps: [CAR.ACURA_RDX_3G, CAR.HONDA_ACCORD, CAR.HONDA_CIVIC_2022, CAR.HONDA_E, CAR.HONDA_HRV_3G], + Ecu.eps: [CAR.ACURA_RDX_3G, CAR.HONDA_ACCORD, CAR.HONDA_CIVIC_2022, CAR.HONDA_E, CAR.HONDA_HRV_3G, CAR.HONDA_CRV_HYBRID_6G], Ecu.vsa: [CAR.ACURA_RDX_3G, CAR.HONDA_ACCORD, CAR.HONDA_CIVIC, CAR.HONDA_CIVIC_BOSCH, CAR.HONDA_CIVIC_2022, CAR.HONDA_CRV_5G, CAR.HONDA_CRV_HYBRID, - CAR.HONDA_E, CAR.HONDA_HRV_3G, CAR.HONDA_INSIGHT], + CAR.HONDA_E, CAR.HONDA_HRV_3G, CAR.HONDA_INSIGHT, CAR.HONDA_CRV_HYBRID_6G], }, extra_ecus=[ (Ecu.combinationMeter, 0x18da60f1, None), @@ -324,6 +333,7 @@ class CAR(Platforms): 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) +HONDA_CANFD_CAR = CAR.with_flags(HondaFlags.CANFD_CAR) DBC = CAR.create_dbc_map() diff --git a/selfdrive/car/tests/routes.py b/selfdrive/car/tests/routes.py index dd3a8f633d2693..53def320fa8d52 100755 --- a/selfdrive/car/tests/routes.py +++ b/selfdrive/car/tests/routes.py @@ -98,6 +98,7 @@ class CarTestRoute(NamedTuple): CarTestRoute("54fd8451b3974762|2021-04-01--14-50-10", HONDA.HONDA_RIDGELINE), CarTestRoute("2d5808fae0b38ac6|2021-09-01--17-14-11", HONDA.HONDA_E), CarTestRoute("f44aa96ace22f34a|2021-12-22--06-22-31", HONDA.HONDA_CIVIC_2022), + CarTestRoute("197afc441c1f8c4f|2024-02-21--11-18-08", HONDA.HONDA_CRV_HYBRID_6G), CarTestRoute("87d7f06ade479c2e|2023-09-11--23-30-11", HYUNDAI.HYUNDAI_AZERA_6TH_GEN), CarTestRoute("66189dd8ec7b50e6|2023-09-20--07-02-12", HYUNDAI.HYUNDAI_AZERA_HEV_6TH_GEN), diff --git a/selfdrive/car/torque_data/substitute.toml b/selfdrive/car/torque_data/substitute.toml index 8724a08010e3b0..af54830b2a7e77 100644 --- a/selfdrive/car/torque_data/substitute.toml +++ b/selfdrive/car/torque_data/substitute.toml @@ -48,6 +48,7 @@ legend = ["LAT_ACCEL_FACTOR", "MAX_LAT_ACCEL_MEASURED", "FRICTION"] "HONDA_CIVIC_BOSCH_DIESEL" = "HONDA_CIVIC_BOSCH" "HONDA_E" = "HONDA_CIVIC_BOSCH" "HONDA_ODYSSEY_CHN" = "HONDA_ODYSSEY" +"HONDA_CRV_HYBRID_6G" = "HONDA_CRV_HYBRID" "BUICK_LACROSSE" = "CHEVROLET_VOLT" "BUICK_REGAL" = "CHEVROLET_VOLT"