BigUI WIP: Cleanup
This commit is contained in:
@@ -1,11 +1,11 @@
|
||||
from __future__ import annotations
|
||||
from openpilot.system.hardware import HARDWARE
|
||||
from openpilot.selfdrive.ui.lib.starpilot_state import starpilot_state
|
||||
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.system.ui.widgets.confirm_dialog import ConfirmDialog
|
||||
from openpilot.system.ui.widgets.selection_dialog import SelectionDialog
|
||||
from openpilot.selfdrive.ui.layouts.settings.starpilot.panel import StarPilotPanel, create_tile_panel
|
||||
from openpilot.selfdrive.ui.layouts.settings.starpilot.panel import StarPilotPanel, create_master_toggle_panel, create_tile_panel
|
||||
from openpilot.selfdrive.ui.layouts.settings.starpilot.tabbed_panel import TabSectionSpec, TabbedSectionHost
|
||||
from openpilot.selfdrive.ui.layouts.settings.starpilot.aethergrid import AetherSliderDialog
|
||||
|
||||
@@ -13,18 +13,93 @@ class StarPilotAdvancedLateralLayout(StarPilotPanel):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.CATEGORIES = [
|
||||
{"title": tr_noop("Advanced Lateral Tuning"), "type": "toggle", "get_state": lambda: self._params.get_bool("AdvancedLateralTune"), "set_state": lambda x: self._params.put_bool("AdvancedLateralTune", x), "icon": "toggle_icons/icon_advanced_lateral_tune.png", "color": "#597497"},
|
||||
{"title": tr_noop("Actuator Delay"), "type": "value", "get_value": lambda: f"{self._params.get_float('SteerDelay'):.2f}s", "on_click": lambda: self._show_float_selector("SteerDelay", 0.0, 0.5, 0.01, "s"), "icon": "toggle_icons/icon_advanced_lateral_tune.png", "color": "#597497"},
|
||||
{"title": tr_noop("Friction"), "type": "value", "get_value": lambda: f"{self._params.get_float('SteerFriction'):.3f}", "on_click": lambda: self._show_float_selector("SteerFriction", 0.0, 0.5, 0.005), "icon": "toggle_icons/icon_advanced_lateral_tune.png", "color": "#597497"},
|
||||
{"title": tr_noop("Kp Factor"), "type": "value", "get_value": lambda: f"{self._params.get_float('SteerKP'):.2f}", "on_click": lambda: self._show_float_selector("SteerKP", 0.5, 2.5, 0.01), "icon": "toggle_icons/icon_advanced_lateral_tune.png", "color": "#597497"},
|
||||
{"title": tr_noop("Lateral Accel"), "type": "value", "get_value": lambda: f"{self._params.get_float('SteerLatAccel'):.2f}", "on_click": lambda: self._show_float_selector("SteerLatAccel", 0.5, 5.0, 0.01), "icon": "toggle_icons/icon_advanced_lateral_tune.png", "color": "#597497"},
|
||||
{"title": tr_noop("Steer Ratio"), "type": "value", "get_value": lambda: f"{self._params.get_float('SteerRatio'):.2f}", "on_click": lambda: self._show_float_selector("SteerRatio", 5.0, 25.0, 0.01), "icon": "toggle_icons/icon_advanced_lateral_tune.png", "color": "#597497"},
|
||||
{"title": tr_noop("Force Auto-Tune On"), "type": "toggle", "get_state": lambda: self._params.get_bool("ForceAutoTune"), "set_state": lambda x: self._params.put_bool("ForceAutoTune", x), "icon": "toggle_icons/icon_tuning.png", "color": "#597497", "visible": lambda: self._params.get_bool("AdvancedLateralTune")},
|
||||
{"title": tr_noop("Force Auto-Tune Off"), "type": "toggle", "get_state": lambda: self._params.get_bool("ForceAutoTuneOff"), "set_state": lambda x: self._params.put_bool("ForceAutoTuneOff", x), "icon": "toggle_icons/icon_tuning.png", "color": "#597497", "visible": lambda: self._params.get_bool("AdvancedLateralTune")},
|
||||
{"title": tr_noop("Force Torque Controller"), "type": "toggle", "get_state": lambda: self._params.get_bool("ForceTorqueController"), "set_state": lambda x: self._on_reboot_toggle("ForceTorqueController", x), "icon": "toggle_icons/icon_advanced_lateral_tune.png", "color": "#597497", "visible": lambda: self._params.get_bool("AdvancedLateralTune")},
|
||||
{"title": tr_noop("Actuator Delay"), "desc": tr_noop("The time between openpilot's steering command and the vehicle's response."), "type": "value", "get_value": lambda: f"{self._params.get_float('SteerDelay'):.2f}s", "on_click": lambda: self._show_float_selector("SteerDelay", 0.01, 1.0, 0.01, "s"), "icon": "toggle_icons/icon_advanced_lateral_tune.png", "color": "#597497", "visible": self._show_steer_delay},
|
||||
{"title": tr_noop("Friction"), "desc": tr_noop("Compensates for steering friction around center."), "type": "value", "get_value": lambda: f"{self._params.get_float('SteerFriction'):.3f}", "on_click": self._show_steer_friction_selector, "icon": "toggle_icons/icon_advanced_lateral_tune.png", "color": "#597497", "visible": self._show_steer_friction},
|
||||
{"title": tr_noop("Kp Factor"), "desc": tr_noop("How strongly openpilot corrects lateral position."), "type": "value", "get_value": lambda: f"{self._params.get_float('SteerKP'):.2f}", "on_click": self._show_steer_kp_selector, "icon": "toggle_icons/icon_advanced_lateral_tune.png", "color": "#597497", "visible": self._show_steer_kp},
|
||||
{"title": tr_noop("Lateral Acceleration"), "desc": tr_noop("Maps steering torque to turning response."), "type": "value", "get_value": lambda: f"{self._params.get_float('SteerLatAccel'):.2f}", "on_click": self._show_steer_lat_accel_selector, "icon": "toggle_icons/icon_advanced_lateral_tune.png", "color": "#597497", "visible": self._show_steer_lat_accel},
|
||||
{"title": tr_noop("Steer Ratio"), "desc": tr_noop("Adjust the relationship between steering wheel input and road-wheel angle."), "type": "value", "get_value": lambda: f"{self._params.get_float('SteerRatio'):.2f}", "on_click": self._show_steer_ratio_selector, "icon": "toggle_icons/icon_advanced_lateral_tune.png", "color": "#597497", "visible": self._show_steer_ratio},
|
||||
{"title": tr_noop("Force Auto-Tune On"), "desc": tr_noop("Force-enable live auto-tuning for friction and lateral acceleration."), "type": "toggle", "get_state": lambda: self._params.get_bool("ForceAutoTune"), "set_state": self._set_force_auto_tune, "icon": "toggle_icons/icon_tuning.png", "color": "#597497", "visible": self._show_force_auto_tune},
|
||||
{"title": tr_noop("Force Auto-Tune Off"), "desc": tr_noop("Force-disable live auto-tuning and use your set values instead."), "type": "toggle", "get_state": lambda: self._params.get_bool("ForceAutoTuneOff"), "set_state": self._set_force_auto_tune_off, "icon": "toggle_icons/icon_tuning.png", "color": "#597497", "visible": self._show_force_auto_tune_off},
|
||||
{"title": tr_noop("Force Torque Controller"), "desc": tr_noop("Use torque-based steering control instead of the stock steering mode when supported."), "type": "toggle", "get_state": lambda: self._params.get_bool("ForceTorqueController"), "set_state": lambda x: self._on_reboot_toggle("ForceTorqueController", x), "icon": "toggle_icons/icon_advanced_lateral_tune.png", "color": "#597497", "visible": self._show_force_torque_controller},
|
||||
]
|
||||
self._rebuild_grid()
|
||||
|
||||
def _advanced_enabled(self):
|
||||
return self._params.get_bool("AdvancedLateralTune")
|
||||
|
||||
def _using_nnff(self):
|
||||
return starpilot_state.car_state.hasNNFFLog and self._params.get_bool("LateralTune") and self._params.get_bool("NNFF")
|
||||
|
||||
def _forcing_auto_tune(self):
|
||||
return not starpilot_state.car_state.hasAutoTune and self._params.get_bool("ForceAutoTune")
|
||||
|
||||
def _forcing_auto_tune_off(self):
|
||||
return starpilot_state.car_state.hasAutoTune and self._params.get_bool("ForceAutoTuneOff")
|
||||
|
||||
def _forcing_torque_controller(self):
|
||||
return not starpilot_state.car_state.isAngleCar and self._params.get_bool("ForceTorqueController")
|
||||
|
||||
def _torque_tuning_active(self):
|
||||
return starpilot_state.car_state.isTorqueCar or self._forcing_torque_controller() or self._using_nnff()
|
||||
|
||||
def _manual_tuning_values_enabled(self):
|
||||
if starpilot_state.car_state.hasAutoTune:
|
||||
return self._forcing_auto_tune_off()
|
||||
return not self._forcing_auto_tune()
|
||||
|
||||
def _show_steer_delay(self):
|
||||
return self._advanced_enabled() and starpilot_state.car_state.steerActuatorDelay != 0
|
||||
|
||||
def _show_steer_friction(self):
|
||||
return (self._advanced_enabled() and starpilot_state.car_state.friction != 0 and self._torque_tuning_active()
|
||||
and not self._using_nnff() and self._manual_tuning_values_enabled())
|
||||
|
||||
def _show_steer_kp(self):
|
||||
return (self._advanced_enabled() and starpilot_state.car_state.steerKp != 0 and self._torque_tuning_active()
|
||||
and not starpilot_state.car_state.isAngleCar)
|
||||
|
||||
def _show_steer_lat_accel(self):
|
||||
return (self._advanced_enabled() and starpilot_state.car_state.latAccelFactor != 0 and self._torque_tuning_active()
|
||||
and not self._using_nnff() and self._manual_tuning_values_enabled())
|
||||
|
||||
def _show_steer_ratio(self):
|
||||
return self._advanced_enabled() and starpilot_state.car_state.steerRatio != 0 and self._manual_tuning_values_enabled()
|
||||
|
||||
def _show_force_auto_tune(self):
|
||||
return (self._advanced_enabled() and not starpilot_state.car_state.hasAutoTune and not starpilot_state.car_state.isAngleCar
|
||||
and self._torque_tuning_active())
|
||||
|
||||
def _show_force_auto_tune_off(self):
|
||||
return self._advanced_enabled() and starpilot_state.car_state.hasAutoTune and not starpilot_state.car_state.isAngleCar
|
||||
|
||||
def _show_force_torque_controller(self):
|
||||
return self._advanced_enabled() and not starpilot_state.car_state.isAngleCar and not starpilot_state.car_state.isTorqueCar
|
||||
|
||||
def _set_force_auto_tune(self, state):
|
||||
self._params.put_bool("ForceAutoTune", state)
|
||||
if state:
|
||||
self._params.put_bool("ForceAutoTuneOff", False)
|
||||
|
||||
def _set_force_auto_tune_off(self, state):
|
||||
self._params.put_bool("ForceAutoTuneOff", state)
|
||||
if state:
|
||||
self._params.put_bool("ForceAutoTune", False)
|
||||
|
||||
def _show_steer_friction_selector(self):
|
||||
self._show_float_selector("SteerFriction", 0.0, max(1.0, starpilot_state.car_state.friction * 1.5), 0.01)
|
||||
|
||||
def _show_steer_kp_selector(self):
|
||||
base = max(0.01, starpilot_state.car_state.steerKp)
|
||||
self._show_float_selector("SteerKP", base * 0.5, base * 1.5, 0.01)
|
||||
|
||||
def _show_steer_lat_accel_selector(self):
|
||||
base = max(0.01, starpilot_state.car_state.latAccelFactor)
|
||||
self._show_float_selector("SteerLatAccel", base * 0.5, base * 1.5, 0.01)
|
||||
|
||||
def _show_steer_ratio_selector(self):
|
||||
base = max(0.01, starpilot_state.car_state.steerRatio)
|
||||
self._show_float_selector("SteerRatio", base * 0.5, base * 1.5, 0.01)
|
||||
|
||||
def _show_float_selector(self, key, min_v, max_v, step, unit=""):
|
||||
def on_close(res, val):
|
||||
if res == DialogResult.CONFIRM:
|
||||
@@ -68,9 +143,9 @@ class StarPilotLaneChangesLayout(StarPilotPanel):
|
||||
self.CATEGORIES = [
|
||||
{"title": tr_noop("Lane Changes"), "type": "toggle", "get_state": lambda: self._params.get_bool("LaneChanges"), "set_state": lambda s: self._params.put_bool("LaneChanges", s), "icon": "toggle_icons/icon_lane.png", "color": "#597497"},
|
||||
{"title": tr_noop("Automatic Lane Changes"), "type": "toggle", "get_state": lambda: self._params.get_bool("NudgelessLaneChange"), "set_state": lambda s: self._params.put_bool("NudgelessLaneChange", s), "icon": "toggle_icons/icon_lane.png", "color": "#597497", "visible": lambda: self._params.get_bool("LaneChanges")},
|
||||
{"title": tr_noop("Lane Change Delay"), "type": "value", "get_value": lambda: f"{self._params.get_float('LaneChangeTime'):.1f}s", "on_click": lambda: self._show_float_selector("LaneChangeTime", 0.0, 5.0, 0.1, "s"), "icon": "toggle_icons/icon_lane.png", "color": "#597497", "visible": lambda: self._params.get_bool("LaneChanges")},
|
||||
{"title": tr_noop("Lane Change Delay"), "type": "value", "get_value": lambda: f"{self._params.get_float('LaneChangeTime'):.1f}s", "on_click": lambda: self._show_float_selector("LaneChangeTime", 0.0, 5.0, 0.1, "s"), "icon": "toggle_icons/icon_lane.png", "color": "#597497", "visible": lambda: self._params.get_bool("LaneChanges") and self._params.get_bool("NudgelessLaneChange")},
|
||||
{"title": tr_noop("Min Lane Change Speed"), "type": "value", "get_value": lambda: f"{self._params.get_int('MinimumLaneChangeSpeed')} mph", "on_click": lambda: self._show_speed_selector("MinimumLaneChangeSpeed"), "icon": "toggle_icons/icon_lane.png", "color": "#597497", "visible": lambda: self._params.get_bool("LaneChanges")},
|
||||
{"title": tr_noop("Minimum Lane Width"), "type": "value", "get_value": lambda: f"{self._params.get_float('LaneDetectionWidth'):.1f} ft", "on_click": lambda: self._show_float_selector("LaneDetectionWidth", 0.0, 15.0, 0.1, " ft"), "icon": "toggle_icons/icon_lane.png", "color": "#597497", "visible": lambda: self._params.get_bool("LaneChanges")},
|
||||
{"title": tr_noop("Minimum Lane Width"), "type": "value", "get_value": lambda: f"{self._params.get_float('LaneDetectionWidth'):.1f} ft", "on_click": lambda: self._show_float_selector("LaneDetectionWidth", 0.0, 15.0, 0.1, " ft"), "icon": "toggle_icons/icon_lane.png", "color": "#597497", "visible": lambda: self._params.get_bool("LaneChanges") and self._params.get_bool("NudgelessLaneChange")},
|
||||
{"title": tr_noop("One Lane Change Per Signal"), "type": "toggle", "get_state": lambda: self._params.get_bool("OneLaneChange"), "set_state": lambda s: self._params.put_bool("OneLaneChange", s), "icon": "toggle_icons/icon_lane.png", "color": "#597497", "visible": lambda: self._params.get_bool("LaneChanges")},
|
||||
]
|
||||
self._rebuild_grid()
|
||||
@@ -93,13 +168,26 @@ class StarPilotLateralTuneLayout(StarPilotPanel):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.CATEGORIES = [
|
||||
{"title": tr_noop("Lateral Tuning"), "type": "toggle", "get_state": lambda: self._params.get_bool("LateralTune"), "set_state": lambda x: self._params.put_bool("LateralTune", x), "icon": "toggle_icons/icon_lateral_tune.png", "color": "#597497"},
|
||||
{"title": tr_noop("Force Turn Desires"), "type": "toggle", "get_state": lambda: self._params.get_bool("TurnDesires"), "set_state": lambda x: self._params.put_bool("TurnDesires", x), "icon": "toggle_icons/icon_lateral_tune.png", "color": "#597497", "visible": lambda: self._params.get_bool("LateralTune")},
|
||||
{"title": tr_noop("NNFF"), "type": "toggle", "get_state": lambda: self._params.get_bool("NNFF"), "set_state": lambda x: self._on_reboot_toggle("NNFF", x), "icon": "toggle_icons/icon_lateral_tune.png", "color": "#597497", "visible": lambda: self._params.get_bool("LateralTune")},
|
||||
{"title": tr_noop("NNFF Lite"), "type": "toggle", "get_state": lambda: self._params.get_bool("NNFFLite"), "set_state": lambda x: self._on_reboot_toggle("NNFFLite", x), "icon": "toggle_icons/icon_lateral_tune.png", "color": "#597497", "visible": lambda: self._params.get_bool("LateralTune")},
|
||||
{"title": tr_noop("Force Turn Desires Below Lane Change Speed"), "desc": tr_noop("Allow openpilot to follow turn intent below the minimum lane change speed when signaling."), "type": "toggle", "get_state": lambda: self._params.get_bool("TurnDesires"), "set_state": lambda x: self._params.put_bool("TurnDesires", x), "icon": "toggle_icons/icon_lateral_tune.png", "color": "#597497", "visible": self._lateral_enabled},
|
||||
{"title": tr_noop("Neural Network Feedforward (NNFF)"), "desc": tr_noop("Use the full neural-network feedforward steering controller when available."), "type": "toggle", "get_state": lambda: self._params.get_bool("NNFF"), "set_state": self._set_nnff, "icon": "toggle_icons/icon_lateral_tune.png", "color": "#597497", "visible": self._show_nnff},
|
||||
{"title": tr_noop("Neural Network Feedforward (NNFF) Lite"), "desc": tr_noop("Use the lightweight NNFF steering logic when the full model is off."), "type": "toggle", "get_state": lambda: self._params.get_bool("NNFFLite"), "set_state": lambda x: self._on_reboot_toggle("NNFFLite", x), "icon": "toggle_icons/icon_lateral_tune.png", "color": "#597497", "visible": self._show_nnff_lite},
|
||||
]
|
||||
self._rebuild_grid()
|
||||
|
||||
def _lateral_enabled(self):
|
||||
return self._params.get_bool("LateralTune")
|
||||
|
||||
def _show_nnff(self):
|
||||
return self._lateral_enabled() and starpilot_state.car_state.hasNNFFLog and not starpilot_state.car_state.isAngleCar
|
||||
|
||||
def _show_nnff_lite(self):
|
||||
return self._lateral_enabled() and not self._params.get_bool("NNFF") and not starpilot_state.car_state.isAngleCar
|
||||
|
||||
def _set_nnff(self, state):
|
||||
self._params.put_bool("NNFF", state)
|
||||
if state:
|
||||
self._params.put_bool("NNFFLite", False)
|
||||
|
||||
def _on_reboot_toggle(self, key, state):
|
||||
self._params.put_bool(key, state)
|
||||
from openpilot.selfdrive.ui.ui_state import ui_state
|
||||
@@ -132,9 +220,33 @@ class StarPilotLateralLayout(StarPilotPanel):
|
||||
"always_on_lateral": StarPilotAlwaysOnLateralLayout(),
|
||||
"qol": StarPilotLateralQOLLayout(),
|
||||
})
|
||||
tune_panel = create_tile_panel([
|
||||
{"title": tr_noop("Advanced Tuning"), "panel": "advanced_lateral", "icon": "toggle_icons/icon_advanced_lateral_tune.png", "color": "#597497"},
|
||||
{"title": tr_noop("Lateral Tuning"), "panel": "lateral_tune", "icon": "toggle_icons/icon_lateral_tune.png", "color": "#597497"},
|
||||
tune_panel = create_master_toggle_panel([
|
||||
{
|
||||
"title": tr_noop("Advanced Lateral Tuning"),
|
||||
"desc": tr_noop("Advanced steering control changes to fine-tune how openpilot drives."),
|
||||
"manage_title": tr_noop("Advanced Settings"),
|
||||
"manage_desc": tr_noop("Adjust steering response, torque controller behavior, and auto-tuning controls."),
|
||||
"manage_label": tr_noop("Configure"),
|
||||
"disabled_label": tr_noop("Enable First"),
|
||||
"panel": "advanced_lateral",
|
||||
"get_state": lambda: self._params.get_bool("AdvancedLateralTune"),
|
||||
"set_state": lambda x: self._params.put_bool("AdvancedLateralTune", x),
|
||||
"icon": "toggle_icons/icon_advanced_lateral_tune.png",
|
||||
"color": "#597497",
|
||||
},
|
||||
{
|
||||
"title": tr_noop("Lateral Tuning"),
|
||||
"desc": tr_noop("Miscellaneous steering control changes such as turn desires and NNFF modes."),
|
||||
"manage_title": tr_noop("Lateral Settings"),
|
||||
"manage_desc": tr_noop("Open turn-intent and neural-network feedforward controls."),
|
||||
"manage_label": tr_noop("Configure"),
|
||||
"disabled_label": tr_noop("Enable First"),
|
||||
"panel": "lateral_tune",
|
||||
"get_state": lambda: self._params.get_bool("LateralTune"),
|
||||
"set_state": lambda x: self._params.put_bool("LateralTune", x),
|
||||
"icon": "toggle_icons/icon_lateral_tune.png",
|
||||
"color": "#597497",
|
||||
},
|
||||
], {
|
||||
"advanced_lateral": StarPilotAdvancedLateralLayout(),
|
||||
"lateral_tune": StarPilotLateralTuneLayout(),
|
||||
|
||||
@@ -6,27 +6,80 @@ from openpilot.system.ui.widgets import DialogResult
|
||||
from openpilot.system.ui.widgets.confirm_dialog import ConfirmDialog
|
||||
from openpilot.system.ui.widgets.selection_dialog import SelectionDialog
|
||||
from openpilot.system.ui.widgets.input_dialog import InputDialog
|
||||
from openpilot.selfdrive.ui.layouts.settings.starpilot.panel import StarPilotPanel, create_tile_panel
|
||||
from openpilot.selfdrive.ui.layouts.settings.starpilot.panel import StarPilotPanel, create_master_toggle_panel, create_tile_panel
|
||||
from openpilot.selfdrive.ui.layouts.settings.starpilot.tabbed_panel import TabSectionSpec, TabbedSectionHost
|
||||
from openpilot.selfdrive.ui.layouts.settings.starpilot.aethergrid import AetherSliderDialog
|
||||
from openpilot.starpilot.common.accel_profile import (
|
||||
ACCELERATION_PROFILES,
|
||||
DECELERATION_PROFILES,
|
||||
normalize_acceleration_profile,
|
||||
normalize_deceleration_profile,
|
||||
)
|
||||
|
||||
|
||||
ACCELERATION_PROFILE_OPTIONS = [
|
||||
(ACCELERATION_PROFILES["STANDARD"], "Standard"),
|
||||
(ACCELERATION_PROFILES["ECO"], "Eco"),
|
||||
(ACCELERATION_PROFILES["SPORT"], "Sport"),
|
||||
(ACCELERATION_PROFILES["SPORT_PLUS"], "Sport+"),
|
||||
]
|
||||
|
||||
DECELERATION_PROFILE_OPTIONS = [
|
||||
(DECELERATION_PROFILES["STANDARD"], "Standard"),
|
||||
(DECELERATION_PROFILES["ECO"], "Eco"),
|
||||
(DECELERATION_PROFILES["SPORT"], "Sport"),
|
||||
]
|
||||
|
||||
|
||||
class StarPilotLongitudinalLayout(StarPilotPanel):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
tune_panel = create_tile_panel([
|
||||
{"title": tr_noop("Longitudinal Tuning"), "panel": "tuning", "icon": "toggle_icons/icon_longitudinal_tune.png", "color": "#597497"},
|
||||
{"title": tr_noop("Advanced Tuning"), "panel": "advanced", "icon": "toggle_icons/icon_advanced_longitudinal_tune.png", "color": "#597497"},
|
||||
{"title": tr_noop("Driving Personalities"), "panel": "personalities", "icon": "toggle_icons/icon_personality.png", "color": "#597497"},
|
||||
longitudinal_tune_panel = StarPilotLongitudinalTuneLayout()
|
||||
advanced_longitudinal_panel = StarPilotAdvancedLongitudinalLayout()
|
||||
tune_panel = create_master_toggle_panel([
|
||||
{
|
||||
"title": tr_noop("Longitudinal Tuning"),
|
||||
"desc": tr_noop("Acceleration and braking control changes to fine-tune how openpilot drives."),
|
||||
"manage_title": tr_noop("Longitudinal Settings"),
|
||||
"manage_desc": tr_noop("Open acceleration profiles, human-like behavior, lead detection, and turn-speed controls."),
|
||||
"manage_label": tr_noop("Configure"),
|
||||
"disabled_label": tr_noop("Enable First"),
|
||||
"panel": "tuning",
|
||||
"get_state": lambda: self._params.get_bool("LongitudinalTune"),
|
||||
"set_state": lambda s: self._params.put_bool("LongitudinalTune", s),
|
||||
"icon": "toggle_icons/icon_longitudinal_tune.png",
|
||||
"color": "#597497",
|
||||
},
|
||||
{
|
||||
"title": tr_noop("Advanced Longitudinal Tuning"),
|
||||
"desc": tr_noop("Advanced acceleration and braking changes for refining launch, stopping, and actuator response."),
|
||||
"manage_title": tr_noop("Advanced Settings"),
|
||||
"manage_desc": tr_noop("Adjust actuator delay, launch and stop behavior, and powertrain-specific tuning options."),
|
||||
"manage_label": tr_noop("Configure"),
|
||||
"disabled_label": tr_noop("Enable First"),
|
||||
"panel": "advanced",
|
||||
"get_state": lambda: self._params.get_bool("AdvancedLongitudinalTune"),
|
||||
"set_state": lambda s: self._params.put_bool("AdvancedLongitudinalTune", s),
|
||||
"icon": "toggle_icons/icon_advanced_longitudinal_tune.png",
|
||||
"color": "#597497",
|
||||
},
|
||||
], {
|
||||
"tuning": StarPilotLongitudinalTuneLayout(),
|
||||
"advanced": StarPilotAdvancedLongitudinalLayout(),
|
||||
"tuning": longitudinal_tune_panel,
|
||||
"advanced": advanced_longitudinal_panel,
|
||||
"personalities": StarPilotPersonalitiesLayout(),
|
||||
"traffic_personality": StarPilotPersonalityProfileLayout("Traffic"),
|
||||
"aggressive_personality": StarPilotPersonalityProfileLayout("Aggressive"),
|
||||
"standard_personality": StarPilotPersonalityProfileLayout("Standard"),
|
||||
"relaxed_personality": StarPilotPersonalityProfileLayout("Relaxed"),
|
||||
})
|
||||
}, extra_categories=[
|
||||
{
|
||||
"title": tr_noop("Driving Personalities"),
|
||||
"desc": tr_noop("Customize the Traffic, Aggressive, Standard, and Relaxed profiles to match your driving style."),
|
||||
"panel": "personalities",
|
||||
"icon": "toggle_icons/icon_personality.png",
|
||||
"color": "#597497",
|
||||
},
|
||||
])
|
||||
|
||||
adaptive_panel = create_tile_panel([
|
||||
{"title": tr_noop("Conditional Experimental"), "panel": "conditional", "icon": "toggle_icons/icon_conditional.png", "color": "#597497"},
|
||||
@@ -73,89 +126,113 @@ class StarPilotAdvancedLongitudinalLayout(StarPilotPanel):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.CATEGORIES = [
|
||||
{
|
||||
"title": tr_noop("Advanced Longitudinal Tuning"),
|
||||
"type": "toggle",
|
||||
"get_state": lambda: self._params.get_bool("AdvancedLongitudinalTune"),
|
||||
"set_state": lambda s: self._params.put_bool("AdvancedLongitudinalTune", s),
|
||||
"icon": "toggle_icons/icon_advanced_longitudinal_tune.png",
|
||||
"color": "#597497",
|
||||
},
|
||||
{
|
||||
"title": tr_noop("EV Tuning"),
|
||||
"desc": tr_noop("Use acceleration tuning intended for EV and direct-drive vehicles."),
|
||||
"type": "toggle",
|
||||
"get_state": lambda: self._params.get_bool("EVTuning"),
|
||||
"set_state": lambda s: self._params.put_bool("EVTuning", s),
|
||||
"set_state": self._set_ev_tuning,
|
||||
"color": "#597497",
|
||||
"visible": lambda: self._params.get_bool("AdvancedLongitudinalTune"),
|
||||
"is_enabled": lambda: not self._params.get_bool("TruckTuning"),
|
||||
"disabled_label": tr_noop("Truck Active"),
|
||||
"visible": self._advanced_enabled,
|
||||
},
|
||||
{
|
||||
"title": tr_noop("Truck Tuning"),
|
||||
"desc": tr_noop("Use stronger launch and acceleration behavior intended for heavier vehicles."),
|
||||
"type": "toggle",
|
||||
"get_state": lambda: self._params.get_bool("TruckTuning"),
|
||||
"set_state": lambda s: self._params.put_bool("TruckTuning", s),
|
||||
"set_state": self._set_truck_tuning,
|
||||
"color": "#597497",
|
||||
"visible": lambda: self._params.get_bool("AdvancedLongitudinalTune"),
|
||||
"is_enabled": lambda: not self._params.get_bool("EVTuning"),
|
||||
"disabled_label": tr_noop("EV Active"),
|
||||
"visible": self._advanced_enabled,
|
||||
},
|
||||
{
|
||||
"title": tr_noop("Actuator Delay"),
|
||||
"desc": tr_noop("The time between an acceleration or brake command and the vehicle's response."),
|
||||
"type": "value",
|
||||
"get_value": lambda: f"{self._params.get_float('LongitudinalActuatorDelay'):.2f}s",
|
||||
"on_click": lambda: self._show_float_selector("LongitudinalActuatorDelay", 0.0, 1.0, 0.01, "s"),
|
||||
"color": "#597497",
|
||||
"visible": lambda: self._params.get_bool("AdvancedLongitudinalTune"),
|
||||
"visible": self._advanced_enabled,
|
||||
},
|
||||
{
|
||||
"title": tr_noop("Max Acceleration"),
|
||||
"title": tr_noop("Maximum Acceleration"),
|
||||
"desc": tr_noop("Limit the strongest acceleration openpilot is allowed to command."),
|
||||
"type": "value",
|
||||
"get_value": lambda: f"{self._params.get_float('MaxDesiredAcceleration'):.1f}m/s²",
|
||||
"on_click": lambda: self._show_float_selector("MaxDesiredAcceleration", 0.1, 4.0, 0.1, "m/s²"),
|
||||
"color": "#597497",
|
||||
"visible": lambda: self._params.get_bool("AdvancedLongitudinalTune"),
|
||||
"visible": self._advanced_enabled,
|
||||
},
|
||||
{
|
||||
"title": tr_noop("Start Accel"),
|
||||
"title": tr_noop("Start Acceleration"),
|
||||
"desc": tr_noop("Extra acceleration applied when moving away from a stop."),
|
||||
"type": "value",
|
||||
"get_value": lambda: f"{self._params.get_float('StartAccel'):.2f}m/s²",
|
||||
"on_click": lambda: self._show_float_selector("StartAccel", 0.0, 4.0, 0.01, "m/s²"),
|
||||
"color": "#597497",
|
||||
"visible": lambda: self._params.get_bool("AdvancedLongitudinalTune"),
|
||||
"visible": lambda: self._advanced_enabled() and not self._using_human_acceleration(),
|
||||
},
|
||||
{
|
||||
"title": tr_noop("Stop Accel"),
|
||||
"title": tr_noop("Stop Acceleration"),
|
||||
"desc": tr_noop("Brake force used to hold the vehicle at a complete stop."),
|
||||
"type": "value",
|
||||
"get_value": lambda: f"{self._params.get_float('StopAccel'):.2f}m/s²",
|
||||
"on_click": lambda: self._show_float_selector("StopAccel", -4.0, 0.0, 0.01, "m/s²"),
|
||||
"color": "#597497",
|
||||
"visible": lambda: self._params.get_bool("AdvancedLongitudinalTune"),
|
||||
"visible": self._advanced_enabled,
|
||||
},
|
||||
{
|
||||
"title": tr_noop("Stopping Rate"),
|
||||
"desc": tr_noop("How quickly braking ramps up when openpilot is bringing the car to a stop."),
|
||||
"type": "value",
|
||||
"get_value": lambda: f"{self._params.get_float('StoppingDecelRate'):.3f}m/s²",
|
||||
"on_click": lambda: self._show_float_selector("StoppingDecelRate", 0.001, 1.0, 0.001, "m/s²"),
|
||||
"color": "#597497",
|
||||
"visible": lambda: self._params.get_bool("AdvancedLongitudinalTune"),
|
||||
"visible": self._show_stop_tuning_values,
|
||||
},
|
||||
{
|
||||
"title": tr_noop("VEgo Starting"),
|
||||
"title": tr_noop("Start Speed"),
|
||||
"desc": tr_noop("The speed where openpilot transitions out of the stopped state."),
|
||||
"type": "value",
|
||||
"get_value": lambda: f"{self._params.get_float('VEgoStarting'):.2f}m/s",
|
||||
"on_click": lambda: self._show_float_selector("VEgoStarting", 0.01, 1.0, 0.01, "m/s"),
|
||||
"color": "#597497",
|
||||
"visible": lambda: self._params.get_bool("AdvancedLongitudinalTune"),
|
||||
"visible": self._show_stop_tuning_values,
|
||||
},
|
||||
{
|
||||
"title": tr_noop("VEgo Stopping"),
|
||||
"title": tr_noop("Stop Speed"),
|
||||
"desc": tr_noop("The speed where openpilot considers the vehicle fully stopped."),
|
||||
"type": "value",
|
||||
"get_value": lambda: f"{self._params.get_float('VEgoStopping'):.2f}m/s",
|
||||
"on_click": lambda: self._show_float_selector("VEgoStopping", 0.01, 1.0, 0.01, "m/s"),
|
||||
"color": "#597497",
|
||||
"visible": lambda: self._params.get_bool("AdvancedLongitudinalTune"),
|
||||
"visible": self._show_stop_tuning_values,
|
||||
},
|
||||
]
|
||||
self._rebuild_grid()
|
||||
|
||||
def _advanced_enabled(self):
|
||||
return self._params.get_bool("AdvancedLongitudinalTune")
|
||||
|
||||
def _using_human_acceleration(self):
|
||||
return self._params.get_bool("LongitudinalTune") and self._params.get_bool("HumanAcceleration")
|
||||
|
||||
def _show_stop_tuning_values(self):
|
||||
return self._advanced_enabled() and not (starpilot_state.car_state.isToyota and self._params.get_bool("FrogsGoMoosTweak"))
|
||||
|
||||
def _set_ev_tuning(self, state: bool):
|
||||
self._params.put_bool("EVTuning", state)
|
||||
if state:
|
||||
self._params.put_bool("TruckTuning", False)
|
||||
|
||||
def _set_truck_tuning(self, state: bool):
|
||||
self._params.put_bool("TruckTuning", state)
|
||||
if state:
|
||||
self._params.put_bool("EVTuning", False)
|
||||
|
||||
def _show_float_selector(self, key, min_v, max_v, step, unit=""):
|
||||
def on_close(res, val):
|
||||
if res == DialogResult.CONFIRM:
|
||||
@@ -470,80 +547,106 @@ class StarPilotLongitudinalTuneLayout(StarPilotPanel):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.CATEGORIES = [
|
||||
{
|
||||
"title": tr_noop("Longitudinal Tuning"),
|
||||
"type": "toggle",
|
||||
"get_state": lambda: self._params.get_bool("LongitudinalTune"),
|
||||
"set_state": lambda s: self._params.put_bool("LongitudinalTune", s),
|
||||
"icon": "toggle_icons/icon_longitudinal_tune.png",
|
||||
"color": "#597497",
|
||||
},
|
||||
{
|
||||
"title": tr_noop("Acceleration Profile"),
|
||||
"desc": tr_noop("Choose how quickly openpilot speeds up."),
|
||||
"type": "value",
|
||||
"get_value": lambda: self._params.get("AccelerationProfile", encoding='utf-8') or "Standard",
|
||||
"on_click": lambda: self._show_selection("AccelerationProfile", ["Standard", "Eco", "Sport", "Sport+"]),
|
||||
"get_value": self._get_acceleration_profile_label,
|
||||
"on_click": self._show_acceleration_profile_selector,
|
||||
"color": "#597497",
|
||||
"visible": lambda: self._params.get_bool("LongitudinalTune"),
|
||||
"visible": self._longitudinal_enabled,
|
||||
},
|
||||
{
|
||||
"title": tr_noop("Deceleration Profile"),
|
||||
"desc": tr_noop("Choose how firmly openpilot slows the car down."),
|
||||
"type": "value",
|
||||
"get_value": lambda: self._params.get("DecelerationProfile", encoding='utf-8') or "Standard",
|
||||
"on_click": lambda: self._show_selection("DecelerationProfile", ["Standard", "Eco", "Sport"]),
|
||||
"get_value": self._get_deceleration_profile_label,
|
||||
"on_click": self._show_deceleration_profile_selector,
|
||||
"color": "#597497",
|
||||
"visible": lambda: self._params.get_bool("LongitudinalTune"),
|
||||
"visible": self._longitudinal_enabled,
|
||||
},
|
||||
{
|
||||
"title": tr_noop("Human Acceleration"),
|
||||
"title": tr_noop("Human-Like Acceleration"),
|
||||
"desc": tr_noop("Smooth throttle behavior at low speed with stronger takeoff from a stop."),
|
||||
"type": "toggle",
|
||||
"get_state": lambda: self._params.get_bool("HumanAcceleration"),
|
||||
"set_state": lambda s: self._params.put_bool("HumanAcceleration", s),
|
||||
"color": "#597497",
|
||||
"visible": lambda: self._params.get_bool("LongitudinalTune"),
|
||||
"visible": self._longitudinal_enabled,
|
||||
},
|
||||
{
|
||||
"title": tr_noop("Human Following"),
|
||||
"title": tr_noop("Human-Like Following"),
|
||||
"desc": tr_noop("Adjust following behavior to feel more natural behind other vehicles."),
|
||||
"type": "toggle",
|
||||
"get_state": lambda: self._params.get_bool("HumanFollowing"),
|
||||
"set_state": lambda s: self._params.put_bool("HumanFollowing", s),
|
||||
"color": "#597497",
|
||||
"visible": lambda: self._params.get_bool("LongitudinalTune"),
|
||||
"visible": self._longitudinal_enabled,
|
||||
},
|
||||
{
|
||||
"title": tr_noop("Human Lane Changes"),
|
||||
"title": tr_noop("Human-Like Lane Changes"),
|
||||
"desc": tr_noop("Use radar-informed behavior during lane changes when radar support is available."),
|
||||
"type": "toggle",
|
||||
"get_state": lambda: self._params.get_bool("HumanLaneChanges"),
|
||||
"set_state": lambda s: self._params.put_bool("HumanLaneChanges", s),
|
||||
"color": "#597497",
|
||||
"visible": lambda: self._params.get_bool("LongitudinalTune"),
|
||||
"visible": lambda: self._longitudinal_enabled() and starpilot_state.car_state.hasRadar,
|
||||
},
|
||||
{
|
||||
"title": tr_noop("Lead Detection"),
|
||||
"title": tr_noop("Lead Detection Sensitivity"),
|
||||
"desc": tr_noop("Control how aggressively openpilot detects and reacts to vehicles ahead."),
|
||||
"type": "value",
|
||||
"get_value": lambda: f"{self._params.get_int('LeadDetectionThreshold')}%",
|
||||
"on_click": lambda: self._show_int_selector("LeadDetectionThreshold", 25, 50, "%"),
|
||||
"color": "#597497",
|
||||
"visible": lambda: self._params.get_bool("LongitudinalTune"),
|
||||
"visible": self._longitudinal_enabled,
|
||||
},
|
||||
{
|
||||
"title": tr_noop("Taco Tune"),
|
||||
"title": tr_noop("\"Taco Bell Run\" Turn Speed Hack"),
|
||||
"desc": tr_noop("Slow down more assertively for turns."),
|
||||
"type": "toggle",
|
||||
"get_state": lambda: self._params.get_bool("TacoTune"),
|
||||
"set_state": lambda s: self._params.put_bool("TacoTune", s),
|
||||
"color": "#597497",
|
||||
"visible": lambda: self._params.get_bool("LongitudinalTune"),
|
||||
"visible": self._longitudinal_enabled,
|
||||
},
|
||||
]
|
||||
self._rebuild_grid()
|
||||
|
||||
def _show_selection(self, key, options):
|
||||
def _longitudinal_enabled(self):
|
||||
return self._params.get_bool("LongitudinalTune")
|
||||
|
||||
def _get_acceleration_profile_label(self):
|
||||
value = normalize_acceleration_profile(self._params.get("AccelerationProfile", encoding='utf-8'))
|
||||
return self._profile_label_for_value(value, ACCELERATION_PROFILE_OPTIONS)
|
||||
|
||||
def _get_deceleration_profile_label(self):
|
||||
value = normalize_deceleration_profile(self._params.get("DecelerationProfile", encoding='utf-8'))
|
||||
return self._profile_label_for_value(value, DECELERATION_PROFILE_OPTIONS)
|
||||
|
||||
def _show_acceleration_profile_selector(self):
|
||||
self._show_selection("Acceleration Profile", "AccelerationProfile", ACCELERATION_PROFILE_OPTIONS, normalize_acceleration_profile(self._params.get("AccelerationProfile", encoding='utf-8')))
|
||||
|
||||
def _show_deceleration_profile_selector(self):
|
||||
self._show_selection("Deceleration Profile", "DecelerationProfile", DECELERATION_PROFILE_OPTIONS, normalize_deceleration_profile(self._params.get("DecelerationProfile", encoding='utf-8')))
|
||||
|
||||
def _profile_label_for_value(self, value, options):
|
||||
for option_value, option_label in options:
|
||||
if option_value == value:
|
||||
return tr(option_label)
|
||||
return tr(options[0][1])
|
||||
|
||||
def _show_selection(self, title, key, options, current_value):
|
||||
option_labels = [tr(option_label) for _, option_label in options]
|
||||
label_to_value = {tr(option_label): option_value for option_value, option_label in options}
|
||||
default_option = next((tr(option_label) for option_value, option_label in options if option_value == current_value), option_labels[0])
|
||||
|
||||
def on_select(res, val):
|
||||
if res == DialogResult.CONFIRM:
|
||||
self._params.put(key, val)
|
||||
self._params.put_int(key, label_to_value[val])
|
||||
self._rebuild_grid()
|
||||
|
||||
gui_app.set_modal_overlay(SelectionDialog(tr(key), options, self._params.get(key, encoding='utf-8') or "Standard", on_close=on_select))
|
||||
gui_app.set_modal_overlay(SelectionDialog(tr(title), option_labels, default_option, on_close=on_select))
|
||||
|
||||
def _show_int_selector(self, key, min_v, max_v, unit=""):
|
||||
def on_close(res, val):
|
||||
|
||||
@@ -89,7 +89,13 @@ class StarPilotPanel(Widget):
|
||||
bg_color=cat.get("color"),
|
||||
)
|
||||
elif tile_type == "toggle":
|
||||
tile = ToggleTile(title=tr(cat["title"]), get_state=cat["get_state"], set_state=cat["set_state"], icon_path=cat.get("icon"), bg_color=cat.get("color"), desc=tr(cat.get("desc", "")), is_enabled=cat.get("is_enabled"), disabled_label=cat.get("disabled_label", ""))
|
||||
raw_set_state = cat["set_state"]
|
||||
|
||||
def on_toggle(state: bool, setter=raw_set_state):
|
||||
setter(state)
|
||||
self._rebuild_grid()
|
||||
|
||||
tile = ToggleTile(title=tr(cat["title"]), get_state=cat["get_state"], set_state=on_toggle, icon_path=cat.get("icon"), bg_color=cat.get("color"), desc=tr(cat.get("desc", "")), is_enabled=cat.get("is_enabled"), disabled_label=cat.get("disabled_label", ""))
|
||||
elif tile_type == "value":
|
||||
tile = ValueTile(title=tr(cat["title"]), get_value=cat["get_value"], on_click=cat["on_click"], icon_path=cat.get("icon"), bg_color=cat.get("color"), is_enabled=cat.get("is_enabled"), desc=tr(cat.get("desc", "")))
|
||||
else:
|
||||
@@ -138,3 +144,41 @@ def create_tile_panel(categories: list[dict], sub_panels: dict[str, Widget] | No
|
||||
|
||||
panel._rebuild_grid()
|
||||
return panel
|
||||
|
||||
|
||||
def create_master_toggle_panel(toggle_specs: list[dict], sub_panels: dict[str, Widget] | None = None,
|
||||
extra_categories: list[dict] | None = None) -> StarPilotPanel:
|
||||
panel = create_tile_panel([], sub_panels)
|
||||
categories: list[dict] = []
|
||||
|
||||
for spec in toggle_specs:
|
||||
get_state = spec["get_state"]
|
||||
visible = spec.get("visible")
|
||||
manage_enabled = spec.get("manage_enabled", get_state)
|
||||
|
||||
categories.append({
|
||||
"title": spec["title"],
|
||||
"desc": spec.get("desc", ""),
|
||||
"type": "toggle",
|
||||
"get_state": get_state,
|
||||
"set_state": spec["set_state"],
|
||||
"icon": spec.get("icon"),
|
||||
"color": spec.get("color"),
|
||||
"visible": visible,
|
||||
})
|
||||
|
||||
categories.append({
|
||||
"title": spec.get("manage_title", "Settings"),
|
||||
"desc": spec.get("manage_desc", ""),
|
||||
"type": "value",
|
||||
"get_value": lambda enabled=get_state, active_label=spec.get("manage_label", "Manage"), inactive_label=spec.get("disabled_label", "Enable First"): tr(active_label) if enabled() else tr(inactive_label),
|
||||
"on_click": lambda sub_panel=spec["panel"]: panel._navigate_to(sub_panel),
|
||||
"is_enabled": manage_enabled,
|
||||
"icon": spec.get("manage_icon", spec.get("icon")),
|
||||
"color": spec.get("color"),
|
||||
"visible": visible,
|
||||
})
|
||||
|
||||
panel.CATEGORIES = categories + list(extra_categories or [])
|
||||
panel._rebuild_grid()
|
||||
return panel
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
from __future__ import annotations
|
||||
import os
|
||||
import re
|
||||
from pathlib import Path
|
||||
|
||||
from openpilot.system.hardware import HARDWARE
|
||||
from openpilot.system.ui.lib.application import gui_app
|
||||
@@ -12,73 +9,11 @@ from openpilot.system.ui.widgets.selection_dialog import SelectionDialog
|
||||
from openpilot.selfdrive.ui.layouts.settings.starpilot.panel import StarPilotPanel
|
||||
from openpilot.selfdrive.ui.layouts.settings.starpilot.aethergrid import AetherSliderDialog, TileGrid, HubTile, ToggleTile, ValueTile
|
||||
from openpilot.selfdrive.ui.lib.starpilot_state import starpilot_state
|
||||
|
||||
MAKE_TO_FOLDER = {
|
||||
"acura": "honda",
|
||||
"audi": "volkswagen",
|
||||
"buick": "gm",
|
||||
"cadillac": "gm",
|
||||
"chevrolet": "gm",
|
||||
"chrysler": "chrysler",
|
||||
"cupra": "volkswagen",
|
||||
"dodge": "chrysler",
|
||||
"ford": "ford",
|
||||
"genesis": "hyundai",
|
||||
"gmc": "gm",
|
||||
"holden": "gm",
|
||||
"honda": "honda",
|
||||
"hyundai": "hyundai",
|
||||
"jeep": "chrysler",
|
||||
"kia": "hyundai",
|
||||
"lexus": "toyota",
|
||||
"lincoln": "ford",
|
||||
"man": "volkswagen",
|
||||
"mazda": "mazda",
|
||||
"nissan": "nissan",
|
||||
"peugeot": "psa",
|
||||
"ram": "chrysler",
|
||||
"rivian": "rivian",
|
||||
"seat": "volkswagen",
|
||||
"škoda": "volkswagen",
|
||||
"subaru": "subaru",
|
||||
"tesla": "tesla",
|
||||
"toyota": "toyota",
|
||||
"volkswagen": "volkswagen",
|
||||
}
|
||||
|
||||
|
||||
def get_car_names(car_make: str):
|
||||
folder = MAKE_TO_FOLDER.get(car_make.lower())
|
||||
if not folder:
|
||||
return [], {}
|
||||
|
||||
# Path to values.py in opendbc
|
||||
values_path = Path(__file__).parents[4] / "opendbc" / "car" / folder / "values.py"
|
||||
if not values_path.exists():
|
||||
return [], {}
|
||||
|
||||
with open(values_path, "r") as f:
|
||||
content = f.read()
|
||||
|
||||
# Clean comments
|
||||
content = re.sub(r'#.*', '', content)
|
||||
|
||||
# Find platforms and car names
|
||||
platforms = re.findall(r'(\w+)\s*=\s*\w+\s*\(', content)
|
||||
car_models = {}
|
||||
car_names = []
|
||||
|
||||
# This is a simplified version of the C++ regex logic
|
||||
# In values.py, CarDocs often appears as CarDocs("Name", ...)
|
||||
matches = re.finditer(r'CarDocs\w*\s*\(\s*"([^"]+)"', content)
|
||||
for match in matches:
|
||||
name = match.group(1)
|
||||
if name.lower().startswith(car_make.lower()):
|
||||
# Find the platform name by looking backwards for the nearest platform assignment
|
||||
# For now, we'll just store the name
|
||||
car_names.append(name)
|
||||
|
||||
return sorted(list(set(car_names))), car_models
|
||||
from openpilot.selfdrive.ui.mici.layouts.settings.fingerprint_catalog import (
|
||||
FingerprintModelOption,
|
||||
get_fingerprint_catalog,
|
||||
shorten_model_label,
|
||||
)
|
||||
|
||||
|
||||
def _lock_doors_timer_labels():
|
||||
@@ -91,6 +26,7 @@ def _lock_doors_timer_labels():
|
||||
class StarPilotVehicleSettingsLayout(StarPilotPanel):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._make_options, self._models_by_make, self._models_by_value, self._make_by_model = get_fingerprint_catalog()
|
||||
self._sub_panels = {
|
||||
"gm": StarPilotGMVehicleLayout(),
|
||||
"hkg": StarPilotHKGVehicleLayout(),
|
||||
@@ -103,14 +39,14 @@ class StarPilotVehicleSettingsLayout(StarPilotPanel):
|
||||
{
|
||||
"title": tr_noop("Car Make"),
|
||||
"type": "value",
|
||||
"get_value": lambda: self._params.get("CarMake", encoding='utf-8') or tr("None"),
|
||||
"get_value": self._get_display_make,
|
||||
"on_click": self._on_select_make,
|
||||
"color": "#64748B",
|
||||
},
|
||||
{
|
||||
"title": tr_noop("Car Model"),
|
||||
"type": "value",
|
||||
"get_value": lambda: self._params.get("CarModelName", encoding='utf-8') or tr("None"),
|
||||
"get_value": self._get_display_model,
|
||||
"on_click": self._on_select_model,
|
||||
"color": "#64748B",
|
||||
},
|
||||
@@ -189,37 +125,93 @@ class StarPilotVehicleSettingsLayout(StarPilotPanel):
|
||||
|
||||
self._tile_grid.add_tile(tile)
|
||||
|
||||
def _get_display_make(self):
|
||||
make = self._params.get("CarMake", encoding='utf-8') or ""
|
||||
if make:
|
||||
return make
|
||||
|
||||
model = self._params.get("CarModel", encoding='utf-8') or ""
|
||||
if model:
|
||||
return self._make_by_model.get(model, tr("None"))
|
||||
return tr("None")
|
||||
|
||||
def _get_selected_model_option(self) -> FingerprintModelOption | None:
|
||||
model = self._params.get("CarModel", encoding='utf-8') or ""
|
||||
if not model:
|
||||
return None
|
||||
|
||||
model_name = self._params.get("CarModelName", encoding='utf-8') or ""
|
||||
make = self._params.get("CarMake", encoding='utf-8') or self._make_by_model.get(model, "")
|
||||
if make and model_name:
|
||||
for option in self._models_by_make.get(make, ()):
|
||||
if option.value == model and option.label == model_name:
|
||||
return option
|
||||
|
||||
return self._models_by_value.get(model)
|
||||
|
||||
def _get_display_model(self):
|
||||
selected_option = self._get_selected_model_option()
|
||||
if selected_option is not None:
|
||||
return selected_option.button_label
|
||||
|
||||
model = self._params.get("CarModel", encoding='utf-8') or ""
|
||||
model_name = self._params.get("CarModelName", encoding='utf-8') or ""
|
||||
make = self._params.get("CarMake", encoding='utf-8') or self._make_by_model.get(model, "")
|
||||
|
||||
if model_name:
|
||||
return shorten_model_label(make, model_name) if make else model_name
|
||||
if model and model in self._models_by_value:
|
||||
return self._models_by_value[model].button_label
|
||||
return tr("None")
|
||||
|
||||
def _on_select_make(self):
|
||||
makes = sorted(list(MAKE_TO_FOLDER.keys()))
|
||||
makes = [m.capitalize() for m in makes]
|
||||
makes = list(self._make_options)
|
||||
if not makes:
|
||||
gui_app.set_modal_overlay(ConfirmDialog(tr("No fingerprint list available."), tr("OK"), on_close=lambda r: None))
|
||||
return
|
||||
|
||||
def on_select(res, val):
|
||||
if res == DialogResult.CONFIRM:
|
||||
self._params.put("CarMake", val)
|
||||
self._params.remove("CarModel")
|
||||
self._params.remove("CarModelName")
|
||||
current_model = self._params.get("CarModel", encoding='utf-8') or ""
|
||||
available_models = {option.value for option in self._models_by_make.get(val, ())}
|
||||
if current_model not in available_models:
|
||||
self._params.remove("CarModel")
|
||||
self._params.remove("CarModelName")
|
||||
self._rebuild_grid()
|
||||
|
||||
gui_app.set_modal_overlay(SelectionDialog(tr("Select Make"), makes, self._params.get("CarMake", encoding='utf-8') or "", on_close=on_select))
|
||||
current_make = self._params.get("CarMake", encoding='utf-8') or ""
|
||||
default_make = current_make if current_make in makes else makes[0]
|
||||
gui_app.set_modal_overlay(SelectionDialog(tr("Select Make"), makes, default_make, on_close=on_select))
|
||||
|
||||
def _on_select_model(self):
|
||||
make = self._params.get("CarMake", encoding='utf-8')
|
||||
make = self._params.get("CarMake", encoding='utf-8') or ""
|
||||
if not make:
|
||||
gui_app.set_modal_overlay(ConfirmDialog(tr("Please select a Car Make first!"), tr("OK"), on_close=lambda r: None))
|
||||
return
|
||||
|
||||
models, _ = get_car_names(make)
|
||||
if not models:
|
||||
gui_app.set_modal_overlay(ConfirmDialog(tr("No models found for this make."), tr("OK"), on_close=lambda r: None))
|
||||
model_options = self._models_by_make.get(make, ())
|
||||
if not model_options:
|
||||
gui_app.set_modal_overlay(ConfirmDialog(tr("No models available for this make."), tr("OK"), on_close=lambda r: None))
|
||||
return
|
||||
|
||||
option_labels = [option.option_label for option in model_options]
|
||||
selected_by_label = {option.option_label: option for option in model_options}
|
||||
current_model = self._params.get("CarModel", encoding='utf-8') or ""
|
||||
current_model_name = self._params.get("CarModelName", encoding='utf-8') or ""
|
||||
default_option = next((option.option_label for option in model_options if option.value == current_model and option.label == current_model_name), None)
|
||||
if default_option is None:
|
||||
default_option = next((option.option_label for option in model_options if option.value == current_model), option_labels[0])
|
||||
|
||||
def on_select(res, val):
|
||||
if res == DialogResult.CONFIRM:
|
||||
self._params.put("CarModelName", val)
|
||||
# In a real build we'd map name to platform code here
|
||||
selected_option = selected_by_label[val]
|
||||
self._params.put("CarModel", selected_option.value)
|
||||
self._params.put("CarModelName", selected_option.label)
|
||||
self._params.put("CarMake", make)
|
||||
self._rebuild_grid()
|
||||
|
||||
gui_app.set_modal_overlay(SelectionDialog(tr("Select Model"), models, self._params.get("CarModelName", encoding='utf-8') or "", on_close=on_select))
|
||||
gui_app.set_modal_overlay(SelectionDialog(tr("Select Model"), option_labels, default_option, on_close=on_select))
|
||||
|
||||
def _on_disable_long(self, state):
|
||||
if state:
|
||||
|
||||
Reference in New Issue
Block a user