From 2abc15c222475aa7bf9763e3b37c71414d040bbb Mon Sep 17 00:00:00 2001 From: firestar5683 <168790843+firestar5683@users.noreply.github.com> Date: Tue, 20 Oct 2026 21:33:52 -0500 Subject: [PATCH] Preserve stock ASCM Volt lateral intent below cruise speed --- openpilot/selfdrive/selfdrived/selfdrived.py | 5 ++- .../aol/tests/test_gm_ascm_stock_low_speed.py | 42 +++++++++++++++++++ openpilot/starpilot/car/gm/aol.py | 9 +++- prebuilt.json | 2 +- 4 files changed, 54 insertions(+), 4 deletions(-) create mode 100644 openpilot/starpilot/aol/tests/test_gm_ascm_stock_low_speed.py diff --git a/openpilot/selfdrive/selfdrived/selfdrived.py b/openpilot/selfdrive/selfdrived/selfdrived.py index 3f1775802e..693689c9e8 100644 --- a/openpilot/selfdrive/selfdrived/selfdrived.py +++ b/openpilot/selfdrive/selfdrived/selfdrived.py @@ -1575,7 +1575,7 @@ class SelfdriveD: def _decide_aol_axes(self, CS, intent, native, *, now_ns=0, ordinary_lag=False): - from openpilot.starpilot.car.gm.aol import physical_cancel_lateral_allowed + from openpilot.starpilot.car.gm.aol import physical_cancel_lateral_allowed, stock_ascm_independent_lateral from openpilot.starpilot.car.hyundai.aol import physical_cancel_lateral_allowed as hkg_cancel_lateral_allowed from openpilot.starpilot.aol.dm import lateral_event_context retained_dm_lateral, lateral_events = lateral_event_context(self, CS, intent, native, now_ns, ordinary_lag) @@ -1598,7 +1598,8 @@ class SelfdriveD: source_ns=getattr(self, 'aol_car_state_log_ns', 0), now_ns=now_ns, axis_session_id=getattr(self, 'aol_session_id', '')), cruise_main_required=getattr(self, 'aol_cruise_main_required', True), - allow_below_engage_speed=bool(is_volt_ascm_longitudinal(self.CP) and + allow_below_engage_speed=bool((is_volt_ascm_longitudinal(self.CP) or + stock_ascm_independent_lateral(self.CP)) and not self.CP.flags & GMFlags.PEDAL_LONG)), immediate_disable=self.events.contains(ET.IMMEDIATE_DISABLE), dm_lockout=bool(not self.sm.all_checks(['driverMonitoringState']) or diff --git a/openpilot/starpilot/aol/tests/test_gm_ascm_stock_low_speed.py b/openpilot/starpilot/aol/tests/test_gm_ascm_stock_low_speed.py new file mode 100644 index 0000000000..b883bb70ba --- /dev/null +++ b/openpilot/starpilot/aol/tests/test_gm_ascm_stock_low_speed.py @@ -0,0 +1,42 @@ +"""Recorded route206ae7ed9f: ordinary ACC minimum must not revoke AOL.""" +from contextlib import ExitStack +import pytest +from openpilot.common.prefix import OpenpilotPrefix +from openpilot.starpilot.aol.tests import test_ioniq_availability as fixture +from openpilot.starpilot.aol.tests.test_input_deadline_continuity import BASE, intent +from openpilot.starpilot.aol.intent import read_settings +from opendbc.car.gm.tests.test_bolt_volt_configurations import ordinary_params +from opendbc.car.gm.values import CAR +from openpilot.cereal import log + + +@pytest.mark.parametrize("c9", [False, True]) +@pytest.mark.parametrize("native_granted", [False, True]) +def test_ascm_stock_cruise_minimum_cannot_revoke_independent_main_intent(c9, native_granted): + cp = ordinary_params(CAR.CHEVROLET_VOLT_ASCM, alpha=False, sascm=True, accelerator=not c9, radar=False) + assert cp.pcmCruise and not cp.openpilotLongitudinalControl + assert cp.safetyConfigs[0].safetyParam == (0x605 if c9 else 0x205) + case = fixture.IoniqAvailabilityTests(methodName="runTest") + with OpenpilotPrefix(), ExitStack() as cleanup: + cleanup.callback(case.doCleanups) + sd, _, step = case._authority_callers(False, cp=cp, genuine_events=True) + sd.aol_settings = read_settings(sd.params) + cs = fixture.car_state() + cs.vEgo = 4. + axis, _, cc = step(2, observed_state=cs, state_stamp=BASE, intent_message=intent(BASE, 3), native_request_long=False) + assert axis.lateralActive and cc.latActive + cs = fixture.car_state(brake=True) + cs.vEgo = 1.3862173557281494 # Recorded ASCM source at57.081039046s. + cs.gearShifter = "low" + stamp = BASE + 10_000_000 + axis, _, cc = step(3, observed_state=cs, state_stamp=stamp, intent_message=intent(stamp, 4), native_request_long=False, allowed=native_granted) + assert log.OnroadEvent.EventName.belowEngageSpeed in sd.events.names + assert not sd.enabled and not cc.longActive + assert axis.desiredLateral, (axis.to_dict(), sd.events.names) + assert bool(axis.lateralActive) == native_granted + assert not cc.latActive # Existing minSteerSpeed still vetoes actual steering. + cs = fixture.car_state() + cs.vEgo = 4. + stamp += 10_000_000 + axis, _, cc = step(4, observed_state=cs, state_stamp=stamp, intent_message=intent(stamp, 5), native_request_long=False) + assert axis.lateralActive and cc.latActive and not cc.longActive diff --git a/openpilot/starpilot/car/gm/aol.py b/openpilot/starpilot/car/gm/aol.py index daaf08c610..39fea230c7 100644 --- a/openpilot/starpilot/car/gm/aol.py +++ b/openpilot/starpilot/car/gm/aol.py @@ -4,7 +4,7 @@ import math from opendbc.car.gm.cancel_remap import aol_enabled, enabled as cancel_remap_enabled, supported as cancel_remap_supported from opendbc.car.structs import CarParams -from opendbc.car.gm.values import CAR, control_flags, camera_acc_pedal_profile, is_volt_ascm_longitudinal +from opendbc.car.gm.values import CAR, GMFlags, control_flags, camera_acc_pedal_profile, is_volt_ascm_longitudinal from opendbc.car.gm.aol import GM_AOL_ALTERNATIVE_EXPERIENCE, GM_AOL_WORDS, qualified_gm from openpilot.starpilot.aol.policy import AolVehiclePolicy from openpilot.starpilot.aol.intent import AOL_TOGGLE, AolCardIntent @@ -28,6 +28,13 @@ def native_accepts_cp(cp, model: int, param: int) -> bool: native_profile_supported(model, param)) +def stock_ascm_independent_lateral(cp) -> bool: + """Stock cruise's engagement speed does not cancel independent lateral intent.""" + return bool(qualified_gm(cp) and cp.carFingerprint == CAR.CHEVROLET_VOLT_ASCM and + cp.pcmCruise and not cp.openpilotLongitudinalControl and + not cp.flags & GMFlags.PEDAL_LONG) + + class GmAolCardIntent(AolCardIntent): """Main-following intent with explicit main-cycle recovery after fatal faults.""" diff --git a/prebuilt.json b/prebuilt.json index 01b7cc9754..3c0200436b 100644 --- a/prebuilt.json +++ b/prebuilt.json @@ -1 +1 @@ -{"protected_inventory_sha256": "226a3f00d9020c539ae74d575cbc3fb3525405d370335ae84327401130bce1b7", "schema_version": 1} +{"protected_inventory_sha256": "783aebd8a8d1be8235fc486528f0d5575a5ce9486520c7dbea7f1aff0cdd59aa", "schema_version": 1}