diff --git a/selfdrive/car/honda/carcontroller.py b/selfdrive/car/honda/carcontroller.py index fe023ea17d714e..b0716ca84e42fd 100644 --- a/selfdrive/car/honda/carcontroller.py +++ b/selfdrive/car/honda/carcontroller.py @@ -5,7 +5,8 @@ from openpilot.common.realtime import DT_CTRL from opendbc.can.packer import CANPacker from openpilot.selfdrive.car.honda import hondacan -from openpilot.selfdrive.car.honda.values import CruiseButtons, VISUAL_HUD, HONDA_BOSCH, HONDA_BOSCH_RADARLESS, HONDA_NIDEC_ALT_PCM_ACCEL, CarControllerParams +from openpilot.selfdrive.car.honda.values import CruiseButtons, CruiseSettings, VISUAL_HUD, HONDA_BOSCH, HONDA_BOSCH_RADARLESS, HONDA_NIDEC_ALT_PCM_ACCEL, \ + CarControllerParams from openpilot.selfdrive.car.interfaces import CarControllerBase from openpilot.selfdrive.controls.lib.drive_helpers import rate_limit @@ -203,11 +204,24 @@ 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 = CruiseSettings.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. Priority: pcm_cancel > user > auto resume > none/idle + cruise = CruiseButtons.NONE + if CS.cruise_buttons or CS.cruise_setting: + cruise = CS.cruise_buttons + setting = CS.cruise_setting + # simulate a momentary press + elif self.frame % 100 <= 25 and CC.cruiseControl.resume: + cruise = CruiseButtons.RES_ACCEL + 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..01ccff8de3a279 100644 --- a/selfdrive/car/honda/carstate.py +++ b/selfdrive/car/honda/carstate.py @@ -200,6 +200,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/hondacan.py b/selfdrive/car/honda/hondacan.py index 1be496d9511612..ceb5026a24b6a6 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, + 'LKAS_ON': 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/values.py b/selfdrive/car/honda/values.py index c3005c667c822e..d0c637f63e411f 100644 --- a/selfdrive/car/honda/values.py +++ b/selfdrive/car/honda/values.py @@ -66,11 +66,13 @@ class CruiseButtons: DECEL_SET = 3 CANCEL = 2 MAIN = 1 + NONE = 0 class CruiseSettings: DISTANCE = 3 LKAS = 1 + NONE = 0 # See dbc files for info on values diff --git a/selfdrive/car/tests/routes.py b/selfdrive/car/tests/routes.py index dd3a8f633d2693..d4b73a46eaa8cc 100755 --- a/selfdrive/car/tests/routes.py +++ b/selfdrive/car/tests/routes.py @@ -97,7 +97,7 @@ class CarTestRoute(NamedTuple): CarTestRoute("f34a60d68d83b1e5|2020-10-06--14-35-55", HONDA.ACURA_RDX), 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("f44aa96ace22f34a|2021-12-22--06-22-31", HONDA.HONDA_CIVIC_2022), # TODO: Replace with route where OP sends buttons to the cam when engaged 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),