mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-11-09 22:13:43 +08:00
80fbb4f6db
Register vehicle controls, planner modes, UI actions and Galaxy services after their providers exist. Wire the shared runtime entrypoints and cover their combined behavior. Co-authored-by: Adeeb Shihadeh <adeebshihadeh@gmail.com> Co-authored-by: Daniel Koepping <elkoled@gmail.com> Co-authored-by: Danny <dannyirwin31@yahoo.com> Co-authored-by: DimitriChrysafis <Dimitri.chrysafis@gmail.com> Co-authored-by: Dom <168790843+firestar5683@users.noreply.github.com> Co-authored-by: Harald Schäfer <harald.the.engineer@gmail.com> Co-authored-by: Kacper Rączy <gfw.kra@gmail.com> Co-authored-by: Prabhaav Pillai <prabhaav@msu.edu> Co-authored-by: dirwin31 <83434411+dirwin31@users.noreply.github.com> Co-authored-by: firestarsdog <229254897+firestarsdog@users.noreply.github.com> Co-authored-by: stef <19478336+stefpi@users.noreply.github.com> Co-authored-by: whoisdomi <dcantu83@gmail.com> Co-authored-by: Intelli <contact@intelli.software> Co-authored-by: haraschax <6804392+haraschax@users.noreply.github.com> Co-authored-by: prabhaavp <prabhaav@msu.edu>
122 lines
5.3 KiB
Python
122 lines
5.3 KiB
Python
from contextlib import ExitStack
|
|
import os
|
|
from unittest import mock
|
|
|
|
import pytest
|
|
|
|
from openpilot.cereal import log
|
|
from openpilot.selfdrive.selfdrived.events import EVENTS, ET, EventName
|
|
from openpilot.starpilot.aol.tests.stock_lateral_test_helpers import callers
|
|
from openpilot.starpilot.aol.tests.test_ioniq_availability import car_state
|
|
|
|
|
|
@pytest.mark.parametrize('family', ['gm', 'toyota'])
|
|
@pytest.mark.parametrize('full', [False, True])
|
|
@pytest.mark.parametrize('vision', [False, True])
|
|
def test_actual_armed_dm_escalation_retains_lateral_and_drops_long(family, full, vision):
|
|
with ExitStack() as cleanup:
|
|
sd, _, drive, card, receive = callers(cleanup, family, not full)
|
|
values = {'level': 'three', 'lockout': False}
|
|
original = sd.update_events
|
|
|
|
def dm_events(state):
|
|
dm = sd.sm['driverMonitoringState'].as_builder()
|
|
dm.alertLevel = values['level']
|
|
dm.activePolicy = 'vision' if vision else 'wheeltouch'
|
|
dm.lockout = values['lockout']
|
|
sd.sm.data['driverMonitoringState'] = dm.as_reader()
|
|
return original(state)
|
|
|
|
cleanup.enter_context(mock.patch.object(sd, 'update_events', side_effect=dm_events))
|
|
for tick, level, locked in ((2, 'one', False), (3, 'two', False), (4, 'three', False),
|
|
(5, 'three', True), (6, 'none', False)):
|
|
values.update(level=level, lockout=locked)
|
|
axis, _, command = drive(tick, native_request_long=full if tick < 4 else False)
|
|
assert axis.lateralActive and command.latActive
|
|
assert receive(10_000_000_000 + tick * 10_000_000)
|
|
assert card.aol_card_intent.allowed_latch
|
|
if tick >= 4:
|
|
assert not axis.desiredLongitudinal and not command.longActive and not sd.enabled
|
|
if level == 'three':
|
|
event = EventName.driverDistracted3 if vision else EventName.driverUnresponsive3
|
|
assert event in sd.events.names
|
|
alert = EVENTS[event][ET.PERMANENT]
|
|
assert alert.audible_alert == log.SelfdriveState.AudibleAlert.warningImmediate
|
|
assert alert.alert_status == log.SelfdriveState.AlertStatus.critical
|
|
assert not sd.enabled and not command.longActive
|
|
|
|
|
|
@pytest.mark.parametrize('fault', ['unarmed', 'native_denied', 'permanent', 'stale_source'])
|
|
def test_dm_does_not_grant_lateral_to_otherwise_ineligible_callers(fault):
|
|
with ExitStack() as cleanup:
|
|
sd, _, drive, _, _ = callers(cleanup, 'toyota', True)
|
|
original = sd.update_events
|
|
|
|
def red_events(state):
|
|
dm = sd.sm['driverMonitoringState'].as_builder()
|
|
dm.alertLevel = 'three'
|
|
sd.sm.data['driverMonitoringState'] = dm.as_reader()
|
|
return original(state)
|
|
|
|
cleanup.enter_context(mock.patch.object(sd, 'update_events', side_effect=red_events))
|
|
state = car_state()
|
|
if fault == 'permanent':
|
|
state.steerFaultPermanent = True
|
|
options = {'observed_state': state, 'native_request_long': False}
|
|
if fault == 'unarmed':
|
|
options['latched'] = False
|
|
elif fault == 'native_denied':
|
|
options['allowed'] = False
|
|
elif fault == 'stale_source':
|
|
options['state_stamp'] = 10_000_000_000
|
|
axis, _, command = drive(5, **options)
|
|
assert not axis.lateralActive and not command.latActive and not command.longActive
|
|
|
|
|
|
@pytest.mark.parametrize('always_only', [False, True])
|
|
def test_dm_lockout_alone_keeps_prior_lateral_but_requires_new_long_engagement(always_only):
|
|
with ExitStack() as cleanup:
|
|
sd, _, drive, _, _ = callers(cleanup, 'gm', False)
|
|
original = sd.update_events
|
|
locked = [True]
|
|
|
|
def events(state):
|
|
dm = sd.sm['driverMonitoringState'].as_builder()
|
|
dm.alertLevel = 'none'
|
|
dm.lockout = locked[0] and not always_only
|
|
dm.alwaysOnLockout = locked[0] and always_only
|
|
sd.sm.data['driverMonitoringState'] = dm.as_reader()
|
|
return original(state)
|
|
|
|
cleanup.enter_context(mock.patch.object(sd, 'update_events', side_effect=events))
|
|
axis, _, command = drive(2)
|
|
assert axis.lateralActive and command.latActive
|
|
assert not sd.enabled and not axis.desiredLongitudinal and not command.longActive
|
|
assert EventName.tooDistracted in sd.events.names
|
|
locked[0] = False
|
|
axis, _, command = drive(3, native_request_long=False)
|
|
assert axis.lateralActive and not sd.enabled and not command.longActive
|
|
|
|
|
|
def test_first_red_admission_cannot_start_previously_unaccepted_lateral():
|
|
from openpilot.common.prefix import OpenpilotPrefix
|
|
from openpilot.starpilot.aol.tests.stock_lateral_test_helpers import honda_family_case
|
|
with ExitStack() as cleanup:
|
|
cleanup.enter_context(OpenpilotPrefix())
|
|
cleanup.enter_context(mock.patch.dict(os.environ, {'SIMULATION': '0', 'AOL_REPLAY_RUNTIME': '1'}))
|
|
family = honda_family_case('honda', True)
|
|
cleanup.callback(family.doCleanups)
|
|
sd, _, drive = family._authority_callers(False, cp=family.family_cp.as_builder(), genuine_events=True)
|
|
original = sd.update_events
|
|
|
|
def events(state):
|
|
dm = sd.sm['driverMonitoringState'].as_builder()
|
|
dm.alertLevel = 'three'
|
|
sd.sm.data['driverMonitoringState'] = dm.as_reader()
|
|
return original(state)
|
|
|
|
cleanup.enter_context(mock.patch.object(sd, 'update_events', side_effect=events))
|
|
axis, _, command = drive(0, latched=True, native_request_long=False)
|
|
assert not axis.lateralActive and not command.latActive and not command.longActive
|
|
assert not getattr(sd, 'aol_dm_retained_owner', None)
|