diff --git a/openpilot/common/params_keys.h b/openpilot/common/params_keys.h index 6a334a7020..93374fdc02 100644 --- a/openpilot/common/params_keys.h +++ b/openpilot/common/params_keys.h @@ -40,8 +40,7 @@ inline static std::unordered_map keys = { {"DriverTooDistracted", {CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_ON, BOOL}}, {"DriverLockoutCount", {CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_ON, INT, "0"}}, {"AlphaLongitudinalEnabled", {PERSISTENT | DEVELOPMENT_ONLY, BOOL}}, - {"ExperimentalMode", {PERSISTENT, BOOL}}, - {"ExperimentalModeConfirmed", {PERSISTENT, BOOL}}, + {"ExperimentalMode", {PERSISTENT, BOOL, "1"}}, {"FirmwareQueryDone", {CLEAR_ON_MANAGER_START | CLEAR_ON_ONROAD_TRANSITION, BOOL}}, {"ForcePowerDown", {PERSISTENT, BOOL}}, {"GitBranch", {PERSISTENT, STRING}}, diff --git a/openpilot/selfdrive/ui/layouts/settings/toggles.py b/openpilot/selfdrive/ui/layouts/settings/toggles.py index 090c49f14e..06091782b1 100644 --- a/openpilot/selfdrive/ui/layouts/settings/toggles.py +++ b/openpilot/selfdrive/ui/layouts/settings/toggles.py @@ -3,10 +3,7 @@ from openpilot.common.params import Params, UnknownKeyName from openpilot.system.ui.widgets import Widget from openpilot.system.ui.widgets.list_view import multiple_button_item, toggle_item from openpilot.system.ui.widgets.scroller_tici import Scroller -from openpilot.system.ui.widgets.confirm_dialog import ConfirmDialog -from openpilot.system.ui.lib.application import gui_app from openpilot.system.ui.lib.multilang import tr, tr_noop -from openpilot.system.ui.widgets import DialogResult from openpilot.selfdrive.ui.ui_state import ui_state PERSONALITY_TO_INT = log.LongitudinalPersonality.schema.enumerants @@ -156,15 +153,9 @@ class TogglesLayout(Widget): ui_state.update_params() e2e_description = tr( - "openpilot defaults to driving in chill mode. Experimental mode enables alpha-level features that aren't ready for chill mode. " + - "Experimental features are listed below:
" + "

End-to-End Longitudinal Control


" + "Let the driving model control the gas and brakes. openpilot will drive as it thinks a human would, including stopping for red lights and stop signs. " + - "Since the driving model decides the speed to drive, the set speed will only act as an upper bound. This is an alpha quality feature; " + - "mistakes should be expected.
" + - "

New Driving Visualization


" + - "The driving visualization will transition to the road-facing wide-angle camera at low speeds to better show some turns. " + - "The Experimental mode logo will also be shown in the top right corner." + "Since the driving model decides the speed to drive, the set speed will only act as an upper bound. Mistakes should be expected.
" ) if ui_state.CP is not None: @@ -212,32 +203,11 @@ class TogglesLayout(Widget): icon = "experimental.png" if self._toggles["ExperimentalMode"].action_item.get_state() else "experimental_white.png" self._toggles["ExperimentalMode"].set_icon(icon) - def _handle_experimental_mode_toggle(self, state: bool): - confirmed = self._params.get_bool("ExperimentalModeConfirmed") - if state and not confirmed: - def confirm_callback(result: DialogResult): - if result == DialogResult.CONFIRM: - self._params.put_bool("ExperimentalMode", True, block=True) - self._params.put_bool("ExperimentalModeConfirmed", True, block=True) - else: - self._toggles["ExperimentalMode"].action_item.set_state(False) - self._update_experimental_mode_icon() - - # show confirmation dialog - content = (f"

{self._toggles['ExperimentalMode'].title}


" + - f"

{self._toggles['ExperimentalMode'].description}

") - dlg = ConfirmDialog(content, tr("Enable"), rich=True, callback=confirm_callback) - gui_app.push_widget(dlg) - else: - self._update_experimental_mode_icon() - self._params.put_bool("ExperimentalMode", state, block=True) - def _toggle_callback(self, state: bool, param: str): - if param == "ExperimentalMode": - self._handle_experimental_mode_toggle(state) - return - self._params.put_bool(param, state, block=True) + if param == "ExperimentalMode": + self._update_experimental_mode_icon() + if self._toggle_defs[param][3]: self._params.put_bool("OnroadCycleRequested", True, block=True) diff --git a/openpilot/selfdrive/ui/mici/layouts/home.py b/openpilot/selfdrive/ui/mici/layouts/home.py index b852bf9ea6..14370d67c4 100644 --- a/openpilot/selfdrive/ui/mici/layouts/home.py +++ b/openpilot/selfdrive/ui/mici/layouts/home.py @@ -173,7 +173,7 @@ class MiciHomeLayout(Widget): if self._mouse_down_t is not None: if time.monotonic() - self._mouse_down_t > 0.5: # long gating for experimental mode - only allow toggle if longitudinal control is available - if ui_state.has_longitudinal_control and ui_state.experimental_mode_confirmed: + if ui_state.has_longitudinal_control: ui_state.experimental_mode = not ui_state.experimental_mode ui_state.params.put("ExperimentalMode", ui_state.experimental_mode, block=True) self._mouse_down_t = None diff --git a/openpilot/selfdrive/ui/mici/layouts/settings/toggles.py b/openpilot/selfdrive/ui/mici/layouts/settings/toggles.py index 40a6188579..0cd552c6cd 100644 --- a/openpilot/selfdrive/ui/mici/layouts/settings/toggles.py +++ b/openpilot/selfdrive/ui/mici/layouts/settings/toggles.py @@ -1,10 +1,7 @@ -from collections.abc import Callable - from openpilot.cereal import log from openpilot.system.ui.widgets.scroller import NavScroller -from openpilot.selfdrive.ui.mici.widgets.button import BigParamControl, BigMultiParamToggle, BigToggle, GreyBigButton -from openpilot.selfdrive.ui.mici.widgets.dialog import BigConfirmationCircleButton +from openpilot.selfdrive.ui.mici.widgets.button import BigParamControl, BigMultiParamToggle from openpilot.system.ui.lib.application import gui_app from openpilot.selfdrive.ui.layouts.settings.common import restart_needed_callback from openpilot.selfdrive.ui.ui_state import ui_state @@ -12,31 +9,6 @@ from openpilot.selfdrive.ui.ui_state import ui_state PERSONALITY_TO_INT = log.LongitudinalPersonality.schema.enumerants -class ExperimentalModeConfirmPage(NavScroller): - def __init__(self, on_confirm: Callable[[], None]): - super().__init__() - - accept = BigConfirmationCircleButton("enable\nexperimental mode", - gui_app.texture("icons_mici/setup/driver_monitoring/dm_check.png", 64, 64), - lambda: self.dismiss(on_confirm)) - - self._scroller.add_widgets([ - GreyBigButton("enabling\nexperimental mode", "scroll to continue", - gui_app.texture("icons_mici/setup/warning.png", 64, 64)), - GreyBigButton("", "openpilot defaults to driving in chill mode."), - GreyBigButton("", "Experimental mode enables alpha-level features that aren't ready for chill mode."), - GreyBigButton("End-to-End Longitudinal Control"), - GreyBigButton("", "Let the driving model control the gas and brakes."), - GreyBigButton("", "openpilot will drive as it thinks a human would, including stopping for red lights and stop signs."), - GreyBigButton("", "The set speed will only act as an upper bound."), - GreyBigButton("", "This is an alpha quality feature; mistakes should be expected."), - GreyBigButton("New Driving Visualization"), - GreyBigButton("", "The path will change colors to communicate acceleration intent."), - GreyBigButton("", "Red for braking, green for acceleration, and gray for coasting."), - accept, - ]) - - class TogglesLayoutMici(NavScroller): def __init__(self): super().__init__() @@ -46,8 +18,8 @@ class TogglesLayoutMici(NavScroller): "Aggressive follows closer, with firmer gas and braking.\n" + "Relaxed leaves more space.\n" + "Use the steering wheel distance button on supported cars.") - self._experimental_btn = BigToggle("experimental mode", description_icon=gui_app.texture("icons_mici/experimental_mode.png", 64, 64), - initial_state=ui_state.params.get_bool("ExperimentalMode"), toggle_callback=self._on_experimental_mode, + self._experimental_btn = BigParamControl("experimental mode", "ExperimentalMode", + description_icon=gui_app.texture("icons_mici/experimental_mode.png", 64, 64), description="Let the driving model control gas and brakes.\n" + "Includes stopping for red lights and stop signs.\n" + "Set speed is a maximum, not a target.\n" + @@ -132,17 +104,3 @@ class TogglesLayoutMici(NavScroller): # Refresh toggles from params to mirror external changes for key, item in self._refresh_toggles: item.set_checked(ui_state.params.get_bool(key)) - - def _on_experimental_mode(self, state: bool): - if state and not ui_state.params.get_bool("ExperimentalModeConfirmed"): - # Don't show enabled state until confirm - self._experimental_btn.set_checked(False) - - def on_confirm(): - ui_state.params.put_bool("ExperimentalModeConfirmed", True) - ui_state.params.put_bool("ExperimentalMode", True) - self._experimental_btn.set_checked(True) - - gui_app.push_widget(ExperimentalModeConfirmPage(on_confirm)) - else: - ui_state.params.put_bool("ExperimentalMode", state) diff --git a/openpilot/selfdrive/ui/onroad/exp_button.py b/openpilot/selfdrive/ui/onroad/exp_button.py index 9a92ebc3c3..a122394c88 100644 --- a/openpilot/selfdrive/ui/onroad/exp_button.py +++ b/openpilot/selfdrive/ui/onroad/exp_button.py @@ -34,7 +34,7 @@ class ExpButton(Widget): def _handle_mouse_release(self, _): super()._handle_mouse_release(_) - if self._is_toggle_allowed(): + if ui_state.has_longitudinal_control: new_mode = not self._experimental_mode self._params.put_bool("ExperimentalMode", new_mode) @@ -61,10 +61,3 @@ class ExpButton(Widget): self._hold_end_time = self._held_mode = None return self._experimental_mode - - def _is_toggle_allowed(self): - if not self._params.get_bool("ExperimentalModeConfirmed"): - return False - - # Mirror exp mode toggle using persistent car params - return ui_state.has_longitudinal_control diff --git a/openpilot/selfdrive/ui/ui_state.py b/openpilot/selfdrive/ui/ui_state.py index 9489673039..647f977677 100644 --- a/openpilot/selfdrive/ui/ui_state.py +++ b/openpilot/selfdrive/ui/ui_state.py @@ -86,7 +86,6 @@ class UIState: self.is_release = self.params.get_bool("IsReleaseBranch") self.always_on_dm: bool = self.params.get_bool("AlwaysOnDM") self.experimental_mode: bool = self.params.get_bool("ExperimentalMode") - self.experimental_mode_confirmed: bool = self.params.get_bool("ExperimentalModeConfirmed") self.chestnut_present: bool = False self.chestnut_compiled: bool = chestnut_compiled() self.chestnut_active: bool | None = None @@ -246,7 +245,6 @@ class UIState: self.is_metric = self.params.get_bool("IsMetric") self.always_on_dm = self.params.get_bool("AlwaysOnDM") self.experimental_mode = self.params.get_bool("ExperimentalMode") - self.experimental_mode_confirmed = self.params.get_bool("ExperimentalModeConfirmed") self.chestnut_active = self.params.get("ChestnutActive") self.chestnut_loading = self.params.get_bool("ChestnutLoading") now = time.monotonic()