diff --git a/opendbc b/opendbc index 3c926e88e87594..d3489b5ec8d427 160000 --- a/opendbc +++ b/opendbc @@ -1 +1 @@ -Subproject commit 3c926e88e87594e788ab96d32ecdd8f66cb01aed +Subproject commit d3489b5ec8d4278debe67a85090bb03e50277023 diff --git a/panda b/panda index 01c54d11990fb8..523534ccaff6b6 160000 --- a/panda +++ b/panda @@ -1 +1 @@ -Subproject commit 01c54d11990fb82b85acc322a6e2e34a4b7ee389 +Subproject commit 523534ccaff6b67e6e86774d96f75fcf37366b4b diff --git a/selfdrive/car/honda/carcontroller.py b/selfdrive/car/honda/carcontroller.py index 6fe8c275850f6e..21a614caebf2c1 100644 --- a/selfdrive/car/honda/carcontroller.py +++ b/selfdrive/car/honda/carcontroller.py @@ -203,11 +203,28 @@ def update(self, CC, CS, now_nanos): if not self.CP.openpilotLongitudinalControl: if self.frame % 2 == 0 and self.CP.carFingerprint not in HONDA_BOSCH_RADARLESS: # radarless cars don't have supplemental message can_sends.append(hondacan.create_bosch_supplemental_1(self.packer, self.CAN, self.CP.carFingerprint)) - # If using stock ACC, spam cancel command to kill gas when OP disengages. + # Buttons: spam the cancel or resume buttons. + cruise = None + setting = CruiseButtons.NONE if pcm_cancel_cmd: - can_sends.append(hondacan.spam_buttons_command(self.packer, self.CAN, CruiseButtons.CANCEL, self.CP.carFingerprint)) - elif CC.cruiseControl.resume: - can_sends.append(hondacan.spam_buttons_command(self.packer, self.CAN, CruiseButtons.RES_ACCEL, self.CP.carFingerprint)) + cruise = CruiseButtons.CANCEL + elif self.CP.carFingerprint not in HONDA_BOSCH_RADARLESS and CC.cruiseControl.resume: + cruise = CruiseButtons.RES_ACCEL + elif self.CP.carFingerprint in HONDA_BOSCH_RADARLESS and CC.enabled and self.frame % 4 == 0: + # Send buttons to the camera when engaged. Only send the LKAS button to turn off stock LKAS off so it can't disengage cruise. + # Priority: pcm_cancel > user > auto resume > turn off lkas > none/idle + cruise = CruiseButtons.NONE + if CS.cruise_buttons or (CS.cruise_setting and CS.cruise_setting != CruiseButtons.LKAS): + cruise = CS.cruise_buttons + setting = CS.cruise_setting + # simulate a momentary press + elif self.frame % 100 <= 25: + if CC.cruiseControl.resume: + cruise = CruiseButtons.RES_ACCEL + elif CS.lkas_hud['ENABLED']: + setting = CruiseButtons.LKAS + if cruise is not None: + can_sends.append(hondacan.create_buttons_command(self.packer, self.CAN, cruise, setting, CS.scm_buttons, self.CP.carFingerprint)) else: # Send gas and brake commands. diff --git a/selfdrive/car/honda/carstate.py b/selfdrive/car/honda/carstate.py index c98d1a72d3cc15..46bcde96fbcc82 100644 --- a/selfdrive/car/honda/carstate.py +++ b/selfdrive/car/honda/carstate.py @@ -8,7 +8,7 @@ from openpilot.selfdrive.car.honda.hondacan import CanBus, get_cruise_speed_conversion from openpilot.selfdrive.car.honda.values import CAR, DBC, STEER_THRESHOLD, HONDA_BOSCH, \ HONDA_NIDEC_ALT_SCM_MESSAGES, HONDA_BOSCH_RADARLESS, \ - HondaFlags + HondaFlags, GearShifter from openpilot.selfdrive.car.interfaces import CarStateBase TransmissionType = car.CarParams.TransmissionType @@ -16,7 +16,6 @@ def get_can_messages(CP, gearbox_msg): messages = [ - ("ENGINE_DATA", 100), ("WHEEL_SPEEDS", 50), ("STEERING_SENSORS", 100), ("SEATBELT_STATUS", 10), @@ -38,8 +37,11 @@ def get_can_messages(CP, gearbox_msg): ("SCM_FEEDBACK", 10), ("SCM_BUTTONS", 25), ] - - if CP.carFingerprint in (CAR.HONDA_CRV_HYBRID, CAR.HONDA_CIVIC_BOSCH_DIESEL, CAR.ACURA_RDX_3G, CAR.HONDA_E): + if CP.carFingerprint not in (CAR.ACURA_INTEGRA): + messages += [ + ("ENGINE_DATA", 100), + ] + if CP.carFingerprint in (CAR.HONDA_CRV_HYBRID, CAR.HONDA_CIVIC_BOSCH_DIESEL, CAR.ACURA_RDX_3G, CAR.HONDA_E, CAR.ACURA_INTEGRA): messages.append((gearbox_msg, 50)) else: messages.append((gearbox_msg, 100)) @@ -65,7 +67,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.ACURA_INTEGRA): pass elif CP.carFingerprint in (CAR.HONDA_ODYSSEY_CHN, CAR.HONDA_FREED, CAR.HONDA_HRV): pass @@ -87,12 +89,15 @@ def __init__(self, CP): self.gearbox_msg = "GEARBOX" if CP.carFingerprint == CAR.HONDA_ACCORD and CP.transmissionType == TransmissionType.cvt: self.gearbox_msg = "GEARBOX_15T" + elif CP.transmissionType == TransmissionType.manual: + self.gearbox_msg = "GEARBOX_BOH" self.main_on_sig_msg = "SCM_FEEDBACK" if CP.carFingerprint in HONDA_NIDEC_ALT_SCM_MESSAGES: self.main_on_sig_msg = "SCM_BUTTONS" - self.shifter_values = can_define.dv[self.gearbox_msg]["GEAR_SHIFTER"] + if CP.transmissionType != TransmissionType.manual: + self.shifter_values = can_define.dv[self.gearbox_msg]["GEAR_SHIFTER"] self.steer_status_values = defaultdict(lambda: "UNKNOWN", can_define.dv["STEER_STATUS"]["STEER_STATUS"]) self.brake_switch_prev = False @@ -123,10 +128,13 @@ def update(self, cp, cp_cam, cp_body): # ******************* parse out can ******************* # STANDSTILL->WHEELS_MOVING bit can be noisy around zero, so use XMISSION_SPEED # panda checks if the signal is non-zero - ret.standstill = cp.vl["ENGINE_DATA"]["XMISSION_SPEED"] < 1e-5 + if self.CP.carFingerprint == CAR.ACURA_INTEGRA: + ret.standstill = cp.vl["CAR_SPEED"]["CAR_SPEED"] < 1e-5 + else: + 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.ACURA_INTEGRA): 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"]) @@ -165,7 +173,10 @@ def update(self, cp, cp_cam, cp_body): # blend in transmission speed at low speed, since it has more low speed accuracy v_weight = interp(v_wheel, v_weight_bp, v_weight_v) - ret.vEgoRaw = (1. - v_weight) * cp.vl["ENGINE_DATA"]["XMISSION_SPEED"] * CV.KPH_TO_MS * self.CP.wheelSpeedFactor + v_weight * v_wheel + if self.CP.carFingerprint == CAR.ACURA_INTEGRA: + ret.vEgoRaw = (1. - v_weight) * cp.vl["CAR_SPEED"]["CAR_SPEED"] * CV.KPH_TO_MS * self.CP.wheelSpeedFactor + v_weight * v_wheel + else: + ret.vEgoRaw = (1. - v_weight) * cp.vl["ENGINE_DATA"]["XMISSION_SPEED"] * CV.KPH_TO_MS * self.CP.wheelSpeedFactor + v_weight * v_wheel ret.vEgo, ret.aEgo = self.update_speed_kf(ret.vEgoRaw) self.dash_speed_seen = self.dash_speed_seen or cp.vl["CAR_SPEED"]["ROUGH_CAR_SPEED_2"] > 1e-3 @@ -184,8 +195,16 @@ def update(self, cp, cp_cam, cp_body): if self.CP.carFingerprint in (HONDA_BOSCH | {CAR.HONDA_CIVIC, CAR.HONDA_ODYSSEY, CAR.HONDA_ODYSSEY_CHN}): ret.parkingBrake = cp.vl["EPB_STATUS"]["EPB_STATE"] != 0 - gear = int(cp.vl[self.gearbox_msg]["GEAR_SHIFTER"]) - ret.gearShifter = self.parse_gear_shifter(self.shifter_values.get(gear, None)) + if self.CP.transmissionType == TransmissionType.manual: + ret.clutchPressed = cp.vl["GEARBOX_BOH"]["GEAR_MT"] == 0 + if cp.vl["GEARBOX_BOH"]["GEAR_MT"] == 14: + ret.gearShifter = GearShifter.reverse + else: + ret.gearShifter = GearShifter.drive + else: + gear = int(cp.vl[self.gearbox_msg]["GEAR_SHIFTER"]) + ret.gearShifter = self.parse_gear_shifter(self.shifter_values.get(gear, None)) + ret.gas = cp.vl["POWERTRAIN_DATA"]["PEDAL_GAS"] ret.gasPressed = ret.gas > 1e-5 @@ -200,6 +219,7 @@ def update(self, cp, cp_cam, cp_body): ret.cruiseState.nonAdaptive = cp_cam.vl["ACC_HUD"]["CRUISE_CONTROL_LABEL"] != 0 if not self.CP.openpilotLongitudinalControl: + self.scm_buttons = cp.vl["SCM_BUTTONS"] if self.CP.carFingerprint in HONDA_BOSCH_RADARLESS else {} # ACC_HUD is on camera bus on radarless cars acc_hud = cp_cam.vl["ACC_HUD"] if self.CP.carFingerprint in HONDA_BOSCH_RADARLESS else cp.vl["ACC_HUD"] ret.cruiseState.nonAdaptive = acc_hud["CRUISE_CONTROL_LABEL"] != 0 diff --git a/selfdrive/car/honda/fingerprints.py b/selfdrive/car/honda/fingerprints.py index c1714fe81038ac..8722a770dedf76 100644 --- a/selfdrive/car/honda/fingerprints.py +++ b/selfdrive/car/honda/fingerprints.py @@ -1411,4 +1411,28 @@ b'37805-64S-AA10\x00\x00', ], }, + CAR.ACURA_INTEGRA: { + (Ecu.eps, 0x18da30f1, None): [ + b'39990-T38-A040\x00\x00', + ], + (Ecu.gateway, 0x18daeff1, None): [ + b'38897-3S5-A110\x00\x00', + b'38897-3S5-A210\x00\x00', + ], + (Ecu.srs, 0x18da53f1, None): [ + b'77959-3S5-A920\x00\x00', + ], + (Ecu.combinationMeter, 0x18da60f1, None): [ + b'78108-3S5-AC20\x00\x00', + b'78108-3S5-A220\x00\x00', + ], + (Ecu.vsa, 0x18da28f1, None): [ + b'57114-3S5-CA30\x00\x00', + b'57114-3S5-CB30\x00\x00' + ], + (Ecu.programmedFuelInjection, 0x18da10f1, None): [ + b'37805-6LM-A020\x00\x00', + b'37805-6LM-A520\x00\x00', + ], + }, } diff --git a/selfdrive/car/honda/hondacan.py b/selfdrive/car/honda/hondacan.py index 1be496d9511612..1b7fdf535eb433 100644 --- a/selfdrive/car/honda/hondacan.py +++ b/selfdrive/car/honda/hondacan.py @@ -167,7 +167,8 @@ def create_ui_commands(packer, CAN, CP, enabled, pcm_speed, hud, is_metric, acc_ commands.append(packer.make_can_msg("ACC_HUD", CAN.pt, acc_hud_values)) lkas_hud_values = { - 'SET_ME_X41': 0x41, + 'ENABLED': 1, + 'SET_ME_X20': 0x20, 'STEERING_REQUIRED': hud.steer_required, 'SOLID_LANES': hud.lanes_visible, 'BEEP': 0, @@ -201,11 +202,17 @@ def create_ui_commands(packer, CAN, CP, enabled, pcm_speed, hud, is_metric, acc_ return commands -def spam_buttons_command(packer, CAN, button_val, car_fingerprint): +def create_buttons_command(packer, CAN, button_val, setting_val, stock_scm_buttons, car_fingerprint): values = { - 'CRUISE_BUTTONS': button_val, - 'CRUISE_SETTING': 0, + 'CRUISE_BUTTONS': button_val } + # Radarless: set CRUISE_SETTING & forward unmodified data bits + if len(stock_scm_buttons): + values.update({ + 'CRUISE_SETTING': setting_val, + 'BOH_1': stock_scm_buttons['BOH_1'], + 'BOH_2': stock_scm_buttons['BOH_2'], + }) # send buttons to camera on radarless cars bus = CAN.camera if car_fingerprint in HONDA_BOSCH_RADARLESS else CAN.pt return packer.make_can_msg("SCM_BUTTONS", bus, values) diff --git a/selfdrive/car/honda/interface.py b/selfdrive/car/honda/interface.py index 2a5a07093d9732..f0f1301041f9cc 100755 --- a/selfdrive/car/honda/interface.py +++ b/selfdrive/car/honda/interface.py @@ -62,6 +62,9 @@ def _get_params(ret, candidate, fingerprint, car_fw, experimental_long, docs): # Accord ICE 1.5T CVT has different gearbox message if candidate == CAR.HONDA_ACCORD and 0x191 in fingerprint[CAN.pt]: ret.transmissionType = TransmissionType.cvt + # Integra has MT option + elif candidate == CAR.ACURA_INTEGRA and 0x191 not in fingerprint[CAN.pt]: + ret.transmissionType = TransmissionType.manual # Certain Hondas have an extra steering sensor at the bottom of the steering rack, # which improves controls quality as it removes the steering column torsion from feedback. @@ -103,7 +106,7 @@ def _get_params(ret, candidate, fingerprint, car_fw, experimental_long, docs): ret.lateralParams.torqueBP, ret.lateralParams.torqueV = [[0, 2560], [0, 2560]] ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[1.1], [0.33]] - elif candidate in (CAR.HONDA_CIVIC_BOSCH, CAR.HONDA_CIVIC_BOSCH_DIESEL, CAR.HONDA_CIVIC_2022): + elif candidate in (CAR.HONDA_CIVIC_BOSCH, CAR.HONDA_CIVIC_BOSCH_DIESEL, CAR.HONDA_CIVIC_2022, CAR.ACURA_INTEGRA): 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]] diff --git a/selfdrive/car/honda/values.py b/selfdrive/car/honda/values.py index 36cdbc87328d1d..bf7e19191360e9 100644 --- a/selfdrive/car/honda/values.py +++ b/selfdrive/car/honda/values.py @@ -10,6 +10,7 @@ Ecu = car.CarParams.Ecu VisualAlert = car.CarControl.HUDControl.VisualAlert +GearShifter = car.CarState.GearShifter class CarControllerParams: @@ -66,6 +67,11 @@ class CruiseButtons: DECEL_SET = 3 CANCEL = 2 MAIN = 1 + NONE = 0 + +# CRUISE_SETTINGS + DISTANCE = 3 + LKAS = 1 class CruiseSettings: @@ -183,6 +189,12 @@ 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), ) + ACURA_INTEGRA = HondaBoschPlatformConfig( + [HondaCarDocs("Acura Integra 2024", "All")], + CarSpecs(mass=3338.8 * CV.LB_TO_KG, wheelbase=2.5, centerToFrontRatio=0.5, steerRatio=16.71, tireStiffnessFactor=0.82), + dbc_dict('honda_civic_ex_2022_can_generated', None), + flags=HondaFlags.BOSCH_RADARLESS, + ) # Nidec Cars ACURA_ILX = HondaNidecPlatformConfig( diff --git a/selfdrive/car/tests/routes.py b/selfdrive/car/tests/routes.py index 036f39c1f35df3..5339095991987e 100755 --- a/selfdrive/car/tests/routes.py +++ b/selfdrive/car/tests/routes.py @@ -96,6 +96,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("3f8ae015ce70365f/0000002b--d07abeff02", HONDA.ACURA_INTEGRA), 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 22ee134ae374aa..e81f109cf66965 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" +"ACURA_INTEGRA" = "HONDA_CIVIC_2022" "BUICK_LACROSSE" = "CHEVROLET_VOLT" "BUICK_REGAL" = "CHEVROLET_VOLT"