You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
86 lines
2.8 KiB
86 lines
2.8 KiB
import os
|
|
|
|
from common.realtime import sec_since_boot
|
|
from common.fingerprints import eliminate_incompatible_cars, all_known_cars
|
|
|
|
from selfdrive.swaglog import cloudlog
|
|
import selfdrive.messaging as messaging
|
|
from common.fingerprints import HONDA, TOYOTA, GM
|
|
|
|
def load_interfaces(x):
|
|
ret = {}
|
|
for interface in x:
|
|
try:
|
|
imp = __import__('selfdrive.car.%s.interface' % interface, fromlist=['CarInterface']).CarInterface
|
|
except ImportError:
|
|
imp = None
|
|
for car in x[interface]:
|
|
ret[car] = imp
|
|
return ret
|
|
|
|
# imports from directory selfdrive/car/<name>/
|
|
interfaces = load_interfaces({
|
|
'honda': [HONDA.CIVIC, HONDA.ACURA_ILX, HONDA.CRV, HONDA.ODYSSEY, HONDA.ACURA_RDX, HONDA.PILOT, HONDA.RIDGELINE],
|
|
'toyota': [TOYOTA.PRIUS, TOYOTA.RAV4, TOYOTA.RAV4H, TOYOTA.COROLLA, TOYOTA.LEXUS_RXH],
|
|
'gm': [GM.VOLT],
|
|
'simulator2': ['simulator2'],
|
|
'mock': ['mock']})
|
|
|
|
# **** for use live only ****
|
|
def fingerprint(logcan, timeout):
|
|
if os.getenv("SIMULATOR2") is not None:
|
|
return ("simulator2", None)
|
|
|
|
finger_st = sec_since_boot()
|
|
|
|
cloudlog.warning("waiting for fingerprint...")
|
|
candidate_cars = all_known_cars()
|
|
finger = {}
|
|
st = None
|
|
while 1:
|
|
for a in messaging.drain_sock(logcan, wait_for_one=True):
|
|
if st is None:
|
|
st = sec_since_boot()
|
|
for can in a.can:
|
|
if can.src == 0:
|
|
finger[can.address] = len(can.dat)
|
|
candidate_cars = eliminate_incompatible_cars(can, candidate_cars)
|
|
|
|
ts = sec_since_boot()
|
|
# if we only have one car choice and the time_fingerprint since we got our first
|
|
# message has elapsed, exit. Toyota needs higher time_fingerprint, since DSU does not
|
|
# broadcast immediately
|
|
if len(candidate_cars) == 1 and st is not None:
|
|
# TODO: better way to decide to wait more if Toyota
|
|
time_fingerprint = 1.0 if ("TOYOTA" in candidate_cars[0] or "LEXUS" in candidate_cars[0]) else 0.1
|
|
if (ts-st) > time_fingerprint:
|
|
break
|
|
|
|
# bail if no cars left or we've been waiting too long
|
|
elif len(candidate_cars) == 0 or (timeout and ts-finger_st > timeout):
|
|
return None, finger
|
|
|
|
cloudlog.warning("fingerprinted %s", candidate_cars[0])
|
|
return (candidate_cars[0], finger)
|
|
|
|
|
|
def get_car(logcan, sendcan=None, passive=True):
|
|
# TODO: timeout only useful for replays so controlsd can start before unlogger
|
|
timeout = 1. if passive else None
|
|
candidate, fingerprints = fingerprint(logcan, timeout)
|
|
|
|
if candidate is None:
|
|
cloudlog.warning("car doesn't match any fingerprints: %r", fingerprints)
|
|
if passive:
|
|
candidate = "mock"
|
|
else:
|
|
return None, None
|
|
|
|
interface_cls = interfaces[candidate]
|
|
if interface_cls is None:
|
|
cloudlog.warning("car matched %s, but interface wasn't available" % candidate)
|
|
return None, None
|
|
|
|
params = interface_cls.get_params(candidate, fingerprints)
|
|
|
|
return interface_cls(params, sendcan), params
|
|
|