mirror of
https://github.com/dragonpilot/dragonpilot.git
synced 2026-07-11 07:52:03 +08:00
CAN-FD HKG: query FW versions from camera (#26063)
* add adas essential ecus * add adas ecu and query * add queries * add name * after * presence of adas ecu * Revert "presence of adas ecu" (POC) This reverts commit ab88a7e7df32e1c02a175b81848bd4112b2e5c69. * no whitelist for debugging * Apply suggestions from code review * add adas response * remove adas version * temp * read pandaStates * works in debug script * only fwdCamera on tucson * fix pandaStates reading * fix test_startup * fix * simpler * use existing socket * pass in number of pandas * need to create sm using outcome of fingerprinting, which uses sm fix * move default argument * use sock * always ignore always ignore * add canfd fingerprint test * Update selfdrive/car/hyundai/tests/test_hyundai.py * set
This commit is contained in:
@@ -76,7 +76,7 @@ interfaces = load_interfaces(interface_names)
|
||||
|
||||
|
||||
# **** for use live only ****
|
||||
def fingerprint(logcan, sendcan):
|
||||
def fingerprint(logcan, sendcan, num_pandas):
|
||||
fixed_fingerprint = os.environ.get('FINGERPRINT', "")
|
||||
skip_fw_query = os.environ.get('SKIP_FW_QUERY', False)
|
||||
ecu_rx_addrs = set()
|
||||
@@ -100,7 +100,7 @@ def fingerprint(logcan, sendcan):
|
||||
cloudlog.warning("Getting VIN & FW versions")
|
||||
vin_rx_addr, vin = get_vin(logcan, sendcan, bus)
|
||||
ecu_rx_addrs = get_present_ecus(logcan, sendcan)
|
||||
car_fw = get_fw_versions_ordered(logcan, sendcan, ecu_rx_addrs)
|
||||
car_fw = get_fw_versions_ordered(logcan, sendcan, ecu_rx_addrs, num_pandas=num_pandas)
|
||||
cached = False
|
||||
|
||||
exact_fw_match, fw_candidates = match_fw_to_car(car_fw)
|
||||
@@ -173,8 +173,8 @@ def fingerprint(logcan, sendcan):
|
||||
return car_fingerprint, finger, vin, car_fw, source, exact_match
|
||||
|
||||
|
||||
def get_car(logcan, sendcan):
|
||||
candidate, fingerprints, vin, car_fw, source, exact_match = fingerprint(logcan, sendcan)
|
||||
def get_car(logcan, sendcan, num_pandas=1):
|
||||
candidate, fingerprints, vin, car_fw, source, exact_match = fingerprint(logcan, sendcan, num_pandas)
|
||||
|
||||
if candidate is None:
|
||||
cloudlog.warning("car doesn't match any fingerprints: %r", fingerprints)
|
||||
|
||||
@@ -194,14 +194,14 @@ def get_brand_ecu_matches(ecu_rx_addrs):
|
||||
return brand_matches
|
||||
|
||||
|
||||
def get_fw_versions_ordered(logcan, sendcan, ecu_rx_addrs, timeout=0.1, debug=False, progress=False):
|
||||
def get_fw_versions_ordered(logcan, sendcan, ecu_rx_addrs, timeout=0.1, num_pandas=1, debug=False, progress=False):
|
||||
"""Queries for FW versions ordering brands by likelihood, breaks when exact match is found"""
|
||||
|
||||
all_car_fw = []
|
||||
brand_matches = get_brand_ecu_matches(ecu_rx_addrs)
|
||||
|
||||
for brand in sorted(brand_matches, key=lambda b: len(brand_matches[b]), reverse=True):
|
||||
car_fw = get_fw_versions(logcan, sendcan, query_brand=brand, timeout=timeout, debug=debug, progress=progress)
|
||||
car_fw = get_fw_versions(logcan, sendcan, query_brand=brand, timeout=timeout, num_pandas=num_pandas, debug=debug, progress=progress)
|
||||
all_car_fw.extend(car_fw)
|
||||
# Try to match using FW returned from this brand only
|
||||
matches = match_fw_to_car_exact(build_fw_dict(car_fw))
|
||||
@@ -211,7 +211,7 @@ def get_fw_versions_ordered(logcan, sendcan, ecu_rx_addrs, timeout=0.1, debug=Fa
|
||||
return all_car_fw
|
||||
|
||||
|
||||
def get_fw_versions(logcan, sendcan, query_brand=None, extra=None, timeout=0.1, debug=False, progress=False):
|
||||
def get_fw_versions(logcan, sendcan, query_brand=None, extra=None, timeout=0.1, num_pandas=1, debug=False, progress=False):
|
||||
versions = VERSIONS.copy()
|
||||
|
||||
# Each brand can define extra ECUs to query for data collection
|
||||
@@ -252,6 +252,10 @@ def get_fw_versions(logcan, sendcan, query_brand=None, extra=None, timeout=0.1,
|
||||
for addr in tqdm(addrs, disable=not progress):
|
||||
for addr_chunk in chunks(addr):
|
||||
for brand, r in requests:
|
||||
# Skip query if no panda available
|
||||
if r.bus > num_pandas * 4 - 1:
|
||||
continue
|
||||
|
||||
try:
|
||||
addrs = [(a, s) for (b, a, s) in addr_chunk if b in (brand, 'any') and
|
||||
(len(r.whitelist_ecus) == 0 or ecu_types[(b, a, s)] in r.whitelist_ecus)]
|
||||
@@ -292,6 +296,7 @@ if __name__ == "__main__":
|
||||
args = parser.parse_args()
|
||||
|
||||
logcan = messaging.sub_sock('can')
|
||||
pandaStates_sock = messaging.sub_sock('pandaStates')
|
||||
sendcan = messaging.pub_sock('sendcan')
|
||||
|
||||
extra: Any = None
|
||||
@@ -305,6 +310,7 @@ if __name__ == "__main__":
|
||||
extra = {"any": {"debug": extra}}
|
||||
|
||||
time.sleep(1.)
|
||||
num_pandas = len(messaging.recv_one_retry(pandaStates_sock).pandaStates)
|
||||
|
||||
t = time.time()
|
||||
print("Getting vin...")
|
||||
@@ -314,7 +320,7 @@ if __name__ == "__main__":
|
||||
print()
|
||||
|
||||
t = time.time()
|
||||
fw_vers = get_fw_versions(logcan, sendcan, query_brand=args.brand, extra=extra, debug=args.debug, progress=True)
|
||||
fw_vers = get_fw_versions(logcan, sendcan, query_brand=args.brand, extra=extra, num_pandas=num_pandas, debug=args.debug, progress=True)
|
||||
_, candidates = match_fw_to_car(fw_vers)
|
||||
|
||||
print()
|
||||
|
||||
Executable
+29
@@ -0,0 +1,29 @@
|
||||
#!/usr/bin/env python3
|
||||
import unittest
|
||||
|
||||
from cereal import car
|
||||
from selfdrive.car.car_helpers import get_interface_attr
|
||||
from selfdrive.car.fw_versions import FW_QUERY_CONFIGS
|
||||
from selfdrive.car.hyundai.values import CANFD_CAR
|
||||
|
||||
Ecu = car.CarParams.Ecu
|
||||
|
||||
ECU_NAME = {v: k for k, v in Ecu.schema.enumerants.items()}
|
||||
VERSIONS = get_interface_attr("FW_VERSIONS", ignore_none=True)
|
||||
|
||||
|
||||
class TestHyundaiFingerprint(unittest.TestCase):
|
||||
def test_auxiliary_request_ecu_whitelist(self):
|
||||
# Asserts only auxiliary Ecus can exist in database for CAN-FD cars
|
||||
config = FW_QUERY_CONFIGS['hyundai']
|
||||
whitelisted_ecus = {ecu for r in config.requests for ecu in r.whitelist_ecus if r.bus > 3}
|
||||
|
||||
for car_model in CANFD_CAR:
|
||||
ecus = {fw[0] for fw in VERSIONS['hyundai'][car_model].keys()}
|
||||
ecus_not_in_whitelist = ecus - whitelisted_ecus
|
||||
ecu_strings = ", ".join([f'Ecu.{ECU_NAME[ecu]}' for ecu in ecus_not_in_whitelist])
|
||||
self.assertEqual(len(ecus_not_in_whitelist), 0, f'{car_model}: Car model has ECUs not in auxiliary request whitelists: {ecu_strings}')
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -300,6 +300,19 @@ FW_QUERY_CONFIG = FwQueryConfig(
|
||||
[HYUNDAI_VERSION_RESPONSE],
|
||||
whitelist_ecus=[Ecu.engine, Ecu.transmission, Ecu.eps, Ecu.abs, Ecu.fwdRadar],
|
||||
),
|
||||
# CAN-FD queries
|
||||
Request(
|
||||
[HYUNDAI_VERSION_REQUEST_LONG],
|
||||
[HYUNDAI_VERSION_RESPONSE],
|
||||
whitelist_ecus=[Ecu.fwdRadar],
|
||||
bus=4,
|
||||
),
|
||||
Request(
|
||||
[HYUNDAI_VERSION_REQUEST_LONG],
|
||||
[HYUNDAI_VERSION_RESPONSE],
|
||||
whitelist_ecus=[Ecu.fwdCamera, Ecu.adas],
|
||||
bus=5,
|
||||
),
|
||||
],
|
||||
extra_ecus=[
|
||||
(Ecu.adas, 0x730, None), # ADAS Driving ECU on HDA2 platforms
|
||||
@@ -1326,15 +1339,6 @@ FW_VERSIONS = {
|
||||
],
|
||||
},
|
||||
CAR.KIA_EV6: {
|
||||
(Ecu.abs, 0x7d1, None): [
|
||||
b'\xf1\x00CV IEB \x02 101!\x10\x18 58520-CV100',
|
||||
b'\xf1\x00CV IEB \x03 101!\x10\x18 58520-CV100',
|
||||
b'\xf1\x8758520CV100\xf1\x00CV IEB \x02 101!\x10\x18 58520-CV100',
|
||||
],
|
||||
(Ecu.eps, 0x7d4, None): [
|
||||
b'\xf1\x00CV1 MDPS R 1.00 1.04 57700-CV000 1B30',
|
||||
b'\xf1\x00CV1 MDPS R 1.00 1.05 57700-CV000 2425',
|
||||
],
|
||||
(Ecu.fwdRadar, 0x7d0, None): [
|
||||
b'\xf1\x00CV1_ RDR ----- 1.00 1.01 99110-CV000 ',
|
||||
b'\xf1\x8799110CV000\xf1\x00CV1_ RDR ----- 1.00 1.01 99110-CV000 ',
|
||||
@@ -1346,16 +1350,6 @@ FW_VERSIONS = {
|
||||
],
|
||||
},
|
||||
CAR.IONIQ_5: {
|
||||
(Ecu.abs, 0x7d1, None): [
|
||||
b'\xf1\x00NE1 IEB \x07 106!\x11) 58520-GI010',
|
||||
b'\xf1\x8758520GI010\xf1\x00NE1 IEB \x07 106!\x11) 58520-GI010',
|
||||
b'\xf1\x00NE1 IEB \x08 104!\x04\x05 58520-GI000',
|
||||
b'\xf1\x8758520GI000\xf1\x00NE1 IEB \x08 104!\x04\x05 58520-GI000',
|
||||
],
|
||||
(Ecu.eps, 0x7d4, None): [
|
||||
b'\xf1\x00NE MDPS R 1.00 1.06 57700GI000 4NEDR106',
|
||||
b'\xf1\x8757700GI000 \xf1\x00NE MDPS R 1.00 1.06 57700GI000 4NEDR106',
|
||||
],
|
||||
(Ecu.fwdRadar, 0x7d0, None): [
|
||||
b'\xf1\x00NE1_ RDR ----- 1.00 1.00 99110-GI000 ',
|
||||
b'\xf1\x8799110GI000\xf1\x00NE1_ RDR ----- 1.00 1.00 99110-GI000 ',
|
||||
@@ -1369,16 +1363,6 @@ FW_VERSIONS = {
|
||||
(Ecu.fwdCamera, 0x7c4, None): [
|
||||
b'\xf1\x00NX4 FR_CMR AT USA LHD 1.00 1.00 99211-N9240 14Q',
|
||||
],
|
||||
(Ecu.eps, 0x7d4, None): [
|
||||
b'\xf1\x00NX4 MDPS C 1.00 1.01 56300-P0100 2228',
|
||||
],
|
||||
(Ecu.engine, 0x7e0, None): [
|
||||
b'\xf1\x87391312MND0',
|
||||
],
|
||||
(Ecu.transmission, 0x7e1, None): [
|
||||
b'\xf1\x00PSBG2441 G19_Rev\x00\x00\x00SNX4T16XXHS01NS2lS\xdfa',
|
||||
b'\xf1\x8795441-3D220\x00\xf1\x81G19_Rev\x00\x00\x00\xf1\x00PSBG2441 G19_Rev\x00\x00\x00SNX4T16XXHS01NS2lS\xdfa',
|
||||
],
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -82,30 +82,30 @@ class Controls:
|
||||
|
||||
self.log_sock = messaging.sub_sock('androidLog')
|
||||
|
||||
if CI is None:
|
||||
# wait for one pandaState and one CAN packet
|
||||
print("Waiting for CAN messages...")
|
||||
get_one_can(self.can_sock)
|
||||
|
||||
self.CI, self.CP = get_car(self.can_sock, self.pm.sock['sendcan'])
|
||||
else:
|
||||
self.CI, self.CP = CI, CI.CP
|
||||
|
||||
params = Params()
|
||||
self.joystick_mode = params.get_bool("JoystickDebugMode") or (self.CP.notCar and sm is None)
|
||||
joystick_packet = ['testJoystick'] if self.joystick_mode else []
|
||||
|
||||
self.sm = sm
|
||||
if self.sm is None:
|
||||
ignore = []
|
||||
ignore = ['testJoystick']
|
||||
if SIMULATION:
|
||||
ignore += ['driverCameraState', 'managerState']
|
||||
if params.get_bool('WideCameraOnly'):
|
||||
ignore += ['roadCameraState']
|
||||
self.sm = messaging.SubMaster(['deviceState', 'pandaStates', 'peripheralState', 'modelV2', 'liveCalibration',
|
||||
'driverMonitoringState', 'longitudinalPlan', 'lateralPlan', 'liveLocationKalman',
|
||||
'managerState', 'liveParameters', 'radarState', 'liveTorqueParameters'] + self.camera_packets + joystick_packet,
|
||||
ignore_alive=ignore, ignore_avg_freq=['radarState', 'longitudinalPlan'])
|
||||
'managerState', 'liveParameters', 'radarState', 'liveTorqueParameters', 'testJoystick'] + self.camera_packets,
|
||||
ignore_alive=ignore, ignore_avg_freq=['radarState', 'longitudinalPlan', 'testJoystick'])
|
||||
|
||||
if CI is None:
|
||||
# wait for one pandaState and one CAN packet
|
||||
print("Waiting for CAN messages...")
|
||||
get_one_can(self.can_sock)
|
||||
|
||||
num_pandas = len(messaging.recv_one_retry(self.sm.sock['pandaStates']).pandaStates)
|
||||
self.CI, self.CP = get_car(self.can_sock, self.pm.sock['sendcan'], num_pandas)
|
||||
else:
|
||||
self.CI, self.CP = CI, CI.CP
|
||||
|
||||
self.joystick_mode = params.get_bool("JoystickDebugMode") or (self.CP.notCar and sm is None)
|
||||
|
||||
# set alternative experiences from parameters
|
||||
self.disengage_on_accelerator = params.get_bool("DisengageOnAccelerator")
|
||||
|
||||
@@ -94,6 +94,9 @@ class TestStartup(unittest.TestCase):
|
||||
|
||||
time.sleep(2) # wait for controlsd to be ready
|
||||
|
||||
pm.send('can', can_list_to_can_capnp([[0, 0, b"", 0]]))
|
||||
time.sleep(0.1)
|
||||
|
||||
msg = messaging.new_message('pandaStates', 1)
|
||||
msg.pandaStates[0].pandaType = log.PandaState.PandaType.uno
|
||||
pm.send('pandaStates', msg)
|
||||
|
||||
Reference in New Issue
Block a user