mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-09-29 10:53:49 +08:00
BigUI WIP: Meet The Parents
This commit is contained in:
@@ -2952,6 +2952,14 @@ class SettingSection:
|
||||
row_height: int = ROW_HEIGHT
|
||||
|
||||
|
||||
@dataclass
|
||||
class ParentToggle:
|
||||
label: str
|
||||
get_state: Callable[[], bool]
|
||||
set_state: Callable[[bool], None]
|
||||
subtitle: str = ""
|
||||
|
||||
|
||||
# ── AetherSettingsView — reusable list-panel ManagerView ──
|
||||
|
||||
class AetherSettingsView(PanelManagerView):
|
||||
@@ -2965,6 +2973,7 @@ class AetherSettingsView(PanelManagerView):
|
||||
|
||||
def __init__(self, controller, sections: list[SettingSection],
|
||||
*, header_title: str = "", header_subtitle: str = "",
|
||||
parent_toggle: ParentToggle | None = None,
|
||||
tab_defs: list[dict] | None = None,
|
||||
panel_style=None, fade_height: float = AETHER_LIST_METRICS.fade_height,
|
||||
metrics = COMPACT_PANEL_METRICS):
|
||||
@@ -2976,7 +2985,8 @@ class AetherSettingsView(PanelManagerView):
|
||||
self._sections = sections
|
||||
self._header_title = header_title
|
||||
self._header_subtitle = header_subtitle
|
||||
self._has_header = bool(header_title)
|
||||
self._parent_toggle = parent_toggle
|
||||
self._has_header = bool(header_title) or parent_toggle is not None
|
||||
self._tab_defs = tab_defs
|
||||
self._active_tab_key = tab_defs[0]["id"] if tab_defs else ""
|
||||
self._scroll_panel = GuiScrollPanel2(horizontal=False)
|
||||
@@ -2992,9 +3002,20 @@ class AetherSettingsView(PanelManagerView):
|
||||
return row
|
||||
return None
|
||||
|
||||
def _target_at(self, mouse_pos: MousePos) -> str | None:
|
||||
if self._parent_toggle:
|
||||
mid = f"parent_toggle:{self._parent_toggle.label}"
|
||||
rect = self._interactive_rects.get(mid)
|
||||
if rect and point_hits(mouse_pos, rect, None, pad_x=6, pad_y=6):
|
||||
return mid
|
||||
return super()._target_at(mouse_pos)
|
||||
|
||||
def _activate_target(self, target_id: str | None):
|
||||
if not target_id:
|
||||
return
|
||||
if target_id.startswith("parent_toggle:") and self._parent_toggle:
|
||||
self._parent_toggle.set_state(not self._parent_toggle.get_state())
|
||||
return
|
||||
if target_id.startswith("tab:") and self._tab_defs:
|
||||
self._active_tab_key = target_id[4:]
|
||||
return
|
||||
@@ -3013,6 +3034,19 @@ class AetherSettingsView(PanelManagerView):
|
||||
def _compute_header_height(self, content_width: float) -> float:
|
||||
if not self._has_header:
|
||||
return 0.0
|
||||
if self._parent_toggle:
|
||||
h = max(42.0, 40.0) # toggle (42px at header top) vs title area (32px + 8px gap)
|
||||
subtitle_text = tr(self._parent_toggle.subtitle) if self._parent_toggle.subtitle else ""
|
||||
if self._header_subtitle:
|
||||
subtitle_text = tr(self._header_subtitle)
|
||||
if subtitle_text:
|
||||
toggle_take = AETHER_LIST_METRICS.toggle_width + AETHER_LIST_METRICS.toggle_right_inset + 16
|
||||
col_w = max(100.0, content_width + AETHER_LIST_METRICS.content_right_gutter - toggle_take)
|
||||
desc_font = gui_app.font(FontWeight.NORMAL)
|
||||
desc_lines = wrap_text(desc_font, subtitle_text, col_w, 18, max_lines=4)
|
||||
h += len(desc_lines) * 22.0 + 12.0
|
||||
h += SECTION_GAP
|
||||
return h
|
||||
h = 40.0 # title (32px) + inner gap (8px)
|
||||
if self._header_subtitle:
|
||||
subtitle_text = tr(self._header_subtitle)
|
||||
@@ -3066,7 +3100,42 @@ class AetherSettingsView(PanelManagerView):
|
||||
def _draw_header(self, rect: rl.Rectangle):
|
||||
title = tr(self._header_title) if self._header_title else ""
|
||||
subtitle = tr(self._header_subtitle) if self._header_subtitle else ""
|
||||
draw_settings_panel_header(rect, title, subtitle, title_size=32, subtitle_size=18)
|
||||
|
||||
if self._parent_toggle:
|
||||
toggle = self._parent_toggle
|
||||
|
||||
display_title = title if title else tr(toggle.label)
|
||||
subtitle_text = subtitle if subtitle else (tr(toggle.subtitle) if toggle.subtitle else "")
|
||||
|
||||
toggle_take = AETHER_LIST_METRICS.toggle_width + AETHER_LIST_METRICS.toggle_right_inset + 16
|
||||
text_rect = rl.Rectangle(rect.x, rect.y, max(100.0, rect.width - toggle_take), rect.height)
|
||||
draw_settings_panel_header(text_rect, display_title, subtitle_text, title_size=32, subtitle_size=18)
|
||||
|
||||
toggle_id = f"parent_toggle:{toggle.label}"
|
||||
tw = AETHER_LIST_METRICS.toggle_width
|
||||
th = AETHER_LIST_METRICS.toggle_height
|
||||
ri = AETHER_LIST_METRICS.toggle_right_inset
|
||||
toggle_rect = rl.Rectangle(rect.x + rect.width - tw - ri, rect.y, tw, th)
|
||||
self._interactive_rects[toggle_id] = toggle_rect
|
||||
|
||||
toggle_value = toggle.get_state()
|
||||
target_progress = 1.0 if toggle_value else 0.0
|
||||
current_progress = _KNOB_ANIMATION_STATES.get(toggle_id, target_progress)
|
||||
dt = rl.get_frame_time()
|
||||
current_progress += (target_progress - current_progress) * 12.0 * dt
|
||||
if abs(current_progress - target_progress) < 0.001:
|
||||
current_progress = target_progress
|
||||
_KNOB_ANIMATION_STATES[toggle_id] = current_progress
|
||||
|
||||
draw_toggle_switch(
|
||||
rl.Rectangle(rect.x, rect.y, rect.width, th),
|
||||
toggle_value,
|
||||
knob_progress=current_progress,
|
||||
track_color=self._panel_style.accent,
|
||||
seed_id=toggle_id,
|
||||
)
|
||||
else:
|
||||
draw_settings_panel_header(rect, title, subtitle, title_size=32, subtitle_size=18)
|
||||
|
||||
def _active_sections(self) -> list[SettingSection]:
|
||||
if self._tab_defs and self._active_tab_key:
|
||||
@@ -3129,12 +3198,20 @@ class AetherSettingsView(PanelManagerView):
|
||||
active = self._active_sections()
|
||||
has_visible = any(self._visible_rows(s) for s in active)
|
||||
if not has_visible:
|
||||
draw_empty_state_card(
|
||||
rl.Rectangle(rect.x, y, width, rect.height - (y - rect.y)),
|
||||
tr("No settings to display"),
|
||||
tr("All options in this panel are hidden or unavailable."),
|
||||
style=self._panel_style,
|
||||
)
|
||||
if self._parent_toggle and not self._parent_toggle.get_state():
|
||||
draw_empty_state_card(
|
||||
rl.Rectangle(rect.x, y, width, rect.height - (y - rect.y)),
|
||||
tr("Enable {} to configure settings.").format(tr(self._parent_toggle.label)),
|
||||
"",
|
||||
style=self._panel_style,
|
||||
)
|
||||
elif not self._parent_toggle:
|
||||
draw_empty_state_card(
|
||||
rl.Rectangle(rect.x, y, width, rect.height - (y - rect.y)),
|
||||
tr("No settings to display"),
|
||||
tr("All options in this panel are hidden or unavailable."),
|
||||
style=self._panel_style,
|
||||
)
|
||||
return
|
||||
i = 0
|
||||
while i < len(active):
|
||||
|
||||
@@ -15,6 +15,7 @@ import pyray as rl
|
||||
from openpilot.selfdrive.ui.layouts.settings.starpilot.aethergrid import (
|
||||
AetherSliderDialog,
|
||||
DEFAULT_PANEL_STYLE,
|
||||
ParentToggle,
|
||||
SettingRow,
|
||||
SettingSection,
|
||||
AetherSettingsView,
|
||||
@@ -177,6 +178,14 @@ class StarPilotAppearanceLayout(_SettingsPage):
|
||||
super().__init__()
|
||||
self._build_view()
|
||||
|
||||
def _make_parent(self, key: str, label: str, subtitle: str = "") -> ParentToggle:
|
||||
return ParentToggle(
|
||||
label=label,
|
||||
subtitle=subtitle,
|
||||
get_state=lambda k=key: self._params.get_bool(k),
|
||||
set_state=lambda s, k=key: self._params.put_bool(k, s),
|
||||
)
|
||||
|
||||
def _show_lead_detection_threshold_selector(self):
|
||||
def on_close(res, val):
|
||||
if res == DialogResult.CONFIRM:
|
||||
@@ -197,127 +206,146 @@ class StarPilotAppearanceLayout(_SettingsPage):
|
||||
po = lambda: self._params.get_bool("PedalsOnUI")
|
||||
ol = lambda: starpilot_state.car_state.hasOpenpilotLongitudinal
|
||||
bsm = lambda: starpilot_state.car_state.hasBSM
|
||||
model_on = lambda: self._params.get_bool("ModelUI")
|
||||
hud_on = lambda: self._params.get_bool("CustomUI")
|
||||
|
||||
# ═══ 1. Model & Path Visualization ═══
|
||||
self._model_rows = [
|
||||
SettingRow("ModelUI", "toggle", tr_noop("Model UI"),
|
||||
subtitle=tr_noop("Display the driving model path, lanes, and road edges."),
|
||||
get_state=lambda: self._params.get_bool("ModelUI"),
|
||||
set_state=lambda s: self._params.put_bool("ModelUI", s)),
|
||||
SettingRow("DynamicPathWidth", "toggle", tr_noop("Dynamic Path"),
|
||||
subtitle="",
|
||||
get_state=lambda: self._params.get_bool("DynamicPathWidth"),
|
||||
set_state=lambda s: self._params.put_bool("DynamicPathWidth", s)),
|
||||
set_state=lambda s: self._params.put_bool("DynamicPathWidth", s),
|
||||
visible=model_on),
|
||||
SettingRow("LaneLinesWidth", "value", tr_noop("Lane Line Width"),
|
||||
subtitle="",
|
||||
get_value=self._get_lane_lines_display,
|
||||
on_click=lambda: self._show_int_selector("LaneLinesWidth", 0, 24, self._get_lane_lines_unit())),
|
||||
on_click=lambda: self._show_int_selector("LaneLinesWidth", 0, 24, self._get_lane_lines_unit()),
|
||||
visible=model_on),
|
||||
SettingRow("LaneLinesColor", "value", tr_noop("Lane Line Color"),
|
||||
subtitle="",
|
||||
get_value=lambda: self._get_color_display("LaneLinesColor"),
|
||||
on_click=lambda: self._show_color_selector("LaneLinesColor")),
|
||||
on_click=lambda: self._show_color_selector("LaneLinesColor"),
|
||||
visible=model_on),
|
||||
SettingRow("PathWidth", "value", tr_noop("Path Width"),
|
||||
subtitle="",
|
||||
get_value=self._get_path_width_display,
|
||||
on_click=self._show_path_width_selector),
|
||||
on_click=self._show_path_width_selector,
|
||||
visible=model_on),
|
||||
SettingRow("PathEdgeWidth", "value", tr_noop("Path Edge Width"),
|
||||
subtitle="",
|
||||
get_value=lambda: f"{self._params.get_int('PathEdgeWidth')}%",
|
||||
on_click=lambda: self._show_int_selector("PathEdgeWidth", 0, 100, "%")),
|
||||
on_click=lambda: self._show_int_selector("PathEdgeWidth", 0, 100, "%"),
|
||||
visible=model_on),
|
||||
SettingRow("PathEdgesColor", "value", tr_noop("Path Edge Color"),
|
||||
subtitle="",
|
||||
get_value=lambda: self._get_color_display("PathEdgesColor"),
|
||||
on_click=lambda: self._show_color_selector("PathEdgesColor")),
|
||||
on_click=lambda: self._show_color_selector("PathEdgesColor"),
|
||||
visible=model_on),
|
||||
SettingRow("PathColor", "value", tr_noop("Path Color"),
|
||||
subtitle="",
|
||||
get_value=lambda: self._get_color_display("PathColor"),
|
||||
on_click=lambda: self._show_color_selector("PathColor")),
|
||||
on_click=lambda: self._show_color_selector("PathColor"),
|
||||
visible=model_on),
|
||||
SettingRow("RoadEdgesWidth", "value", tr_noop("Road Edge Width"),
|
||||
subtitle="",
|
||||
get_value=self._get_road_edges_display,
|
||||
on_click=lambda: self._show_int_selector("RoadEdgesWidth", 0, 24, self._get_road_edges_unit())),
|
||||
on_click=lambda: self._show_int_selector("RoadEdgesWidth", 0, 24, self._get_road_edges_unit()),
|
||||
visible=model_on),
|
||||
SettingRow("RainbowPath", "toggle", tr_noop("Rainbow Path"),
|
||||
subtitle="",
|
||||
get_state=lambda: self._params.get_bool("RainbowPath"),
|
||||
set_state=lambda s: self._params.put_bool("RainbowPath", s)),
|
||||
set_state=lambda s: self._params.put_bool("RainbowPath", s),
|
||||
visible=model_on),
|
||||
SettingRow("AccelerationPath", "toggle", tr_noop("Acceleration Path"),
|
||||
subtitle="",
|
||||
get_state=lambda: self._params.get_bool("AccelerationPath"),
|
||||
set_state=lambda s: self._params.put_bool("AccelerationPath", s),
|
||||
enabled=ol),
|
||||
enabled=ol,
|
||||
visible=model_on),
|
||||
SettingRow("AdjacentPath", "toggle", tr_noop("Adjacent Lanes"),
|
||||
subtitle="",
|
||||
get_state=lambda: self._params.get_bool("AdjacentPath"),
|
||||
set_state=lambda s: self._params.put_bool("AdjacentPath", s)),
|
||||
set_state=lambda s: self._params.put_bool("AdjacentPath", s),
|
||||
visible=model_on),
|
||||
SettingRow("AdjacentPathMetrics", "toggle", tr_noop("Adjacent Lane Metrics"),
|
||||
subtitle="",
|
||||
get_state=lambda: self._params.get_bool("AdjacentPathMetrics"),
|
||||
set_state=lambda s: self._params.put_bool("AdjacentPathMetrics", s)),
|
||||
set_state=lambda s: self._params.put_bool("AdjacentPathMetrics", s),
|
||||
visible=model_on),
|
||||
SettingRow("BlindSpotPath", "toggle", tr_noop("Blind Spot Path"),
|
||||
subtitle="",
|
||||
get_state=lambda: self._params.get_bool("BlindSpotPath"),
|
||||
set_state=lambda s: self._params.put_bool("BlindSpotPath", s),
|
||||
enabled=bsm),
|
||||
enabled=bsm,
|
||||
visible=model_on),
|
||||
]
|
||||
|
||||
# ═══ 2. Driving Widgets & HUD ═══
|
||||
self._hud_rows = [
|
||||
SettingRow("CustomUI", "toggle", tr_noop("Driving Screen Widgets"),
|
||||
subtitle=tr_noop("Show interactive indicators on the driving screen."),
|
||||
get_state=lambda: self._params.get_bool("CustomUI"),
|
||||
set_state=lambda s: self._params.put_bool("CustomUI", s)),
|
||||
SettingRow("Compass", "toggle", tr_noop("Compass"),
|
||||
subtitle="",
|
||||
get_state=lambda: self._params.get_bool("Compass"),
|
||||
set_state=lambda s: self._params.put_bool("Compass", s)),
|
||||
set_state=lambda s: self._params.put_bool("Compass", s),
|
||||
visible=hud_on),
|
||||
SettingRow("OnroadDistanceButton", "toggle", tr_noop("Personality Button"),
|
||||
subtitle="",
|
||||
get_state=lambda: self._params.get_bool("OnroadDistanceButton"),
|
||||
set_state=lambda s: self._params.put_bool("OnroadDistanceButton", s)),
|
||||
set_state=lambda s: self._params.put_bool("OnroadDistanceButton", s),
|
||||
visible=hud_on),
|
||||
SettingRow("RotatingWheel", "toggle", tr_noop("Rotating Wheel"),
|
||||
subtitle="",
|
||||
get_state=lambda: self._params.get_bool("RotatingWheel"),
|
||||
set_state=lambda s: self._params.put_bool("RotatingWheel", s)),
|
||||
set_state=lambda s: self._params.put_bool("RotatingWheel", s),
|
||||
visible=hud_on),
|
||||
SettingRow("ShowSteering", "toggle", tr_noop("Steering Torque Indicator"),
|
||||
subtitle="",
|
||||
get_state=lambda: self._params.get_bool("ShowSteering"),
|
||||
set_state=lambda s: self._params.put_bool("ShowSteering", s)),
|
||||
set_state=lambda s: self._params.put_bool("ShowSteering", s),
|
||||
visible=hud_on),
|
||||
SettingRow("SignalMetrics", "toggle", tr_noop("Turn Signal Borders"),
|
||||
subtitle="",
|
||||
get_state=lambda: self._params.get_bool("SignalMetrics"),
|
||||
set_state=lambda s: self._params.put_bool("SignalMetrics", s)),
|
||||
set_state=lambda s: self._params.put_bool("SignalMetrics", s),
|
||||
visible=hud_on),
|
||||
SettingRow("BlindSpotMetrics", "toggle", tr_noop("Blind Spot Borders"),
|
||||
subtitle="",
|
||||
get_state=lambda: self._params.get_bool("BlindSpotMetrics"),
|
||||
set_state=lambda s: self._params.put_bool("BlindSpotMetrics", s),
|
||||
enabled=bsm),
|
||||
enabled=bsm,
|
||||
visible=hud_on),
|
||||
SettingRow("WheelSpeed", "toggle", tr_noop("Wheel Speed"),
|
||||
subtitle="",
|
||||
get_state=lambda: self._params.get_bool("WheelSpeed"),
|
||||
set_state=lambda s: self._params.put_bool("WheelSpeed", s)),
|
||||
set_state=lambda s: self._params.put_bool("WheelSpeed", s),
|
||||
visible=hud_on),
|
||||
SettingRow("BorderWidth", "value", tr_noop("Border Width"),
|
||||
subtitle="",
|
||||
get_value=lambda: f"{int(round(self._params.get_float('BorderWidth')))}%",
|
||||
on_click=lambda: self._show_float_selector("BorderWidth", 25, 250, 5, "%")),
|
||||
on_click=lambda: self._show_float_selector("BorderWidth", 25, 250, 5, "%"),
|
||||
visible=hud_on),
|
||||
SettingRow("PedalsOnUI", "toggle", tr_noop("Pedal Indicators"),
|
||||
subtitle="",
|
||||
get_state=lambda: self._params.get_bool("PedalsOnUI"),
|
||||
set_state=lambda s: self._params.put_bool("PedalsOnUI", s),
|
||||
enabled=ol),
|
||||
enabled=ol,
|
||||
visible=hud_on),
|
||||
SettingRow("DynamicPedalsOnUI", "toggle", tr_noop("Dynamic Pedals"),
|
||||
subtitle="",
|
||||
get_state=lambda: self._params.get_bool("DynamicPedalsOnUI"),
|
||||
set_state=lambda s: self._set_exclusive_pedal("DynamicPedalsOnUI", "StaticPedalsOnUI", s),
|
||||
enabled=lambda: po() and ol()),
|
||||
enabled=lambda: po() and ol(),
|
||||
visible=hud_on),
|
||||
SettingRow("StaticPedalsOnUI", "toggle", tr_noop("Static Pedals"),
|
||||
subtitle="",
|
||||
get_state=lambda: self._params.get_bool("StaticPedalsOnUI"),
|
||||
set_state=lambda s: self._set_exclusive_pedal("StaticPedalsOnUI", "DynamicPedalsOnUI", s),
|
||||
enabled=lambda: po() and ol()),
|
||||
enabled=lambda: po() and ol(),
|
||||
visible=hud_on),
|
||||
SettingRow("StoppedTimer", "toggle", tr_noop("Stopped Timer"),
|
||||
subtitle="",
|
||||
get_state=lambda: self._params.get_bool("StoppedTimer"),
|
||||
set_state=lambda s: self._params.put_bool("StoppedTimer", s)),
|
||||
set_state=lambda s: self._params.put_bool("StoppedTimer", s),
|
||||
visible=hud_on),
|
||||
]
|
||||
|
||||
# ═══ 3. Screen Declutter & Visibility ═══
|
||||
@@ -461,12 +489,18 @@ class StarPilotAppearanceLayout(_SettingsPage):
|
||||
panel_style=PANEL_STYLE,
|
||||
)
|
||||
|
||||
pt_model = self._make_parent("ModelUI", "Model UI",
|
||||
"Display the driving model path, lanes, and road edges.")
|
||||
pt_hud = self._make_parent("CustomUI", "Driving Screen Widgets",
|
||||
"Show interactive indicators on the driving screen.")
|
||||
|
||||
# Register subpanels for Level 2 slide transitions
|
||||
self._sub_panels["model"] = AetherSettingsView(
|
||||
self,
|
||||
[SettingSection(title="", rows=self._model_rows)],
|
||||
header_title=tr_noop("Model & Path Visualization"),
|
||||
header_subtitle=tr_noop("Customize dynamic lane paths, road edges, and colors."),
|
||||
parent_toggle=pt_model,
|
||||
panel_style=PANEL_STYLE,
|
||||
)
|
||||
self._sub_panels["hud"] = AetherSettingsView(
|
||||
@@ -474,6 +508,7 @@ class StarPilotAppearanceLayout(_SettingsPage):
|
||||
[SettingSection(title="", rows=self._hud_rows)],
|
||||
header_title=tr_noop("Driving Widgets & HUD"),
|
||||
header_subtitle=tr_noop("Configure compass, dynamic pedals, signals, and screen borders."),
|
||||
parent_toggle=pt_hud,
|
||||
panel_style=PANEL_STYLE,
|
||||
)
|
||||
self._sub_panels["declutter"] = AetherSettingsView(
|
||||
|
||||
@@ -13,6 +13,7 @@ from openpilot.selfdrive.ui.layouts.settings.starpilot.panel import _SettingsPag
|
||||
from openpilot.selfdrive.ui.layouts.settings.starpilot.aethergrid import (
|
||||
DEFAULT_PANEL_STYLE,
|
||||
AetherSettingsView,
|
||||
ParentToggle,
|
||||
SettingRow,
|
||||
SettingSection,
|
||||
TileGrid,
|
||||
@@ -140,6 +141,14 @@ class StarPilotLateralLayout(_SettingsPage):
|
||||
super().__init__()
|
||||
self._build_panels()
|
||||
|
||||
def _make_parent(self, key: str, label: str, subtitle: str = "") -> ParentToggle:
|
||||
return ParentToggle(
|
||||
label=label,
|
||||
subtitle=subtitle,
|
||||
get_state=lambda k=key: self._params.get_bool(k),
|
||||
set_state=lambda s, k=key: self._params.put_bool(k, s),
|
||||
)
|
||||
|
||||
def _build_panels(self):
|
||||
p = self._params
|
||||
cs = starpilot_state.car_state
|
||||
@@ -161,12 +170,6 @@ class StarPilotLateralLayout(_SettingsPage):
|
||||
|
||||
# ── 1. Steering Behavior ──
|
||||
self._behavior_rows = [
|
||||
SettingRow(
|
||||
"AlwaysOnLateral", "toggle", tr_noop("Always On Lateral"),
|
||||
subtitle=tr_noop("Steering stays active when ACC is off."),
|
||||
get_state=lambda: p.get_bool("AlwaysOnLateral"),
|
||||
set_state=lambda s: _confirm_reboot_toggle(p, "AlwaysOnLateral", s) if s else p.put_bool("AlwaysOnLateral", False),
|
||||
),
|
||||
SettingRow(
|
||||
"PauseAOLOnBrake", "value", tr_noop("Pause AOL On Brake"),
|
||||
subtitle=tr_noop("Pause AOL below this speed while brake is pressed."),
|
||||
@@ -203,12 +206,6 @@ class StarPilotLateralLayout(_SettingsPage):
|
||||
|
||||
# ── 2. Lane Changes ──
|
||||
self._lane_change_rows = [
|
||||
SettingRow(
|
||||
"LaneChanges", "toggle", tr_noop("Lane Changes"),
|
||||
subtitle=tr_noop("Allow openpilot to change lanes."),
|
||||
get_state=lambda: p.get_bool("LaneChanges"),
|
||||
set_state=lambda s: p.put_bool("LaneChanges", s),
|
||||
),
|
||||
SettingRow(
|
||||
"NudgelessLaneChange", "toggle", tr_noop("Auto Lane Changes"),
|
||||
subtitle=tr_noop("Signal triggers automatic lane change."),
|
||||
@@ -255,12 +252,6 @@ class StarPilotLateralLayout(_SettingsPage):
|
||||
|
||||
# ── 3. Advanced Lateral Tuning ──
|
||||
self._advanced_rows = [
|
||||
SettingRow(
|
||||
"AdvancedLateralTune", "toggle", tr_noop("Advanced Lateral Tuning"),
|
||||
subtitle=tr_noop("Fine-tune steering response and auto-tuning."),
|
||||
get_state=lambda: p.get_bool("AdvancedLateralTune"),
|
||||
set_state=lambda s: p.put_bool("AdvancedLateralTune", s),
|
||||
),
|
||||
SettingRow(
|
||||
"NNFF", "toggle", tr_noop("NNFF"),
|
||||
subtitle=tr_noop("Neural net feedforward steering controller."),
|
||||
@@ -365,12 +356,25 @@ class StarPilotLateralLayout(_SettingsPage):
|
||||
header_subtitle=tr_noop("Configure steering behavior and lane changes."),
|
||||
)
|
||||
|
||||
p = self._params
|
||||
pt_behavior = ParentToggle(
|
||||
label="Always On Lateral",
|
||||
subtitle="Steering stays active when ACC is off.",
|
||||
get_state=lambda: p.get_bool("AlwaysOnLateral"),
|
||||
set_state=lambda s: _confirm_reboot_toggle(p, "AlwaysOnLateral", s) if s else p.put_bool("AlwaysOnLateral", False),
|
||||
)
|
||||
pt_lane_changes = self._make_parent("LaneChanges", "Lane Changes",
|
||||
"Allow openpilot to change lanes.")
|
||||
pt_advanced = self._make_parent("AdvancedLateralTune", "Advanced Lateral Tuning",
|
||||
"Fine-tune steering response and auto-tuning.")
|
||||
|
||||
# Register subpanels for Level 2 slide transitions
|
||||
self._sub_panels["behavior"] = AetherSettingsView(
|
||||
self,
|
||||
[SettingSection(title="", rows=self._behavior_rows)],
|
||||
header_title=tr_noop("Steering Behavior"),
|
||||
header_subtitle=tr_noop("Configure Always On Lateral (AOL), pause speed thresholds, and turn signal behaviors."),
|
||||
parent_toggle=pt_behavior,
|
||||
panel_style=PANEL_STYLE,
|
||||
)
|
||||
self._sub_panels["lane_changes"] = AetherSettingsView(
|
||||
@@ -378,6 +382,7 @@ class StarPilotLateralLayout(_SettingsPage):
|
||||
[SettingSection(title="", rows=self._lane_change_rows)],
|
||||
header_title=tr_noop("Lane Changes"),
|
||||
header_subtitle=tr_noop("Configure automatic lane changes, speed/width thresholds, and smoothing parameters."),
|
||||
parent_toggle=pt_lane_changes,
|
||||
panel_style=PANEL_STYLE,
|
||||
)
|
||||
self._sub_panels["advanced"] = AetherSettingsView(
|
||||
@@ -385,6 +390,7 @@ class StarPilotLateralLayout(_SettingsPage):
|
||||
[SettingSection(title="", rows=self._advanced_rows)],
|
||||
header_title=tr_noop("Advanced Lateral Tuning"),
|
||||
header_subtitle=tr_noop("Adjust actuator delay, steer ratio, Kp, friction, and neural network feedforward controllers."),
|
||||
parent_toggle=pt_advanced,
|
||||
panel_style=PANEL_STYLE,
|
||||
)
|
||||
self._wire_sub_panels()
|
||||
|
||||
@@ -19,6 +19,7 @@ from openpilot.selfdrive.ui.layouts.settings.starpilot.aethergrid import (
|
||||
AETHER_LIST_METRICS,
|
||||
AetherSliderDialog,
|
||||
DEFAULT_PANEL_STYLE,
|
||||
ParentToggle,
|
||||
SettingRow,
|
||||
SettingSection,
|
||||
AetherSettingsView,
|
||||
@@ -249,6 +250,14 @@ class StarPilotLongitudinalLayout(_SettingsPage):
|
||||
def _show_stop_tuning_values(self) -> bool:
|
||||
return self._advanced_enabled() and not (starpilot_state.car_state.isToyota and self._params.get_bool("FrogsGoMoosTweak"))
|
||||
|
||||
def _make_parent(self, key: str, label: str, subtitle: str = "") -> ParentToggle:
|
||||
return ParentToggle(
|
||||
label=label,
|
||||
subtitle=subtitle,
|
||||
get_state=lambda k=key: self._params.get_bool(k),
|
||||
set_state=lambda s, k=key: self._params.put_bool(k, s),
|
||||
)
|
||||
|
||||
def _build_view(self):
|
||||
ol = lambda: starpilot_state.car_state.hasOpenpilotLongitudinal
|
||||
ce_on = lambda: self._params.get_bool("ConditionalExperimental")
|
||||
@@ -258,10 +267,6 @@ class StarPilotLongitudinalLayout(_SettingsPage):
|
||||
|
||||
# ── 1. Longitudinal Tuning Rows ──
|
||||
self._tune_rows = [
|
||||
SettingRow("LongitudinalTune", "toggle", tr_noop("Longitudinal Tuning"),
|
||||
subtitle=tr_noop("Acceleration and braking control changes to fine-tune how openpilot drives."),
|
||||
get_state=lambda: self._params.get_bool("LongitudinalTune"),
|
||||
set_state=lambda s: self._params.put_bool("LongitudinalTune", s)),
|
||||
SettingRow("AccelProfile", "value", tr_noop("Acceleration Profile"),
|
||||
subtitle=tr_noop("Choose how quickly openpilot speeds up."),
|
||||
get_value=self._get_acceleration_profile_label,
|
||||
@@ -297,10 +302,6 @@ class StarPilotLongitudinalLayout(_SettingsPage):
|
||||
# ── 2. Advanced Actuators Rows ──
|
||||
adv = self._advanced_enabled
|
||||
self._advanced_rows = [
|
||||
SettingRow("AdvancedLongitudinalTune", "toggle", tr_noop("Advanced Longitudinal Tuning"),
|
||||
subtitle=tr_noop("Advanced acceleration and braking changes for refining launch, stopping, and actuator response."),
|
||||
get_state=lambda: self._params.get_bool("AdvancedLongitudinalTune"),
|
||||
set_state=lambda s: self._params.put_bool("AdvancedLongitudinalTune", s)),
|
||||
SettingRow("EVTuning", "toggle", tr_noop("EV Tuning"),
|
||||
subtitle=tr_noop("Acceleration tuning for EV and direct-drive vehicles."),
|
||||
get_state=lambda: self._params.get_bool("EVTuning"),
|
||||
@@ -359,10 +360,6 @@ class StarPilotLongitudinalLayout(_SettingsPage):
|
||||
|
||||
# ── 3. Speed Limit Controller (SLC) Rows ──
|
||||
self._slc_rows = [
|
||||
SettingRow("SLC", "toggle", tr_noop("Speed Limit Controller"),
|
||||
subtitle=tr_noop("Limit the car's maximum speed to the current speed limit."),
|
||||
get_state=lambda: self._params.get_bool("SpeedLimitController"),
|
||||
set_state=lambda s: self._params.put_bool("SpeedLimitController", s)),
|
||||
SettingRow("SLCFallback", "value", tr_noop("Fallback Speed"),
|
||||
subtitle="",
|
||||
get_value=lambda: self._params.get("SLCFallback", encoding="utf-8") or "Set Speed",
|
||||
@@ -436,10 +433,6 @@ class StarPilotLongitudinalLayout(_SettingsPage):
|
||||
|
||||
# ── 4. Adaptive Speed Controls Rows (CES + CSC) ──
|
||||
self._conditional_experimental_rows = [
|
||||
SettingRow("ConditionalExperimental", "toggle", tr_noop("Conditional Experimental Mode"),
|
||||
subtitle="",
|
||||
get_state=lambda: self._params.get_bool("ConditionalExperimental"),
|
||||
set_state=lambda s: self._params.put_bool("ConditionalExperimental", s)),
|
||||
SettingRow("PersistExp", "toggle", tr_noop("Persist Experimental State"),
|
||||
subtitle=tr_noop("Keep override through reboots until manually cleared."),
|
||||
get_state=lambda: self._params.get_bool("PersistExperimentalState"),
|
||||
@@ -508,10 +501,6 @@ class StarPilotLongitudinalLayout(_SettingsPage):
|
||||
]
|
||||
|
||||
self._curve_speed_controller_rows = [
|
||||
SettingRow("CurveSpeed", "toggle", tr_noop("Curve Speed Controller"),
|
||||
subtitle="",
|
||||
get_state=lambda: self._params.get_bool("CurveSpeedController"),
|
||||
set_state=lambda s: self._params.put_bool("CurveSpeedController", s)),
|
||||
SettingRow("ShowCSCStatus", "toggle", tr_noop("Status Widget"),
|
||||
subtitle=tr_noop("Show the Curve Speed Controller ambient effect on the driving screen."),
|
||||
get_state=lambda: self._params.get_bool("ShowCSCStatus"),
|
||||
@@ -537,10 +526,6 @@ class StarPilotLongitudinalLayout(_SettingsPage):
|
||||
|
||||
# ── 5. Driving Personalities Rows ──
|
||||
self._personality_rows = [
|
||||
SettingRow("PersonalitiesToggle", "toggle", tr_noop("Driving Personalities"),
|
||||
subtitle="",
|
||||
get_state=lambda: self._params.get_bool("CustomPersonalities"),
|
||||
set_state=lambda s: self._params.put_bool("CustomPersonalities", s)),
|
||||
SettingRow("Traffic", "value", tr_noop("Traffic"),
|
||||
subtitle=tr_noop("Configure follow distance, smoothness, and response for traffic conditions."),
|
||||
get_value=lambda: tr_noop("Configure"),
|
||||
@@ -561,10 +546,6 @@ class StarPilotLongitudinalLayout(_SettingsPage):
|
||||
|
||||
# ── 6. Daily QOL & Weather Rows ──
|
||||
self._daily_rows = [
|
||||
SettingRow("QOLToggle", "toggle", tr_noop("Quality of Life"),
|
||||
subtitle="",
|
||||
get_state=lambda: self._params.get_bool("QOLLongitudinal"),
|
||||
set_state=lambda s: self._params.put_bool("QOLLongitudinal", s)),
|
||||
SettingRow("CustomCruise", "value", tr_noop("Cruise Interval"),
|
||||
subtitle="",
|
||||
get_value=lambda: f"{max(1, self._params.get_int('CustomCruise'))} mph",
|
||||
@@ -661,6 +642,19 @@ class StarPilotLongitudinalLayout(_SettingsPage):
|
||||
panel_style=PANEL_STYLE,
|
||||
)
|
||||
|
||||
pt_tune = self._make_parent("LongitudinalTune", "Longitudinal Tuning",
|
||||
"Acceleration and braking control changes to fine-tune how openpilot drives.")
|
||||
pt_advanced = self._make_parent("AdvancedLongitudinalTune", "Advanced Longitudinal Tuning",
|
||||
"Advanced acceleration and braking changes for refining launch, stopping, and actuator response.")
|
||||
pt_personality = self._make_parent("CustomPersonalities", "Driving Personalities")
|
||||
pt_daily = self._make_parent("QOLLongitudinal", "Quality of Life")
|
||||
pt_slc = self._make_parent("SpeedLimitController", "Speed Limit Controller",
|
||||
"Limit the car's maximum speed to the current speed limit.")
|
||||
pt_ce = self._make_parent("ConditionalExperimental", "Conditional Experimental",
|
||||
"Configure triggers and threshold speeds for automated Experimental Mode switching.")
|
||||
pt_csc = self._make_parent("CurveSpeedController", "Curve Speed Controller",
|
||||
"Configure speed control on curves and reset collected calibration data.")
|
||||
|
||||
ce_rows = self._conditional_experimental_rows
|
||||
self._sub_panels["ce"] = AetherSettingsView(
|
||||
self,
|
||||
@@ -670,6 +664,7 @@ class StarPilotLongitudinalLayout(_SettingsPage):
|
||||
],
|
||||
header_title=tr("Conditional Experimental"),
|
||||
header_subtitle=tr("Configure triggers and threshold speeds for automated Experimental Mode switching."),
|
||||
parent_toggle=pt_ce,
|
||||
panel_style=PANEL_STYLE,
|
||||
)
|
||||
|
||||
@@ -682,6 +677,7 @@ class StarPilotLongitudinalLayout(_SettingsPage):
|
||||
],
|
||||
header_title=tr("Curve Speed Controller"),
|
||||
header_subtitle=tr("Configure speed control on curves and reset collected calibration data."),
|
||||
parent_toggle=pt_csc,
|
||||
panel_style=PANEL_STYLE,
|
||||
)
|
||||
|
||||
@@ -693,6 +689,7 @@ class StarPilotLongitudinalLayout(_SettingsPage):
|
||||
[SettingSection(title="", rows=self._tune_rows)],
|
||||
header_title=tr_noop("Longitudinal Tuning"),
|
||||
header_subtitle=tr_noop("Configure acceleration profiles, smooth following, lane changes, and route speed control."),
|
||||
parent_toggle=pt_tune,
|
||||
panel_style=PANEL_STYLE,
|
||||
)
|
||||
self._sub_panels["advanced"] = AetherSettingsView(
|
||||
@@ -700,6 +697,7 @@ class StarPilotLongitudinalLayout(_SettingsPage):
|
||||
[SettingSection(title="", rows=self._advanced_rows)],
|
||||
header_title=tr_noop("Advanced Actuators"),
|
||||
header_subtitle=tr_noop("Adjust actuator delay, EV/Truck tuning, and launch/stop speeds/rates."),
|
||||
parent_toggle=pt_advanced,
|
||||
panel_style=PANEL_STYLE,
|
||||
)
|
||||
self._sub_panels["slc"] = AetherSettingsView(
|
||||
@@ -707,6 +705,7 @@ class StarPilotLongitudinalLayout(_SettingsPage):
|
||||
[SettingSection(title="", rows=self._slc_rows)],
|
||||
header_title=tr_noop("Speed Limit Controller"),
|
||||
header_subtitle=tr_noop("Manage auto speed matching, confirmation, offsets, and source priority."),
|
||||
parent_toggle=pt_slc,
|
||||
panel_style=PANEL_STYLE,
|
||||
)
|
||||
self._sub_panels["personality"] = AetherSettingsView(
|
||||
@@ -714,6 +713,7 @@ class StarPilotLongitudinalLayout(_SettingsPage):
|
||||
[SettingSection(title="", rows=self._personality_rows)],
|
||||
header_title=tr_noop("Driving Personalities"),
|
||||
header_subtitle=tr_noop("Customize follow distance and jerk/response metrics for each personality profile."),
|
||||
parent_toggle=pt_personality,
|
||||
panel_style=PANEL_STYLE,
|
||||
)
|
||||
self._sub_panels["daily"] = AetherSettingsView(
|
||||
@@ -721,6 +721,7 @@ class StarPilotLongitudinalLayout(_SettingsPage):
|
||||
[SettingSection(title="", rows=self._daily_rows)],
|
||||
header_title=tr_noop("Daily QOL & Weather"),
|
||||
header_subtitle=tr_noop("Configure cruise intervals, standstill behaviors, gear mapping, and weather presets."),
|
||||
parent_toggle=pt_daily,
|
||||
panel_style=PANEL_STYLE,
|
||||
)
|
||||
self._wire_sub_panels()
|
||||
|
||||
Reference in New Issue
Block a user