mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-11-08 13:33:42 +08:00
100 lines
5.1 KiB
Python
100 lines
5.1 KiB
Python
"""Real selected LaC/native calls; unit-issued live witness is not physical proof."""
|
|
|
|
from dataclasses import replace
|
|
from types import SimpleNamespace
|
|
import math
|
|
import pytest
|
|
from openpilot.starpilot.flm.live_trial_owner import TrackingTrialOwner
|
|
from openpilot.starpilot.flm.tests.test_live_trial_owner import offer
|
|
|
|
|
|
@pytest.mark.parametrize('domain', ['torque', 'starpilot', 'pid'])
|
|
@pytest.mark.parametrize('curvature', [-0.0003, 0.0003])
|
|
def test_actual_controller_hooks_and_native_packet_are_preserved(domain, curvature):
|
|
from openpilot.starpilot.flm.controller_replay import SelectedControllerFactory
|
|
from openpilot.starpilot.flm.pid_controller_replay import PidControllerFactory
|
|
from openpilot.starpilot.flm.tests.test_event_lazy_native import TOYOTA, HYUNDAI, HONDA, make_interface, install_observer, settle, control, apply, BASE_NS
|
|
|
|
platform = {'torque': TOYOTA.TOYOTA_COROLLA_TSS2, 'starpilot': HYUNDAI.HYUNDAI_IONIQ_6, 'pid': HONDA.HONDA_CIVIC}[domain]
|
|
ci = make_interface(platform)
|
|
assert install_observer(ci)
|
|
settle(ci, control(0.0))
|
|
factory = PidControllerFactory(ci.CP, 'native') if domain == 'pid' else SelectedControllerFactory(ci.CP, 'starpilot' if domain == 'starpilot' else 'standard')
|
|
controller, vm = factory.create()
|
|
from openpilot.starpilot.flm.global_runtime import GlobalRuntime
|
|
runtime = GlobalRuntime(ci.CP, ci, controller)
|
|
assert runtime.descriptor is not None
|
|
assert runtime.descriptor.domain == ('torque_pid' if domain == 'pid' else 'torque')
|
|
assert controller.automatic_flm_observation is runtime.observation and runtime.observation is not None
|
|
if domain != 'pid':
|
|
assert controller.automatic_flm_stages is runtime and controller.automatic_flm_centre is runtime
|
|
start = BASE_NS + ci.CC.frame * 10_000_000
|
|
o = offer(start)
|
|
owner = TrackingTrialOwner(o.binding, domain='torque_pid' if domain == 'pid' else 'torque')
|
|
seen = 0
|
|
from openpilot.starpilot.flm.live_tracking_response import ResponseWitness, prepare_response_witness, validate_response_witness
|
|
|
|
raw = validate_response_witness(o.response_witness, o.binding, start)
|
|
for tick in range(120):
|
|
now = start + tick * 10_000_000
|
|
if tick % 5 == 0:
|
|
w = prepare_response_witness(
|
|
ResponseWitness(
|
|
raw.certificate, o.binding, now - raw.certificate.lag_ns, now - raw.certificate.lag_ns, now, start - 500_000_000, 8, 0.001, now + 100_000_000
|
|
),
|
|
o.binding,
|
|
now,
|
|
)
|
|
current = replace(o, sequence=tick // 5 + 1, observed_ns=now, expires_ns=now + 100_000_000, response_witness=w)
|
|
assert owner.prepare(current, now_ns=now, permission=True, binding=o.binding)
|
|
runtime.observation.begin_frame()
|
|
controller.automatic_flm_effects = owner
|
|
result, _, _ = controller.update(True, ci.CS.out, vm, SimpleNamespace(angleOffsetDeg=0.0, roll=0.0), False, curvature, False, 0.2)
|
|
assert math.isfinite(float(result)) and abs(float(result)) <= 1.0
|
|
assert owner.used and owner.source.stage_calls == 1
|
|
assert owner.frame_complete(owner.domain)
|
|
ack = owner.acknowledge_frame(True)
|
|
assert ack is not None and ack.status == 'applied'
|
|
if domain == 'pid':
|
|
assert owner.source.pid_error_calls == 1
|
|
else:
|
|
assert owner.source.friction_calls == 1
|
|
_, packets, witness = apply(ci, control(float(result)))
|
|
if witness is not None:
|
|
seen += 1
|
|
assert (witness.can_address, witness.can_data, witness.can_bus) in packets
|
|
assert seen > 0
|
|
assert owner.applied_full['ff_gain_left'] == pytest.approx(0.005)
|
|
# A confirmed acknowledgement requires the actual domain hooks again.
|
|
now = start + 1_200_000_000
|
|
w = prepare_response_witness(
|
|
ResponseWitness(
|
|
raw.certificate, o.binding, now - raw.certificate.lag_ns, now - raw.certificate.lag_ns, now, start - 500_000_000, 8, 0.001, now + 100_000_000
|
|
),
|
|
o.binding,
|
|
now,
|
|
)
|
|
confirmed = replace(o, phase='confirmed', sequence=25, observed_ns=now, expires_ns=now + 100_000_000, response_witness=w)
|
|
assert owner.prepare(confirmed, now_ns=now, permission=True, binding=o.binding)
|
|
runtime.observation.begin_frame()
|
|
controller.automatic_flm_effects = owner
|
|
controller.update(True, ci.CS.out, vm, SimpleNamespace(angleOffsetDeg=0.0, roll=0.0), False, curvature, False, 0.2)
|
|
ack = owner.acknowledge_frame(True)
|
|
assert ack is not None and ack.status == 'applied' and ack.confirmed_target_sha256 == o.target_sha256
|
|
assert owner.confirmed_full == o.target
|
|
owner.neutral('driver_override')
|
|
controller.automatic_flm_effects = owner
|
|
assert owner.source is None and not any(owner.applied_full.values())
|
|
assert owner.acknowledge_frame(True) is None
|
|
|
|
|
|
def test_pid_registry_keeps26_and_exact4_unsupported():
|
|
from openpilot.starpilot.flm.pid_stages import SUPPORTED, UNSUPPORTED
|
|
from openpilot.starpilot.flm.canonical_surface_adapter import NAMES
|
|
|
|
assert len(NAMES) == 30 and len(SUPPORTED) == 26 and len(UNSUPPORTED) == 4
|
|
assert set(SUPPORTED) | set(UNSUPPORTED) == set(NAMES)
|
|
assert UNSUPPORTED == frozenset(
|
|
('turn_in_threshold_reduction_left', 'turn_in_threshold_reduction_right', 'unwind_threshold_increase_left', 'unwind_threshold_increase_right')
|
|
)
|