From f3d94fc291da6862cbbae91003912a751da14425 Mon Sep 17 00:00:00 2001 From: Jason Wen Date: Wed, 15 Jan 2025 01:26:23 -0500 Subject: [PATCH 1/4] Longitudinal: Distance button hold to toggle Chill/Experimental Mode --- cereal/log.capnp | 1 + selfdrive/selfdrived/events.py | 4 ++ selfdrive/selfdrived/selfdrived.py | 17 ++++++-- .../selfdrive/car/experimental_switcher.py | 42 +++++++++++++++++++ 4 files changed, 60 insertions(+), 4 deletions(-) create mode 100644 sunnypilot/selfdrive/car/experimental_switcher.py diff --git a/cereal/log.capnp b/cereal/log.capnp index fb38185dfe..b2932a2298 100644 --- a/cereal/log.capnp +++ b/cereal/log.capnp @@ -199,6 +199,7 @@ struct OnroadEvent @0xc4fa6047f024e718 { silentParkBrake @162; controlsMismatchLateral @163; hyundaiRadarTracksConfirmed @164; + experimentalModeSwitched @165; soundsUnavailableDEPRECATED @47; } diff --git a/selfdrive/selfdrived/events.py b/selfdrive/selfdrived/events.py index 481a33079b..065dd635b8 100755 --- a/selfdrive/selfdrived/events.py +++ b/selfdrive/selfdrived/events.py @@ -1063,6 +1063,10 @@ EVENTS: dict[int, dict[str, Alert | AlertCallbackType]] = { EventName.hyundaiRadarTracksConfirmed: { ET.PERMANENT: NormalPermanentAlert("Radar tracks available. Restart the car to initialize") + }, + + EventName.experimentalModeSwitched: { + ET.WARNING: NormalPermanentAlert(f"Experimental Mode Switched", duration=1.5) } } diff --git a/selfdrive/selfdrived/selfdrived.py b/selfdrive/selfdrived/selfdrived.py index 759682f44f..f1ab4d6ed3 100755 --- a/selfdrive/selfdrived/selfdrived.py +++ b/selfdrive/selfdrived/selfdrived.py @@ -25,6 +25,7 @@ from openpilot.system.version import get_build_metadata from openpilot.sunnypilot.mads.mads import ModularAssistiveDrivingSystem from openpilot.sunnypilot.selfdrive.car.car_specific import CarSpecificEventsSP +from openpilot.sunnypilot.selfdrive.car.experimental_switcher import ExperimentalSwitcher, DISTANCE_LONG_PRESS REPLAY = "REPLAY" in os.environ SIMULATION = "SIMULATION" in os.environ @@ -44,7 +45,7 @@ SafetyModel = car.CarParams.SafetyModel IGNORED_SAFETY_MODES = (SafetyModel.silent, SafetyModel.noOutput) -class SelfdriveD: +class SelfdriveD(ExperimentalSwitcher): def __init__(self, CP=None): self.params = Params() @@ -140,6 +141,8 @@ class SelfdriveD: self.car_events_sp = CarSpecificEventsSP(self.CP, self.params) + ExperimentalSwitcher.__init__(self, self.params) + def update_events(self, CS): """Compute onroadEvents from carState""" @@ -367,12 +370,18 @@ class SelfdriveD: if self.sm['modelV2'].frameDropPerc > 20: self.events.add(EventName.modeldLagging) + # toggle experimental mode once on distance button hold + if self.CP.openpilotLongitudinalControl: + ExperimentalSwitcher.update(self, CS, self.events, self.experimental_mode) + # decrement personality on distance button press if self.CP.openpilotLongitudinalControl: if any(not be.pressed and be.type == ButtonType.gapAdjustCruise for be in CS.buttonEvents): - self.personality = (self.personality - 1) % 3 - self.params.put_nonblocking('LongitudinalPersonality', str(self.personality)) - self.events.add(EventName.personalityChanged) + if not self.experimental_mode_switched: + self.personality = (self.personality - 1) % 3 + self.params.put_nonblocking('LongitudinalPersonality', str(self.personality)) + self.events.add(EventName.personalityChanged) + self.experimental_mode_switched = False def data_sample(self): car_state = messaging.recv_one(self.car_state_sock) diff --git a/sunnypilot/selfdrive/car/experimental_switcher.py b/sunnypilot/selfdrive/car/experimental_switcher.py new file mode 100644 index 0000000000..db8665ddf9 --- /dev/null +++ b/sunnypilot/selfdrive/car/experimental_switcher.py @@ -0,0 +1,42 @@ +""" +Copyright (c) 2021-, Haibin Wen, sunnypilot, and a number of other contributors. + +This file is part of sunnypilot and is licensed under the MIT License. +See the LICENSE.md file in the root directory for more details. +""" + +from cereal import car + +ButtonType = car.CarState.ButtonEvent.Type +EventName = car.CarEvent.EventName + +DISTANCE_LONG_PRESS = 50 + + +class ExperimentalSwitcher: + def __init__(self, params): + self.params = params + + self.button_timers = {ButtonType.gapAdjustCruise: 0} + self.experimental_mode_switched = False + + def update(self, CS, events, experimental_mode): + if CS.cruiseState.available: + self.update_button_timers(CS) + self.update_mode(events, experimental_mode) + + def update_button_timers(self, CS) -> None: + for k in self.button_timers: + if self.button_timers[k] > 0: + self.button_timers[k] += 1 + + for b in CS.buttonEvents: + if b.type.raw in self.button_timers: + self.button_timers[b.type.raw] = 1 if b.pressed else 0 + + def update_mode(self, events, experimental_mode) -> None: + if self.button_timers[ButtonType.gapAdjustCruise] >= DISTANCE_LONG_PRESS and not self.experimental_mode_switched: + experimental_mode = not experimental_mode + self.params.put_bool_nonblocking("ExperimentalMode", experimental_mode) + events.add(EventName.experimentalModeSwitched) + self.experimental_mode_switched = True From d7f0e8dd04dcde70223ac8f712b1c97c9ae7f9c1 Mon Sep 17 00:00:00 2001 From: Jason Wen Date: Wed, 15 Jan 2025 01:28:15 -0500 Subject: [PATCH 2/4] unused --- selfdrive/selfdrived/selfdrived.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/selfdrive/selfdrived/selfdrived.py b/selfdrive/selfdrived/selfdrived.py index f1ab4d6ed3..f45e16bce6 100755 --- a/selfdrive/selfdrived/selfdrived.py +++ b/selfdrive/selfdrived/selfdrived.py @@ -25,7 +25,7 @@ from openpilot.system.version import get_build_metadata from openpilot.sunnypilot.mads.mads import ModularAssistiveDrivingSystem from openpilot.sunnypilot.selfdrive.car.car_specific import CarSpecificEventsSP -from openpilot.sunnypilot.selfdrive.car.experimental_switcher import ExperimentalSwitcher, DISTANCE_LONG_PRESS +from openpilot.sunnypilot.selfdrive.car.experimental_switcher import ExperimentalSwitcher REPLAY = "REPLAY" in os.environ SIMULATION = "SIMULATION" in os.environ From 6b4ef00ae60a7ab76b807c439a9409233e3e6c56 Mon Sep 17 00:00:00 2001 From: Jason Wen Date: Wed, 15 Jan 2025 10:57:51 -0500 Subject: [PATCH 3/4] fix --- sunnypilot/selfdrive/car/experimental_switcher.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sunnypilot/selfdrive/car/experimental_switcher.py b/sunnypilot/selfdrive/car/experimental_switcher.py index db8665ddf9..3dd3db1478 100644 --- a/sunnypilot/selfdrive/car/experimental_switcher.py +++ b/sunnypilot/selfdrive/car/experimental_switcher.py @@ -5,10 +5,10 @@ This file is part of sunnypilot and is licensed under the MIT License. See the LICENSE.md file in the root directory for more details. """ -from cereal import car +from cereal import car, log ButtonType = car.CarState.ButtonEvent.Type -EventName = car.CarEvent.EventName +EventName = log.OnroadEvent.EventName DISTANCE_LONG_PRESS = 50 From 391a3160a0391b9b03bb4b93a57549d5237777a0 Mon Sep 17 00:00:00 2001 From: Jason Wen Date: Wed, 15 Jan 2025 11:00:08 -0500 Subject: [PATCH 4/4] no need --- selfdrive/selfdrived/events.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/selfdrive/selfdrived/events.py b/selfdrive/selfdrived/events.py index 065dd635b8..1e587caece 100755 --- a/selfdrive/selfdrived/events.py +++ b/selfdrive/selfdrived/events.py @@ -1066,7 +1066,7 @@ EVENTS: dict[int, dict[str, Alert | AlertCallbackType]] = { }, EventName.experimentalModeSwitched: { - ET.WARNING: NormalPermanentAlert(f"Experimental Mode Switched", duration=1.5) + ET.WARNING: NormalPermanentAlert("Experimental Mode Switched", duration=1.5) } }