mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-11-12 15:33:45 +08:00
Qualify split HKG angle EPS publications
This commit is contained in:
@@ -37,12 +37,23 @@ jobs:
|
||||
opendbc_repo/opendbc/dbc
|
||||
openpilot/selfdrive/controls/lib/longitudinal_mpc_lib/c_generated_code/acados_ocp_solver_pyx.so
|
||||
openpilot/selfdrive/locationd/models/generated/libcar.so
|
||||
- name: Verify paired controller-default replay contract
|
||||
run: .venv/bin/python tools/ci/review_hkg_defaults/review.py
|
||||
- name: Run steering retention and independent safety veto regressions
|
||||
run: |
|
||||
.venv/bin/python -m pytest -q --junitxml=qualification.xml openpilot/starpilot/aol/tests/test_hkg_angle_eps_retention.py openpilot/starpilot/aol/tests/test_pe_combined_profile_contract.py openpilot/starpilot/aol/tests/test_stock_eps_recovery.py openpilot/starpilot/aol/tests/test_runtime.py openpilot/starpilot/aol/tests/test_source_pause_driver_monitoring.py openpilot/system/hardware/tests openpilot/starpilot/drive_state/tests/test_hardware_lifecycle.py openpilot/starpilot/ui/tests/test_weather.py openpilot/starpilot/flm/tests/test_pid_global_capture.py openpilot/starpilot/flm/tests/test_registered_controls_global.py::test_actual_controls_source_freshness_calibration_and_override_rejection openpilot/starpilot/lateral/tests/test_ev6_default.py openpilot/starpilot/lateral/tests/test_ioniq6_policy.py tools/ci/tests/test_replay_references.py
|
||||
- name: Check owned Python files
|
||||
run: |
|
||||
.venv/bin/ruff check openpilot/starpilot/aol/temporary_steering.py openpilot/starpilot/aol/tests/test_hkg_angle_eps_retention.py openpilot/starpilot/aol/transport_pause.py openpilot/system/hardware/hardwared.py openpilot/system/hardware/hardware_timing.py openpilot/system/hardware/tests/test_hardware_timing.py openpilot/starpilot/ui/tests/test_weather.py openpilot/starpilot/lateral/tests/test_ev6_default.py openpilot/starpilot/lateral/tests/test_ioniq6_policy.py
|
||||
.venv/bin/ty check openpilot/starpilot/aol/temporary_steering.py openpilot/starpilot/aol/tests/test_hkg_angle_eps_retention.py openpilot/starpilot/aol/transport_pause.py openpilot/system/hardware/hardwared.py openpilot/system/hardware/hardware_timing.py openpilot/system/hardware/tests/test_hardware_timing.py openpilot/starpilot/ui/tests/test_weather.py openpilot/starpilot/lateral/tests/test_ev6_default.py openpilot/starpilot/lateral/tests/test_ioniq6_policy.py
|
||||
- name: Compare both reviewed default-controller recordings
|
||||
run: .venv/bin/python openpilot/selfdrive/test/process_replay/test_processes.py --whitelist-cars HYUNDAI HYUNDAI2 --whitelist-procs controlsd --output reviewed-defaults -j2
|
||||
- name: Save exact results
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: hkg-angle-recovery-results
|
||||
path: |
|
||||
review-results/
|
||||
baseline.xml
|
||||
baseline-result.json
|
||||
qualification.xml
|
||||
reviewed-defaults/coverage.json
|
||||
reviewed-defaults/diff.txt
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
BIN
Binary file not shown.
@@ -1,4 +1,4 @@
|
||||
"""Untuned EV6 lateral selection and steering command boundaries."""
|
||||
"""EV6 vehicle-policy defaults and steering command boundaries."""
|
||||
|
||||
import unittest
|
||||
|
||||
@@ -15,6 +15,7 @@ from opendbc.car.hyundai.values import CAR, DBC, HyundaiFlags, CarControllerPara
|
||||
from opendbc.car.lateral import apply_driver_steer_torque_limits
|
||||
from openpilot.selfdrive.controls.lib.latcontrol_torque import LatControlTorque
|
||||
from openpilot.starpilot.lateral.torque_extension import selected_policy
|
||||
from openpilot.starpilot.lateral.hkg_vehicle_policy import HKGVehicleTorquePolicy
|
||||
from openpilot.starpilot.lateral.torque_runtime import runtime_enabled
|
||||
|
||||
|
||||
@@ -26,7 +27,7 @@ def ev6(lka_steering: bool):
|
||||
|
||||
|
||||
class TestEV6DefaultLateral(unittest.TestCase):
|
||||
def test_hda_topologies_keep_vehicle_tune_and_generic_controller(self):
|
||||
def test_hda_topologies_keep_vehicle_tune_and_vehicle_policy(self):
|
||||
for lka_steering in (False, True):
|
||||
with self.subTest(lka_steering=lka_steering), OpenpilotPrefix():
|
||||
cp = ev6(lka_steering)
|
||||
@@ -40,7 +41,8 @@ class TestEV6DefaultLateral(unittest.TestCase):
|
||||
self.assertFalse(runtime_enabled(cp, Params()))
|
||||
self.assertEqual(cp.lateralTuning.to_dict(), original_tune)
|
||||
lateral = LatControlTorque(cp.as_reader(), CarInterface(cp), DT_CTRL)
|
||||
self.assertIsNone(selected_policy(lateral))
|
||||
self.assertIsInstance(selected_policy(lateral), HKGVehicleTorquePolicy)
|
||||
self.assertEqual(selected_policy(lateral).profile, "kia_ev6")
|
||||
self.assertAlmostEqual(lateral.torque_params.latAccelFactor, cp.lateralTuning.torque.latAccelFactor)
|
||||
controller = CarController(DBC[cp.carFingerprint], cp)
|
||||
self.assertIsNone(controller.ioniq6_longitudinal)
|
||||
|
||||
@@ -28,7 +28,7 @@ def _legacy_friction(controller, error, deadzone, threshold, _cs, _setpoint):
|
||||
|
||||
|
||||
def _rows(car, sequence, *, profile='2023', matched_frozen_cp=False, passive=False, direct_original_controller=False, turn_assist=True,
|
||||
roll=None):
|
||||
roll=None, controller_mode=None):
|
||||
cp = interfaces[car].get_non_essential_params(car)
|
||||
cp.passive = passive
|
||||
if matched_frozen_cp:
|
||||
@@ -44,7 +44,7 @@ def _rows(car, sequence, *, profile='2023', matched_frozen_cp=False, passive=Fal
|
||||
versions[0].fwVersion = b'IONIQ6-230915'
|
||||
versions[1].fwVersion = b'IONIQ6-240206'
|
||||
ci = interfaces[car](cp)
|
||||
controller = LatControlTorque(cp.as_reader(), ci, DT_CTRL, turn_assist=turn_assist)
|
||||
controller = LatControlTorque(cp.as_reader(), ci, DT_CTRL, turn_assist=turn_assist, controller_mode=controller_mode)
|
||||
if direct_original_controller:
|
||||
# The older frozen vectors called the controller directly, before the
|
||||
# original controlsd drive loop replaced the PID gain curve each tick.
|
||||
@@ -178,7 +178,8 @@ class Ioniq6PolicyTests(unittest.TestCase):
|
||||
parent = json.loads((TESTDATA / 'non_ioniq_parent.json').read_text())
|
||||
for car in (TOYOTA.TOYOTA_COROLLA_TSS2, HYUNDAI.HYUNDAI_IONIQ_5):
|
||||
with self.subTest(car=str(car)):
|
||||
controller, actual = _rows(car, sequence, passive=car == TOYOTA.TOYOTA_COROLLA_TSS2, turn_assist=False)
|
||||
controller, actual = _rows(car, sequence, passive=car == TOYOTA.TOYOTA_COROLLA_TSS2, turn_assist=False,
|
||||
controller_mode='standard')
|
||||
self.assertIsNone(selected_policy(controller))
|
||||
for row, expected in zip(actual, parent[str(car)], strict=True):
|
||||
for value, reference in zip(row, expected, strict=True):
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
def default_selection(CP) -> ControllerSelection:
|
||||
policy = policy_for(CP)
|
||||
from openpilot.starpilot.lateral.hkg_vehicle_policy import PROFILES
|
||||
forte_non_scc = policy == 'kia_forte' and str(CP.carFingerprint) in ('KIA_FORTE_2019_NON_SCC', 'KIA_FORTE_2021_NON_SCC')
|
||||
dom_default = forte_non_scc or policy == 'kia_carnival'
|
||||
mode = ControllerMode.STARPILOT if policy and policy != 'generic' and (policy not in PROFILES or dom_default) else ControllerMode.STANDARD
|
||||
return ControllerSelection(mode, policy, 'default')
|
||||
Binary file not shown.
@@ -1,38 +0,0 @@
|
||||
from pathlib import Path
|
||||
import ast,hashlib,json,subprocess,sys
|
||||
R=Path.cwd();D=Path(__file__).parent;O=R/'review-results';O.mkdir(exist_ok=True)
|
||||
selection=R/'openpilot/starpilot/lateral/controller_selection.py'
|
||||
original=selection.read_bytes();text=original.decode();node=next(n for n in ast.parse(text).body if isinstance(n,ast.FunctionDef) and n.name=='default_selection')
|
||||
current=ast.get_source_segment(text,node);previous=(D/'old_default.txt').read_text().rstrip()
|
||||
assert hashlib.sha256((previous+'\n').encode()).hexdigest()=='c046839822779ce34ef902bc5698ee894a164880bdceb38d2473bde71c2a3aa2'
|
||||
assert text.count(current)==1
|
||||
args=[sys.executable,'openpilot/selfdrive/test/process_replay/test_processes.py','--whitelist-cars','HYUNDAI','HYUNDAI2','--whitelist-procs','controlsd','-j2']
|
||||
def run(label,expected):
|
||||
result=subprocess.run([*args,'--output',str(O/label)],stdout=subprocess.PIPE,stderr=subprocess.STDOUT)
|
||||
(O/(label+'.log')).write_bytes(result.stdout)
|
||||
print(label,'returncode',result.returncode,flush=True)
|
||||
assert result.returncode==expected,result.stdout.decode(errors='replace')[-3000:]
|
||||
try:
|
||||
selection.write_text(text.replace(current,previous))
|
||||
run('previous-default',0)
|
||||
finally:
|
||||
selection.write_bytes(original)
|
||||
assert selection.read_bytes()==original
|
||||
run('current-default',1)
|
||||
from openpilot.selfdrive.test.process_replay.process_replay import CONFIGS
|
||||
from openpilot.selfdrive.test.process_replay.compare_logs import compare_logs
|
||||
from openpilot.selfdrive.test.process_replay.test_processes import get_log_data
|
||||
from openpilot.tools.lib.logreader import LogReader
|
||||
from tools.ci.replay_references import config_signature
|
||||
cfg=next(c for c in CONFIGS if c.proc_name=='controlsd');rows=[]
|
||||
for segment in ('regenAA0FC4ED71E|2025-04-08--22-57-50--0','regenAFB9780D823|2025-04-08--23-00-34--0'):
|
||||
stem=segment.replace('|','_')+'_controlsd';fresh=next((O/'current-default/new').glob(stem+'_*.zst'));prior=next((O/'previous-default/new').glob(stem+'_*.zst'));expected=D/(stem+'.zst')
|
||||
fresh_msgs=list(LogReader(str(fresh)));expected_msgs=list(LogReader(str(expected)));prior_msgs=list(LogReader(str(prior)))
|
||||
diffs=compare_logs(expected_msgs,fresh_msgs,cfg.ignore,[],cfg.tolerance);assert not diffs,str(diffs[:3])
|
||||
assert {m.controlsState.lateralControlState.torqueState.version for m in fresh_msgs if m.which()=='controlsState'}=={2}
|
||||
assert {m.controlsState.lateralControlState.torqueState.version for m in prior_msgs if m.which()=='controlsState'}=={1}
|
||||
assert any(m.which()=='carControl' and m.carControl.latActive and abs(m.carControl.actuators.torque)>.01 for m in fresh_msgs)
|
||||
_,raw,params=get_log_data(segment);cp=next(e.carParams for e in LogReader.from_bytes(raw) if e.which()=='carParams')
|
||||
rows.append({'segment':segment,'process':'controlsd','input_sha256':hashlib.sha256(raw).hexdigest(),'input_bytes':len(raw),'config_sha256':config_signature(cfg),'car_fingerprint':cp.carFingerprint,'expected_file':expected.name,'expected_bytes':expected.stat().st_size,'expected_sha256':hashlib.sha256(expected.read_bytes()).hexdigest(),'messages':len(fresh_msgs),'current_vs_published_differences':len(diffs),'previous_default_vs_prior_reference_differences':0,'old_version':1,'current_version':2,'fixture_param_keys':sorted(params or {})})
|
||||
result={'sourceCommit':subprocess.check_output(['git','rev-parse','HEAD'],text=True).strip(),'shippingSourceRestored':selection.read_bytes()==original,'selection_sha256':hashlib.sha256(original).hexdigest(),'old_default_sha256':hashlib.sha256((previous+'\n').encode()).hexdigest(),'extraIgnoredFields':[],'extraIgnoredMessages':[],'comparisons':'Original complete-message comparator and original configuration/tolerances','intentionalCommit':'13839683908c449dfbb055cb4950e339ed2b1a1f','rows':rows}
|
||||
(O/'paired-review.json').write_text(json.dumps(result,indent=2));print(json.dumps(result),flush=True)
|
||||
Reference in New Issue
Block a user