mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-11-12 15:33:45 +08:00
96 lines
4.8 KiB
Python
96 lines
4.8 KiB
Python
from contextlib import ExitStack
|
|
|
|
import pytest
|
|
|
|
from opendbc.car.hyundai.canfd_angle_aol import MODELS
|
|
from openpilot.cereal import log
|
|
from openpilot.common.params import Params
|
|
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 (
|
|
test_fresh_source_replaces_expired_output_without_restoring_disengagement as _fresh_source,
|
|
test_late_carstate_during_environment_work_reaches_final_owners_once as _restrictive_source,
|
|
)
|
|
|
|
|
|
@pytest.mark.parametrize('timing', ['timely', 'late_poll', 'processing_crosses_deadline'])
|
|
def test_stock_angle_fresh_source_keeps_independent_lateral_with_stock_cruise_off(timing):
|
|
_fresh_source('stock_angle_gas', timing)
|
|
|
|
|
|
@pytest.mark.parametrize('pulse', ['stock_angle_gas_invalid_envelope', 'stock_angle_gas_permanent_eps'])
|
|
def test_stock_angle_fresh_source_still_observes_invalid_envelope_and_eps_fault(pulse):
|
|
_restrictive_source(pulse)
|
|
|
|
|
|
@pytest.mark.parametrize('restriction', ['cancel', 'eps', 'can_invalid', 'native_denied', 'native_invalid', 'intent_withdrawn'])
|
|
def test_stock_angle_expired_output_never_renews_through_restrictions(restriction):
|
|
case = fixture.IoniqAvailabilityTests(methodName='runTest')
|
|
with ExitStack() as cleanup:
|
|
cleanup.callback(case.doCleanups)
|
|
with OpenpilotPrefix():
|
|
sd, _, step, _, _ = case._ioniq_availability_callers(full_op=False, stock_angle=True)
|
|
initial, _, command = step(2, gas=True)
|
|
assert initial.lateralActive and command.latActive
|
|
state = fixture.car_state()
|
|
state.vEgoRaw = state.vEgo
|
|
if restriction == 'cancel':
|
|
state.buttonEvents = [fixture.car.CarState.ButtonEvent(type='cancel', pressed=True)]
|
|
elif restriction == 'eps':
|
|
state.steerFaultPermanent = True
|
|
elif restriction == 'can_invalid':
|
|
state.canValid = False
|
|
axis, _, command = step(6, observed_state=state, gas=True, allowed=restriction != 'native_denied',
|
|
native_valid=restriction != 'native_invalid', latched=restriction != 'intent_withdrawn')
|
|
assert not axis.lateralActive and not command.latActive
|
|
assert not axis.longitudinalActive and not command.longActive and not sd.enabled
|
|
|
|
|
|
def test_stock_angle_explicit_lateral_pause_keeps_latch_beyond_native_ack_timeout():
|
|
from openpilot.starpilot.aol.intent import PAUSE_LATERAL
|
|
|
|
case = fixture.IoniqAvailabilityTests(methodName='runTest')
|
|
with ExitStack() as cleanup:
|
|
cleanup.callback(case.doCleanups)
|
|
with OpenpilotPrefix():
|
|
sd, _, step, card, receive = case._ioniq_availability_callers(full_op=False, stock_angle=True)
|
|
card.aol_card_intent._perform(PAUSE_LATERAL)
|
|
for tick in range(2, 37):
|
|
pause = tick < 36
|
|
if not pause:
|
|
card.aol_card_intent._perform(PAUSE_LATERAL)
|
|
axis, _, command = step(tick, pause=pause, allowed=not pause, native_request_lat=not pause)
|
|
assert axis.lateralActive == command.latActive == (not pause)
|
|
assert not axis.longitudinalActive and not command.longActive and not sd.enabled
|
|
assert receive(10_000_000_000 + tick * 10_000_000,
|
|
axis=sd.pm.messages['aolAxisState'], event=sd.pm.messages['onroadEvents'])
|
|
assert card.aol_card_intent.allowed_latch
|
|
|
|
|
|
@pytest.mark.parametrize('pause_speed', [0., 30.])
|
|
@pytest.mark.parametrize('identity', sorted(MODELS))
|
|
def test_moving_stock_angle_brake_keeps_latch_and_respects_saved_pause(pause_speed, identity):
|
|
case = fixture.IoniqAvailabilityTests(methodName='runTest')
|
|
with ExitStack() as cleanup:
|
|
cleanup.callback(case.doCleanups)
|
|
with OpenpilotPrefix():
|
|
params = Params()
|
|
params.put('PauseAOLOnBrake', pause_speed, block=True)
|
|
sd, _, step, card, receive = case._ioniq_availability_callers(full_op=False, stock_angle=identity)
|
|
assert card.CP.alternativeExperience == 32
|
|
assert not card.CP.openpilotLongitudinalControl
|
|
for tick in range(2, 37):
|
|
brake = tick < 36
|
|
state = fixture.car_state(brake=brake)
|
|
state.vEgo = state.vEgoRaw = 3.
|
|
expected = not brake or pause_speed == 0.
|
|
axis, _, command = step(tick, observed_state=state, allowed=expected, native_request_lat=expected)
|
|
assert axis.lateralActive == command.latActive == expected
|
|
assert not axis.longitudinalActive and not command.longActive and not sd.enabled
|
|
assert not sd.aol_authority_lost
|
|
assert log.OnroadEvent.EventName.controlsMismatch not in sd.events.names
|
|
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
|
|
assert float(params.get('PauseAOLOnBrake')) == pause_speed
|