Volkswagen: improve fuzzy fingerprinting (#32378)

* improve VW fuzzy FP matching

* annotate

* Revert "annotate"

This reverts commit 09cbb150e9.

* hmm
old-commit-hash: a83b182c55
pull/32199/head
Shane Smiskol 12 months ago committed by GitHub
parent 583fa3bfbf
commit af0310ff0c
  1. 9
      selfdrive/car/volkswagen/tests/test_volkswagen.py
  2. 15
      selfdrive/car/volkswagen/values.py

@ -1,4 +1,5 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import random
import re import re
import unittest import unittest
@ -38,9 +39,9 @@ class TestVolkswagenPlatformConfigs(unittest.TestCase):
f"Shared chassis codes: {comp}") f"Shared chassis codes: {comp}")
def test_custom_fuzzy_fingerprinting(self): def test_custom_fuzzy_fingerprinting(self):
for platform in CAR: all_radar_fw = list({fw for ecus in FW_VERSIONS.values() for fw in ecus[Ecu.fwdRadar, 0x757, None]})
expected_radar_fw = FW_VERSIONS[platform][Ecu.fwdRadar, 0x757, None]
for platform in CAR:
with self.subTest(platform=platform): with self.subTest(platform=platform):
for wmi in WMI: for wmi in WMI:
for chassis_code in platform.config.chassis_codes | {"00"}: for chassis_code in platform.config.chassis_codes | {"00"}:
@ -50,9 +51,9 @@ class TestVolkswagenPlatformConfigs(unittest.TestCase):
vin = "".join(vin) vin = "".join(vin)
# Check a few FW cases - expected, unexpected # 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 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]} live_fws = {(0x757, None): [radar_fw]}
matches = FW_QUERY_CONFIG.match_fw_to_car_fuzzy(live_fws, vin, FW_VERSIONS) matches = FW_QUERY_CONFIG.match_fw_to_car_fuzzy(live_fws, vin, FW_VERSIONS)

@ -1,4 +1,4 @@
from collections import namedtuple from collections import defaultdict, namedtuple
from dataclasses import dataclass, field from dataclasses import dataclass, field
from enum import Enum, IntFlag, StrEnum from enum import Enum, IntFlag, StrEnum
@ -9,7 +9,7 @@ from openpilot.common.conversions import Conversions as CV
from openpilot.selfdrive.car import dbc_dict, CarSpecs, DbcDict, PlatformConfig, Platforms from openpilot.selfdrive.car import dbc_dict, CarSpecs, DbcDict, PlatformConfig, Platforms
from openpilot.selfdrive.car.docs_definitions import CarFootnote, CarHarness, CarDocs, CarParts, Column, \ from openpilot.selfdrive.car.docs_definitions import CarFootnote, CarHarness, CarDocs, CarParts, Column, \
Device 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 Ecu = car.CarParams.Ecu
NetworkLocation = car.CarParams.NetworkLocation 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]: def match_fw_to_car_fuzzy(live_fw_versions, vin, offline_fw_versions) -> set[str]:
candidates = set() 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 # Check the WMI and chassis code to determine the platform
wmi = vin[:3] wmi = vin[:3]
chassis_code = vin[6:8] chassis_code = vin[6:8]
for platform in CAR: for platform in CAR:
valid_ecus = set() valid_ecus = set()
for ecu, expected_versions in offline_fw_versions[platform].items(): for ecu in offline_fw_versions[platform]:
addr = ecu[1:] addr = ecu[1:]
if ecu[0] not in CHECK_FUZZY_ECUS: if ecu[0] not in CHECK_FUZZY_ECUS:
continue 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, []) 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): if not any(found_version in expected_versions for found_version in found_versions):
break break

Loading…
Cancel
Save