diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index e0a1755d10..d65b68b13d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -10,12 +10,12 @@ repos: rev: master hooks: - 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 rev: master hooks: - 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: - --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 @@ -27,5 +27,3 @@ repos: language: system types: [python] exclude: '^(pyextra)|(external)|(cereal)|(rednose)|(panda)|(laika)|(laika_repo)|(rednose_repo)/' - args: - - --disable=R,C,W diff --git a/.pylintrc b/.pylintrc index 9a55710c45..be7701c906 100644 --- a/.pylintrc +++ b/.pylintrc @@ -54,121 +54,7 @@ confidence= # --enable=similarities". If you want to run only the classes checker, but have # no Warning level messages displayed, use"--disable=all --enable=classes # --disable=W" -disable=print-statement, - 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 +disable=C,R,W0613,W0511,W0212,W0201,W0311,W0106,W0603,W0621,W0703,E1136 # Enable the message, report, category or checker with the given id(s). You can diff --git a/common/file_helpers.py b/common/file_helpers.py index 187f0f9ac6..c33ebac6f6 100644 --- a/common/file_helpers.py +++ b/common/file_helpers.py @@ -3,6 +3,7 @@ import shutil import tempfile from atomicwrites import AtomicWriter + def mkdirs_exists_ok(path): try: os.makedirs(path) @@ -10,6 +11,7 @@ def mkdirs_exists_ok(path): if not os.path.isdir(path): raise + def rm_not_exists_ok(path): try: os.remove(path) @@ -17,12 +19,14 @@ def rm_not_exists_ok(path): if os.path.exists(path): raise + def rm_tree_or_link(path): if os.path.islink(path): os.unlink(path) elif os.path.isdir(path): shutil.rmtree(path) + def get_tmpdir_on_same_filesystem(path): normpath = os.path.normpath(path) parts = normpath.split("/") @@ -32,6 +36,7 @@ def get_tmpdir_on_same_filesystem(path): return "/{}/runner/tmp".format(parts[1]) return "/tmp" + class AutoMoveTempdir(): def __init__(self, target_path, temp_dir=None): self._target_path = target_path @@ -47,12 +52,13 @@ class AutoMoveTempdir(): def __enter__(self): return self - def __exit__(self, type, value, traceback): - if type is None: + def __exit__(self, exc_type, exc_value, traceback): + if exc_type is None: self.close() else: shutil.rmtree(self._path) + class NamedTemporaryDir(): def __init__(self, temp_dir=None): self._path = tempfile.mkdtemp(dir=temp_dir) @@ -67,9 +73,10 @@ class NamedTemporaryDir(): def __enter__(self): return self - def __exit__(self, type, value, traceback): + def __exit__(self, exc_type, exc_value, traceback): self.close() + def _get_fileobject_func(writer, temp_dir): def _get_fileobject(): file_obj = writer.get_fileobject(dir=temp_dir) @@ -77,6 +84,7 @@ def _get_fileobject_func(writer, temp_dir): return file_obj return _get_fileobject + def atomic_write_on_fs_tmp(path, **kwargs): """Creates an atomic writer using a temporary file in a temporary directory on the same filesystem as path. @@ -94,6 +102,7 @@ def atomic_write_in_dir(path, **kwargs): writer = AtomicWriter(path, **kwargs) return writer._open(_get_fileobject_func(writer, os.path.dirname(path))) + def atomic_write_in_dir_neos(path, contents, mode=None): """ Atomically writes contents to path using a temporary file in the same directory diff --git a/common/logging_extra.py b/common/logging_extra.py index 2c49561fb9..7d9bcd7b6e 100644 --- a/common/logging_extra.py +++ b/common/logging_extra.py @@ -143,7 +143,9 @@ class SwagLogger(logging.Logger): while hasattr(f, "f_code"): co = f.f_code 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 continue sinfo = None diff --git a/common/params.py b/common/params.py index b92f17ca26..ddaf56ae51 100755 --- a/common/params.py +++ b/common/params.py @@ -30,6 +30,7 @@ import threading from enum import Enum from common.basedir import PARAMS + def mkdirs_exists_ok(path): try: os.makedirs(path) @@ -143,6 +144,10 @@ class DBAccessor(): def get(self, key): self._check_entered() + + if self._vals is None: + return None + try: return self._vals[key] except KeyError: @@ -195,7 +200,7 @@ class DBReader(DBAccessor): finally: lock.release() - def __exit__(self, type, value, traceback): + def __exit__(self, exc_type, exc_value, traceback): pass @@ -221,14 +226,14 @@ class DBWriter(DBAccessor): os.chmod(self._path, 0o777) self._lock = self._get_lock(True) self._vals = self._read_values_locked() - except: + except Exception: os.umask(self._prev_umask) self._prev_umask = None raise return self - def __exit__(self, type, value, traceback): + def __exit__(self, exc_type, exc_value, traceback): self._check_entered() try: @@ -302,12 +307,13 @@ def read_db(params_path, key): except IOError: return None + def write_db(params_path, key, value): if isinstance(value, str): value = value.encode('utf8') prev_umask = os.umask(0) - lock = FileLock(params_path+"/.lock", True) + lock = FileLock(params_path + "/.lock", True) lock.acquire() try: @@ -324,12 +330,13 @@ def write_db(params_path, key, value): os.umask(prev_umask) lock.release() + class Params(): def __init__(self, db=PARAMS): self.db = db # 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): pass diff --git a/common/spinner.py b/common/spinner.py index 370d54c815..c49b124c98 100644 --- a/common/spinner.py +++ b/common/spinner.py @@ -36,12 +36,12 @@ class Spinner(): def __del__(self): self.close() - def __exit__(self, type, value, traceback): + def __exit__(self, exc_type, exc_value, traceback): self.close() class FakeSpinner(Spinner): - def __init__(self): + def __init__(self): # pylint: disable=super-init-not-called pass def __enter__(self): @@ -53,7 +53,7 @@ class FakeSpinner(Spinner): def close(self): pass - def __exit__(self, type, value, traceback): + def __exit__(self, exc_type, exc_value, traceback): pass diff --git a/common/text_window.py b/common/text_window.py index 7bcad25094..88da8e53f5 100755 --- a/common/text_window.py +++ b/common/text_window.py @@ -39,12 +39,12 @@ class TextWindow(): def __del__(self): self.close() - def __exit__(self, type, value, traceback): + def __exit__(self, exc_type, exc_value, traceback): self.close() class FakeTextWindow(TextWindow): - def __init__(self, s): + def __init__(self, s): # pylint: disable=super-init-not-called pass def get_status(self): @@ -62,7 +62,7 @@ class FakeTextWindow(TextWindow): def close(self): pass - def __exit__(self, type, value, traceback): + def __exit__(self, exc_type, exc_value, traceback): pass diff --git a/common/transformations/coordinates.py b/common/transformations/coordinates.py index 4f8445145c..e39ad697aa 100644 --- a/common/transformations/coordinates.py +++ b/common/transformations/coordinates.py @@ -1,8 +1,8 @@ -import numpy as np """ Coordinate transformation module. All methods accept arrays as input with each row as a position. """ +import numpy as np a = 6378137 diff --git a/common/transformations/orientation.py b/common/transformations/orientation.py index f594f05678..e6161ea28d 100644 --- a/common/transformations/orientation.py +++ b/common/transformations/orientation.py @@ -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 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!). ''' +import numpy as np +from numpy import dot, inner, array, linalg +from common.transformations.coordinates import LocalCoord + + def euler2quat(eulers): eulers = array(eulers) if len(eulers.shape) > 1: diff --git a/common/url_file.py b/common/url_file.py index 343e7537be..38637d90cc 100644 --- a/common/url_file.py +++ b/common/url_file.py @@ -9,6 +9,7 @@ import pycurl from io import BytesIO from tenacity import retry, wait_random_exponential, stop_after_attempt + class URLFile(object): _tlocal = threading.local() @@ -26,7 +27,7 @@ class URLFile(object): def __enter__(self): return self - def __exit__(self, type, value, traceback): + def __exit__(self, exc_type, exc_value, traceback): if self._local_file is not None: os.remove(self._local_file.name) self._local_file.close() @@ -37,7 +38,7 @@ class URLFile(object): if ll is None: trange = 'bytes=%d-' % self._pos else: - trange = 'bytes=%d-%d' % (self._pos, self._pos+ll-1) + trange = 'bytes=%d-%d' % (self._pos, self._pos + ll - 1) dats = BytesIO() c = self._curl @@ -68,8 +69,8 @@ class URLFile(object): if self._debug: t2 = time.time() - if t2-t1 > 0.1: - print("get %s %r %.f slow" % (self._url, trange, t2-t1)) + if t2 - t1 > 0.1: + print("get %s %r %.f slow" % (self._url, trange, t2 - t1)) response_code = c.getinfo(pycurl.RESPONSE_CODE) if response_code == 416: # Requested Range Not Satisfiable @@ -96,7 +97,7 @@ class URLFile(object): try: os.write(local_fd, self.read()) local_file = open(local_path, "rb") - except: + except Exception: os.remove(local_path) raise finally: diff --git a/selfdrive/athena/athenad.py b/selfdrive/athena/athenad.py index cbebb08e56..72e81a58bb 100755 --- a/selfdrive/athena/athenad.py +++ b/selfdrive/athena/athenad.py @@ -29,7 +29,7 @@ from selfdrive.loggerd.config import ROOT from selfdrive.swaglog import cloudlog 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]) dispatcher["echo"] = lambda s: s @@ -39,6 +39,7 @@ upload_queue: Any = queue.Queue() cancelled_uploads: Any = set() UploadItem = namedtuple('UploadItem', ['path', 'url', 'headers', 'created_at', 'id']) + def handle_long_poll(ws): end_event = threading.Event() @@ -60,9 +61,10 @@ def handle_long_poll(ws): end_event.set() raise finally: - for i, thread in enumerate(threads): + for thread in threads: thread.join() + def jsonrpc_handler(end_event): dispatcher["startLocalProxy"] = partial(startLocalProxy, end_event) while not end_event.is_set(): @@ -76,6 +78,7 @@ def jsonrpc_handler(end_event): cloudlog.exception("athena jsonrpc handler failed") response_queue.put_nowait(json.dumps({"error": str(e)})) + def upload_handler(end_event): while not end_event.is_set(): try: @@ -89,6 +92,7 @@ def upload_handler(end_event): except Exception: cloudlog.exception("athena.upload_handler.exception") + def _do_upload(upload_item): with open(upload_item.path, "rb") as f: size = os.fstat(f.fileno()).st_size @@ -97,6 +101,7 @@ def _do_upload(upload_item): headers={**upload_item.headers, 'Content-Length': str(size)}, timeout=10) + # security: user should be able to request any message from their car @dispatcher.add_method def getMessage(service=None, timeout=1000): @@ -111,11 +116,13 @@ def getMessage(service=None, timeout=1000): return ret.to_dict() + @dispatcher.add_method def listDataDirectory(): files = [os.path.relpath(os.path.join(dp, f), ROOT) for dp, dn, fn in os.walk(ROOT) for f in fn] return files + @dispatcher.add_method def reboot(): thermal_sock = messaging.sub_sock("thermal", timeout=1000) @@ -131,6 +138,7 @@ def reboot(): return {"success": 1} + @dispatcher.add_method def uploadFileToUrl(fn, url, headers): 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): 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() item = item._replace(id=upload_id) @@ -147,10 +155,12 @@ def uploadFileToUrl(fn, url, headers): return {"enqueued": 1, "item": item._asdict()} + @dispatcher.add_method def listUploadQueue(): return [item._asdict() for item in list(upload_queue.queue)] + @dispatcher.add_method def cancelUpload(upload_id): 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) return {"success": 1} + def startLocalProxy(global_end_event, remote_ws_uri, local_port): try: 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") raise e + @dispatcher.add_method def getPublicKey(): - if not os.path.isfile(PERSIST+'/comma/id_rsa.pub'): + if not os.path.isfile(PERSIST + '/comma/id_rsa.pub'): 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() + @dispatcher.add_method def getSshAuthorizedKeys(): return Params().get("GithubSshKeys", encoding='utf8') or '' + @dispatcher.add_method def getSimInfo(): sim_state = android.getprop("gsm.sim.state").split(",") @@ -220,6 +234,7 @@ def getSimInfo(): 'data_connected': cell_data_connected } + @dispatcher.add_method def takeSnapshot(): from selfdrive.camerad.snapshot.snapshot import snapshot, jpeg_write @@ -237,6 +252,7 @@ def takeSnapshot(): else: raise Exception("not available while camerad is started") + 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()): try: @@ -252,6 +268,7 @@ def ws_proxy_recv(ws, local_sock, ssock, end_event, global_end_event): local_sock.close() end_event.set() + def ws_proxy_send(ws, local_sock, signal_sock, end_event): while not end_event.is_set(): try: @@ -272,6 +289,7 @@ def ws_proxy_send(ws, local_sock, signal_sock, end_event): cloudlog.exception("athenad.ws_proxy_send.exception") end_event.set() + def ws_recv(ws, end_event): while not end_event.is_set(): try: @@ -281,13 +299,14 @@ def ws_recv(ws, end_event): data = data.decode("utf-8") payload_queue.put_nowait(data) 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: pass except Exception: cloudlog.exception("athenad.ws_recv.exception") end_event.set() + def ws_send(ws, end_event): while not end_event.is_set(): try: @@ -299,9 +318,11 @@ def ws_send(ws, end_event): cloudlog.exception("athenad.ws_send.exception") end_event.set() + def backoff(retries): return random.randrange(0, min(128, int(2 ** retries))) + def main(): params = Params() dongle_id = params.get("DongleId").decode('utf-8') @@ -328,5 +349,6 @@ def main(): time.sleep(backoff(conn_retries)) + if __name__ == "__main__": main() diff --git a/selfdrive/athena/test_helpers.py b/selfdrive/athena/test_helpers.py index 2335ce89c5..2919de6637 100644 --- a/selfdrive/athena/test_helpers.py +++ b/selfdrive/athena/test_helpers.py @@ -8,6 +8,7 @@ import time from functools import wraps from multiprocessing import Process + class EchoSocket(): def __init__(self, port): self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) @@ -15,7 +16,7 @@ class EchoSocket(): self.socket.listen(1) def run(self): - conn, client_address = self.socket.accept() + conn, _ = self.socket.accept() conn.settimeout(5.0) try: @@ -32,6 +33,7 @@ class EchoSocket(): self.socket.shutdown(0) self.socket.close() + class MockApi(): def __init__(self, dongle_id): pass @@ -39,6 +41,7 @@ class MockApi(): def get_token(self): return "fake-token" + class MockParams(): def __init__(self): self.params = { @@ -52,6 +55,7 @@ class MockParams(): ret = ret.decode(encoding) return ret + class MockWebsocket(): def __init__(self, recv_queue, send_queue): self.recv_queue = recv_queue @@ -66,6 +70,7 @@ class MockWebsocket(): def send(self, data, opcode): self.send_queue.put_nowait((data, opcode)) + class HTTPRequestHandler(http.server.SimpleHTTPRequestHandler): def do_PUT(self): length = int(self.headers['Content-Length']) @@ -73,6 +78,7 @@ class HTTPRequestHandler(http.server.SimpleHTTPRequestHandler): self.send_response(201, "Created") self.end_headers() + def http_server(port_queue, **kwargs): while 1: try: @@ -83,6 +89,7 @@ def http_server(port_queue, **kwargs): if e.errno == 98: continue + def with_http_server(func): @wraps(func) def inner(*args, **kwargs): diff --git a/selfdrive/boardd/tests/boardd_old.py b/selfdrive/boardd/tests/boardd_old.py index 4c62e94883..87e579023d 100755 --- a/selfdrive/boardd/tests/boardd_old.py +++ b/selfdrive/boardd/tests/boardd_old.py @@ -1,4 +1,5 @@ #!/usr/bin/env python3 +# pylint: skip-file # This file is not used by OpenPilot. Only boardd.cc is used. # The python version is slower, but has more options for development. diff --git a/selfdrive/boardd/tests/test_boardd_api.py b/selfdrive/boardd/tests/test_boardd_api.py index f41e1e3571..9386c7845e 100644 --- a/selfdrive/boardd/tests/test_boardd_api.py +++ b/selfdrive/boardd/tests/test_boardd_api.py @@ -12,7 +12,7 @@ import unittest def generate_random_can_data_list(): can_list = [] cnt = random.randint(1, 64) - for j in range(cnt): + for _ in range(cnt): 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)]) 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')) def test_performance(self): - can_list, cnt = generate_random_can_data_list() + can_list, _ = generate_random_can_data_list() recursions = 1000 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() n2 = sec_since_boot() elapsed_old = n2 - n1 # print('Old API, elapsed time: {} secs'.format(elapsed_old)) n1 = sec_since_boot() - for i in range(recursions): + for _ in range(recursions): boardd.can_list_to_can_capnp(can_list) n2 = sec_since_boot() elapsed_new = n2 - n1 diff --git a/selfdrive/car/__init__.py b/selfdrive/car/__init__.py index 1d579543a6..09edb03156 100644 --- a/selfdrive/car/__init__.py +++ b/selfdrive/car/__init__.py @@ -4,9 +4,11 @@ from common.numpy_fast import clip # kg of standard extra cargo to count for drive, gas, etc... STD_CARGO_KG = 136. + def gen_empty_fingerprint(): return {i: {} for i in range(0, 4)} + # FIXME: hardcoding honda civic 2016 touring params so they can be used to # scale unknown params for other cars class CivicParams: @@ -18,11 +20,13 @@ class CivicParams: TIRE_STIFFNESS_FRONT = 192150 TIRE_STIFFNESS_REAR = 202500 + # TODO: get actual value, for now starting with reasonable value for # civic and scaling by mass and wheelbase def scale_rot_inertia(mass, wheelbase): 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 # 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): @@ -35,6 +39,7 @@ def scale_tire_stiffness(mass, wheelbase, center_to_front, tire_stiffness_factor return tire_stiffness_front, tire_stiffness_rear + def dbc_dict(pt_dbc, radar_dbc, chassis_dbc=None): 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 if apply_torque_last > 0: 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: 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))) @@ -83,9 +88,9 @@ def crc8_pedal(data): crc = 0xFF # standard init value poly = 0xD5 # standard crc8: x8+x7+x6+x4+x2+1 size = len(data) - for i in range(size-1, -1, -1): + for i in range(size - 1, -1, -1): crc ^= data[i] - for j in range(8): + for _ in range(8): if ((crc & 0x80) != 0): crc = ((crc << 1) ^ poly) & 0xFF else: diff --git a/selfdrive/car/chrysler/interface.py b/selfdrive/car/chrysler/interface.py index 85ad43af14..294b96c5ea 100755 --- a/selfdrive/car/chrysler/interface.py +++ b/selfdrive/car/chrysler/interface.py @@ -11,7 +11,12 @@ class CarInterface(CarInterfaceBase): return float(accel) / 3.0 @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.carName = "chrysler" ret.safetyModel = car.CarParams.SafetyModel.chrysler diff --git a/selfdrive/car/ford/interface.py b/selfdrive/car/ford/interface.py index 0c1ce863c5..59e6191420 100755 --- a/selfdrive/car/ford/interface.py +++ b/selfdrive/car/ford/interface.py @@ -14,7 +14,7 @@ class CarInterface(CarInterfaceBase): return float(accel) / 3.0 @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.carName = "ford" ret.safetyModel = car.CarParams.SafetyModel.ford diff --git a/selfdrive/car/gm/carcontroller.py b/selfdrive/car/gm/carcontroller.py index c304081c0a..2018d73306 100644 --- a/selfdrive/car/gm/carcontroller.py +++ b/selfdrive/car/gm/carcontroller.py @@ -38,24 +38,8 @@ class CarControllerParams(): 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(): def __init__(self, dbc_name, CP, VM): - self.pedal_steady = 0. self.start_time = 0. self.apply_steer_last = 0 self.lka_icon_status_last = (False, False) @@ -79,8 +63,7 @@ class CarController(): if hud_alert == VisualAlert.fcw: self.fcw_frames = 100 - ### STEER ### - + # STEER if (frame % P.STEER_STEP) == 0: lkas_enabled = enabled and not CS.out.steerWarning and CS.out.vEgo > P.MIN_STEER_SPEED if lkas_enabled: @@ -93,19 +76,13 @@ class CarController(): self.apply_steer_last = apply_steer idx = (frame // P.STEER_STEP) % 4 - can_sends.append(gmcan.create_steering_control(self.packer_pt, - CanBus.POWERTRAIN, apply_steer, idx, lkas_enabled)) - - ### GAS/BRAKE ### + can_sends.append(gmcan.create_steering_control(self.packer_pt, CanBus.POWERTRAIN, apply_steer, idx, lkas_enabled)) + # GAS/BRAKE # no output if not enabled, but keep sending keepalive messages # treat pedals as one final_pedal = actuators.gas - actuators.brake - # *** apply pedal hysteresis *** - final_brake, self.brake_steady = actuator_hystereses( - final_pedal, self.pedal_steady) - if not enabled: # Stock ECU sends max regen when not enabled. apply_gas = P.MAX_ACC_REGEN diff --git a/selfdrive/car/gm/interface.py b/selfdrive/car/gm/interface.py index 4dffa73c2b..6dda4f3a0a 100755 --- a/selfdrive/car/gm/interface.py +++ b/selfdrive/car/gm/interface.py @@ -16,7 +16,7 @@ class CarInterface(CarInterfaceBase): return float(accel) / 4.0 @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.carName = "gm" ret.safetyModel = car.CarParams.SafetyModel.gm # default to gm diff --git a/selfdrive/car/honda/interface.py b/selfdrive/car/honda/interface.py index b18252d579..aa315afd52 100755 --- a/selfdrive/car/honda/interface.py +++ b/selfdrive/car/honda/interface.py @@ -82,6 +82,10 @@ class CarInterface(CarInterfaceBase): else: self.compute_gb = compute_gb_honda + @staticmethod + def compute_gb(accel, speed): + raise NotImplementedError + @staticmethod 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) @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.carName = "honda" diff --git a/selfdrive/car/hyundai/interface.py b/selfdrive/car/hyundai/interface.py index 5b28d573b1..c38f54923d 100644 --- a/selfdrive/car/hyundai/interface.py +++ b/selfdrive/car/hyundai/interface.py @@ -12,7 +12,7 @@ class CarInterface(CarInterfaceBase): return float(accel) / 3.0 @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.carName = "hyundai" diff --git a/selfdrive/car/interfaces.py b/selfdrive/car/interfaces.py index a72024a138..db6b75319a 100644 --- a/selfdrive/car/interfaces.py +++ b/selfdrive/car/interfaces.py @@ -41,7 +41,7 @@ class CarInterfaceBase(): raise NotImplementedError @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 # returns a set of default params to avoid repetition in car specific params @@ -84,7 +84,7 @@ class CarInterfaceBase(): def apply(self, c): 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() if cs_out.doorOpen: diff --git a/selfdrive/car/mazda/interface.py b/selfdrive/car/mazda/interface.py index 2cd286b6ed..037b84e107 100755 --- a/selfdrive/car/mazda/interface.py +++ b/selfdrive/car/mazda/interface.py @@ -15,7 +15,7 @@ class CarInterface(CarInterfaceBase): return float(accel) / 4.0 @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.carName = "mazda" diff --git a/selfdrive/car/mock/interface.py b/selfdrive/car/mock/interface.py index b0474f8ce8..617f7e23d2 100755 --- a/selfdrive/car/mock/interface.py +++ b/selfdrive/car/mock/interface.py @@ -33,7 +33,7 @@ class CarInterface(CarInterfaceBase): return accel @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.carName = "mock" ret.safetyModel = car.CarParams.SafetyModel.noOutput diff --git a/selfdrive/car/nissan/interface.py b/selfdrive/car/nissan/interface.py index ebcfd573e7..cc9547aedd 100644 --- a/selfdrive/car/nissan/interface.py +++ b/selfdrive/car/nissan/interface.py @@ -14,7 +14,7 @@ class CarInterface(CarInterfaceBase): return float(accel) / 4.0 @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.carName = "nissan" diff --git a/selfdrive/car/subaru/interface.py b/selfdrive/car/subaru/interface.py index 328666d79c..a0cfdd0102 100644 --- a/selfdrive/car/subaru/interface.py +++ b/selfdrive/car/subaru/interface.py @@ -11,7 +11,7 @@ class CarInterface(CarInterfaceBase): return float(accel) / 4.0 @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.carName = "subaru" diff --git a/selfdrive/car/toyota/interface.py b/selfdrive/car/toyota/interface.py index 93bed7e989..9b9b46cf39 100755 --- a/selfdrive/car/toyota/interface.py +++ b/selfdrive/car/toyota/interface.py @@ -14,7 +14,7 @@ class CarInterface(CarInterfaceBase): return float(accel) / 3.0 @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.carName = "toyota" diff --git a/selfdrive/car/volkswagen/interface.py b/selfdrive/car/volkswagen/interface.py index 3632b7b0c9..3ec4b07000 100644 --- a/selfdrive/car/volkswagen/interface.py +++ b/selfdrive/car/volkswagen/interface.py @@ -19,7 +19,7 @@ class CarInterface(CarInterfaceBase): return float(accel) / 4.0 @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) # VW port is a community feature, since we don't own one to test diff --git a/selfdrive/controls/lib/events.py b/selfdrive/controls/lib/events.py index 2b21cd7171..413a402407 100644 --- a/selfdrive/controls/lib/events.py +++ b/selfdrive/controls/lib/events.py @@ -59,7 +59,10 @@ class Events: return True 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 = [] for e in self.events: types = EVENTS[e].keys() diff --git a/selfdrive/controls/lib/vehicle_model.py b/selfdrive/controls/lib/vehicle_model.py index 9959f82dc8..85acca54d9 100755 --- a/selfdrive/controls/lib/vehicle_model.py +++ b/selfdrive/controls/lib/vehicle_model.py @@ -1,7 +1,4 @@ #!/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" @@ -15,6 +12,8 @@ x_dot = A*x + B*u 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): diff --git a/selfdrive/controls/tests/test_events.py b/selfdrive/controls/tests/test_events.py index 3c5bc9d34b..ef41eea91e 100755 --- a/selfdrive/controls/tests/test_events.py +++ b/selfdrive/controls/tests/test_events.py @@ -9,8 +9,8 @@ from selfdrive.controls.lib.events import Alert, EVENTS AlertSize = log.ControlsState.AlertSize -class TestAlerts(unittest.TestCase): +class TestAlerts(unittest.TestCase): def test_events_defined(self): # Ensure all events in capnp schema are defined in events.py events = car.CarEvent.EventName.schema.enumerants @@ -34,9 +34,9 @@ class TestAlerts(unittest.TestCase): draw = ImageDraw.Draw(Image.new('RGB', (0, 0))) fonts = { - AlertSize.small: [ImageFont.truetype(semibold_font_path, int(40*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))], + AlertSize.small: [ImageFont.truetype(semibold_font_path, int(40 * 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))], } alerts = [] @@ -56,9 +56,10 @@ class TestAlerts(unittest.TestCase): break 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) self.assertLessEqual(w, max_text_width, msg=msg) + if __name__ == "__main__": unittest.main() diff --git a/selfdrive/crash.py b/selfdrive/crash.py index a24466622e..7459f71668 100644 --- a/selfdrive/crash.py +++ b/selfdrive/crash.py @@ -39,6 +39,12 @@ else: client.extra_context(kwargs) 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 __excepthook__ = sys.excepthook @@ -48,12 +54,6 @@ else: __excepthook__(*exc_info) 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__ def init(self, *args, **kwargs): diff --git a/selfdrive/debug/cpu_usage_stat.py b/selfdrive/debug/cpu_usage_stat.py index b18199885e..50307c228c 100755 --- a/selfdrive/debug/cpu_usage_stat.py +++ b/selfdrive/debug/cpu_usage_stat.py @@ -1,14 +1,5 @@ #!/usr/bin/env python3 # 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. 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% 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 PRINT_INTERVAL = 5 SLEEP_INTERVAL = 0.2 monitored_proc_names = [ - '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'] + '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'] cpu_time_names = ['user', 'system', 'children_user', 'children_system'] timer = getattr(time, 'monotonic', time.time) + def get_arg_parser(): parser = argparse.ArgumentParser( description="Unlogger and UI", diff --git a/selfdrive/debug/internal/sensor_test_bootloop.py b/selfdrive/debug/internal/sensor_test_bootloop.py index 5d0208d298..9e89add6bb 100755 --- a/selfdrive/debug/internal/sensor_test_bootloop.py +++ b/selfdrive/debug/internal/sensor_test_bootloop.py @@ -32,7 +32,7 @@ except Exception: sys.exit(-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: text = "Current run: SUCCESS\n" diff --git a/selfdrive/locationd/locationd.py b/selfdrive/locationd/locationd.py index 3798b3a456..959684e1b6 100755 --- a/selfdrive/locationd/locationd.py +++ b/selfdrive/locationd/locationd.py @@ -47,7 +47,10 @@ def get_H(): 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.reset_kalman() self.max_age = .2 # seconds @@ -279,7 +282,11 @@ class Localizer(): self.speed_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: socks = ['gpsLocationExternal', 'sensorEvents', 'cameraOdometry', 'liveCalibration', 'carState'] sm = messaging.SubMaster(socks, ignore_alive=['gpsLocationExternal']) diff --git a/selfdrive/locationd/models/car_kf.py b/selfdrive/locationd/models/car_kf.py index dda5cea1b2..ee409ecebc 100755 --- a/selfdrive/locationd/models/car_kf.py +++ b/selfdrive/locationd/models/car_kf.py @@ -12,6 +12,7 @@ from selfdrive.locationd.models.constants import ObservationKind i = 0 + def _slice(n): global i s = slice(i, i + n) @@ -48,7 +49,7 @@ class CarKalman(KalmanFilter): # process noise Q = np.diag([ - (.05/100)**2, + (.05 / 100)**2, .01**2, math.radians(0.02)**2, math.radians(0.25)**2, @@ -59,7 +60,7 @@ class CarKalman(KalmanFilter): ]) 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.ANGLE_OFFSET_FAST: np.atleast_2d(math.radians(10.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) - 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_err = self.P_initial.shape[0] x_init = self.initial_x diff --git a/selfdrive/locationd/models/gnss_kf.py b/selfdrive/locationd/models/gnss_kf.py index 59c3877e44..db1a7e81a5 100755 --- a/selfdrive/locationd/models/gnss_kf.py +++ b/selfdrive/locationd/models/gnss_kf.py @@ -76,14 +76,14 @@ class GNSSKalman(): # extra args sat_pos_freq_sym = sp.MatrixSymbol('sat_pos', 4, 1) sat_pos_vel_sym = sp.MatrixSymbol('sat_pos_vel', 6, 1) - sat_los_sym = sp.MatrixSymbol('sat_los', 3, 1) - orb_epos_sym = sp.MatrixSymbol('orb_epos_sym', 3, 1) + # sat_los_sym = sp.MatrixSymbol('sat_los', 3, 1) + # orb_epos_sym = sp.MatrixSymbol('orb_epos_sym', 3, 1) # expand extra args sat_x, sat_y, sat_z, glonass_freq = sat_pos_freq_sym sat_vx, sat_vy, sat_vz = sat_pos_vel_sym[3:] - los_x, los_y, los_z = sat_los_sym - orb_x, orb_y, orb_z = orb_epos_sym + # los_x, los_y, los_z = sat_los_sym + # orb_x, orb_y, orb_z = orb_epos_sym h_pseudorange_sym = sp.Matrix([ sp.sqrt( diff --git a/selfdrive/locationd/models/loc_kf.py b/selfdrive/locationd/models/loc_kf.py index 9b1329511d..421b0a64f9 100755 --- a/selfdrive/locationd/models/loc_kf.py +++ b/selfdrive/locationd/models/loc_kf.py @@ -252,13 +252,13 @@ class LocKalman(): # extra args sat_pos_freq_sym = sp.MatrixSymbol('sat_pos', 4, 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) # expand extra args sat_x, sat_y, sat_z, glonass_freq = sat_pos_freq_sym 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 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 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.max_tracks = max_tracks @@ -569,14 +569,14 @@ class LocKalman(): def maha_test_pseudorange(self, x, P, meas, kind, maha_thresh=.3): bools = [] - for i, m in enumerate(meas): + for m in meas: 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)) return np.array(bools) def maha_test_pseudorange_rate(self, x, P, meas, kind, maha_thresh=.999): bools = [] - for i, m in enumerate(meas): + for m in meas: 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)) return np.array(bools) diff --git a/selfdrive/locationd/test/ephemeris.py b/selfdrive/locationd/test/ephemeris.py index bca45c59e8..2793e3c62a 100644 --- a/selfdrive/locationd/test/ephemeris.py +++ b/selfdrive/locationd/test/ephemeris.py @@ -1,3 +1,5 @@ +import math + def GET_FIELD_U(w, nb, pos): return (((w) >> (pos)) & ((1 << (nb)) - 1)) @@ -35,7 +37,6 @@ on of this parser ''' def __init__(self, svId, subframes): - from math import pow self.svId = svId week_no = GET_FIELD_U(subframes[1][2+0], 10, 20) # code_on_l2 = GET_FIELD_U(subframes[1][0], 2, 12) @@ -84,30 +85,30 @@ on of this parser gpsPi = 3.1415926535898 # now form variables in radians, meters and seconds etc - self.Tgd = t_gd * pow(2, -31) - self.A = pow(a_powhalf * pow(2, -19), 2.0) - self.cic = c_ic * pow(2, -29) - self.cis = c_is * pow(2, -29) - self.crc = c_rc * pow(2, -5) - self.crs = c_rs * pow(2, -5) - self.cuc = c_uc * pow(2, -29) - self.cus = c_us * pow(2, -29) - self.deltaN = delta_n * pow(2, -43) * gpsPi - self.ecc = e * pow(2, -33) - self.i0 = i_0 * pow(2, -31) * gpsPi - self.idot = idot * pow(2, -43) * gpsPi - self.M0 = m_0 * pow(2, -31) * gpsPi - self.omega = w * pow(2, -31) * gpsPi - self.omega_dot = omega_dot * pow(2, -43) * gpsPi - self.omega0 = omega_0 * pow(2, -31) * gpsPi - self.toe = t_oe * pow(2, 4) + self.Tgd = t_gd * math.pow(2, -31) + self.A = math.pow(a_powhalf * math.pow(2, -19), 2.0) + self.cic = c_ic * math.pow(2, -29) + self.cis = c_is * math.pow(2, -29) + self.crc = c_rc * math.pow(2, -5) + self.crs = c_rs * math.pow(2, -5) + self.cuc = c_uc * math.pow(2, -29) + self.cus = c_us * math.pow(2, -29) + self.deltaN = delta_n * math.pow(2, -43) * gpsPi + self.ecc = e * math.pow(2, -33) + self.i0 = i_0 * math.pow(2, -31) * gpsPi + self.idot = idot * math.pow(2, -43) * gpsPi + self.M0 = m_0 * math.pow(2, -31) * gpsPi + self.omega = w * math.pow(2, -31) * gpsPi + self.omega_dot = omega_dot * math.pow(2, -43) * gpsPi + self.omega0 = omega_0 * math.pow(2, -31) * gpsPi + self.toe = t_oe * math.pow(2, 4) # clock correction information - self.toc = t_oc * pow(2, 4) + self.toc = t_oc * math.pow(2, 4) self.gpsWeek = week_no - self.af0 = a_f0 * pow(2, -31) - self.af1 = a_f1 * pow(2, -43) - self.af2 = a_f2 * pow(2, -55) + self.af0 = a_f0 * math.pow(2, -31) + self.af1 = a_f1 * math.pow(2, -43) + self.af2 = a_f2 * math.pow(2, -55) iode1 = GET_FIELD_U(subframes[2][2+0], 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 \ GET_FIELD_U(subframes[4][2+0], 2, 28) == 1 and \ GET_FIELD_U(subframes[5][2+0], 2, 28) == 1: - a0 = GET_FIELD_S(subframes[4][2], 8, 14) * pow(2, -30) - a1 = GET_FIELD_S(subframes[4][2], 8, 6) * pow(2, -27) - a2 = GET_FIELD_S(subframes[4][3], 8, 22) * pow(2, -24) - a3 = GET_FIELD_S(subframes[4][3], 8, 14) * pow(2, -24) - b0 = GET_FIELD_S(subframes[4][3], 8, 6) * pow(2, 11) - b1 = GET_FIELD_S(subframes[4][4], 8, 22) * pow(2, 14) - b2 = GET_FIELD_S(subframes[4][4], 8, 14) * pow(2, 16) - b3 = GET_FIELD_S(subframes[4][4], 8, 6) * pow(2, 16) + a0 = GET_FIELD_S(subframes[4][2], 8, 14) * math.pow(2, -30) + a1 = GET_FIELD_S(subframes[4][2], 8, 6) * math.pow(2, -27) + a2 = GET_FIELD_S(subframes[4][3], 8, 22) * math.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) * math.pow(2, 11) + b1 = GET_FIELD_S(subframes[4][4], 8, 22) * math.pow(2, 14) + b2 = GET_FIELD_S(subframes[4][4], 8, 14) * math.pow(2, 16) + b3 = GET_FIELD_S(subframes[4][4], 8, 6) * math.pow(2, 16) self.ionoAlpha = [a0, a1, a2, a3] self.ionoBeta = [b0, b1, b2, b3] diff --git a/selfdrive/locationd/test/test_params_learner.py b/selfdrive/locationd/test/test_params_learner.py index bd2399b24b..df0e851cd7 100755 --- a/selfdrive/locationd/test/test_params_learner.py +++ b/selfdrive/locationd/test/test_params_learner.py @@ -31,7 +31,7 @@ class TestParamsLearner(unittest.TestCase): steering_angles = np.radians(10 * np.sin(2 * np.pi * times / 100.)) + angle_offset speeds = 10 * np.sin(2 * np.pi * times / 1000.) + 25 - for i, t in enumerate(times): + for i, _ in enumerate(times): u = speeds[i] sa = steering_angles[i] psi = VM_sim.yaw_rate(sa - angle_offset, u) diff --git a/selfdrive/locationd/test/ublox.py b/selfdrive/locationd/test/ublox.py index 8120f70fd2..6a28edb1aa 100644 --- a/selfdrive/locationd/test/ublox.py +++ b/selfdrive/locationd/test/ublox.py @@ -1,4 +1,5 @@ #!/usr/bin/env python3 +# pylint: skip-file ''' UBlox binary protocol handling diff --git a/selfdrive/locationd/test/ubloxd.py b/selfdrive/locationd/test/ubloxd.py index 6d858c9ecf..314c80237f 100755 --- a/selfdrive/locationd/test/ubloxd.py +++ b/selfdrive/locationd/test/ubloxd.py @@ -1,5 +1,6 @@ #!/usr/bin/env python3 # type: ignore +# pylint: skip-file import os import serial diff --git a/selfdrive/loggerd/tests/test_deleter.py b/selfdrive/loggerd/tests/test_deleter.py index f06946b2fe..89904e694a 100644 --- a/selfdrive/loggerd/tests/test_deleter.py +++ b/selfdrive/loggerd/tests/test_deleter.py @@ -23,9 +23,6 @@ class TestDeleter(UploaderTestCase): deleter.os.statvfs = self.fake_statvfs deleter.ROOT = self.root - def tearDown(self): - super(TestDeleter, self).tearDown() - def start_thread(self): self.end_event = threading.Event() self.del_thread = threading.Thread(target=deleter.deleter_thread, args=[self.end_event]) diff --git a/selfdrive/loggerd/tests/test_uploader.py b/selfdrive/loggerd/tests/test_uploader.py index 3df3d937ac..4a44f80b5c 100644 --- a/selfdrive/loggerd/tests/test_uploader.py +++ b/selfdrive/loggerd/tests/test_uploader.py @@ -38,9 +38,6 @@ class TestUploader(UploaderTestCase): super(TestUploader, self).setUp() log_handler.reset() - def tearDown(self): - super(TestUploader, self).tearDown() - def start_thread(self): self.end_event = threading.Event() self.up_thread = threading.Thread(target=uploader.uploader_fn, args=[self.end_event]) diff --git a/selfdrive/loggerd/uploader.py b/selfdrive/loggerd/uploader.py index b3b25a2610..b479574b02 100644 --- a/selfdrive/loggerd/uploader.py +++ b/selfdrive/loggerd/uploader.py @@ -25,6 +25,7 @@ UPLOAD_ATTR_VALUE = b'1' fake_upload = os.getenv("FAKEUPLOAD") is not None def raise_on_thread(t, exctype): + '''Raises an exception in the threads with id tid''' for ctid, tobj in threading._active.items(): if tobj is t: tid = ctid @@ -32,7 +33,6 @@ def raise_on_thread(t, exctype): else: raise Exception("Could not find thread") - '''Raises an exception in the threads with id tid''' if not inspect.isclass(exctype): raise TypeError("Only types can be raised (not instances)") diff --git a/selfdrive/manager.py b/selfdrive/manager.py index c3ca373372..bee1dacb4c 100755 --- a/selfdrive/manager.py +++ b/selfdrive/manager.py @@ -305,11 +305,11 @@ def start_daemon_process(name): pass cloudlog.info("starting daemon %s" % name) - proc = subprocess.Popen(['python', '-m', proc], - stdin=open('/dev/null', 'r'), - stdout=open('/dev/null', 'w'), - stderr=open('/dev/null', 'w'), - preexec_fn=os.setpgrp) + proc = subprocess.Popen(['python', '-m', proc], # pylint: disable=subprocess-popen-preexec-fn + stdin=open('/dev/null', 'r'), + stdout=open('/dev/null', 'w'), + stderr=open('/dev/null', 'w'), + preexec_fn=os.setpgrp) params.put(pid_param, str(proc.pid)) @@ -590,8 +590,6 @@ def main(): try: manager_thread() - except SystemExit: - raise except Exception: traceback.print_exc() crash.capture_exception() diff --git a/selfdrive/modeld/runners/keras_runner.py b/selfdrive/modeld/runners/keras_runner.py index 33d4322732..c692ac5988 100755 --- a/selfdrive/modeld/runners/keras_runner.py +++ b/selfdrive/modeld/runners/keras_runner.py @@ -10,19 +10,22 @@ import numpy as np from tensorflow.keras.models import Model # pylint: disable=import-error from tensorflow.keras.models import load_model # pylint: disable=import-error + def read(sz): dd = [] gt = 0 - while gt < sz*4: - st = os.read(0, sz*4 - gt) + while gt < sz * 4: + st = os.read(0, sz * 4 - gt) assert(len(st) > 0) dd.append(st) gt += len(st) return np.fromstring(b''.join(dd), dtype=np.float32) + def write(d): os.write(1, d.tobytes()) + def run_loop(m): isize = m.inputs[0].shape[1] osize = m.outputs[0].shape[1] @@ -32,6 +35,7 @@ def run_loop(m): ret = m.predict_on_batch(idata) write(ret) + if __name__ == "__main__": print(tf.__version__, file=sys.stderr) # limit gram alloc @@ -48,7 +52,7 @@ if __name__ == "__main__": acc = 0 for i, ii in enumerate(m.inputs): 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] tr = keras.layers.Reshape(ii.shape[1:])(ti) tii.append(tr) diff --git a/selfdrive/modeld/visiontest.py b/selfdrive/modeld/visiontest.py index 72dbe59acc..6f97684244 100644 --- a/selfdrive/modeld/visiontest.py +++ b/selfdrive/modeld/visiontest.py @@ -8,11 +8,12 @@ _visiond_dir = os.path.dirname(os.path.abspath(__file__)) _libvisiontest = "libvisiontest.so" try: # bacause this crashes somtimes when running pipeline subprocess.check_output(["make", "-C", _visiond_dir, "-f", - os.path.join(_visiond_dir, "visiontest.mk"), - _libvisiontest]) + os.path.join(_visiond_dir, "visiontest.mk"), + _libvisiontest]) except Exception: pass + class VisionTest(): """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, 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 from_buffer = self.ffi.from_buffer @@ -126,7 +127,7 @@ class VisionTest(): def __enter__(self): return self - def __exit__(self, type, value, traceback): + def __exit__(self, exc_type, exc_value, traceback): self.close() diff --git a/selfdrive/test/longitudinal_maneuvers/test_longitudinal.py b/selfdrive/test/longitudinal_maneuvers/test_longitudinal.py index a7fb64b224..24f5015bd2 100755 --- a/selfdrive/test/longitudinal_maneuvers/test_longitudinal.py +++ b/selfdrive/test/longitudinal_maneuvers/test_longitudinal.py @@ -24,20 +24,23 @@ def create_dir(path): def check_no_collision(log): return min(log['d_rel']) > 0 + def check_fcw(log): return any(log['fcw']) + def check_engaged(log): return log['controls_state_msgs'][-1][-1].active + maneuvers = [ Maneuver( 'while cruising at 40 mph, change cruise speed to 50mph', duration=30., initial_speed=40. * CV.MPH_TO_MS, cruise_button_presses=[(CB.DECEL_SET, 2.), (0, 2.3), - (CB.RES_ACCEL, 10.), (0, 10.1), - (CB.RES_ACCEL, 10.2), (0, 10.3)], + (CB.RES_ACCEL, 10.), (0, 10.1), + (CB.RES_ACCEL, 10.2), (0, 10.3)], checks=[check_engaged], ), Maneuver( @@ -45,8 +48,8 @@ maneuvers = [ duration=30., initial_speed=60. * CV.MPH_TO_MS, cruise_button_presses=[(CB.DECEL_SET, 2.), (0, 2.3), - (CB.DECEL_SET, 10.), (0, 10.1), - (CB.DECEL_SET, 10.2), (0, 10.3)], + (CB.DECEL_SET, 10.), (0, 10.1), + (CB.DECEL_SET, 10.2), (0, 10.3)], checks=[check_engaged], ), Maneuver( @@ -73,7 +76,7 @@ maneuvers = [ initial_speed=60. * CV.MPH_TO_MS, lead_relevancy=True, 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.], cruise_button_presses=[(CB.DECEL_SET, 1.2), (0, 1.3)], checks=[check_engaged, check_no_collision], @@ -84,7 +87,7 @@ maneuvers = [ initial_speed=40. * CV.MPH_TO_MS, lead_relevancy=True, 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.], cruise_button_presses=[(CB.DECEL_SET, 1.2), (0, 1.3)], checks=[check_engaged, check_no_collision], @@ -140,9 +143,9 @@ maneuvers = [ lead_relevancy=True, initial_distance_lead=100., cruise_button_presses=[(CB.DECEL_SET, 1.2), (0, 1.3), - (CB.RES_ACCEL, 1.4), (0.0, 1.5), - (CB.RES_ACCEL, 1.6), (0.0, 1.7), - (CB.RES_ACCEL, 1.8), (0.0, 1.9)], + (CB.RES_ACCEL, 1.4), (0.0, 1.5), + (CB.RES_ACCEL, 1.6), (0.0, 1.7), + (CB.RES_ACCEL, 1.8), (0.0, 1.9)], checks=[check_engaged, check_no_collision], ), Maneuver( @@ -154,8 +157,8 @@ maneuvers = [ speed_lead_values=[30., 30., 29., 31., 29., 31., 29.], speed_lead_breakpoints=[0., 6., 8., 12., 16., 20., 24.], cruise_button_presses=[(CB.DECEL_SET, 1.2), (0, 1.3), - (CB.RES_ACCEL, 1.4), (0.0, 1.5), - (CB.RES_ACCEL, 1.6), (0.0, 1.7)], + (CB.RES_ACCEL, 1.4), (0.0, 1.5), + (CB.RES_ACCEL, 1.6), (0.0, 1.7)], checks=[check_engaged, check_no_collision], ), Maneuver( @@ -167,8 +170,8 @@ maneuvers = [ speed_lead_values=[10., 0., 0., 10., 0., 10.], speed_lead_breakpoints=[10., 20., 30., 40., 50., 60.], cruise_button_presses=[(CB.DECEL_SET, 1.2), (0, 1.3), - (CB.RES_ACCEL, 1.4), (0.0, 1.5), - (CB.RES_ACCEL, 1.6), (0.0, 1.7)], + (CB.RES_ACCEL, 1.4), (0.0, 1.5), + (CB.RES_ACCEL, 1.6), (0.0, 1.7)], checks=[check_engaged, check_no_collision], ), Maneuver( @@ -177,14 +180,14 @@ maneuvers = [ initial_speed=0., lead_relevancy=True, initial_distance_lead=4., - speed_lead_values=[0, 0 , 45], + speed_lead_values=[0, 0, 45], speed_lead_breakpoints=[0, 10., 40.], cruise_button_presses=[(CB.DECEL_SET, 1.2), (0, 1.3), - (CB.RES_ACCEL, 1.4), (0.0, 1.5), - (CB.RES_ACCEL, 1.6), (0.0, 1.7), - (CB.RES_ACCEL, 1.8), (0.0, 1.9), - (CB.RES_ACCEL, 2.0), (0.0, 2.1), - (CB.RES_ACCEL, 2.2), (0.0, 2.3)], + (CB.RES_ACCEL, 1.4), (0.0, 1.5), + (CB.RES_ACCEL, 1.6), (0.0, 1.7), + (CB.RES_ACCEL, 1.8), (0.0, 1.9), + (CB.RES_ACCEL, 2.0), (0.0, 2.1), + (CB.RES_ACCEL, 2.2), (0.0, 2.3)], checks=[check_engaged, check_no_collision], ), Maneuver( @@ -193,11 +196,11 @@ maneuvers = [ initial_speed=0., lead_relevancy=True, 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.], cruise_button_presses=[(CB.DECEL_SET, 1.2), (0, 1.3), - (CB.RES_ACCEL, 1.4), (0.0, 1.5), - (CB.RES_ACCEL, 1.6), (0.0, 1.7)], + (CB.RES_ACCEL, 1.4), (0.0, 1.5), + (CB.RES_ACCEL, 1.6), (0.0, 1.7)], checks=[check_engaged, check_no_collision], ), Maneuver( @@ -206,11 +209,11 @@ maneuvers = [ initial_speed=0., lead_relevancy=True, 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.], cruise_button_presses=[(CB.DECEL_SET, 1.2), (0, 1.3), - (CB.RES_ACCEL, 1.4), (0.0, 1.5), - (CB.RES_ACCEL, 1.6), (0.0, 1.7)], + (CB.RES_ACCEL, 1.4), (0.0, 1.5), + (CB.RES_ACCEL, 1.6), (0.0, 1.7)], checks=[check_engaged, check_no_collision], ), Maneuver( @@ -222,11 +225,11 @@ maneuvers = [ speed_lead_values=[20., 10.], speed_lead_breakpoints=[1., 11.], cruise_button_presses=[(CB.DECEL_SET, 1.2), (0, 1.3), - (CB.RES_ACCEL, 1.4), (0.0, 1.5), - (CB.RES_ACCEL, 1.6), (0.0, 1.7), - (CB.RES_ACCEL, 1.8), (0.0, 1.9), - (CB.RES_ACCEL, 2.0), (0.0, 2.1), - (CB.RES_ACCEL, 2.2), (0.0, 2.3)], + (CB.RES_ACCEL, 1.4), (0.0, 1.5), + (CB.RES_ACCEL, 1.6), (0.0, 1.7), + (CB.RES_ACCEL, 1.8), (0.0, 1.9), + (CB.RES_ACCEL, 2.0), (0.0, 2.1), + (CB.RES_ACCEL, 2.2), (0.0, 2.3)], checks=[check_engaged, check_no_collision], ), Maneuver( @@ -238,11 +241,11 @@ maneuvers = [ speed_lead_values=[20., 0.], speed_lead_breakpoints=[1., 11.], cruise_button_presses=[(CB.DECEL_SET, 1.2), (0, 1.3), - (CB.RES_ACCEL, 1.4), (0.0, 1.5), - (CB.RES_ACCEL, 1.6), (0.0, 1.7), - (CB.RES_ACCEL, 1.8), (0.0, 1.9), - (CB.RES_ACCEL, 2.0), (0.0, 2.1), - (CB.RES_ACCEL, 2.2), (0.0, 2.3)], + (CB.RES_ACCEL, 1.4), (0.0, 1.5), + (CB.RES_ACCEL, 1.6), (0.0, 1.7), + (CB.RES_ACCEL, 1.8), (0.0, 1.9), + (CB.RES_ACCEL, 2.0), (0.0, 2.1), + (CB.RES_ACCEL, 2.2), (0.0, 2.3)], checks=[check_engaged, check_no_collision], ), Maneuver( @@ -291,8 +294,6 @@ maneuvers = [ ) ] -# maneuvers = [maneuvers[-11]] -# maneuvers = [maneuvers[6]] def setup_output(): output_dir = os.path.join(os.getcwd(), 'out/longitudinal') @@ -313,13 +314,14 @@ def setup_output(): for i, man in enumerate(maneuvers): view_html += "