mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-11-06 04:23:42 +08:00
Keep first AOL arming available during native startup
This commit is contained in:
@@ -1948,7 +1948,9 @@ class SelfdriveD:
|
||||
native = current_native(self.sm, self.CP, now_ns=now_ns, axis_session_id=self.aol_session_id)
|
||||
if native is None and self.initialized:
|
||||
lost_active_aol = self.aol_axis_decision.lateral_active or self.aol_axis_decision.longitudinal_active
|
||||
self.events.add(EventName.controlsMismatch)
|
||||
native_missing_at_startup = (not self.sm.seen['aolSafetyWire'] and not self.enabled and
|
||||
not self.active and not lost_active_aol)
|
||||
self.events.add(EventName.commIssue if native_missing_at_startup else EventName.controlsMismatch)
|
||||
self.aol_decision_native = native
|
||||
if self.aol_replay:
|
||||
previous_intent = getattr(self, 'aol_last_intent', None)
|
||||
|
||||
@@ -690,3 +690,100 @@ def test_nostalgia_paddle_expiry_cannot_restore_invalid_lateral(fault):
|
||||
assert not axis.lateralActive and not command.latActive
|
||||
finally:
|
||||
case.doCleanups()
|
||||
|
||||
|
||||
@pytest.mark.parametrize('alpha', (False, True))
|
||||
def test_startup_native_wait_preserves_first_lkas_through_model_loading(alpha):
|
||||
from opendbc.car.hyundai.tests.test_palisade_2023 import params as blended_params
|
||||
from opendbc.car.hyundai.blended_longitudinal import candidate_from_stock
|
||||
from openpilot.cereal import log
|
||||
|
||||
case = caller_fixture.IoniqAvailabilityTests(methodName='runTest')
|
||||
with OpenpilotPrefix():
|
||||
cp = blended_params('hdaii')
|
||||
startup = None
|
||||
if alpha:
|
||||
from opendbc.car.hyundai.blended_longitudinal import BlendedStartup
|
||||
from unittest.mock import Mock
|
||||
stock = cp
|
||||
cp = candidate_from_stock(stock, alpha_requested=True, native_qualified=True)
|
||||
startup = BlendedStartup(stock, cp.as_reader().as_builder(), (Mock(), Mock()))
|
||||
assert startup.prepare(admission=lambda: True).to_dict() == cp.to_dict()
|
||||
case.addCleanup(startup.close)
|
||||
Params().put('LKASButtonControl', AOL_TOGGLE, block=True)
|
||||
try:
|
||||
sd, _, drive, card, receive = case._ioniq_availability_callers(
|
||||
False, initially_armed=False, cp=cp, cold_start=True, startup_owner=startup)
|
||||
original_receive = sd.sm.update_msgs
|
||||
missing = {'aolSafetyWire', 'modelV2'}
|
||||
|
||||
def receive_sources(now, messages):
|
||||
return original_receive(now, [message for message in messages if message.which() not in missing])
|
||||
|
||||
for name in missing:
|
||||
sd.sm.seen[name] = sd.sm.alive[name] = sd.sm.valid[name] = False
|
||||
with patch.object(sd.sm, 'update_msgs', side_effect=receive_sources):
|
||||
axis, _, command = drive(0, allowed=False, native_request_lat=False, native_request_long=False)
|
||||
assert not axis.lateralActive and not axis.longitudinalActive
|
||||
assert not command.latActive and not command.longActive
|
||||
assert log.OnroadEvent.EventName.commIssue in sd.events.names
|
||||
assert log.OnroadEvent.EventName.controlsMismatch not in sd.events.names
|
||||
assert axis.faultReason == 'availabilityPause'
|
||||
assert not receive(10_000_000_000, axis=sd.pm.messages['aolAxisState'], event=sd.pm.messages['onroadEvents'])
|
||||
missing.remove('aolSafetyWire')
|
||||
axis, _, command = drive(1, allowed=False, native_request_lat=False, native_request_long=False)
|
||||
cs = caller_fixture.car_state()
|
||||
cs.buttonEvents = [structs.CarState.ButtonEvent(type='lkas', pressed=True)]
|
||||
assert receive(10_010_000_000, axis=sd.pm.messages['aolAxisState'], event=sd.pm.messages['onroadEvents'], state=cs)
|
||||
assert not command.latActive and not command.longActive
|
||||
assert axis.faultReason == 'availabilityPause'
|
||||
for tick in range(2, 5):
|
||||
axis, _, command = drive(tick, allowed=False, native_request_lat=False, native_request_long=False)
|
||||
assert receive(10_000_000_000 + tick * 10_000_000,
|
||||
axis=sd.pm.messages['aolAxisState'], event=sd.pm.messages['onroadEvents'])
|
||||
assert not command.latActive and not command.longActive
|
||||
assert axis.validUntilMonoTime - axis.observedMonoTime == 30_000_000
|
||||
missing.clear()
|
||||
for tick in range(5, 16):
|
||||
axis, _, command = drive(tick, allowed=True, native_request_lat=True, native_request_long=False)
|
||||
assert receive(10_000_000_000 + tick * 10_000_000,
|
||||
axis=sd.pm.messages['aolAxisState'], event=sd.pm.messages['onroadEvents'])
|
||||
assert axis.lateralActive and command.latActive and not command.longActive
|
||||
assert not sd.enabled and not sd.active
|
||||
assert card.aol_card_intent.allowed_latch
|
||||
finally:
|
||||
case.doCleanups()
|
||||
|
||||
|
||||
@pytest.mark.parametrize('fault', ('invalid_native', 'missing_after_receipt', 'missing_while_enabled', 'rx_fault', 'relay_fault'))
|
||||
def test_startup_native_wait_retains_fault_and_permission_checks(fault):
|
||||
from opendbc.car.hyundai.tests.test_palisade_2023 import params as blended_params
|
||||
from openpilot.cereal import log
|
||||
|
||||
case = caller_fixture.IoniqAvailabilityTests(methodName='runTest')
|
||||
with OpenpilotPrefix():
|
||||
try:
|
||||
sd, _, drive = case._authority_callers(fault == 'missing_while_enabled', cp=blended_params('hdaii'), genuine_events=True)
|
||||
original_receive = sd.sm.update_msgs
|
||||
missing = set()
|
||||
|
||||
def receive_sources(now, messages):
|
||||
return original_receive(now, [message for message in messages if message.which() not in missing])
|
||||
|
||||
if fault == 'missing_after_receipt':
|
||||
drive(0, latched=False, allowed=False, native_request_lat=False, native_request_long=False)
|
||||
assert sd.sm.seen['aolSafetyWire']
|
||||
missing.add('aolSafetyWire')
|
||||
elif fault == 'missing_while_enabled':
|
||||
missing.add('aolSafetyWire')
|
||||
sd.sm.seen['aolSafetyWire'] = sd.sm.valid['aolSafetyWire'] = sd.sm.alive['aolSafetyWire'] = False
|
||||
with patch.object(sd.sm, 'update_msgs', side_effect=receive_sources):
|
||||
axis, _, command = drive(30, latched=False, allowed=False, native_request_lat=False, native_request_long=False,
|
||||
native_valid=fault != 'invalid_native', panda_fault=fault == 'rx_fault',
|
||||
relay_fault=fault == 'relay_fault')
|
||||
assert log.OnroadEvent.EventName.controlsMismatch in sd.events.names
|
||||
assert not axis.lateralActive and not axis.longitudinalActive
|
||||
assert not command.latActive and not command.longActive
|
||||
assert axis.faultReason == 'critical'
|
||||
finally:
|
||||
case.doCleanups()
|
||||
|
||||
@@ -338,7 +338,7 @@ class IoniqAvailabilityTests(unittest.TestCase):
|
||||
return sd.pm.messages['aolAxisState'].aolAxisState, sd.pm.messages['selfdriveState'].selfdriveState, command
|
||||
return sd, controls, step
|
||||
|
||||
def _ioniq_availability_callers(self, full_op=True, *, initially_armed=True, stock_angle=False, cp=None):
|
||||
def _ioniq_availability_callers(self, full_op=True, *, initially_armed=True, stock_angle=False, cp=None, cold_start=False, startup_owner=None):
|
||||
from opendbc.car.hyundai.interface import CarInterface
|
||||
from opendbc.car.hyundai.radar_interface import RadarInterface
|
||||
from openpilot.selfdrive.car.card import Car
|
||||
@@ -363,8 +363,8 @@ class IoniqAvailabilityTests(unittest.TestCase):
|
||||
_, cp = candidate(True)
|
||||
cp.safetyConfigs[-1].safetyParam |= 0x0800
|
||||
sd, controls, step = self._authority_callers(full_op, cp=cp, genuine_events=True)
|
||||
card_cp = cp.as_reader().as_builder()
|
||||
card = Car(CI=CarInterface(card_cp), RI=RadarInterface(card_cp))
|
||||
card_cp = cp.as_reader().as_builder() if startup_owner is None else startup_owner.owner.cp
|
||||
card = Car(CI=CarInterface(card_cp), RI=RadarInterface(card_cp), startup_owner=startup_owner)
|
||||
self.assertEqual(card.CP.to_dict(), sd.CP.to_dict())
|
||||
self.assertEqual(card.CP.safetyConfigs[-1].safetyParam, cp.safetyConfigs[-1].safetyParam if stock_angle or supplied_profile else 0x8895)
|
||||
self.assertTrue(card.aol_card_intent.explicit_latch)
|
||||
@@ -412,7 +412,7 @@ class IoniqAvailabilityTests(unittest.TestCase):
|
||||
kwargs['observed_state'] = state
|
||||
return step(tick, **kwargs)
|
||||
|
||||
for tick in (0, 1):
|
||||
for tick in (() if cold_start else (0, 1)):
|
||||
axis, _, command = drive(tick)
|
||||
if full_op:
|
||||
self.assertTrue(axis.lateralActive and axis.longitudinalActive and command.latActive and command.longActive)
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
{"protected_inventory_sha256": "b77124d8cb762c0142394084c7a9683df83856033a3d5890f4b26579e6103197", "schema_version": 1}
|
||||
{"protected_inventory_sha256": "7a5367f4e7de8fcfda84fcef36fd862b3431f5a23aa9bc84342442e73cd129ef", "schema_version": 1}
|
||||
|
||||
Reference in New Issue
Block a user