Files
sunnypilot-byd/tools/car_porting/examples/ford_vin_fingerprint.ipynb
T
github-actions[bot] de77c89cf6 sunnypilot v2026.002.000
version: sunnypilot v2026.002.000 (staging)
date: 2026-07-21T07:44:02
master commit: 2c334ede443d7391d27575af8c854a095ba702a8
2026-07-21 07:44:02 +00:00

7.0 KiB

In [12]:
"""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")
Got 9 Ford cars from opendbc
In [6]:
# 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"
In [13]:
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")
Collecting segments from commaCarSegments dataset:
Got 287 segments for platform FORD_BRONCO_SPORT_MK1, sampling 5 segments
Got 137 segments for platform FORD_ESCAPE_MK4, sampling 5 segments
Got 1041 segments for platform FORD_EXPLORER_MK6, sampling 5 segments
Got 5 segments for platform FORD_F_150_MK14, sampling 5 segments
Got 3 segments for platform FORD_F_150_LIGHTNING_MK1, sampling 3 segments
Got 56 segments for platform FORD_FOCUS_MK4, sampling 5 segments
Got 637 segments for platform FORD_MAVERICK_MK1, sampling 5 segments
Got 3 segments for platform FORD_MUSTANG_MACH_E_MK1, sampling 3 segments
Skipping platform: FORD_RANGER_MK2, no data available
Segment collection finished
In [16]:
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}")
vin: 3FMCR9B69NRXXXXXX real platform: FORD BRONCO SPORT 1ST GEN          determined platform: mock                              correct: False
vin: 00000000000XXXXXX real platform: FORD F-150 14TH GEN                determined platform: mock                              correct: False
vin: 1FMCU9J94MUXXXXXX real platform: FORD ESCAPE 4TH GEN                determined platform: mock                              correct: False
vin: 3FMTK3SU0MMXXXXXX real platform: FORD MUSTANG MACH-E 1ST GEN        determined platform: FORD MUSTANG MACH-E 1ST GEN       correct: True
vin: 1FM5K8HC7MGXXXXXX real platform: FORD EXPLORER 6TH GEN              determined platform: mock                              correct: False
vin: 5LM5J7XC9LGXXXXXX real platform: FORD EXPLORER 6TH GEN              determined platform: mock                              correct: False
vin: 1FTVW1EL4NWXXXXXX real platform: FORD F-150 LIGHTNING 1ST GEN       determined platform: FORD F-150 LIGHTNING 1ST GEN      correct: True
vin: WF0NXXGCHNJXXXXXX real platform: FORD FOCUS 4TH GEN                 determined platform: mock                              correct: False
vin: 3FTTW8E99NRXXXXXX real platform: FORD MAVERICK 1ST GEN              determined platform: mock                              correct: False
vin: 1FM5K8GC7LGXXXXXX real platform: FORD EXPLORER 6TH GEN              determined platform: mock                              correct: False
vin: 3FTTW8E33NRXXXXXX real platform: FORD MAVERICK 1ST GEN              determined platform: mock                              correct: False
vin: 5LM5J7XC1LGXXXXXX real platform: FORD EXPLORER 6TH GEN              determined platform: mock                              correct: False
vin: 3FTTW8E3XPRXXXXXX real platform: FORD MAVERICK 1ST GEN              determined platform: mock                              correct: False