openpilot is an open source driver assistance system. openpilot performs the functions of Automated Lane Centering and Adaptive Cruise Control for over 200 supported car makes and models.
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.
 
 
 
 
 
 

108 lines
3.7 KiB

import os
import time
from common.basedir import BASEDIR
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
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
def _get_interface_names():
# read all the folders in selfdrive/car and return a dict where:
# - keys are all the car names that which we have an interface for
# - values are lists of spefic car models for a given car
interface_names = {}
for car_folder in [x[0] for x in os.walk(BASEDIR + '/selfdrive/car')]:
try:
car_name = car_folder.split('/')[-1]
model_names = __import__('selfdrive.car.%s.values' % car_name, fromlist=['CAR']).CAR
model_names = [getattr(model_names, c) for c in model_names.__dict__.keys() if not c.startswith("__")]
interface_names[car_name] = model_names
except (ImportError, IOError):
pass
return interface_names
# imports from directory selfdrive/car/<name>/
interfaces = load_interfaces(_get_interface_names())
# BOUNTY: every added fingerprint in selfdrive/car/*/values.py is a $100 coupon code on shop.comma.ai
# **** for use live only ****
def fingerprint(logcan, timeout):
if os.getenv("SIMULATOR2") is not None:
return ("simulator2", None)
elif os.getenv("SIMULATOR") is not None:
return ("simulator", None)
cloudlog.warning("waiting for fingerprint...")
candidate_cars = all_known_cars()
finger = {}
st = None
st_passive = sec_since_boot() # only relevant when passive
can_seen = False
while 1:
for a in messaging.drain_sock(logcan):
for can in a.can:
can_seen = True
# ignore everything not on bus 0 and with more than 11 bits,
# which are ussually sporadic and hard to include in fingerprints
if can.src == 0 and can.address < 0x800:
finger[can.address] = len(can.dat)
candidate_cars = eliminate_incompatible_cars(can, candidate_cars)
if st is None and can_seen:
st = sec_since_boot() # start time
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 - st_passive) > timeout):
return None, finger
time.sleep(0.01)
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 = 2. 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 or failed to import" % candidate)
return None, None
params = interface_cls.get_params(candidate, fingerprints)
return interface_cls(params, sendcan), params