custom accel and screen timeout

This commit is contained in:
firestar5683
2026-04-04 19:12:45 -05:00
parent 5f1e0eeb3a
commit 4ebe5a277a
49 changed files with 424 additions and 117 deletions
@@ -6,6 +6,7 @@ const endpointOptionsInflight = {}
// Plain variables — scheduling/routing flags that must NOT be reactive
let syncScheduled = false
let lastParams = null
const DYNAMIC_DEFAULT_DEP_KEYS = new Set(["AccelerationProfile", "EVTuning", "TruckTuning"])
// Module-level state (persists across route changes)
const state = reactive({
@@ -141,6 +142,21 @@ async function fetchDefaultValues() {
}
}
async function refreshParamsAndDefaults() {
await fetchDefaultValues()
try {
const valuesRes = await fetch("/api/params/all")
if (valuesRes.ok) {
const data = await valuesRes.json()
state.values = data || {}
}
} catch (e) {
console.error("Failed to refresh param values:", e)
}
scheduleSyncInputs()
}
async function fetchLayoutAndParams() {
state.loadingLayout = true
state.loadingValues = true
@@ -176,14 +192,13 @@ async function fetchLayoutAndParams() {
// Pull params once at page load; local state handles subsequent edits.
try {
const valuesRes = await fetch("/api/params/all")
const data = await valuesRes.json()
state.values = data
if (!(await fetchDefaultValues())) {
state.defaultValues = {}
}
const valuesRes = await fetch("/api/params/all")
const data = await valuesRes.json()
state.values = data
} catch (e) {
console.error("Failed to fetch param values:", e)
state.defaultValues = {}
@@ -520,7 +535,11 @@ async function updateParam(key, elType) {
const updated = (data.updated && typeof data.updated === "object") ? data.updated : {}
state.values = { ...state.values, [key]: formattedVal, ...updated }
showParamSnackbar(data.message || `Parameter '${key}' updated.`)
scheduleSyncInputs()
if (DYNAMIC_DEFAULT_DEP_KEYS.has(key)) {
await refreshParamsAndDefaults()
} else {
scheduleSyncInputs()
}
} else {
revertInput(key, current, elType)
showParamSnackbar(data.error || "Failed to update parameter", "error")
@@ -254,6 +254,99 @@
"ui_type": "toggle",
"parent_key": "AdvancedLongitudinalTune"
},
{
"key": "CustomAccelProfile",
"label": "Custom Accel Profile",
"description": "Replace the built-in acceleration profile with your own per-speed max-acceleration values. Breakpoint speeds stay fixed, and the starting defaults mirror the currently selected acceleration profile plus EV or Truck tuning.",
"data_type": "bool",
"ui_type": "toggle",
"is_parent_toggle": true,
"parent_key": "AdvancedLongitudinalTune"
},
{
"key": "CustomAccelProfile0MPH",
"label": "0 mph",
"description": "Max acceleration in m/s² at the fixed 0 mph breakpoint.",
"data_type": "float",
"ui_type": "numeric",
"min": 0.0,
"max": 6.0,
"step": 0.01,
"precision": 2,
"parent_key": "CustomAccelProfile"
},
{
"key": "CustomAccelProfile11MPH",
"label": "11 mph",
"description": "Max acceleration in m/s² at the fixed 11 mph breakpoint.",
"data_type": "float",
"ui_type": "numeric",
"min": 0.0,
"max": 6.0,
"step": 0.01,
"precision": 2,
"parent_key": "CustomAccelProfile"
},
{
"key": "CustomAccelProfile22MPH",
"label": "22 mph",
"description": "Max acceleration in m/s² at the fixed 22 mph breakpoint.",
"data_type": "float",
"ui_type": "numeric",
"min": 0.0,
"max": 6.0,
"step": 0.01,
"precision": 2,
"parent_key": "CustomAccelProfile"
},
{
"key": "CustomAccelProfile34MPH",
"label": "34 mph",
"description": "Max acceleration in m/s² at the fixed 34 mph breakpoint.",
"data_type": "float",
"ui_type": "numeric",
"min": 0.0,
"max": 6.0,
"step": 0.01,
"precision": 2,
"parent_key": "CustomAccelProfile"
},
{
"key": "CustomAccelProfile45MPH",
"label": "45 mph",
"description": "Max acceleration in m/s² at the fixed 45 mph breakpoint.",
"data_type": "float",
"ui_type": "numeric",
"min": 0.0,
"max": 6.0,
"step": 0.01,
"precision": 2,
"parent_key": "CustomAccelProfile"
},
{
"key": "CustomAccelProfile56MPH",
"label": "56 mph",
"description": "Max acceleration in m/s² at the fixed 56 mph breakpoint.",
"data_type": "float",
"ui_type": "numeric",
"min": 0.0,
"max": 6.0,
"step": 0.01,
"precision": 2,
"parent_key": "CustomAccelProfile"
},
{
"key": "CustomAccelProfile89MPH",
"label": "89 mph",
"description": "Max acceleration in m/s² at the fixed 89 mph breakpoint.",
"data_type": "float",
"ui_type": "numeric",
"min": 0.0,
"max": 6.0,
"step": 0.01,
"precision": 2,
"parent_key": "CustomAccelProfile"
},
{
"key": "LongitudinalActuatorDelay",
"label": "Actuator Delay",
+83 -47
View File
@@ -41,6 +41,11 @@ from openpilot.system.version import get_build_metadata
from panda import Panda
from openpilot.starpilot.assets.theme_manager import HOLIDAY_THEME_PATH, THEME_COMPONENT_PARAMS
from openpilot.starpilot.common.accel_profile import (
CUSTOM_ACCEL_PROFILE_PARAM_KEYS,
build_custom_accel_profile_defaults,
normalize_acceleration_profile,
)
from openpilot.starpilot.common.maps_catalog import (
MAPS_CATALOG,
MAP_SCHEDULE_OPTIONS,
@@ -629,6 +634,8 @@ _TROUBLESHOOT_ADVANCED_LONGITUDINAL_KEYS = [
"AdvancedLongitudinalTune",
"EVTuning",
"TruckTuning",
"CustomAccelProfile",
*CUSTOM_ACCEL_PROFILE_PARAM_KEYS,
"LongitudinalActuatorDelay",
"StartAccel",
"VEgoStarting",
@@ -1663,6 +1670,7 @@ def _get_layout_type_overrides():
_cached_allowed_keys = None
_cached_param_types = None
_cached_default_values = None
_cached_static_default_values = None
def _get_param_type_info():
global _cached_allowed_keys, _cached_param_types
@@ -1699,15 +1707,18 @@ def _get_param_type_info():
_cached_param_types = types
return _cached_allowed_keys, _cached_param_types
def _get_default_param_values():
global _cached_default_values
if _cached_default_values is None:
_cached_default_values = {
def _get_static_default_param_values():
global _cached_static_default_values
if _cached_static_default_values is None:
_cached_static_default_values = {
key: default_val
for key, default_val, _, _ in starpilot_default_params
if key not in EXCLUDED_KEYS
}
default_values = dict(_cached_default_values)
return _cached_static_default_values
def _get_default_param_values():
default_values = dict(_get_static_default_param_values())
default_values.update(_get_runtime_default_param_overrides())
return default_values
@@ -1790,6 +1801,7 @@ def _has_runtime_default_value(key, raw_value):
def _get_runtime_default_param_overrides():
overrides = {}
static_defaults = _get_static_default_param_values()
for key, stock_key in _RUNTIME_DEFAULT_STOCK_KEYS.items():
stock_raw = _safe_params_get_live_raw(stock_key)
@@ -1798,40 +1810,60 @@ def _get_runtime_default_param_overrides():
overrides[stock_key] = stock_raw
cp_bytes = _safe_params_get_live_raw("CarParamsPersistent")
if not cp_bytes:
return overrides
if cp_bytes:
try:
with car.CarParams.from_bytes(cp_bytes) as cp:
overrides["EVTuning"] = default_ev_tuning_enabled(cp)
try:
with car.CarParams.from_bytes(cp_bytes) as cp:
overrides["EVTuning"] = default_ev_tuning_enabled(cp)
car_param_defaults = {
"SteerDelay": getattr(cp, "steerActuatorDelay", None),
"SteerRatio": getattr(cp, "steerRatio", None),
"LongitudinalActuatorDelay": getattr(cp, "longitudinalActuatorDelay", None),
"StartAccel": getattr(cp, "startAccel", None),
"StopAccel": getattr(cp, "stopAccel", None),
"StoppingDecelRate": getattr(cp, "stoppingDecelRate", None),
"VEgoStarting": getattr(cp, "vEgoStarting", None),
"VEgoStopping": getattr(cp, "vEgoStopping", None),
}
car_param_defaults = {
"SteerDelay": getattr(cp, "steerActuatorDelay", None),
"SteerRatio": getattr(cp, "steerRatio", None),
"LongitudinalActuatorDelay": getattr(cp, "longitudinalActuatorDelay", None),
"StartAccel": getattr(cp, "startAccel", None),
"StopAccel": getattr(cp, "stopAccel", None),
"StoppingDecelRate": getattr(cp, "stoppingDecelRate", None),
"VEgoStarting": getattr(cp, "vEgoStarting", None),
"VEgoStopping": getattr(cp, "vEgoStopping", None),
}
for key, value in car_param_defaults.items():
if key in overrides or value is None:
continue
if key not in _RUNTIME_DEFAULT_ZERO_OK_KEYS and float(value) == 0.0:
continue
overrides[key] = value
except Exception:
pass
for key, value in car_param_defaults.items():
if key in overrides or value is None:
continue
if key not in _RUNTIME_DEFAULT_ZERO_OK_KEYS and float(value) == 0.0:
continue
overrides[key] = value
except Exception:
pass
ev_tuning_raw = _safe_params_get_live_raw("EVTuning")
truck_tuning_raw = _safe_params_get_live_raw("TruckTuning")
acceleration_profile_raw = _safe_params_get_live_raw("AccelerationProfile")
ev_tuning = _coerce_param_value(
ev_tuning_raw if not _is_blank_param_raw(ev_tuning_raw) else overrides.get("EVTuning", static_defaults.get("EVTuning", "0")),
bool,
)
truck_tuning = _coerce_param_value(
truck_tuning_raw if not _is_blank_param_raw(truck_tuning_raw) else static_defaults.get("TruckTuning", "0"),
bool,
)
if truck_tuning:
ev_tuning = False
acceleration_profile = normalize_acceleration_profile(
acceleration_profile_raw if not _is_blank_param_raw(acceleration_profile_raw) else static_defaults.get("AccelerationProfile", "0")
)
overrides.update(build_custom_accel_profile_defaults(acceleration_profile, ev_tuning, truck_tuning))
return overrides
def _get_current_param_value(key, value_type):
safe_type = value_type or str
if safe_type == bool:
return params.get_bool(key)
return _coerce_param_value(params.get(key), safe_type)
def _get_current_param_value(key, value_type, defaults_lookup=None):
raw_value = _safe_params_get_live_raw(key)
if _is_blank_param_raw(raw_value):
if defaults_lookup is None:
defaults_lookup = _get_default_param_values()
raw_value = defaults_lookup.get(key)
return _coerce_param_value(raw_value, value_type)
def _serialize_param_write_value(raw_value):
if isinstance(raw_value, bool):
@@ -3108,6 +3140,22 @@ def setup(app):
if key == "AutomaticUpdates" and params.get_bool("IsOnroad"):
return jsonify({"error": "Cannot change Automatic Updates while driving."}), 403
if key in {"EVTuning", "TruckTuning"}:
enabled = str_val.strip() in ("1", "true", "True")
params.put_bool(key, enabled)
updated = {key: enabled}
if enabled:
other_key = "TruckTuning" if key == "EVTuning" else "EVTuning"
params.put_bool(other_key, False)
updated[other_key] = False
update_starpilot_toggles()
return jsonify({
"message": f"Parameter '{key}' updated successfully.",
"updated": updated,
}), 200
if key == "CarMake":
catalog = _get_fingerprint_catalog()
normalized_make = _normalize_fingerprint_make_key(str_val)
@@ -3225,25 +3273,13 @@ def setup(app):
def get_all_params():
_enforce_cancel_remap_lkas_lock()
allowed_keys, types = _get_param_type_info()
defaults_lookup = _get_default_param_values()
result = {}
for key in allowed_keys:
t = types.get(key, str)
try:
if t == bool:
result[key] = params.get_bool(key)
else:
raw = params.get(key)
raw_str = raw.decode("utf-8", errors="replace") if isinstance(raw, bytes) else str(raw or "")
if not raw_str:
result[key] = 0.0 if t == float else (0 if t == int else "")
elif t == float:
result[key] = float(raw_str)
elif t == int:
result[key] = int(float(raw_str))
else:
result[key] = raw_str
result[key] = _get_current_param_value(key, t, defaults_lookup)
except Exception:
result[key] = None