diff --git a/common/params.cc b/common/params.cc index 74106a17c1..04906f3d6a 100644 --- a/common/params.cc +++ b/common/params.cc @@ -255,7 +255,6 @@ std::unordered_map keys = { {"EnforceTorqueLateral", PERSISTENT | BACKUP}, {"EnhancedScc", PERSISTENT | BACKUP}, {"FeatureStatus", PERSISTENT | BACKUP}, - {"Fingerprints", CLEAR_ON_MANAGER_START | CLEAR_ON_ONROAD_TRANSITION}, {"FleetManagerPin", PERSISTENT}, {"ForceOffroad", CLEAR_ON_MANAGER_START}, {"GmapKey", PERSISTENT | BACKUP}, diff --git a/selfdrive/car/car_helpers.py b/selfdrive/car/car_helpers.py index f1864ac737..5fcfe34a4f 100644 --- a/selfdrive/car/car_helpers.py +++ b/selfdrive/car/car_helpers.py @@ -169,7 +169,6 @@ def fingerprint(logcan, sendcan, num_pandas): # drain CAN socket so we get the latest messages messaging.drain_sock_raw(logcan) car_fingerprint, finger = can_fingerprint(lambda: get_one_can(logcan)) - params.put("Fingerprints", repr(finger)) exact_match = True source = car.CarParams.FingerprintSource.can diff --git a/selfdrive/car/hyundai/interface.py b/selfdrive/car/hyundai/interface.py index 4581a9daa0..d7561dcc86 100644 --- a/selfdrive/car/hyundai/interface.py +++ b/selfdrive/car/hyundai/interface.py @@ -1,8 +1,7 @@ -import ast - from cereal import car from panda import Panda from openpilot.common.params import Params +from openpilot.selfdrive.car.sunnypilot.fingerprinting import can_fingerprint, get_one_can from openpilot.selfdrive.car.hyundai.enable_radar_tracks import enable_radar_tracks from openpilot.selfdrive.car.hyundai.hyundaicanfd import CanBus from openpilot.selfdrive.car.hyundai.values import HyundaiFlags, HyundaiFlagsSP, CAR, DBC, CANFD_CAR, CAMERA_SCC_CAR, CANFD_RADAR_SCC_CAR, \ @@ -208,9 +207,10 @@ class CarInterface(CarInterfaceBase): rt_avail_cache = params.get_bool("HyundaiRadarTracksAvailableCache") if rt_avail and rt_avail_cache: pass + elif rt_avail != rt_avail_cache: + params.put_bool_nonblocking("HyundaiRadarTracksAvailableCache", rt_avail) else: - params.put_bool_nonblocking("HyundaiRadarTracksAvailableCache", bool(rt_avail)) - fingerprint = ast.literal_eval(params.get("Fingerprints", encoding="utf8")) + _, fingerprint = can_fingerprint(lambda: get_one_can(logcan)) if RADAR_START_ADDR in fingerprint[1] and DBC[CP.carFingerprint]["radar"] is not None: params.put_bool_nonblocking("HyundaiRadarTracksAvailable", True) elif RADAR_START_ADDR not in fingerprint[1] or DBC[CP.carFingerprint]["radar"] is None: diff --git a/selfdrive/car/sunnypilot/fingerprinting.py b/selfdrive/car/sunnypilot/fingerprinting.py new file mode 100644 index 0000000000..8a2565edc2 --- /dev/null +++ b/selfdrive/car/sunnypilot/fingerprinting.py @@ -0,0 +1,54 @@ +from collections.abc import Callable + +from openpilot.selfdrive.car.fingerprints import eliminate_incompatible_cars, all_legacy_fingerprint_cars +import cereal.messaging as messaging +from openpilot.selfdrive.car import gen_empty_fingerprint + +FRAME_FINGERPRINT = 100 # 1s + + +def get_one_can(logcan): + while True: + can = messaging.recv_one_retry(logcan) + if len(can.can) > 0: + return can + + +def can_fingerprint(next_can: Callable) -> tuple[str | None, dict[int, dict]]: + finger = gen_empty_fingerprint() + candidate_cars = {i: all_legacy_fingerprint_cars() for i in [0, 1]} # attempt fingerprint on both bus 0 and 1 + frame = 0 + car_fingerprint = None + done = False + + while not done: + a = next_can() + + for can in a.can: + # The fingerprint dict is generated for all buses, this way the car interface + # can use it to detect a (valid) multipanda setup and initialize accordingly + if can.src < 128: + if can.src not in finger: + finger[can.src] = {} + finger[can.src][can.address] = len(can.dat) + + for b in candidate_cars: + # Ignore extended messages and VIN query response. + if can.src == b and can.address < 0x800 and can.address not in (0x7df, 0x7e0, 0x7e8): + candidate_cars[b] = eliminate_incompatible_cars(can, candidate_cars[b]) + + # if we only have one car choice and the time since we got our first + # message has elapsed, exit + for b in candidate_cars: + if len(candidate_cars[b]) == 1 and frame > FRAME_FINGERPRINT: + # fingerprint done + car_fingerprint = candidate_cars[b][0] + + # bail if no cars left or we've been waiting for more than 2s + failed = (all(len(cc) == 0 for cc in candidate_cars.values()) and frame > FRAME_FINGERPRINT) or frame > 200 + succeeded = car_fingerprint is not None + done = failed or succeeded + + frame += 1 + + return car_fingerprint, finger