custom accel and screen timeout
This commit is contained in:
Binary file not shown.
@@ -199,6 +199,14 @@ inline static std::unordered_map<std::string, ParamKeyAttributes> keys = {
|
||||
{"CurvatureData", {PERSISTENT | DONT_LOG, JSON, "{}", "{}"}},
|
||||
{"CurveSpeedController", {PERSISTENT, BOOL, "1", "0", 1}},
|
||||
{"CustomAlerts", {PERSISTENT, BOOL, "0", "0", 0}},
|
||||
{"CustomAccelProfile", {PERSISTENT, BOOL, "0", "0", 3}},
|
||||
{"CustomAccelProfile0MPH", {PERSISTENT, FLOAT, "3.0", "3.0", 3}},
|
||||
{"CustomAccelProfile11MPH", {PERSISTENT, FLOAT, "2.5", "2.5", 3}},
|
||||
{"CustomAccelProfile22MPH", {PERSISTENT, FLOAT, "2.0", "2.0", 3}},
|
||||
{"CustomAccelProfile34MPH", {PERSISTENT, FLOAT, "1.5", "1.5", 3}},
|
||||
{"CustomAccelProfile45MPH", {PERSISTENT, FLOAT, "1.0", "1.0", 3}},
|
||||
{"CustomAccelProfile56MPH", {PERSISTENT, FLOAT, "0.8", "0.8", 3}},
|
||||
{"CustomAccelProfile89MPH", {PERSISTENT, FLOAT, "0.6", "0.6", 3}},
|
||||
{"CustomCruise", {PERSISTENT, FLOAT, "1.0", "1.0", 2}},
|
||||
{"CustomCruiseLong", {PERSISTENT, FLOAT, "5.0", "5.0", 2}},
|
||||
{"CustomPersonalities", {PERSISTENT, BOOL, "0", "0", 2}},
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,2 +1,2 @@
|
||||
extern const uint8_t gitversion[19];
|
||||
const uint8_t gitversion[19] = "DEV-a695eda0-DEBUG";
|
||||
const uint8_t gitversion[19] = "DEV-5f1e0eeb-DEBUG";
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1 +1 @@
|
||||
DEV-a695eda0-DEBUG
|
||||
DEV-5f1e0eeb-DEBUG
|
||||
Binary file not shown.
Binary file not shown.
+15
-9
@@ -237,20 +237,26 @@ void Device::updateBrightness(const UIState &s, const StarPilotUIState &fs) {
|
||||
void Device::updateWakefulness(const UIState &s, const StarPilotUIState &fs) {
|
||||
const StarPilotUIScene &starpilot_scene = fs.starpilot_scene;
|
||||
const QJsonObject &starpilot_toggles = starpilot_scene.starpilot_toggles;
|
||||
const bool standby_mode = starpilot_toggles.value("standby_mode").toBool();
|
||||
const int screen_timeout = starpilot_toggles.value("screen_timeout").toInt();
|
||||
const int screen_timeout_onroad = starpilot_toggles.value("screen_timeout_onroad").toInt();
|
||||
|
||||
bool ignition_just_turned_off = !s.scene.ignition && ignition_on;
|
||||
bool ignition_state_changed = s.scene.ignition != ignition_on;
|
||||
ignition_on = s.scene.ignition;
|
||||
|
||||
if (ignition_on && starpilot_toggles.value("standby_mode").toBool()) {
|
||||
if (starpilot_scene.wake_up_screen) {
|
||||
resetInteractiveTimeout(starpilot_toggles.value("screen_timeout").toInt(), starpilot_toggles.value("screen_timeout_onroad").toInt());
|
||||
} else {
|
||||
// Standby mode should extend the current wake window for alerts and status
|
||||
// changes, but it must not clear the timer every frame or manual wakes will
|
||||
// collapse immediately.
|
||||
if (ignition_on && standby_mode && starpilot_scene.wake_up_screen) {
|
||||
resetInteractiveTimeout(screen_timeout, screen_timeout_onroad);
|
||||
}
|
||||
|
||||
if (ignition_state_changed) {
|
||||
if (ignition_on && starpilot_toggles.value("screen_brightness_onroad").toInt() == 0 && !standby_mode) {
|
||||
resetInteractiveTimeout(0, 0);
|
||||
} else {
|
||||
resetInteractiveTimeout(screen_timeout, screen_timeout_onroad);
|
||||
}
|
||||
} else if (ignition_just_turned_off) {
|
||||
resetInteractiveTimeout(starpilot_toggles.value("screen_timeout").toInt(), starpilot_toggles.value("screen_timeout_onroad").toInt());
|
||||
} else if (ignition_on && starpilot_toggles.value("screen_brightness_onroad").toInt() == 0) {
|
||||
resetInteractiveTimeout(0, 0);
|
||||
} else if (interactive_timeout > 0 && --interactive_timeout == 0) {
|
||||
emit interactiveTimeout();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,143 @@
|
||||
#!/usr/bin/env python3
|
||||
from __future__ import annotations
|
||||
|
||||
from openpilot.selfdrive.controls.lib.longitudinal_planner import get_max_accel
|
||||
|
||||
ACCELERATION_PROFILES = {
|
||||
"STANDARD": 0,
|
||||
"ECO": 1,
|
||||
"SPORT": 2,
|
||||
"SPORT_PLUS": 3,
|
||||
}
|
||||
|
||||
DECELERATION_PROFILES = {
|
||||
"STANDARD": 0,
|
||||
"ECO": 1,
|
||||
"SPORT": 2,
|
||||
}
|
||||
|
||||
# MPH = [0.0, 11, 22, 34, 45, 56, 89]
|
||||
A_CRUISE_MAX_BP_CUSTOM = [0.0, 5.0, 10.0, 15.0, 20.0, 25.0, 40.0]
|
||||
|
||||
CUSTOM_ACCEL_PROFILE_PARAM_SPECS = [
|
||||
("CustomAccelProfile0MPH", 0),
|
||||
("CustomAccelProfile11MPH", 11),
|
||||
("CustomAccelProfile22MPH", 22),
|
||||
("CustomAccelProfile34MPH", 34),
|
||||
("CustomAccelProfile45MPH", 45),
|
||||
("CustomAccelProfile56MPH", 56),
|
||||
("CustomAccelProfile89MPH", 89),
|
||||
]
|
||||
CUSTOM_ACCEL_PROFILE_PARAM_KEYS = [key for key, _ in CUSTOM_ACCEL_PROFILE_PARAM_SPECS]
|
||||
CUSTOM_ACCEL_PROFILE_VALUE_MIN = 0.0
|
||||
CUSTOM_ACCEL_PROFILE_VALUE_MAX = 6.0
|
||||
|
||||
A_CRUISE_MAX_VALS_ECO_EV = [1.25, 1.25, 1.25, 1.25, 1.45, 1.50, 2.00]
|
||||
A_CRUISE_MAX_VALS_STANDARD_EV = [1.35, 1.35, 1.35, 1.35, 1.60, 1.60, 2.10]
|
||||
A_CRUISE_MAX_VALS_SPORT_EV = [1.55, 1.55, 1.55, 1.55, 1.84, 1.84, 2.42]
|
||||
A_CRUISE_MAX_VALS_SPORT_PLUS_EV = [1.7825, 1.7825, 1.7825, 1.7825, 2.116, 2.116, 2.783]
|
||||
A_CRUISE_MAX_VALS_ECO_GAS = [2.0, 1.5, 1.0, 0.8, 0.6, 0.4, 0.2]
|
||||
A_CRUISE_MAX_VALS_SPORT_GAS = [3.0, 2.5, 2.0, 1.5, 1.0, 0.8, 0.6]
|
||||
A_CRUISE_MAX_VALS_ECO_TRUCK = [3.00, 1.05, 0.60, 0.50, 0.50, 0.45, 0.35]
|
||||
A_CRUISE_MAX_VALS_STANDARD_TRUCK = [6.00, 1.10, 0.70, 0.60, 0.55, 0.45, 0.35]
|
||||
A_CRUISE_MAX_VALS_SPORT_TRUCK = [6.00, 1.15, 0.75, 0.70, 0.60, 0.50, 0.40]
|
||||
A_CRUISE_MAX_VALS_SPORT_PLUS_TRUCK = [6.00, 1.30, 0.90, 0.80, 0.70, 0.60, 0.45]
|
||||
|
||||
|
||||
def akima_interp(x, xp, fp):
|
||||
if x <= xp[0]:
|
||||
return fp[0]
|
||||
if x >= xp[-1]:
|
||||
return fp[-1]
|
||||
|
||||
i = max(0, min(len(xp) - 2, int(next(idx for idx, bp in enumerate(xp[1:], start=1) if bp >= x) - 1)))
|
||||
t = (x - xp[i]) / float(xp[i + 1] - xp[i])
|
||||
t2 = t * t
|
||||
t3 = t2 * t
|
||||
t4 = t2 * t2
|
||||
return (fp[i] * (1 - 10 * t3 + 15 * t4 - 6 * t3 * t2)
|
||||
+ fp[i + 1] * (10 * t3 - 15 * t4 + 6 * t3 * t2))
|
||||
|
||||
|
||||
def normalize_acceleration_profile(value):
|
||||
return _normalize_profile(value, ACCELERATION_PROFILES, ACCELERATION_PROFILES["STANDARD"])
|
||||
|
||||
|
||||
def normalize_deceleration_profile(value):
|
||||
return _normalize_profile(value, DECELERATION_PROFILES, DECELERATION_PROFILES["STANDARD"])
|
||||
|
||||
|
||||
def get_accel_profile_curve_values(acceleration_profile, ev_tuning=True, truck_tuning=False):
|
||||
profile = normalize_acceleration_profile(acceleration_profile)
|
||||
if truck_tuning:
|
||||
ev_tuning = False
|
||||
|
||||
if profile == ACCELERATION_PROFILES["ECO"]:
|
||||
if ev_tuning:
|
||||
return list(A_CRUISE_MAX_VALS_ECO_EV)
|
||||
if truck_tuning:
|
||||
return list(A_CRUISE_MAX_VALS_ECO_TRUCK)
|
||||
return list(A_CRUISE_MAX_VALS_ECO_GAS)
|
||||
|
||||
if profile == ACCELERATION_PROFILES["SPORT"]:
|
||||
if ev_tuning:
|
||||
return list(A_CRUISE_MAX_VALS_SPORT_EV)
|
||||
if truck_tuning:
|
||||
return list(A_CRUISE_MAX_VALS_SPORT_TRUCK)
|
||||
return list(A_CRUISE_MAX_VALS_SPORT_GAS)
|
||||
|
||||
if profile == ACCELERATION_PROFILES["SPORT_PLUS"]:
|
||||
if ev_tuning:
|
||||
return list(A_CRUISE_MAX_VALS_SPORT_PLUS_EV)
|
||||
if truck_tuning:
|
||||
return list(A_CRUISE_MAX_VALS_SPORT_PLUS_TRUCK)
|
||||
return [float(akima_interp(v_ego, [0.0, 5.0, 20.0], [4.0, 4.0, 2.0])) for v_ego in A_CRUISE_MAX_BP_CUSTOM]
|
||||
|
||||
if ev_tuning:
|
||||
return list(A_CRUISE_MAX_VALS_STANDARD_EV)
|
||||
if truck_tuning:
|
||||
return list(A_CRUISE_MAX_VALS_STANDARD_TRUCK)
|
||||
return [float(get_max_accel(v_ego)) for v_ego in A_CRUISE_MAX_BP_CUSTOM]
|
||||
|
||||
|
||||
def interpolate_accel_profile(v_ego, curve_values):
|
||||
return float(akima_interp(v_ego, A_CRUISE_MAX_BP_CUSTOM, curve_values))
|
||||
|
||||
|
||||
def get_max_allowed_accel(v_ego, ev_tuning=True, truck_tuning=False):
|
||||
return interpolate_accel_profile(v_ego, get_accel_profile_curve_values(ACCELERATION_PROFILES["SPORT_PLUS"], ev_tuning, truck_tuning))
|
||||
|
||||
|
||||
def build_custom_accel_profile_defaults(acceleration_profile, ev_tuning=True, truck_tuning=False):
|
||||
curve_values = get_accel_profile_curve_values(acceleration_profile, ev_tuning, truck_tuning)
|
||||
return {
|
||||
key: float(curve_values[idx])
|
||||
for idx, key in enumerate(CUSTOM_ACCEL_PROFILE_PARAM_KEYS)
|
||||
}
|
||||
|
||||
|
||||
def coerce_custom_accel_profile_values(raw_values, acceleration_profile, ev_tuning=True, truck_tuning=False):
|
||||
defaults = get_accel_profile_curve_values(acceleration_profile, ev_tuning, truck_tuning)
|
||||
values = []
|
||||
for idx, default in enumerate(defaults):
|
||||
try:
|
||||
value = float(raw_values[idx])
|
||||
except (IndexError, TypeError, ValueError):
|
||||
value = default
|
||||
values.append(min(CUSTOM_ACCEL_PROFILE_VALUE_MAX, max(CUSTOM_ACCEL_PROFILE_VALUE_MIN, value)))
|
||||
return values
|
||||
|
||||
|
||||
def _normalize_profile(value, profile_map, fallback):
|
||||
if isinstance(value, bytes):
|
||||
value = value.decode("utf-8", errors="replace")
|
||||
|
||||
if isinstance(value, str):
|
||||
normalized = value.strip().upper().replace("+", "_PLUS").replace(" ", "_")
|
||||
if normalized in profile_map:
|
||||
return profile_map[normalized]
|
||||
|
||||
try:
|
||||
return int(float(value))
|
||||
except (TypeError, ValueError):
|
||||
return fallback
|
||||
@@ -48,6 +48,14 @@ SAFE_MODE_MANAGED_KEYS = (
|
||||
"AdvancedLongitudinalTune",
|
||||
"EVTuning",
|
||||
"TruckTuning",
|
||||
"CustomAccelProfile",
|
||||
"CustomAccelProfile0MPH",
|
||||
"CustomAccelProfile11MPH",
|
||||
"CustomAccelProfile22MPH",
|
||||
"CustomAccelProfile34MPH",
|
||||
"CustomAccelProfile45MPH",
|
||||
"CustomAccelProfile56MPH",
|
||||
"CustomAccelProfile89MPH",
|
||||
"LongitudinalActuatorDelay",
|
||||
"MaxDesiredAcceleration",
|
||||
"StartAccel",
|
||||
|
||||
@@ -10,6 +10,7 @@ from pathlib import Path
|
||||
from types import SimpleNamespace
|
||||
|
||||
import cereal.messaging as messaging
|
||||
import numpy as np
|
||||
|
||||
from cereal import car, custom, log
|
||||
from opendbc.car import gen_empty_fingerprint
|
||||
@@ -25,6 +26,16 @@ from openpilot.common.constants import CV
|
||||
from openpilot.common.params import Params
|
||||
from openpilot.selfdrive.controls.lib.latcontrol_torque import KP
|
||||
from openpilot.selfdrive.modeld.constants import ModelConstants
|
||||
from openpilot.starpilot.common.accel_profile import (
|
||||
ACCELERATION_PROFILES,
|
||||
CUSTOM_ACCEL_PROFILE_PARAM_KEYS,
|
||||
CUSTOM_ACCEL_PROFILE_VALUE_MAX,
|
||||
CUSTOM_ACCEL_PROFILE_VALUE_MIN,
|
||||
DECELERATION_PROFILES,
|
||||
build_custom_accel_profile_defaults,
|
||||
normalize_acceleration_profile,
|
||||
normalize_deceleration_profile,
|
||||
)
|
||||
from openpilot.system.hardware import HARDWARE
|
||||
from openpilot.system.hardware.hw import Paths
|
||||
from openpilot.system.hardware.power_monitoring import VBATT_PAUSE_CHARGING
|
||||
@@ -787,8 +798,19 @@ class StarPilotVariables:
|
||||
toggle.lock_doors_timer = self.get_value("LockDoorsTimer", cast=float, condition=(toggle.car_make == "toyota"))
|
||||
|
||||
longitudinal_tuning = toggle.openpilot_longitudinal and self.get_value("LongitudinalTune")
|
||||
toggle.acceleration_profile = self.get_value("AccelerationProfile", cast=float, condition=longitudinal_tuning)
|
||||
toggle.deceleration_profile = self.get_value("DecelerationProfile", cast=float, condition=longitudinal_tuning)
|
||||
toggle.acceleration_profile = normalize_acceleration_profile(
|
||||
self.get_value("AccelerationProfile", cast=None, condition=longitudinal_tuning, default=ACCELERATION_PROFILES["SPORT"])
|
||||
)
|
||||
toggle.deceleration_profile = normalize_deceleration_profile(
|
||||
self.get_value("DecelerationProfile", cast=None, condition=longitudinal_tuning, default=DECELERATION_PROFILES["ECO"])
|
||||
)
|
||||
toggle.custom_accel_profile = self.get_value("CustomAccelProfile", condition=longitudinal_tuning)
|
||||
custom_accel_defaults = build_custom_accel_profile_defaults(toggle.acceleration_profile, toggle.ev_tuning, toggle.truck_tuning)
|
||||
toggle.custom_accel_profile_values = [
|
||||
self.get_value(key, cast=float, condition=longitudinal_tuning, default=custom_accel_defaults[key],
|
||||
min=CUSTOM_ACCEL_PROFILE_VALUE_MIN, max=CUSTOM_ACCEL_PROFILE_VALUE_MAX)
|
||||
for key in CUSTOM_ACCEL_PROFILE_PARAM_KEYS
|
||||
]
|
||||
toggle.human_acceleration = self.get_value("HumanAcceleration", condition=longitudinal_tuning)
|
||||
toggle.human_following = self.get_value("HumanFollowing", condition=longitudinal_tuning)
|
||||
toggle.human_lane_changes = has_radar and self.get_value("HumanLaneChanges", condition=longitudinal_tuning)
|
||||
|
||||
@@ -3,6 +3,14 @@ import numpy as np
|
||||
|
||||
from openpilot.selfdrive.controls.lib.longitudinal_planner import A_CRUISE_MIN, get_max_accel
|
||||
|
||||
from openpilot.starpilot.common.accel_profile import (
|
||||
ACCELERATION_PROFILES,
|
||||
DECELERATION_PROFILES,
|
||||
coerce_custom_accel_profile_values,
|
||||
get_accel_profile_curve_values,
|
||||
get_max_allowed_accel as get_profile_max_allowed_accel,
|
||||
interpolate_accel_profile,
|
||||
)
|
||||
from openpilot.starpilot.common.starpilot_variables import CITY_SPEED_LIMIT
|
||||
|
||||
def cubic_interp(x, xp, fp):
|
||||
@@ -45,56 +53,20 @@ def akima_interp(x, xp, fp):
|
||||
A_CRUISE_MIN_ECO = A_CRUISE_MIN / 2
|
||||
A_CRUISE_MIN_SPORT = A_CRUISE_MIN * 2
|
||||
|
||||
# MPH = [0.0, 11, 22, 34, 45, 56, 89]
|
||||
A_CRUISE_MAX_BP_CUSTOM = [0.0, 5., 10., 15., 20., 25., 40.]
|
||||
A_CRUISE_MAX_VALS_ECO_EV = [1.25, 1.25, 1.25, 1.25, 1.45, 1.50, 2.00]
|
||||
A_CRUISE_MAX_VALS_STANDARD_EV = [1.35, 1.35, 1.35, 1.35, 1.60, 1.60, 2.10]
|
||||
A_CRUISE_MAX_VALS_SPORT_EV = [1.55, 1.55, 1.55, 1.55, 1.84, 1.84, 2.42]
|
||||
A_CRUISE_MAX_VALS_SPORT_PLUS_EV = [1.7825, 1.7825, 1.7825, 1.7825, 2.116, 2.116, 2.783]
|
||||
A_CRUISE_MAX_VALS_ECO_GAS = [2.0, 1.5, 1.0, 0.8, 0.6, 0.4, 0.2]
|
||||
A_CRUISE_MAX_VALS_SPORT_GAS = [3.0, 2.5, 2.0, 1.5, 1.0, 0.8, 0.6]
|
||||
A_CRUISE_MAX_VALS_ECO_TRUCK = [3.00, 1.05, 0.60, 0.50, 0.50, 0.45, 0.35]
|
||||
A_CRUISE_MAX_VALS_STANDARD_TRUCK = [6.00, 1.10, 0.70, 0.60, 0.55, 0.45, 0.35]
|
||||
A_CRUISE_MAX_VALS_SPORT_TRUCK = [6.00, 1.15, 0.75, 0.70, 0.60, 0.50, 0.40]
|
||||
A_CRUISE_MAX_VALS_SPORT_PLUS_TRUCK = [6.00, 1.30, 0.90, 0.80, 0.70, 0.60, 0.45]
|
||||
|
||||
ACCELERATION_PROFILES = {
|
||||
"STANDARD": 0,
|
||||
"ECO": 1,
|
||||
"SPORT": 2,
|
||||
"SPORT_PLUS": 3
|
||||
}
|
||||
|
||||
DECELERATION_PROFILES = {
|
||||
"STANDARD": 0,
|
||||
"ECO": 1,
|
||||
"SPORT": 2
|
||||
}
|
||||
|
||||
def get_max_accel_eco(v_ego, ev_tuning=True, truck_tuning=False):
|
||||
if ev_tuning:
|
||||
cruise_vals = A_CRUISE_MAX_VALS_ECO_EV
|
||||
elif truck_tuning:
|
||||
cruise_vals = A_CRUISE_MAX_VALS_ECO_TRUCK
|
||||
else:
|
||||
cruise_vals = A_CRUISE_MAX_VALS_ECO_GAS
|
||||
return float(akima_interp(v_ego, A_CRUISE_MAX_BP_CUSTOM, cruise_vals))
|
||||
return interpolate_accel_profile(v_ego, get_accel_profile_curve_values(ACCELERATION_PROFILES["ECO"], ev_tuning, truck_tuning))
|
||||
|
||||
def get_max_accel_sport(v_ego, ev_tuning=True, truck_tuning=False):
|
||||
if ev_tuning:
|
||||
cruise_vals = A_CRUISE_MAX_VALS_SPORT_EV
|
||||
elif truck_tuning:
|
||||
cruise_vals = A_CRUISE_MAX_VALS_SPORT_TRUCK
|
||||
else:
|
||||
cruise_vals = A_CRUISE_MAX_VALS_SPORT_GAS
|
||||
return float(akima_interp(v_ego, A_CRUISE_MAX_BP_CUSTOM, cruise_vals))
|
||||
return interpolate_accel_profile(v_ego, get_accel_profile_curve_values(ACCELERATION_PROFILES["SPORT"], ev_tuning, truck_tuning))
|
||||
|
||||
def get_max_accel_standard(v_ego, ev_tuning=True, truck_tuning=False):
|
||||
if ev_tuning:
|
||||
return float(akima_interp(v_ego, A_CRUISE_MAX_BP_CUSTOM, A_CRUISE_MAX_VALS_STANDARD_EV))
|
||||
if truck_tuning:
|
||||
return float(akima_interp(v_ego, A_CRUISE_MAX_BP_CUSTOM, A_CRUISE_MAX_VALS_STANDARD_TRUCK))
|
||||
return get_max_accel(v_ego)
|
||||
if ev_tuning or truck_tuning:
|
||||
return interpolate_accel_profile(v_ego, get_accel_profile_curve_values(ACCELERATION_PROFILES["STANDARD"], ev_tuning, truck_tuning))
|
||||
return float(get_max_accel(v_ego))
|
||||
|
||||
def get_max_accel_custom(v_ego, custom_curve, acceleration_profile, ev_tuning=True, truck_tuning=False):
|
||||
curve_values = coerce_custom_accel_profile_values(custom_curve, acceleration_profile, ev_tuning, truck_tuning)
|
||||
return interpolate_accel_profile(v_ego, curve_values)
|
||||
|
||||
def get_max_accel_low_speeds(max_accel, v_cruise):
|
||||
return float(akima_interp(v_cruise, [0., CITY_SPEED_LIMIT / 2, CITY_SPEED_LIMIT], [max_accel / 4, max_accel / 2, max_accel]))
|
||||
@@ -103,11 +75,7 @@ def get_max_accel_ramp_off(max_accel, v_cruise, v_ego):
|
||||
return float(akima_interp(v_cruise - v_ego, [0., 1., 5., 10.], [0., 0.5, 1.0, max_accel]))
|
||||
|
||||
def get_max_allowed_accel(v_ego, ev_tuning=True, truck_tuning=False):
|
||||
if ev_tuning:
|
||||
return float(akima_interp(v_ego, A_CRUISE_MAX_BP_CUSTOM, A_CRUISE_MAX_VALS_SPORT_PLUS_EV))
|
||||
if truck_tuning:
|
||||
return float(akima_interp(v_ego, A_CRUISE_MAX_BP_CUSTOM, A_CRUISE_MAX_VALS_SPORT_PLUS_TRUCK))
|
||||
return float(akima_interp(v_ego, [0., 5., 20.], [4.0, 4.0, 2.0])) # ISO 15622:2018
|
||||
return float(get_profile_max_allowed_accel(v_ego, ev_tuning, truck_tuning))
|
||||
|
||||
class StarPilotAcceleration:
|
||||
def __init__(self, StarPilotPlanner):
|
||||
@@ -121,8 +89,12 @@ class StarPilotAcceleration:
|
||||
sport_gear = sm["starpilotCarState"].sportGear
|
||||
ev_tuning = getattr(starpilot_toggles, "ev_tuning", True)
|
||||
truck_tuning = getattr(starpilot_toggles, "truck_tuning", False)
|
||||
custom_accel_profile = getattr(starpilot_toggles, "custom_accel_profile", False)
|
||||
custom_accel_profile_values = getattr(starpilot_toggles, "custom_accel_profile_values", [])
|
||||
|
||||
if sm["starpilotCarState"].trafficModeEnabled:
|
||||
if custom_accel_profile:
|
||||
self.max_accel = get_max_accel_custom(v_ego, custom_accel_profile_values, starpilot_toggles.acceleration_profile, ev_tuning, truck_tuning)
|
||||
elif sm["starpilotCarState"].trafficModeEnabled:
|
||||
self.max_accel = get_max_accel_standard(v_ego, ev_tuning, truck_tuning)
|
||||
elif starpilot_toggles.map_acceleration and (eco_gear or sport_gear):
|
||||
if eco_gear:
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user