Make pylint more strict (#1626)

* make pylint more strict

* cleanup in progress

* done cleaning up

* no opendbc
pull/1625/head
Willem Melching 5 years ago committed by GitHub
parent 676d0901e5
commit 843a64c72f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 6
      .pre-commit-config.yaml
  2. 116
      .pylintrc
  3. 15
      common/file_helpers.py
  4. 4
      common/logging_extra.py
  5. 17
      common/params.py
  6. 6
      common/spinner.py
  7. 6
      common/text_window.py
  8. 2
      common/transformations/coordinates.py
  9. 10
      common/transformations/orientation.py
  10. 11
      common/url_file.py
  11. 34
      selfdrive/athena/athenad.py
  12. 9
      selfdrive/athena/test_helpers.py
  13. 1
      selfdrive/boardd/tests/boardd_old.py
  14. 8
      selfdrive/boardd/tests/test_boardd_api.py
  15. 13
      selfdrive/car/__init__.py
  16. 7
      selfdrive/car/chrysler/interface.py
  17. 2
      selfdrive/car/ford/interface.py
  18. 29
      selfdrive/car/gm/carcontroller.py
  19. 2
      selfdrive/car/gm/interface.py
  20. 7
      selfdrive/car/honda/interface.py
  21. 2
      selfdrive/car/hyundai/interface.py
  22. 4
      selfdrive/car/interfaces.py
  23. 2
      selfdrive/car/mazda/interface.py
  24. 2
      selfdrive/car/mock/interface.py
  25. 2
      selfdrive/car/nissan/interface.py
  26. 2
      selfdrive/car/subaru/interface.py
  27. 2
      selfdrive/car/toyota/interface.py
  28. 2
      selfdrive/car/volkswagen/interface.py
  29. 5
      selfdrive/controls/lib/events.py
  30. 5
      selfdrive/controls/lib/vehicle_model.py
  31. 11
      selfdrive/controls/tests/test_events.py
  32. 12
      selfdrive/crash.py
  33. 23
      selfdrive/debug/cpu_usage_stat.py
  34. 2
      selfdrive/debug/internal/sensor_test_bootloop.py
  35. 11
      selfdrive/locationd/locationd.py
  36. 7
      selfdrive/locationd/models/car_kf.py
  37. 8
      selfdrive/locationd/models/gnss_kf.py
  38. 10
      selfdrive/locationd/models/loc_kf.py
  39. 61
      selfdrive/locationd/test/ephemeris.py
  40. 2
      selfdrive/locationd/test/test_params_learner.py
  41. 1
      selfdrive/locationd/test/ublox.py
  42. 1
      selfdrive/locationd/test/ubloxd.py
  43. 3
      selfdrive/loggerd/tests/test_deleter.py
  44. 3
      selfdrive/loggerd/tests/test_uploader.py
  45. 2
      selfdrive/loggerd/uploader.py
  46. 12
      selfdrive/manager.py
  47. 10
      selfdrive/modeld/runners/keras_runner.py
  48. 9
      selfdrive/modeld/visiontest.py
  49. 80
      selfdrive/test/longitudinal_maneuvers/test_longitudinal.py
  50. 11
      selfdrive/test/process_replay/compare_logs.py
  51. 7
      selfdrive/test/process_replay/process_replay.py
  52. 6
      selfdrive/test/process_replay/test_processes.py
  53. 4
      selfdrive/test/profiling/lib.py
  54. 5
      selfdrive/test/test_car_models.py
  55. 1
      selfdrive/test/test_openpilot.py
  56. 2
      selfdrive/thermald/power_monitoring.py
  57. 2
      selfdrive/tombstoned.py
  58. 2
      selfdrive/updated.py
  59. 2
      tools/lib/auth.py
  60. 2
      tools/lib/kbhit.py
  61. 5
      tools/lib/route_framereader.py
  62. 2
      tools/replay/camera.py
  63. 10
      tools/replay/unlogger.py
  64. 8
      tools/sim/bridge.py
  65. 2
      tools/sim/lib/manual_ctrl.py

@ -10,12 +10,12 @@ repos:
rev: master rev: master
hooks: hooks:
- id: mypy - id: mypy
exclude: '^(pyextra)|(external)|(cereal)|(rednose)|(panda)|(laika)|(laika_repo)|(rednose_repo)/' exclude: '^(pyextra)|(external)|(cereal)|(rednose)|(panda)|(laika)|(opendbc)|(laika_repo)|(rednose_repo)/'
- repo: https://github.com/PyCQA/flake8 - repo: https://github.com/PyCQA/flake8
rev: master rev: master
hooks: hooks:
- id: flake8 - id: flake8
exclude: '^(pyextra)|(external)|(cereal)|(rednose)|(panda)|(laika)|(laika_repo)|(rednose_repo)/' exclude: '^(pyextra)|(external)|(cereal)|(rednose)|(panda)|(laika)|(opendbc)|(laika_repo)|(rednose_repo)/'
args: args:
- --ignore=E111,E114,E121,E122,E123,E124,E126,E127,E128,E201,E202,E203,E226,E241,E265,E266,E302,E305,E402,E501,E722,E741,W504 - --ignore=E111,E114,E121,E122,E123,E124,E126,E127,E128,E201,E202,E203,E226,E241,E265,E266,E302,E305,E402,E501,E722,E741,W504
- --statistics - --statistics
@ -27,5 +27,3 @@ repos:
language: system language: system
types: [python] types: [python]
exclude: '^(pyextra)|(external)|(cereal)|(rednose)|(panda)|(laika)|(laika_repo)|(rednose_repo)/' exclude: '^(pyextra)|(external)|(cereal)|(rednose)|(panda)|(laika)|(laika_repo)|(rednose_repo)/'
args:
- --disable=R,C,W

@ -54,121 +54,7 @@ confidence=
# --enable=similarities". If you want to run only the classes checker, but have # --enable=similarities". If you want to run only the classes checker, but have
# no Warning level messages displayed, use"--disable=all --enable=classes # no Warning level messages displayed, use"--disable=all --enable=classes
# --disable=W" # --disable=W"
disable=print-statement, disable=C,R,W0613,W0511,W0212,W0201,W0311,W0106,W0603,W0621,W0703,E1136
parameter-unpacking,
unpacking-in-except,
old-raise-syntax,
backtick,
long-suffix,
old-ne-operator,
old-octal-literal,
import-star-module-level,
non-ascii-bytes-literal,
raw-checker-failed,
bad-inline-option,
locally-disabled,
locally-enabled,
file-ignored,
suppressed-message,
useless-suppression,
deprecated-pragma,
apply-builtin,
basestring-builtin,
buffer-builtin,
cmp-builtin,
coerce-builtin,
execfile-builtin,
file-builtin,
long-builtin,
raw_input-builtin,
reduce-builtin,
standarderror-builtin,
unicode-builtin,
xrange-builtin,
coerce-method,
delslice-method,
getslice-method,
setslice-method,
no-absolute-import,
old-division,
dict-iter-method,
dict-view-method,
next-method-called,
metaclass-assignment,
indexing-exception,
raising-string,
reload-builtin,
oct-method,
hex-method,
nonzero-method,
cmp-method,
input-builtin,
round-builtin,
intern-builtin,
unichr-builtin,
map-builtin-not-iterating,
zip-builtin-not-iterating,
range-builtin-not-iterating,
filter-builtin-not-iterating,
using-cmp-argument,
eq-without-hash,
div-method,
idiv-method,
rdiv-method,
exception-message-attribute,
invalid-str-codec,
sys-max-int,
bad-python3-import,
deprecated-string-function,
deprecated-str-translate-call,
deprecated-itertools-function,
deprecated-types-field,
next-method-defined,
dict-items-not-iterating,
dict-keys-not-iterating,
dict-values-not-iterating,
bad-indentation,
line-too-long,
missing-docstring,
multiple-statements,
bad-continuation,
invalid-name,
too-many-arguments,
too-many-locals,
superfluous-parens,
bad-whitespace,
too-many-instance-attributes,
wrong-import-position,
ungrouped-imports,
wrong-import-order,
protected-access,
trailing-whitespace,
too-many-branches,
too-few-public-methods,
too-many-statements,
trailing-newlines,
attribute-defined-outside-init,
too-many-return-statements,
too-many-public-methods,
unused-argument,
old-style-class,
no-init,
len-as-condition,
unneeded-not,
no-self-use,
multiple-imports,
no-else-return,
logging-not-lazy,
fixme,
redefined-outer-name,
unused-variable,
unsubscriptable-object,
expression-not-assigned,
too-many-boolean-expressions,
consider-using-ternary,
invalid-unary-operand-type,
relative-import,
deprecated-lambda
# Enable the message, report, category or checker with the given id(s). You can # Enable the message, report, category or checker with the given id(s). You can

@ -3,6 +3,7 @@ import shutil
import tempfile import tempfile
from atomicwrites import AtomicWriter from atomicwrites import AtomicWriter
def mkdirs_exists_ok(path): def mkdirs_exists_ok(path):
try: try:
os.makedirs(path) os.makedirs(path)
@ -10,6 +11,7 @@ def mkdirs_exists_ok(path):
if not os.path.isdir(path): if not os.path.isdir(path):
raise raise
def rm_not_exists_ok(path): def rm_not_exists_ok(path):
try: try:
os.remove(path) os.remove(path)
@ -17,12 +19,14 @@ def rm_not_exists_ok(path):
if os.path.exists(path): if os.path.exists(path):
raise raise
def rm_tree_or_link(path): def rm_tree_or_link(path):
if os.path.islink(path): if os.path.islink(path):
os.unlink(path) os.unlink(path)
elif os.path.isdir(path): elif os.path.isdir(path):
shutil.rmtree(path) shutil.rmtree(path)
def get_tmpdir_on_same_filesystem(path): def get_tmpdir_on_same_filesystem(path):
normpath = os.path.normpath(path) normpath = os.path.normpath(path)
parts = normpath.split("/") parts = normpath.split("/")
@ -32,6 +36,7 @@ def get_tmpdir_on_same_filesystem(path):
return "/{}/runner/tmp".format(parts[1]) return "/{}/runner/tmp".format(parts[1])
return "/tmp" return "/tmp"
class AutoMoveTempdir(): class AutoMoveTempdir():
def __init__(self, target_path, temp_dir=None): def __init__(self, target_path, temp_dir=None):
self._target_path = target_path self._target_path = target_path
@ -47,12 +52,13 @@ class AutoMoveTempdir():
def __enter__(self): def __enter__(self):
return self return self
def __exit__(self, type, value, traceback): def __exit__(self, exc_type, exc_value, traceback):
if type is None: if exc_type is None:
self.close() self.close()
else: else:
shutil.rmtree(self._path) shutil.rmtree(self._path)
class NamedTemporaryDir(): class NamedTemporaryDir():
def __init__(self, temp_dir=None): def __init__(self, temp_dir=None):
self._path = tempfile.mkdtemp(dir=temp_dir) self._path = tempfile.mkdtemp(dir=temp_dir)
@ -67,9 +73,10 @@ class NamedTemporaryDir():
def __enter__(self): def __enter__(self):
return self return self
def __exit__(self, type, value, traceback): def __exit__(self, exc_type, exc_value, traceback):
self.close() self.close()
def _get_fileobject_func(writer, temp_dir): def _get_fileobject_func(writer, temp_dir):
def _get_fileobject(): def _get_fileobject():
file_obj = writer.get_fileobject(dir=temp_dir) file_obj = writer.get_fileobject(dir=temp_dir)
@ -77,6 +84,7 @@ def _get_fileobject_func(writer, temp_dir):
return file_obj return file_obj
return _get_fileobject return _get_fileobject
def atomic_write_on_fs_tmp(path, **kwargs): def atomic_write_on_fs_tmp(path, **kwargs):
"""Creates an atomic writer using a temporary file in a temporary directory """Creates an atomic writer using a temporary file in a temporary directory
on the same filesystem as path. on the same filesystem as path.
@ -94,6 +102,7 @@ def atomic_write_in_dir(path, **kwargs):
writer = AtomicWriter(path, **kwargs) writer = AtomicWriter(path, **kwargs)
return writer._open(_get_fileobject_func(writer, os.path.dirname(path))) return writer._open(_get_fileobject_func(writer, os.path.dirname(path)))
def atomic_write_in_dir_neos(path, contents, mode=None): def atomic_write_in_dir_neos(path, contents, mode=None):
""" """
Atomically writes contents to path using a temporary file in the same directory Atomically writes contents to path using a temporary file in the same directory

@ -143,7 +143,9 @@ class SwagLogger(logging.Logger):
while hasattr(f, "f_code"): while hasattr(f, "f_code"):
co = f.f_code co = f.f_code
filename = os.path.normcase(co.co_filename) filename = os.path.normcase(co.co_filename)
if filename == _srcfile:
# TODO: is this pylint exception correct?
if filename == _srcfile: # pylint: disable=comparison-with-callable
f = f.f_back f = f.f_back
continue continue
sinfo = None sinfo = None

@ -30,6 +30,7 @@ import threading
from enum import Enum from enum import Enum
from common.basedir import PARAMS from common.basedir import PARAMS
def mkdirs_exists_ok(path): def mkdirs_exists_ok(path):
try: try:
os.makedirs(path) os.makedirs(path)
@ -143,6 +144,10 @@ class DBAccessor():
def get(self, key): def get(self, key):
self._check_entered() self._check_entered()
if self._vals is None:
return None
try: try:
return self._vals[key] return self._vals[key]
except KeyError: except KeyError:
@ -195,7 +200,7 @@ class DBReader(DBAccessor):
finally: finally:
lock.release() lock.release()
def __exit__(self, type, value, traceback): def __exit__(self, exc_type, exc_value, traceback):
pass pass
@ -221,14 +226,14 @@ class DBWriter(DBAccessor):
os.chmod(self._path, 0o777) os.chmod(self._path, 0o777)
self._lock = self._get_lock(True) self._lock = self._get_lock(True)
self._vals = self._read_values_locked() self._vals = self._read_values_locked()
except: except Exception:
os.umask(self._prev_umask) os.umask(self._prev_umask)
self._prev_umask = None self._prev_umask = None
raise raise
return self return self
def __exit__(self, type, value, traceback): def __exit__(self, exc_type, exc_value, traceback):
self._check_entered() self._check_entered()
try: try:
@ -302,12 +307,13 @@ def read_db(params_path, key):
except IOError: except IOError:
return None return None
def write_db(params_path, key, value): def write_db(params_path, key, value):
if isinstance(value, str): if isinstance(value, str):
value = value.encode('utf8') value = value.encode('utf8')
prev_umask = os.umask(0) prev_umask = os.umask(0)
lock = FileLock(params_path+"/.lock", True) lock = FileLock(params_path + "/.lock", True)
lock.acquire() lock.acquire()
try: try:
@ -324,12 +330,13 @@ def write_db(params_path, key, value):
os.umask(prev_umask) os.umask(prev_umask)
lock.release() lock.release()
class Params(): class Params():
def __init__(self, db=PARAMS): def __init__(self, db=PARAMS):
self.db = db self.db = db
# create the database if it doesn't exist... # create the database if it doesn't exist...
if not os.path.exists(self.db+"/d"): if not os.path.exists(self.db + "/d"):
with self.transaction(write=True): with self.transaction(write=True):
pass pass

@ -36,12 +36,12 @@ class Spinner():
def __del__(self): def __del__(self):
self.close() self.close()
def __exit__(self, type, value, traceback): def __exit__(self, exc_type, exc_value, traceback):
self.close() self.close()
class FakeSpinner(Spinner): class FakeSpinner(Spinner):
def __init__(self): def __init__(self): # pylint: disable=super-init-not-called
pass pass
def __enter__(self): def __enter__(self):
@ -53,7 +53,7 @@ class FakeSpinner(Spinner):
def close(self): def close(self):
pass pass
def __exit__(self, type, value, traceback): def __exit__(self, exc_type, exc_value, traceback):
pass pass

@ -39,12 +39,12 @@ class TextWindow():
def __del__(self): def __del__(self):
self.close() self.close()
def __exit__(self, type, value, traceback): def __exit__(self, exc_type, exc_value, traceback):
self.close() self.close()
class FakeTextWindow(TextWindow): class FakeTextWindow(TextWindow):
def __init__(self, s): def __init__(self, s): # pylint: disable=super-init-not-called
pass pass
def get_status(self): def get_status(self):
@ -62,7 +62,7 @@ class FakeTextWindow(TextWindow):
def close(self): def close(self):
pass pass
def __exit__(self, type, value, traceback): def __exit__(self, exc_type, exc_value, traceback):
pass pass

@ -1,8 +1,8 @@
import numpy as np
""" """
Coordinate transformation module. All methods accept arrays as input Coordinate transformation module. All methods accept arrays as input
with each row as a position. with each row as a position.
""" """
import numpy as np
a = 6378137 a = 6378137

@ -1,8 +1,3 @@
import numpy as np
from numpy import dot, inner, array, linalg
from common.transformations.coordinates import LocalCoord
''' '''
Vectorized functions that transform between Vectorized functions that transform between
rotation matrices, euler angles and quaternions. rotation matrices, euler angles and quaternions.
@ -10,6 +5,11 @@ All support lists, array or array of arrays as inputs.
Supports both x2y and y_from_x format (y_from_x preferred!). Supports both x2y and y_from_x format (y_from_x preferred!).
''' '''
import numpy as np
from numpy import dot, inner, array, linalg
from common.transformations.coordinates import LocalCoord
def euler2quat(eulers): def euler2quat(eulers):
eulers = array(eulers) eulers = array(eulers)
if len(eulers.shape) > 1: if len(eulers.shape) > 1:

@ -9,6 +9,7 @@ import pycurl
from io import BytesIO from io import BytesIO
from tenacity import retry, wait_random_exponential, stop_after_attempt from tenacity import retry, wait_random_exponential, stop_after_attempt
class URLFile(object): class URLFile(object):
_tlocal = threading.local() _tlocal = threading.local()
@ -26,7 +27,7 @@ class URLFile(object):
def __enter__(self): def __enter__(self):
return self return self
def __exit__(self, type, value, traceback): def __exit__(self, exc_type, exc_value, traceback):
if self._local_file is not None: if self._local_file is not None:
os.remove(self._local_file.name) os.remove(self._local_file.name)
self._local_file.close() self._local_file.close()
@ -37,7 +38,7 @@ class URLFile(object):
if ll is None: if ll is None:
trange = 'bytes=%d-' % self._pos trange = 'bytes=%d-' % self._pos
else: else:
trange = 'bytes=%d-%d' % (self._pos, self._pos+ll-1) trange = 'bytes=%d-%d' % (self._pos, self._pos + ll - 1)
dats = BytesIO() dats = BytesIO()
c = self._curl c = self._curl
@ -68,8 +69,8 @@ class URLFile(object):
if self._debug: if self._debug:
t2 = time.time() t2 = time.time()
if t2-t1 > 0.1: if t2 - t1 > 0.1:
print("get %s %r %.f slow" % (self._url, trange, t2-t1)) print("get %s %r %.f slow" % (self._url, trange, t2 - t1))
response_code = c.getinfo(pycurl.RESPONSE_CODE) response_code = c.getinfo(pycurl.RESPONSE_CODE)
if response_code == 416: # Requested Range Not Satisfiable if response_code == 416: # Requested Range Not Satisfiable
@ -96,7 +97,7 @@ class URLFile(object):
try: try:
os.write(local_fd, self.read()) os.write(local_fd, self.read())
local_file = open(local_path, "rb") local_file = open(local_path, "rb")
except: except Exception:
os.remove(local_path) os.remove(local_path)
raise raise
finally: finally:

@ -29,7 +29,7 @@ from selfdrive.loggerd.config import ROOT
from selfdrive.swaglog import cloudlog from selfdrive.swaglog import cloudlog
ATHENA_HOST = os.getenv('ATHENA_HOST', 'wss://athena.comma.ai') ATHENA_HOST = os.getenv('ATHENA_HOST', 'wss://athena.comma.ai')
HANDLER_THREADS = os.getenv('HANDLER_THREADS', 4) HANDLER_THREADS = int(os.getenv('HANDLER_THREADS', "4"))
LOCAL_PORT_WHITELIST = set([8022]) LOCAL_PORT_WHITELIST = set([8022])
dispatcher["echo"] = lambda s: s dispatcher["echo"] = lambda s: s
@ -39,6 +39,7 @@ upload_queue: Any = queue.Queue()
cancelled_uploads: Any = set() cancelled_uploads: Any = set()
UploadItem = namedtuple('UploadItem', ['path', 'url', 'headers', 'created_at', 'id']) UploadItem = namedtuple('UploadItem', ['path', 'url', 'headers', 'created_at', 'id'])
def handle_long_poll(ws): def handle_long_poll(ws):
end_event = threading.Event() end_event = threading.Event()
@ -60,9 +61,10 @@ def handle_long_poll(ws):
end_event.set() end_event.set()
raise raise
finally: finally:
for i, thread in enumerate(threads): for thread in threads:
thread.join() thread.join()
def jsonrpc_handler(end_event): def jsonrpc_handler(end_event):
dispatcher["startLocalProxy"] = partial(startLocalProxy, end_event) dispatcher["startLocalProxy"] = partial(startLocalProxy, end_event)
while not end_event.is_set(): while not end_event.is_set():
@ -76,6 +78,7 @@ def jsonrpc_handler(end_event):
cloudlog.exception("athena jsonrpc handler failed") cloudlog.exception("athena jsonrpc handler failed")
response_queue.put_nowait(json.dumps({"error": str(e)})) response_queue.put_nowait(json.dumps({"error": str(e)}))
def upload_handler(end_event): def upload_handler(end_event):
while not end_event.is_set(): while not end_event.is_set():
try: try:
@ -89,6 +92,7 @@ def upload_handler(end_event):
except Exception: except Exception:
cloudlog.exception("athena.upload_handler.exception") cloudlog.exception("athena.upload_handler.exception")
def _do_upload(upload_item): def _do_upload(upload_item):
with open(upload_item.path, "rb") as f: with open(upload_item.path, "rb") as f:
size = os.fstat(f.fileno()).st_size size = os.fstat(f.fileno()).st_size
@ -97,6 +101,7 @@ def _do_upload(upload_item):
headers={**upload_item.headers, 'Content-Length': str(size)}, headers={**upload_item.headers, 'Content-Length': str(size)},
timeout=10) timeout=10)
# security: user should be able to request any message from their car # security: user should be able to request any message from their car
@dispatcher.add_method @dispatcher.add_method
def getMessage(service=None, timeout=1000): def getMessage(service=None, timeout=1000):
@ -111,11 +116,13 @@ def getMessage(service=None, timeout=1000):
return ret.to_dict() return ret.to_dict()
@dispatcher.add_method @dispatcher.add_method
def listDataDirectory(): def listDataDirectory():
files = [os.path.relpath(os.path.join(dp, f), ROOT) for dp, dn, fn in os.walk(ROOT) for f in fn] files = [os.path.relpath(os.path.join(dp, f), ROOT) for dp, dn, fn in os.walk(ROOT) for f in fn]
return files return files
@dispatcher.add_method @dispatcher.add_method
def reboot(): def reboot():
thermal_sock = messaging.sub_sock("thermal", timeout=1000) thermal_sock = messaging.sub_sock("thermal", timeout=1000)
@ -131,6 +138,7 @@ def reboot():
return {"success": 1} return {"success": 1}
@dispatcher.add_method @dispatcher.add_method
def uploadFileToUrl(fn, url, headers): def uploadFileToUrl(fn, url, headers):
if len(fn) == 0 or fn[0] == '/' or '..' in fn: if len(fn) == 0 or fn[0] == '/' or '..' in fn:
@ -139,7 +147,7 @@ def uploadFileToUrl(fn, url, headers):
if not os.path.exists(path): if not os.path.exists(path):
return 404 return 404
item = UploadItem(path=path, url=url, headers=headers, created_at=int(time.time()*1000), id=None) item = UploadItem(path=path, url=url, headers=headers, created_at=int(time.time() * 1000), id=None)
upload_id = hashlib.sha1(str(item).encode()).hexdigest() upload_id = hashlib.sha1(str(item).encode()).hexdigest()
item = item._replace(id=upload_id) item = item._replace(id=upload_id)
@ -147,10 +155,12 @@ def uploadFileToUrl(fn, url, headers):
return {"enqueued": 1, "item": item._asdict()} return {"enqueued": 1, "item": item._asdict()}
@dispatcher.add_method @dispatcher.add_method
def listUploadQueue(): def listUploadQueue():
return [item._asdict() for item in list(upload_queue.queue)] return [item._asdict() for item in list(upload_queue.queue)]
@dispatcher.add_method @dispatcher.add_method
def cancelUpload(upload_id): def cancelUpload(upload_id):
upload_ids = set(item.id for item in list(upload_queue.queue)) upload_ids = set(item.id for item in list(upload_queue.queue))
@ -160,6 +170,7 @@ def cancelUpload(upload_id):
cancelled_uploads.add(upload_id) cancelled_uploads.add(upload_id)
return {"success": 1} return {"success": 1}
def startLocalProxy(global_end_event, remote_ws_uri, local_port): def startLocalProxy(global_end_event, remote_ws_uri, local_port):
try: try:
if local_port not in LOCAL_PORT_WHITELIST: if local_port not in LOCAL_PORT_WHITELIST:
@ -190,18 +201,21 @@ def startLocalProxy(global_end_event, remote_ws_uri, local_port):
cloudlog.exception("athenad.startLocalProxy.exception") cloudlog.exception("athenad.startLocalProxy.exception")
raise e raise e
@dispatcher.add_method @dispatcher.add_method
def getPublicKey(): def getPublicKey():
if not os.path.isfile(PERSIST+'/comma/id_rsa.pub'): if not os.path.isfile(PERSIST + '/comma/id_rsa.pub'):
return None return None
with open(PERSIST+'/comma/id_rsa.pub', 'r') as f: with open(PERSIST + '/comma/id_rsa.pub', 'r') as f:
return f.read() return f.read()
@dispatcher.add_method @dispatcher.add_method
def getSshAuthorizedKeys(): def getSshAuthorizedKeys():
return Params().get("GithubSshKeys", encoding='utf8') or '' return Params().get("GithubSshKeys", encoding='utf8') or ''
@dispatcher.add_method @dispatcher.add_method
def getSimInfo(): def getSimInfo():
sim_state = android.getprop("gsm.sim.state").split(",") sim_state = android.getprop("gsm.sim.state").split(",")
@ -220,6 +234,7 @@ def getSimInfo():
'data_connected': cell_data_connected 'data_connected': cell_data_connected
} }
@dispatcher.add_method @dispatcher.add_method
def takeSnapshot(): def takeSnapshot():
from selfdrive.camerad.snapshot.snapshot import snapshot, jpeg_write from selfdrive.camerad.snapshot.snapshot import snapshot, jpeg_write
@ -237,6 +252,7 @@ def takeSnapshot():
else: else:
raise Exception("not available while camerad is started") raise Exception("not available while camerad is started")
def ws_proxy_recv(ws, local_sock, ssock, end_event, global_end_event): def ws_proxy_recv(ws, local_sock, ssock, end_event, global_end_event):
while not (end_event.is_set() or global_end_event.is_set()): while not (end_event.is_set() or global_end_event.is_set()):
try: try:
@ -252,6 +268,7 @@ def ws_proxy_recv(ws, local_sock, ssock, end_event, global_end_event):
local_sock.close() local_sock.close()
end_event.set() end_event.set()
def ws_proxy_send(ws, local_sock, signal_sock, end_event): def ws_proxy_send(ws, local_sock, signal_sock, end_event):
while not end_event.is_set(): while not end_event.is_set():
try: try:
@ -272,6 +289,7 @@ def ws_proxy_send(ws, local_sock, signal_sock, end_event):
cloudlog.exception("athenad.ws_proxy_send.exception") cloudlog.exception("athenad.ws_proxy_send.exception")
end_event.set() end_event.set()
def ws_recv(ws, end_event): def ws_recv(ws, end_event):
while not end_event.is_set(): while not end_event.is_set():
try: try:
@ -281,13 +299,14 @@ def ws_recv(ws, end_event):
data = data.decode("utf-8") data = data.decode("utf-8")
payload_queue.put_nowait(data) payload_queue.put_nowait(data)
elif opcode == ABNF.OPCODE_PING: elif opcode == ABNF.OPCODE_PING:
Params().put("LastAthenaPingTime", str(int(sec_since_boot()*1e9))) Params().put("LastAthenaPingTime", str(int(sec_since_boot() * 1e9)))
except WebSocketTimeoutException: except WebSocketTimeoutException:
pass pass
except Exception: except Exception:
cloudlog.exception("athenad.ws_recv.exception") cloudlog.exception("athenad.ws_recv.exception")
end_event.set() end_event.set()
def ws_send(ws, end_event): def ws_send(ws, end_event):
while not end_event.is_set(): while not end_event.is_set():
try: try:
@ -299,9 +318,11 @@ def ws_send(ws, end_event):
cloudlog.exception("athenad.ws_send.exception") cloudlog.exception("athenad.ws_send.exception")
end_event.set() end_event.set()
def backoff(retries): def backoff(retries):
return random.randrange(0, min(128, int(2 ** retries))) return random.randrange(0, min(128, int(2 ** retries)))
def main(): def main():
params = Params() params = Params()
dongle_id = params.get("DongleId").decode('utf-8') dongle_id = params.get("DongleId").decode('utf-8')
@ -328,5 +349,6 @@ def main():
time.sleep(backoff(conn_retries)) time.sleep(backoff(conn_retries))
if __name__ == "__main__": if __name__ == "__main__":
main() main()

@ -8,6 +8,7 @@ import time
from functools import wraps from functools import wraps
from multiprocessing import Process from multiprocessing import Process
class EchoSocket(): class EchoSocket():
def __init__(self, port): def __init__(self, port):
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
@ -15,7 +16,7 @@ class EchoSocket():
self.socket.listen(1) self.socket.listen(1)
def run(self): def run(self):
conn, client_address = self.socket.accept() conn, _ = self.socket.accept()
conn.settimeout(5.0) conn.settimeout(5.0)
try: try:
@ -32,6 +33,7 @@ class EchoSocket():
self.socket.shutdown(0) self.socket.shutdown(0)
self.socket.close() self.socket.close()
class MockApi(): class MockApi():
def __init__(self, dongle_id): def __init__(self, dongle_id):
pass pass
@ -39,6 +41,7 @@ class MockApi():
def get_token(self): def get_token(self):
return "fake-token" return "fake-token"
class MockParams(): class MockParams():
def __init__(self): def __init__(self):
self.params = { self.params = {
@ -52,6 +55,7 @@ class MockParams():
ret = ret.decode(encoding) ret = ret.decode(encoding)
return ret return ret
class MockWebsocket(): class MockWebsocket():
def __init__(self, recv_queue, send_queue): def __init__(self, recv_queue, send_queue):
self.recv_queue = recv_queue self.recv_queue = recv_queue
@ -66,6 +70,7 @@ class MockWebsocket():
def send(self, data, opcode): def send(self, data, opcode):
self.send_queue.put_nowait((data, opcode)) self.send_queue.put_nowait((data, opcode))
class HTTPRequestHandler(http.server.SimpleHTTPRequestHandler): class HTTPRequestHandler(http.server.SimpleHTTPRequestHandler):
def do_PUT(self): def do_PUT(self):
length = int(self.headers['Content-Length']) length = int(self.headers['Content-Length'])
@ -73,6 +78,7 @@ class HTTPRequestHandler(http.server.SimpleHTTPRequestHandler):
self.send_response(201, "Created") self.send_response(201, "Created")
self.end_headers() self.end_headers()
def http_server(port_queue, **kwargs): def http_server(port_queue, **kwargs):
while 1: while 1:
try: try:
@ -83,6 +89,7 @@ def http_server(port_queue, **kwargs):
if e.errno == 98: if e.errno == 98:
continue continue
def with_http_server(func): def with_http_server(func):
@wraps(func) @wraps(func)
def inner(*args, **kwargs): def inner(*args, **kwargs):

@ -1,4 +1,5 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# pylint: skip-file
# This file is not used by OpenPilot. Only boardd.cc is used. # This file is not used by OpenPilot. Only boardd.cc is used.
# The python version is slower, but has more options for development. # The python version is slower, but has more options for development.

@ -12,7 +12,7 @@ import unittest
def generate_random_can_data_list(): def generate_random_can_data_list():
can_list = [] can_list = []
cnt = random.randint(1, 64) cnt = random.randint(1, 64)
for j in range(cnt): for _ in range(cnt):
can_data = np.random.bytes(random.randint(1, 8)) can_data = np.random.bytes(random.randint(1, 8))
can_list.append([random.randint(0, 128), random.randint(0, 128), can_data, random.randint(0, 128)]) can_list.append([random.randint(0, 128), random.randint(0, 128), can_data, random.randint(0, 128)])
return can_list, cnt return can_list, cnt
@ -54,18 +54,18 @@ class TestBoarddApiMethods(unittest.TestCase):
self.assertEqual(getattr(ev.can[i], attr, 'new'), getattr(ev_old.can[i], attr, 'old')) self.assertEqual(getattr(ev.can[i], attr, 'new'), getattr(ev_old.can[i], attr, 'old'))
def test_performance(self): def test_performance(self):
can_list, cnt = generate_random_can_data_list() can_list, _ = generate_random_can_data_list()
recursions = 1000 recursions = 1000
n1 = sec_since_boot() n1 = sec_since_boot()
for i in range(recursions): for _ in range(recursions):
boardd_old.can_list_to_can_capnp(can_list, 'sendcan').to_bytes() boardd_old.can_list_to_can_capnp(can_list, 'sendcan').to_bytes()
n2 = sec_since_boot() n2 = sec_since_boot()
elapsed_old = n2 - n1 elapsed_old = n2 - n1
# print('Old API, elapsed time: {} secs'.format(elapsed_old)) # print('Old API, elapsed time: {} secs'.format(elapsed_old))
n1 = sec_since_boot() n1 = sec_since_boot()
for i in range(recursions): for _ in range(recursions):
boardd.can_list_to_can_capnp(can_list) boardd.can_list_to_can_capnp(can_list)
n2 = sec_since_boot() n2 = sec_since_boot()
elapsed_new = n2 - n1 elapsed_new = n2 - n1

@ -4,9 +4,11 @@ from common.numpy_fast import clip
# kg of standard extra cargo to count for drive, gas, etc... # kg of standard extra cargo to count for drive, gas, etc...
STD_CARGO_KG = 136. STD_CARGO_KG = 136.
def gen_empty_fingerprint(): def gen_empty_fingerprint():
return {i: {} for i in range(0, 4)} return {i: {} for i in range(0, 4)}
# FIXME: hardcoding honda civic 2016 touring params so they can be used to # FIXME: hardcoding honda civic 2016 touring params so they can be used to
# scale unknown params for other cars # scale unknown params for other cars
class CivicParams: class CivicParams:
@ -18,11 +20,13 @@ class CivicParams:
TIRE_STIFFNESS_FRONT = 192150 TIRE_STIFFNESS_FRONT = 192150
TIRE_STIFFNESS_REAR = 202500 TIRE_STIFFNESS_REAR = 202500
# TODO: get actual value, for now starting with reasonable value for # TODO: get actual value, for now starting with reasonable value for
# civic and scaling by mass and wheelbase # civic and scaling by mass and wheelbase
def scale_rot_inertia(mass, wheelbase): def scale_rot_inertia(mass, wheelbase):
return CivicParams.ROTATIONAL_INERTIA * mass * wheelbase ** 2 / (CivicParams.MASS * CivicParams.WHEELBASE ** 2) return CivicParams.ROTATIONAL_INERTIA * mass * wheelbase ** 2 / (CivicParams.MASS * CivicParams.WHEELBASE ** 2)
# TODO: start from empirically derived lateral slip stiffness for the civic and scale by # TODO: start from empirically derived lateral slip stiffness for the civic and scale by
# mass and CG position, so all cars will have approximately similar dyn behaviors # mass and CG position, so all cars will have approximately similar dyn behaviors
def scale_tire_stiffness(mass, wheelbase, center_to_front, tire_stiffness_factor=1.0): def scale_tire_stiffness(mass, wheelbase, center_to_front, tire_stiffness_factor=1.0):
@ -35,6 +39,7 @@ def scale_tire_stiffness(mass, wheelbase, center_to_front, tire_stiffness_factor
return tire_stiffness_front, tire_stiffness_rear return tire_stiffness_front, tire_stiffness_rear
def dbc_dict(pt_dbc, radar_dbc, chassis_dbc=None): def dbc_dict(pt_dbc, radar_dbc, chassis_dbc=None):
return {'pt': pt_dbc, 'radar': radar_dbc, 'chassis': chassis_dbc} return {'pt': pt_dbc, 'radar': radar_dbc, 'chassis': chassis_dbc}
@ -51,10 +56,10 @@ def apply_std_steer_torque_limits(apply_torque, apply_torque_last, driver_torque
# slow rate if steer torque increases in magnitude # slow rate if steer torque increases in magnitude
if apply_torque_last > 0: if apply_torque_last > 0:
apply_torque = clip(apply_torque, max(apply_torque_last - LIMITS.STEER_DELTA_DOWN, -LIMITS.STEER_DELTA_UP), apply_torque = clip(apply_torque, max(apply_torque_last - LIMITS.STEER_DELTA_DOWN, -LIMITS.STEER_DELTA_UP),
apply_torque_last + LIMITS.STEER_DELTA_UP) apply_torque_last + LIMITS.STEER_DELTA_UP)
else: else:
apply_torque = clip(apply_torque, apply_torque_last - LIMITS.STEER_DELTA_UP, apply_torque = clip(apply_torque, apply_torque_last - LIMITS.STEER_DELTA_UP,
min(apply_torque_last + LIMITS.STEER_DELTA_DOWN, LIMITS.STEER_DELTA_UP)) min(apply_torque_last + LIMITS.STEER_DELTA_DOWN, LIMITS.STEER_DELTA_UP))
return int(round(float(apply_torque))) return int(round(float(apply_torque)))
@ -83,9 +88,9 @@ def crc8_pedal(data):
crc = 0xFF # standard init value crc = 0xFF # standard init value
poly = 0xD5 # standard crc8: x8+x7+x6+x4+x2+1 poly = 0xD5 # standard crc8: x8+x7+x6+x4+x2+1
size = len(data) size = len(data)
for i in range(size-1, -1, -1): for i in range(size - 1, -1, -1):
crc ^= data[i] crc ^= data[i]
for j in range(8): for _ in range(8):
if ((crc & 0x80) != 0): if ((crc & 0x80) != 0):
crc = ((crc << 1) ^ poly) & 0xFF crc = ((crc << 1) ^ poly) & 0xFF
else: else:

@ -11,7 +11,12 @@ class CarInterface(CarInterfaceBase):
return float(accel) / 3.0 return float(accel) / 3.0
@staticmethod @staticmethod
def get_params(candidate, fingerprint=gen_empty_fingerprint(), has_relay=False, car_fw=[]): def get_params(candidate, fingerprint=None, has_relay=False, car_fw=None):
if fingerprint is None:
fingerprint = gen_empty_fingerprint()
if car_fw is None:
car_fw = []
ret = CarInterfaceBase.get_std_params(candidate, fingerprint, has_relay) ret = CarInterfaceBase.get_std_params(candidate, fingerprint, has_relay)
ret.carName = "chrysler" ret.carName = "chrysler"
ret.safetyModel = car.CarParams.SafetyModel.chrysler ret.safetyModel = car.CarParams.SafetyModel.chrysler

@ -14,7 +14,7 @@ class CarInterface(CarInterfaceBase):
return float(accel) / 3.0 return float(accel) / 3.0
@staticmethod @staticmethod
def get_params(candidate, fingerprint=gen_empty_fingerprint(), has_relay=False, car_fw=[]): def get_params(candidate, fingerprint=gen_empty_fingerprint(), has_relay=False, car_fw=[]): # pylint: disable=dangerous-default-value
ret = CarInterfaceBase.get_std_params(candidate, fingerprint, has_relay) ret = CarInterfaceBase.get_std_params(candidate, fingerprint, has_relay)
ret.carName = "ford" ret.carName = "ford"
ret.safetyModel = car.CarParams.SafetyModel.ford ret.safetyModel = car.CarParams.SafetyModel.ford

@ -38,24 +38,8 @@ class CarControllerParams():
self.BRAKE_LOOKUP_V = [MAX_BRAKE, 0] self.BRAKE_LOOKUP_V = [MAX_BRAKE, 0]
def actuator_hystereses(final_pedal, pedal_steady):
# hyst params... TODO: move these to VehicleParams
pedal_hyst_gap = 0.01 # don't change pedal command for small oscillations within this value
# for small pedal oscillations within pedal_hyst_gap, don't change the pedal command
if final_pedal == 0.:
pedal_steady = 0.
elif final_pedal > pedal_steady + pedal_hyst_gap:
pedal_steady = final_pedal - pedal_hyst_gap
elif final_pedal < pedal_steady - pedal_hyst_gap:
pedal_steady = final_pedal + pedal_hyst_gap
final_pedal = pedal_steady
return final_pedal, pedal_steady
class CarController(): class CarController():
def __init__(self, dbc_name, CP, VM): def __init__(self, dbc_name, CP, VM):
self.pedal_steady = 0.
self.start_time = 0. self.start_time = 0.
self.apply_steer_last = 0 self.apply_steer_last = 0
self.lka_icon_status_last = (False, False) self.lka_icon_status_last = (False, False)
@ -79,8 +63,7 @@ class CarController():
if hud_alert == VisualAlert.fcw: if hud_alert == VisualAlert.fcw:
self.fcw_frames = 100 self.fcw_frames = 100
### STEER ### # STEER
if (frame % P.STEER_STEP) == 0: if (frame % P.STEER_STEP) == 0:
lkas_enabled = enabled and not CS.out.steerWarning and CS.out.vEgo > P.MIN_STEER_SPEED lkas_enabled = enabled and not CS.out.steerWarning and CS.out.vEgo > P.MIN_STEER_SPEED
if lkas_enabled: if lkas_enabled:
@ -93,19 +76,13 @@ class CarController():
self.apply_steer_last = apply_steer self.apply_steer_last = apply_steer
idx = (frame // P.STEER_STEP) % 4 idx = (frame // P.STEER_STEP) % 4
can_sends.append(gmcan.create_steering_control(self.packer_pt, can_sends.append(gmcan.create_steering_control(self.packer_pt, CanBus.POWERTRAIN, apply_steer, idx, lkas_enabled))
CanBus.POWERTRAIN, apply_steer, idx, lkas_enabled))
### GAS/BRAKE ###
# GAS/BRAKE
# no output if not enabled, but keep sending keepalive messages # no output if not enabled, but keep sending keepalive messages
# treat pedals as one # treat pedals as one
final_pedal = actuators.gas - actuators.brake final_pedal = actuators.gas - actuators.brake
# *** apply pedal hysteresis ***
final_brake, self.brake_steady = actuator_hystereses(
final_pedal, self.pedal_steady)
if not enabled: if not enabled:
# Stock ECU sends max regen when not enabled. # Stock ECU sends max regen when not enabled.
apply_gas = P.MAX_ACC_REGEN apply_gas = P.MAX_ACC_REGEN

@ -16,7 +16,7 @@ class CarInterface(CarInterfaceBase):
return float(accel) / 4.0 return float(accel) / 4.0
@staticmethod @staticmethod
def get_params(candidate, fingerprint=gen_empty_fingerprint(), has_relay=False, car_fw=[]): def get_params(candidate, fingerprint=gen_empty_fingerprint(), has_relay=False, car_fw=[]): # pylint: disable=dangerous-default-value
ret = CarInterfaceBase.get_std_params(candidate, fingerprint, has_relay) ret = CarInterfaceBase.get_std_params(candidate, fingerprint, has_relay)
ret.carName = "gm" ret.carName = "gm"
ret.safetyModel = car.CarParams.SafetyModel.gm # default to gm ret.safetyModel = car.CarParams.SafetyModel.gm # default to gm

@ -82,6 +82,10 @@ class CarInterface(CarInterfaceBase):
else: else:
self.compute_gb = compute_gb_honda self.compute_gb = compute_gb_honda
@staticmethod
def compute_gb(accel, speed):
raise NotImplementedError
@staticmethod @staticmethod
def calc_accel_override(a_ego, a_target, v_ego, v_target): def calc_accel_override(a_ego, a_target, v_ego, v_target):
@ -115,8 +119,7 @@ class CarInterface(CarInterfaceBase):
return float(max(max_accel, a_target / A_ACC_MAX)) * min(speedLimiter, accelLimiter) return float(max(max_accel, a_target / A_ACC_MAX)) * min(speedLimiter, accelLimiter)
@staticmethod @staticmethod
def get_params(candidate, fingerprint=gen_empty_fingerprint(), has_relay=False, car_fw=[]): def get_params(candidate, fingerprint=gen_empty_fingerprint(), has_relay=False, car_fw=[]): # pylint: disable=dangerous-default-value
ret = CarInterfaceBase.get_std_params(candidate, fingerprint, has_relay) ret = CarInterfaceBase.get_std_params(candidate, fingerprint, has_relay)
ret.carName = "honda" ret.carName = "honda"

@ -12,7 +12,7 @@ class CarInterface(CarInterfaceBase):
return float(accel) / 3.0 return float(accel) / 3.0
@staticmethod @staticmethod
def get_params(candidate, fingerprint=gen_empty_fingerprint(), has_relay=False, car_fw=[]): def get_params(candidate, fingerprint=gen_empty_fingerprint(), has_relay=False, car_fw=[]): # pylint: disable=dangerous-default-value
ret = CarInterfaceBase.get_std_params(candidate, fingerprint, has_relay) ret = CarInterfaceBase.get_std_params(candidate, fingerprint, has_relay)
ret.carName = "hyundai" ret.carName = "hyundai"

@ -41,7 +41,7 @@ class CarInterfaceBase():
raise NotImplementedError raise NotImplementedError
@staticmethod @staticmethod
def get_params(candidate, fingerprint=gen_empty_fingerprint(), has_relay=False, car_fw=[]): def get_params(candidate, fingerprint=gen_empty_fingerprint(), has_relay=False, car_fw=[]): # pylint: disable=dangerous-default-value
raise NotImplementedError raise NotImplementedError
# returns a set of default params to avoid repetition in car specific params # returns a set of default params to avoid repetition in car specific params
@ -84,7 +84,7 @@ class CarInterfaceBase():
def apply(self, c): def apply(self, c):
raise NotImplementedError raise NotImplementedError
def create_common_events(self, cs_out, extra_gears=[], gas_resume_speed=-1, pcm_enable=True): def create_common_events(self, cs_out, extra_gears=[], gas_resume_speed=-1, pcm_enable=True): # pylint: disable=dangerous-default-value
events = Events() events = Events()
if cs_out.doorOpen: if cs_out.doorOpen:

@ -15,7 +15,7 @@ class CarInterface(CarInterfaceBase):
return float(accel) / 4.0 return float(accel) / 4.0
@staticmethod @staticmethod
def get_params(candidate, fingerprint=gen_empty_fingerprint(), has_relay=False, car_fw=[]): def get_params(candidate, fingerprint=gen_empty_fingerprint(), has_relay=False, car_fw=[]): # pylint: disable=dangerous-default-value
ret = CarInterfaceBase.get_std_params(candidate, fingerprint, has_relay) ret = CarInterfaceBase.get_std_params(candidate, fingerprint, has_relay)
ret.carName = "mazda" ret.carName = "mazda"

@ -33,7 +33,7 @@ class CarInterface(CarInterfaceBase):
return accel return accel
@staticmethod @staticmethod
def get_params(candidate, fingerprint=gen_empty_fingerprint(), has_relay=False, car_fw=[]): def get_params(candidate, fingerprint=gen_empty_fingerprint(), has_relay=False, car_fw=[]): # pylint: disable=dangerous-default-value
ret = CarInterfaceBase.get_std_params(candidate, fingerprint, has_relay) ret = CarInterfaceBase.get_std_params(candidate, fingerprint, has_relay)
ret.carName = "mock" ret.carName = "mock"
ret.safetyModel = car.CarParams.SafetyModel.noOutput ret.safetyModel = car.CarParams.SafetyModel.noOutput

@ -14,7 +14,7 @@ class CarInterface(CarInterfaceBase):
return float(accel) / 4.0 return float(accel) / 4.0
@staticmethod @staticmethod
def get_params(candidate, fingerprint=gen_empty_fingerprint(), has_relay=False, car_fw=[]): def get_params(candidate, fingerprint=gen_empty_fingerprint(), has_relay=False, car_fw=[]): # pylint: disable=dangerous-default-value
ret = CarInterfaceBase.get_std_params(candidate, fingerprint, has_relay) ret = CarInterfaceBase.get_std_params(candidate, fingerprint, has_relay)
ret.carName = "nissan" ret.carName = "nissan"

@ -11,7 +11,7 @@ class CarInterface(CarInterfaceBase):
return float(accel) / 4.0 return float(accel) / 4.0
@staticmethod @staticmethod
def get_params(candidate, fingerprint=gen_empty_fingerprint(), has_relay=False, car_fw=[]): def get_params(candidate, fingerprint=gen_empty_fingerprint(), has_relay=False, car_fw=[]): # pylint: disable=dangerous-default-value
ret = CarInterfaceBase.get_std_params(candidate, fingerprint, has_relay) ret = CarInterfaceBase.get_std_params(candidate, fingerprint, has_relay)
ret.carName = "subaru" ret.carName = "subaru"

@ -14,7 +14,7 @@ class CarInterface(CarInterfaceBase):
return float(accel) / 3.0 return float(accel) / 3.0
@staticmethod @staticmethod
def get_params(candidate, fingerprint=gen_empty_fingerprint(), has_relay=False, car_fw=[]): def get_params(candidate, fingerprint=gen_empty_fingerprint(), has_relay=False, car_fw=[]): # pylint: disable=dangerous-default-value
ret = CarInterfaceBase.get_std_params(candidate, fingerprint, has_relay) ret = CarInterfaceBase.get_std_params(candidate, fingerprint, has_relay)
ret.carName = "toyota" ret.carName = "toyota"

@ -19,7 +19,7 @@ class CarInterface(CarInterfaceBase):
return float(accel) / 4.0 return float(accel) / 4.0
@staticmethod @staticmethod
def get_params(candidate, fingerprint=gen_empty_fingerprint(), has_relay=False, car_fw=[]): def get_params(candidate, fingerprint=gen_empty_fingerprint(), has_relay=False, car_fw=[]): # pylint: disable=dangerous-default-value
ret = CarInterfaceBase.get_std_params(candidate, fingerprint, has_relay) ret = CarInterfaceBase.get_std_params(candidate, fingerprint, has_relay)
# VW port is a community feature, since we don't own one to test # VW port is a community feature, since we don't own one to test

@ -59,7 +59,10 @@ class Events:
return True return True
return False return False
def create_alerts(self, event_types, callback_args=[]): def create_alerts(self, event_types, callback_args=None):
if callback_args is None:
callback_args = []
ret = [] ret = []
for e in self.events: for e in self.events:
types = EVENTS[e].keys() types = EVENTS[e].keys()

@ -1,7 +1,4 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import numpy as np
from numpy.linalg import solve
""" """
Dynamic bycicle model from "The Science of Vehicle Dynamics (2014), M. Guiggiani" Dynamic bycicle model from "The Science of Vehicle Dynamics (2014), M. Guiggiani"
@ -15,6 +12,8 @@ x_dot = A*x + B*u
A depends on longitudinal speed, u [m/s], and vehicle parameters CP A depends on longitudinal speed, u [m/s], and vehicle parameters CP
""" """
import numpy as np
from numpy.linalg import solve
def create_dyn_state_matrices(u, VM): def create_dyn_state_matrices(u, VM):

@ -9,8 +9,8 @@ from selfdrive.controls.lib.events import Alert, EVENTS
AlertSize = log.ControlsState.AlertSize AlertSize = log.ControlsState.AlertSize
class TestAlerts(unittest.TestCase):
class TestAlerts(unittest.TestCase):
def test_events_defined(self): def test_events_defined(self):
# Ensure all events in capnp schema are defined in events.py # Ensure all events in capnp schema are defined in events.py
events = car.CarEvent.EventName.schema.enumerants events = car.CarEvent.EventName.schema.enumerants
@ -34,9 +34,9 @@ class TestAlerts(unittest.TestCase):
draw = ImageDraw.Draw(Image.new('RGB', (0, 0))) draw = ImageDraw.Draw(Image.new('RGB', (0, 0)))
fonts = { fonts = {
AlertSize.small: [ImageFont.truetype(semibold_font_path, int(40*font_scale_factor))], AlertSize.small: [ImageFont.truetype(semibold_font_path, int(40 * font_scale_factor))],
AlertSize.mid: [ImageFont.truetype(bold_font_path, int(48*font_scale_factor)), AlertSize.mid: [ImageFont.truetype(bold_font_path, int(48 * font_scale_factor)),
ImageFont.truetype(regular_font_path, int(36*font_scale_factor))], ImageFont.truetype(regular_font_path, int(36 * font_scale_factor))],
} }
alerts = [] alerts = []
@ -56,9 +56,10 @@ class TestAlerts(unittest.TestCase):
break break
font = fonts[alert.alert_size][i] font = fonts[alert.alert_size][i]
w, h = draw.textsize(txt, font) w, _ = draw.textsize(txt, font)
msg = "type: %s msg: %s" % (alert.alert_type, txt) msg = "type: %s msg: %s" % (alert.alert_type, txt)
self.assertLessEqual(w, max_text_width, msg=msg) self.assertLessEqual(w, max_text_width, msg=msg)
if __name__ == "__main__": if __name__ == "__main__":
unittest.main() unittest.main()

@ -39,6 +39,12 @@ else:
client.extra_context(kwargs) client.extra_context(kwargs)
def install(): def install():
"""
Workaround for `sys.excepthook` thread bug from:
http://bugs.python.org/issue1230540
Call once from the main thread before creating any threads.
Source: https://stackoverflow.com/a/31622038
"""
# installs a sys.excepthook # installs a sys.excepthook
__excepthook__ = sys.excepthook __excepthook__ = sys.excepthook
@ -48,12 +54,6 @@ else:
__excepthook__(*exc_info) __excepthook__(*exc_info)
sys.excepthook = handle_exception sys.excepthook = handle_exception
"""
Workaround for `sys.excepthook` thread bug from:
http://bugs.python.org/issue1230540
Call once from the main thread before creating any threads.
Source: https://stackoverflow.com/a/31622038
"""
init_original = threading.Thread.__init__ init_original = threading.Thread.__init__
def init(self, *args, **kwargs): def init(self, *args, **kwargs):

@ -1,14 +1,5 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# type: ignore # type: ignore
import psutil
import time
import os
import sys
import numpy as np
import argparse
import re
from collections import defaultdict
''' '''
System tools like top/htop can only show current cpu usage values, so I write this script to do statistics jobs. System tools like top/htop can only show current cpu usage values, so I write this script to do statistics jobs.
Features: Features:
@ -24,18 +15,28 @@ System tools like top/htop can only show current cpu usage values, so I write th
boardd: 1.96%, min: 1.96%, max: 1.96%, acc: 1.96% boardd: 1.96%, min: 1.96%, max: 1.96%, acc: 1.96%
ubloxd.py: 0.39%, min: 0.39%, max: 0.39%, acc: 0.39% ubloxd.py: 0.39%, min: 0.39%, max: 0.39%, acc: 0.39%
''' '''
import psutil
import time
import os
import sys
import numpy as np
import argparse
import re
from collections import defaultdict
# Do statistics every 5 seconds # Do statistics every 5 seconds
PRINT_INTERVAL = 5 PRINT_INTERVAL = 5
SLEEP_INTERVAL = 0.2 SLEEP_INTERVAL = 0.2
monitored_proc_names = [ monitored_proc_names = [
'ubloxd', 'thermald', 'uploader', 'deleter', 'controlsd', 'plannerd', 'radard', 'mapd', 'loggerd' , 'logmessaged', 'tombstoned', 'ubloxd', 'thermald', 'uploader', 'deleter', 'controlsd', 'plannerd', 'radard', 'mapd', 'loggerd', 'logmessaged', 'tombstoned',
'logcatd', 'proclogd', 'boardd', 'pandad', './ui', 'ui', 'calibrationd', 'params_learner', 'modeld', 'dmonitoringmodeld', 'camerad', 'sensord', 'updated', 'gpsd', 'athena'] 'logcatd', 'proclogd', 'boardd', 'pandad', './ui', 'ui', 'calibrationd', 'params_learner', 'modeld', 'dmonitoringmodeld', 'camerad', 'sensord', 'updated', 'gpsd', 'athena']
cpu_time_names = ['user', 'system', 'children_user', 'children_system'] cpu_time_names = ['user', 'system', 'children_user', 'children_system']
timer = getattr(time, 'monotonic', time.time) timer = getattr(time, 'monotonic', time.time)
def get_arg_parser(): def get_arg_parser():
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
description="Unlogger and UI", description="Unlogger and UI",

@ -32,7 +32,7 @@ except Exception:
sys.exit(-1) sys.exit(-1)
sensord_env = {**os.environ, 'SENSOR_TEST': '1'} sensord_env = {**os.environ, 'SENSOR_TEST': '1'}
process = subprocess.run("./sensord", cwd="/data/openpilot/selfdrive/sensord", env=sensord_env) process = subprocess.run("./sensord", cwd="/data/openpilot/selfdrive/sensord", env=sensord_env) # pylint: disable=subprocess-run-check
if process.returncode == 40: if process.returncode == 40:
text = "Current run: SUCCESS\n" text = "Current run: SUCCESS\n"

@ -47,7 +47,10 @@ def get_H():
class Localizer(): class Localizer():
def __init__(self, disabled_logs=[], dog=None): def __init__(self, disabled_logs=None, dog=None):
if disabled_logs is None:
disabled_logs = []
self.kf = LiveKalman(GENERATED_DIR) self.kf = LiveKalman(GENERATED_DIR)
self.reset_kalman() self.reset_kalman()
self.max_age = .2 # seconds self.max_age = .2 # seconds
@ -279,7 +282,11 @@ class Localizer():
self.speed_counter = 0 self.speed_counter = 0
self.cam_counter = 0 self.cam_counter = 0
def locationd_thread(sm, pm, disabled_logs=[]):
def locationd_thread(sm, pm, disabled_logs=None):
if disabled_logs is None:
disabled_logs = []
if sm is None: if sm is None:
socks = ['gpsLocationExternal', 'sensorEvents', 'cameraOdometry', 'liveCalibration', 'carState'] socks = ['gpsLocationExternal', 'sensorEvents', 'cameraOdometry', 'liveCalibration', 'carState']
sm = messaging.SubMaster(socks, ignore_alive=['gpsLocationExternal']) sm = messaging.SubMaster(socks, ignore_alive=['gpsLocationExternal'])

@ -12,6 +12,7 @@ from selfdrive.locationd.models.constants import ObservationKind
i = 0 i = 0
def _slice(n): def _slice(n):
global i global i
s = slice(i, i + n) s = slice(i, i + n)
@ -48,7 +49,7 @@ class CarKalman(KalmanFilter):
# process noise # process noise
Q = np.diag([ Q = np.diag([
(.05/100)**2, (.05 / 100)**2,
.01**2, .01**2,
math.radians(0.02)**2, math.radians(0.02)**2,
math.radians(0.25)**2, math.radians(0.25)**2,
@ -59,7 +60,7 @@ class CarKalman(KalmanFilter):
]) ])
P_initial = Q.copy() P_initial = Q.copy()
obs_noise : Dict[int, Any] = { obs_noise: Dict[int, Any] = {
ObservationKind.STEER_ANGLE: np.atleast_2d(math.radians(0.01)**2), ObservationKind.STEER_ANGLE: np.atleast_2d(math.radians(0.01)**2),
ObservationKind.ANGLE_OFFSET_FAST: np.atleast_2d(math.radians(10.0)**2), ObservationKind.ANGLE_OFFSET_FAST: np.atleast_2d(math.radians(10.0)**2),
ObservationKind.STEER_RATIO: np.atleast_2d(5.0**2), ObservationKind.STEER_RATIO: np.atleast_2d(5.0**2),
@ -138,7 +139,7 @@ class CarKalman(KalmanFilter):
gen_code(generated_dir, name, f_sym, dt, state_sym, obs_eqs, dim_state, dim_state, global_vars=CarKalman.global_vars) gen_code(generated_dir, name, f_sym, dt, state_sym, obs_eqs, dim_state, dim_state, global_vars=CarKalman.global_vars)
def __init__(self, generated_dir, steer_ratio=15, stiffness_factor=1, angle_offset=0): def __init__(self, generated_dir, steer_ratio=15, stiffness_factor=1, angle_offset=0): # pylint: disable=super-init-not-called
dim_state = self.initial_x.shape[0] dim_state = self.initial_x.shape[0]
dim_state_err = self.P_initial.shape[0] dim_state_err = self.P_initial.shape[0]
x_init = self.initial_x x_init = self.initial_x

@ -76,14 +76,14 @@ class GNSSKalman():
# extra args # extra args
sat_pos_freq_sym = sp.MatrixSymbol('sat_pos', 4, 1) sat_pos_freq_sym = sp.MatrixSymbol('sat_pos', 4, 1)
sat_pos_vel_sym = sp.MatrixSymbol('sat_pos_vel', 6, 1) sat_pos_vel_sym = sp.MatrixSymbol('sat_pos_vel', 6, 1)
sat_los_sym = sp.MatrixSymbol('sat_los', 3, 1) # sat_los_sym = sp.MatrixSymbol('sat_los', 3, 1)
orb_epos_sym = sp.MatrixSymbol('orb_epos_sym', 3, 1) # orb_epos_sym = sp.MatrixSymbol('orb_epos_sym', 3, 1)
# expand extra args # expand extra args
sat_x, sat_y, sat_z, glonass_freq = sat_pos_freq_sym sat_x, sat_y, sat_z, glonass_freq = sat_pos_freq_sym
sat_vx, sat_vy, sat_vz = sat_pos_vel_sym[3:] sat_vx, sat_vy, sat_vz = sat_pos_vel_sym[3:]
los_x, los_y, los_z = sat_los_sym # los_x, los_y, los_z = sat_los_sym
orb_x, orb_y, orb_z = orb_epos_sym # orb_x, orb_y, orb_z = orb_epos_sym
h_pseudorange_sym = sp.Matrix([ h_pseudorange_sym = sp.Matrix([
sp.sqrt( sp.sqrt(

@ -252,13 +252,13 @@ class LocKalman():
# extra args # extra args
sat_pos_freq_sym = sp.MatrixSymbol('sat_pos', 4, 1) sat_pos_freq_sym = sp.MatrixSymbol('sat_pos', 4, 1)
sat_pos_vel_sym = sp.MatrixSymbol('sat_pos_vel', 6, 1) sat_pos_vel_sym = sp.MatrixSymbol('sat_pos_vel', 6, 1)
sat_los_sym = sp.MatrixSymbol('sat_los', 3, 1) # sat_los_sym = sp.MatrixSymbol('sat_los', 3, 1)
orb_epos_sym = sp.MatrixSymbol('orb_epos_sym', 3, 1) orb_epos_sym = sp.MatrixSymbol('orb_epos_sym', 3, 1)
# expand extra args # expand extra args
sat_x, sat_y, sat_z, glonass_freq = sat_pos_freq_sym sat_x, sat_y, sat_z, glonass_freq = sat_pos_freq_sym
sat_vx, sat_vy, sat_vz = sat_pos_vel_sym[3:] sat_vx, sat_vy, sat_vz = sat_pos_vel_sym[3:]
los_x, los_y, los_z = sat_los_sym # los_x, los_y, los_z = sat_los_sym
orb_x, orb_y, orb_z = orb_epos_sym orb_x, orb_y, orb_z = orb_epos_sym
h_pseudorange_sym = sp.Matrix([ h_pseudorange_sym = sp.Matrix([
@ -377,7 +377,7 @@ class LocKalman():
self.dim_state_err = self.dim_main_err + self.dim_augment_err * self.N self.dim_state_err = self.dim_main_err + self.dim_augment_err * self.N
if self.N > 0: if self.N > 0:
x_initial, P_initial, Q = self.pad_augmented(self.x_initial, self.P_initial, self.Q) x_initial, P_initial, Q = self.pad_augmented(self.x_initial, self.P_initial, self.Q) # pylint: disable=unbalanced-tuple-unpacking
self.computer = LstSqComputer(generated_dir, N) self.computer = LstSqComputer(generated_dir, N)
self.max_tracks = max_tracks self.max_tracks = max_tracks
@ -569,14 +569,14 @@ class LocKalman():
def maha_test_pseudorange(self, x, P, meas, kind, maha_thresh=.3): def maha_test_pseudorange(self, x, P, meas, kind, maha_thresh=.3):
bools = [] bools = []
for i, m in enumerate(meas): for m in meas:
z, R, sat_pos_freq = parse_pr(m) z, R, sat_pos_freq = parse_pr(m)
bools.append(self.filter.maha_test(x, P, kind, z, R, extra_args=sat_pos_freq, maha_thresh=maha_thresh)) bools.append(self.filter.maha_test(x, P, kind, z, R, extra_args=sat_pos_freq, maha_thresh=maha_thresh))
return np.array(bools) return np.array(bools)
def maha_test_pseudorange_rate(self, x, P, meas, kind, maha_thresh=.999): def maha_test_pseudorange_rate(self, x, P, meas, kind, maha_thresh=.999):
bools = [] bools = []
for i, m in enumerate(meas): for m in meas:
z, R, sat_pos_vel = parse_prr(m) z, R, sat_pos_vel = parse_prr(m)
bools.append(self.filter.maha_test(x, P, kind, z, R, extra_args=sat_pos_vel, maha_thresh=maha_thresh)) bools.append(self.filter.maha_test(x, P, kind, z, R, extra_args=sat_pos_vel, maha_thresh=maha_thresh))
return np.array(bools) return np.array(bools)

@ -1,3 +1,5 @@
import math
def GET_FIELD_U(w, nb, pos): def GET_FIELD_U(w, nb, pos):
return (((w) >> (pos)) & ((1 << (nb)) - 1)) return (((w) >> (pos)) & ((1 << (nb)) - 1))
@ -35,7 +37,6 @@ on of this parser
''' '''
def __init__(self, svId, subframes): def __init__(self, svId, subframes):
from math import pow
self.svId = svId self.svId = svId
week_no = GET_FIELD_U(subframes[1][2+0], 10, 20) week_no = GET_FIELD_U(subframes[1][2+0], 10, 20)
# code_on_l2 = GET_FIELD_U(subframes[1][0], 2, 12) # code_on_l2 = GET_FIELD_U(subframes[1][0], 2, 12)
@ -84,30 +85,30 @@ on of this parser
gpsPi = 3.1415926535898 gpsPi = 3.1415926535898
# now form variables in radians, meters and seconds etc # now form variables in radians, meters and seconds etc
self.Tgd = t_gd * pow(2, -31) self.Tgd = t_gd * math.pow(2, -31)
self.A = pow(a_powhalf * pow(2, -19), 2.0) self.A = math.pow(a_powhalf * math.pow(2, -19), 2.0)
self.cic = c_ic * pow(2, -29) self.cic = c_ic * math.pow(2, -29)
self.cis = c_is * pow(2, -29) self.cis = c_is * math.pow(2, -29)
self.crc = c_rc * pow(2, -5) self.crc = c_rc * math.pow(2, -5)
self.crs = c_rs * pow(2, -5) self.crs = c_rs * math.pow(2, -5)
self.cuc = c_uc * pow(2, -29) self.cuc = c_uc * math.pow(2, -29)
self.cus = c_us * pow(2, -29) self.cus = c_us * math.pow(2, -29)
self.deltaN = delta_n * pow(2, -43) * gpsPi self.deltaN = delta_n * math.pow(2, -43) * gpsPi
self.ecc = e * pow(2, -33) self.ecc = e * math.pow(2, -33)
self.i0 = i_0 * pow(2, -31) * gpsPi self.i0 = i_0 * math.pow(2, -31) * gpsPi
self.idot = idot * pow(2, -43) * gpsPi self.idot = idot * math.pow(2, -43) * gpsPi
self.M0 = m_0 * pow(2, -31) * gpsPi self.M0 = m_0 * math.pow(2, -31) * gpsPi
self.omega = w * pow(2, -31) * gpsPi self.omega = w * math.pow(2, -31) * gpsPi
self.omega_dot = omega_dot * pow(2, -43) * gpsPi self.omega_dot = omega_dot * math.pow(2, -43) * gpsPi
self.omega0 = omega_0 * pow(2, -31) * gpsPi self.omega0 = omega_0 * math.pow(2, -31) * gpsPi
self.toe = t_oe * pow(2, 4) self.toe = t_oe * math.pow(2, 4)
# clock correction information # clock correction information
self.toc = t_oc * pow(2, 4) self.toc = t_oc * math.pow(2, 4)
self.gpsWeek = week_no self.gpsWeek = week_no
self.af0 = a_f0 * pow(2, -31) self.af0 = a_f0 * math.pow(2, -31)
self.af1 = a_f1 * pow(2, -43) self.af1 = a_f1 * math.pow(2, -43)
self.af2 = a_f2 * pow(2, -55) self.af2 = a_f2 * math.pow(2, -55)
iode1 = GET_FIELD_U(subframes[2][2+0], 8, 22) iode1 = GET_FIELD_U(subframes[2][2+0], 8, 22)
iode2 = GET_FIELD_U(subframes[3][2+7], 8, 22) iode2 = GET_FIELD_U(subframes[3][2+7], 8, 22)
@ -117,14 +118,14 @@ on of this parser
if GET_FIELD_U(subframes[4][2+0], 6, 22) == 56 and \ if GET_FIELD_U(subframes[4][2+0], 6, 22) == 56 and \
GET_FIELD_U(subframes[4][2+0], 2, 28) == 1 and \ GET_FIELD_U(subframes[4][2+0], 2, 28) == 1 and \
GET_FIELD_U(subframes[5][2+0], 2, 28) == 1: GET_FIELD_U(subframes[5][2+0], 2, 28) == 1:
a0 = GET_FIELD_S(subframes[4][2], 8, 14) * pow(2, -30) a0 = GET_FIELD_S(subframes[4][2], 8, 14) * math.pow(2, -30)
a1 = GET_FIELD_S(subframes[4][2], 8, 6) * pow(2, -27) a1 = GET_FIELD_S(subframes[4][2], 8, 6) * math.pow(2, -27)
a2 = GET_FIELD_S(subframes[4][3], 8, 22) * pow(2, -24) a2 = GET_FIELD_S(subframes[4][3], 8, 22) * math.pow(2, -24)
a3 = GET_FIELD_S(subframes[4][3], 8, 14) * pow(2, -24) a3 = GET_FIELD_S(subframes[4][3], 8, 14) * math.pow(2, -24)
b0 = GET_FIELD_S(subframes[4][3], 8, 6) * pow(2, 11) b0 = GET_FIELD_S(subframes[4][3], 8, 6) * math.pow(2, 11)
b1 = GET_FIELD_S(subframes[4][4], 8, 22) * pow(2, 14) b1 = GET_FIELD_S(subframes[4][4], 8, 22) * math.pow(2, 14)
b2 = GET_FIELD_S(subframes[4][4], 8, 14) * pow(2, 16) b2 = GET_FIELD_S(subframes[4][4], 8, 14) * math.pow(2, 16)
b3 = GET_FIELD_S(subframes[4][4], 8, 6) * pow(2, 16) b3 = GET_FIELD_S(subframes[4][4], 8, 6) * math.pow(2, 16)
self.ionoAlpha = [a0, a1, a2, a3] self.ionoAlpha = [a0, a1, a2, a3]
self.ionoBeta = [b0, b1, b2, b3] self.ionoBeta = [b0, b1, b2, b3]

@ -31,7 +31,7 @@ class TestParamsLearner(unittest.TestCase):
steering_angles = np.radians(10 * np.sin(2 * np.pi * times / 100.)) + angle_offset steering_angles = np.radians(10 * np.sin(2 * np.pi * times / 100.)) + angle_offset
speeds = 10 * np.sin(2 * np.pi * times / 1000.) + 25 speeds = 10 * np.sin(2 * np.pi * times / 1000.) + 25
for i, t in enumerate(times): for i, _ in enumerate(times):
u = speeds[i] u = speeds[i]
sa = steering_angles[i] sa = steering_angles[i]
psi = VM_sim.yaw_rate(sa - angle_offset, u) psi = VM_sim.yaw_rate(sa - angle_offset, u)

@ -1,4 +1,5 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# pylint: skip-file
''' '''
UBlox binary protocol handling UBlox binary protocol handling

@ -1,5 +1,6 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# type: ignore # type: ignore
# pylint: skip-file
import os import os
import serial import serial

@ -23,9 +23,6 @@ class TestDeleter(UploaderTestCase):
deleter.os.statvfs = self.fake_statvfs deleter.os.statvfs = self.fake_statvfs
deleter.ROOT = self.root deleter.ROOT = self.root
def tearDown(self):
super(TestDeleter, self).tearDown()
def start_thread(self): def start_thread(self):
self.end_event = threading.Event() self.end_event = threading.Event()
self.del_thread = threading.Thread(target=deleter.deleter_thread, args=[self.end_event]) self.del_thread = threading.Thread(target=deleter.deleter_thread, args=[self.end_event])

@ -38,9 +38,6 @@ class TestUploader(UploaderTestCase):
super(TestUploader, self).setUp() super(TestUploader, self).setUp()
log_handler.reset() log_handler.reset()
def tearDown(self):
super(TestUploader, self).tearDown()
def start_thread(self): def start_thread(self):
self.end_event = threading.Event() self.end_event = threading.Event()
self.up_thread = threading.Thread(target=uploader.uploader_fn, args=[self.end_event]) self.up_thread = threading.Thread(target=uploader.uploader_fn, args=[self.end_event])

@ -25,6 +25,7 @@ UPLOAD_ATTR_VALUE = b'1'
fake_upload = os.getenv("FAKEUPLOAD") is not None fake_upload = os.getenv("FAKEUPLOAD") is not None
def raise_on_thread(t, exctype): def raise_on_thread(t, exctype):
'''Raises an exception in the threads with id tid'''
for ctid, tobj in threading._active.items(): for ctid, tobj in threading._active.items():
if tobj is t: if tobj is t:
tid = ctid tid = ctid
@ -32,7 +33,6 @@ def raise_on_thread(t, exctype):
else: else:
raise Exception("Could not find thread") raise Exception("Could not find thread")
'''Raises an exception in the threads with id tid'''
if not inspect.isclass(exctype): if not inspect.isclass(exctype):
raise TypeError("Only types can be raised (not instances)") raise TypeError("Only types can be raised (not instances)")

@ -305,11 +305,11 @@ def start_daemon_process(name):
pass pass
cloudlog.info("starting daemon %s" % name) cloudlog.info("starting daemon %s" % name)
proc = subprocess.Popen(['python', '-m', proc], proc = subprocess.Popen(['python', '-m', proc], # pylint: disable=subprocess-popen-preexec-fn
stdin=open('/dev/null', 'r'), stdin=open('/dev/null', 'r'),
stdout=open('/dev/null', 'w'), stdout=open('/dev/null', 'w'),
stderr=open('/dev/null', 'w'), stderr=open('/dev/null', 'w'),
preexec_fn=os.setpgrp) preexec_fn=os.setpgrp)
params.put(pid_param, str(proc.pid)) params.put(pid_param, str(proc.pid))
@ -590,8 +590,6 @@ def main():
try: try:
manager_thread() manager_thread()
except SystemExit:
raise
except Exception: except Exception:
traceback.print_exc() traceback.print_exc()
crash.capture_exception() crash.capture_exception()

@ -10,19 +10,22 @@ import numpy as np
from tensorflow.keras.models import Model # pylint: disable=import-error from tensorflow.keras.models import Model # pylint: disable=import-error
from tensorflow.keras.models import load_model # pylint: disable=import-error from tensorflow.keras.models import load_model # pylint: disable=import-error
def read(sz): def read(sz):
dd = [] dd = []
gt = 0 gt = 0
while gt < sz*4: while gt < sz * 4:
st = os.read(0, sz*4 - gt) st = os.read(0, sz * 4 - gt)
assert(len(st) > 0) assert(len(st) > 0)
dd.append(st) dd.append(st)
gt += len(st) gt += len(st)
return np.fromstring(b''.join(dd), dtype=np.float32) return np.fromstring(b''.join(dd), dtype=np.float32)
def write(d): def write(d):
os.write(1, d.tobytes()) os.write(1, d.tobytes())
def run_loop(m): def run_loop(m):
isize = m.inputs[0].shape[1] isize = m.inputs[0].shape[1]
osize = m.outputs[0].shape[1] osize = m.outputs[0].shape[1]
@ -32,6 +35,7 @@ def run_loop(m):
ret = m.predict_on_batch(idata) ret = m.predict_on_batch(idata)
write(ret) write(ret)
if __name__ == "__main__": if __name__ == "__main__":
print(tf.__version__, file=sys.stderr) print(tf.__version__, file=sys.stderr)
# limit gram alloc # limit gram alloc
@ -48,7 +52,7 @@ if __name__ == "__main__":
acc = 0 acc = 0
for i, ii in enumerate(m.inputs): for i, ii in enumerate(m.inputs):
print(ii, file=sys.stderr) print(ii, file=sys.stderr)
ti = keras.layers.Lambda(lambda x: x[:, acc:acc+bs[i]], output_shape=(1, bs[i]))(ri) ti = keras.layers.Lambda(lambda x, i=i: x[:, acc:acc + bs[i]], output_shape=(1, bs[i]))(ri)
acc += bs[i] acc += bs[i]
tr = keras.layers.Reshape(ii.shape[1:])(ti) tr = keras.layers.Reshape(ii.shape[1:])(ti)
tii.append(tr) tii.append(tr)

@ -8,11 +8,12 @@ _visiond_dir = os.path.dirname(os.path.abspath(__file__))
_libvisiontest = "libvisiontest.so" _libvisiontest = "libvisiontest.so"
try: # bacause this crashes somtimes when running pipeline try: # bacause this crashes somtimes when running pipeline
subprocess.check_output(["make", "-C", _visiond_dir, "-f", subprocess.check_output(["make", "-C", _visiond_dir, "-f",
os.path.join(_visiond_dir, "visiontest.mk"), os.path.join(_visiond_dir, "visiontest.mk"),
_libvisiontest]) _libvisiontest])
except Exception: except Exception:
pass pass
class VisionTest(): class VisionTest():
"""A version of the vision model that can be run on a desktop. """A version of the vision model that can be run on a desktop.
@ -105,7 +106,7 @@ class VisionTest():
def transform_output_buffer(self, yuv_data, y_out, u_out, v_out, def transform_output_buffer(self, yuv_data, y_out, u_out, v_out,
transform): transform):
assert len(yuv_data) == self.input_size[0] * self.input_size[1] * 3/2 assert len(yuv_data) == self.input_size[0] * self.input_size[1] * 3 / 2
cast = self.ffi.cast cast = self.ffi.cast
from_buffer = self.ffi.from_buffer from_buffer = self.ffi.from_buffer
@ -126,7 +127,7 @@ class VisionTest():
def __enter__(self): def __enter__(self):
return self return self
def __exit__(self, type, value, traceback): def __exit__(self, exc_type, exc_value, traceback):
self.close() self.close()

@ -24,20 +24,23 @@ def create_dir(path):
def check_no_collision(log): def check_no_collision(log):
return min(log['d_rel']) > 0 return min(log['d_rel']) > 0
def check_fcw(log): def check_fcw(log):
return any(log['fcw']) return any(log['fcw'])
def check_engaged(log): def check_engaged(log):
return log['controls_state_msgs'][-1][-1].active return log['controls_state_msgs'][-1][-1].active
maneuvers = [ maneuvers = [
Maneuver( Maneuver(
'while cruising at 40 mph, change cruise speed to 50mph', 'while cruising at 40 mph, change cruise speed to 50mph',
duration=30., duration=30.,
initial_speed=40. * CV.MPH_TO_MS, initial_speed=40. * CV.MPH_TO_MS,
cruise_button_presses=[(CB.DECEL_SET, 2.), (0, 2.3), cruise_button_presses=[(CB.DECEL_SET, 2.), (0, 2.3),
(CB.RES_ACCEL, 10.), (0, 10.1), (CB.RES_ACCEL, 10.), (0, 10.1),
(CB.RES_ACCEL, 10.2), (0, 10.3)], (CB.RES_ACCEL, 10.2), (0, 10.3)],
checks=[check_engaged], checks=[check_engaged],
), ),
Maneuver( Maneuver(
@ -45,8 +48,8 @@ maneuvers = [
duration=30., duration=30.,
initial_speed=60. * CV.MPH_TO_MS, initial_speed=60. * CV.MPH_TO_MS,
cruise_button_presses=[(CB.DECEL_SET, 2.), (0, 2.3), cruise_button_presses=[(CB.DECEL_SET, 2.), (0, 2.3),
(CB.DECEL_SET, 10.), (0, 10.1), (CB.DECEL_SET, 10.), (0, 10.1),
(CB.DECEL_SET, 10.2), (0, 10.3)], (CB.DECEL_SET, 10.2), (0, 10.3)],
checks=[check_engaged], checks=[check_engaged],
), ),
Maneuver( Maneuver(
@ -73,7 +76,7 @@ maneuvers = [
initial_speed=60. * CV.MPH_TO_MS, initial_speed=60. * CV.MPH_TO_MS,
lead_relevancy=True, lead_relevancy=True,
initial_distance_lead=100., initial_distance_lead=100.,
speed_lead_values=[40.*CV.MPH_TO_MS, 40.*CV.MPH_TO_MS], speed_lead_values=[40. * CV.MPH_TO_MS, 40. * CV.MPH_TO_MS],
speed_lead_breakpoints=[0., 100.], speed_lead_breakpoints=[0., 100.],
cruise_button_presses=[(CB.DECEL_SET, 1.2), (0, 1.3)], cruise_button_presses=[(CB.DECEL_SET, 1.2), (0, 1.3)],
checks=[check_engaged, check_no_collision], checks=[check_engaged, check_no_collision],
@ -84,7 +87,7 @@ maneuvers = [
initial_speed=40. * CV.MPH_TO_MS, initial_speed=40. * CV.MPH_TO_MS,
lead_relevancy=True, lead_relevancy=True,
initial_distance_lead=150., initial_distance_lead=150.,
speed_lead_values=[0.*CV.MPH_TO_MS, 0.*CV.MPH_TO_MS], speed_lead_values=[0. * CV.MPH_TO_MS, 0. * CV.MPH_TO_MS],
speed_lead_breakpoints=[0., 100.], speed_lead_breakpoints=[0., 100.],
cruise_button_presses=[(CB.DECEL_SET, 1.2), (0, 1.3)], cruise_button_presses=[(CB.DECEL_SET, 1.2), (0, 1.3)],
checks=[check_engaged, check_no_collision], checks=[check_engaged, check_no_collision],
@ -140,9 +143,9 @@ maneuvers = [
lead_relevancy=True, lead_relevancy=True,
initial_distance_lead=100., initial_distance_lead=100.,
cruise_button_presses=[(CB.DECEL_SET, 1.2), (0, 1.3), cruise_button_presses=[(CB.DECEL_SET, 1.2), (0, 1.3),
(CB.RES_ACCEL, 1.4), (0.0, 1.5), (CB.RES_ACCEL, 1.4), (0.0, 1.5),
(CB.RES_ACCEL, 1.6), (0.0, 1.7), (CB.RES_ACCEL, 1.6), (0.0, 1.7),
(CB.RES_ACCEL, 1.8), (0.0, 1.9)], (CB.RES_ACCEL, 1.8), (0.0, 1.9)],
checks=[check_engaged, check_no_collision], checks=[check_engaged, check_no_collision],
), ),
Maneuver( Maneuver(
@ -154,8 +157,8 @@ maneuvers = [
speed_lead_values=[30., 30., 29., 31., 29., 31., 29.], speed_lead_values=[30., 30., 29., 31., 29., 31., 29.],
speed_lead_breakpoints=[0., 6., 8., 12., 16., 20., 24.], speed_lead_breakpoints=[0., 6., 8., 12., 16., 20., 24.],
cruise_button_presses=[(CB.DECEL_SET, 1.2), (0, 1.3), cruise_button_presses=[(CB.DECEL_SET, 1.2), (0, 1.3),
(CB.RES_ACCEL, 1.4), (0.0, 1.5), (CB.RES_ACCEL, 1.4), (0.0, 1.5),
(CB.RES_ACCEL, 1.6), (0.0, 1.7)], (CB.RES_ACCEL, 1.6), (0.0, 1.7)],
checks=[check_engaged, check_no_collision], checks=[check_engaged, check_no_collision],
), ),
Maneuver( Maneuver(
@ -167,8 +170,8 @@ maneuvers = [
speed_lead_values=[10., 0., 0., 10., 0., 10.], speed_lead_values=[10., 0., 0., 10., 0., 10.],
speed_lead_breakpoints=[10., 20., 30., 40., 50., 60.], speed_lead_breakpoints=[10., 20., 30., 40., 50., 60.],
cruise_button_presses=[(CB.DECEL_SET, 1.2), (0, 1.3), cruise_button_presses=[(CB.DECEL_SET, 1.2), (0, 1.3),
(CB.RES_ACCEL, 1.4), (0.0, 1.5), (CB.RES_ACCEL, 1.4), (0.0, 1.5),
(CB.RES_ACCEL, 1.6), (0.0, 1.7)], (CB.RES_ACCEL, 1.6), (0.0, 1.7)],
checks=[check_engaged, check_no_collision], checks=[check_engaged, check_no_collision],
), ),
Maneuver( Maneuver(
@ -177,14 +180,14 @@ maneuvers = [
initial_speed=0., initial_speed=0.,
lead_relevancy=True, lead_relevancy=True,
initial_distance_lead=4., initial_distance_lead=4.,
speed_lead_values=[0, 0 , 45], speed_lead_values=[0, 0, 45],
speed_lead_breakpoints=[0, 10., 40.], speed_lead_breakpoints=[0, 10., 40.],
cruise_button_presses=[(CB.DECEL_SET, 1.2), (0, 1.3), cruise_button_presses=[(CB.DECEL_SET, 1.2), (0, 1.3),
(CB.RES_ACCEL, 1.4), (0.0, 1.5), (CB.RES_ACCEL, 1.4), (0.0, 1.5),
(CB.RES_ACCEL, 1.6), (0.0, 1.7), (CB.RES_ACCEL, 1.6), (0.0, 1.7),
(CB.RES_ACCEL, 1.8), (0.0, 1.9), (CB.RES_ACCEL, 1.8), (0.0, 1.9),
(CB.RES_ACCEL, 2.0), (0.0, 2.1), (CB.RES_ACCEL, 2.0), (0.0, 2.1),
(CB.RES_ACCEL, 2.2), (0.0, 2.3)], (CB.RES_ACCEL, 2.2), (0.0, 2.3)],
checks=[check_engaged, check_no_collision], checks=[check_engaged, check_no_collision],
), ),
Maneuver( Maneuver(
@ -193,11 +196,11 @@ maneuvers = [
initial_speed=0., initial_speed=0.,
lead_relevancy=True, lead_relevancy=True,
initial_distance_lead=20., initial_distance_lead=20.,
speed_lead_values=[10., 0., 0., 10., 0., 0.] , speed_lead_values=[10., 0., 0., 10., 0., 0.],
speed_lead_breakpoints=[10., 20., 30., 40., 50., 60.], speed_lead_breakpoints=[10., 20., 30., 40., 50., 60.],
cruise_button_presses=[(CB.DECEL_SET, 1.2), (0, 1.3), cruise_button_presses=[(CB.DECEL_SET, 1.2), (0, 1.3),
(CB.RES_ACCEL, 1.4), (0.0, 1.5), (CB.RES_ACCEL, 1.4), (0.0, 1.5),
(CB.RES_ACCEL, 1.6), (0.0, 1.7)], (CB.RES_ACCEL, 1.6), (0.0, 1.7)],
checks=[check_engaged, check_no_collision], checks=[check_engaged, check_no_collision],
), ),
Maneuver( Maneuver(
@ -206,11 +209,11 @@ maneuvers = [
initial_speed=0., initial_speed=0.,
lead_relevancy=True, lead_relevancy=True,
initial_distance_lead=20., initial_distance_lead=20.,
speed_lead_values=[10., 0., 0., 10., 0., 0.] , speed_lead_values=[10., 0., 0., 10., 0., 0.],
speed_lead_breakpoints=[10., 13., 26., 33., 36., 45.], speed_lead_breakpoints=[10., 13., 26., 33., 36., 45.],
cruise_button_presses=[(CB.DECEL_SET, 1.2), (0, 1.3), cruise_button_presses=[(CB.DECEL_SET, 1.2), (0, 1.3),
(CB.RES_ACCEL, 1.4), (0.0, 1.5), (CB.RES_ACCEL, 1.4), (0.0, 1.5),
(CB.RES_ACCEL, 1.6), (0.0, 1.7)], (CB.RES_ACCEL, 1.6), (0.0, 1.7)],
checks=[check_engaged, check_no_collision], checks=[check_engaged, check_no_collision],
), ),
Maneuver( Maneuver(
@ -222,11 +225,11 @@ maneuvers = [
speed_lead_values=[20., 10.], speed_lead_values=[20., 10.],
speed_lead_breakpoints=[1., 11.], speed_lead_breakpoints=[1., 11.],
cruise_button_presses=[(CB.DECEL_SET, 1.2), (0, 1.3), cruise_button_presses=[(CB.DECEL_SET, 1.2), (0, 1.3),
(CB.RES_ACCEL, 1.4), (0.0, 1.5), (CB.RES_ACCEL, 1.4), (0.0, 1.5),
(CB.RES_ACCEL, 1.6), (0.0, 1.7), (CB.RES_ACCEL, 1.6), (0.0, 1.7),
(CB.RES_ACCEL, 1.8), (0.0, 1.9), (CB.RES_ACCEL, 1.8), (0.0, 1.9),
(CB.RES_ACCEL, 2.0), (0.0, 2.1), (CB.RES_ACCEL, 2.0), (0.0, 2.1),
(CB.RES_ACCEL, 2.2), (0.0, 2.3)], (CB.RES_ACCEL, 2.2), (0.0, 2.3)],
checks=[check_engaged, check_no_collision], checks=[check_engaged, check_no_collision],
), ),
Maneuver( Maneuver(
@ -238,11 +241,11 @@ maneuvers = [
speed_lead_values=[20., 0.], speed_lead_values=[20., 0.],
speed_lead_breakpoints=[1., 11.], speed_lead_breakpoints=[1., 11.],
cruise_button_presses=[(CB.DECEL_SET, 1.2), (0, 1.3), cruise_button_presses=[(CB.DECEL_SET, 1.2), (0, 1.3),
(CB.RES_ACCEL, 1.4), (0.0, 1.5), (CB.RES_ACCEL, 1.4), (0.0, 1.5),
(CB.RES_ACCEL, 1.6), (0.0, 1.7), (CB.RES_ACCEL, 1.6), (0.0, 1.7),
(CB.RES_ACCEL, 1.8), (0.0, 1.9), (CB.RES_ACCEL, 1.8), (0.0, 1.9),
(CB.RES_ACCEL, 2.0), (0.0, 2.1), (CB.RES_ACCEL, 2.0), (0.0, 2.1),
(CB.RES_ACCEL, 2.2), (0.0, 2.3)], (CB.RES_ACCEL, 2.2), (0.0, 2.3)],
checks=[check_engaged, check_no_collision], checks=[check_engaged, check_no_collision],
), ),
Maneuver( Maneuver(
@ -291,8 +294,6 @@ maneuvers = [
) )
] ]
# maneuvers = [maneuvers[-11]]
# maneuvers = [maneuvers[6]]
def setup_output(): def setup_output():
output_dir = os.path.join(os.getcwd(), 'out/longitudinal') output_dir = os.path.join(os.getcwd(), 'out/longitudinal')
@ -313,13 +314,14 @@ def setup_output():
for i, man in enumerate(maneuvers): for i, man in enumerate(maneuvers):
view_html += "<tr><td class='maneuver_title' colspan=5><div>%s</div></td></tr><tr>" % (man.title,) view_html += "<tr><td class='maneuver_title' colspan=5><div>%s</div></td></tr><tr>" % (man.title,)
for c in ['distance.svg', 'speeds.svg', 'acceleration.svg', 'pedals.svg', 'pid.svg']: for c in ['distance.svg', 'speeds.svg', 'acceleration.svg', 'pedals.svg', 'pid.svg']:
view_html += "<td><img class='maneuver_graph' src='%s'/></td>" % (os.path.join("maneuver" + str(i+1).zfill(2), c), ) view_html += "<td><img class='maneuver_graph' src='%s'/></td>" % (os.path.join("maneuver" + str(i + 1).zfill(2), c), )
view_html += "</tr>" view_html += "</tr>"
create_dir(output_dir) create_dir(output_dir)
with open(os.path.join(output_dir, "index.html"), "w") as f: with open(os.path.join(output_dir, "index.html"), "w") as f:
f.write(view_html) f.write(view_html)
class LongitudinalControl(unittest.TestCase): class LongitudinalControl(unittest.TestCase):
@classmethod @classmethod
def setUpClass(cls): def setUpClass(cls):
@ -355,7 +357,7 @@ def run_maneuver_worker(k):
print(man.title) print(man.title)
valid = False valid = False
for retries in range(3): for _ in range(3):
manager.start_managed_process('radard') manager.start_managed_process('radard')
manager.start_managed_process('controlsd') manager.start_managed_process('controlsd')
manager.start_managed_process('plannerd') manager.start_managed_process('plannerd')

@ -13,6 +13,7 @@ else:
from tools.lib.logreader import LogReader from tools.lib.logreader import LogReader
def save_log(dest, log_msgs): def save_log(dest, log_msgs):
dat = b"" dat = b""
for msg in tqdm(log_msgs): for msg in tqdm(log_msgs):
@ -22,6 +23,7 @@ def save_log(dest, log_msgs):
with open(dest, "wb") as f: with open(dest, "wb") as f:
f.write(dat) f.write(dat)
def remove_ignored_fields(msg, ignore): def remove_ignored_fields(msg, ignore):
msg = msg.as_builder() msg = msg.as_builder()
for key in ignore: for key in ignore:
@ -46,7 +48,13 @@ def remove_ignored_fields(msg, ignore):
setattr(attr, keys[-1], val) setattr(attr, keys[-1], val)
return msg.as_reader() return msg.as_reader()
def compare_logs(log1, log2, ignore_fields=[], ignore_msgs=[]):
def compare_logs(log1, log2, ignore_fields=None, ignore_msgs=None):
if ignore_fields is None:
ignore_fields = []
if ignore_msgs is None:
ignore_msgs = []
log1, log2 = [list(filter(lambda m: m.which() not in ignore_msgs, log)) for log in (log1, log2)] log1, log2 = [list(filter(lambda m: m.which() not in ignore_msgs, log)) for log in (log1, log2)]
assert len(log1) == len(log2), "logs are not same length: " + str(len(log1)) + " VS " + str(len(log2)) assert len(log1) == len(log2), "logs are not same length: " + str(len(log1)) + " VS " + str(len(log2))
@ -66,6 +74,7 @@ def compare_logs(log1, log2, ignore_fields=[], ignore_msgs=[]):
diff.extend(dd) diff.extend(dd)
return diff return diff
if __name__ == "__main__": if __name__ == "__main__":
log1 = list(LogReader(sys.argv[1])) log1 = list(LogReader(sys.argv[1]))
log2 = list(LogReader(sys.argv[2])) log2 = list(LogReader(sys.argv[2]))

@ -21,6 +21,7 @@ from collections import namedtuple
ProcessConfig = namedtuple('ProcessConfig', ['proc_name', 'pub_sub', 'ignore', 'init_callback', 'should_recv_callback']) ProcessConfig = namedtuple('ProcessConfig', ['proc_name', 'pub_sub', 'ignore', 'init_callback', 'should_recv_callback'])
def wait_for_event(evt): def wait_for_event(evt):
if not evt.wait(15): if not evt.wait(15):
if threading.currentThread().getName() == "MainThread": if threading.currentThread().getName() == "MainThread":
@ -30,6 +31,7 @@ def wait_for_event(evt):
# done testing this process, let it die # done testing this process, let it die
sys.exit(0) sys.exit(0)
class FakeSocket: class FakeSocket:
def __init__(self, wait=True): def __init__(self, wait=True):
self.data = [] self.data = []
@ -60,6 +62,7 @@ class FakeSocket:
def wait_for_recv(self): def wait_for_recv(self):
wait_for_event(self.recv_called) wait_for_event(self.recv_called)
class DumbSocket: class DumbSocket:
def __init__(self, s=None): def __init__(self, s=None):
if s is not None: if s is not None:
@ -72,6 +75,7 @@ class DumbSocket:
def send(self, dat): def send(self, dat):
pass pass
class FakeSubMaster(messaging.SubMaster): class FakeSubMaster(messaging.SubMaster):
def __init__(self, services): def __init__(self, services):
super(FakeSubMaster, self).__init__(services, addr=None) super(FakeSubMaster, self).__init__(services, addr=None)
@ -103,8 +107,9 @@ class FakeSubMaster(messaging.SubMaster):
def wait_for_update(self): def wait_for_update(self):
wait_for_event(self.update_called) wait_for_event(self.update_called)
class FakePubMaster(messaging.PubMaster): class FakePubMaster(messaging.PubMaster):
def __init__(self, services): def __init__(self, services): # pylint: disable=super-init-not-called
self.data = {} self.data = {}
self.sock = {} self.sock = {}
self.last_updated = None self.last_updated = None

@ -49,7 +49,11 @@ def get_segment(segment_name, original=True):
return rlog_url return rlog_url
def test_process(cfg, lr, cmp_log_fn, ignore_fields=[], ignore_msgs=[]): def test_process(cfg, lr, cmp_log_fn, ignore_fields=None, ignore_msgs=None):
if ignore_fields is None:
ignore_fields = []
if ignore_msgs is None:
ignore_msgs = []
url = BASE_URL + os.path.basename(cmp_log_fn) url = BASE_URL + os.path.basename(cmp_log_fn)
cmp_log_msgs = list(LogReader(url)) cmp_log_msgs = list(LogReader(url))

@ -36,7 +36,7 @@ class PubSocket():
class SubMaster(messaging.SubMaster): class SubMaster(messaging.SubMaster):
def __init__(self, msgs, trigger, services): def __init__(self, msgs, trigger, services): # pylint: disable=super-init-not-called
self.max_i = len(msgs) - 1 self.max_i = len(msgs) - 1
self.i = 0 self.i = 0
self.frame = 0 self.frame = 0
@ -88,5 +88,5 @@ class SubMaster(messaging.SubMaster):
class PubMaster(messaging.PubMaster): class PubMaster(messaging.PubMaster):
def __init__(self): def __init__(self): # pylint: disable=super-init-not-called
self.sock = defaultdict(PubSocket) self.sock = defaultdict(PubSocket)

@ -40,6 +40,7 @@ def wait_for_sockets(socks, timeout=10.0):
recvd.append(s) recvd.append(s)
return recvd return recvd
def get_route_log(route_name): def get_route_log(route_name):
log_path = os.path.join("/tmp", "%s--0--%s" % (route_name.replace("|", "_"), "rlog.bz2")) log_path = os.path.join("/tmp", "%s--0--%s" % (route_name.replace("|", "_"), "rlog.bz2"))
@ -49,7 +50,7 @@ def get_route_log(route_name):
# if request fails, try again once and let it throw exception if fails again # if request fails, try again once and let it throw exception if fails again
try: try:
r = requests.get(log_url, timeout=15) r = requests.get(log_url, timeout=15)
except: except Exception:
r = requests.get(log_url, timeout=15) r = requests.get(log_url, timeout=15)
if r.status_code == 200: if r.status_code == 200:
@ -460,7 +461,7 @@ if __name__ == "__main__":
# Start unlogger # Start unlogger
print("Start unlogger") print("Start unlogger")
unlogger_cmd = [os.path.join(BASEDIR, 'tools/replay/unlogger.py'), route, '/tmp'] unlogger_cmd = [os.path.join(BASEDIR, 'tools/replay/unlogger.py'), route, '/tmp']
unlogger = subprocess.Popen(unlogger_cmd + ['--disable', 'frame,encodeIdx,plan,pathPlan,liveLongitudinalMpc,radarState,controlsState,liveTracks,liveMpc,sendcan,carState,carControl,carEvents,carParams', '--no-interactive'], preexec_fn=os.setsid) unlogger = subprocess.Popen(unlogger_cmd + ['--disable', 'frame,encodeIdx,plan,pathPlan,liveLongitudinalMpc,radarState,controlsState,liveTracks,liveMpc,sendcan,carState,carControl,carEvents,carParams', '--no-interactive'], preexec_fn=os.setsid) # pylint: disable=subprocess-popen-preexec-fn
print("Check sockets") print("Check sockets")
extra_socks = [] extra_socks = []

@ -15,7 +15,6 @@ import requests
import signal import signal
import subprocess import subprocess
import time import time
from datetime import datetime, timedelta
DID_INIT = False DID_INIT = False

@ -114,7 +114,7 @@ class PowerMonitoring:
# Measure for a few sec to get a good average # Measure for a few sec to get a good average
voltages = [] voltages = []
currents = [] currents = []
for i in range(6): for _ in range(6):
voltages.append(get_battery_voltage()) voltages.append(get_battery_voltage())
currents.append(get_battery_current()) currents.append(get_battery_current())
time.sleep(1) time.sleep(1)

@ -61,7 +61,7 @@ def main():
while True: while True:
now_tombstones = set(get_tombstones()) now_tombstones = set(get_tombstones())
for fn, ctime in (now_tombstones - initial_tombstones): for fn, _ in (now_tombstones - initial_tombstones):
try: try:
cloudlog.info(f"reporting new tombstone {fn}") cloudlog.info(f"reporting new tombstone {fn}")
report_tombstone(fn, client) report_tombstone(fn, client)

@ -195,7 +195,7 @@ def inodes_in_tree(search_dir):
"""Given a search root, produce a dictionary mapping of inodes to relative """Given a search root, produce a dictionary mapping of inodes to relative
pathnames of regular files (no directories, symlinks, or special files).""" pathnames of regular files (no directories, symlinks, or special files)."""
inode_map = {} inode_map = {}
for root, dirs, files in os.walk(search_dir, topdown=True): for root, _, files in os.walk(search_dir, topdown=True):
for file_name in files: for file_name in files:
full_path_name = os.path.join(root, file_name) full_path_name = os.path.join(root, file_name)
st = os.lstat(full_path_name) st = os.lstat(full_path_name)

@ -25,7 +25,7 @@ class ClientRedirectHandler(BaseHTTPRequestHandler):
self.end_headers() self.end_headers()
self.wfile.write(b'Return to the CLI to continue') self.wfile.write(b'Return to the CLI to continue')
def log_message(self, format, *args): def log_message(self, format, *args): # pylint: disable=redefined-builtin
pass # this prevent http server from dumping messages to stdout pass # this prevent http server from dumping messages to stdout
def auth_redirect_link(port): def auth_redirect_link(port):

@ -54,7 +54,7 @@ class KBHit:
def kbhit(self): def kbhit(self):
''' Returns True if keyboard character was hit, False otherwise. ''' Returns True if keyboard character was hit, False otherwise.
''' '''
dr, dw, de = select([sys.stdin], [], [], 0) dr, _, _ = select([sys.stdin], [], [], 0)
return dr != [] return dr != []

@ -1,6 +1,7 @@
"""RouteFrameReader indexes and reads frames across routes, by frameId or segment indices.""" """RouteFrameReader indexes and reads frames across routes, by frameId or segment indices."""
from tools.lib.framereader import FrameReader from tools.lib.framereader import FrameReader
class _FrameReaderDict(dict): class _FrameReaderDict(dict):
def __init__(self, camera_paths, cache_paths, framereader_kwargs, *args, **kwargs): def __init__(self, camera_paths, cache_paths, framereader_kwargs, *args, **kwargs):
super(_FrameReaderDict, self).__init__(*args, **kwargs) super(_FrameReaderDict, self).__init__(*args, **kwargs)
@ -8,7 +9,7 @@ class _FrameReaderDict(dict):
if cache_paths is None: if cache_paths is None:
cache_paths = {} cache_paths = {}
if not isinstance(cache_paths, dict): if not isinstance(cache_paths, dict):
cache_paths = { k: v for k, v in enumerate(cache_paths) } cache_paths = {k: v for k, v in enumerate(cache_paths)}
self._camera_paths = camera_paths self._camera_paths = camera_paths
self._cache_paths = cache_paths self._cache_paths = cache_paths
@ -84,5 +85,5 @@ class RouteFrameReader(object):
def __enter__(self): def __enter__(self):
return self return self
def __exit__(self, type, value, traceback): def __exit__(self, exc_type, exc_value, traceback):
self.close() self.close()

@ -3,7 +3,7 @@ import os
from common.basedir import BASEDIR from common.basedir import BASEDIR
os.environ['BASEDIR'] = BASEDIR os.environ['BASEDIR'] = BASEDIR
SCALE = float(os.getenv("SCALE", 1.0)) SCALE = float(os.getenv("SCALE", "1"))
import argparse import argparse
import pygame # pylint: disable=import-error import pygame # pylint: disable=import-error

@ -5,10 +5,10 @@ import sys
import zmq import zmq
import time import time
import signal import signal
import multiprocessing
from uuid import uuid4 from uuid import uuid4
from collections import namedtuple from collections import namedtuple
from collections import deque from collections import deque
from multiprocessing import Process, TimeoutError
from datetime import datetime from datetime import datetime
# strat 1: script to copy files # strat 1: script to copy files
@ -404,11 +404,11 @@ def main(argv):
subprocesses = {} subprocesses = {}
try: try:
subprocesses["data"] = Process( subprocesses["data"] = multiprocessing.Process(
target=UnloggerWorker().run, target=UnloggerWorker().run,
args=(forward_commands_address, data_address, address_mapping.copy())) args=(forward_commands_address, data_address, address_mapping.copy()))
subprocesses["control"] = Process( subprocesses["control"] = multiprocessing.Process(
target=unlogger_thread, target=unlogger_thread,
args=(command_address, forward_commands_address, data_address, args.realtime, args=(command_address, forward_commands_address, data_address, args.realtime,
_get_address_mapping(args), args.publish_time_length, args.bind_early, args.no_loop)) _get_address_mapping(args), args.publish_time_length, args.bind_early, args.no_loop))
@ -421,7 +421,7 @@ def main(argv):
# Exit if any of the children die. # Exit if any of the children die.
def exit_if_children_dead(*_): def exit_if_children_dead(*_):
for name, p in subprocesses.items(): for _, p in subprocesses.items():
if not p.is_alive(): if not p.is_alive():
[p.terminate() for p in subprocesses.values()] [p.terminate() for p in subprocesses.values()]
exit() exit()
@ -439,7 +439,7 @@ def main(argv):
if p.is_alive(): if p.is_alive():
try: try:
p.join(3.) p.join(3.)
except TimeoutError: except multiprocessing.TimeoutError:
p.terminate() p.terminate()
continue continue
return 0 return 0

@ -97,11 +97,9 @@ def go(q):
world.set_weather(weather) world.set_weather(weather)
blueprint_library = world.get_blueprint_library() blueprint_library = world.get_blueprint_library()
""" # for blueprint in blueprint_library.filter('sensor.*'):
for blueprint in blueprint_library.filter('sensor.*'): # print(blueprint.id)
print(blueprint.id) # exit(0)
exit(0)
"""
world_map = world.get_map() world_map = world.get_map()
vehicle_bp = random.choice(blueprint_library.filter('vehicle.tesla.*')) vehicle_bp = random.choice(blueprint_library.filter('vehicle.tesla.*'))

@ -143,7 +143,7 @@ def wheel_poll_thread(q):
while True: while True:
evbuf = jsdev.read(8) evbuf = jsdev.read(8)
time, value, mtype, number = struct.unpack('IhBB', evbuf) _, value, mtype, number = struct.unpack('IhBB', evbuf)
# print(mtype, number, value) # print(mtype, number, value)
if mtype & 0x02: # wheel & paddles if mtype & 0x02: # wheel & paddles
axis = axis_map[number] axis = axis_map[number]

Loading…
Cancel
Save