From bab2d776b6eaf24a56c7cd4631940dd5c16dc505 Mon Sep 17 00:00:00 2001 From: Tim Wilson Date: Sat, 22 Mar 2025 17:49:05 -0600 Subject: [PATCH] NNLC: use torque substitutes as fuzzy fingerprints (#700) * NNLC: use torque substitutes as fuzzy fingerprints * substitutes are not exact matches * update nnlc helpers for extra nnlc model path checks, take the first one that passes. * Update sunnypilot/selfdrive/controls/lib/nnlc/helpers.py --------- Co-authored-by: Jason Wen --- sunnypilot/selfdrive/controls/lib/nnlc/helpers.py | 14 ++++++++++++-- .../controls/lib/nnlc/tests/test_load_model.py | 7 +++---- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/sunnypilot/selfdrive/controls/lib/nnlc/helpers.py b/sunnypilot/selfdrive/controls/lib/nnlc/helpers.py index d533eb126..0ea920f19 100644 --- a/sunnypilot/selfdrive/controls/lib/nnlc/helpers.py +++ b/sunnypilot/selfdrive/controls/lib/nnlc/helpers.py @@ -5,12 +5,14 @@ This file is part of sunnypilot and is licensed under the MIT License. See the LICENSE.md file in the root directory for more details. """ import os +import tomllib from difflib import SequenceMatcher from opendbc.car import structs from openpilot.common.basedir import BASEDIR TORQUE_NN_MODEL_PATH = os.path.join(BASEDIR, "sunnypilot", "neural_network_data", "neural_network_lateral_control") +TORQUE_NN_MODEL_SUBSTITUTE_PATH = os.path.join(BASEDIR, "opendbc", "car", "torque_data/substitute.toml") MOCK_MODEL_PATH = os.path.join(TORQUE_NN_MODEL_PATH, "MOCK.json") @@ -42,16 +44,24 @@ def get_nn_model_path(CP: structs.CarParams) -> tuple[str, str, bool]: model_path, max_similarity = check_nn_path(nn_candidate) + exact_match = max_similarity >= 0.99 + if car_fingerprint not in model_path or 0.0 <= max_similarity < 0.8: nn_candidate = car_fingerprint model_path, max_similarity = check_nn_path(nn_candidate) if 0.0 <= max_similarity < 0.8: - model_path = MOCK_MODEL_PATH + with open(TORQUE_NN_MODEL_SUBSTITUTE_PATH, 'rb') as f: + sub = tomllib.load(f) + sub_candidate = sub.get(car_fingerprint, car_fingerprint) + + for candidate in [car_fingerprint, sub_candidate]: + model_path, max_similarity = check_nn_path(candidate) + + exact_match = False if CP.steerControlType == structs.CarParams.SteerControlType.angle: model_path = MOCK_MODEL_PATH model_name = os.path.splitext(os.path.basename(model_path))[0] - exact_match = max_similarity >= 0.99 return model_path, model_name, exact_match diff --git a/sunnypilot/selfdrive/controls/lib/nnlc/tests/test_load_model.py b/sunnypilot/selfdrive/controls/lib/nnlc/tests/test_load_model.py index 7c70f4fa0..f76830829 100644 --- a/sunnypilot/selfdrive/controls/lib/nnlc/tests/test_load_model.py +++ b/sunnypilot/selfdrive/controls/lib/nnlc/tests/test_load_model.py @@ -1,4 +1,3 @@ -from numpy.ma.testutils import assert_equal from parameterized import parameterized from opendbc.car.car_helpers import interfaces @@ -13,8 +12,8 @@ from openpilot.sunnypilot.selfdrive.car import interfaces as sunnypilot_interfac class TestNNTorqueModel: - @parameterized.expand([(HONDA.HONDA_CIVIC, True), (TOYOTA.TOYOTA_RAV4, True), (HYUNDAI.HYUNDAI_SANTA_CRUZ_1ST_GEN, False)]) - def test_load_model(self, car_name, should_load_model): + @parameterized.expand([HONDA.HONDA_CIVIC, TOYOTA.TOYOTA_RAV4, HYUNDAI.HYUNDAI_SANTA_CRUZ_1ST_GEN]) + def test_load_model(self, car_name): params = Params() params.put_bool("NeuralNetworkLateralControl", True) @@ -29,4 +28,4 @@ class TestNNTorqueModel: controller = LatControlTorque(CP.as_reader(), CP_SP.as_reader(), CI) - assert_equal(should_load_model, controller.extension.has_nn_model) + assert controller.extension.has_nn_model