mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-11-08 05:23:41 +08:00
a82935f326
Integrate onroad views, configurable widgets, local settings, steering-profile contracts, Bluetooth and Android Auto with their device and runtime services. Co-authored-by: Adeeb Shihadeh <adeebshihadeh@gmail.com> Co-authored-by: Daniel Koepping <elkoled@gmail.com> Co-authored-by: Danny <dannyirwin31@yahoo.com> Co-authored-by: DimitriChrysafis <Dimitri.chrysafis@gmail.com> Co-authored-by: Dom <168790843+firestar5683@users.noreply.github.com> Co-authored-by: Harald Schäfer <harald.the.engineer@gmail.com> Co-authored-by: Prabhaav Pillai <prabhaav@msu.edu> Co-authored-by: Shane Smiskol <shane@smiskol.com> Co-authored-by: dirwin31 <83434411+dirwin31@users.noreply.github.com> Co-authored-by: firestarsdog <229254897+firestarsdog@users.noreply.github.com> Co-authored-by: stef <19478336+stefpi@users.noreply.github.com> Co-authored-by: whoisdomi <dcantu83@gmail.com> Co-authored-by: Intelli <contact@intelli.software> Co-authored-by: pharmacomaniac <blittle65@gmail.com> Co-authored-by: prabhaavp <prabhaav@msu.edu>
104 lines
6.2 KiB
Python
104 lines
6.2 KiB
Python
"""Explicit controller-bound steering response edits in the shared torque document."""
|
|
|
|
import json
|
|
|
|
from openpilot.starpilot.lateral.torque_runtime import gm_manual_supported_cp as supported_cp
|
|
from openpilot.starpilot.lateral.torque_supported import BOLT_VEHICLES
|
|
from openpilot.starpilot.lateral.controller_selection import DOCUMENT_KEY as SELECTION_KEY, ControllerMode, selection_from_bytes
|
|
from openpilot.starpilot.lateral.torque_settings import (DOCUMENT_KEY, GainBasis, FieldChoice, gain_bounds, parse_document, replace_gain, serialize_document)
|
|
from openpilot.starpilot.ui.feature_settings_state import FeatureRow
|
|
|
|
|
|
class GainFeature:
|
|
def __init__(self, owner):
|
|
self.owner = owner
|
|
|
|
def _basis(self, capability):
|
|
cp = self.owner.vehicle_params()
|
|
if cp is None or not supported_cp(cp) or capability != self.owner._capability("torque"):
|
|
raise ValueError("Qualified vehicle unavailable")
|
|
if not self.owner._readable(SELECTION_KEY):
|
|
raise ValueError("Controller selection unavailable")
|
|
selection = selection_from_bytes(cp, self.owner._raw(SELECTION_KEY))
|
|
if selection.source == "invalid":
|
|
raise ValueError("Controller selection needs review")
|
|
if selection.mode == ControllerMode.STARPILOT:
|
|
table = ((0,), (0.6,))
|
|
else:
|
|
from openpilot.selfdrive.controls.lib.latcontrol_torque import INTERP_SPEEDS, KP_INTERP
|
|
table = (tuple(INTERP_SPEEDS), tuple(KP_INTERP))
|
|
return GainBasis(selection.mode.value, table, (capability[5], capability[6], capability[7]))
|
|
|
|
def rows(self, capability, profiles, raw, allowed, repair_allowed):
|
|
try:
|
|
basis = self._basis(capability)
|
|
except (AttributeError, ValueError, TypeError, OverflowError):
|
|
return (FeatureRow("", "Steering response", "Controller selection unavailable"),)
|
|
profile = profiles.get(capability[0])
|
|
choice = profile.proportional_gain if profile is not None else FieldChoice()
|
|
dependencies = self.owner._dependents(*(("AdvancedLateralTune",) if capability[0] in BOLT_VEHICLES else ()), "ForceAutoTuneOff", SELECTION_KEY)
|
|
if choice.mode == "custom" and profile.gain_basis != basis:
|
|
return (FeatureRow("torque_gain_rebase", "Review steering response",
|
|
"Controller or vehicle tune changed. Confirm this response for the selected controller.", raw,
|
|
available=repair_allowed, capability=capability, dependencies=dependencies),
|
|
FeatureRow("torque:gain:mode", "Steering response source", "Custom", raw,
|
|
choices=("Selected controller",), available=allowed, capability=capability, dependencies=dependencies,
|
|
default_value="Selected controller"))
|
|
rows = [FeatureRow("", "Manual steering response",
|
|
"Higher values respond more strongly; lower values respond more gently. First manual activation " +
|
|
"requires a driving-process restart; an active tuning owner refreshes changes during the drive.")]
|
|
rows.append(FeatureRow("torque:gain:mode", "Steering response source",
|
|
"Custom" if choice.mode == "custom" else "Selected controller", raw,
|
|
choices=("Selected controller", "Custom"), available=allowed, capability=capability, dependencies=dependencies,
|
|
default_value="Selected controller"))
|
|
if choice.mode == "custom":
|
|
low, high = gain_bounds(capability[0], basis)
|
|
rows.append(FeatureRow("torque:gain:value", "Steering response", f"{choice.custom_value:.2f}", raw,
|
|
minimum=low, maximum=high, step=0.05, available=allowed,
|
|
default_value="Selected controller", default_key="torque:gain:mode",
|
|
capability=capability, dependencies=dependencies))
|
|
return tuple(rows)
|
|
|
|
def apply(self, request):
|
|
owner = self.owner
|
|
def current():
|
|
required = {"ForceAutoTuneOff", SELECTION_KEY}
|
|
if request.capability is not None and request.capability[0] in BOLT_VEHICLES:
|
|
required.add("AdvancedLateralTune")
|
|
return (owner.authority("torque") and request.vehicle_fingerprint == owner.vehicle_fingerprint() and
|
|
request.capability is not None and request.capability == owner._capability("torque") and
|
|
required.issubset(key for key, _ in request.dependencies) and
|
|
owner._readable(DOCUMENT_KEY) and owner._raw(DOCUMENT_KEY) == request.expected and
|
|
all(owner._readable(key) and owner._raw(key) == value for key, value in request.dependencies))
|
|
try:
|
|
if not current() or request.expected is None and request.capability[0] in BOLT_VEHICLES:
|
|
return False
|
|
basis = self._basis(request.capability)
|
|
profiles = {} if request.expected is None else parse_document(request.expected)
|
|
prior = profiles.get(request.capability[0])
|
|
choice = prior.proportional_gain if prior is not None else FieldChoice()
|
|
review = request.key == "torque_gain_rebase"
|
|
if review:
|
|
if not request.confirmation or not owner.authority("parked_preferences") or choice.mode != "custom":
|
|
return False
|
|
mode, value = choice.mode, choice.custom_value
|
|
elif request.key == "torque:gain:mode":
|
|
if request.value == "Selected controller":
|
|
mode, value = "source", None
|
|
elif request.value == "Custom":
|
|
initial = 0.6 if request.capability[0] in BOLT_VEHICLES else basis.source_table[1][-1]
|
|
mode, value = "custom", choice.custom_value if choice.custom_value is not None else initial
|
|
else:
|
|
return False
|
|
elif request.key == "torque:gain:value" and choice.mode == "custom":
|
|
mode, value = "custom", float(request.value)
|
|
else:
|
|
return False
|
|
updated = replace_gain(profiles, request.capability[0], basis, mode, value, review=review)
|
|
if not current() or self._basis(request.capability) != basis or review and not owner.authority("parked_preferences"):
|
|
return False
|
|
owner.params.put(DOCUMENT_KEY, json.loads(serialize_document(updated)), block=True)
|
|
return parse_document(owner._raw(DOCUMENT_KEY)) == updated
|
|
except (OSError, ValueError, TypeError, AttributeError, OverflowError, UnicodeError):
|
|
return False
|