From a83b182c552476dfda71784570916777135b3d4e Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Wed, 8 May 2024 17:17:08 -0700 Subject: [PATCH] Volkswagen: improve fuzzy fingerprinting (#32378) * improve VW fuzzy FP matching * annotate * Revert "annotate" This reverts commit 09cbb150e91f5093849c22d95e31152fb8d4d1a9. * hmm --- selfdrive/car/volkswagen/tests/test_volkswagen.py | 9 +++++---- selfdrive/car/volkswagen/values.py | 15 +++++++++++---- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/selfdrive/car/volkswagen/tests/test_volkswagen.py b/selfdrive/car/volkswagen/tests/test_volkswagen.py index 92569e194e3e76..17331203bbe855 100755 --- a/selfdrive/car/volkswagen/tests/test_volkswagen.py +++ b/selfdrive/car/volkswagen/tests/test_volkswagen.py @@ -1,4 +1,5 @@ #!/usr/bin/env python3 +import random import re import unittest @@ -38,9 +39,9 @@ def test_chassis_codes(self): f"Shared chassis codes: {comp}") def test_custom_fuzzy_fingerprinting(self): - for platform in CAR: - expected_radar_fw = FW_VERSIONS[platform][Ecu.fwdRadar, 0x757, None] + all_radar_fw = list({fw for ecus in FW_VERSIONS.values() for fw in ecus[Ecu.fwdRadar, 0x757, None]}) + for platform in CAR: with self.subTest(platform=platform): for wmi in WMI: for chassis_code in platform.config.chassis_codes | {"00"}: @@ -50,9 +51,9 @@ def test_custom_fuzzy_fingerprinting(self): vin = "".join(vin) # Check a few FW cases - expected, unexpected - for radar_fw in expected_radar_fw + [b'\xf1\x877H9907572AA\xf1\x890396']: + for radar_fw in random.sample(all_radar_fw, 5) + [b'\xf1\x875Q0907572G \xf1\x890571', b'\xf1\x877H9907572AA\xf1\x890396']: should_match = ((wmi in platform.config.wmis and chassis_code in platform.config.chassis_codes) and - radar_fw in expected_radar_fw) + radar_fw in all_radar_fw) live_fws = {(0x757, None): [radar_fw]} matches = FW_QUERY_CONFIG.match_fw_to_car_fuzzy(live_fws, vin, FW_VERSIONS) diff --git a/selfdrive/car/volkswagen/values.py b/selfdrive/car/volkswagen/values.py index 2ea169d1c6ad5f..eb537575fade70 100644 --- a/selfdrive/car/volkswagen/values.py +++ b/selfdrive/car/volkswagen/values.py @@ -1,4 +1,4 @@ -from collections import namedtuple +from collections import defaultdict, namedtuple from dataclasses import dataclass, field from enum import Enum, IntFlag, StrEnum @@ -9,7 +9,7 @@ from openpilot.selfdrive.car import dbc_dict, CarSpecs, DbcDict, PlatformConfig, Platforms from openpilot.selfdrive.car.docs_definitions import CarFootnote, CarHarness, CarDocs, CarParts, Column, \ Device -from openpilot.selfdrive.car.fw_query_definitions import FwQueryConfig, Request, p16 +from openpilot.selfdrive.car.fw_query_definitions import EcuAddrSubAddr, FwQueryConfig, Request, p16 Ecu = car.CarParams.Ecu NetworkLocation = car.CarParams.NetworkLocation @@ -434,19 +434,26 @@ class CAR(Platforms): def match_fw_to_car_fuzzy(live_fw_versions, vin, offline_fw_versions) -> set[str]: candidates = set() + # Compile all FW versions for each ECU + all_ecu_versions: dict[EcuAddrSubAddr, set[str]] = defaultdict(set) + for ecus in offline_fw_versions.values(): + for ecu, versions in ecus.items(): + all_ecu_versions[ecu] |= set(versions) + # Check the WMI and chassis code to determine the platform wmi = vin[:3] chassis_code = vin[6:8] for platform in CAR: valid_ecus = set() - for ecu, expected_versions in offline_fw_versions[platform].items(): + for ecu in offline_fw_versions[platform]: addr = ecu[1:] if ecu[0] not in CHECK_FUZZY_ECUS: continue - # Sanity check that a subset of Volkswagen FW is in the database + # Sanity check that live FW is in the superset of all FW, Volkswagen ECU part numbers are commonly shared found_versions = live_fw_versions.get(addr, []) + expected_versions = all_ecu_versions[ecu] if not any(found_version in expected_versions for found_version in found_versions): break