From 24f5a6170dc2e3bea9565115a09a1e20e18572de Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Fri, 25 Aug 2023 16:47:10 -0700 Subject: [PATCH] car interfaces: handle buttons changing state without going unpressed (#26463) * rename function first and foremost * the function * comment * move usages over * probably fine * comments * btn * single line * not comments * fix keyword * is it not clear? * noEntry while holding cancel * bumpo * remove * better? * better? * try this * try this * loop * better * more clear * Revert "more clear" This reverts commit 37e0277e4bfe6f1c553dbbcece6f532a280be62e. * no optional * fine * add comment * clean up honda * one line * can also do this * but unclear This reverts commit 1984a72cc8680b23c202695b8aeeb1aa28f7160c. * bumppanda --- panda | 2 +- selfdrive/car/__init__.py | 25 ++++++++++++++----------- selfdrive/car/gm/interface.py | 13 +++++-------- selfdrive/car/honda/interface.py | 15 +++++---------- selfdrive/car/hyundai/interface.py | 11 +++-------- 5 files changed, 28 insertions(+), 38 deletions(-) diff --git a/panda b/panda index 09cd81752d..cca252c8d4 160000 --- a/panda +++ b/panda @@ -1 +1 @@ -Subproject commit 09cd81752d1d53de4cc1c63f950dc717acc20ad8 +Subproject commit cca252c8d497f52494b5c21aa30f915e9ffc6ce8 diff --git a/selfdrive/car/__init__.py b/selfdrive/car/__init__.py index 773d990fac..89828a5cf5 100644 --- a/selfdrive/car/__init__.py +++ b/selfdrive/car/__init__.py @@ -1,6 +1,6 @@ # functions common among cars from collections import namedtuple -from typing import Dict, Optional +from typing import Dict, List, Optional import capnp @@ -24,16 +24,19 @@ def apply_hysteresis(val: float, val_steady: float, hyst_gap: float) -> float: return val_steady -def create_button_event(cur_but: int, prev_but: int, buttons_dict: Dict[int, capnp.lib.capnp._EnumModule], - unpressed: int = 0) -> capnp.lib.capnp._DynamicStructBuilder: - if cur_but != unpressed: - be = car.CarState.ButtonEvent(pressed=True) - but = cur_but - else: - be = car.CarState.ButtonEvent(pressed=False) - but = prev_but - be.type = buttons_dict.get(but, ButtonType.unknown) - return be +def create_button_events(cur_btn: int, prev_btn: int, buttons_dict: Dict[int, capnp.lib.capnp._EnumModule], + unpressed_btn: int = 0) -> List[capnp.lib.capnp._DynamicStructBuilder]: + events: List[capnp.lib.capnp._DynamicStructBuilder] = [] + + if cur_btn == prev_btn: + return events + + # Add events for button presses, multiple when a button switches without going to unpressed + for pressed, btn in ((False, prev_btn), (True, cur_btn)): + if btn != unpressed_btn: + events.append(car.CarState.ButtonEvent(pressed=pressed, + type=buttons_dict.get(btn, ButtonType.unknown))) + return events def gen_empty_fingerprint(): diff --git a/selfdrive/car/gm/interface.py b/selfdrive/car/gm/interface.py index 75465b8dde..9b5cae0961 100755 --- a/selfdrive/car/gm/interface.py +++ b/selfdrive/car/gm/interface.py @@ -4,7 +4,7 @@ from math import fabs, exp from panda import Panda from openpilot.common.conversions import Conversions as CV -from openpilot.selfdrive.car import create_button_event, get_safety_config +from openpilot.selfdrive.car import create_button_events, get_safety_config from openpilot.selfdrive.car.gm.radar_interface import RADAR_HEADER_MSG from openpilot.selfdrive.car.gm.values import CAR, CruiseButtons, CarControllerParams, EV_CAR, CAMERA_ACC_CAR, CanBus from openpilot.selfdrive.car.interfaces import CarInterfaceBase, TorqueFromLateralAccelCallbackType, FRICTION_THRESHOLD @@ -253,13 +253,10 @@ class CarInterface(CarInterfaceBase): def _update(self, c): ret = self.CS.update(self.cp, self.cp_cam, self.cp_loopback) - if self.CS.cruise_buttons != self.CS.prev_cruise_buttons and self.CS.prev_cruise_buttons != CruiseButtons.INIT: - buttonEvents = [create_button_event(self.CS.cruise_buttons, self.CS.prev_cruise_buttons, BUTTONS_DICT, CruiseButtons.UNPRESS)] - # Handle ACCButtons changing buttons mid-press - if self.CS.cruise_buttons != CruiseButtons.UNPRESS and self.CS.prev_cruise_buttons != CruiseButtons.UNPRESS: - buttonEvents.append(create_button_event(CruiseButtons.UNPRESS, self.CS.prev_cruise_buttons, BUTTONS_DICT, CruiseButtons.UNPRESS)) - - ret.buttonEvents = buttonEvents + # 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: + ret.buttonEvents = create_button_events(self.CS.cruise_buttons, self.CS.prev_cruise_buttons, BUTTONS_DICT, + unpressed_btn=CruiseButtons.UNPRESS) # The ECM allows enabling on falling edge of set, but only rising edge of resume events = self.create_common_events(ret, extra_gears=[GearShifter.sport, GearShifter.low, diff --git a/selfdrive/car/honda/interface.py b/selfdrive/car/honda/interface.py index 3b87009a24..d1a287a76a 100755 --- a/selfdrive/car/honda/interface.py +++ b/selfdrive/car/honda/interface.py @@ -5,7 +5,7 @@ from openpilot.common.conversions import Conversions as CV from openpilot.common.numpy_fast import interp from openpilot.selfdrive.car.honda.values import CarControllerParams, CruiseButtons, HondaFlags, CAR, HONDA_BOSCH, HONDA_NIDEC_ALT_SCM_MESSAGES, \ HONDA_BOSCH_ALT_BRAKE_SIGNAL, HONDA_BOSCH_RADARLESS -from openpilot.selfdrive.car import create_button_event, get_safety_config +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 @@ -308,15 +308,10 @@ class CarInterface(CarInterfaceBase): def _update(self, c): ret = self.CS.update(self.cp, self.cp_cam, self.cp_body) - buttonEvents = [] - - if self.CS.cruise_buttons != self.CS.prev_cruise_buttons: - buttonEvents.append(create_button_event(self.CS.cruise_buttons, self.CS.prev_cruise_buttons, BUTTONS_DICT)) - - if self.CS.cruise_setting != self.CS.prev_cruise_setting: - buttonEvents.append(create_button_event(self.CS.cruise_setting, self.CS.prev_cruise_setting, {1: ButtonType.altButton1})) - - ret.buttonEvents = buttonEvents + ret.buttonEvents = [ + *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, {1: ButtonType.altButton1}), + ] # events events = self.create_common_events(ret, pcm_enable=False) diff --git a/selfdrive/car/hyundai/interface.py b/selfdrive/car/hyundai/interface.py index 16e93e1623..2c8b478838 100644 --- a/selfdrive/car/hyundai/interface.py +++ b/selfdrive/car/hyundai/interface.py @@ -7,7 +7,7 @@ from openpilot.selfdrive.car.hyundai.values import HyundaiFlags, CAR, DBC, CANFD EV_CAR, HYBRID_CAR, LEGACY_SAFETY_MODE_CAR, UNSUPPORTED_LONGITUDINAL_CAR, \ Buttons from openpilot.selfdrive.car.hyundai.radar_interface import RADAR_START_ADDR -from openpilot.selfdrive.car import create_button_event, get_safety_config +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 @@ -320,13 +320,8 @@ class CarInterface(CarInterfaceBase): def _update(self, c): ret = self.CS.update(self.cp, self.cp_cam) - if self.CS.CP.openpilotLongitudinalControl and self.CS.cruise_buttons[-1] != self.CS.prev_cruise_buttons: - buttonEvents = [create_button_event(self.CS.cruise_buttons[-1], self.CS.prev_cruise_buttons, BUTTONS_DICT)] - # Handle CF_Clu_CruiseSwState changing buttons mid-press - if self.CS.cruise_buttons[-1] != 0 and self.CS.prev_cruise_buttons != 0: - buttonEvents.append(create_button_event(0, self.CS.prev_cruise_buttons, BUTTONS_DICT)) - - ret.buttonEvents = buttonEvents + if self.CS.CP.openpilotLongitudinalControl: + ret.buttonEvents = create_button_events(self.CS.cruise_buttons[-1], self.CS.prev_cruise_buttons, BUTTONS_DICT) # 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