openpilot
openpilot copied to clipboard
Ford: use platform codes to fuzzy fingerprint
Use the FW prefix to identify the model and model year/generation of the vehicle.
Notes:
- This ignores the "software version" suffix of the FW since we can identify changes in API (e.g. Ford Q3 -> Q4) from the rest of the FW. For example, the 2024 Escape is Q4 and its FW has a new model year hint (see FW table)
- The FW version cannot tell us whether the car is compatible (has LCA/ACC), except the lack of a radar can be used to rule cars out. Some cars have radar without ACC, and some with ACC do not have LCA.
- We can identify the model from the 'platform hint' and model year/generation from the 'model year hint' without any false matches/collisions (see notebook using big vin database)
Verification
- [x] Checked all segments in commaCarSegments to make sure they still fingerprint as expected. The only ones which do not are from a Maverick which is missing a radar anyway.
Future improvements
- Remove requirement for all four ECUs to match: we can guarantee a match/no false positives from just three for some platforms
May close #31052
Platform codes (platform + model year hints)
FORD BRONCO SPORT 1ST GEN
(Ecu.eps, 0x730, None):
Codes: [(b'X6C', b'L')]
(Ecu.abs, 0x760, None):
Codes: [(b'X6C', b'L')]
(Ecu.fwdRadar, 0x764, None):
Codes: [(b'B5T', b'L')]
(Ecu.fwdCamera, 0x706, None):
Codes: [(b'1PT', b'M')]
FORD ESCAPE 4TH GEN
(Ecu.eps, 0x730, None):
Codes: [(b'X6C', b'L')]
(Ecu.abs, 0x760, None):
Codes: [(b'X6C', b'L')]
(Ecu.fwdRadar, 0x764, None):
Codes: [(b'B5T', b'L')]
(Ecu.fwdCamera, 0x706, None):
Codes: [(b'J6T', b'L'), (b'V4T', b'L')]
FORD EXPLORER 6TH GEN
(Ecu.eps, 0x730, None):
Codes: [(b'1MC', b'L'), (b'1MC', b'M'), (b'1MC', b'P')]
(Ecu.abs, 0x760, None):
Codes: [(b'1MC', b'L')]
(Ecu.fwdRadar, 0x764, None):
Codes: [(b'B5T', b'L')]
(Ecu.fwdCamera, 0x706, None):
Codes: [(b'B5T', b'L'), (b'C5T', b'L')]
FORD F-150 14TH GEN
(Ecu.eps, 0x730, None):
Codes: [(b'L3V', b'M')]
(Ecu.abs, 0x760, None):
Codes: [(b'L34', b'P')]
(Ecu.fwdRadar, 0x764, None):
Codes: [(b'L3T', b'M')]
(Ecu.fwdCamera, 0x706, None):
Codes: [(b'J6T', b'P')]
FORD F-150 LIGHTNING 1ST GEN
(Ecu.abs, 0x760, None):
Codes: [(b'L38', b'P')]
(Ecu.fwdRadar, 0x764, None):
Codes: [(b'L3T', b'M')]
(Ecu.fwdCamera, 0x706, None):
Codes: [(b'L3T', b'M')]
FORD MUSTANG MACH-E 1ST GEN
(Ecu.eps, 0x730, None):
Codes: [(b'J9C', b'L')]
(Ecu.abs, 0x760, None):
Codes: [(b'K9C', b'L')]
(Ecu.fwdRadar, 0x764, None):
Codes: [(b'L3T', b'M')]
(Ecu.fwdCamera, 0x706, None):
Codes: [(b'L3T', b'M')]
FORD FOCUS 4TH GEN
(Ecu.eps, 0x730, None):
Codes: [(b'X6C', b'J')]
(Ecu.abs, 0x760, None):
Codes: [(b'X61', b'J')]
(Ecu.fwdRadar, 0x764, None):
Codes: [(b'X7T', b'J')]
(Ecu.fwdCamera, 0x706, None):
Codes: [(b'X7T', b'J')]
FORD MAVERICK 1ST GEN
(Ecu.eps, 0x730, None):
Codes: [(b'Z6C', b'N')]
(Ecu.abs, 0x760, None):
Codes: [(b'Z6C', b'N'), (b'Z6C', b'P')]
(Ecu.fwdRadar, 0x764, None):
Codes: [(b'Z6T', b'N')]
(Ecu.fwdCamera, 0x706, None):
Codes: [(b'Z6T', b'N')]
Car models vs. platform codes:
(Ecu.eps, 0x730, None):
(b'X6C', b'L'): ['FORD BRONCO SPORT 1ST GEN', 'FORD ESCAPE 4TH GEN']
(b'1MC', b'P'): ['FORD EXPLORER 6TH GEN']
(b'1MC', b'M'): ['FORD EXPLORER 6TH GEN']
(b'1MC', b'L'): ['FORD EXPLORER 6TH GEN']
(b'L3V', b'M'): ['FORD F-150 14TH GEN']
(b'J9C', b'L'): ['FORD MUSTANG MACH-E 1ST GEN']
(b'X6C', b'J'): ['FORD FOCUS 4TH GEN']
(b'Z6C', b'N'): ['FORD MAVERICK 1ST GEN']
(Ecu.abs, 0x760, None):
(b'X6C', b'L'): ['FORD BRONCO SPORT 1ST GEN', 'FORD ESCAPE 4TH GEN']
(b'1MC', b'L'): ['FORD EXPLORER 6TH GEN']
(b'L34', b'P'): ['FORD F-150 14TH GEN']
(b'L38', b'P'): ['FORD F-150 LIGHTNING 1ST GEN']
(b'K9C', b'L'): ['FORD MUSTANG MACH-E 1ST GEN']
(b'X61', b'J'): ['FORD FOCUS 4TH GEN']
(b'Z6C', b'P'): ['FORD MAVERICK 1ST GEN']
(b'Z6C', b'N'): ['FORD MAVERICK 1ST GEN']
(Ecu.fwdRadar, 0x764, None):
(b'B5T', b'L'): ['FORD BRONCO SPORT 1ST GEN', 'FORD ESCAPE 4TH GEN', 'FORD EXPLORER 6TH GEN']
(b'L3T', b'M'): ['FORD F-150 14TH GEN', 'FORD F-150 LIGHTNING 1ST GEN', 'FORD MUSTANG MACH-E 1ST GEN']
(b'X7T', b'J'): ['FORD FOCUS 4TH GEN']
(b'Z6T', b'N'): ['FORD MAVERICK 1ST GEN']
(Ecu.fwdCamera, 0x706, None):
(b'1PT', b'M'): ['FORD BRONCO SPORT 1ST GEN']
(b'J6T', b'L'): ['FORD ESCAPE 4TH GEN']
(b'V4T', b'L'): ['FORD ESCAPE 4TH GEN']
(b'B5T', b'L'): ['FORD EXPLORER 6TH GEN']
(b'C5T', b'L'): ['FORD EXPLORER 6TH GEN']
(b'J6T', b'P'): ['FORD F-150 14TH GEN']
(b'L3T', b'M'): ['FORD F-150 LIGHTNING 1ST GEN', 'FORD MUSTANG MACH-E 1ST GEN']
(b'X7T', b'J'): ['FORD FOCUS 4TH GEN']
(b'Z6T', b'N'): ['FORD MAVERICK 1ST GEN']
great work! I love how this is mostly just our other fuzzy FP functions; it mostly works for all brands. With verification, I made sure that:
- [ ] No dongles ever changed fingerprint except mock (including checking all other brands), running
match_fw_to_car - [ ] Check how many mock dongles gained a fingerprint (
match_fw_to_car) @jnewb1 can we add mock unfingerprinting segments to the dataset if not already there? - [ ] Check how many Ford fingerprinting dongles (fuzzy or exact) gained a fingerprint, running
match_fw_to_car(allow_exact=False) - [ ] No dongles lost a fingerprint (checking both allow_exact True and False
Let me know if you have any other verification step ideas
I found some VINs for Ford Explorers online (most of our FW PRs are for those) and used https://motorcraft.com/AsBuilt to download information about them (ECU configuration, part numbers and FW versions). I collected 44 VINs and data.
Here are the results of running the current OP fingerprint vs running with the custom fuzzy matcher:
Show results
Of the 15 newly fingerprinted VINs, 100% were previously failing to fingerprint due to missing Engine FWs. For example, LB5A-14C204-EAE was not in the offline database, but there are many versions with the same platform code B5A and part number 14C204, so the custom matcher allows it to match.
Of the 21 VINs which continue to not match, three of these (MY17 and MY19) did not have any camera or radar part numbers/fw. The other 18 did have cameras but did not have radars.
Of the 15 newly fingerprinted VINs, 100% were previously failing to fingerprint due to missing Engine FWs. For example, LB5A-14C204-EAE was not in the offline database, but there are many versions with the same platform code B5A and part number 14C204, so the custom matcher allows it to match.
I wonder how many matches we gain just by removing engine!
Of the 21 VINs which continue to not match, three of these (MY17 and MY19) did not have any camera or radar part numbers/fw. The other 18 did have cameras but did not have radars.
So with a perfect fuzzy matcher, we still expect none of these to match? Ie. they all have LKAS but not ACC as stock?
So with a perfect fuzzy matcher, we still expect none of these to match? Ie. they all have LKAS but not ACC as stock?
Yes pretty much.
Looking at the cars which are fingerprinting in more detail, there is a car which shouldn't be compatible which is matching right now, without the custom fuzzy matcher.
For example this 2020 Ford Explorer XLT (1FMSK8DH1LGB19569) has this FW:
Ecu.eps: [b'L1MC-14D003-AK\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00']
Ecu.abs: [b'L1MC-2D053-BA\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00']
Ecu.fwdCamera: [b'LB5T-14F397-AE\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00']
Ecu.engine: [b'LB5A-14C204-BUJ\x00\x00\x00\x00\x00\x00\x00\x00\x00']
Note it doesn't have a radar. It fingerprints anyway, I think because fuzzy matching requires just two matching ECUs.
Fingerprinted FORD EXPLORER 6TH GEN using fuzzy match. 2 matching ECUs
Since camera/radar/eps are excluded from fuzzy, it's the abs and engine FW matching the database. Both were added in https://github.com/commaai/openpilot/commit/fd2e03decf0a89e1c04e0a8d6aee0bf033d2ec0b.
Looking at that PR, the 2020 Explorer Limited (1FMSK8FH6LGB17698) does have a radar, and all other FW are identical. So either we have to require the radar FW or use some other query to determine whether it has ACC.
Ecu.eps: [b'L1MC-14D003-AK\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00']
Ecu.abs: [b'L1MC-2D053-BA\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00']
Ecu.fwdRadar: [b'LB5T-14D049-AB\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00']
Ecu.fwdCamera: [b'LB5T-14F397-AE\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00']
Ecu.engine: [b'LB5A-14C204-BUJ\x00\x00\x00\x00\x00\x00\x00\x00\x00']
Show full results
VIN Comment Fingerprint Fuzzy NewFingerprint NewFuzzy FactoryACC FactoryTJA Result
23 1FMSK8DHXLGBXXXXXX 2020 Ford Explorer XLT FORD EXPLORER 6TH GEN False FORD EXPLORER 6TH GEN False RadarFusion On fp -> fp
25 1FM5K8GC0LGAXXXXXX 2020 Ford Explorer ST FORD EXPLORER 6TH GEN False FORD EXPLORER 6TH GEN False RadarFusion On fp -> fp
39 1FM5K8GC3LGAXXXXXX 2020 Ford Explorer ST FORD EXPLORER 6TH GEN False FORD EXPLORER 6TH GEN False RadarFusion On fp -> fp
41 1FMSK8DH0NGBXXXXXX 2022 Ford Explorer XLT 4WD FORD EXPLORER 6TH GEN False FORD EXPLORER 6TH GEN False RadarFusion On fp -> fp
6 1FMSK8DH1LGBXXXXXX 2020 Ford Explorer XLT FORD EXPLORER 6TH GEN True FORD EXPLORER 6TH GEN True Off (no radar) Off fp -> fp
8 1FMSK8DH7NGBXXXXXX 2022 Ford Explorer XLT FORD EXPLORER 6TH GEN True FORD EXPLORER 6TH GEN True Off (no radar) Off fp -> fp
10 1FMSK8DH6NGBXXXXXX 2022 Ford Explorer XLT FORD EXPLORER 6TH GEN True FORD EXPLORER 6TH GEN True Off (no radar) Off fp -> fp
17 1FMSK8DH9NGBXXXXXX 2022 Ford Explorer XLT FORD EXPLORER 6TH GEN True FORD EXPLORER 6TH GEN True Off (no radar) Off fp -> fp
11 1FMSK8FH7NGAXXXXXX 2022 Ford Explorer Limited mock False FORD EXPLORER 6TH GEN True RadarFusion On mock -> fp
12 1FMSK7FHXPGAXXXXXX 2023 Ford Explorer Limited RWD mock False FORD EXPLORER 6TH GEN True RadarFusion On mock -> fp
15 1FMSK8DH9LGBXXXXXX 2020 Ford Explorer XLT 4WD mock False FORD EXPLORER 6TH GEN True RadarFusion On mock -> fp
20 1FMSK8FH9MGAXXXXXX 2021 Ford Explorer Limited 4WD mock False FORD EXPLORER 6TH GEN True RadarFusion On mock -> fp
21 1FMSK8DH1LGBXXXXXX 2020 Ford Explorer XLT mock False FORD EXPLORER 6TH GEN True RadarFusion On mock -> fp
22 1FMSK8DH1LGDXXXXXX 2020 Ford Explorer XLT mock False FORD EXPLORER 6TH GEN True RadarFusion On mock -> fp
24 1FMSK8DHXLGAXXXXXX 2020 Ford Explorer XLT mock False FORD EXPLORER 6TH GEN True RadarFusion On mock -> fp
26 1FMSK8FH2MGBXXXXXX 2021 Ford Explorer Limited mock False FORD EXPLORER 6TH GEN True RadarFusion On mock -> fp
27 1FMSK8FHXMGBXXXXXX 2021 Ford Explorer Limited mock False FORD EXPLORER 6TH GEN True RadarFusion On mock -> fp
28 1FMSK8FH2MGBXXXXXX 2021 Ford Explorer Limited mock False FORD EXPLORER 6TH GEN True RadarFusion On mock -> fp
29 1FMSK8FH8MGBXXXXXX 2021 Ford Explorer Limited mock False FORD EXPLORER 6TH GEN True RadarFusion On mock -> fp
31 1FMSK8FH5MGAXXXXXX 2021 Ford Explorer Limited mock False FORD EXPLORER 6TH GEN True RadarFusion On mock -> fp
32 1FMSK8FH4MGBXXXXXX 2021 Ford Explorer Limited mock False FORD EXPLORER 6TH GEN True RadarFusion On mock -> fp
33 1FMSK8FH5MGAXXXXXX 2021 Ford Explorer Limited mock False FORD EXPLORER 6TH GEN True RadarFusion On mock -> fp
38 1FMSK8DH5MGAXXXXXX 2021 Ford Explorer XLT mock False FORD EXPLORER 6TH GEN True RadarFusion On mock -> fp
0 1FMSK8DH1NGAXXXXXX 2022 Ford Explorer XLT mock False mock False Off (no radar) Off mock -> mock
1 1FMSK8DH7MGCXXXXXX 2021 Ford Explorer XLT mock False mock False Off (no radar) Off mock -> mock
2 1FMSK8DH9MGBXXXXXX 2021 Ford Explorer XLT mock False mock False Off (no radar) Off mock -> mock
3 1FMSK8DH4NGAXXXXXX 2022 Ford Explorer XLT mock False mock False Off (no radar) Off mock -> mock
4 1FMSK8DH8MGAXXXXXX 2021 Ford Explorer XLT mock False mock False Off (no radar) Off mock -> mock
5 1FMSK8DH3NGAXXXXXX 2022 Ford Explorer XLT mock False mock False Off (no radar) Off mock -> mock
7 1FMSK8DH8NGAXXXXXX 2022 Ford Explorer XLT mock False mock False Off (no radar) Off mock -> mock
9 1FMSK8DH9LGBXXXXXX 2020 Ford Explorer XLT mock False mock False Off (no radar) Off mock -> mock
13 1FMSK8DH0NGAXXXXXX 2022 Ford Explorer XLT mock False mock False Off (no radar) Off mock -> mock
14 1FMSK8DH9LGCXXXXXX 2020 Ford Explorer XLT mock False mock False Off (no radar) Off mock -> mock
16 1FMSK8DH6NGBXXXXXX 2022 Ford Explorer XLT mock False mock False Off (no radar) Off mock -> mock
18 1FMSK8DH0NGAXXXXXX 2022 Ford Explorer XLT mock False mock False Off (no radar) Off mock -> mock
19 1FM5K8D83KGAXXXXXX 2019 Ford Explorer XLT mock False mock False no camera no camera mock -> mock
30 1FMSK8DH1LGCXXXXXX 2020 Ford Explorer XLT mock False mock False Off (no radar) Off mock -> mock
34 1FMSK7DH5LGAXXXXXX 2020 Ford Explorer XLT mock False mock False Off (no radar) Off mock -> mock
35 1FM5K8D8XHGCXXXXXX 2017 Ford Explorer XLT 4WD mock False mock False no camera no camera mock -> mock
36 1FMSK8DH0LGBXXXXXX 2020 Ford Explorer XLT mock False mock False Off (no radar) Off mock -> mock
37 1FMSK8DH4MGAXXXXXX 2021 Ford Explorer mock False mock False Off (no radar) Off mock -> mock
40 1FM5K8GT6HGDXXXXXX 2017 Ford Explorer Sport mock False mock False no camera no camera mock -> mock
42 1FMSK8DH1NGAXXXXXX 2022 Ford Explorer XLT mock False mock False Off (no radar) Off mock -> mock
43 1FMSK8DH5NGAXXXXXX 2022 Ford Explorer XLT mock False mock False Off (no radar) Off mock -> mock
I think we should pick a subset of ECUs to care about, and ignore the rest. This random Bronco does not fingerprint because the engine version is out of range (we pick radar and camera on Hyundai and radar camera and EPS on Toyota): d1aacbb70e8a9d4b|2024-01-27--09-47-46
A heads up, alot of us are running this UDS fix https://github.com/commaai/panda/pull/1524 to get CANFD responses.
I'm not sure you've tested this with some Mazda data, but I found shared ECUs. https://github.com/commaai/panda/pull/1524#issuecomment-1858925102
I've been writing scripts to pull information from the NHTSA and Ford Motorcraft site for a scraped list of VINs so that I can find patterns in the software versions. I can determine whether a given car has ACC and Lane Centering enabled from the configuration which Motorcraft tells us was written to the ECU.
For the Explorer (and Aviator), the presence of a radar ECU is enough to confirm that the car has ACC and Lane Centering. For all the other ECUs the software versions are common between cars both with and without ACC and Lane Centering.
Show table
| Ecu | Part Number | Software | ACC? | Lane Centering? |
|---|---|---|---|---|
| radar | - | - | No | No |
| LB5T-14F089-AA | LB5T-14D049-AB | Yes | Yes | |
| camera | - | - | No | No |
| LB5T-14F403-CA | LB5T-14F397-AD | Both | Both | |
| LB5T-14F397-AE | Both | Both | ||
| LB5T-14F397-AF | Both | Both | ||
| LC5T-14F403-FA | LC5T-14F397-AH | Yes | Yes | |
| eps | GG13-14F079-AD | HB53-14D003-AF | No | No |
| L1MC-14F079-AE | L1MC-14D003-AJ | Both | Both | |
| L1MC-14D003-AK | Both | Both | ||
| L1MC-14D003-AL | Both | Both | ||
| M1MC-14D003-AB | Yes | Yes | ||
| M1MC-14D003-AC | Yes | Yes | ||
| M1MC-14F079-AA | L1MC-14D003-AL | Both | Both | |
| M1MC-14D003-AB | Both | Both | ||
| M1MC-14D003-AC | Both | Both | ||
| P1MC-14F079-AA | P1MC-14D003-AA | Both | Both | |
| abs | FB53-14F065-BA | HB53-2D053-BA | No | No |
| L1MC-14F065-AB | L1MC-2D053-AJ | Yes | Yes | |
| L1MC-2D053-BA | Both | Both | ||
| L1MC-2D053-BD | Yes | Yes | ||
| L1MC-2D053-BF | Yes | Yes | ||
| L1MC-2D053-BJ | No | No | ||
| L1MC-14F065-CB | L1MC-2D053-BB | Both | Both | |
| L1MC-2D053-BC | Both | Both | ||
| L1MC-2D053-BD | Both | Both | ||
| L1MC-2D053-BE | Both | Both | ||
| L1MC-2D053-BF | Both | Both | ||
| L1MC-2D053-BJ | Both | Both | ||
| L1MC-14F065-DA | L1MC-2D053-KB | Both | Both |
For the Escape (and Bronco Sport) there is no way of identifying whether the car has both ACC and Lane Centering from the FW response alone. Ford packages ACC and LCA separately on these cars, and the ECU configuration which determines whether LCA is active isn't recorded in the software version.
Soon I'll check if we can query other identifiers from the camera to see whether LCA is enabled. Otherwise, there is likely signals on CAN we could use, similar to checking that adaptive cruise is enabled (and not normal cruise). I'm not sure which is preferable.
I'll continue working on collecting the FW versions since it will still be useful for fuzzy fingerprinting.
I collected FW for 30,000 VINs and produced a table grouped by the different part numbers/fw versions for the abs, eps, fwdCamera and fwdRadar. (Note: the table only includes US cars right now - so the Fiesta/Focus/Kuga from the EU are excluded)
Only the ABS firmware is not shared between models. In some cases, the PSCM firmware is shared between the F-150 and Mustang Mach-E, and separately between the Bronco Sport and Escape.
We cannot use firmware to determine whether ACC and LCA are enabled. Instead we can send queries to the ABS, PSCM and potentially the PCM. If we can't reach the PCM behind the gateway with this query then we can still detect whether the cruise mode is adaptive when onroad from the CAN signal. Lots of ECUs in the car also have this information (BdyCM, IPMA, APIM, IPC...) for one purpose or another.
Thanks for contributing to openpilot! In order for us to review your PR as quickly as possible, check the following:
- Convert your PR to a draft unless it's ready to review
- Read the contributing docs
- Before marking as "ready for review", ensure:
- the goal is clearly stated in the description
- all the tests are passing
- the change is something we merge
- include a route or your device' dongle ID if relevant
I updated the matching to only look at the "model year" and "platform code" hints in the FW (so, the first four characters) and ignore the software version.
If we considered the software version, we could allow any within the known range of software for that platform + ecu (for example, we could allow AB if we had seen AA and AC), but we normally receive PRs for consecutive FW versions anyway and there aren't many gaps:
Old platform codes
PlatformHint: [ModelYearHint-SoftwareRevision]
FORD BRONCO SPORT 1ST GEN
(Ecu.eps, 0x730, None):
X6C: ['L-AAH', 'L-AAK']
Have other brands had to use the software version (or "date code") to restrict compatibility?
Since I already collected FW for lots of cars we haven't seen yet in openpilot, I could write a notebook to compare fingerprinting success rates without fuzzy, fuzzy with model year + platform hint + software and just model year + platform hint.
Have other brands had to use the software version (or "date code") to restrict compatibility?
I believe we ignore the software revisions on Hyundai, but we use the date code to block new model years (sometimes old parts are used on newer cars but it's rare and there's usually nothing different) as Hyundai usually introduces new features/differences when they bump the date code. See: https://github.com/commaai/openpilot/discussions/30810 - we don't want to nor do we fuzzy fingerprint on any of these cars because of this.
We can potentially switch to the software versions for HKG but so far the date code is sufficient to block new cars from fuzzy fingerprinting just because how different new Hyundais are. Since Ford's API is way more static I would think about ways to possibly relax this if we determine it safe.
So far we've drawn the fingerprinting line at: if this car is a known model + it has all the ADAS features required for openpilot (ACC + LKAS) + there is an expected lateral API. But perhaps we want to move towards fingerprinting any known model and detecting the API later on, preventing engagement if it is not expected. I don't know if we fully understand the API well enough to do this for all makes yet though.
Since Ford's API is way more static I would think about ways to possibly relax this if we determine it safe.
I think the only path forward for Ford is to just identify the platform using the FW, and detect LKAS/ACC availability later, since there is no pattern in the FW representing the packages.
We already prevent engagement for non-adaptive cruise, and for most models (except at least the Bronco Sport and Escape) the LKAS and ACC features we require are in the same package (i.e. if ACC is available then LKAS just works). We will be able to catch the missing LKAS API later either using the UDS queries already merged, or finding some CAN signal.