Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Car Interfaces: Refactor button state tracking with ButtonTracker #1278

Merged
merged 3 commits into from
Oct 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 18 additions & 11 deletions opendbc/car/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,19 +33,26 @@ def apply_hysteresis(val: float, val_steady: float, hyst_gap: float) -> float:
return val_steady


def create_button_events(cur_btn: int, prev_btn: int, buttons_dict: dict[int, structs.CarState.ButtonEvent.Type],
unpressed_btn: int = 0) -> list[structs.CarState.ButtonEvent]:
events: list[structs.CarState.ButtonEvent] = []
class ButtonTracker:
def __init__(self):
self.prev_buttons: dict = {}

if cur_btn == prev_btn:
return events
def create_button_events(self, cur_btn: int, buttons_dict: dict[int, structs.CarState.ButtonEvent.Type],
unpressed_btn: int = 0) -> list[structs.CarState.ButtonEvent]:
events: list[structs.CarState.ButtonEvent] = []

button = id(buttons_dict)
prev_btn = self.prev_buttons.get(button, unpressed_btn)

# 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(structs.CarState.ButtonEvent(pressed=pressed,
type=buttons_dict.get(btn, ButtonType.unknown)))
return events
if cur_btn != prev_btn:
# 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(structs.CarState.ButtonEvent(pressed=pressed,
type=buttons_dict.get(btn, ButtonType.unknown)))

self.prev_buttons[button] = cur_btn
return events


def gen_empty_fingerprint():
Expand Down
5 changes: 2 additions & 3 deletions opendbc/car/chrysler/carstate.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from opendbc.can.parser import CANParser
from opendbc.can.can_define import CANDefine
from opendbc.car import create_button_events, structs
from opendbc.car import structs
from opendbc.car.chrysler.values import DBC, STEER_THRESHOLD, RAM_CARS
from opendbc.car.common.conversions import Conversions as CV
from opendbc.car.interfaces import CarStateBase
Expand Down Expand Up @@ -29,7 +29,6 @@ def update(self, cp, cp_cam, *_) -> structs.CarState:

ret = structs.CarState()

prev_distance_button = self.distance_button
self.distance_button = cp.vl["CRUISE_BUTTONS"]["ACC_Distance_Dec"]

# lock info
Expand Down Expand Up @@ -102,7 +101,7 @@ def update(self, cp, cp_cam, *_) -> structs.CarState:
self.lkas_car_model = cp_cam.vl["DAS_6"]["CAR_MODEL"]
self.button_counter = cp.vl["CRUISE_BUTTONS"]["COUNTER"]

ret.buttonEvents = create_button_events(self.distance_button, prev_distance_button, {1: ButtonType.gapAdjustCruise})
ret.buttonEvents = self.button_tracker.create_button_events(self.distance_button, {1: ButtonType.gapAdjustCruise})

return ret

Expand Down
5 changes: 2 additions & 3 deletions opendbc/car/ford/carstate.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from opendbc.can.can_define import CANDefine
from opendbc.can.parser import CANParser
from opendbc.car import create_button_events, structs
from opendbc.car import structs
from opendbc.car.common.conversions import Conversions as CV
from opendbc.car.ford.fordcan import CanBus
from opendbc.car.ford.values import DBC, CarControllerParams, FordFlags
Expand Down Expand Up @@ -85,7 +85,6 @@ def update(self, cp, cp_cam, *_) -> structs.CarState:
ret.rightBlinker = cp.vl["Steering_Data_FD1"]["TurnLghtSwtch_D_Stat"] == 2
# TODO: block this going to the camera otherwise it will enable stock TJA
ret.genericToggle = bool(cp.vl["Steering_Data_FD1"]["TjaButtnOnOffPress"])
prev_distance_button = self.distance_button
self.distance_button = cp.vl["Steering_Data_FD1"]["AccButtnGapTogglePress"]

# lock info
Expand All @@ -105,7 +104,7 @@ def update(self, cp, cp_cam, *_) -> structs.CarState:
self.acc_tja_status_stock_values = cp_cam.vl["ACCDATA_3"]
self.lkas_status_stock_values = cp_cam.vl["IPMA_Data"]

ret.buttonEvents = create_button_events(self.distance_button, prev_distance_button, {1: ButtonType.gapAdjustCruise})
ret.buttonEvents = self.button_tracker.create_button_events(self.distance_button, {1: ButtonType.gapAdjustCruise})

return ret

Expand Down
9 changes: 3 additions & 6 deletions opendbc/car/gm/carstate.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import copy
from opendbc.can.can_define import CANDefine
from opendbc.can.parser import CANParser
from opendbc.car import create_button_events, structs
from opendbc.car import structs
from opendbc.car.common.conversions import Conversions as CV
from opendbc.car.common.numpy_fast import mean
from opendbc.car.interfaces import CarStateBase
Expand Down Expand Up @@ -37,7 +37,6 @@ def update(self, pt_cp, cam_cp, _, __, loopback_cp) -> structs.CarState:
ret = structs.CarState()

prev_cruise_buttons = self.cruise_buttons
prev_distance_button = self.distance_button
self.cruise_buttons = pt_cp.vl["ASCMSteeringButton"]["ACCButtons"]
self.distance_button = pt_cp.vl["ASCMSteeringButton"]["DistanceButton"]
self.buttons_counter = pt_cp.vl["ASCMSteeringButton"]["RollingCounter"]
Expand Down Expand Up @@ -132,10 +131,8 @@ def update(self, pt_cp, cam_cp, _, __, loopback_cp) -> structs.CarState:
# Don't add event if transitioning from INIT, unless it's to an actual button
if self.cruise_buttons != CruiseButtons.UNPRESS or prev_cruise_buttons != CruiseButtons.INIT:
ret.buttonEvents = [
*create_button_events(self.cruise_buttons, prev_cruise_buttons, BUTTONS_DICT,
unpressed_btn=CruiseButtons.UNPRESS),
*create_button_events(self.distance_button, prev_distance_button,
{1: ButtonType.gapAdjustCruise})
*self.button_tracker.create_button_events(self.cruise_buttons, BUTTONS_DICT, unpressed_btn=CruiseButtons.UNPRESS),
*self.button_tracker.create_button_events(self.distance_button, {1: ButtonType.gapAdjustCruise})
]

return ret
Expand Down
9 changes: 3 additions & 6 deletions opendbc/car/honda/carstate.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from opendbc.can.can_define import CANDefine
from opendbc.can.parser import CANParser
from opendbc.car import create_button_events, structs
from opendbc.car import structs
from opendbc.car.common.conversions import Conversions as CV
from opendbc.car.common.numpy_fast import interp
from opendbc.car.honda.hondacan import CanBus, get_cruise_speed_conversion
Expand Down Expand Up @@ -116,9 +116,6 @@ def update(self, cp, cp_cam, _, cp_body, __) -> structs.CarState:
v_weight_v = [0., 1.] # don't trust smooth speed at low values to avoid premature zero snapping
v_weight_bp = [1., 6.] # smooth blending, below ~0.6m/s the smooth speed snaps to zero

# update prevs, update must run once per loop
prev_cruise_buttons = self.cruise_buttons
prev_cruise_setting = self.cruise_setting
self.cruise_setting = cp.vl["SCM_BUTTONS"]["CRUISE_SETTING"]
self.cruise_buttons = cp.vl["SCM_BUTTONS"]["CRUISE_BUTTONS"]

Expand Down Expand Up @@ -264,8 +261,8 @@ def update(self, cp, cp_cam, _, cp_body, __) -> structs.CarState:
ret.rightBlindspot = cp_body.vl["BSM_STATUS_RIGHT"]["BSM_ALERT"] == 1

ret.buttonEvents = [
*create_button_events(self.cruise_buttons, prev_cruise_buttons, BUTTONS_DICT),
*create_button_events(self.cruise_setting, prev_cruise_setting, SETTINGS_BUTTONS_DICT),
*self.button_tracker.create_button_events(self.cruise_buttons, BUTTONS_DICT),
*self.button_tracker.create_button_events(self.cruise_setting, SETTINGS_BUTTONS_DICT),
]

return ret
Expand Down
8 changes: 3 additions & 5 deletions opendbc/car/hyundai/carstate.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

from opendbc.can.parser import CANParser
from opendbc.can.can_define import CANDefine
from opendbc.car import create_button_events, structs
from opendbc.car import structs
from opendbc.car.common.conversions import Conversions as CV
from opendbc.car.hyundai.hyundaicanfd import CanBus
from opendbc.car.hyundai.values import HyundaiFlags, CAR, DBC, CAN_GEARS, CAMERA_SCC_CAR, \
Expand Down Expand Up @@ -167,12 +167,11 @@ def update(self, cp, cp_cam, *_) -> structs.CarState:
self.lkas11 = copy.copy(cp_cam.vl["LKAS11"])
self.clu11 = copy.copy(cp.vl["CLU11"])
self.steer_state = cp.vl["MDPS12"]["CF_Mdps_ToiActive"] # 0 NOT ACTIVE, 1 ACTIVE
prev_cruise_buttons = self.cruise_buttons[-1]
self.cruise_buttons.extend(cp.vl_all["CLU11"]["CF_Clu_CruiseSwState"])
self.main_buttons.extend(cp.vl_all["CLU11"]["CF_Clu_CruiseSwMain"])

if self.CP.openpilotLongitudinalControl:
ret.buttonEvents = create_button_events(self.cruise_buttons[-1], prev_cruise_buttons, BUTTONS_DICT)
ret.buttonEvents = self.button_tracker.create_button_events(self.cruise_buttons[-1], BUTTONS_DICT)

return ret

Expand Down Expand Up @@ -246,7 +245,6 @@ def update_canfd(self, cp, cp_cam) -> structs.CarState:
if self.CP.flags & HyundaiFlags.EV:
ret.cruiseState.nonAdaptive = cp.vl["MANUAL_SPEED_LIMIT_ASSIST"]["MSLA_ENABLED"] == 1

prev_cruise_buttons = self.cruise_buttons[-1]
self.cruise_buttons.extend(cp.vl_all[self.cruise_btns_msg_canfd]["CRUISE_BUTTONS"])
self.main_buttons.extend(cp.vl_all[self.cruise_btns_msg_canfd]["ADAPTIVE_CRUISE_MAIN_BTN"])
self.buttons_counter = cp.vl[self.cruise_btns_msg_canfd]["COUNTER"]
Expand All @@ -257,7 +255,7 @@ def update_canfd(self, cp, cp_cam) -> structs.CarState:
else cp_cam.vl["CAM_0x2a4"])

if self.CP.openpilotLongitudinalControl:
ret.buttonEvents = create_button_events(self.cruise_buttons[-1], prev_cruise_buttons, BUTTONS_DICT)
ret.buttonEvents = self.button_tracker.create_button_events(self.cruise_buttons[-1], BUTTONS_DICT)

return ret

Expand Down
3 changes: 2 additions & 1 deletion opendbc/car/interfaces.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from collections.abc import Callable
from functools import cache

from opendbc.car import DT_CTRL, apply_hysteresis, gen_empty_fingerprint, scale_rot_inertia, scale_tire_stiffness, get_friction, STD_CARGO_KG
from opendbc.car import DT_CTRL, apply_hysteresis, gen_empty_fingerprint, scale_rot_inertia, scale_tire_stiffness, get_friction, STD_CARGO_KG, ButtonTracker
from opendbc.car import structs
from opendbc.car.can_definitions import CanData, CanRecvCallable, CanSendCallable
from opendbc.car.common.basedir import BASEDIR
Expand Down Expand Up @@ -284,6 +284,7 @@ def __init__(self, CP: structs.CarParams):
self.right_blinker_prev = False
self.cluster_speed_hyst_gap = 0.0
self.cluster_min_speed = 0.0 # min speed before dropping to 0
self.button_tracker = ButtonTracker()

Q = [[0.0, 0.0], [0.0, 100.0]]
R = 0.3
Expand Down
5 changes: 2 additions & 3 deletions opendbc/car/mazda/carstate.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from opendbc.can.can_define import CANDefine
from opendbc.can.parser import CANParser
from opendbc.car import create_button_events, structs
from opendbc.car import structs
from opendbc.car.common.conversions import Conversions as CV
from opendbc.car.interfaces import CarStateBase
from opendbc.car.mazda.values import DBC, LKAS_LIMITS, MazdaFlags
Expand All @@ -27,7 +27,6 @@ def update(self, cp, cp_cam, *_) -> structs.CarState:

ret = structs.CarState()

prev_distance_button = self.distance_button
self.distance_button = cp.vl["CRZ_BTNS"]["DISTANCE_LESS"]

ret.wheelSpeeds = self.get_wheel_speeds(
Expand Down Expand Up @@ -113,7 +112,7 @@ def update(self, cp, cp_cam, *_) -> structs.CarState:
ret.steerFaultPermanent = cp_cam.vl["CAM_LKAS"]["ERR_BIT_1"] == 1

# TODO: add button types for inc and dec
ret.buttonEvents = create_button_events(self.distance_button, prev_distance_button, {1: ButtonType.gapAdjustCruise})
ret.buttonEvents = self.button_tracker.create_button_events(self.distance_button, {1: ButtonType.gapAdjustCruise})

return ret

Expand Down
5 changes: 2 additions & 3 deletions opendbc/car/nissan/carstate.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from collections import deque
from opendbc.can.can_define import CANDefine
from opendbc.can.parser import CANParser
from opendbc.car import create_button_events, structs
from opendbc.car import structs
from opendbc.car.common.conversions import Conversions as CV
from opendbc.car.interfaces import CarStateBase
from opendbc.car.nissan.values import CAR, DBC, CarControllerParams
Expand All @@ -28,7 +28,6 @@ def __init__(self, CP):
def update(self, cp, cp_cam, cp_adas, *_) -> structs.CarState:
ret = structs.CarState()

prev_distance_button = self.distance_button
self.distance_button = cp.vl["CRUISE_THROTTLE"]["FOLLOW_DISTANCE_BUTTON"]

if self.CP.carFingerprint in (CAR.NISSAN_ROGUE, CAR.NISSAN_XTRAIL, CAR.NISSAN_ALTIMA):
Expand Down Expand Up @@ -123,7 +122,7 @@ def update(self, cp, cp_cam, cp_adas, *_) -> structs.CarState:
self.lkas_hud_msg = copy.copy(cp_adas.vl["PROPILOT_HUD"])
self.lkas_hud_info_msg = copy.copy(cp_adas.vl["PROPILOT_HUD_INFO_MSG"])

ret.buttonEvents = create_button_events(self.distance_button, prev_distance_button, {1: ButtonType.gapAdjustCruise})
ret.buttonEvents = self.button_tracker.create_button_events(self.distance_button, {1: ButtonType.gapAdjustCruise})

return ret

Expand Down
5 changes: 2 additions & 3 deletions opendbc/car/toyota/carstate.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from opendbc.can.can_define import CANDefine
from opendbc.can.parser import CANParser
from opendbc.car import DT_CTRL, create_button_events, structs
from opendbc.car import DT_CTRL, structs
from opendbc.car.common.conversions import Conversions as CV
from opendbc.car.common.filter_simple import FirstOrderFilter
from opendbc.car.common.numpy_fast import mean
Expand Down Expand Up @@ -185,10 +185,9 @@ def update(self, cp, cp_cam, *_) -> structs.CarState:

if self.CP.carFingerprint in (TSS2_CAR - RADAR_ACC_CAR):
# distance button is wired to the ACC module (camera or radar)
prev_distance_button = self.distance_button
self.distance_button = cp_acc.vl["ACC_CONTROL"]["DISTANCE"]

ret.buttonEvents = create_button_events(self.distance_button, prev_distance_button, {1: ButtonType.gapAdjustCruise})
ret.buttonEvents = self.button_tracker.create_button_events(self.distance_button, {1: ButtonType.gapAdjustCruise})

return ret

Expand Down
Loading