revert volt long tune

This commit is contained in:
firestar5683
2026-04-18 16:01:49 -05:00
parent 278c89b1a5
commit 0b2261ce08
7 changed files with 34 additions and 46 deletions
+8 -6
View File
@@ -24,6 +24,7 @@ from opendbc.car.gm.values import (
from opendbc.car.interfaces import CarInterfaceBase, TorqueFromLateralAccelCallbackType, LateralAccelFromTorqueCallbackType
from opendbc.safety import ALTERNATIVE_EXPERIENCE
from openpilot.common.params import Params, UnknownKeyName
from openpilot.starpilot.common.testing_grounds import testing_ground
TransmissionType = structs.CarParams.TransmissionType
NetworkLocation = structs.CarParams.NetworkLocation
@@ -76,7 +77,7 @@ VOLT_LIKE_CARS = {
CAR.CHEVROLET_MALIBU_HYBRID_CC,
}
VOLT_LONG_TUNE_CARS = {
VOLT_LONG_TEST_TUNE_CARS = {
CAR.CHEVROLET_VOLT,
CAR.CHEVROLET_VOLT_2019,
CAR.CHEVROLET_VOLT_ASCM,
@@ -565,14 +566,15 @@ class CarInterface(CarInterfaceBase):
ret.pcmCruise = False
ret.openpilotLongitudinalControl = not disable_openpilot_long
volt_long_tune_active = (
volt_test_tune_active = (
testing_ground.use_2 and
ret.openpilotLongitudinalControl and
candidate in VOLT_LONG_TUNE_CARS
candidate in VOLT_LONG_TEST_TUNE_CARS
)
if volt_long_tune_active:
if volt_test_tune_active:
# Volt long can still fall back to an all-I tune on both the interceptor and
# ASCM-int paths. Use the promoted tune by default: add a modest P term,
# trim mid/high-speed I memory, and keep a dedicated starting state so
# ASCM-int paths. The test-ground tune adds a modest P term, trims
# mid/high-speed I memory, and uses a dedicated starting state so
# stop-and-go launches do not wind up the PID.
ret.longitudinalTuning.kpBP = [0.0, 4.0, 12.0, 35.0]
ret.longitudinalTuning.kpV = [0.10, 0.072, 0.050, 0.040]
+4 -1
View File
@@ -4,6 +4,7 @@ from parameterized import parameterized
from opendbc.car.car_helpers import interfaces
from opendbc.car.gm.carcontroller import should_spoof_dash_speed
import opendbc.car.gm.interface as gm_interface
from opendbc.car.common.conversions import Conversions as CV
from opendbc.car.gm.fingerprints import FINGERPRINTS
from opendbc.car.gm.values import CAMERA_ACC_CAR, CAR, CC_ONLY_CAR, GM_RX_OFFSET
@@ -60,13 +61,15 @@ class TestGMInterface:
("interceptor", True),
("ascm_int", False),
])
def test_volt_default_long_tune_sets_nonzero_p_and_starting_state(self, _name, pedal_present):
def test_volt_testing_ground_tune_sets_nonzero_p_and_starting_state(self, _name, pedal_present, monkeypatch):
CarInterface = interfaces[CAR.CHEVROLET_VOLT_ASCM]
fingerprint = _empty_fingerprint()
if pedal_present:
fingerprint[0][0x201] = 8 # pedal detected
fingerprint[0][0x2FF] = 8 # SASCM detected
monkeypatch.setattr(gm_interface.testing_ground, "use_2", True, raising=False)
car_params = CarInterface.get_params(CAR.CHEVROLET_VOLT_ASCM, fingerprint, [], alpha_long=False, is_release=False, docs=False,
starpilot_toggles=_test_starpilot_toggles())
+6 -5
View File
@@ -6,6 +6,7 @@ from openpilot.common.pid import PIDController
from openpilot.selfdrive.modeld.constants import ModelConstants
from openpilot.common.filter_simple import FirstOrderFilter
from opendbc.car.gm.values import CarControllerParams, GMFlags
from openpilot.starpilot.common.testing_grounds import testing_ground
CONTROL_N_T_IDX = ModelConstants.T_IDXS[:CONTROL_N]
clip = np.clip
@@ -154,9 +155,9 @@ class LongControl:
self.integrator_hold_frames = 0
def _get_pedal_long_freeze(self, a_target, error, v_ego, accel_limits):
volt_long_handoff = self.is_volt
volt_test_tune_handoff = self.is_volt and testing_ground.use_2
if not self.is_gm_pedal_long and not volt_long_handoff:
if not self.is_gm_pedal_long and not volt_test_tune_handoff:
self.last_a_target = a_target
self.integrator_hold_frames = 0
return False
@@ -183,8 +184,8 @@ class LongControl:
return self.integrator_hold_frames > 0 or sat_pushing_lower or sat_pushing_upper
def _shape_volt_integrator(self, error, v_ego):
if not self.is_volt:
def _shape_volt_test_tune_integrator(self, error, v_ego):
if not (self.is_volt and testing_ground.use_2):
return
# Bleed stale I quickly when the target reverses against stored integrator.
@@ -223,7 +224,7 @@ class LongControl:
else: # LongCtrlState.pid
error = a_target - CS.aEgo
self.update_mpc_mode(self.experimental_mode)
self._shape_volt_integrator(error, CS.vEgo)
self._shape_volt_test_tune_integrator(error, CS.vEgo)
feedforward = a_target * self.feedforward_gain
freeze_integrator = self._get_pedal_long_freeze(a_target, error, CS.vEgo, accel_limits)
raw_output_accel = self.pid.update(error, speed=CS.vEgo, feedforward=feedforward,
+7 -2
View File
@@ -2,6 +2,7 @@ from types import SimpleNamespace
from cereal import car
import openpilot.selfdrive.controls.lib.longcontrol as longcontrol
from openpilot.selfdrive.controls.lib.longcontrol import LongControl, LongCtrlState, long_control_state_trans
@@ -124,7 +125,7 @@ def test_starting_accel_obeys_a_target_cap_when_custom_profile_enabled():
assert output_accel == 0.1
def test_volt_pedal_handoff_freezes_integrator():
def test_volt_testing_ground_handoff_freezes_integrator(monkeypatch):
CP = car.CarParams.new_message()
CP.brand = "gm"
CP.enableGasInterceptorDEPRECATED = True
@@ -134,6 +135,8 @@ def test_volt_pedal_handoff_freezes_integrator():
CP.longitudinalTuning.kiBP = [0.0]
CP.longitudinalTuning.kiV = [0.03]
monkeypatch.setattr(longcontrol.testing_ground, "use_2", True, raising=False)
lc = LongControl(CP)
freeze = lc._get_pedal_long_freeze(a_target=0.7, error=0.7, v_ego=8.0, accel_limits=(-3.0, 2.0))
@@ -141,7 +144,7 @@ def test_volt_pedal_handoff_freezes_integrator():
assert lc.integrator_hold_frames > 0
def test_non_interceptor_volt_handoff_freezes_integrator():
def test_non_interceptor_volt_testing_ground_handoff_freezes_integrator(monkeypatch):
CP = car.CarParams.new_message()
CP.brand = "gm"
CP.enableGasInterceptorDEPRECATED = False
@@ -151,6 +154,8 @@ def test_non_interceptor_volt_handoff_freezes_integrator():
CP.longitudinalTuning.kiBP = [0.0]
CP.longitudinalTuning.kiV = [0.03]
monkeypatch.setattr(longcontrol.testing_ground, "use_2", True, raising=False)
lc = LongControl(CP)
freeze = lc._get_pedal_long_freeze(a_target=0.7, error=0.7, v_ego=8.0, accel_limits=(-3.0, 2.0))
+5 -18
View File
@@ -40,9 +40,10 @@ TESTING_GROUNDS_SLOT_DEFINITIONS = (
},
{
"id": TESTING_GROUND_2,
"name": "Unused",
"description": "",
"aLabel": "A",
"name": "Volt Long Tune",
"description": "Volt longitudinal tuning sandbox.",
"aLabel": "A - Installed tune",
"bLabel": "B - Firestar Tune",
},
{
"id": TESTING_GROUND_3,
@@ -149,18 +150,6 @@ def _normalize_selection(slot_id, variant):
return normalized_slot_id, _normalize_variant(variant, normalized_slot_id)
def migrate_testing_ground_selection(slot_id, variant, default_slot_id=None):
normalized_slot_id = str(slot_id or "").strip()
normalized_variant = str(variant or "").strip().upper()
fallback_slot_id = str(default_slot_id or _DEFAULT_ACTIVE_SLOT).strip() or _DEFAULT_ACTIVE_SLOT
# Retire the Volt B sandbox cleanly when the tune graduates to default behavior.
if normalized_slot_id == TESTING_GROUND_2 and normalized_variant == TESTING_GROUND_TEST_VARIANT:
return fallback_slot_id, DEFAULT_TESTING_GROUND_VARIANT, True
return normalized_slot_id, normalized_variant, False
def _write_testing_ground_selection(payload, slot_id, variant):
normalized_payload = dict(payload) if isinstance(payload, dict) else {}
normalized_payload["schemaVersion"] = TESTING_GROUNDS_SCHEMA_VERSION
@@ -209,12 +198,10 @@ def get_testing_ground_selection(refresh_interval_s=0.5):
raw_slot_id = str(payload.get("activeSlot") or "").strip()
raw_variant = payload.get("activeVariant")
migrated_slot_id, migrated_variant, selection_migrated = migrate_testing_ground_selection(raw_slot_id, raw_variant)
normalized_slot_id, normalized_variant = _normalize_selection(migrated_slot_id, migrated_variant)
normalized_slot_id, normalized_variant = _normalize_selection(raw_slot_id, raw_variant)
raw_variant_text = str(raw_variant or "").strip().upper()
if (
payload.get("schemaVersion") != TESTING_GROUNDS_SCHEMA_VERSION or
selection_migrated or
raw_slot_id != normalized_slot_id or
raw_variant_text != normalized_variant
):
@@ -5,7 +5,7 @@ import pytest
from openpilot.starpilot.common import testing_grounds as tg
@pytest.mark.parametrize("hidden_slot_id", [tg.TESTING_GROUND_2, tg.TESTING_GROUND_5])
@pytest.mark.parametrize("hidden_slot_id", [tg.TESTING_GROUND_5])
def test_hidden_testing_ground_selection_is_migrated(tmp_path, monkeypatch, hidden_slot_id):
state_path = tmp_path / "slots.json"
state_path.write_text(json.dumps({
@@ -28,11 +28,3 @@ def test_hidden_testing_ground_selection_is_migrated(tmp_path, monkeypatch, hidd
payload = json.loads(state_path.read_text(encoding="utf-8"))
assert payload["activeSlot"] == tg.TESTING_GROUND_1
assert payload["activeVariant"] == tg.DEFAULT_TESTING_GROUND_VARIANT
def test_retired_volt_b_selection_is_explicitly_migrated_to_default_a():
slot_id, variant, migrated = tg.migrate_testing_ground_selection(tg.TESTING_GROUND_2, tg.TESTING_GROUND_TEST_VARIANT, tg.TESTING_GROUND_1)
assert migrated
assert slot_id == tg.TESTING_GROUND_1
assert variant == tg.DEFAULT_TESTING_GROUND_VARIANT
+3 -5
View File
@@ -71,7 +71,6 @@ from openpilot.starpilot.common.testing_grounds import (
TESTING_GROUNDS_SCHEMA_VERSION as SHARED_TESTING_GROUNDS_SCHEMA_VERSION,
TESTING_GROUNDS_SLOT_DEFINITIONS as SHARED_TESTING_GROUNDS_SLOT_DEFINITIONS,
TESTING_GROUNDS_STATE_PATH as SHARED_TESTING_GROUNDS_STATE_PATH,
migrate_testing_ground_selection as migrate_shared_testing_ground_selection,
)
from openpilot.starpilot.system.the_pond import utilities
@@ -2937,8 +2936,6 @@ def _load_testing_grounds_state_unlocked():
}
default_slot_id = _get_first_selectable_testing_ground_slot_id(state["slots"])
active_slot = str(raw_state.get("activeSlot") or "").strip()
raw_active_variant = str(raw_state.get("activeVariant") or "").strip().upper()
active_slot, migrated_variant, selection_migrated = migrate_shared_testing_ground_selection(active_slot, raw_active_variant, default_slot_id)
active_slot_migrated = active_slot not in fallback_slot_ids or active_slot not in selectable_slot_ids
if active_slot_migrated:
active_slot = default_slot_id
@@ -2946,10 +2943,11 @@ def _load_testing_grounds_state_unlocked():
state["activeSlot"] = active_slot
active_slot_data = _find_testing_ground_slot(state, active_slot)
if active_slot_migrated or selection_migrated:
raw_active_variant = str(raw_state.get("activeVariant") or "").strip().upper()
if active_slot_migrated:
active_variant = _TESTING_GROUNDS_DEFAULT_VARIANT
else:
active_variant = _normalize_testing_ground_variant(active_slot, migrated_variant, active_slot_data)
active_variant = _normalize_testing_ground_variant(active_slot, raw_active_variant, active_slot_data)
if raw_active_variant != active_variant:
needs_write = True
state["activeVariant"] = active_variant