Files
IQ.Pilot/iqpilot/selfdrive/ui/mici/layouts/settings/steering.py
2026-08-22 23:42:41 -05:00

152 lines
5.7 KiB
Python

"""
Copyright © IQ.Lvbs, apart of Project Teal Lvbs, All Rights Reserved, licensed under https://konn3kt.com/tos/
"""
from iqpilot.cereal import car
from iqpilot.common.params import Params
from iqpilot.selfdrive.controls.lib.helpers.lane_change import AutoLaneChangeMode
from iqpilot.selfdrive.ui.mici.widgets.stock_button import BigButton, BigParamControl
from iqpilot.selfdrive.ui.mici.layouts.settings.iq_widgets import MappedParamToggle
from iqpilot.selfdrive.ui.ui_state import ui_state
from iqpilot.system.ui.lib.application import gui_app
from iqpilot.system.ui.widgets.scroller import NavScroller
from iqpilot.system.ui.lib.multilang import tr
def _aol_modes() -> list[str]:
return [tr("stay engaged"), tr("standby"), tr("disengage")]
class SabBrakeToggle(BigParamControl):
"""Driver-intervention toggle backed by AolSteeringMode == 2."""
def __init__(self):
super().__init__(tr("Driver Intervention Handling"), "AolEnabled")
def refresh(self):
self.set_checked(int(self.params.get("AolSteeringMode", return_default=True)) == 2)
def _handle_mouse_release(self, mouse_pos):
super(BigParamControl, self)._handle_mouse_release(mouse_pos)
enabled = self._checked
current_mode = int(self.params.get("AolSteeringMode", return_default=True))
if enabled:
self.params.put("AolSteeringMode", 2)
elif current_mode == 2:
self.params.put("AolSteeringMode", 1)
def _has_limited_sab_options() -> bool:
brand = ""
if ui_state.is_offroad():
bundle = ui_state.params.get("CarPlatformBundle")
if bundle:
brand = bundle.get("brand", "")
if not brand:
brand = ui_state.CP.brand if ui_state.CP else ""
return brand == "rivian"
class SabSettingsPanel(NavScroller):
def __init__(self):
super().__init__()
self._main_cruise = BigParamControl(tr("Availability While Cruise Changes"), "AolMainCruiseAllowed")
self._brake = SabBrakeToggle()
self._mode = MappedParamToggle(tr("Brake Response Mode"), "AolSteeringMode",
_aol_modes(), [0, 1, 2])
self._steer_override = BigParamControl(tr("Pause While You Steer"), "AolPauseOnSteeringOverride")
self._scroller.add_widgets([self._main_cruise, self._brake, self._mode, self._steer_override])
def show_event(self):
super().show_event()
limited = _has_limited_sab_options()
if limited:
ui_state.params.remove("AolMainCruiseAllowed")
ui_state.params.put_bool("AolUnifiedEngagementMode", True)
ui_state.params.put("AolSteeringMode", 2)
offroad = ui_state.is_offroad()
for w in (self._main_cruise, self._brake, self._mode):
w.refresh()
w.set_enabled(offroad and not limited)
self._steer_override.refresh()
self._steer_override.set_enabled(offroad)
class LaneChangePanel(NavScroller):
def __init__(self):
super().__init__()
self._timer = MappedParamToggle(tr("Auto Lane Change"), "IQLaneChangeTimer",
[tr("off"), tr("nudge"), tr("no nudge"), "0.5 s", "1 s", "2 s", "3 s"],
[-1, 0, 1, 2, 3, 4, 5])
self._bsm_delay = BigParamControl(tr("Delay with Blind Spot"), "IQLaneChangeBsmDelay")
self._continuous = BigParamControl(tr("Continuous Changes"), "LaneChangeContinuous")
self._scroller.add_widgets([self._timer, self._bsm_delay, self._continuous])
def show_event(self):
super().show_event()
self._timer.refresh()
enable_bsm = bool(ui_state.CP and ui_state.CP.enableBsm)
if not enable_bsm and ui_state.params.get_bool("IQLaneChangeBsmDelay"):
ui_state.params.remove("IQLaneChangeBsmDelay")
self._bsm_delay.refresh()
self._bsm_delay.set_enabled(
enable_bsm and int(ui_state.params.get("IQLaneChangeTimer", return_default=True)) > AutoLaneChangeMode.NUDGE
)
self._continuous.refresh()
class SteeringLayoutMici(NavScroller):
def __init__(self):
super().__init__()
self._sab_panel = SabSettingsPanel()
self._lc_panel = LaneChangePanel()
self._aol = BigParamControl(tr("AOL"), "AolEnabled", toggle_callback=self._on_aol_toggled)
self._sab_settings_button = BigButton(tr("steering assistance behavior"))
self._sab_settings_button.set_click_callback(lambda: gui_app.push_widget(self._sab_panel))
self._lane_change = BigButton(tr("lane change"))
self._lane_change.set_click_callback(lambda: gui_app.push_widget(self._lc_panel))
self._nnff = BigParamControl(tr("Neural Net FF"), "NeuralNetworkFeedForward", toggle_callback=self._on_nnff_toggled)
self._scroller.add_widgets([
self._aol, self._sab_settings_button, self._lane_change,
self._nnff,
])
def _aol_mode_str(self) -> str:
try:
return _aol_modes()[int(ui_state.params.get("AolSteeringMode", return_default=True))]
except (TypeError, ValueError, IndexError):
return _aol_modes()[0]
def _on_aol_toggled(self, checked: bool):
if checked:
ui_state.params.put_bool("AolUnifiedEngagementMode", True)
def _on_nnff_toggled(self, checked: bool):
return None
def _refresh(self):
offroad = ui_state.is_offroad()
self._aol.refresh()
self._aol.set_value(self._aol_mode_str())
self._nnff.refresh()
steering_supported = (ui_state.CP is not None and
ui_state.CP.steerControlType != car.CarParams.SteerControlType.angle)
if not steering_supported:
ui_state.params.remove("NeuralNetworkFeedForward")
self._nnff.refresh()
self._aol.set_enabled(offroad)
self._sab_settings_button.set_enabled(offroad and self._aol._checked)
self._nnff.set_enabled(offroad and steering_supported)
def _update_state(self):
super()._update_state()
self._refresh()
def show_event(self):
super().show_event()
self._refresh()