Preserve independent HKG lateral across cancel deadline joins

This commit is contained in:
firestar5683
2026-11-10 22:36:34 -06:00
parent 4c5de70635
commit ded2aceced
3 changed files with 68 additions and 1 deletions
@@ -1487,6 +1487,12 @@ class SelfdriveD:
# An already-off PCM is not a new cruise cancellation. Only a fresh,
# independently checked LAT source may replace the expired LAT-only proof.
user_disable = any(event.userDisable and event.name != EventName.pcmDisable for event in self.events.to_msg())
if user_disable and fresh_successor and self.CP.brand == 'hyundai':
from openpilot.starpilot.car.hyundai.aol import physical_cancel_lateral_allowed
native = current_native(self.sm, self.CP, now_ns=now_ns, axis_session_id=self.aol_session_id)
if physical_cancel_lateral_allowed(self.CP, CS, intent, native, settings=self.aol_settings,
previous=decision, source_ns=source_ns, now_ns=now_ns, axis_session_id=self.aol_session_id):
user_disable = any(event.userDisable and event.name != EventName.buttonCancel for event in self.events.to_msg())
if user_disable and fresh_successor and self.ford_source_deadline_supported():
from openpilot.starpilot.car.ford.aol import physical_cancel_lateral_allowed
native = current_native(self.sm, self.CP, now_ns=now_ns, axis_session_id=self.aol_session_id)
@@ -0,0 +1,61 @@
from contextlib import ExitStack
from unittest import mock
import pytest
from opendbc.car.structs import car
from opendbc.car.hyundai.values import CAR
from opendbc.car.hyundai.tests.test_ioniq5pe_stock import params
from opendbc.car.hyundai.ioniq5pe_long_profile import candidate as pe_long
from opendbc.car.hyundai.ev9_longitudinal import candidate as ev9_long
from openpilot.cereal import log
from openpilot.common.params import Params
from openpilot.common.prefix import OpenpilotPrefix
from openpilot.starpilot.aol.intent import read_settings
from openpilot.starpilot.aol.tests import test_ioniq_availability as fixture
from openpilot.starpilot.aol.tests.test_input_deadline_continuity import BASE, intent
@pytest.mark.parametrize('restriction', ['none', 'coast', 'native_denied', 'native_invalid', 'critical', 'cancel_mapping', 'expired_source', 'latch_off'])
@pytest.mark.parametrize('identity', [CAR.HYUNDAI_IONIQ_5_PE, CAR.KIA_EV9])
def test_cancel_crossing_output_deadline_keeps_fresh_independent_lateral(identity, restriction):
case = fixture.IoniqAvailabilityTests(methodName='runTest')
with ExitStack() as cleanup:
cleanup.callback(case.doCleanups)
with OpenpilotPrefix():
saved = Params()
saved.put('LKASButtonControl', 9, block=True)
for key in ('CancelButtonControl', 'LongCancelButtonControl', 'VeryLongCancelButtonControl'):
saved.put(key, 0, block=True)
if restriction in ('coast', 'cancel_mapping'):
saved.put('LongCancelButtonControl', 8 if restriction == 'coast' else 9, block=True)
cp = (pe_long if identity == CAR.HYUNDAI_IONIQ_5_PE else ev9_long)(
params(candidate=identity), enabled=True, is_release=False)
cp.alternativeExperience = 32
sd, controls, step = case._authority_callers(True, cp=cp, genuine_events=True)
sd.aol_settings = read_settings(saved)
for tick in (0, 1):
step(tick)
prior, _, command = step(2, offset_ns=4_266_961, state_stamp=BASE, intent_message=intent(BASE, 3))
assert prior.lateralActive and prior.longitudinalActive and command.latActive and command.longActive
now = BASE + 34_638_124
source = now - (31_000_000 if restriction == 'expired_source' else 24_218_150)
assert now - prior.validUntilMonoTime == 371_163
with mock.patch('openpilot.selfdrive.controls.controlsd.time.monotonic_ns', return_value=now):
expired, _ = controls.state_control()
assert not expired.latActive and not expired.longActive
state = fixture.car_state()
state.vEgoRaw = state.vEgo
state.buttonEvents = [car.CarState.ButtonEvent(type='cancel', pressed=True)]
axis, _, command = step(5, offset_ns=4_638_124, state_stamp=source,
intent_message=intent(source, 4, latched=restriction != 'latch_off'), observed_state=state,
allowed=restriction != 'native_denied', native_valid=restriction != 'native_invalid',
critical_event=log.OnroadEvent.EventName.controlsMismatch if restriction == 'critical' else None)
assert axis.sourceCarStateMonoTime == (0 if restriction == 'expired_source' else source)
assert not axis.longitudinalActive and not command.longActive and not sd.enabled
if restriction in ('none', 'coast'):
assert axis.lateralActive and command.latActive
assert not sd.aol_authority_lost and sd.aol_last_intent.allowedLatch
assert log.OnroadEvent.EventName.controlsMismatch not in sd.events.names
else:
assert not axis.lateralActive and not command.latActive
+1 -1
View File
@@ -1 +1 @@
{"protected_inventory_sha256": "fb78a23b1998f94730ef0e7f177e9477f8bee39b6960c9328939e91c60e8f2f9", "schema_version": 1}
{"protected_inventory_sha256": "f8e452106b5698682f884462e64e20b46664de48f31ca48b964759a66f05e54b", "schema_version": 1}