mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-10-28 00:53:45 +08:00
Align HKG location regressions with shared armed intent policy
This commit is contained in:
@@ -23,7 +23,7 @@ from openpilot.starpilot.aol.runtime import current_native
|
||||
from openpilot.starpilot.aol.tests import test_ioniq_availability as caller_fixture
|
||||
from openpilot.starpilot.aol.tests.test_classic_location_stock_intent import host_heartbeat_bridge as host_heartbeat_bridge
|
||||
from openpilot.starpilot.aol.tests.test_classic_location_stock_intent import (
|
||||
assert_classic_location_independent_refusals as assert_stock_location_refusals,
|
||||
assert_stock_location_warning_contract as assert_stock_location_refusals,
|
||||
)
|
||||
from openpilot.starpilot.aol.wire import PandaSlot, SafetyState, encode_safety
|
||||
|
||||
|
||||
@@ -94,7 +94,7 @@ def _invalid_controls_emits_no_commands(received):
|
||||
|
||||
|
||||
|
||||
def assert_classic_location_independent_refusals(sd, card, state, now_ns):
|
||||
def assert_stock_location_warning_contract(sd, card, state, now_ns):
|
||||
from copy import copy
|
||||
from openpilot.starpilot.aol.wire import decode_safety
|
||||
|
||||
@@ -178,10 +178,22 @@ def assert_classic_location_independent_refusals(sd, card, state, now_ns):
|
||||
view.values['pandaStates'] = panda.as_reader().pandaStates
|
||||
native = dataclasses.replace(native, pandaInventory=tuple(inventory))
|
||||
view.values['aolSafetyWire'] = encode_safety(native)
|
||||
# Production dispatches location SOFT withdrawals through observe() and
|
||||
# the shared warning owner, rather than the older critical-only helper.
|
||||
view.values['aolAxisState'] = proof.as_reader()
|
||||
view.logMonoTime['aolAxisState'] = stamp
|
||||
before = (current.lateral_baseline_ns, current.lateral_native_ns)
|
||||
retained = current._temporary_host_intent_current(view, card.CP, cs, proof, stamp, now_ns,
|
||||
latched=card.aol_card_intent.allowed_latch, producer=feedback.availability_producer)
|
||||
assert retained == (fault == 'none'), fault
|
||||
retained = not current.observe(view, card.CP, cs, now_ns,
|
||||
latched=card.aol_card_intent.allowed_latch, intent_producer_session=feedback.availability_producer)
|
||||
# Pedals, belt and temporary EPS conditions preserve only armed intent.
|
||||
# A denied native LAT receipt while both host axes are withdrawn is also
|
||||
# a pause; it supplies no native permission and never resumes commands.
|
||||
# Classic independent AOL does not require the cruise MAIN level. This
|
||||
# is not a new MAIN button edge and cannot replay the configured toggle.
|
||||
expected = fault in ('none', 'seatbelt', 'brake', 'regen', 'gas', 'cancel', 'temporary_eps', 'native_denial') or (
|
||||
fault == 'main_off' and qualified_classic(card.CP, marked_only=True))
|
||||
assert retained == expected, (fault, current.__dict__)
|
||||
assert not original.aolAxisState.lateralActive and not original.aolAxisState.longitudinalActive
|
||||
assert (current.lateral_baseline_ns, current.lateral_native_ns) == before
|
||||
|
||||
|
||||
@@ -633,7 +645,7 @@ def test_real_classic_stock_engagement_then_location_loss_keeps_intent(raw_fault
|
||||
continue
|
||||
fault_ticks += 1
|
||||
if fault_ticks == 1:
|
||||
assert_classic_location_independent_refusals(sd, card, state, now[0])
|
||||
assert_stock_location_warning_contract(sd, card, state, now[0])
|
||||
assert log.OnroadEvent.EventName.pcmDisable in sd.events.names
|
||||
assert not axis.lateralActive and not axis.longitudinalActive
|
||||
assert not command.latActive and not command.longActive
|
||||
|
||||
@@ -81,7 +81,7 @@ def test_stock_pcm_location_input_pause_retains_intent_without_output(identity,
|
||||
@pytest.mark.parametrize('identity', [CAR.HYUNDAI_IONIQ_5_PE, CAR.KIA_EV9])
|
||||
@pytest.mark.parametrize('fault', ['native_denial', 'native_invalid', 'panda_rx', 'relay', 'permanent_eps',
|
||||
'invalid_can', 'can_timeout', 'door', 'seatbelt', 'brake', 'regen', 'physical_cancel', 'reverse', 'unknown_gear',
|
||||
'extra_user', 'hard_event', 'epoch', 'session', 'expired', 'future_source', 'no_baseline'])
|
||||
'extra_user', 'hard_event', 'epoch', 'session', 'expired', 'future_source', 'no_baseline', 'configured_cancel'])
|
||||
def test_stock_location_input_retention_refuses_independent_faults(identity, fault):
|
||||
case = fixture.IoniqAvailabilityTests(methodName='runTest')
|
||||
with ExitStack() as cleanup:
|
||||
@@ -107,7 +107,10 @@ def test_stock_location_input_retention_refuses_independent_faults(identity, fau
|
||||
state.seatbeltUnlatched = fault == 'seatbelt'
|
||||
state.brakePressed = fault == 'brake'
|
||||
state.regenBraking = fault == 'regen'
|
||||
if fault == 'physical_cancel':
|
||||
if fault == 'configured_cancel':
|
||||
from dataclasses import replace
|
||||
card.aol_card_intent.settings = replace(card.aol_card_intent.settings, cancel_actions=(9, 0, 0))
|
||||
if fault in ('physical_cancel', 'configured_cancel'):
|
||||
state.buttonEvents = [structs.CarState.ButtonEvent(type='cancel', pressed=True)]
|
||||
if fault in ('reverse', 'unknown_gear'):
|
||||
state.gearShifter = 'reverse' if fault == 'reverse' else 'unknown'
|
||||
@@ -124,7 +127,18 @@ def test_stock_location_input_retention_refuses_independent_faults(identity, fau
|
||||
if fault == 'future_source':
|
||||
proof.aolAxisState.sourceCarStateMonoTime = 10_030_000_000
|
||||
if fault == 'no_baseline':
|
||||
from openpilot.starpilot.aol.transport_pause import TransportPauseFeedback
|
||||
card.aol_transport_feedback = TransportPauseFeedback(card.CP)
|
||||
assert not receive(10_020_000_000, state=state, axis=proof.as_reader(), event=event.as_reader())
|
||||
assert not card.aol_card_intent.allowed_latch
|
||||
# Remove the established baseline without erasing its session/history.
|
||||
card.aol_transport_feedback.lateral_baseline_ns = 0
|
||||
# A physical pause is independent of the location SOFT warning. Current
|
||||
# native proof and zero host commands remain mandatory; unassigned CANCEL
|
||||
# preserves intent, whereas the explicitly configured CANCEL still clears.
|
||||
baseline = (card.aol_transport_feedback.lateral_baseline_ns, card.aol_transport_feedback.lateral_native_ns)
|
||||
retained = receive(10_020_000_000, state=state, axis=proof.as_reader(), event=event.as_reader())
|
||||
expected = fault in ('seatbelt', 'brake', 'regen')
|
||||
assert retained == expected, fault
|
||||
assert card.aol_card_intent.allowed_latch == expected
|
||||
assert not axis.lateralActive and not axis.longitudinalActive
|
||||
assert not command.latActive and not command.longActive
|
||||
if expected:
|
||||
assert baseline == (card.aol_transport_feedback.lateral_baseline_ns, card.aol_transport_feedback.lateral_native_ns)
|
||||
|
||||
|
||||
@@ -93,7 +93,7 @@ def test_existing_stock_hkg_location_and_nominal_pcm_off_keep_established_intent
|
||||
@pytest.mark.parametrize('family', ['canfd_radar', 'canfd_lka', 'canfd_lka_alt', 'canfd_camera', 'canfd_ccnc_camera'])
|
||||
@pytest.mark.parametrize('fault', ['native_denial', 'native_invalid', 'panda_rx', 'relay', 'permanent_eps',
|
||||
'invalid_can', 'can_timeout', 'door', 'seatbelt', 'brake', 'regen', 'gas', 'physical_cancel', 'reverse', 'unknown_gear',
|
||||
'extra_user', 'hard_event', 'epoch', 'session', 'expired', 'future_source', 'no_baseline'])
|
||||
'extra_user', 'hard_event', 'epoch', 'session', 'expired', 'future_source', 'no_baseline', 'configured_cancel'])
|
||||
def test_stock_location_never_retains_intent_through_independent_fault(family, fault):
|
||||
from opendbc.car import structs
|
||||
|
||||
@@ -134,7 +134,10 @@ def test_stock_location_never_retains_intent_through_independent_fault(family, f
|
||||
state.brakePressed = fault == 'brake'
|
||||
state.regenBraking = fault == 'regen'
|
||||
state.gasPressed = fault == 'gas'
|
||||
if fault == 'physical_cancel':
|
||||
if fault == 'configured_cancel':
|
||||
from dataclasses import replace
|
||||
card.aol_card_intent.settings = replace(card.aol_card_intent.settings, cancel_actions=(9, 0, 0))
|
||||
if fault in ('physical_cancel', 'configured_cancel'):
|
||||
state.buttonEvents = [structs.CarState.ButtonEvent(type='cancel', pressed=True)]
|
||||
if fault in ('reverse', 'unknown_gear'):
|
||||
state.gearShifter = 'reverse' if fault == 'reverse' else 'unknown'
|
||||
@@ -152,5 +155,16 @@ def test_stock_location_never_retains_intent_through_independent_fault(family, f
|
||||
proof.aolAxisState.sourceCarStateMonoTime = 10_060_000_000
|
||||
if fault == 'no_baseline':
|
||||
card.aol_transport_feedback.lateral_baseline_ns = 0
|
||||
assert not receive(10_050_000_001, state=state, axis=proof.as_reader(), event=event.as_reader())
|
||||
assert not card.aol_card_intent.allowed_latch
|
||||
# A physical pause is independent of the location SOFT warning. Current
|
||||
# native proof and zero host commands remain mandatory; unassigned CANCEL
|
||||
# preserves intent, whereas the explicitly configured CANCEL still clears.
|
||||
baseline = (card.aol_transport_feedback.lateral_baseline_ns, card.aol_transport_feedback.lateral_native_ns)
|
||||
retained = receive(10_050_000_001, state=state, axis=proof.as_reader(), event=event.as_reader())
|
||||
expected = fault in ('seatbelt', 'brake', 'regen', 'gas', 'physical_cancel')
|
||||
assert retained == expected, fault
|
||||
assert card.aol_card_intent.allowed_latch == expected
|
||||
assert not axis.lateralActive and not axis.longitudinalActive
|
||||
assert not command.latActive and not command.longActive
|
||||
if expected:
|
||||
assert baseline == (card.aol_transport_feedback.lateral_baseline_ns, card.aol_transport_feedback.lateral_native_ns)
|
||||
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
{"protected_inventory_sha256": "3a3c366dd4876659aa63861b1316f18d9db29ddd42b8b63f66b660f6faa97f77", "schema_version": 1}
|
||||
{"protected_inventory_sha256": "a8cf3e523e217d01bce30adf58c7478a7ca9a4216a754d6729da51111304172a", "schema_version": 1}
|
||||
|
||||
Reference in New Issue
Block a user