VIN: query on bus 0 to log data (#31165)

* query on bus 0

* fix

* log vin_rx_bus

* fix!
old-commit-hash: 289868297e
chrysler-long2
Shane Smiskol 1 year ago committed by GitHub
parent 9488aafba4
commit ff6ae8f1b9
  1. 14
      selfdrive/car/car_helpers.py
  2. 4
      selfdrive/car/fw_versions.py
  3. 4
      selfdrive/car/tests/test_fw_fingerprint.py
  4. 43
      selfdrive/car/vin.py

@ -127,9 +127,6 @@ def fingerprint(logcan, sendcan, num_pandas):
start_time = time.monotonic() start_time = time.monotonic()
if not skip_fw_query: if not skip_fw_query:
# Vin query only reliably works through OBDII
bus = 1
cached_params = params.get("CarParamsCache") cached_params = params.get("CarParamsCache")
if cached_params is not None: if cached_params is not None:
with car.CarParams.from_bytes(cached_params) as cached_params: with car.CarParams.from_bytes(cached_params) as cached_params:
@ -139,20 +136,21 @@ def fingerprint(logcan, sendcan, num_pandas):
if cached_params is not None and len(cached_params.carFw) > 0 and \ if cached_params is not None and len(cached_params.carFw) > 0 and \
cached_params.carVin is not VIN_UNKNOWN and not disable_fw_cache: cached_params.carVin is not VIN_UNKNOWN and not disable_fw_cache:
cloudlog.warning("Using cached CarParams") cloudlog.warning("Using cached CarParams")
vin, vin_rx_addr = cached_params.carVin, 0 vin_rx_addr, vin_rx_bus, vin = -1, -1, cached_params.carVin
car_fw = list(cached_params.carFw) car_fw = list(cached_params.carFw)
cached = True cached = True
else: else:
cloudlog.warning("Getting VIN & FW versions") cloudlog.warning("Getting VIN & FW versions")
set_obd_multiplexing(params, True) set_obd_multiplexing(params, True)
vin_rx_addr, vin = get_vin(logcan, sendcan, bus) # Vin query only reliably works through OBDII
vin_rx_addr, vin_rx_bus, vin = get_vin(logcan, sendcan, (1, 0))
ecu_rx_addrs = get_present_ecus(logcan, sendcan, num_pandas=num_pandas) ecu_rx_addrs = get_present_ecus(logcan, sendcan, num_pandas=num_pandas)
car_fw = get_fw_versions_ordered(logcan, sendcan, ecu_rx_addrs, num_pandas=num_pandas) car_fw = get_fw_versions_ordered(logcan, sendcan, ecu_rx_addrs, num_pandas=num_pandas)
cached = False cached = False
exact_fw_match, fw_candidates = match_fw_to_car(car_fw) exact_fw_match, fw_candidates = match_fw_to_car(car_fw)
else: else:
vin, vin_rx_addr = VIN_UNKNOWN, 0 vin_rx_addr, vin_rx_bus, vin = -1, -1, VIN_UNKNOWN
exact_fw_match, fw_candidates, car_fw = True, set(), [] exact_fw_match, fw_candidates, car_fw = True, set(), []
cached = False cached = False
@ -187,8 +185,8 @@ def fingerprint(logcan, sendcan, num_pandas):
source = car.CarParams.FingerprintSource.fixed source = car.CarParams.FingerprintSource.fixed
cloudlog.event("fingerprinted", car_fingerprint=car_fingerprint, source=source, fuzzy=not exact_match, cached=cached, cloudlog.event("fingerprinted", car_fingerprint=car_fingerprint, source=source, fuzzy=not exact_match, cached=cached,
fw_count=len(car_fw), ecu_responses=list(ecu_rx_addrs), vin_rx_addr=vin_rx_addr, fingerprints=finger, fw_count=len(car_fw), ecu_responses=list(ecu_rx_addrs), vin_rx_addr=vin_rx_addr, vin_rx_bus=vin_rx_bus,
fw_query_time=fw_query_time, error=True) fingerprints=finger, fw_query_time=fw_query_time, error=True)
return car_fingerprint, finger, vin, car_fw, source, exact_match return car_fingerprint, finger, vin, car_fw, source, exact_match

@ -370,8 +370,8 @@ if __name__ == "__main__":
t = time.time() t = time.time()
print("Getting vin...") print("Getting vin...")
vin_rx_addr, vin = get_vin(logcan, sendcan, 1, retry=10, debug=args.debug) vin_rx_addr, vin_rx_bus, vin = get_vin(logcan, sendcan, (1, 0), retry=10, debug=args.debug)
print(f'RX: {hex(vin_rx_addr)}, VIN: {vin}') print(f'RX: {hex(vin_rx_addr)}, BUS: {vin_rx_bus}, VIN: {vin}')
print(f"Getting VIN took {time.time() - t:.3f} s") print(f"Getting VIN took {time.time() - t:.3f} s")
print() print()

@ -212,7 +212,7 @@ class TestFwFingerprintTiming(unittest.TestCase):
def test_startup_timing(self): def test_startup_timing(self):
# Tests worse-case VIN query time and typical present ECU query time # Tests worse-case VIN query time and typical present ECU query time
vin_ref_time = 1.0 vin_ref_time = 2.0
present_ecu_ref_time = 0.75 present_ecu_ref_time = 0.75
def fake_get_ecu_addrs(*_, timeout): def fake_get_ecu_addrs(*_, timeout):
@ -232,7 +232,7 @@ class TestFwFingerprintTiming(unittest.TestCase):
self.total_time = 0.0 self.total_time = 0.0
with (mock.patch("openpilot.selfdrive.car.isotp_parallel_query.IsoTpParallelQuery.get_data", self.fake_get_data)): with (mock.patch("openpilot.selfdrive.car.isotp_parallel_query.IsoTpParallelQuery.get_data", self.fake_get_data)):
for _ in range(self.N): for _ in range(self.N):
get_vin(fake_socket, fake_socket, 1) get_vin(fake_socket, fake_socket, (0, 1))
self._assert_timing(self.total_time / self.N, vin_ref_time) self._assert_timing(self.total_time / self.N, vin_ref_time)
print(f'get_vin, query time={self.total_time / self.N} seconds') print(f'get_vin, query time={self.total_time / self.N} seconds')

@ -15,33 +15,34 @@ def is_valid_vin(vin: str):
return re.fullmatch(VIN_RE, vin) is not None return re.fullmatch(VIN_RE, vin) is not None
def get_vin(logcan, sendcan, bus, timeout=0.1, retry=5, debug=False): def get_vin(logcan, sendcan, buses, timeout=0.1, retry=5, debug=False):
addrs = list(range(0x7e0, 0x7e8)) + list(range(0x18DA00F1, 0x18DB00F1, 0x100)) # addrs to process/wait for addrs = list(range(0x7e0, 0x7e8)) + list(range(0x18DA00F1, 0x18DB00F1, 0x100)) # addrs to process/wait for
valid_vin_addrs = [0x7e0, 0x7e2, 0x18da10f1, 0x18da0ef1] # engine, VMCU, 29-bit engine, PGM-FI valid_vin_addrs = [0x7e0, 0x7e2, 0x18da10f1, 0x18da0ef1] # engine, VMCU, 29-bit engine, PGM-FI
for i in range(retry): for i in range(retry):
for request, response in ((StdQueries.UDS_VIN_REQUEST, StdQueries.UDS_VIN_RESPONSE), (StdQueries.OBD_VIN_REQUEST, StdQueries.OBD_VIN_RESPONSE)): for bus in buses:
try: for request, response in ((StdQueries.UDS_VIN_REQUEST, StdQueries.UDS_VIN_RESPONSE), (StdQueries.OBD_VIN_REQUEST, StdQueries.OBD_VIN_RESPONSE)):
query = IsoTpParallelQuery(sendcan, logcan, bus, addrs, [request, ], [response, ], functional_addrs=FUNCTIONAL_ADDRS, debug=debug) try:
results = query.get_data(timeout) query = IsoTpParallelQuery(sendcan, logcan, bus, addrs, [request, ], [response, ], functional_addrs=FUNCTIONAL_ADDRS, debug=debug)
results = query.get_data(timeout)
for addr in valid_vin_addrs: for addr in valid_vin_addrs:
vin = results.get((addr, None)) vin = results.get((addr, None))
if vin is not None: if vin is not None:
# Ford pads with null bytes # Ford pads with null bytes
if len(vin) == 24: if len(vin) == 24:
vin = re.sub(b'\x00*$', b'', vin) vin = re.sub(b'\x00*$', b'', vin)
# Honda Bosch response starts with a length, trim to correct length # Honda Bosch response starts with a length, trim to correct length
if vin.startswith(b'\x11'): if vin.startswith(b'\x11'):
vin = vin[1:18] vin = vin[1:18]
return get_rx_addr_for_tx_addr(addr), vin.decode() return get_rx_addr_for_tx_addr(addr), bus, vin.decode()
cloudlog.error(f"vin query retry ({i+1}) ...") cloudlog.error(f"vin query retry ({i+1}) ...")
except Exception: except Exception:
cloudlog.exception("VIN query exception") cloudlog.exception("VIN query exception")
return 0, VIN_UNKNOWN return -1, -1, VIN_UNKNOWN
if __name__ == "__main__": if __name__ == "__main__":
@ -59,5 +60,5 @@ if __name__ == "__main__":
logcan = messaging.sub_sock('can') logcan = messaging.sub_sock('can')
time.sleep(1) time.sleep(1)
vin_rx_addr, vin = get_vin(logcan, sendcan, args.bus, args.timeout, args.retry, debug=args.debug) vin_rx_addr, vin_rx_bus, vin = get_vin(logcan, sendcan, (args.bus,), args.timeout, args.retry, debug=args.debug)
print(f'RX: {hex(vin_rx_addr)}, VIN: {vin}') print(f'RX: {hex(vin_rx_addr)}, BUS: {vin_rx_bus}, VIN: {vin}')

Loading…
Cancel
Save