mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-11-08 05:23:41 +08:00
105 lines
5.4 KiB
Python
105 lines
5.4 KiB
Python
from contextlib import ExitStack
|
|
from dataclasses import replace
|
|
|
|
import pytest
|
|
|
|
from opendbc.car import structs
|
|
from opendbc.car.hyundai.canfd_angle_aol import MODELS
|
|
from opendbc.car.hyundai.tests.test_stock_angle_aol import source_profile
|
|
from opendbc.car.hyundai.values import CAR
|
|
from openpilot.common.prefix import OpenpilotPrefix
|
|
from openpilot.common.params import Params
|
|
from openpilot.starpilot.aol.intent import AolSettings, read_settings
|
|
from openpilot.starpilot.aol.tests import test_ioniq_availability as fixture
|
|
from openpilot.starpilot.car.hyundai.aol import create_intent, physical_cancel_lateral_allowed
|
|
from openpilot.starpilot.aol.runtime import AxisDecision
|
|
from openpilot.starpilot.aol.wire import IntentState, PandaSlot, SafetyState
|
|
|
|
|
|
@pytest.mark.parametrize('identity', sorted(MODELS))
|
|
@pytest.mark.parametrize('tick', [2, 6])
|
|
def test_unassigned_cancel_retains_current_angle_lateral_and_card_latch(identity, tick):
|
|
case = fixture.IoniqAvailabilityTests(methodName='runTest')
|
|
with ExitStack() as cleanup:
|
|
cleanup.callback(case.doCleanups)
|
|
with OpenpilotPrefix():
|
|
saved = Params()
|
|
saved.put('LKASButtonControl', 9, block=True)
|
|
saved.put('MainCruiseButtonControl', 0, block=True)
|
|
for key in ('CancelButtonControl', 'LongCancelButtonControl', 'VeryLongCancelButtonControl'):
|
|
saved.put(key, 0, block=True)
|
|
sd, _, step, card, receive = case._ioniq_availability_callers(full_op=False, stock_angle=identity)
|
|
sd.aol_settings = read_settings(saved)
|
|
assert sd.aol_settings == card.aol_card_intent.settings
|
|
state = fixture.car_state()
|
|
state.vEgoRaw = state.vEgo
|
|
state.buttonEvents = [structs.CarState.ButtonEvent(type='cancel', pressed=True)]
|
|
axis, _, command = step(tick, observed_state=state)
|
|
assert axis.lateralActive and command.latActive
|
|
assert not axis.longitudinalActive and not command.longActive and not sd.enabled
|
|
assert receive(10_000_000_000 + tick * 10_000_000, state=state, axis=sd.pm.messages['aolAxisState'],
|
|
event=sd.pm.messages['onroadEvents'])
|
|
assert card.aol_card_intent.allowed_latch
|
|
|
|
|
|
@pytest.mark.parametrize('identity', sorted(MODELS))
|
|
@pytest.mark.parametrize('action', [0, 3, 4, 9])
|
|
def test_angle_cancel_mapping_preserves_saved_action_semantics(identity, action):
|
|
cp = source_profile(CAR(identity))
|
|
cp.alternativeExperience = 32
|
|
settings = AolSettings(True, 0., 9, 0, (0, 0, 0), (action, 0, 0))
|
|
owner = create_intent(cp, settings)
|
|
state = structs.CarState(canValid=True, gearShifter='drive')
|
|
state.cruiseState.available = True
|
|
owner.update(state, now_ns=1)
|
|
state.buttonEvents = [structs.CarState.ButtonEvent(type='lkas', pressed=True)]
|
|
owner.update(state, now_ns=2)
|
|
assert owner.allowed_latch
|
|
state.buttonEvents = [structs.CarState.ButtonEvent(type='lkas', pressed=False)]
|
|
owner.update(state, now_ns=3)
|
|
state.buttonEvents = [structs.CarState.ButtonEvent(type='cancel', pressed=True)]
|
|
owner.update(state, now_ns=4)
|
|
assert owner.allowed_latch == (action == 0)
|
|
assert owner.settings == settings
|
|
|
|
|
|
@pytest.mark.parametrize('identity', sorted(MODELS))
|
|
@pytest.mark.parametrize('restriction', ['none', 'unclaimed', 'mapped_cancel', 'paused', 'old_source', 'old_native',
|
|
'wrong_session', 'foreign_inventory', 'rx_invalid', 'lat_denied', 'no_cancel'])
|
|
def test_angle_cancel_preservation_requires_current_claim_and_native_inventory(identity, restriction):
|
|
cp = source_profile(CAR(identity))
|
|
cp.alternativeExperience = 32
|
|
now, source = 10_000_000_000, 9_990_000_000
|
|
settings = AolSettings(True, 0., 9, 0, (0, 0, 0), (0, 0, 0))
|
|
state = structs.CarState(canValid=True, gearShifter='drive', vEgo=10.)
|
|
state.buttonEvents = [structs.CarState.ButtonEvent(type='cancel', pressed=True)]
|
|
intent = IntentState('angle-card', 1, source, source, source + 200_000_000, True, False, False, True, True)
|
|
config = cp.safetyConfigs[0]
|
|
slot = PandaSlot(0, 'angle-panda', int(config.safetyModel.raw), config.safetyParam, 32)
|
|
native = SafetyState(1, True, now, now + 200_000_000, int(config.safetyModel.raw), config.safetyParam,
|
|
True, False, True, False, 'angle-panda', 'angle-session', now, (slot,))
|
|
previous = AxisDecision(lateral_active=True, native_acknowledged=True)
|
|
if restriction == 'unclaimed':
|
|
previous = replace(previous, lateral_active=False)
|
|
elif restriction == 'mapped_cancel':
|
|
settings = replace(settings, cancel_actions=(3, 0, 0))
|
|
elif restriction == 'paused':
|
|
intent = replace(intent, pauseLateral=True)
|
|
elif restriction == 'old_source':
|
|
source = now - 30_000_001
|
|
intent = replace(intent, carStateLogMonoTime=source, observedMonoTime=source)
|
|
elif restriction == 'old_native':
|
|
native = replace(native, validUntilMonoTime=now - 1)
|
|
elif restriction == 'wrong_session':
|
|
native = replace(native, axisSessionId='foreign-session')
|
|
elif restriction == 'foreign_inventory':
|
|
native = replace(native, pandaInventory=(replace(slot, safetyParam=config.safetyParam ^ 1),))
|
|
elif restriction == 'rx_invalid':
|
|
native = replace(native, pandaInventory=(replace(slot, safetyRxChecksInvalid=True),))
|
|
elif restriction == 'lat_denied':
|
|
native = replace(native, lateralAllowed=False)
|
|
elif restriction == 'no_cancel':
|
|
state.buttonEvents = []
|
|
assert physical_cancel_lateral_allowed(cp, state, intent, native, settings=settings, previous=previous,
|
|
source_ns=source, now_ns=now, axis_session_id='angle-session') == (restriction == 'none')
|