mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-10-28 17:13:54 +08:00
Merge qualified HKG and MQB source
This commit is contained in:
@@ -244,7 +244,13 @@ class PEPendingStartup:
|
||||
self._tester()
|
||||
self.check()
|
||||
self.thread = self.thread_factory(target=self._loop, name='pe-startup-tester', daemon=True)
|
||||
self.thread.start()
|
||||
try:
|
||||
self.thread.start()
|
||||
except BaseException:
|
||||
self.stop_event.set()
|
||||
if getattr(self.thread, 'ident', None) is None:
|
||||
self.thread = None
|
||||
raise
|
||||
except BaseException:
|
||||
self.owner.phase = Phase.ABORT
|
||||
self._restore()
|
||||
|
||||
@@ -183,11 +183,28 @@ def test_actual_card_publisher_keeps_sibling_diagnostics_until_sent(identity, pa
|
||||
|
||||
@pytest.mark.parametrize('identity', [CAR.KIA_EV9, CAR.HYUNDAI_IONIQ_5, CAR.HYUNDAI_KONA_EV_2ND_GEN])
|
||||
def test_existing_keeper_owners_close_after_real_thread_launch_failure(identity):
|
||||
from opendbc.car.hyundai.tests.test_ioniq5pe_stock import params as ev9_params
|
||||
from openpilot.starpilot.vehicle_startup import VehicleStartupOwner
|
||||
|
||||
if identity == CAR.KIA_EV9:
|
||||
cp = ev9_params(candidate=identity)
|
||||
import threading
|
||||
from opendbc.car.hyundai.tests.test_ev9_pending_startup import pending_startup_fixture
|
||||
|
||||
with pending_startup_fixture() as (fixture, owner, ci, packer):
|
||||
fixture.warm(owner, ci, packer)
|
||||
published = ci.CP.to_dict()
|
||||
owner.thread_factory = threading.Thread
|
||||
with patch('threading.Thread.start', side_effect=OSError('launch failed')):
|
||||
with pytest.raises(OSError, match='launch failed'):
|
||||
try:
|
||||
fixture.commit(owner, ci)
|
||||
finally:
|
||||
owner.close()
|
||||
assert owner.closed and owner.restored and owner.close_completed
|
||||
assert owner.thread is None and owner.stop_event.is_set()
|
||||
assert owner.fault and not owner.owner.active() and not owner.can_emit(ci.CC)
|
||||
assert owner.owner.published and ci.CP.to_dict() == published
|
||||
assert [request for request, _ in fixture.queries[-3:]] == [b'\x10\x03', b'\x28\x00\x01', b'\x10\x01']
|
||||
return
|
||||
else:
|
||||
fp = gen_empty_fingerprint()
|
||||
fp[2].update({0x50: 16, 0x2A4: 24})
|
||||
@@ -197,8 +214,6 @@ def test_existing_keeper_owners_close_after_real_thread_launch_failure(identity)
|
||||
sent = []
|
||||
owner = CarInterface.startup_owner(cp, (list, sent.extend), requested=True)
|
||||
assert owner is not None
|
||||
if identity == CAR.KIA_EV9:
|
||||
owner._ready = lambda: False
|
||||
requests = []
|
||||
|
||||
def query(send, recv, bus, addresses, commands, responses):
|
||||
|
||||
@@ -507,9 +507,16 @@ class TestHyundaiLongitudinalSafetyCameraSCCRefreshHybrid(HyundaiRefreshHybridGa
|
||||
self.packer = CANPackerSafety("hyundai_can_refresh_generated")
|
||||
self.safety = libsafety_py.libsafety
|
||||
flags = HyundaiSafetyFlags.CAMERA_SCC | HyundaiSafetyFlags.CAN_REFRESH_MSGS | HyundaiSafetyFlags.HYBRID_GAS | HyundaiSafetyFlags.LONG
|
||||
self.safety.set_alternative_experience(0)
|
||||
self.safety.set_safety_hooks(CarParams.SafetyModel.hyundai, flags)
|
||||
self.safety.init_tests()
|
||||
|
||||
def test_set_resume_buttons(self):
|
||||
self.assertFalse(self.safety.get_controls_allowed())
|
||||
self.assertTrue(self._rx(self._button_msg(0, main_button=1)))
|
||||
self.assertTrue(self._rx(self._button_msg(0, main_button=0)))
|
||||
super().test_set_resume_buttons()
|
||||
|
||||
def test_hybrid_long_refresh_length_and_acc_allowlist(self):
|
||||
self.assertTrue(self._tx(common.make_msg(0, 0x485, 8)))
|
||||
self.assertFalse(self._tx(common.make_msg(0, 0x485, 4)))
|
||||
|
||||
@@ -37,7 +37,8 @@ class TestBlendedCruiseAcknowledgment(unittest.TestCase):
|
||||
helper.v_cruise_kph = helper.v_cruise_kph_last = 90.
|
||||
instance = SimpleNamespace(sm={'carControl': SimpleNamespace(enabled=True)},
|
||||
CC_prev=SimpleNamespace(enabled=False), CS_prev=previous,
|
||||
experimental_mode=False, is_metric=True, vehicle_startup=holder, v_cruise_helper=helper)
|
||||
experimental_mode=False, is_metric=True, initial_cruise_speed=V_CRUISE_INITIAL,
|
||||
vehicle_startup=holder, v_cruise_helper=helper)
|
||||
Car.update_cruise_speed(cast(Car, instance), previous)
|
||||
self.assertIsNone(holder.consume_cruise_resume())
|
||||
return helper.v_cruise_kph
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import unittest
|
||||
from functools import cache
|
||||
|
||||
from opendbc.can import CANPacker
|
||||
from opendbc.car.structs import CarParams
|
||||
@@ -8,7 +9,16 @@ from opendbc.safety.tests.libsafety import libsafety_py
|
||||
from opendbc.safety.tests.test_hyundai_ev9_long import Ev9LongFixture
|
||||
|
||||
|
||||
@cache
|
||||
def release_safety():
|
||||
default = libsafety_py.libsafety
|
||||
library = libsafety_py.ffi.dlopen(libsafety_py._build_libsafety(release=True))
|
||||
assert libsafety_py.libsafety is default
|
||||
return library
|
||||
|
||||
|
||||
class PEFixture:
|
||||
RELEASE_NATIVE = False
|
||||
|
||||
packet = Ev9LongFixture.packet
|
||||
feed = Ev9LongFixture.feed
|
||||
@@ -16,7 +26,7 @@ class PEFixture:
|
||||
ready = Ev9LongFixture.ready
|
||||
|
||||
def setUp(self):
|
||||
self.safety = libsafety_py.libsafety
|
||||
self.safety = release_safety() if self.RELEASE_NATIVE else libsafety_py.libsafety
|
||||
self.packer = CANPacker('hyundai_canfd_generated')
|
||||
self.safety.init_tests()
|
||||
self.safety.set_alternative_experience(0)
|
||||
@@ -177,6 +187,8 @@ class TestPELongDebug(PEFixture, unittest.TestCase):
|
||||
|
||||
|
||||
class TestPELongReleaseDenied(PEFixture, unittest.TestCase):
|
||||
RELEASE_NATIVE = True
|
||||
|
||||
def test_release_never_admits_proposed_pe_long_profile(self):
|
||||
|
||||
for _ in range(6):
|
||||
|
||||
@@ -8,6 +8,8 @@ from opendbc.safety.tests.test_hyundai_ev9_long import Ev9LongFixture
|
||||
|
||||
|
||||
class TestPECombinedReleaseDenied(PEFixture, unittest.TestCase):
|
||||
RELEASE_NATIVE = True
|
||||
|
||||
def test_combined_pe_profile_has_no_transmit_authority_in_release(self):
|
||||
self.safety.set_alternative_experience(32)
|
||||
self.assertEqual(self.safety.set_safety_hooks(CarParams.SafetyModel.hyundaiCanfd, 0x5495), 0)
|
||||
|
||||
@@ -29,7 +29,7 @@ from openpilot.cereal import log
|
||||
disable_ecu_module = importlib.import_module('opendbc.car.disable_ecu')
|
||||
|
||||
|
||||
def classic_frames(ci, tick, *, main=0, lkas=0, button=0, engaged=False):
|
||||
def classic_frames(ci, tick, *, main=0, main_button=0, lkas=0, button=0, engaged=False):
|
||||
|
||||
assert ci.CP.carFingerprint == CAR.HYUNDAI_SONATA_HYBRID
|
||||
packer = CANPacker('hyundai_can_generated')
|
||||
@@ -52,7 +52,7 @@ def classic_frames(ci, tick, *, main=0, lkas=0, button=0, engaged=False):
|
||||
counter = tick // period
|
||||
values = {}
|
||||
if name == 'CLU11':
|
||||
values.update(CF_Clu_AliveCnt1=counter%16, CF_Clu_CruiseSwState=button, CF_Clu_CruiseSwMain=main)
|
||||
values.update(CF_Clu_AliveCnt1=counter%16, CF_Clu_CruiseSwState=button, CF_Clu_CruiseSwMain=main_button)
|
||||
elif name == 'E_EMS11':
|
||||
values.update(CR_Vcu_AccPedDep_Pos=0)
|
||||
elif name == 'WHL_SPD11':
|
||||
@@ -204,7 +204,7 @@ def test_full_engagement_arms_aol_through_stock_off_with_main_on(raw_fault, with
|
||||
return send(service, raw)
|
||||
local.setattr(card.pm, 'send', capture)
|
||||
|
||||
def step(*, main=1, lkas=0, button=0, engaged=False, withdraw_request=False, bad_checksum=False,
|
||||
def step(*, main=1, main_button=0, lkas=0, button=0, engaged=False, withdraw_request=False, bad_checksum=False,
|
||||
heartbeat_override=None, inject_relay=False, drop_wheel=False):
|
||||
nonlocal tick
|
||||
tick += 1
|
||||
@@ -219,7 +219,7 @@ def test_full_engagement_arms_aol_through_stock_off_with_main_on(raw_fault, with
|
||||
native.set_timer(source_ns // 1000)
|
||||
native.set_aol_test_heartbeat(heartbeat if heartbeat_override is None else heartbeat_override)
|
||||
native.aol_set_host_request(request)
|
||||
frames = classic_frames(card.CI, tick, main=main, lkas=lkas, button=button, engaged=engaged)
|
||||
frames = classic_frames(card.CI, tick, main=main, main_button=main_button, lkas=lkas, button=button, engaged=engaged)
|
||||
if drop_wheel:
|
||||
frames = [frame for frame in frames if frame[0] != 0x386]
|
||||
if bad_checksum:
|
||||
@@ -352,6 +352,10 @@ def test_full_engagement_arms_aol_through_stock_off_with_main_on(raw_fault, with
|
||||
assert card.aol_card_intent.allowed_latch and not card.aol_card_intent.pause_lateral
|
||||
assert not state.cruiseState.enabled and state.cruiseState.available
|
||||
assert native_counts['lateral_only_nonzero'] > 0
|
||||
assert not card.aol_card_intent._main_held
|
||||
if withdrawal == 'main-off':
|
||||
for _ in range(2):
|
||||
step(main=0, main_button=1, engaged=False)
|
||||
if withdrawal == 'lkas-off':
|
||||
for _ in range(2):
|
||||
step(main=1, lkas=1, engaged=False)
|
||||
|
||||
@@ -571,7 +571,14 @@ def run(
|
||||
|
||||
drain(control_socket, control, messaging.recv_one_or_none, sink, now)
|
||||
drain(applied_socket, output, messaging.recv_one_or_none, sink, now)
|
||||
source_valid, now = source_current()
|
||||
if collector is not None:
|
||||
# Decoding queued frames may outlast the sampled shared inputs. Consume
|
||||
# real pending deliveries before pose/native checks; keep their original
|
||||
# headers and receipts for the next iteration instead of polling twice.
|
||||
source_delivery.refresh(sm)
|
||||
source_valid, now = source_current(read=collector is not None)
|
||||
if tracking_pose_header < source_delivery.pose_header <= now:
|
||||
tracking_pose_header = source_delivery.pose_header
|
||||
current_native = False
|
||||
if source_valid and collector is not None and collector.ready:
|
||||
current_native = current_native_health(sm, CP, collector.ready[-1][0], now)
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
"""Actual daemon scheduling only; synthetic collector is not fit/native proof."""
|
||||
from types import SimpleNamespace as S
|
||||
import pytest
|
||||
from openpilot.starpilot.flm import steerlearnerd
|
||||
from openpilot.starpilot.flm.tests.test_live_tracking_daemon import BASE, source
|
||||
|
||||
|
||||
@pytest.mark.parametrize('fresh_allowed', [True, False])
|
||||
def test_pose_observer_consumes_delivery_that_arrived_during_decoding(monkeypatch, fresh_allowed):
|
||||
now = [BASE]
|
||||
class Stop(Exception):
|
||||
pass
|
||||
class SM:
|
||||
updated = {'deviceMotion': False}
|
||||
logMonoTime = {'deviceMotion': BASE}
|
||||
marker = 'old'
|
||||
pending = False
|
||||
def update(self, timeout=None):
|
||||
if timeout == 0 and self.pending:
|
||||
self.marker = 'new'
|
||||
self.updated['deviceMotion'] = True
|
||||
self.logMonoTime['deviceMotion'] = now[0]
|
||||
self.pending = False
|
||||
sm = SM()
|
||||
evidence = S(source_epoch='b'*64, source_receipt_ns=BASE, control_ns=BASE,
|
||||
identity='a'*64, generation=1, domain='normalized_torque', stage_revision='stage',
|
||||
response_revision='response', controller_mode='torque', policy='policy',
|
||||
baseline_revision='d'*64, controller_revision='controller', turn_assist=False)
|
||||
adapter = S(event_collection=True, source_plant_protocol='fixture',
|
||||
bind_source=lambda value: None, select_objective=lambda key: None, prepare_control=lambda value: value)
|
||||
collector = S(adapter=adapter, ready=[(evidence, object())], control=lambda *args: None)
|
||||
monkeypatch.setattr('openpilot.starpilot.flm.event_collector.EventFullrateCollector', lambda value: collector)
|
||||
monkeypatch.setattr('openpilot.starpilot.flm.source_plant_runtime.start_original_capture', lambda value: True)
|
||||
monkeypatch.setattr('openpilot.starpilot.flm.native_health.current_native_health',
|
||||
lambda *args: sm.marker == 'new' and fresh_allowed)
|
||||
monkeypatch.setattr(steerlearnerd, 'read_control', lambda event: evidence)
|
||||
seen = []
|
||||
def observe(_sm, cp, current, stamp, native):
|
||||
seen.append((_sm.marker, stamp, native, _sm.logMonoTime['deviceMotion']))
|
||||
raise Stop
|
||||
monkeypatch.setattr('openpilot.starpilot.flm.source_plant_runtime.observe', observe)
|
||||
control_socket, applied_socket = object(), object()
|
||||
def drain(sock, callback, *args):
|
||||
if sock is control_socket:
|
||||
callback(S(which=lambda:'starpilotLateralState', starpilotLateralState=S(learningEvidence=S(version=1))), None, BASE)
|
||||
else:
|
||||
now[0] += 80_000_000
|
||||
sm.pending = True
|
||||
monkeypatch.setattr(steerlearnerd, 'drain', drain)
|
||||
actor=S(ingress=None, interrupt=lambda *a,**k: None, close=lambda *a: True)
|
||||
fitter=S(cancel=lambda *a: None, close=lambda *a: True)
|
||||
with pytest.raises(Stop):
|
||||
steerlearnerd.run(S(),sm,control_socket,applied_socket,S(),lambda *a:adapter,None,
|
||||
lambda stamp:source(stamp),lambda value:('objective',),lambda value:'objective',
|
||||
None,None,fitter,None,clock=lambda:now[0],live_actor=actor)
|
||||
assert seen == [('new', BASE+80_000_000, fresh_allowed, BASE+80_000_000)]
|
||||
assert sm.logMonoTime['deviceMotion'] == BASE+80_000_000
|
||||
+1
-1
@@ -1 +1 @@
|
||||
{"protected_inventory_sha256": "fd982ffeecd96a97883067e2a73d2d794c594ea548cc5c7bd82ad98e076f88d7", "schema_version": 1}
|
||||
{"protected_inventory_sha256": "fd1aca7f7dace9d37ff77f6dbd3da45e95cf674ac48b3bb1a0a26ddad8f3435f", "schema_version": 1}
|
||||
|
||||
Reference in New Issue
Block a user