wip
This commit is contained in:
@@ -10,6 +10,7 @@ from openpilot.selfdrive.car.nissan.values import CAR as NISSAN
|
||||
from openpilot.selfdrive.car.mazda.values import CAR as MAZDA
|
||||
from openpilot.selfdrive.car.subaru.values import CAR as SUBARU
|
||||
from openpilot.selfdrive.car.toyota.values import CAR as TOYOTA
|
||||
from openpilot.selfdrive.car.values import Platform
|
||||
from openpilot.selfdrive.car.volkswagen.values import CAR as VOLKSWAGEN
|
||||
from openpilot.selfdrive.car.tesla.values import CAR as TESLA
|
||||
from openpilot.selfdrive.car.body.values import CAR as COMMA
|
||||
@@ -29,7 +30,7 @@ non_tested_cars = [
|
||||
|
||||
class CarTestRoute(NamedTuple):
|
||||
route: str
|
||||
car_model: str | None
|
||||
car_model: Platform | None
|
||||
segment: int | None = None
|
||||
|
||||
|
||||
@@ -229,7 +230,7 @@ routes = [
|
||||
|
||||
CarTestRoute("202c40641158a6e5|2021-09-21--09-43-24", VOLKSWAGEN.ARTEON_MK1),
|
||||
CarTestRoute("2c68dda277d887ac|2021-05-11--15-22-20", VOLKSWAGEN.ATLAS_MK1),
|
||||
#CarTestRoute("ffcd23abbbd02219|2024-02-28--14-59-38", VOLKSWAGEN.CADDY_MK3),
|
||||
CarTestRoute("ffcd23abbbd02219|2024-02-28--14-59-38", VOLKSWAGEN.CADDY_MK3),
|
||||
CarTestRoute("cae14e88932eb364|2021-03-26--14-43-28", VOLKSWAGEN.GOLF_MK7), # Stock ACC
|
||||
CarTestRoute("3cfdec54aa035f3f|2022-10-13--14-58-58", VOLKSWAGEN.GOLF_MK7), # openpilot longitudinal
|
||||
CarTestRoute("58a7d3b707987d65|2021-03-25--17-26-37", VOLKSWAGEN.JETTA_MK7),
|
||||
@@ -289,7 +290,7 @@ routes = [
|
||||
|
||||
CarTestRoute("6c14ee12b74823ce|2021-06-30--11-49-02", TESLA.AP1_MODELS),
|
||||
CarTestRoute("bb50caf5f0945ab1|2021-06-19--17-20-18", TESLA.AP2_MODELS),
|
||||
#CarTestRoute("66c1699b7697267d/2024-03-03--13-09-53", TESLA.MODELS_RAVEN),
|
||||
CarTestRoute("66c1699b7697267d/2024-03-03--13-09-53", TESLA.MODELS_RAVEN),
|
||||
|
||||
# Segments that test specific issues
|
||||
# Controls mismatch due to interceptor threshold
|
||||
|
||||
@@ -9,7 +9,6 @@ from parameterized import parameterized
|
||||
|
||||
from cereal import car, messaging
|
||||
from openpilot.common.realtime import DT_CTRL
|
||||
from openpilot.common.params import Params
|
||||
from openpilot.selfdrive.car import gen_empty_fingerprint
|
||||
from openpilot.selfdrive.car.car_helpers import interfaces
|
||||
from openpilot.selfdrive.car.fingerprints import all_known_cars
|
||||
@@ -19,7 +18,6 @@ from openpilot.selfdrive.controls.lib.latcontrol_angle import LatControlAngle
|
||||
from openpilot.selfdrive.controls.lib.latcontrol_pid import LatControlPID
|
||||
from openpilot.selfdrive.controls.lib.latcontrol_torque import LatControlTorque
|
||||
from openpilot.selfdrive.controls.lib.longcontrol import LongControl
|
||||
from openpilot.selfdrive.controls.controlsd import Controls
|
||||
from openpilot.selfdrive.test.fuzzy_generation import DrawType, FuzzyGenerator
|
||||
|
||||
ALL_ECUS = list({ecu for ecus in FW_VERSIONS.values() for ecu in ecus.keys()})
|
||||
@@ -46,6 +44,7 @@ def get_fuzzy_car_interface_args(draw: DrawType) -> dict:
|
||||
params['car_fw'] = [car.CarParams.CarFw(ecu=fw[0], address=fw[1], subAddress=fw[2] or 0) for fw in params['car_fw']]
|
||||
return params
|
||||
|
||||
|
||||
class TestCarInterfaces(unittest.TestCase):
|
||||
# FIXME: Due to the lists used in carParams, Phase.target is very slow and will cause
|
||||
# many generated examples to overrun when max_examples > ~20, don't use it
|
||||
@@ -57,11 +56,9 @@ class TestCarInterfaces(unittest.TestCase):
|
||||
CarInterface, CarController, CarState = interfaces[car_name]
|
||||
|
||||
args = get_fuzzy_car_interface_args(data.draw)
|
||||
params = Params()
|
||||
|
||||
car_params = CarInterface.get_params(params, car_name, args['fingerprints'], args['car_fw'],
|
||||
car_params = CarInterface.get_params(car_name, args['fingerprints'], args['car_fw'],
|
||||
experimental_long=args['experimental_long'], docs=False)
|
||||
|
||||
car_interface = CarInterface(car_params, CarController, CarState)
|
||||
assert car_params
|
||||
assert car_interface
|
||||
@@ -97,19 +94,18 @@ class TestCarInterfaces(unittest.TestCase):
|
||||
# Run car interface
|
||||
now_nanos = 0
|
||||
CC = car.CarControl.new_message(**cc_msg)
|
||||
controls = Controls(CI=car_interface)
|
||||
for _ in range(10):
|
||||
car_interface.update(CC, [], controls.frogpilot_variables)
|
||||
car_interface.apply(CC, now_nanos, controls.frogpilot_variables)
|
||||
car_interface.apply(CC, now_nanos, controls.frogpilot_variables)
|
||||
car_interface.update(CC, [])
|
||||
car_interface.apply(CC, now_nanos)
|
||||
car_interface.apply(CC, now_nanos)
|
||||
now_nanos += DT_CTRL * 1e9 # 10 ms
|
||||
|
||||
CC = car.CarControl.new_message(**cc_msg)
|
||||
CC.enabled = True
|
||||
for _ in range(10):
|
||||
car_interface.update(CC, [], controls.frogpilot_variables)
|
||||
car_interface.apply(CC, now_nanos, controls.frogpilot_variables)
|
||||
car_interface.apply(CC, now_nanos, controls.frogpilot_variables)
|
||||
car_interface.update(CC, [])
|
||||
car_interface.apply(CC, now_nanos)
|
||||
car_interface.apply(CC, now_nanos)
|
||||
now_nanos += DT_CTRL * 1e9 # 10ms
|
||||
|
||||
# Test controller initialization
|
||||
|
||||
@@ -6,18 +6,18 @@ import unittest
|
||||
|
||||
from openpilot.common.basedir import BASEDIR
|
||||
from openpilot.selfdrive.car.car_helpers import interfaces
|
||||
from openpilot.selfdrive.car.docs import CARS_MD_OUT, CARS_MD_TEMPLATE, generate_cars_md, get_all_car_info
|
||||
from openpilot.selfdrive.car.docs import CARS_MD_OUT, CARS_MD_TEMPLATE, generate_cars_md, get_all_car_docs
|
||||
from openpilot.selfdrive.car.docs_definitions import Cable, Column, PartType, Star
|
||||
from openpilot.selfdrive.car.honda.values import CAR as HONDA
|
||||
from openpilot.selfdrive.car.values import PLATFORMS
|
||||
from openpilot.selfdrive.debug.dump_car_info import dump_car_info
|
||||
from openpilot.selfdrive.debug.print_docs_diff import print_car_info_diff
|
||||
from openpilot.selfdrive.debug.dump_car_docs import dump_car_docs
|
||||
from openpilot.selfdrive.debug.print_docs_diff import print_car_docs_diff
|
||||
|
||||
|
||||
class TestCarDocs(unittest.TestCase):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.all_cars = get_all_car_info()
|
||||
cls.all_cars = get_all_car_docs()
|
||||
|
||||
def test_generator(self):
|
||||
generated_cars_md = generate_cars_md(self.all_cars, CARS_MD_TEMPLATE)
|
||||
@@ -29,24 +29,24 @@ class TestCarDocs(unittest.TestCase):
|
||||
|
||||
def test_docs_diff(self):
|
||||
dump_path = os.path.join(BASEDIR, "selfdrive", "car", "tests", "cars_dump")
|
||||
dump_car_info(dump_path)
|
||||
print_car_info_diff(dump_path)
|
||||
dump_car_docs(dump_path)
|
||||
print_car_docs_diff(dump_path)
|
||||
os.remove(dump_path)
|
||||
|
||||
def test_duplicate_years(self):
|
||||
make_model_years = defaultdict(list)
|
||||
for car in self.all_cars:
|
||||
with self.subTest(car_info_name=car.name):
|
||||
with self.subTest(car_docs_name=car.name):
|
||||
make_model = (car.make, car.model)
|
||||
for year in car.year_list:
|
||||
self.assertNotIn(year, make_model_years[make_model], f"{car.name}: Duplicate model year")
|
||||
make_model_years[make_model].append(year)
|
||||
|
||||
def test_missing_car_info(self):
|
||||
all_car_info_platforms = [name for name, config in PLATFORMS.items()]
|
||||
def test_missing_car_docs(self):
|
||||
all_car_docs_platforms = [name for name, config in PLATFORMS.items()]
|
||||
for platform in sorted(interfaces.keys()):
|
||||
with self.subTest(platform=platform):
|
||||
self.assertTrue(platform in all_car_info_platforms, f"Platform: {platform} doesn't have a CarInfo entry")
|
||||
self.assertTrue(platform in all_car_docs_platforms, f"Platform: {platform} doesn't have a CarDocs entry")
|
||||
|
||||
def test_naming_conventions(self):
|
||||
# Asserts market-standard car naming conventions by brand
|
||||
|
||||
@@ -263,7 +263,7 @@ class TestFwFingerprintTiming(unittest.TestCase):
|
||||
print(f'get_vin {name} case, query time={self.total_time / self.N} seconds')
|
||||
|
||||
def test_fw_query_timing(self):
|
||||
total_ref_time = {1: 8.4, 2: 9.3}
|
||||
total_ref_time = {1: 8.6, 2: 9.5}
|
||||
brand_ref_times = {
|
||||
1: {
|
||||
'gm': 1.0,
|
||||
@@ -274,7 +274,7 @@ class TestFwFingerprintTiming(unittest.TestCase):
|
||||
'hyundai': 1.05,
|
||||
'mazda': 0.1,
|
||||
'nissan': 0.8,
|
||||
'subaru': 0.45,
|
||||
'subaru': 0.65,
|
||||
'tesla': 0.3,
|
||||
'toyota': 1.6,
|
||||
'volkswagen': 0.65,
|
||||
|
||||
@@ -19,6 +19,7 @@ from openpilot.selfdrive.car.fingerprints import all_known_cars
|
||||
from openpilot.selfdrive.car.car_helpers import FRAME_FINGERPRINT, interfaces
|
||||
from openpilot.selfdrive.car.honda.values import CAR as HONDA, HondaFlags
|
||||
from openpilot.selfdrive.car.tests.routes import non_tested_cars, routes, CarTestRoute
|
||||
from openpilot.selfdrive.car.values import Platform
|
||||
from openpilot.selfdrive.controls.controlsd import Controls
|
||||
from openpilot.selfdrive.test.helpers import read_segment_list
|
||||
from openpilot.system.hardware.hw import DEFAULT_DOWNLOAD_CACHE_ROOT
|
||||
@@ -64,7 +65,7 @@ def get_test_cases() -> list[tuple[str, CarTestRoute | None]]:
|
||||
@pytest.mark.slow
|
||||
@pytest.mark.shared_download_cache
|
||||
class TestCarModelBase(unittest.TestCase):
|
||||
car_model: str | None = None
|
||||
platform: Platform | None = None
|
||||
test_route: CarTestRoute | None = None
|
||||
test_route_on_bucket: bool = True # whether the route is on the preserved CI bucket
|
||||
|
||||
@@ -93,8 +94,8 @@ class TestCarModelBase(unittest.TestCase):
|
||||
car_fw = msg.carParams.carFw
|
||||
if msg.carParams.openpilotLongitudinalControl:
|
||||
experimental_long = True
|
||||
if cls.car_model is None and not cls.ci:
|
||||
cls.car_model = msg.carParams.carFingerprint
|
||||
if cls.platform is None and not cls.ci:
|
||||
cls.platform = msg.carParams.carFingerprint
|
||||
|
||||
# Log which can frame the panda safety mode left ELM327, for CAN validity checks
|
||||
elif msg.which() == 'pandaStates':
|
||||
@@ -155,15 +156,11 @@ class TestCarModelBase(unittest.TestCase):
|
||||
if cls.__name__ == 'TestCarModel' or cls.__name__.endswith('Base'):
|
||||
raise unittest.SkipTest
|
||||
|
||||
if 'FILTER' in os.environ:
|
||||
if not cls.car_model.startswith(tuple(os.environ.get('FILTER').split(','))):
|
||||
raise unittest.SkipTest
|
||||
|
||||
if cls.test_route is None:
|
||||
if cls.car_model in non_tested_cars:
|
||||
print(f"Skipping tests for {cls.car_model}: missing route")
|
||||
if cls.platform in non_tested_cars:
|
||||
print(f"Skipping tests for {cls.platform}: missing route")
|
||||
raise unittest.SkipTest
|
||||
raise Exception(f"missing test route for {cls.car_model}")
|
||||
raise Exception(f"missing test route for {cls.platform}")
|
||||
|
||||
car_fw, can_msgs, experimental_long = cls.get_testing_data()
|
||||
|
||||
@@ -172,10 +169,10 @@ class TestCarModelBase(unittest.TestCase):
|
||||
|
||||
cls.can_msgs = sorted(can_msgs, key=lambda msg: msg.logMonoTime)
|
||||
|
||||
cls.CarInterface, cls.CarController, cls.CarState = interfaces[cls.car_model]
|
||||
cls.CP = cls.CarInterface.get_params(cls.car_model, cls.fingerprint, car_fw, experimental_long, docs=False)
|
||||
cls.CarInterface, cls.CarController, cls.CarState = interfaces[cls.platform]
|
||||
cls.CP = cls.CarInterface.get_params(cls.platform, cls.fingerprint, car_fw, experimental_long, docs=False)
|
||||
assert cls.CP
|
||||
assert cls.CP.carFingerprint == cls.car_model
|
||||
assert cls.CP.carFingerprint == cls.platform
|
||||
|
||||
os.environ["COMMA_CACHE"] = DEFAULT_DOWNLOAD_CACHE_ROOT
|
||||
|
||||
@@ -478,7 +475,7 @@ class TestCarModelBase(unittest.TestCase):
|
||||
"This is fine to fail for WIP car ports, just let us know and we can upload your routes to the CI bucket.")
|
||||
|
||||
|
||||
@parameterized_class(('car_model', 'test_route'), get_test_cases())
|
||||
@parameterized_class(('platform', 'test_route'), get_test_cases())
|
||||
@pytest.mark.xdist_group_class_property('test_route')
|
||||
class TestCarModel(TestCarModelBase):
|
||||
pass
|
||||
|
||||
Reference in New Issue
Block a user