mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-08-19 23:34:14 +08:00
1096 lines
45 KiB
Python
1096 lines
45 KiB
Python
from __future__ import annotations
|
|
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.system.ui.widgets.input_dialog import InputDialog
|
|
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,
|
|
)
|
|
from openpilot.starpilot.common.experimental_state import sync_persist_experimental_state
|
|
|
|
|
|
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__()
|
|
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": 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"},
|
|
{"title": tr_noop("Curve Speed"), "panel": "curve", "icon": "toggle_icons/icon_speed_map.png", "color": "#597497"},
|
|
{"title": tr_noop("Weather"), "panel": "weather", "icon": "toggle_icons/icon_rainbow.png", "color": "#597497"},
|
|
], {
|
|
"conditional": StarPilotConditionalExperimentalLayout(),
|
|
"curve": StarPilotCurveSpeedLayout(),
|
|
"weather": StarPilotWeatherLayout(),
|
|
"low_visibility": StarPilotWeatherBase("LowVisibility"),
|
|
"rain": StarPilotWeatherBase("Rain"),
|
|
"rainstorm": StarPilotWeatherBase("RainStorm"),
|
|
"snow": StarPilotWeatherBase("Snow"),
|
|
})
|
|
|
|
self._section_tabs = TabbedSectionHost([
|
|
TabSectionSpec("tune", "Tune", tune_panel),
|
|
TabSectionSpec("adaptive", "Adaptive", adaptive_panel),
|
|
TabSectionSpec("limits", "Limits", StarPilotSpeedLimitControllerLayout()),
|
|
TabSectionSpec("daily", "Daily", StarPilotLongitudinalQOLLayout()),
|
|
])
|
|
self._rebuild_grid()
|
|
|
|
def set_navigate_callback(self, callback):
|
|
self._section_tabs.set_navigate_callback(callback)
|
|
|
|
def set_back_callback(self, callback):
|
|
self._section_tabs.set_back_callback(callback)
|
|
|
|
def _render(self, rect):
|
|
self._section_tabs.render(rect)
|
|
|
|
def set_current_sub_panel(self, sub_panel: str):
|
|
self._section_tabs.set_current_sub_panel(sub_panel)
|
|
|
|
def show_event(self):
|
|
self._section_tabs.show_event()
|
|
|
|
def hide_event(self):
|
|
self._section_tabs.hide_event()
|
|
|
|
|
|
class StarPilotAdvancedLongitudinalLayout(StarPilotPanel):
|
|
def __init__(self):
|
|
super().__init__()
|
|
self.CATEGORIES = [
|
|
{
|
|
"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": self._set_ev_tuning,
|
|
"color": "#597497",
|
|
"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": self._set_truck_tuning,
|
|
"color": "#597497",
|
|
"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": self._advanced_enabled,
|
|
},
|
|
{
|
|
"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": self._advanced_enabled,
|
|
},
|
|
{
|
|
"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._advanced_enabled() and not self._using_human_acceleration(),
|
|
},
|
|
{
|
|
"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": 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": self._show_stop_tuning_values,
|
|
},
|
|
{
|
|
"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": self._show_stop_tuning_values,
|
|
},
|
|
{
|
|
"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": 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:
|
|
self._params.put_float(key, float(val))
|
|
self._rebuild_grid()
|
|
|
|
gui_app.set_modal_overlay(AetherSliderDialog(tr(key), min_v, max_v, step, self._params.get_float(key), on_close, unit=unit, color="#597497"))
|
|
|
|
|
|
class StarPilotConditionalExperimentalLayout(StarPilotPanel):
|
|
def __init__(self):
|
|
super().__init__()
|
|
self.CATEGORIES = [
|
|
{
|
|
"title": tr_noop("Conditional Experimental Mode"),
|
|
"type": "toggle",
|
|
"get_state": lambda: self._params.get_bool("ConditionalExperimental"),
|
|
"set_state": lambda s: self._params.put_bool("ConditionalExperimental", s),
|
|
"icon": "toggle_icons/icon_conditional.png",
|
|
"color": "#597497",
|
|
},
|
|
{
|
|
"title": tr_noop("Persist Experimental State"),
|
|
"desc": tr_noop("Keep your manual Conditional Experimental override through reboots until you manually clear it."),
|
|
"type": "toggle",
|
|
"get_state": lambda: self._params.get_bool("PersistExperimentalState"),
|
|
"set_state": self._set_persist_experimental_state,
|
|
"color": "#597497",
|
|
"visible": lambda: self._params.get_bool("ConditionalExperimental"),
|
|
},
|
|
{
|
|
"title": tr_noop("Below Speed"),
|
|
"type": "value",
|
|
"get_value": lambda: f"{self._params.get_int('CESpeed')} mph",
|
|
"on_click": lambda: self._show_speed_selector("CESpeed"),
|
|
"color": "#597497",
|
|
"visible": lambda: self._params.get_bool("ConditionalExperimental"),
|
|
},
|
|
{
|
|
"title": tr_noop("Curves"),
|
|
"type": "toggle",
|
|
"get_state": lambda: self._params.get_bool("CECurves"),
|
|
"set_state": lambda s: self._params.put_bool("CECurves", s),
|
|
"color": "#597497",
|
|
"visible": lambda: self._params.get_bool("ConditionalExperimental"),
|
|
},
|
|
{
|
|
"title": tr_noop("Curves Lead"),
|
|
"type": "toggle",
|
|
"get_state": lambda: self._params.get_bool("CECurvesLead"),
|
|
"set_state": lambda s: self._params.put_bool("CECurvesLead", s),
|
|
"visible": lambda: self._params.get_bool("CECurves"),
|
|
"color": "#597497",
|
|
},
|
|
{
|
|
"title": tr_noop("Stop Lights"),
|
|
"type": "toggle",
|
|
"get_state": lambda: self._params.get_bool("CEStopLights"),
|
|
"set_state": lambda s: self._params.put_bool("CEStopLights", s),
|
|
"color": "#597497",
|
|
"visible": lambda: self._params.get_bool("ConditionalExperimental"),
|
|
},
|
|
{
|
|
"title": tr_noop("Lead Detected"),
|
|
"type": "toggle",
|
|
"get_state": lambda: self._params.get_bool("CELead"),
|
|
"set_state": lambda s: self._params.put_bool("CELead", s),
|
|
"color": "#597497",
|
|
"visible": lambda: self._params.get_bool("ConditionalExperimental"),
|
|
},
|
|
{
|
|
"title": tr_noop("Slower Lead"),
|
|
"type": "toggle",
|
|
"get_state": lambda: self._params.get_bool("CESlowerLead"),
|
|
"set_state": lambda s: self._params.put_bool("CESlowerLead", s),
|
|
"color": "#597497",
|
|
"visible": lambda: self._params.get_bool("ConditionalExperimental") and self._params.get_bool("CELead"),
|
|
},
|
|
{
|
|
"title": tr_noop("Stopped Lead"),
|
|
"type": "toggle",
|
|
"get_state": lambda: self._params.get_bool("CEStoppedLead"),
|
|
"set_state": lambda s: self._params.put_bool("CEStoppedLead", s),
|
|
"color": "#597497",
|
|
"visible": lambda: self._params.get_bool("ConditionalExperimental") and self._params.get_bool("CELead"),
|
|
},
|
|
{
|
|
"title": tr_noop("Predicted Stop"),
|
|
"type": "value",
|
|
"get_value": lambda: f"{self._params.get_int('CEModelStopTime')}s",
|
|
"on_click": lambda: self._show_int_selector("CEModelStopTime", 0, 10, "s"),
|
|
"color": "#597497",
|
|
"visible": lambda: self._params.get_bool("ConditionalExperimental"),
|
|
},
|
|
{
|
|
"title": tr_noop("Signal Below"),
|
|
"type": "value",
|
|
"get_value": lambda: f"{self._params.get_int('CESignalSpeed')} mph",
|
|
"on_click": lambda: self._show_speed_selector("CESignalSpeed"),
|
|
"color": "#597497",
|
|
"visible": lambda: self._params.get_bool("ConditionalExperimental"),
|
|
},
|
|
{
|
|
"title": tr_noop("Speed Lead"),
|
|
"type": "value",
|
|
"get_value": lambda: f"{self._params.get_int('CESpeedLead')} mph",
|
|
"on_click": lambda: self._show_speed_selector("CESpeedLead"),
|
|
"color": "#597497",
|
|
"visible": lambda: self._params.get_bool("ConditionalExperimental"),
|
|
},
|
|
{
|
|
"title": tr_noop("Signal Lane Detection"),
|
|
"type": "toggle",
|
|
"get_state": lambda: self._params.get_bool("CESignalLaneDetection"),
|
|
"set_state": lambda s: self._params.put_bool("CESignalLaneDetection", s),
|
|
"visible": lambda: self._params.get_int("CESignalSpeed") > 0,
|
|
"color": "#597497",
|
|
},
|
|
{
|
|
"title": tr_noop("Status Widget"),
|
|
"type": "toggle",
|
|
"get_state": lambda: self._params.get_bool("ShowCEMStatus"),
|
|
"set_state": lambda s: self._params.put_bool("ShowCEMStatus", s),
|
|
"color": "#597497",
|
|
"visible": lambda: self._params.get_bool("ConditionalExperimental"),
|
|
},
|
|
]
|
|
self._rebuild_grid()
|
|
|
|
def _set_persist_experimental_state(self, state: bool):
|
|
sync_persist_experimental_state(self._params, self._params_memory, state)
|
|
|
|
def _show_speed_selector(self, key):
|
|
def on_close(res, val):
|
|
if res == DialogResult.CONFIRM:
|
|
self._params.put_int(key, int(val))
|
|
self._rebuild_grid()
|
|
|
|
gui_app.set_modal_overlay(AetherSliderDialog(tr(key), 0, 100, 1, self._params.get_int(key), on_close, unit=" mph", color="#597497"))
|
|
|
|
def _show_int_selector(self, key, min_v, max_v, unit=""):
|
|
def on_close(res, val):
|
|
if res == DialogResult.CONFIRM:
|
|
self._params.put_int(key, int(val))
|
|
self._rebuild_grid()
|
|
|
|
gui_app.set_modal_overlay(AetherSliderDialog(tr(key), min_v, max_v, 1, self._params.get_int(key), on_close, unit=unit, color="#597497"))
|
|
|
|
|
|
class StarPilotCurveSpeedLayout(StarPilotPanel):
|
|
def __init__(self):
|
|
super().__init__()
|
|
self.CATEGORIES = [
|
|
{
|
|
"title": tr_noop("Curve Speed Controller"),
|
|
"type": "toggle",
|
|
"get_state": lambda: self._params.get_bool("CurveSpeedController"),
|
|
"set_state": lambda s: self._params.put_bool("CurveSpeedController", s),
|
|
"icon": "toggle_icons/icon_speed_map.png",
|
|
"color": "#597497",
|
|
},
|
|
{
|
|
"title": tr_noop("Status Widget"),
|
|
"desc": tr_noop("Show the Curve Speed Controller ambient effect on the driving screen."),
|
|
"type": "toggle",
|
|
"get_state": lambda: self._params.get_bool("ShowCSCStatus"),
|
|
"set_state": lambda s: self._params.put_bool("ShowCSCStatus", s),
|
|
"color": "#597497",
|
|
"visible": lambda: self._params.get_bool("CurveSpeedController"),
|
|
},
|
|
{
|
|
"title": tr_noop("Calibrated Lateral Accel"),
|
|
"desc": tr_noop("The learned lateral acceleration from collected driving data. Higher values allow faster cornering."),
|
|
"type": "value",
|
|
"get_value": lambda: f"{self._params_memory.get_float('CalibratedLateralAcceleration'):.2f} m/s²",
|
|
"on_click": lambda: None,
|
|
"color": "#597497",
|
|
"visible": lambda: self._params.get_bool("CurveSpeedController"),
|
|
},
|
|
{
|
|
"title": tr_noop("Calibration Progress"),
|
|
"desc": tr_noop("How much curve data has been collected. Normal for the value to stay low."),
|
|
"type": "value",
|
|
"get_value": lambda: f"{self._params_memory.get_float('CalibrationProgress'):.2f}%",
|
|
"on_click": lambda: None,
|
|
"color": "#597497",
|
|
"visible": lambda: self._params.get_bool("CurveSpeedController"),
|
|
},
|
|
{
|
|
"title": tr_noop("Reset Curve Data"),
|
|
"desc": tr_noop("Reset collected user data for Curve Speed Controller."),
|
|
"type": "hub",
|
|
"on_click": lambda: self._reset_curve_data(),
|
|
"color": "#597497",
|
|
"visible": lambda: self._params.get_bool("CurveSpeedController"),
|
|
},
|
|
]
|
|
self._rebuild_grid()
|
|
|
|
def _reset_curve_data(self):
|
|
def on_close(res):
|
|
if res == DialogResult.CONFIRM:
|
|
self._params.put_float("CalibratedLateralAcceleration", 2.00)
|
|
self._params.remove("CalibrationProgress")
|
|
self._params.remove("CurvatureData")
|
|
self._rebuild_grid()
|
|
|
|
gui_app.set_modal_overlay(ConfirmDialog(tr("Reset Curve Data?"), tr("Confirm"), on_close=on_close))
|
|
|
|
|
|
class StarPilotPersonalitiesLayout(StarPilotPanel):
|
|
def __init__(self):
|
|
super().__init__()
|
|
self.CATEGORIES = [
|
|
{
|
|
"title": tr_noop("Driving Personalities"),
|
|
"type": "toggle",
|
|
"get_state": lambda: self._params.get_bool("CustomPersonalities"),
|
|
"set_state": lambda s: self._params.put_bool("CustomPersonalities", s),
|
|
"icon": "toggle_icons/icon_personality.png",
|
|
"color": "#597497",
|
|
},
|
|
{"title": tr_noop("Traffic"), "panel": "traffic_personality", "icon": "toggle_icons/icon_personality.png", "color": "#597497"},
|
|
{"title": tr_noop("Aggressive"), "panel": "aggressive_personality", "icon": "toggle_icons/icon_personality.png", "color": "#597497"},
|
|
{"title": tr_noop("Standard"), "panel": "standard_personality", "icon": "toggle_icons/icon_personality.png", "color": "#597497"},
|
|
{"title": tr_noop("Relaxed"), "panel": "relaxed_personality", "icon": "toggle_icons/icon_personality.png", "color": "#597497"},
|
|
]
|
|
self._rebuild_grid()
|
|
|
|
|
|
class StarPilotPersonalityProfileLayout(StarPilotPanel):
|
|
def __init__(self, profile: str):
|
|
super().__init__()
|
|
self._profile = profile
|
|
follow_min = 1.0 if profile == "Traffic" else 0.5
|
|
follow_max = 2.5 if profile == "Traffic" else 3.0
|
|
self.CATEGORIES = [
|
|
{
|
|
"title": tr_noop("Follow Distance"),
|
|
"type": "value",
|
|
"get_value": lambda: f"{self._params.get_float(self._profile + 'Follow'):.2f}s",
|
|
"on_click": lambda: self._show_float_selector(self._profile + "Follow", follow_min, follow_max, 0.05, "s"),
|
|
"color": "#597497",
|
|
},
|
|
{
|
|
"title": tr_noop("Follow High"),
|
|
"type": "value",
|
|
"get_value": lambda: f"{self._params.get_float(self._profile + 'FollowHigh'):.2f}s",
|
|
"on_click": lambda: self._show_float_selector(self._profile + "FollowHigh", 1.0, 3.0, 0.05, "s"),
|
|
"visible": lambda: self._profile != "Traffic",
|
|
"color": "#597497",
|
|
},
|
|
{
|
|
"title": tr_noop("Accel Smoothness"),
|
|
"type": "value",
|
|
"get_value": lambda: f"{self._params.get_int(self._profile + 'JerkAcceleration')}%",
|
|
"on_click": lambda: self._show_int_selector(self._profile + "JerkAcceleration", 25, 200, "%"),
|
|
"color": "#597497",
|
|
},
|
|
{
|
|
"title": tr_noop("Brake Smoothness"),
|
|
"type": "value",
|
|
"get_value": lambda: f"{self._params.get_int(self._profile + 'JerkDeceleration')}%",
|
|
"on_click": lambda: self._show_int_selector(self._profile + "JerkDeceleration", 25, 200, "%"),
|
|
"color": "#597497",
|
|
},
|
|
{
|
|
"title": tr_noop("Safety Gap Bias"),
|
|
"type": "value",
|
|
"get_value": lambda: f"{self._params.get_int(self._profile + 'JerkDanger')}%",
|
|
"on_click": lambda: self._show_int_selector(self._profile + "JerkDanger", 25, 200, "%"),
|
|
"color": "#597497",
|
|
},
|
|
{
|
|
"title": tr_noop("Slowdown Response"),
|
|
"type": "value",
|
|
"get_value": lambda: f"{self._params.get_int(self._profile + 'JerkSpeedDecrease')}%",
|
|
"on_click": lambda: self._show_int_selector(self._profile + "JerkSpeedDecrease", 25, 200, "%"),
|
|
"color": "#597497",
|
|
},
|
|
{
|
|
"title": tr_noop("Speed-Up Response"),
|
|
"type": "value",
|
|
"get_value": lambda: f"{self._params.get_int(self._profile + 'JerkSpeed')}%",
|
|
"on_click": lambda: self._show_int_selector(self._profile + "JerkSpeed", 25, 200, "%"),
|
|
"color": "#597497",
|
|
},
|
|
{
|
|
"title": tr_noop("Reset to Defaults"),
|
|
"type": "hub",
|
|
"on_click": lambda: self._reset_profile(),
|
|
"color": "#597497",
|
|
},
|
|
]
|
|
self._rebuild_grid()
|
|
|
|
def _reset_profile(self):
|
|
def on_close(res):
|
|
if res == DialogResult.CONFIRM:
|
|
for key in ["Follow", "FollowHigh", "JerkAcceleration", "JerkDeceleration", "JerkDanger", "JerkSpeedDecrease", "JerkSpeed"]:
|
|
self._params.remove(self._profile + key)
|
|
self._rebuild_grid()
|
|
|
|
gui_app.set_modal_overlay(ConfirmDialog(tr("Reset to Defaults?"), tr("Confirm"), on_close=on_close))
|
|
|
|
def _show_float_selector(self, key, min_v, max_v, step, unit=""):
|
|
def on_close(res, val):
|
|
if res == DialogResult.CONFIRM:
|
|
self._params.put_float(key, float(val))
|
|
self._rebuild_grid()
|
|
|
|
gui_app.set_modal_overlay(AetherSliderDialog(tr(key), min_v, max_v, step, self._params.get_float(key), on_close, unit=unit, color="#597497"))
|
|
|
|
def _show_int_selector(self, key, min_v, max_v, unit=""):
|
|
def on_close(res, val):
|
|
if res == DialogResult.CONFIRM:
|
|
self._params.put_int(key, int(val))
|
|
self._rebuild_grid()
|
|
|
|
gui_app.set_modal_overlay(AetherSliderDialog(tr(key), min_v, max_v, 5, self._params.get_int(key), on_close, unit=unit, color="#597497"))
|
|
|
|
|
|
class StarPilotLongitudinalTuneLayout(StarPilotPanel):
|
|
def __init__(self):
|
|
super().__init__()
|
|
self.CATEGORIES = [
|
|
{
|
|
"title": tr_noop("Acceleration Profile"),
|
|
"desc": tr_noop("Choose how quickly openpilot speeds up."),
|
|
"type": "value",
|
|
"get_value": self._get_acceleration_profile_label,
|
|
"on_click": self._show_acceleration_profile_selector,
|
|
"color": "#597497",
|
|
"visible": self._longitudinal_enabled,
|
|
},
|
|
{
|
|
"title": tr_noop("Deceleration Profile"),
|
|
"desc": tr_noop("Choose how firmly openpilot slows the car down."),
|
|
"type": "value",
|
|
"get_value": self._get_deceleration_profile_label,
|
|
"on_click": self._show_deceleration_profile_selector,
|
|
"color": "#597497",
|
|
"visible": self._longitudinal_enabled,
|
|
},
|
|
{
|
|
"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": self._longitudinal_enabled,
|
|
},
|
|
{
|
|
"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": self._longitudinal_enabled,
|
|
},
|
|
{
|
|
"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._longitudinal_enabled() and starpilot_state.car_state.hasRadar,
|
|
},
|
|
{
|
|
"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": self._longitudinal_enabled,
|
|
},
|
|
{
|
|
"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": self._longitudinal_enabled,
|
|
},
|
|
]
|
|
self._rebuild_grid()
|
|
|
|
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_int(key, label_to_value[val])
|
|
self._rebuild_grid()
|
|
|
|
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):
|
|
if res == DialogResult.CONFIRM:
|
|
self._params.put_int(key, int(val))
|
|
self._rebuild_grid()
|
|
|
|
gui_app.set_modal_overlay(AetherSliderDialog(tr(key), min_v, max_v, 1, self._params.get_int(key), on_close, unit=unit, color="#597497"))
|
|
|
|
|
|
class StarPilotLongitudinalQOLLayout(StarPilotPanel):
|
|
def __init__(self):
|
|
super().__init__()
|
|
self.CATEGORIES = [
|
|
{
|
|
"title": tr_noop("Quality of Life"),
|
|
"type": "toggle",
|
|
"get_state": lambda: self._params.get_bool("QOLLongitudinal"),
|
|
"set_state": lambda s: self._params.put_bool("QOLLongitudinal", s),
|
|
"icon": "toggle_icons/icon_quality_of_life.png",
|
|
"color": "#597497",
|
|
},
|
|
{
|
|
"title": tr_noop("Cruise Interval"),
|
|
"type": "value",
|
|
"get_value": lambda: f"{max(1, self._params.get_int('CustomCruise'))} mph",
|
|
"on_click": lambda: self._show_speed_selector("CustomCruise"),
|
|
"color": "#597497",
|
|
"visible": lambda: self._params.get_bool("QOLLongitudinal"),
|
|
},
|
|
{
|
|
"title": tr_noop("Cruise Long"),
|
|
"type": "value",
|
|
"get_value": lambda: f"{max(1, self._params.get_int('CustomCruiseLong'))} mph",
|
|
"on_click": lambda: self._show_speed_selector("CustomCruiseLong"),
|
|
"color": "#597497",
|
|
"visible": lambda: self._params.get_bool("QOLLongitudinal"),
|
|
},
|
|
{
|
|
"title": tr_noop("Reverse Cruise"),
|
|
"type": "toggle",
|
|
"get_state": lambda: self._params.get_bool("ReverseCruise"),
|
|
"set_state": lambda s: self._params.put_bool("ReverseCruise", s),
|
|
"color": "#597497",
|
|
"visible": lambda: self._params.get_bool("QOLLongitudinal"),
|
|
},
|
|
{
|
|
"title": tr_noop("Force Stops"),
|
|
"type": "toggle",
|
|
"get_state": lambda: self._params.get_bool("ForceStops"),
|
|
"set_state": lambda s: self._params.put_bool("ForceStops", s),
|
|
"color": "#597497",
|
|
"visible": lambda: self._params.get_bool("QOLLongitudinal"),
|
|
},
|
|
{
|
|
"title": tr_noop("Force Standstill State"),
|
|
"type": "toggle",
|
|
"get_state": lambda: self._params.get_bool("ForceStandstill"),
|
|
"set_state": lambda s: self._params.put_bool("ForceStandstill", s),
|
|
"color": "#597497",
|
|
"visible": lambda: self._params.get_bool("QOLLongitudinal"),
|
|
},
|
|
{
|
|
"title": tr_noop("Stopped Distance"),
|
|
"type": "value",
|
|
"get_value": lambda: f"{self._params.get_int('IncreasedStoppedDistance')} ft",
|
|
"on_click": lambda: self._show_int_selector("IncreasedStoppedDistance", 0, 10, " ft"),
|
|
"color": "#597497",
|
|
"visible": lambda: self._params.get_bool("QOLLongitudinal"),
|
|
},
|
|
{
|
|
"title": tr_noop("Set Speed Offset"),
|
|
"type": "value",
|
|
"get_value": lambda: f"+{self._params.get_int('SetSpeedOffset')} mph",
|
|
"on_click": lambda: self._show_int_selector("SetSpeedOffset", 0, 99, " mph"),
|
|
"color": "#597497",
|
|
"visible": lambda: self._params.get_bool("QOLLongitudinal"),
|
|
},
|
|
{
|
|
"title": tr_noop("Map Gears"),
|
|
"type": "toggle",
|
|
"get_state": lambda: self._params.get_bool("MapGears"),
|
|
"set_state": lambda s: self._params.put_bool("MapGears", s),
|
|
"color": "#597497",
|
|
"visible": lambda: self._params.get_bool("QOLLongitudinal"),
|
|
},
|
|
{
|
|
"title": tr_noop("Map Acceleration"),
|
|
"type": "toggle",
|
|
"get_state": lambda: self._params.get_bool("MapAcceleration"),
|
|
"set_state": lambda s: self._params.put_bool("MapAcceleration", s),
|
|
"visible": lambda: self._params.get_bool("MapGears"),
|
|
"color": "#597497",
|
|
},
|
|
{
|
|
"title": tr_noop("Map Deceleration"),
|
|
"type": "toggle",
|
|
"get_state": lambda: self._params.get_bool("MapDeceleration"),
|
|
"set_state": lambda s: self._params.put_bool("MapDeceleration", s),
|
|
"visible": lambda: self._params.get_bool("MapGears"),
|
|
"color": "#597497",
|
|
},
|
|
]
|
|
self._rebuild_grid()
|
|
|
|
def _show_speed_selector(self, key):
|
|
def on_close(res, val):
|
|
if res == DialogResult.CONFIRM:
|
|
self._params.put_int(key, int(val))
|
|
self._rebuild_grid()
|
|
|
|
current = max(1, self._params.get_int(key))
|
|
gui_app.set_modal_overlay(AetherSliderDialog(tr(key), 1, 100, 1, current, on_close, unit=" mph", color="#597497"))
|
|
|
|
def _show_int_selector(self, key, min_v, max_v, unit=""):
|
|
def on_close(res, val):
|
|
if res == DialogResult.CONFIRM:
|
|
self._params.put_int(key, int(val))
|
|
self._rebuild_grid()
|
|
|
|
gui_app.set_modal_overlay(AetherSliderDialog(tr(key), min_v, max_v, 1, self._params.get_int(key), on_close, unit=unit, color="#597497"))
|
|
|
|
|
|
class StarPilotSpeedLimitControllerLayout(StarPilotPanel):
|
|
def __init__(self):
|
|
super().__init__()
|
|
self._sub_panels = {
|
|
"slc_offsets": StarPilotSLCOffsetsLayout(),
|
|
"slc_qol": StarPilotSLCQOLLayout(),
|
|
"slc_visuals": StarPilotSLCVisualsLayout(),
|
|
}
|
|
self.CATEGORIES = [
|
|
{
|
|
"title": tr_noop("Speed Limit Controller"),
|
|
"desc": tr_noop("Limit the car's maximum speed to the current speed limit."),
|
|
"type": "toggle",
|
|
"get_state": lambda: self._params.get_bool("SpeedLimitController"),
|
|
"set_state": lambda s: self._params.put_bool("SpeedLimitController", s),
|
|
"icon": "toggle_icons/icon_speed_limit.png",
|
|
"color": "#597497",
|
|
},
|
|
{"title": tr_noop("SLC Offsets"), "panel": "slc_offsets", "icon": "toggle_icons/icon_speed_limit.png", "color": "#597497"},
|
|
{"title": tr_noop("SLC Quality of Life"), "panel": "slc_qol", "icon": "toggle_icons/icon_speed_limit.png", "color": "#597497"},
|
|
{"title": tr_noop("SLC Visuals"), "panel": "slc_visuals", "icon": "toggle_icons/icon_speed_limit.png", "color": "#597497"},
|
|
{
|
|
"title": tr_noop("Fallback Speed"),
|
|
"type": "value",
|
|
"get_value": lambda: self._params.get("SLCFallback", encoding='utf-8') or "Set Speed",
|
|
"on_click": lambda: self._show_selection("SLCFallback", ["Set Speed", "Experimental Mode", "Previous Limit"]),
|
|
"color": "#597497",
|
|
},
|
|
{
|
|
"title": tr_noop("Override Speed"),
|
|
"type": "value",
|
|
"get_value": lambda: self._params.get("SLCOverride", encoding='utf-8') or "None",
|
|
"on_click": lambda: self._show_selection("SLCOverride", ["None", "Set With Gas Pedal", "Max Set Speed"]),
|
|
"color": "#597497",
|
|
},
|
|
{
|
|
"title": tr_noop("Source Priority"),
|
|
"type": "value",
|
|
"get_value": self._get_priority_value,
|
|
"on_click": self._on_priority_clicked,
|
|
"color": "#597497",
|
|
},
|
|
]
|
|
|
|
for panel in self._sub_panels.values():
|
|
if hasattr(panel, 'set_navigate_callback'):
|
|
panel.set_navigate_callback(self._navigate_to)
|
|
if hasattr(panel, 'set_back_callback'):
|
|
panel.set_back_callback(self._go_back)
|
|
|
|
self._rebuild_grid()
|
|
|
|
def _get_priority_value(self):
|
|
primary = self._params.get("SLCPriority1", encoding='utf-8') or "Map Data"
|
|
secondary = self._params.get("SLCPriority2", encoding='utf-8') or "None"
|
|
if primary in ("Highest", "Lowest") or secondary in ("", "None", primary):
|
|
return primary
|
|
return f"{primary}, {secondary}"
|
|
|
|
def _on_priority_clicked(self):
|
|
primary_options = ["Dashboard", "Map Data", "Vision", "Highest", "Lowest"]
|
|
current_primary = self._params.get("SLCPriority1", encoding='utf-8') or "Map Data"
|
|
current_secondary = self._params.get("SLCPriority2", encoding='utf-8') or "None"
|
|
|
|
def on_secondary_select(primary, res, val):
|
|
if res == DialogResult.CONFIRM:
|
|
self._params.put("SLCPriority1", primary)
|
|
self._params.put("SLCPriority2", val)
|
|
self._rebuild_grid()
|
|
|
|
def show_secondary_dialog(primary):
|
|
secondary_options = ["None"] + [option for option in ("Dashboard", "Map Data", "Vision") if option != primary]
|
|
selected_secondary = current_secondary if current_secondary in secondary_options else "None"
|
|
gui_app.set_modal_overlay(
|
|
SelectionDialog(
|
|
tr("SLC Secondary Priority"),
|
|
secondary_options,
|
|
selected_secondary,
|
|
on_close=lambda res, val: on_secondary_select(primary, res, val),
|
|
)
|
|
)
|
|
|
|
def on_primary_select(res, val):
|
|
if res != DialogResult.CONFIRM:
|
|
return
|
|
if val in ("Highest", "Lowest"):
|
|
self._params.put("SLCPriority1", val)
|
|
self._params.put("SLCPriority2", "None")
|
|
self._rebuild_grid()
|
|
return
|
|
show_secondary_dialog(val)
|
|
|
|
gui_app.set_modal_overlay(
|
|
SelectionDialog(tr("SLC Primary Priority"), primary_options, current_primary, on_close=on_primary_select)
|
|
)
|
|
|
|
def _show_selection(self, key, options):
|
|
def on_select(res, val):
|
|
if res == DialogResult.CONFIRM:
|
|
self._params.put(key, val)
|
|
self._rebuild_grid()
|
|
|
|
gui_app.set_modal_overlay(SelectionDialog(tr(key), options, self._params.get(key, encoding='utf-8') or "None", on_close=on_select))
|
|
|
|
|
|
class StarPilotSLCOffsetsLayout(StarPilotPanel):
|
|
def __init__(self):
|
|
super().__init__()
|
|
self.CATEGORIES = []
|
|
for i in range(1, 8):
|
|
key = f"Offset{i}"
|
|
self.CATEGORIES.append(
|
|
{
|
|
"title": tr_noop(f"Offset {i}"),
|
|
"type": "value",
|
|
"get_value": lambda k=key: f"{self._params.get_int(k)} mph",
|
|
"on_click": lambda k=key: self._show_speed_selector(k),
|
|
"color": "#597497",
|
|
}
|
|
)
|
|
self._rebuild_grid()
|
|
|
|
def _show_speed_selector(self, key):
|
|
def on_close(res, val):
|
|
if res == DialogResult.CONFIRM:
|
|
self._params.put_int(key, int(val))
|
|
self._rebuild_grid()
|
|
|
|
gui_app.set_modal_overlay(AetherSliderDialog(tr(key), -99, 100, 1, self._params.get_int(key), on_close, unit=" mph", color="#597497"))
|
|
|
|
|
|
class StarPilotSLCQOLLayout(StarPilotPanel):
|
|
def __init__(self):
|
|
super().__init__()
|
|
self.CATEGORIES = [
|
|
{
|
|
"title": tr_noop("Match Speed on Engage"),
|
|
"type": "toggle",
|
|
"get_state": lambda: self._params.get_bool("SetSpeedLimit"),
|
|
"set_state": lambda s: self._params.put_bool("SetSpeedLimit", s),
|
|
"color": "#597497",
|
|
},
|
|
{
|
|
"title": tr_noop("Confirm New Limits"),
|
|
"type": "toggle",
|
|
"get_state": lambda: self._params.get_bool("SLCConfirmation"),
|
|
"set_state": lambda s: self._params.put_bool("SLCConfirmation", s),
|
|
"color": "#597497",
|
|
},
|
|
{
|
|
"title": tr_noop("Confirm Lower"),
|
|
"type": "toggle",
|
|
"get_state": lambda: self._params.get_bool("SLCConfirmationLower"),
|
|
"set_state": lambda s: self._params.put_bool("SLCConfirmationLower", s),
|
|
"visible": lambda: self._params.get_bool("SLCConfirmation"),
|
|
"color": "#597497",
|
|
},
|
|
{
|
|
"title": tr_noop("Confirm Higher"),
|
|
"type": "toggle",
|
|
"get_state": lambda: self._params.get_bool("SLCConfirmationHigher"),
|
|
"set_state": lambda s: self._params.put_bool("SLCConfirmationHigher", s),
|
|
"visible": lambda: self._params.get_bool("SLCConfirmation"),
|
|
"color": "#597497",
|
|
},
|
|
{
|
|
"title": tr_noop("Higher Lookahead"),
|
|
"type": "value",
|
|
"get_value": lambda: f"{self._params.get_int('SLCLookaheadHigher')}s",
|
|
"on_click": lambda: self._show_int_selector("SLCLookaheadHigher", 0, 30, "s"),
|
|
"color": "#597497",
|
|
},
|
|
{
|
|
"title": tr_noop("Lower Lookahead"),
|
|
"type": "value",
|
|
"get_value": lambda: f"{self._params.get_int('SLCLookaheadLower')}s",
|
|
"on_click": lambda: self._show_int_selector("SLCLookaheadLower", 0, 30, "s"),
|
|
"color": "#597497",
|
|
},
|
|
{
|
|
"title": tr_noop("Mapbox Fallback"),
|
|
"type": "toggle",
|
|
"get_state": lambda: self._params.get_bool("SLCMapboxFiller"),
|
|
"set_state": lambda s: self._params.put_bool("SLCMapboxFiller", s),
|
|
"color": "#597497",
|
|
},
|
|
]
|
|
self._rebuild_grid()
|
|
|
|
def _show_int_selector(self, key, min_v, max_v, unit=""):
|
|
def on_close(res, val):
|
|
if res == DialogResult.CONFIRM:
|
|
self._params.put_int(key, int(val))
|
|
self._rebuild_grid()
|
|
|
|
gui_app.set_modal_overlay(AetherSliderDialog(tr(key), min_v, max_v, 1, self._params.get_int(key), on_close, unit=unit, color="#597497"))
|
|
|
|
|
|
class StarPilotSLCVisualsLayout(StarPilotPanel):
|
|
def __init__(self):
|
|
super().__init__()
|
|
self.CATEGORIES = [
|
|
{
|
|
"title": tr_noop("Show SLC Offset"),
|
|
"type": "toggle",
|
|
"get_state": lambda: self._params.get_bool("ShowSLCOffset"),
|
|
"set_state": lambda s: self._params.put_bool("ShowSLCOffset", s),
|
|
"color": "#597497",
|
|
},
|
|
{
|
|
"title": tr_noop("Show Sources"),
|
|
"type": "toggle",
|
|
"get_state": lambda: self._params.get_bool("SpeedLimitSources"),
|
|
"set_state": lambda s: self._params.put_bool("SpeedLimitSources", s),
|
|
"color": "#597497",
|
|
},
|
|
]
|
|
self._rebuild_grid()
|
|
|
|
|
|
class StarPilotWeatherLayout(StarPilotPanel):
|
|
def __init__(self):
|
|
super().__init__()
|
|
self.CATEGORIES = [
|
|
{"title": tr_noop("Low Visibility"), "panel": "low_visibility", "icon": "toggle_icons/icon_rainbow.png", "color": "#597497"},
|
|
{"title": tr_noop("Rain"), "panel": "rain", "icon": "toggle_icons/icon_rainbow.png", "color": "#597497"},
|
|
{"title": tr_noop("Rainstorms"), "panel": "rainstorm", "icon": "toggle_icons/icon_rainbow.png", "color": "#597497"},
|
|
{"title": tr_noop("Snow"), "panel": "snow", "icon": "toggle_icons/icon_rainbow.png", "color": "#597497"},
|
|
{
|
|
"title": tr_noop("Set Weather Key"),
|
|
"type": "hub",
|
|
"on_click": lambda: self._set_weather_key(),
|
|
"color": "#597497",
|
|
},
|
|
]
|
|
self._rebuild_grid()
|
|
|
|
def _set_weather_key(self):
|
|
options = ["ADD", "REMOVE"]
|
|
|
|
def on_select(res, val):
|
|
if res == DialogResult.CONFIRM:
|
|
if val == "ADD":
|
|
|
|
def on_key(res, text):
|
|
if res == DialogResult.CONFIRM:
|
|
self._params.put("WeatherAPIKey", text)
|
|
self._rebuild_grid()
|
|
|
|
gui_app.set_modal_overlay(InputDialog(tr("Weather API Key"), on_close=on_key))
|
|
elif val == "REMOVE":
|
|
|
|
def on_confirm(res):
|
|
if res == DialogResult.CONFIRM:
|
|
self._params.remove("WeatherAPIKey")
|
|
self._rebuild_grid()
|
|
|
|
gui_app.set_modal_overlay(ConfirmDialog(tr("Remove API Key?"), tr("Confirm"), on_close=on_confirm))
|
|
|
|
gui_app.set_modal_overlay(SelectionDialog(tr("Weather API Key"), options, "ADD", on_close=on_select))
|
|
|
|
|
|
class StarPilotWeatherBase(StarPilotPanel):
|
|
def __init__(self, suffix: str):
|
|
super().__init__()
|
|
self._suffix = suffix
|
|
self.CATEGORIES = [
|
|
{
|
|
"title": tr_noop("Following Distance"),
|
|
"type": "value",
|
|
"get_value": lambda: f"+{self._params.get_int('IncreaseFollowing' + self._suffix)}s",
|
|
"on_click": lambda: self._show_value_selector("IncreaseFollowing" + self._suffix, 0, 3, 0.5, "s"),
|
|
"icon": "toggle_icons/icon_longitudinal_tune.png",
|
|
"color": "#597497",
|
|
},
|
|
{
|
|
"title": tr_noop("Stopped Distance"),
|
|
"type": "value",
|
|
"get_value": lambda: f"+{self._params.get_int('IncreasedStoppedDistance' + self._suffix)} ft",
|
|
"on_click": lambda: self._show_value_selector("IncreasedStoppedDistance" + self._suffix, 0, 10, 1, " ft"),
|
|
"icon": "toggle_icons/icon_longitudinal_tune.png",
|
|
"color": "#597497",
|
|
},
|
|
{
|
|
"title": tr_noop("Reduce Accel"),
|
|
"type": "value",
|
|
"get_value": lambda: f"{self._params.get_int('ReduceAcceleration' + self._suffix)}%",
|
|
"on_click": lambda: self._show_value_selector("ReduceAcceleration" + self._suffix, 0, 99, 1, "%"),
|
|
"icon": "toggle_icons/icon_longitudinal_tune.png",
|
|
"color": "#597497",
|
|
},
|
|
{
|
|
"title": tr_noop("Reduce Curve Speed"),
|
|
"type": "value",
|
|
"get_value": lambda: f"{self._params.get_int('ReduceLateralAcceleration' + self._suffix)}%",
|
|
"on_click": lambda: self._show_value_selector("ReduceLateralAcceleration" + self._suffix, 0, 99, 1, "%"),
|
|
"icon": "toggle_icons/icon_longitudinal_tune.png",
|
|
"color": "#597497",
|
|
},
|
|
]
|
|
self._rebuild_grid()
|
|
|
|
def _show_value_selector(self, key, min_v, max_v, step, unit=""):
|
|
def on_close(res, val):
|
|
if res == DialogResult.CONFIRM:
|
|
self._params.put_int(key, int(float(val)))
|
|
self._rebuild_grid()
|
|
|
|
curr = self._params.get_int(key)
|
|
gui_app.set_modal_overlay(AetherSliderDialog(tr(key), min_v, max_v, step, curr, on_close, unit=unit, color="#597497"))
|