diff --git a/selfdrive/car/chrysler/carcontroller.py b/selfdrive/car/chrysler/carcontroller.py index f9277af62e..54bed40b51 100644 --- a/selfdrive/car/chrysler/carcontroller.py +++ b/selfdrive/car/chrysler/carcontroller.py @@ -1,3 +1,5 @@ +from cereal import car + import cereal.messaging as messaging from common.conversions import Conversions as CV from opendbc.can.packer import CANPacker @@ -9,7 +11,7 @@ from openpilot.selfdrive.car.chrysler.values import RAM_CARS, RAM_DT, CarControl from openpilot.selfdrive.car.interfaces import CarControllerBase, FORWARD_GEARS from openpilot.selfdrive.controls.lib.drive_helpers import FCA_V_CRUISE_MIN -BUTTONS_STATES = ["accelCruise", "decelCruise", "cancel", "resumeCruise"] +ButtonType = car.CarState.ButtonEvent.Type class CarController(CarControllerBase): @@ -104,7 +106,7 @@ class CarController(CarControllerBase): self.last_button_frame = CS.button_counter if ram_cars: - if CS.buttonStates["cancel"]: + if any(b.type == ButtonType.cancel for b in CS.out.buttonEvents): can_sends.append(chryslercan.create_cruise_buttons(self.packer, CS.button_counter, das_bus, self.CP, cancel=True)) else: can_sends.append(chryslercan.create_cruise_buttons(self.packer, CS.button_counter, das_bus, self.CP, @@ -189,8 +191,10 @@ class CarController(CarControllerBase): # multikyd methods, sunnyhaibin logic def get_cruise_buttons_status(self, CS): - if not CS.out.cruiseState.enabled or any(CS.buttonStates[button_state] for button_state in BUTTONS_STATES): - self.timer = 40 + if not CS.out.cruiseState.enabled: + for be in CS.out.buttonEvents: + if be.type in (ButtonType.accelCruise, ButtonType.decelCruise, ButtonType.resumeCruise) and be.pressed: + self.timer = 40 elif self.timer: self.timer -= 1 else: diff --git a/selfdrive/car/chrysler/carstate.py b/selfdrive/car/chrysler/carstate.py index d29be9226e..6d949e9f9a 100644 --- a/selfdrive/car/chrysler/carstate.py +++ b/selfdrive/car/chrysler/carstate.py @@ -3,7 +3,7 @@ from openpilot.common.conversions import Conversions as CV from opendbc.can.parser import CANParser from opendbc.can.can_define import CANDefine from openpilot.selfdrive.car.interfaces import CarStateBase -from openpilot.selfdrive.car.chrysler.values import DBC, STEER_THRESHOLD, RAM_CARS, BUTTON_STATES +from openpilot.selfdrive.car.chrysler.values import DBC, STEER_THRESHOLD, RAM_CARS, BUTTONS class CarState(CarStateBase): @@ -29,8 +29,7 @@ class CarState(CarStateBase): self.lkas_heartbit = None self.lkas_disabled = False - self.buttonStates = BUTTON_STATES.copy() - self.buttonStatesPrev = BUTTON_STATES.copy() + self.button_states = {button.event_type: False for button in BUTTONS} def update(self, cp, cp_cam): @@ -41,7 +40,6 @@ class CarState(CarStateBase): self.prev_mads_enabled = self.mads_enabled self.prev_lkas_enabled = self.lkas_enabled - self.buttonStatesPrev = self.buttonStates.copy() # lock info ret.doorOpen = any([cp.vl["BCM_1"]["DOOR_OPEN_FL"], @@ -76,6 +74,18 @@ class CarState(CarStateBase): unit=1, ) + # Buttons + button_events = [] + for button in BUTTONS: + state = (cp.vl[button.can_addr][button.can_msg] in button.values) + if self.button_states[button.event_type] != state: + event = car.CarState.ButtonEvent.new_message() + event.type = button.event_type + event.pressed = state + button_events.append(event) + self.button_states[button.event_type] = state + self.button_events = button_events + # button presses ret.leftBlinker, ret.rightBlinker = ret.leftBlinkerOn, ret.rightBlinkerOn = self.update_blinker_from_stalk(200, cp.vl["STEERING_LEVERS"]["TURN_SIGNALS"] == 1, cp.vl["STEERING_LEVERS"]["TURN_SIGNALS"] == 2) @@ -116,11 +126,6 @@ class CarState(CarStateBase): ret.leftBlindspot = cp.vl["BSM_1"]["LEFT_STATUS"] == 1 ret.rightBlindspot = cp.vl["BSM_1"]["RIGHT_STATUS"] == 1 - self.buttonStates["accelCruise"] = bool(cp.vl["CRUISE_BUTTONS"]["ACC_Accel"]) - self.buttonStates["decelCruise"] = bool(cp.vl["CRUISE_BUTTONS"]["ACC_Decel"]) - self.buttonStates["cancel"] = bool(cp.vl["CRUISE_BUTTONS"]["ACC_Cancel"]) - self.buttonStates["resumeCruise"] = bool(cp.vl["CRUISE_BUTTONS"]["ACC_Resume"]) - self.lkas_car_model = cp_cam.vl["DAS_6"]["CAR_MODEL"] self.button_counter = cp.vl["CRUISE_BUTTONS"]["COUNTER"] self.cruise_buttons = cp.vl["CRUISE_BUTTONS"] diff --git a/selfdrive/car/chrysler/interface.py b/selfdrive/car/chrysler/interface.py index d09fa7ac56..bc80530011 100755 --- a/selfdrive/car/chrysler/interface.py +++ b/selfdrive/car/chrysler/interface.py @@ -2,7 +2,7 @@ from cereal import car from panda import Panda from openpilot.selfdrive.car import create_button_events, get_safety_config, create_mads_event -from openpilot.selfdrive.car.chrysler.values import CAR, RAM_HD, RAM_DT, RAM_CARS, ChryslerFlags, ChryslerFlagsSP, BUTTON_STATES +from openpilot.selfdrive.car.chrysler.values import CAR, RAM_HD, RAM_DT, RAM_CARS, ChryslerFlags, ChryslerFlagsSP from openpilot.selfdrive.car.interfaces import CarInterfaceBase ButtonType = car.CarState.ButtonEvent.Type @@ -13,7 +13,6 @@ GearShifter = car.CarState.GearShifter class CarInterface(CarInterfaceBase): def __init__(self, CP, CarController, CarState): super().__init__(CP, CarController, CarState) - self.buttonStatesPrev = BUTTON_STATES.copy() @staticmethod def _get_params(ret, candidate, fingerprint, car_fw, experimental_long, docs): @@ -94,19 +93,15 @@ class CarInterface(CarInterfaceBase): ret = self.CS.update(self.cp, self.cp_cam) self.sp_update_params() - buttonEvents = create_button_events(self.CS.distance_button, self.CS.prev_distance_button, {1: ButtonType.gapAdjustCruise}) - - for button in self.CS.buttonStates: - if self.CS.buttonStates[button] != self.buttonStatesPrev[button]: - be = car.CarState.ButtonEvent.new_message() - be.type = button - be.pressed = self.CS.buttonStates[button] - buttonEvents.append(be) + self.CS.button_events = [ + *self.CS.button_events, + *create_button_events(self.CS.distance_button, self.CS.prev_distance_button, {1: ButtonType.gapAdjustCruise}) + ] self.CS.mads_enabled = self.get_sp_cruise_main_state(ret, self.CS) self.CS.accEnabled = self.get_sp_v_cruise_non_pcm_state(ret, self.CS.accEnabled, - buttonEvents, c.vCruise, + self.CS.button_events, c.vCruise, enable_buttons=(ButtonType.accelCruise, ButtonType.decelCruise, ButtonType.resumeCruise) if not self.CP.pcmCruiseSpeed else (ButtonType.accelCruise, ButtonType.decelCruise), resume_button=(ButtonType.resumeCruise,) if not self.CP.pcmCruiseSpeed else @@ -125,7 +120,7 @@ class CarInterface(CarInterfaceBase): self.CS.madsEnabled = self.get_sp_started_mads(ret, self.CS) if not self.CP.pcmCruise or (self.CP.pcmCruise and self.CP.minEnableSpeed > 0) or not self.CP.pcmCruiseSpeed: - if any(b.type == ButtonType.cancel for b in buttonEvents): + if any(b.type == ButtonType.cancel for b in self.CS.button_events): self.CS.madsEnabled, self.CS.accEnabled = self.get_sp_cancel_cruise_state(self.CS.madsEnabled) if self.get_sp_pedal_disengage(ret): self.CS.madsEnabled, self.CS.accEnabled = self.get_sp_cancel_cruise_state(self.CS.madsEnabled) @@ -146,14 +141,14 @@ class CarInterface(CarInterfaceBase): # MADS BUTTON if self.CS.out.madsEnabled != self.CS.madsEnabled: if self.mads_event_lock: - buttonEvents.append(create_mads_event(self.mads_event_lock)) + self.CS.button_events.append(create_mads_event(self.mads_event_lock)) self.mads_event_lock = False else: if not self.mads_event_lock: - buttonEvents.append(create_mads_event(self.mads_event_lock)) + self.CS.button_events.append(create_mads_event(self.mads_event_lock)) self.mads_event_lock = True - ret.buttonEvents = buttonEvents + ret.buttonEvents = self.CS.button_events # events events = self.create_common_events(ret, c, extra_gears=[car.CarState.GearShifter.low], pcm_enable=False) @@ -180,6 +175,4 @@ class CarInterface(CarInterfaceBase): ret.events = events.to_msg() - self.buttonStatesPrev = self.CS.buttonStates.copy() - return ret diff --git a/selfdrive/car/chrysler/values.py b/selfdrive/car/chrysler/values.py index 85835d453a..c681040023 100644 --- a/selfdrive/car/chrysler/values.py +++ b/selfdrive/car/chrysler/values.py @@ -1,3 +1,4 @@ +from collections import namedtuple from enum import IntFlag from dataclasses import dataclass, field @@ -8,6 +9,7 @@ from openpilot.selfdrive.car.docs_definitions import CarHarness, CarDocs, CarPar from openpilot.selfdrive.car.fw_query_definitions import FwQueryConfig, Request, p16 Ecu = car.CarParams.Ecu +Button = namedtuple('Button', ['event_type', 'can_addr', 'can_msg', 'values']) class ChryslerFlags(IntFlag): @@ -113,12 +115,12 @@ class CarControllerParams: self.STEER_MAX = 261 # higher than this faults the EPS -BUTTON_STATES = { - "accelCruise": False, - "decelCruise": False, - "cancel": False, - "resumeCruise": False, -} +BUTTONS = [ + Button(car.CarState.ButtonEvent.Type.accelCruise, "CRUISE_BUTTONS", "ACC_Accel", [1]), + Button(car.CarState.ButtonEvent.Type.decelCruise, "CRUISE_BUTTONS", "ACC_Decel", [1]), + Button(car.CarState.ButtonEvent.Type.cancel, "CRUISE_BUTTONS", "ACC_Cancel", [1]), + Button(car.CarState.ButtonEvent.Type.resumeCruise, "CRUISE_BUTTONS", "ACC_Resume", [1]), +] STEER_THRESHOLD = 120 diff --git a/selfdrive/car/ford/carstate.py b/selfdrive/car/ford/carstate.py index 99ed6e83b5..2d512c383d 100644 --- a/selfdrive/car/ford/carstate.py +++ b/selfdrive/car/ford/carstate.py @@ -3,7 +3,7 @@ from opendbc.can.can_define import CANDefine from opendbc.can.parser import CANParser from openpilot.common.conversions import Conversions as CV from openpilot.selfdrive.car.ford.fordcan import CanBus -from openpilot.selfdrive.car.ford.values import DBC, CarControllerParams, FordFlags, BUTTON_STATES +from openpilot.selfdrive.car.ford.values import DBC, CarControllerParams, FordFlags, BUTTONS from openpilot.selfdrive.car.interfaces import CarStateBase GearShifter = car.CarState.GearShifter @@ -24,16 +24,15 @@ class CarState(CarStateBase): self.lkas_enabled = None self.prev_lkas_enabled = None - self.buttonStates = BUTTON_STATES.copy() - self.buttonStatesPrev = BUTTON_STATES.copy() self.v_limit = 0 + self.button_states = {button.event_type: False for button in BUTTONS} + def update(self, cp, cp_cam): ret = car.CarState.new_message() self.prev_mads_enabled = self.mads_enabled self.prev_lkas_enabled = self.lkas_enabled - self.buttonStatesPrev = self.buttonStates.copy() # Occasionally on startup, the ABS module recalibrates the steering pinion offset, so we need to block engagement # The vehicle usually recovers out of this state within a minute of normal driving @@ -92,6 +91,18 @@ class CarState(CarStateBase): else: ret.gearShifter = GearShifter.drive + # Buttons + button_events = [] + for button in BUTTONS: + state = (cp.vl[button.can_addr][button.can_msg] in button.values) + if self.button_states[button.event_type] != state: + event = car.CarState.ButtonEvent.new_message() + event.type = button.event_type + event.pressed = state + button_events.append(event) + self.button_states[button.event_type] = state + self.button_events = button_events + # safety ret.stockFcw = bool(cp_cam.vl["ACCDATA_3"]["FcwVisblWarn_B_Rq"]) ret.stockAeb = bool(cp_cam.vl["ACCDATA_2"]["CmbbBrkDecel_B_Rq"]) @@ -117,13 +128,6 @@ class CarState(CarStateBase): self.lkas_enabled = bool(cp.vl["Steering_Data_FD1"]["TjaButtnOnOffPress"]) - self.buttonStates["accelCruise"] = bool(cp.vl["Steering_Data_FD1"]["CcAslButtnSetIncPress"]) - self.buttonStates["decelCruise"] = bool(cp.vl["Steering_Data_FD1"]["CcAslButtnSetDecPress"]) - self.buttonStates["cancel"] = bool(cp.vl["Steering_Data_FD1"]["CcAslButtnCnclPress"]) - self.buttonStates["setCruise"] = bool(cp.vl["Steering_Data_FD1"]["CcAslButtnSetPress"]) - self.buttonStates["resumeCruise"] = bool(cp.vl["Steering_Data_FD1"]["CcAsllButtnResPress"]) - self.buttonStates["gapAdjustCruise"] = bool(cp.vl["Steering_Data_FD1"]["AccButtnGapTogglePress"]) - # Stock steering buttons so that we can passthru blinkers etc. self.buttons_stock_values = cp.vl["Steering_Data_FD1"] # Stock values from IPMA so that we can retain some stock functionality diff --git a/selfdrive/car/ford/interface.py b/selfdrive/car/ford/interface.py index 89dc10ecdd..6045339557 100644 --- a/selfdrive/car/ford/interface.py +++ b/selfdrive/car/ford/interface.py @@ -4,7 +4,7 @@ from openpilot.common.conversions import Conversions as CV from openpilot.selfdrive.car import create_button_events, get_safety_config, create_mads_event from openpilot.selfdrive.car.ford.fordcan import CanBus from openpilot.common.params import Params -from openpilot.selfdrive.car.ford.values import Ecu, FordFlags, BUTTON_STATES, FordFlagsSP +from openpilot.selfdrive.car.ford.values import Ecu, FordFlags, FordFlagsSP from openpilot.selfdrive.car.interfaces import CarInterfaceBase ButtonType = car.CarState.ButtonEvent.Type @@ -16,8 +16,6 @@ class CarInterface(CarInterfaceBase): def __init__(self, CP, CarController, CarState): super().__init__(CP, CarController, CarState) - self.buttonStatesPrev = BUTTON_STATES.copy() - @staticmethod def _get_params(ret, candidate, fingerprint, car_fw, experimental_long, docs): ret.carName = "ford" @@ -86,19 +84,15 @@ class CarInterface(CarInterfaceBase): ret = self.CS.update(self.cp, self.cp_cam) self.sp_update_params() - buttonEvents = create_button_events(self.CS.distance_button, self.CS.prev_distance_button, {1: ButtonType.gapAdjustCruise}) - - for button in self.CS.buttonStates: - if self.CS.buttonStates[button] != self.buttonStatesPrev[button]: - be = car.CarState.ButtonEvent.new_message() - be.type = button - be.pressed = self.CS.buttonStates[button] - buttonEvents.append(be) + self.CS.button_events = [ + *self.CS.button_events, + *create_button_events(self.CS.distance_button, self.CS.prev_distance_button, {1: ButtonType.gapAdjustCruise}) + ] self.CS.mads_enabled = self.get_sp_cruise_main_state(ret, self.CS) self.CS.accEnabled = self.get_sp_v_cruise_non_pcm_state(ret, self.CS.accEnabled, - buttonEvents, c.vCruise) + self.CS.button_events, c.vCruise) if ret.cruiseState.available: if self.enable_mads: @@ -111,7 +105,7 @@ class CarInterface(CarInterfaceBase): self.CS.madsEnabled = False if not self.CP.pcmCruise or (self.CP.pcmCruise and self.CP.minEnableSpeed > 0): - if any(b.type == ButtonType.cancel for b in buttonEvents): + if any(b.type == ButtonType.cancel for b in self.CS.button_events): self.CS.madsEnabled, self.CS.accEnabled = self.get_sp_cancel_cruise_state(self.CS.madsEnabled) if self.get_sp_pedal_disengage(ret): self.CS.madsEnabled, self.CS.accEnabled = self.get_sp_cancel_cruise_state(self.CS.madsEnabled) @@ -126,14 +120,14 @@ class CarInterface(CarInterfaceBase): if self.CS.out.madsEnabled != self.CS.madsEnabled: if self.mads_event_lock: - buttonEvents.append(create_mads_event(self.mads_event_lock)) + self.CS.button_events.append(create_mads_event(self.mads_event_lock)) self.mads_event_lock = False else: if not self.mads_event_lock: - buttonEvents.append(create_mads_event(self.mads_event_lock)) + self.CS.button_events.append(create_mads_event(self.mads_event_lock)) self.mads_event_lock = True - ret.buttonEvents = buttonEvents + ret.buttonEvents = self.CS.button_events events = self.create_common_events(ret, c, extra_gears=[GearShifter.manumatic], pcm_enable=False) @@ -144,7 +138,4 @@ class CarInterface(CarInterfaceBase): ret.events = events.to_msg() - # update previous car states - self.buttonStatesPrev = self.CS.buttonStates.copy() - return ret diff --git a/selfdrive/car/ford/values.py b/selfdrive/car/ford/values.py index d11e54ac4e..7af6ec607f 100644 --- a/selfdrive/car/ford/values.py +++ b/selfdrive/car/ford/values.py @@ -1,5 +1,6 @@ import copy import re +from collections import namedtuple from dataclasses import dataclass, field, replace from enum import Enum, IntFlag @@ -11,6 +12,7 @@ from openpilot.selfdrive.car.docs_definitions import CarFootnote, CarHarness, Ca from openpilot.selfdrive.car.fw_query_definitions import FwQueryConfig, LiveFwVersions, OfflineFwVersions, Request, StdQueries, p16 Ecu = car.CarParams.Ecu +Button = namedtuple('Button', ['event_type', 'can_addr', 'can_msg', 'values']) class CarControllerParams: @@ -50,16 +52,6 @@ class FordFlagsSP(IntFlag): SP_ENHANCED_LAT_CONTROL = 1 -BUTTON_STATES = { - "accelCruise": False, - "decelCruise": False, - "cancel": False, - "setCruise": False, - "resumeCruise": False, - "gapAdjustCruise": False -} - - class RADAR: DELPHI_ESR = 'ford_fusion_2018_adas' DELPHI_MRR = 'FORD_CADS' @@ -159,6 +151,15 @@ class CAR(Platforms): ) +BUTTONS = [ + Button(car.CarState.ButtonEvent.Type.accelCruise, "Steering_Data_FD1", "CcAslButtnSetIncPress", [1]), + Button(car.CarState.ButtonEvent.Type.decelCruise, "Steering_Data_FD1", "CcAslButtnSetDecPress", [1]), + Button(car.CarState.ButtonEvent.Type.cancel, "Steering_Data_FD1", "CcAslButtnCnclPress", [1]), + Button(car.CarState.ButtonEvent.Type.setCruise, "Steering_Data_FD1", "CcAslButtnSetPress", [1]), + Button(car.CarState.ButtonEvent.Type.resumeCruise, "Steering_Data_FD1", "CcAsllButtnResPress", [1]), +] + + # FW response contains a combined software and part number # A-Z except no I, O or W # e.g. NZ6A-14C204-AAA diff --git a/selfdrive/car/gm/carstate.py b/selfdrive/car/gm/carstate.py index 2fc1ac024b..78092c23bd 100644 --- a/selfdrive/car/gm/carstate.py +++ b/selfdrive/car/gm/carstate.py @@ -33,6 +33,7 @@ class CarState(CarStateBase): self.prev_lkas_enabled = False def update(self, pt_cp, cam_cp, loopback_cp): + self.button_events = [] ret = car.CarState.new_message() self.prev_cruise_buttons = self.cruise_buttons diff --git a/selfdrive/car/gm/interface.py b/selfdrive/car/gm/interface.py index f39d150c2f..a570c547ff 100755 --- a/selfdrive/car/gm/interface.py +++ b/selfdrive/car/gm/interface.py @@ -207,12 +207,11 @@ class CarInterface(CarInterfaceBase): ret = self.CS.update(self.cp, self.cp_cam, self.cp_loopback) self.sp_update_params() - buttonEvents = [] distance_button = 0 # Don't add event if transitioning from INIT, unless it's to an actual button if self.CS.cruise_buttons != CruiseButtons.UNPRESS or self.CS.prev_cruise_buttons != CruiseButtons.INIT: - buttonEvents = [ + self.CS.button_events = [ *create_button_events(self.CS.cruise_buttons, self.CS.prev_cruise_buttons, BUTTONS_DICT, unpressed_btn=CruiseButtons.UNPRESS), *create_button_events(self.CS.distance_button, self.CS.prev_distance_button, @@ -223,11 +222,11 @@ class CarInterface(CarInterfaceBase): self.CS.mads_enabled = self.get_sp_cruise_main_state(ret, self.CS) if not self.CP.pcmCruise: - if any(b.type == ButtonType.accelCruise and b.pressed for b in buttonEvents): + if any(b.type == ButtonType.accelCruise and b.pressed for b in self.CS.button_events): self.CS.accEnabled = True self.CS.accEnabled = self.get_sp_v_cruise_non_pcm_state(ret, self.CS.accEnabled, - buttonEvents, c.vCruise) + self.CS.button_events, c.vCruise) if ret.cruiseState.available: if self.enable_mads: @@ -240,7 +239,7 @@ class CarInterface(CarInterfaceBase): self.CS.madsEnabled = False if not self.CP.pcmCruise or (self.CP.pcmCruise and self.CP.minEnableSpeed > 0) or not self.CP.pcmCruiseSpeed: - if any(b.type == ButtonType.cancel for b in buttonEvents): + if any(b.type == ButtonType.cancel for b in self.CS.button_events): self.CS.madsEnabled, self.CS.accEnabled = self.get_sp_cancel_cruise_state(self.CS.madsEnabled) if self.get_sp_pedal_disengage(ret): self.CS.madsEnabled, self.CS.accEnabled = self.get_sp_cancel_cruise_state(self.CS.madsEnabled) @@ -256,14 +255,14 @@ class CarInterface(CarInterfaceBase): # MADS BUTTON if self.CS.out.madsEnabled != self.CS.madsEnabled: if self.mads_event_lock: - buttonEvents.append(create_mads_event(self.mads_event_lock)) + self.CS.button_events.append(create_mads_event(self.mads_event_lock)) self.mads_event_lock = False else: if not self.mads_event_lock: - buttonEvents.append(create_mads_event(self.mads_event_lock)) + self.CS.button_events.append(create_mads_event(self.mads_event_lock)) self.mads_event_lock = True - ret.buttonEvents = buttonEvents + ret.buttonEvents = self.CS.button_events # The ECM allows enabling on falling edge of set, but only rising edge of resume events = self.create_common_events(ret, c, extra_gears=[GearShifter.sport, GearShifter.low, diff --git a/selfdrive/car/honda/carstate.py b/selfdrive/car/honda/carstate.py index ae8746d958..c50c6d08fb 100644 --- a/selfdrive/car/honda/carstate.py +++ b/selfdrive/car/honda/carstate.py @@ -111,6 +111,7 @@ class CarState(CarStateBase): self.dash_speed_seen = False def update(self, cp, cp_cam, cp_body): + self.button_events = [] ret = car.CarState.new_message() # car params diff --git a/selfdrive/car/honda/interface.py b/selfdrive/car/honda/interface.py index 457b095e6a..52984035c4 100755 --- a/selfdrive/car/honda/interface.py +++ b/selfdrive/car/honda/interface.py @@ -268,7 +268,7 @@ class CarInterface(CarInterfaceBase): ret = self.CS.update(self.cp, self.cp_cam, self.cp_body) self.sp_update_params() - buttonEvents = [ + self.CS.button_events = [ *create_button_events(self.CS.cruise_buttons, self.CS.prev_cruise_buttons, BUTTONS_DICT), *create_button_events(self.CS.cruise_setting, self.CS.prev_cruise_setting, SETTINGS_BUTTONS_DICT), ] @@ -276,7 +276,7 @@ class CarInterface(CarInterfaceBase): self.CS.mads_enabled = self.get_sp_cruise_main_state(ret, self.CS) self.CS.accEnabled = self.get_sp_v_cruise_non_pcm_state(ret, self.CS.accEnabled, - buttonEvents, c.vCruise) + self.CS.button_events, c.vCruise) if ret.cruiseState.available: if self.enable_mads: @@ -289,7 +289,7 @@ class CarInterface(CarInterfaceBase): self.CS.madsEnabled = False if not self.CP.pcmCruise or (self.CP.pcmCruise and self.CP.minEnableSpeed > 0) or not self.CP.pcmCruiseSpeed: - if any(b.type == ButtonType.cancel for b in buttonEvents): + if any(b.type == ButtonType.cancel for b in self.CS.button_events): self.CS.madsEnabled, self.CS.accEnabled = self.get_sp_cancel_cruise_state(self.CS.madsEnabled) if self.get_sp_pedal_disengage(ret): self.CS.madsEnabled, self.CS.accEnabled = self.get_sp_cancel_cruise_state(self.CS.madsEnabled) @@ -304,7 +304,7 @@ class CarInterface(CarInterfaceBase): min_enable_speed_pcm=(self.CP.pcmCruise and self.CP.minEnableSpeed > 0 and self.CP.pcmCruiseSpeed), gap_button=(self.CS.cruise_setting == 3)) - ret.buttonEvents = buttonEvents + ret.buttonEvents = self.CS.button_events # events events = self.create_common_events(ret, c, extra_gears=[GearShifter.sport, GearShifter.low], pcm_enable=False) diff --git a/selfdrive/car/hyundai/carstate.py b/selfdrive/car/hyundai/carstate.py index d8329c5ba7..4066a988ec 100644 --- a/selfdrive/car/hyundai/carstate.py +++ b/selfdrive/car/hyundai/carstate.py @@ -63,6 +63,7 @@ class CarState(CarStateBase): self._speed_limit_clu = 0 def update(self, cp, cp_cam): + self.button_events = [] if self.CP.carFingerprint in CANFD_CAR: return self.update_canfd(cp, cp_cam) diff --git a/selfdrive/car/hyundai/interface.py b/selfdrive/car/hyundai/interface.py index eb46caf21a..7db9867d4a 100644 --- a/selfdrive/car/hyundai/interface.py +++ b/selfdrive/car/hyundai/interface.py @@ -210,10 +210,10 @@ class CarInterface(CarInterfaceBase): ret = self.CS.update(self.cp, self.cp_cam) self.sp_update_params() - buttonEvents = create_button_events(self.CS.cruise_buttons[-1], self.CS.prev_cruise_buttons, BUTTONS_DICT) + self.CS.button_events = create_button_events(self.CS.cruise_buttons[-1], self.CS.prev_cruise_buttons, BUTTONS_DICT) self.CS.accEnabled = self.get_sp_v_cruise_non_pcm_state(ret, self.CS.accEnabled, - buttonEvents, c.vCruise) + self.CS.button_events, c.vCruise) self.CS.mads_enabled = False if not self.mads_main_toggle else self.CS.mads_enabled @@ -236,7 +236,7 @@ class CarInterface(CarInterfaceBase): if not self.CP.pcmCruise or not self.CP.pcmCruiseSpeed: if not self.CP.pcmCruise: - if any(b.type == ButtonType.cancel for b in buttonEvents): + if any(b.type == ButtonType.cancel for b in self.CS.button_events): self.CS.madsEnabled, self.CS.accEnabled = self.get_sp_cancel_cruise_state(self.CS.madsEnabled) if not self.CP.pcmCruiseSpeed: if not ret.cruiseState.enabled: @@ -250,14 +250,14 @@ class CarInterface(CarInterfaceBase): # MADS BUTTON if self.CS.out.madsEnabled != self.CS.madsEnabled: if self.mads_event_lock: - buttonEvents.append(create_mads_event(self.mads_event_lock)) + self.CS.button_events.append(create_mads_event(self.mads_event_lock)) self.mads_event_lock = False else: if not self.mads_event_lock: - buttonEvents.append(create_mads_event(self.mads_event_lock)) + self.CS.button_events.append(create_mads_event(self.mads_event_lock)) self.mads_event_lock = True - ret.buttonEvents = buttonEvents + ret.buttonEvents = self.CS.button_events # On some newer model years, the CANCEL button acts as a pause/resume button based on the PCM state # To avoid re-engaging when openpilot cancels, check user engagement intention via buttons diff --git a/selfdrive/car/interfaces.py b/selfdrive/car/interfaces.py index 3aa621e85c..5f8a83f93e 100644 --- a/selfdrive/car/interfaces.py +++ b/selfdrive/car/interfaces.py @@ -1,3 +1,4 @@ +import capnp import json import os import numpy as np @@ -780,6 +781,8 @@ class CarStateBase(ABC): self.prev_mads_enabled = False self.control_initialized = False + self.button_events: list[capnp.lib.capnp._DynamicStructBuilder] = [] + Q = [[0.0, 0.0], [0.0, 100.0]] R = 0.3 A = [[1.0, DT_CTRL], [0.0, 1.0]] diff --git a/selfdrive/car/mazda/carcontroller.py b/selfdrive/car/mazda/carcontroller.py index 9832cebe46..368198e1c8 100644 --- a/selfdrive/car/mazda/carcontroller.py +++ b/selfdrive/car/mazda/carcontroller.py @@ -11,8 +11,7 @@ from openpilot.selfdrive.car.mazda.values import CarControllerParams, Buttons from openpilot.selfdrive.controls.lib.drive_helpers import MAZDA_V_CRUISE_MIN VisualAlert = car.CarControl.HUDControl.VisualAlert - -BUTTONS_STATES = ["accelCruise", "decelCruise", "cancel", "resumeCruise"] +ButtonType = car.CarState.ButtonEvent.Type class CarController(CarControllerBase): @@ -141,8 +140,10 @@ class CarController(CarControllerBase): # multikyd methods, sunnyhaibin logic def get_cruise_buttons_status(self, CS): if not CS.out.cruiseState.enabled: - if any(CS.buttonStates[button_state] for button_state in BUTTONS_STATES): - self.timer = 40 + for be in CS.out.buttonEvents: + if be.type in (ButtonType.accelCruise, ButtonType.resumeCruise, + ButtonType.decelCruise, ButtonType.setCruise) and be.pressed: + self.timer = 40 elif self.timer: self.timer -= 1 else: diff --git a/selfdrive/car/mazda/carstate.py b/selfdrive/car/mazda/carstate.py index dea768c03a..6fd287fa7c 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, MazdaFlags, BUTTON_STATES +from openpilot.selfdrive.car.mazda.values import DBC, LKAS_LIMITS, MazdaFlags, BUTTONS class CarState(CarStateBase): def __init__(self, CP): @@ -24,8 +24,7 @@ class CarState(CarStateBase): self.lkas_enabled = False self.prev_lkas_enabled = False - self.buttonStates = BUTTON_STATES.copy() - self.buttonStatesPrev = BUTTON_STATES.copy() + self.button_states = {button.event_type: False for button in BUTTONS} def update(self, cp, cp_cam): @@ -36,7 +35,6 @@ class CarState(CarStateBase): self.prev_mads_enabled = self.mads_enabled self.prev_lkas_enabled = self.lkas_enabled - self.buttonStatesPrev = self.buttonStates.copy() ret.wheelSpeeds = self.get_wheel_speeds( cp.vl["WHEEL_SPEEDS"]["FL"], @@ -56,6 +54,18 @@ class CarState(CarStateBase): can_gear = int(cp.vl["GEAR"]["GEAR"]) ret.gearShifter = self.parse_gear_shifter(self.shifter_values.get(can_gear, None)) + # Buttons + button_events = [] + for button in BUTTONS: + state = (cp.vl[button.can_addr][button.can_msg] in button.values) + if self.button_states[button.event_type] != state: + event = car.CarState.ButtonEvent.new_message() + event.type = button.event_type + event.pressed = state + button_events.append(event) + self.button_states[button.event_type] = state + self.button_events = button_events + ret.genericToggle = bool(cp.vl["BLINK_INFO"]["HIGH_BEAMS"]) ret.leftBlindspot = cp.vl["BSM"]["LEFT_BS_STATUS"] != 0 ret.rightBlindspot = cp.vl["BSM"]["RIGHT_BS_STATUS"] != 0 @@ -114,11 +124,6 @@ class CarState(CarStateBase): self.acc_active_last = ret.cruiseState.enabled - self.buttonStates["accelCruise"] = bool(cp.vl["CRZ_BTNS"]["SET_P"]) - self.buttonStates["decelCruise"] = bool(cp.vl["CRZ_BTNS"]["SET_M"]) - self.buttonStates["cancel"] = bool(cp.vl["CRZ_BTNS"]["CAN_OFF"]) - self.buttonStates["resumeCruise"] = bool(cp.vl["CRZ_BTNS"]["RES"]) - self.crz_btns_counter = cp.vl["CRZ_BTNS"]["CTR"] # camera signals diff --git a/selfdrive/car/mazda/interface.py b/selfdrive/car/mazda/interface.py index bb9a3f93a0..f8919d13e7 100755 --- a/selfdrive/car/mazda/interface.py +++ b/selfdrive/car/mazda/interface.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 from cereal import car from openpilot.common.conversions import Conversions as CV -from openpilot.selfdrive.car.mazda.values import CAR, LKAS_LIMITS, BUTTON_STATES +from openpilot.selfdrive.car.mazda.values import CAR, LKAS_LIMITS from openpilot.selfdrive.car import create_button_events, get_safety_config, create_mads_event from openpilot.selfdrive.car.interfaces import CarInterfaceBase @@ -12,7 +12,6 @@ GearShifter = car.CarState.GearShifter class CarInterface(CarInterfaceBase): def __init__(self, CP, CarController, CarState): super().__init__(CP, CarController, CarState) - self.buttonStatesPrev = BUTTON_STATES.copy() @staticmethod def _get_params(ret, candidate, fingerprint, car_fw, experimental_long, docs): @@ -41,19 +40,15 @@ class CarInterface(CarInterfaceBase): self.sp_update_params() # TODO: add button types for inc and dec - buttonEvents = create_button_events(self.CS.distance_button, self.CS.prev_distance_button, {1: ButtonType.gapAdjustCruise}) - - for button in self.CS.buttonStates: - if self.CS.buttonStates[button] != self.buttonStatesPrev[button]: - be = car.CarState.ButtonEvent.new_message() - be.type = button - be.pressed = self.CS.buttonStates[button] - buttonEvents.append(be) + self.CS.button_events = [ + *self.CS.button_events, + *create_button_events(self.CS.distance_button, self.CS.prev_distance_button, {1: ButtonType.gapAdjustCruise}) + ] self.CS.mads_enabled = self.get_sp_cruise_main_state(ret, self.CS) self.CS.accEnabled = self.get_sp_v_cruise_non_pcm_state(ret, self.CS.accEnabled, - buttonEvents, c.vCruise) + self.CS.button_events, c.vCruise) if ret.cruiseState.available: if self.enable_mads: @@ -66,7 +61,7 @@ class CarInterface(CarInterfaceBase): self.CS.madsEnabled = False if not self.CP.pcmCruise or (self.CP.pcmCruise and self.CP.minEnableSpeed > 0) or not self.CP.pcmCruiseSpeed: - if any(b.type == ButtonType.cancel for b in buttonEvents): + if any(b.type == ButtonType.cancel for b in self.CS.button_events): self.CS.madsEnabled, self.CS.accEnabled = self.get_sp_cancel_cruise_state(self.CS.madsEnabled) if self.get_sp_pedal_disengage(ret): self.CS.madsEnabled, self.CS.accEnabled = self.get_sp_cancel_cruise_state(self.CS.madsEnabled) @@ -82,14 +77,14 @@ class CarInterface(CarInterfaceBase): # MADS BUTTON if self.CS.out.madsEnabled != self.CS.madsEnabled: if self.mads_event_lock: - buttonEvents.append(create_mads_event(self.mads_event_lock)) + self.CS.button_events.append(create_mads_event(self.mads_event_lock)) self.mads_event_lock = False else: if not self.mads_event_lock: - buttonEvents.append(create_mads_event(self.mads_event_lock)) + self.CS.button_events.append(create_mads_event(self.mads_event_lock)) self.mads_event_lock = True - ret.buttonEvents = buttonEvents + ret.buttonEvents = self.CS.button_events # events events = self.create_common_events(ret, c, extra_gears=[GearShifter.sport, GearShifter.low, GearShifter.brake], @@ -108,6 +103,4 @@ class CarInterface(CarInterfaceBase): ret.events = events.to_msg() - self.buttonStatesPrev = self.CS.buttonStates.copy() - return ret diff --git a/selfdrive/car/mazda/values.py b/selfdrive/car/mazda/values.py index 2aac951dbb..2889cbb7b2 100644 --- a/selfdrive/car/mazda/values.py +++ b/selfdrive/car/mazda/values.py @@ -1,3 +1,4 @@ +from collections import namedtuple from dataclasses import dataclass, field from enum import IntFlag @@ -8,6 +9,7 @@ from openpilot.selfdrive.car.docs_definitions import CarHarness, CarDocs, CarPar from openpilot.selfdrive.car.fw_query_definitions import FwQueryConfig, Request, StdQueries Ecu = car.CarParams.Ecu +Button = namedtuple('Button', ['event_type', 'can_addr', 'can_msg', 'values']) # Steer torque limits @@ -26,14 +28,6 @@ class CarControllerParams: pass -BUTTON_STATES = { - "accelCruise": False, - "decelCruise": False, - "cancel": False, - "resumeCruise": False, -} - - @dataclass class MazdaCarDocs(CarDocs): package: str = "All" @@ -98,6 +92,14 @@ class Buttons: CANCEL = 4 +BUTTONS = [ + Button(car.CarState.ButtonEvent.Type.accelCruise, "CRZ_BTNS", "SET_P", [1]), + Button(car.CarState.ButtonEvent.Type.decelCruise, "CRZ_BTNS", "SET_M", [1]), + Button(car.CarState.ButtonEvent.Type.cancel, "CRZ_BTNS", "CAN_OFF", [1]), + Button(car.CarState.ButtonEvent.Type.resumeCruise, "CRZ_BTNS", "RES", [1]), +] + + FW_QUERY_CONFIG = FwQueryConfig( requests=[ # TODO: check data to ensure ABS does not skip ISO-TP frames on bus 0 diff --git a/selfdrive/car/nissan/carstate.py b/selfdrive/car/nissan/carstate.py index 17c6abf681..8dba6dcdf6 100644 --- a/selfdrive/car/nissan/carstate.py +++ b/selfdrive/car/nissan/carstate.py @@ -24,6 +24,7 @@ class CarState(CarStateBase): self.distance_button = 0 def update(self, cp, cp_adas, cp_cam): + self.button_events = [] ret = car.CarState.new_message() self.prev_distance_button = self.distance_button diff --git a/selfdrive/car/nissan/interface.py b/selfdrive/car/nissan/interface.py index 3d744a41a0..707eab06c0 100644 --- a/selfdrive/car/nissan/interface.py +++ b/selfdrive/car/nissan/interface.py @@ -34,7 +34,7 @@ class CarInterface(CarInterfaceBase): ret = self.CS.update(self.cp, self.cp_adas, self.cp_cam) self.sp_update_params() - buttonEvents = create_button_events(self.CS.distance_button, self.CS.prev_distance_button, {1: ButtonType.gapAdjustCruise}) + self.CS.button_events = create_button_events(self.CS.distance_button, self.CS.prev_distance_button, {1: ButtonType.gapAdjustCruise}) self.CS.mads_enabled = self.get_sp_cruise_main_state(ret, self.CS) @@ -58,19 +58,19 @@ class CarInterface(CarInterfaceBase): be = car.CarState.ButtonEvent.new_message() be.pressed = True be.type = ButtonType.cancel - buttonEvents.append(be) + self.CS.button_events.append(be) # MADS BUTTON if self.CS.out.madsEnabled != self.CS.madsEnabled: if self.mads_event_lock: - buttonEvents.append(create_mads_event(self.mads_event_lock)) + self.CS.button_events.append(create_mads_event(self.mads_event_lock)) self.mads_event_lock = False else: if not self.mads_event_lock: - buttonEvents.append(create_mads_event(self.mads_event_lock)) + self.CS.button_events.append(create_mads_event(self.mads_event_lock)) self.mads_event_lock = True - ret.buttonEvents = buttonEvents + ret.buttonEvents = self.CS.button_events events = self.create_common_events(ret, c, extra_gears=[GearShifter.sport, GearShifter.low, GearShifter.brake], pcm_enable=False) diff --git a/selfdrive/car/subaru/carstate.py b/selfdrive/car/subaru/carstate.py index 5cff425efe..1a48901dde 100644 --- a/selfdrive/car/subaru/carstate.py +++ b/selfdrive/car/subaru/carstate.py @@ -20,6 +20,7 @@ class CarState(CarStateBase): self.prev_lkas_enabled = None def update(self, cp, cp_cam, cp_body): + self.button_events = [] ret = car.CarState.new_message() self.prev_mads_enabled = self.mads_enabled diff --git a/selfdrive/car/subaru/interface.py b/selfdrive/car/subaru/interface.py index 744c017a96..967d426fe4 100644 --- a/selfdrive/car/subaru/interface.py +++ b/selfdrive/car/subaru/interface.py @@ -118,8 +118,6 @@ class CarInterface(CarInterfaceBase): ret = self.CS.update(self.cp, self.cp_cam, self.cp_body) self.sp_update_params() - buttonEvents = [] - self.CS.mads_enabled = self.get_sp_cruise_main_state(ret, self.CS) if ret.cruiseState.available: @@ -150,19 +148,19 @@ class CarInterface(CarInterfaceBase): be = car.CarState.ButtonEvent.new_message() be.pressed = True be.type = ButtonType.cancel - buttonEvents.append(be) + self.CS.button_events.append(be) # MADS BUTTON if self.CS.out.madsEnabled != self.CS.madsEnabled: if self.mads_event_lock: - buttonEvents.append(create_mads_event(self.mads_event_lock)) + self.CS.button_events.append(create_mads_event(self.mads_event_lock)) self.mads_event_lock = False else: if not self.mads_event_lock: - buttonEvents.append(create_mads_event(self.mads_event_lock)) + self.CS.button_events.append(create_mads_event(self.mads_event_lock)) self.mads_event_lock = True - ret.buttonEvents = buttonEvents + ret.buttonEvents = self.CS.button_events events = self.create_common_events(ret, c, extra_gears=[GearShifter.sport, GearShifter.low], pcm_enable=False) diff --git a/selfdrive/car/toyota/carstate.py b/selfdrive/car/toyota/carstate.py index 456282982b..53bf7da4c2 100644 --- a/selfdrive/car/toyota/carstate.py +++ b/selfdrive/car/toyota/carstate.py @@ -85,6 +85,7 @@ class CarState(CarStateBase): self.frame = 0 def update(self, cp, cp_cam): + self.button_events = [] ret = car.CarState.new_message() self.prev_mads_enabled = self.mads_enabled diff --git a/selfdrive/car/toyota/interface.py b/selfdrive/car/toyota/interface.py index dca2cfd12a..71e08e4bea 100644 --- a/selfdrive/car/toyota/interface.py +++ b/selfdrive/car/toyota/interface.py @@ -212,11 +212,10 @@ class CarInterface(CarInterfaceBase): ret = self.CS.update(self.cp, self.cp_cam) self.sp_update_params() - buttonEvents = [] distance_button = 0 if self.CP.carFingerprint in (TSS2_CAR - RADAR_ACC_CAR) or (self.CP.flags & ToyotaFlags.SMART_DSU and not self.CP.flags & ToyotaFlags.RADAR_CAN_FILTER): - buttonEvents = create_button_events(self.CS.distance_button, self.CS.prev_distance_button, {1: ButtonType.gapAdjustCruise}) + self.CS.button_events = create_button_events(self.CS.distance_button, self.CS.prev_distance_button, {1: ButtonType.gapAdjustCruise}) distance_button = self.CS.distance_button self.CS.mads_enabled = self.get_sp_cruise_main_state(ret, self.CS) @@ -250,19 +249,19 @@ class CarInterface(CarInterfaceBase): be = car.CarState.ButtonEvent.new_message() be.pressed = True be.type = ButtonType.cancel - buttonEvents.append(be) + self.CS.button_events.append(be) # MADS BUTTON if self.CS.out.madsEnabled != self.CS.madsEnabled: if self.mads_event_lock: - buttonEvents.append(create_mads_event(self.mads_event_lock)) + self.CS.button_events.append(create_mads_event(self.mads_event_lock)) self.mads_event_lock = False else: if not self.mads_event_lock: - buttonEvents.append(create_mads_event(self.mads_event_lock)) + self.CS.button_events.append(create_mads_event(self.mads_event_lock)) self.mads_event_lock = True - ret.buttonEvents = buttonEvents + ret.buttonEvents = self.CS.button_events # events events = self.create_common_events(ret, c, extra_gears=[GearShifter.sport, GearShifter.low, GearShifter.brake], diff --git a/selfdrive/car/volkswagen/carstate.py b/selfdrive/car/volkswagen/carstate.py index 6ec27b8be0..1dc4c0e430 100644 --- a/selfdrive/car/volkswagen/carstate.py +++ b/selfdrive/car/volkswagen/carstate.py @@ -4,7 +4,7 @@ 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, NetworkLocation, TransmissionType, GearShifter, \ - CarControllerParams, VolkswagenFlags, BUTTON_STATES, VolkswagenFlagsSP + CarControllerParams, VolkswagenFlags, VolkswagenFlagsSP class CarState(CarStateBase): @@ -17,8 +17,6 @@ class CarState(CarStateBase): self.esp_hold_confirmation = False self.upscale_lead_car_signal = False self.eps_stock_values = False - self.buttonStates = BUTTON_STATES.copy() - self.buttonStatesPrev = BUTTON_STATES.copy() def create_button_events(self, pt_cp, buttons): button_events = [] @@ -41,7 +39,6 @@ class CarState(CarStateBase): ret = car.CarState.new_message() self.prev_mads_enabled = self.mads_enabled - self.buttonStatesPrev = self.buttonStates.copy() # Update vehicle speed and acceleration from ABS wheel speeds. ret.wheelSpeeds = self.get_wheel_speeds( @@ -150,18 +147,10 @@ class CarState(CarStateBase): if ret.cruiseState.speed > 90: ret.cruiseState.speed = 0 - # Update control button states for turn signals and ACC controls. - self.buttonStates["accelCruise"] = bool(pt_cp.vl["GRA_ACC_01"]["GRA_Tip_Hoch"]) - self.buttonStates["decelCruise"] = bool(pt_cp.vl["GRA_ACC_01"]["GRA_Tip_Runter"]) - self.buttonStates["cancel"] = bool(pt_cp.vl["GRA_ACC_01"]["GRA_Abbrechen"]) - self.buttonStates["setCruise"] = bool(pt_cp.vl["GRA_ACC_01"]["GRA_Tip_Setzen"]) - self.buttonStates["resumeCruise"] = bool(pt_cp.vl["GRA_ACC_01"]["GRA_Tip_Wiederaufnahme"]) - self.buttonStates["gapAdjustCruise"] = bool(pt_cp.vl["GRA_ACC_01"]["GRA_Verstellung_Zeitluecke"]) - # Update button states for turn signals and ACC controls, capture all ACC button state/config for passthrough ret.leftBlinker = ret.leftBlinkerOn = bool(pt_cp.vl["Blinkmodi_02"]["Comfort_Signal_Left"]) ret.rightBlinker = ret.rightBlinkerOn = bool(pt_cp.vl["Blinkmodi_02"]["Comfort_Signal_Right"]) - ret.buttonEvents = self.create_button_events(pt_cp, self.CCP.BUTTONS) + self.button_events = self.create_button_events(pt_cp, self.CCP.BUTTONS) self.gra_stock_values = pt_cp.vl["GRA_ACC_01"] # Additional safety checks performed in CarInterface. @@ -177,7 +166,6 @@ class CarState(CarStateBase): ret = car.CarState.new_message() self.prev_mads_enabled = self.mads_enabled - self.buttonStatesPrev = self.buttonStates.copy() # Update vehicle speed and acceleration from ABS wheel speeds. ret.wheelSpeeds = self.get_wheel_speeds( @@ -265,18 +253,10 @@ class CarState(CarStateBase): if ret.cruiseState.speed > 70: # 255 kph in m/s == no current setpoint ret.cruiseState.speed = 0 - # Update control button states for turn signals and ACC controls. - self.buttonStates["accelCruise"] = bool(pt_cp.vl["GRA_Neu"]["GRA_Up_kurz"]) - self.buttonStates["decelCruise"] = bool(pt_cp.vl["GRA_Neu"]["GRA_Down_kurz"]) - self.buttonStates["cancel"] = bool(pt_cp.vl["GRA_Neu"]["GRA_Abbrechen"]) - self.buttonStates["setCruise"] = bool(pt_cp.vl["GRA_Neu"]["GRA_Neu_Setzen"]) - self.buttonStates["resumeCruise"] = bool(pt_cp.vl["GRA_Neu"]["GRA_Recall"]) - self.buttonStates["gapAdjustCruise"] = bool(pt_cp.vl["GRA_Neu"]["GRA_Zeitluecke"]) - # Update button states for turn signals and ACC controls, capture all ACC button state/config for passthrough ret.leftBlinker, ret.rightBlinker = ret.leftBlinkerOn, ret.rightBlinkerOn = self.update_blinker_from_stalk(300, pt_cp.vl["Gate_Komf_1"]["GK1_Blinker_li"], pt_cp.vl["Gate_Komf_1"]["GK1_Blinker_re"]) - ret.buttonEvents = self.create_button_events(pt_cp, self.CCP.BUTTONS) + self.button_events = self.create_button_events(pt_cp, self.CCP.BUTTONS) self.gra_stock_values = pt_cp.vl["GRA_Neu"] # Additional safety checks performed in CarInterface. diff --git a/selfdrive/car/volkswagen/interface.py b/selfdrive/car/volkswagen/interface.py index 31dea25cbb..fe042984e2 100644 --- a/selfdrive/car/volkswagen/interface.py +++ b/selfdrive/car/volkswagen/interface.py @@ -4,7 +4,7 @@ from openpilot.common.params import Params from openpilot.selfdrive.car import get_safety_config, create_mads_event from openpilot.selfdrive.car.interfaces import CarInterfaceBase from openpilot.selfdrive.car.volkswagen.values import CAR, CANBUS, CarControllerParams, NetworkLocation, TransmissionType, GearShifter, VolkswagenFlags, \ - BUTTON_STATES, VolkswagenFlagsSP + VolkswagenFlagsSP ButtonType = car.CarState.ButtonEvent.Type EventName = car.CarEvent.EventName @@ -21,8 +21,6 @@ class CarInterface(CarInterfaceBase): self.ext_bus = CANBUS.cam self.cp_ext = self.cp_cam - self.buttonStatesPrev = BUTTON_STATES.copy() - @staticmethod def _get_params(ret, candidate: CAR, fingerprint, car_fw, experimental_long, docs): ret.carName = "volkswagen" @@ -117,21 +115,10 @@ class CarInterface(CarInterfaceBase): ret = self.CS.update(self.cp, self.cp_cam, self.cp_ext, self.CP.transmissionType) self.sp_update_params() - buttonEvents = [] - - # Check for and process state-change events (button press or release) from - # the turn stalk switch or ACC steering wheel/control stalk buttons. - for button in self.CS.buttonStates: - if self.CS.buttonStates[button] != self.buttonStatesPrev[button]: - be = car.CarState.ButtonEvent.new_message() - be.type = button - be.pressed = self.CS.buttonStates[button] - buttonEvents.append(be) - self.CS.mads_enabled = self.get_sp_cruise_main_state(ret, self.CS) self.CS.accEnabled = self.get_sp_v_cruise_non_pcm_state(ret, self.CS.accEnabled, - buttonEvents, c.vCruise, + self.CS.button_events, c.vCruise, enable_buttons=(ButtonType.setCruise, ButtonType.resumeCruise)) if ret.cruiseState.available: @@ -144,7 +131,7 @@ class CarInterface(CarInterfaceBase): self.CS.madsEnabled = self.get_sp_started_mads(ret, self.CS) if not self.CP.pcmCruise or (self.CP.pcmCruise and self.CP.minEnableSpeed > 0) or not self.CP.pcmCruiseSpeed: - if any(b.type == ButtonType.cancel for b in buttonEvents): + if any(b.type == ButtonType.cancel for b in self.CS.button_events): self.CS.madsEnabled, self.CS.accEnabled = self.get_sp_cancel_cruise_state(self.CS.madsEnabled) if self.get_sp_pedal_disengage(ret): self.CS.madsEnabled, self.CS.accEnabled = self.get_sp_cancel_cruise_state(self.CS.madsEnabled) @@ -155,19 +142,20 @@ class CarInterface(CarInterfaceBase): self.CS.accEnabled = False self.CS.accEnabled = ret.cruiseState.enabled or self.CS.accEnabled - ret, self.CS = self.get_sp_common_state(ret, self.CS, gap_button=bool(self.CS.buttonStates["gapAdjustCruise"])) + ret, self.CS = self.get_sp_common_state(ret, self.CS, + gap_button=any(b.type == ButtonType.gapAdjustCruise and b.pressed for b in self.CS.button_events)) # MADS BUTTON if self.CS.out.madsEnabled != self.CS.madsEnabled: if self.mads_event_lock: - buttonEvents.append(create_mads_event(self.mads_event_lock)) + self.CS.button_events.append(create_mads_event(self.mads_event_lock)) self.mads_event_lock = False else: if not self.mads_event_lock: - buttonEvents.append(create_mads_event(self.mads_event_lock)) + self.CS.button_events.append(create_mads_event(self.mads_event_lock)) self.mads_event_lock = True - ret.buttonEvents = buttonEvents + ret.buttonEvents = self.CS.button_events events = self.create_common_events(ret, c, extra_gears=[GearShifter.eco, GearShifter.sport, GearShifter.manumatic], pcm_enable=False, @@ -199,8 +187,4 @@ class CarInterface(CarInterfaceBase): ret.events = events.to_msg() - # update previous car states - self.buttonStatesPrev = self.CS.buttonStates.copy() - return ret - diff --git a/selfdrive/car/volkswagen/values.py b/selfdrive/car/volkswagen/values.py index 2996db602f..80b7ca0b0b 100644 --- a/selfdrive/car/volkswagen/values.py +++ b/selfdrive/car/volkswagen/values.py @@ -147,16 +147,6 @@ class VolkswagenFlagsSP(IntFlag): SP_CC_ONLY_NO_RADAR = 2 -BUTTON_STATES = { - "accelCruise": False, - "decelCruise": False, - "cancel": False, - "setCruise": False, - "resumeCruise": False, - "gapAdjustCruise": False -} - - @dataclass class VolkswagenMQBPlatformConfig(PlatformConfig): dbc_dict: DbcDict = field(default_factory=lambda: dbc_dict('vw_mqb_2010', None))