Back to Openpilot

Adapted from https://github.com/commaai/openpilot/issues/31052#issuecomment-1902690083

tools/car_porting/examples/ford_vin_fingerprint.ipynb

0.11.02.4 KB
Original Source
python
"""In this example, we use the public comma car segments database to check if vin fingerprinting is feasible for ford."""

from openpilot.tools.lib.logreader import LogReader, comma_car_segments_source
from openpilot.tools.lib.comma_car_segments import get_comma_car_segments_database
from opendbc.car.ford.values import CAR

database = get_comma_car_segments_database()

platforms = [c.value for c in CAR]
print(f"Got {len(platforms)} Ford cars from opendbc")
python
# Adapted from https://github.com/commaai/openpilot/issues/31052#issuecomment-1902690083

MODEL_YEAR_CODES = {'M': 2021, 'N': 2022, 'P': 2023, 'R': 2024, 'S': 2025}


F150_CODES = ['F1C', 'F1E', 'W1C', 'W1E', 'X1C', 'X1E', 'W1R', 'W1P', 'W1S', 'W1T']
LIGHTNING_CODES = ['L', 'V']
MACHE_CODES = ['K1R', 'K1S', 'K2S', 'K3R', 'K3S', 'K4S']

FORD_VIN_START = ['1FT', '3FM', '5LM']

def ford_vin_fingerprint(vin): # Check if it's a Ford vehicle and determine the model
  vin_positions_567 = vin[4:7]

  if vin.startswith('1FT'):
    if vin_positions_567 in F150_CODES:
      if vin[7] in LIGHTNING_CODES:
        return f"FORD F-150 LIGHTNING 1ST GEN"
      else:
        return f"FORD F-150 14TH GEN"
  elif vin.startswith('3FM'):
    if vin_positions_567 in MACHE_CODES:
      return f"FORD MUSTANG MACH-E 1ST GEN"
  elif vin.startswith('5LM'):
    pass

  return "mock"
python
import random

MAX_SEGS_PER_PLATFORM = 5

VINS_TO_CHECK = set()

print("Collecting segments from commaCarSegments dataset:")
for platform in platforms:
  if platform not in database:
    print(f"Skipping platform: {platform}, no data available")
    continue

  all_segments = database[platform]

  NUM_SEGMENTS = min(len(all_segments), MAX_SEGS_PER_PLATFORM)

  print(f"Got {len(all_segments)} segments for platform {platform}, sampling {NUM_SEGMENTS} segments")

  segments = random.sample(all_segments, NUM_SEGMENTS)

  for segment in segments:
    lr = LogReader(segment, sources=[comma_car_segments_source])
    CP = lr.first("carParams")
    if "FORD" not in CP.carFingerprint:
      print(segment, CP.carFingerprint)
    VINS_TO_CHECK.add((CP.carVin, CP.carFingerprint))

print("Segment collection finished")
python
for vin, real_fingerprint in VINS_TO_CHECK:
  determined_fingerprint = ford_vin_fingerprint(vin)
  print(f"vin: {vin} real platform: {real_fingerprint: <30}     determined platform: {determined_fingerprint: <30}    correct: {real_fingerprint == determined_fingerprint}")