From d09a411cb4589a9b411cabf4eefb86a3b5f38686 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Harald=20Sch=C3=A4fer?= Date: Tue, 2 Jun 2026 16:35:40 -0700 Subject: [PATCH 001/151] Refactor compile_modeld model setup (#38128) --- selfdrive/modeld/compile_modeld.py | 71 ++++++++++++++++++------------ 1 file changed, 42 insertions(+), 29 deletions(-) diff --git a/selfdrive/modeld/compile_modeld.py b/selfdrive/modeld/compile_modeld.py index 2f91076ab7..a7298705ef 100755 --- a/selfdrive/modeld/compile_modeld.py +++ b/selfdrive/modeld/compile_modeld.py @@ -5,7 +5,7 @@ import os import pickle import time from functools import partial -from collections import namedtuple, defaultdict +from collections import namedtuple import numpy as np @@ -113,31 +113,43 @@ def make_frame_prepare(nv12: NV12Frame, model_w, model_h): return frame_prepare_tinygrad -def make_input_queues(vision_input_shapes, policy_input_shapes, frame_skip, device): +def make_warp_input_queues(vision_input_shapes, frame_skip, device): img = vision_input_shapes['img'] # (1, 12, 128, 256) n_frames = img[1] // 6 img_buf_shape = (frame_skip * (n_frames - 1) + 1, 6, img[2], img[3]) + npy = { + 'tfm': np.zeros((3, 3), dtype=np.float32), + 'big_tfm': np.zeros((3, 3), dtype=np.float32), + } + input_queues = { + 'img_q': Tensor(np.zeros(img_buf_shape, dtype=np.uint8), device=device).contiguous().realize(), + 'big_img_q': Tensor(np.zeros(img_buf_shape, dtype=np.uint8), device=device).contiguous().realize(), + **{k: Tensor(v, device='NPY').realize() for k, v in npy.items()}, + } + return input_queues, npy + + +def make_input_queues(vision_input_shapes, policy_input_shapes, frame_skip, device): + input_queues, npy = make_warp_input_queues(vision_input_shapes, frame_skip, device) + fb = policy_input_shapes['features_buffer'] # (1, 25, 512) dp = policy_input_shapes['desire_pulse'] # (1, 25, 8) tc = policy_input_shapes['traffic_convention'] # (1, 2) #TODO action_t is hardcoded to match tc for future compatibility at = tc - npy = { + policy_npy = { 'desire': np.zeros(dp[2], dtype=np.float32), 'traffic_convention': np.zeros(tc, dtype=np.float32), - 'tfm': np.zeros((3, 3), dtype=np.float32), - 'big_tfm': np.zeros((3, 3), dtype=np.float32), 'action_t': np.zeros(at, dtype=np.float32), } - input_queues = { - 'img_q': Tensor(np.zeros(img_buf_shape, dtype=np.uint8), device=device).contiguous().realize(), - 'big_img_q': Tensor(np.zeros(img_buf_shape, dtype=np.uint8), device=device).contiguous().realize(), + npy.update(policy_npy) + input_queues.update({ 'feat_q': Tensor(np.zeros((frame_skip * (fb[1] - 1) + 1, fb[0], fb[2]), dtype=np.float32), device=device).contiguous().realize(), 'desire_q': Tensor(np.zeros((frame_skip * dp[1], dp[0], dp[2]), dtype=np.float32), device=device).contiguous().realize(), - **{k: Tensor(v, device='NPY').realize() for k, v in npy.items()}, - } + **{k: Tensor(v, device='NPY').realize() for k, v in policy_npy.items()}, + }) return input_queues, npy @@ -171,9 +183,10 @@ def make_warp(nv12, model_w, model_h, frame_skip): return warp_enqueue -def make_run_policy(vision_runner, on_policy_runner, vision_features_slice, frame_skip): +def make_run_policy(model_runners, model_metadata, frame_skip): sample_desire_fn = partial(sample_desire, frame_skip=frame_skip) sample_skip_fn = partial(sample_skip, frame_skip=frame_skip) + vision_features_slice = model_metadata['vision']['output_slices']['hidden_state'] def run_policy(img, big_img, feat_q, desire_q, desire, traffic_convention, action_t): desire = desire.to(Device.DEFAULT) @@ -181,7 +194,7 @@ def make_run_policy(vision_runner, on_policy_runner, vision_features_slice, fram action_t = action_t.to(Device.DEFAULT) Tensor.realize(desire, traffic_convention, action_t) desire_buf = shift_and_sample(desire_q, desire.reshape(1, 1, -1), sample_desire_fn) - vision_out = next(iter(vision_runner({'img': img, 'big_img': big_img}).values())).cast('float32') + vision_out = next(iter(model_runners['vision']({'img': img, 'big_img': big_img}).values())).cast('float32') new_feat = vision_out[:, vision_features_slice].reshape(1, -1).unsqueeze(0) feat_buf = shift_and_sample(feat_q, new_feat, sample_skip_fn) @@ -192,20 +205,16 @@ def make_run_policy(vision_runner, on_policy_runner, vision_features_slice, fram 'traffic_convention': traffic_convention, 'action_t': action_t, } - on_policy_out = next(iter(on_policy_runner(inputs).values())).cast('float32') + on_policy_out = next(iter(model_runners['on_policy'](inputs).values())).cast('float32') #off_policy_out = next(iter(off_policy_runner(inputs).values())).cast('float32') return vision_out, on_policy_out - return run_policy -def compile_jit(jit, make_random_inputs, input_keys, frame_skip, vision_metadata, policy_metadata): - vision_input_shapes = vision_metadata['input_shapes'] - policy_input_shapes = policy_metadata['input_shapes'] - +def compile_jit(jit, make_random_inputs, input_keys, make_queues): SEED = 42 def random_inputs_run(fn, seed, test_val=None, test_buffers=None, expect_match=True): - input_queues, npy = make_input_queues(vision_input_shapes, policy_input_shapes, frame_skip, Device.DEFAULT) + input_queues, npy = make_queues(Device.DEFAULT) np.random.seed(seed) Tensor.manual_seed(seed) @@ -274,25 +283,29 @@ if __name__ == "__main__": p.add_argument('--frame-skip', type=int, required=True) args = p.parse_args() - out = defaultdict(dict) - vision_path, on_policy_path = read_file_chunked_to_shm(args.vision_onnx), read_file_chunked_to_shm(args.on_policy_onnx) + model_paths = { + 'vision': read_file_chunked_to_shm(args.vision_onnx), + 'on_policy': read_file_chunked_to_shm(args.on_policy_onnx), + } model_w, model_h = args.model_size - vision_runner = OnnxRunner(vision_path) - on_policy_runner = OnnxRunner(on_policy_path) - vision_metadata, on_policy_metadata = make_metadata_dict(vision_path), make_metadata_dict(on_policy_path) + model_runners = {name: OnnxRunner(path) for name, path in model_paths.items()} + out = {'metadata': {name: make_metadata_dict(path) for name, path in model_paths.items()}} - run_policy_jit = TinyJit(make_run_policy(vision_runner, on_policy_runner, vision_metadata['output_slices']['hidden_state'], args.frame_skip), prune=True) - out['metadata']['vision'], out['metadata']['on_policy'] = vision_metadata, on_policy_metadata + run_policy_jit = TinyJit(make_run_policy(model_runners, out['metadata'], args.frame_skip), prune=True) - make_random_model_inputs = partial(make_random_images, keys=['img', 'big_img'], shape=vision_metadata['input_shapes']['img']) - out['run_policy'] = compile_jit(run_policy_jit, make_random_model_inputs, POLICY_INPUTS, args.frame_skip, vision_metadata, on_policy_metadata) + make_policy_queues = partial(make_input_queues, out['metadata']['vision']['input_shapes'], + out['metadata']['on_policy']['input_shapes'], args.frame_skip) + make_random_model_inputs = partial(make_random_images, keys=['img', 'big_img'], shape=out['metadata']['vision']['input_shapes']['img']) + out['run_policy'] = compile_jit(run_policy_jit, make_random_model_inputs, POLICY_INPUTS, + make_policy_queues) for cam_w, cam_h in args.camera_resolutions: nv12 = NV12Frame(cam_w, cam_h, *get_nv12_info(cam_w, cam_h)) make_random_warp_inputs = partial(make_random_images, keys=['frame', 'big_frame'], shape=nv12.size, device=WARP_DEV) warp_enqueue = TinyJit(make_warp(nv12, model_w, model_h, args.frame_skip), prune=True) - out[(cam_w,cam_h)] = compile_jit(warp_enqueue, make_random_warp_inputs, WARP_INPUTS, args.frame_skip, vision_metadata, on_policy_metadata) + make_warp_queues = partial(make_warp_input_queues, out['metadata']['vision']['input_shapes'], args.frame_skip) + out[(cam_w,cam_h)] = compile_jit(warp_enqueue, make_random_warp_inputs, WARP_INPUTS, make_warp_queues) with open(args.output, "wb") as f: pickle.dump(out, f) From 866cd01f32d073b298ee8fc1d1984387ebd8435e Mon Sep 17 00:00:00 2001 From: stef <19478336+stefpi@users.noreply.github.com> Date: Tue, 2 Jun 2026 21:07:12 -0400 Subject: [PATCH 002/151] webrtc: initialize on medium bitrate (#38129) initialize on medium quality --- system/webrtc/webrtcd.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/system/webrtc/webrtcd.py b/system/webrtc/webrtcd.py index aac020dd06..38c30862f8 100755 --- a/system/webrtc/webrtcd.py +++ b/system/webrtc/webrtcd.py @@ -144,7 +144,8 @@ class LivestreamBitrateController(AsyncTaskRunner): self.pc = peer_connection self.params = Params() - self.level = 0 + self.level = 1 + self._publish(self.bitrates[self.level]) self.prev_lost, self.prev_sent = None, None self.counter = 0 self.up_samples = 5 # 1s From 5b3d5f74ed6606fcc280f5e79695d846fcedc48d Mon Sep 17 00:00:00 2001 From: Daniel Koepping Date: Tue, 2 Jun 2026 19:23:31 -0700 Subject: [PATCH 003/151] test models: add VW MEB angle exception (#38119) * add vw meb exception * comment --- selfdrive/car/tests/test_models.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/selfdrive/car/tests/test_models.py b/selfdrive/car/tests/test_models.py index 6171d02b5e..62ddadef8f 100644 --- a/selfdrive/car/tests/test_models.py +++ b/selfdrive/car/tests/test_models.py @@ -427,8 +427,9 @@ class TestCarModelBase(unittest.TestCase): v_ego_raw < (self.safety.get_vehicle_speed_min() - 1e-3)) # check steering angle for angle control cars (panda stores angle_meas in CAN units) - # ford excluded since it tracks curvature, not steering angle - if self.CP.steerControlType == SteerControlType.angle and not self.CP.notCar and self.CP.brand != "ford": + # ford and VW MEB excluded since they track curvature, not steering angle + # TODO: add curvature check, standardize CAN units to rm brand specific ANGLE_DEG_TO_CAN + if self.CP.steerControlType == SteerControlType.angle and not self.CP.notCar and self.CP.brand not in ("ford", "volkswagen"): angle_can = (CS.steeringAngleDeg + CS.steeringAngleOffsetDeg) * ANGLE_DEG_TO_CAN[self.CP.brand] checks['steeringAngleDeg'] += (angle_can > (self.safety.get_angle_meas_max() + 1) or angle_can < (self.safety.get_angle_meas_min() - 1)) From f02d134f40f5e7be22b182af21b438915a47600e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Harald=20Sch=C3=A4fer?= Date: Wed, 3 Jun 2026 12:48:58 -0700 Subject: [PATCH 004/151] Op model16 deep (#38073) * modeld: RL driving model with 3-file split Split the driving model into vision + off_policy + on_policy ONNX files and wire up the RL policy: - 3-file model split (vision / off_policy / on_policy), replacing the combined big_driving_policy/vision models - compiler updates for the split models - actually consume the policy action in modeld - add desire state to the driving model - model iterations (smoothness, off/on-policy weight updates) * modeld: update driving model * 1e72cf5a-785f-45ea-888f-28cdb14785de/100 * tinygrad hack * fix parsing * looser timing * big * Remove unnecessary modeld rebase changes * Tighten modeld split cleanup --------- Co-authored-by: Comma Device Co-authored-by: Armandpl --- selfdrive/modeld/SConscript | 3 ++- selfdrive/modeld/compile_modeld.py | 8 ++++++-- selfdrive/modeld/modeld.py | 13 +++++++++---- .../modeld/models/big_driving_off_policy.onnx | 3 +++ selfdrive/modeld/models/big_driving_on_policy.onnx | 4 ++-- selfdrive/modeld/models/big_driving_vision.onnx | 4 ++-- selfdrive/modeld/models/driving_off_policy.onnx | 3 +++ selfdrive/modeld/models/driving_on_policy.onnx | 4 ++-- selfdrive/modeld/models/driving_vision.onnx | 4 ++-- selfdrive/modeld/parse_model_outputs.py | 14 ++++++++++---- selfdrive/test/process_replay/model_replay.py | 2 +- system/hardware/tici/tests/test_power_draw.py | 2 +- tinygrad_repo | 2 +- 13 files changed, 44 insertions(+), 22 deletions(-) create mode 100644 selfdrive/modeld/models/big_driving_off_policy.onnx create mode 100644 selfdrive/modeld/models/driving_off_policy.onnx diff --git a/selfdrive/modeld/SConscript b/selfdrive/modeld/SConscript index 80a7df4515..c13842115d 100644 --- a/selfdrive/modeld/SConscript +++ b/selfdrive/modeld/SConscript @@ -87,13 +87,14 @@ frame_skip = ModelConstants.MODEL_RUN_FREQ // ModelConstants.MODEL_CONTEXT_FREQ for usbgpu in [False, True] if USBGPU else [False]: target_pkl_path = File(modeld_pkl_path(usbgpu)).abspath file_prefix, cmd_flags = ('big_', usbgpu_tg_flags) if usbgpu else ('', tg_flags) - driving_onnx_deps = [p for m in [f'{file_prefix}driving_vision', f'{file_prefix}driving_on_policy'] + driving_onnx_deps = [p for m in [f'{file_prefix}driving_vision', f'{file_prefix}driving_on_policy', f'{file_prefix}driving_off_policy'] for p in get_existing_chunks(File(f"models/{m}.onnx").abspath)] camera_res_args = ' '.join(f'{cw}x{ch}' for cw, ch in CAMERA_CONFIGS) cmd = (f'{cmd_flags} {mac_brew_string} python3 {modeld_dir}/compile_modeld.py ' f'--model-size {model_w}x{model_h} ' f'--camera-resolutions {camera_res_args} ' f'--vision-onnx {File(f"models/{file_prefix}driving_vision.onnx").abspath} ' + f'--off-policy-onnx {File(f"models/{file_prefix}driving_off_policy.onnx").abspath} ' f'--on-policy-onnx {File(f"models/{file_prefix}driving_on_policy.onnx").abspath} ' f'--output {target_pkl_path} --frame-skip {frame_skip}') onnx_sizes_sum = sum(os.path.getsize(f) for f in driving_onnx_deps) diff --git a/selfdrive/modeld/compile_modeld.py b/selfdrive/modeld/compile_modeld.py index a7298705ef..8d6058f39d 100755 --- a/selfdrive/modeld/compile_modeld.py +++ b/selfdrive/modeld/compile_modeld.py @@ -206,8 +206,8 @@ def make_run_policy(model_runners, model_metadata, frame_skip): 'action_t': action_t, } on_policy_out = next(iter(model_runners['on_policy'](inputs).values())).cast('float32') - #off_policy_out = next(iter(off_policy_runner(inputs).values())).cast('float32') - return vision_out, on_policy_out + off_policy_out = next(iter(model_runners['off_policy'](inputs).values())).cast('float32') + return vision_out, on_policy_out, off_policy_out return run_policy @@ -278,6 +278,7 @@ if __name__ == "__main__": p.add_argument('--camera-resolutions', type=_parse_size, nargs='+', required=True, help='camera resolutions WxH (one or more)') p.add_argument('--vision-onnx', required=True) + p.add_argument('--off-policy-onnx', required=True) p.add_argument('--on-policy-onnx', required=True) p.add_argument('--output', required=True) p.add_argument('--frame-skip', type=int, required=True) @@ -285,6 +286,7 @@ if __name__ == "__main__": model_paths = { 'vision': read_file_chunked_to_shm(args.vision_onnx), + 'off_policy': read_file_chunked_to_shm(args.off_policy_onnx), 'on_policy': read_file_chunked_to_shm(args.on_policy_onnx), } model_w, model_h = args.model_size @@ -292,6 +294,8 @@ if __name__ == "__main__": model_runners = {name: OnnxRunner(path) for name, path in model_paths.items()} out = {'metadata': {name: make_metadata_dict(path) for name, path in model_paths.items()}} + assert out['metadata']['off_policy']['input_shapes'] == out['metadata']['on_policy']['input_shapes'] + run_policy_jit = TinyJit(make_run_policy(model_runners, out['metadata'], args.frame_skip), prune=True) make_policy_queues = partial(make_input_queues, out['metadata']['vision']['input_shapes'], diff --git a/selfdrive/modeld/modeld.py b/selfdrive/modeld/modeld.py index 682633b02f..338f26b598 100755 --- a/selfdrive/modeld/modeld.py +++ b/selfdrive/modeld/modeld.py @@ -84,6 +84,9 @@ class ModelState: self.vision_input_names = list(self.vision_input_shapes.keys()) self.vision_output_slices = vision_metadata['output_slices'] + off_policy_metadata = jits['metadata']['off_policy'] + self.off_policy_output_slices = off_policy_metadata['output_slices'] + policy_metadata = jits['metadata']['on_policy'] self.policy_input_shapes = policy_metadata['input_shapes'] self.policy_output_slices = policy_metadata['output_slices'] @@ -128,18 +131,20 @@ class ModelState: if prepare_only: return None - vision_output, on_policy_output = self.run_policy( - **{k: self.input_queues[k] for k in POLICY_INPUTS}, img=img, big_img=big_img + vision_output, on_policy_output, off_policy_output = self.run_policy( + **{k: self.input_queues[k] for k in POLICY_INPUTS if k in self.input_queues}, img=img, big_img=big_img ) vision_output = vision_output.numpy().flatten() + off_policy_output = off_policy_output.numpy().flatten() on_policy_output = on_policy_output.numpy().flatten() vision_outputs_dict = self.parser.parse_vision_outputs(self.slice_outputs(vision_output, self.vision_output_slices)) + off_policy_outputs_dict = self.parser.parse_off_policy_outputs(self.slice_outputs(off_policy_output, self.off_policy_output_slices)) policy_outputs_dict = self.parser.parse_policy_outputs(self.slice_outputs(on_policy_output, self.policy_output_slices)) - combined_outputs_dict = {**vision_outputs_dict, **policy_outputs_dict} + combined_outputs_dict = {**vision_outputs_dict, **off_policy_outputs_dict, **policy_outputs_dict} if SEND_RAW_PRED: - combined_outputs_dict['raw_pred'] = np.concatenate([vision_output.copy(), on_policy_output.copy()]) + combined_outputs_dict['raw_pred'] = np.concatenate([vision_output.copy(), on_policy_output.copy(), off_policy_output.copy()]) return combined_outputs_dict diff --git a/selfdrive/modeld/models/big_driving_off_policy.onnx b/selfdrive/modeld/models/big_driving_off_policy.onnx new file mode 100644 index 0000000000..715f9f9c99 --- /dev/null +++ b/selfdrive/modeld/models/big_driving_off_policy.onnx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8a26866121d1d3a1152bfce024ed7584b8569507d120d4bc8917320093dcd31a +size 41191256 diff --git a/selfdrive/modeld/models/big_driving_on_policy.onnx b/selfdrive/modeld/models/big_driving_on_policy.onnx index f7b49c018a..6011d4be22 100644 --- a/selfdrive/modeld/models/big_driving_on_policy.onnx +++ b/selfdrive/modeld/models/big_driving_on_policy.onnx @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:565e53c38dcd64c50dd3fe4d5ee1530213aeefd66c3f6b67ea6a72a32612a6bf -size 14061419 +oid sha256:94b07ef7a0f65d5c41ac696b4ae7bdc59e2d4c5f504460e2b0d720620892c2e8 +size 33679037 diff --git a/selfdrive/modeld/models/big_driving_vision.onnx b/selfdrive/modeld/models/big_driving_vision.onnx index d14f1969e0..bfebd4f7a6 100644 --- a/selfdrive/modeld/models/big_driving_vision.onnx +++ b/selfdrive/modeld/models/big_driving_vision.onnx @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1f0cab5033fe9e3bc5e174a2e790fa277f7d9fc44c65822d734064d2f899a9a0 -size 296203378 +oid sha256:eda005282417ffa825092ece5c16b5584142044cdbcf15b6d0246136ac6db601 +size 120584466 diff --git a/selfdrive/modeld/models/driving_off_policy.onnx b/selfdrive/modeld/models/driving_off_policy.onnx new file mode 100644 index 0000000000..673f7949f8 --- /dev/null +++ b/selfdrive/modeld/models/driving_off_policy.onnx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6173be8a69b1d9633a09969c80b2a8bd990bfe7d3e76e192a0e537f6fd72222b +size 41192485 diff --git a/selfdrive/modeld/models/driving_on_policy.onnx b/selfdrive/modeld/models/driving_on_policy.onnx index 611ae9fe85..dc9f587949 100644 --- a/selfdrive/modeld/models/driving_on_policy.onnx +++ b/selfdrive/modeld/models/driving_on_policy.onnx @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:78477124cbf3ffe30fa951ebada8410b43c4242c6054584d656f1d329b067e15 -size 14060847 +oid sha256:6b66ef783af3fa86190e85a6b4f729cd1443b20be41134aa258f9c376825a45c +size 33680163 diff --git a/selfdrive/modeld/models/driving_vision.onnx b/selfdrive/modeld/models/driving_vision.onnx index 6c9fc4c84d..6bfff25c21 100644 --- a/selfdrive/modeld/models/driving_vision.onnx +++ b/selfdrive/modeld/models/driving_vision.onnx @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ee29ee5bce84d1ce23e9ff381280de9b4e4d96d2934cd751740354884e112c66 -size 46877473 +oid sha256:bbd0761201b3b161587d097f173c66bf82cd02966e5f0d1edd888c970d6f6d87 +size 21735970 diff --git a/selfdrive/modeld/parse_model_outputs.py b/selfdrive/modeld/parse_model_outputs.py index 26c138b8ec..3b35c15acb 100644 --- a/selfdrive/modeld/parse_model_outputs.py +++ b/selfdrive/modeld/parse_model_outputs.py @@ -96,11 +96,17 @@ class Parser: self.parse_mdn('pose', outs, in_N=0, out_N=0, out_shape=(ModelConstants.POSE_WIDTH,)) self.parse_mdn('wide_from_device_euler', outs, in_N=0, out_N=0, out_shape=(ModelConstants.WIDE_FROM_DEVICE_WIDTH,)) self.parse_mdn('road_transform', outs, in_N=0, out_N=0, out_shape=(ModelConstants.POSE_WIDTH,)) + self.parse_categorical_crossentropy('desire_pred', outs, out_shape=(ModelConstants.DESIRE_PRED_LEN,ModelConstants.DESIRE_PRED_WIDTH)) + self.parse_binary_crossentropy('meta', outs) self.parse_mdn('lane_lines', outs, in_N=0, out_N=0, out_shape=(ModelConstants.NUM_LANE_LINES,ModelConstants.IDX_N,ModelConstants.LANE_LINES_WIDTH)) self.parse_mdn('road_edges', outs, in_N=0, out_N=0, out_shape=(ModelConstants.NUM_ROAD_EDGES,ModelConstants.IDX_N,ModelConstants.LANE_LINES_WIDTH)) self.parse_binary_crossentropy('lane_lines_prob', outs) - self.parse_categorical_crossentropy('desire_pred', outs, out_shape=(ModelConstants.DESIRE_PRED_LEN,ModelConstants.DESIRE_PRED_WIDTH)) - self.parse_binary_crossentropy('meta', outs) + return outs + + def parse_off_policy_outputs(self, outs: dict[str, np.ndarray]) -> dict[str, np.ndarray]: + plan_mhp = self.is_mhp(outs, 'plan', ModelConstants.IDX_N * ModelConstants.PLAN_WIDTH) + plan_in_N, plan_out_N = (ModelConstants.PLAN_MHP_N, ModelConstants.PLAN_MHP_SELECTION) if plan_mhp else (0, 0) + self.parse_mdn('plan', outs, in_N=plan_in_N, out_N=plan_out_N, out_shape=(ModelConstants.IDX_N, ModelConstants.PLAN_WIDTH)) self.parse_binary_crossentropy('lead_prob', outs) lead_mhp = self.is_mhp(outs, 'lead', ModelConstants.LEAD_MHP_SELECTION * ModelConstants.LEAD_TRAJ_LEN * ModelConstants.LEAD_WIDTH) lead_in_N, lead_out_N = (ModelConstants.LEAD_MHP_N, ModelConstants.LEAD_MHP_SELECTION) if lead_mhp else (0, 0) @@ -110,11 +116,11 @@ class Parser: return outs def parse_policy_outputs(self, outs: dict[str, np.ndarray]) -> dict[str, np.ndarray]: - self.parse_mdn('plan', outs, in_N=0, out_N=0, out_shape=(ModelConstants.IDX_N, ModelConstants.PLAN_WIDTH)) - self.parse_categorical_crossentropy('desire_state', outs, out_shape=(ModelConstants.DESIRE_PRED_WIDTH,)) + self.parse_mdn('action', outs, in_N=0, out_N=0, out_shape=(ModelConstants.ACTION_WIDTH,)) return outs def parse_outputs(self, outs: dict[str, np.ndarray]) -> dict[str, np.ndarray]: outs = self.parse_vision_outputs(outs) + outs = self.parse_off_policy_outputs(outs) outs = self.parse_policy_outputs(outs) return outs diff --git a/selfdrive/test/process_replay/model_replay.py b/selfdrive/test/process_replay/model_replay.py index 266f66aaf2..25ee6ac8d1 100755 --- a/selfdrive/test/process_replay/model_replay.py +++ b/selfdrive/test/process_replay/model_replay.py @@ -34,7 +34,7 @@ GITHUB = GithubUtils(API_TOKEN, DATA_TOKEN) EXEC_TIMINGS = [ # model, instant max, average max - ("modelV2", 0.05, 0.028), + ("modelV2", 0.05, 0.032), ("driverStateV2", 0.05, 0.018), ] diff --git a/system/hardware/tici/tests/test_power_draw.py b/system/hardware/tici/tests/test_power_draw.py index 6656addf73..2de2efe2d8 100644 --- a/system/hardware/tici/tests/test_power_draw.py +++ b/system/hardware/tici/tests/test_power_draw.py @@ -32,7 +32,7 @@ class Proc: PROCS = [ Proc(['camerad'], 1.65, atol=0.4, msgs=['roadCameraState', 'wideRoadCameraState', 'driverCameraState']), - Proc(['modeld'], 1.5, atol=0.2, msgs=['modelV2']), + Proc(['modeld'], 1.8, atol=0.2, msgs=['modelV2']), Proc(['dmonitoringmodeld'], 0.65, atol=0.35, msgs=['driverStateV2']), Proc(['encoderd'], 0.23, msgs=[]), ] diff --git a/tinygrad_repo b/tinygrad_repo index 556defa0f7..fd992d6684 160000 --- a/tinygrad_repo +++ b/tinygrad_repo @@ -1 +1 @@ -Subproject commit 556defa0f78ed10b6ce675a2fa15a1c2521b5e93 +Subproject commit fd992d668400ded1b0114f0a741fc37214fbc4a4 From 094591793aba4aa0afaf4d0701962fbfacde00d9 Mon Sep 17 00:00:00 2001 From: brian Date: Wed, 3 Jun 2026 19:25:39 -0400 Subject: [PATCH 005/151] A valid livePose should not carry a timestamp produced from uninitialized Kalman filter time (#38124) * locationd: require finite filter time for valid livePose * cast to bool and rename --- selfdrive/locationd/locationd.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/selfdrive/locationd/locationd.py b/selfdrive/locationd/locationd.py index 57aecb22e7..41b80a1c41 100755 --- a/selfdrive/locationd/locationd.py +++ b/selfdrive/locationd/locationd.py @@ -206,9 +206,11 @@ class LocationEstimator: self._finite_check(t, new_x, new_P) return HandleLogResult.SUCCESS - def get_msg(self, sensors_valid: bool, inputs_valid: bool, filter_valid: bool): + def get_msg(self, sensors_valid: bool, inputs_valid: bool, filter_initialized: bool): state, cov = self.kf.x, self.kf.P std = np.sqrt(np.diag(cov)) + filter_time_valid = bool(np.isfinite(self.kf.t)) + filter_valid = filter_initialized and filter_time_valid orientation_ned, orientation_ned_std = state[States.NED_ORIENTATION], std[States.NED_ORIENTATION] velocity_device, velocity_device_std = state[States.DEVICE_VELOCITY], std[States.DEVICE_VELOCITY] From c01b8be9682f54d7305c79ed7f2c8f2812bcc486 Mon Sep 17 00:00:00 2001 From: Daniel Koepping Date: Wed, 3 Jun 2026 19:35:51 -0700 Subject: [PATCH 006/151] set max cpu core frequency (#38132) cap cpu core frequency --- system/hardware/tici/hardware.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/system/hardware/tici/hardware.py b/system/hardware/tici/hardware.py index 34c426d6e7..35bed55721 100644 --- a/system/hardware/tici/hardware.py +++ b/system/hardware/tici/hardware.py @@ -313,6 +313,9 @@ class Tici(HardwareBase): continue gov = 'ondemand' if powersave_enabled else 'performance' sudo_write(gov, f'/sys/devices/system/cpu/cpufreq/policy{n}/scaling_governor') + if not powersave_enabled: + # cap max core freq to 1689 Mhz + sudo_write('1689600', f'/sys/devices/system/cpu/cpufreq/policy{n}/scaling_max_freq') # *** IRQ config *** From 900a896c63470f5f85b7dd3a70d9a91a245d8861 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20R=C4=85czy?= Date: Thu, 4 Jun 2026 03:24:27 +0000 Subject: [PATCH 007/151] lagd: higher min speed (#38133) * Higher min vego * Use CV * Bump speed in simulated tests --- selfdrive/locationd/lagd.py | 3 ++- selfdrive/locationd/test/test_lagd.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/selfdrive/locationd/lagd.py b/selfdrive/locationd/lagd.py index e2026908c9..2df3dc9ad9 100755 --- a/selfdrive/locationd/lagd.py +++ b/selfdrive/locationd/lagd.py @@ -8,6 +8,7 @@ from functools import partial import cereal.messaging as messaging from cereal import car, log from cereal.services import SERVICE_LIST +from openpilot.common.constants import CV from openpilot.common.params import Params from openpilot.common.realtime import config_realtime_process from openpilot.common.swaglog import cloudlog @@ -19,7 +20,7 @@ BLOCK_NUM_NEEDED = 5 MOVING_WINDOW_SEC = 60.0 MIN_OKAY_WINDOW_SEC = 25.0 MIN_RECOVERY_BUFFER_SEC = 2.0 -MIN_VEGO = 15.0 +MIN_VEGO = 50.0 * CV.MPH_TO_MS MIN_ABS_YAW_RATE = 0.0 MAX_YAW_RATE_SANITY_CHECK = 1.0 MIN_NCC = 0.95 diff --git a/selfdrive/locationd/test/test_lagd.py b/selfdrive/locationd/test/test_lagd.py index 746f7ad478..7e8d79a7de 100644 --- a/selfdrive/locationd/test/test_lagd.py +++ b/selfdrive/locationd/test/test_lagd.py @@ -16,7 +16,7 @@ MAX_ERR_FRAMES = 1 DT = 0.05 -def process_messages(estimator, lag_frames, n_frames, vego=20.0, rejection_threshold=0.0): +def process_messages(estimator, lag_frames, n_frames, vego=25.0, rejection_threshold=0.0): for i in range(n_frames): t = i * estimator.dt desired_la = np.cos(10 * t) * 0.3 From 268126f3761dccd276a158ac67951407381eba32 Mon Sep 17 00:00:00 2001 From: Armand du Parc Locmaria Date: Wed, 3 Jun 2026 23:32:32 -0700 Subject: [PATCH 008/151] usbgpu: pin modeld (#38123) usbgpu: pin modeld to core 7 --- selfdrive/modeld/modeld.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/selfdrive/modeld/modeld.py b/selfdrive/modeld/modeld.py index 338f26b598..49ea0d5cdf 100755 --- a/selfdrive/modeld/modeld.py +++ b/selfdrive/modeld/modeld.py @@ -158,10 +158,7 @@ def main(demo=False): params.put_bool("UsbGpuPresent", _present) params.put_bool("UsbGpuCompiled", _compiled) - if not USBGPU: - # USB GPU currently saturates a core so can't do this yet, - # also need to move the aux USB interrupts for good timings - config_realtime_process(7, 54) + config_realtime_process(7, 54) # visionipc clients while True: From 14a00e0cc8759a42e86d7c620cfae1dfce61f59b Mon Sep 17 00:00:00 2001 From: Daniel Koepping Date: Fri, 5 Jun 2026 20:32:30 -0700 Subject: [PATCH 009/151] Add latcontrol for curvature (#38141) * undeprecate curvature * use pid_log * bump * fix test * bump * bump * fix * tune saturation * bump * fix torque bar * bump * rm redundant * reduce sesitivity * pid * bump * reset opendbc * preserve sorting * bump opendbc --- cereal/deprecated.capnp | 12 ---- cereal/log.capnp | 14 ++++- opendbc_repo | 2 +- selfdrive/car/tests/test_models.py | 2 +- selfdrive/controls/controlsd.py | 16 +++-- .../controls/lib/latcontrol_curvature.py | 58 +++++++++++++++++++ selfdrive/ui/mici/onroad/torque_bar.py | 2 +- 7 files changed, 86 insertions(+), 20 deletions(-) create mode 100644 selfdrive/controls/lib/latcontrol_curvature.py diff --git a/cereal/deprecated.capnp b/cereal/deprecated.capnp index 45ce25c682..5e4b0b4de0 100644 --- a/cereal/deprecated.capnp +++ b/cereal/deprecated.capnp @@ -760,18 +760,6 @@ struct LateralLQRState @0x9024e2d790c82ade { steeringAngleDesiredDeg @6 :Float32; } -struct LateralCurvatureState @0xad9d8095c06f7c61 { - active @0 :Bool; - actualCurvature @1 :Float32; - desiredCurvature @2 :Float32; - error @3 :Float32; - p @4 :Float32; - i @5 :Float32; - f @6 :Float32; - output @7 :Float32; - saturated @8 :Bool; -} - struct LateralPlannerSolution @0x84caeca5a6b4acfe { x @0 :List(Float32); y @1 :List(Float32); diff --git a/cereal/log.capnp b/cereal/log.capnp index d12cd6cdc8..b7202dfcf7 100644 --- a/cereal/log.capnp +++ b/cereal/log.capnp @@ -818,7 +818,7 @@ struct ControlsState @0x97ff69c53601abf1 { debugState @59 :LateralDebugState; torqueState @60 :LateralTorqueState; - curvatureStateDEPRECATED @65 :Deprecated.LateralCurvatureState; + curvatureState @65 :LateralCurvatureState; lqrStateDEPRECATED @55 :Deprecated.LateralLQRState; indiStateDEPRECATED @52 :Deprecated.LateralINDIState; } @@ -867,6 +867,18 @@ struct ControlsState @0x97ff69c53601abf1 { saturated @3 :Bool; } + struct LateralCurvatureState @0xad9d8095c06f7c61 { + active @0 :Bool; + actualCurvature @1 :Float32; + desiredCurvature @2 :Float32; + error @3 :Float32; + p @4 :Float32; + i @5 :Float32; + f @6 :Float32; + output @7 :Float32; + saturated @8 :Bool; + } + deprecated :group { vEgo @0 :Float32; vEgoRaw @32 :Float32; diff --git a/opendbc_repo b/opendbc_repo index 560b75d6bb..7343ffe79d 160000 --- a/opendbc_repo +++ b/opendbc_repo @@ -1 +1 @@ -Subproject commit 560b75d6bb5ba14dc594727e5cc7c7bbf0ed0f3c +Subproject commit 7343ffe79d4ce3244cb0faead4cfbebc3ffc9d87 diff --git a/selfdrive/car/tests/test_models.py b/selfdrive/car/tests/test_models.py index 62ddadef8f..dd0826e513 100644 --- a/selfdrive/car/tests/test_models.py +++ b/selfdrive/car/tests/test_models.py @@ -186,7 +186,7 @@ class TestCarModelBase(unittest.TestCase): # make sure car params are within a valid range self.assertGreater(self.CP.mass, 1) - if self.CP.steerControlType != SteerControlType.angle: + if self.CP.steerControlType not in (SteerControlType.angle, SteerControlType.curvature): tuning = self.CP.lateralTuning.which() if tuning == 'pid': self.assertTrue(len(self.CP.lateralTuning.pid.kpV)) diff --git a/selfdrive/controls/controlsd.py b/selfdrive/controls/controlsd.py index e1d9650d72..cdd00f7234 100755 --- a/selfdrive/controls/controlsd.py +++ b/selfdrive/controls/controlsd.py @@ -15,6 +15,7 @@ from openpilot.selfdrive.controls.lib.drive_helpers import clip_curvature from openpilot.selfdrive.controls.lib.latcontrol import LatControl from openpilot.selfdrive.controls.lib.latcontrol_pid import LatControlPID from openpilot.selfdrive.controls.lib.latcontrol_angle import LatControlAngle, STEER_ANGLE_SATURATION_THRESHOLD +from openpilot.selfdrive.controls.lib.latcontrol_curvature import LatControlCurvature from openpilot.selfdrive.controls.lib.latcontrol_torque import LatControlTorque from openpilot.selfdrive.controls.lib.longcontrol import LongControl from openpilot.selfdrive.modeld.modeld import LAT_SMOOTH_SECONDS @@ -53,6 +54,8 @@ class Controls: self.LaC: LatControl if self.CP.steerControlType == car.CarParams.SteerControlType.angle: self.LaC = LatControlAngle(self.CP, self.CI, DT_CTRL) + elif self.CP.steerControlType == car.CarParams.SteerControlType.curvature: + self.LaC = LatControlCurvature(self.CP, self.CI, DT_CTRL) elif self.CP.lateralTuning.which() == 'pid': self.LaC = LatControlPID(self.CP, self.CI, DT_CTRL) elif self.CP.lateralTuning.which() == 'torque': @@ -124,11 +127,14 @@ class Controls: lat_delay = self.sm["liveDelay"].lateralDelay + LAT_SMOOTH_SECONDS actuators.curvature = self.desired_curvature - steer, steeringAngleDeg, lac_log = self.LaC.update(CC.latActive, CS, self.VM, lp, - self.steer_limited_by_safety, self.desired_curvature, - curvature_limited, lat_delay) + steer, lateral_output, lac_log = self.LaC.update(CC.latActive, CS, self.VM, lp, + self.steer_limited_by_safety, self.desired_curvature, + curvature_limited, lat_delay) actuators.torque = float(steer) - actuators.steeringAngleDeg = float(steeringAngleDeg) + if self.CP.steerControlType == car.CarParams.SteerControlType.curvature: + actuators.curvature = float(lateral_output) + else: + actuators.steeringAngleDeg = float(lateral_output) # Ensure no NaNs/Infs for p in ACTUATOR_FIELDS: attr = getattr(actuators, p) @@ -199,6 +205,8 @@ class Controls: lat_tuning = self.CP.lateralTuning.which() if self.CP.steerControlType == car.CarParams.SteerControlType.angle: cs.lateralControlState.angleState = lac_log + elif self.CP.steerControlType == car.CarParams.SteerControlType.curvature: + cs.lateralControlState.curvatureState = lac_log elif lat_tuning == 'pid': cs.lateralControlState.pidState = lac_log elif lat_tuning == 'torque': diff --git a/selfdrive/controls/lib/latcontrol_curvature.py b/selfdrive/controls/lib/latcontrol_curvature.py new file mode 100644 index 0000000000..cd2d8e3284 --- /dev/null +++ b/selfdrive/controls/lib/latcontrol_curvature.py @@ -0,0 +1,58 @@ +import math + +from cereal import log +from openpilot.common.pid import PIDController +from openpilot.selfdrive.controls.lib.latcontrol import LatControl +from openpilot.selfdrive.controls.lib.drive_helpers import MAX_CURVATURE + +CURVATURE_SATURATION_THRESHOLD = 1e-3 # 1/m + + +class LatControlCurvature(LatControl): + def __init__(self, CP, CI, dt): + super().__init__(CP, CI, dt) + self.sat_check_min_speed = 5. + if CP.lateralTuning.which() == 'pid': + ct = CP.lateralTuning.pid + self.pid = PIDController((ct.kpBP, ct.kpV), (ct.kiBP, ct.kiV), + pos_limit=MAX_CURVATURE, neg_limit=-MAX_CURVATURE, rate=1 / dt) + self.kf = ct.kf + else: + self.pid = None + self.kf = 1. + + def reset(self): + super().reset() + if self.pid is not None: + self.pid.reset() + + def update(self, active, CS, VM, params, steer_limited_by_safety, desired_curvature, curvature_limited, lat_delay): + curvature_log = log.ControlsState.LateralCurvatureState.new_message() + actual_curvature = -VM.calc_curvature(math.radians(CS.steeringAngleDeg - params.angleOffsetDeg), CS.vEgo, params.roll) + error = desired_curvature - actual_curvature + + if not active: + output_curvature = 0.0 + curvature_log.active = False + if self.pid is not None: + self.pid.reset() + elif self.pid is None or CS.steeringPressed: + # no PID or override: feedforward only + if self.pid is not None: + self.pid.reset() + output_curvature = self.kf * desired_curvature + curvature_log.active = True + else: + output_curvature = self.pid.update(error, speed=CS.vEgo, feedforward=self.kf * desired_curvature) + curvature_log.p = float(self.pid.p) + curvature_log.i = float(self.pid.i) + curvature_log.f = float(self.pid.f) + curvature_log.active = True + + curvature_log.error = float(error) + curvature_log.actualCurvature = float(actual_curvature) + curvature_log.desiredCurvature = float(desired_curvature) + curvature_log.output = float(output_curvature) + curvature_log.saturated = bool(self._check_saturation(abs(error) > CURVATURE_SATURATION_THRESHOLD, CS, + False, curvature_limited)) + return 0.0, float(output_curvature), curvature_log diff --git a/selfdrive/ui/mici/onroad/torque_bar.py b/selfdrive/ui/mici/onroad/torque_bar.py index 406e6ff712..6a1d12b6c4 100644 --- a/selfdrive/ui/mici/onroad/torque_bar.py +++ b/selfdrive/ui/mici/onroad/torque_bar.py @@ -163,7 +163,7 @@ class TorqueBar(Widget): return # torque line - if ui_state.sm['controlsState'].lateralControlState.which() == 'angleState': + if ui_state.sm['controlsState'].lateralControlState.which() in ('angleState', 'curvatureState'): controls_state = ui_state.sm['controlsState'] car_state = ui_state.sm['carState'] live_parameters = ui_state.sm['liveParameters'] From bfd8d4868df6f46a18334e349d952bdd6ab996ff Mon Sep 17 00:00:00 2001 From: CommaKia Date: Sat, 6 Jun 2026 16:32:58 +1000 Subject: [PATCH 010/151] cabana: fix "seperated" typo in findsignal placeholders (#38142) --- tools/cabana/tools/findsignal.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/cabana/tools/findsignal.cc b/tools/cabana/tools/findsignal.cc index b131893942..d538d676b1 100644 --- a/tools/cabana/tools/findsignal.cc +++ b/tools/cabana/tools/findsignal.cc @@ -98,9 +98,9 @@ FindSignalDlg::FindSignalDlg(QWidget *parent) : QDialog(parent, Qt::WindowFlags( message_group = new QGroupBox(tr("Messages"), this); QFormLayout *message_layout = new QFormLayout(message_group); message_layout->addRow(tr("Bus"), bus_edit = new QLineEdit()); - bus_edit->setPlaceholderText(tr("comma-seperated values. Leave blank for all")); + bus_edit->setPlaceholderText(tr("comma-separated values. Leave blank for all")); message_layout->addRow(tr("Address"), address_edit = new QLineEdit()); - address_edit->setPlaceholderText(tr("comma-seperated hex values. Leave blank for all")); + address_edit->setPlaceholderText(tr("comma-separated hex values. Leave blank for all")); QHBoxLayout *hlayout = new QHBoxLayout(); hlayout->addWidget(first_time_edit = new QLineEdit("0")); hlayout->addWidget(new QLabel("-")); From cc110d1eb1b5581a93d8b7d99805fd127de737de Mon Sep 17 00:00:00 2001 From: Daniel Koepping Date: Sat, 6 Jun 2026 12:02:46 -0700 Subject: [PATCH 011/151] Add driverMonitoringEscalation for stock DM trigger (#38143) * trigger dm * rename * ci * opendbc bump --- opendbc_repo | 2 +- selfdrive/controls/controlsd.py | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/opendbc_repo b/opendbc_repo index 7343ffe79d..e91d019968 160000 --- a/opendbc_repo +++ b/opendbc_repo @@ -1 +1 @@ -Subproject commit 7343ffe79d4ce3244cb0faead4cfbebc3ffc9d87 +Subproject commit e91d0199680b096fcea94baf287f17cb852b7231 diff --git a/selfdrive/controls/controlsd.py b/selfdrive/controls/controlsd.py index cdd00f7234..5e3817c298 100755 --- a/selfdrive/controls/controlsd.py +++ b/selfdrive/controls/controlsd.py @@ -202,6 +202,9 @@ class Controls: cs.forceDecel = bool((self.sm['driverMonitoringState'].alertLevel == log.DriverMonitoringState.AlertLevel.three) or (self.sm['selfdriveState'].state == State.softDisabling)) + # trigger the car's stock driver monitoring escalation + CC.driverMonitoringEscalation = cs.forceDecel + lat_tuning = self.CP.lateralTuning.which() if self.CP.steerControlType == car.CarParams.SteerControlType.angle: cs.lateralControlState.angleState = lac_log From b0600a422548f421e6467b58fdd411f378e6ed72 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Sun, 7 Jun 2026 10:00:08 -0700 Subject: [PATCH 012/151] rm unused updated test --- selfdrive/test/test_updated.py | 295 --------------------------------- 1 file changed, 295 deletions(-) delete mode 100644 selfdrive/test/test_updated.py diff --git a/selfdrive/test/test_updated.py b/selfdrive/test/test_updated.py deleted file mode 100644 index e4cc714b87..0000000000 --- a/selfdrive/test/test_updated.py +++ /dev/null @@ -1,295 +0,0 @@ -import datetime -import os -import pytest -import time -import tempfile -import shutil -import signal -import subprocess -import random - -from openpilot.common.basedir import BASEDIR -from openpilot.common.params import Params - - -@pytest.mark.tici -class TestUpdated: - - def setup_method(self): - self.updated_proc = None - - self.tmp_dir = tempfile.TemporaryDirectory() - org_dir = os.path.join(self.tmp_dir.name, "commaai") - - self.basedir = os.path.join(org_dir, "openpilot") - self.git_remote_dir = os.path.join(org_dir, "openpilot_remote") - self.staging_dir = os.path.join(org_dir, "safe_staging") - for d in [org_dir, self.basedir, self.git_remote_dir, self.staging_dir]: - os.mkdir(d) - - self.neos_version = os.path.join(org_dir, "neos_version") - self.neosupdate_dir = os.path.join(org_dir, "neosupdate") - with open(self.neos_version, "w") as f: - v = subprocess.check_output(r"bash -c 'source launch_env.sh && echo $REQUIRED_NEOS_VERSION'", - cwd=BASEDIR, shell=True, encoding='utf8').strip() - f.write(v) - - self.upper_dir = os.path.join(self.staging_dir, "upper") - self.merged_dir = os.path.join(self.staging_dir, "merged") - self.finalized_dir = os.path.join(self.staging_dir, "finalized") - - # setup local submodule remotes - submodules = subprocess.check_output("git submodule --quiet foreach 'echo $name'", - shell=True, cwd=BASEDIR, encoding='utf8').split() - for s in submodules: - sub_path = os.path.join(org_dir, s.split("_repo")[0]) - self._run(f"git clone {s} {sub_path}.git", cwd=BASEDIR) - - # setup two git repos, a remote and one we'll run updated in - self._run([ - f"git clone {BASEDIR} {self.git_remote_dir}", - f"git clone {self.git_remote_dir} {self.basedir}", - f"cd {self.basedir} && git submodule init && git submodule update", - f"cd {self.basedir} && scons cereal/ common/" - ]) - - self.params = Params(os.path.join(self.basedir, "persist/params")) - self.params.clear_all() - os.sync() - - def teardown_method(self): - try: - if self.updated_proc is not None: - self.updated_proc.terminate() - self.updated_proc.wait(30) - except Exception as e: - print(e) - self.tmp_dir.cleanup() - - - # *** test helpers *** - - - def _run(self, cmd, cwd=None): - if not isinstance(cmd, list): - cmd = (cmd,) - - for c in cmd: - subprocess.check_output(c, cwd=cwd, shell=True) - - def _get_updated_proc(self): - os.environ["PYTHONPATH"] = self.basedir - os.environ["GIT_AUTHOR_NAME"] = "testy tester" - os.environ["GIT_COMMITTER_NAME"] = "testy tester" - os.environ["GIT_AUTHOR_EMAIL"] = "testy@tester.test" - os.environ["GIT_COMMITTER_EMAIL"] = "testy@tester.test" - os.environ["UPDATER_TEST_IP"] = "localhost" - os.environ["UPDATER_LOCK_FILE"] = os.path.join(self.tmp_dir.name, "updater.lock") - os.environ["UPDATER_STAGING_ROOT"] = self.staging_dir - os.environ["UPDATER_NEOS_VERSION"] = self.neos_version - os.environ["UPDATER_NEOSUPDATE_DIR"] = self.neosupdate_dir - updated_path = os.path.join(self.basedir, "system/updated.py") - return subprocess.Popen(updated_path, env=os.environ) - - def _start_updater(self, offroad=True, nosleep=False): - self.params.put_bool("IsOffroad", offroad, block=True) - self.updated_proc = self._get_updated_proc() - if not nosleep: - time.sleep(1) - - def _update_now(self): - self.updated_proc.send_signal(signal.SIGHUP) - - # TODO: this should be implemented in params - def _read_param(self, key, timeout=1): - ret = None - start_time = time.monotonic() - while ret is None: - ret = self.params.get(key) - if time.monotonic() - start_time > timeout: - break - time.sleep(0.01) - return ret - - def _wait_for_update(self, timeout=30, clear_param=False): - if clear_param: - self.params.remove("LastUpdateTime") - - self._update_now() - t = self._read_param("LastUpdateTime", timeout=timeout) - if t is None: - raise Exception("timed out waiting for update to complete") - - def _make_commit(self): - all_dirs, all_files = [], [] - for root, dirs, files in os.walk(self.git_remote_dir): - if ".git" in root: - continue - for d in dirs: - all_dirs.append(os.path.join(root, d)) - for f in files: - all_files.append(os.path.join(root, f)) - - # make a new dir and some new files - new_dir = os.path.join(self.git_remote_dir, "this_is_a_new_dir") - os.mkdir(new_dir) - for _ in range(random.randrange(5, 30)): - for d in (new_dir, random.choice(all_dirs)): - with tempfile.NamedTemporaryFile(dir=d, delete=False) as f: - f.write(os.urandom(random.randrange(1, 1000000))) - - # modify some files - for f in random.sample(all_files, random.randrange(5, 50)): - with open(f, "w+") as ff: - txt = ff.readlines() - ff.seek(0) - for line in txt: - ff.write(line[::-1]) - - # remove some files - for f in random.sample(all_files, random.randrange(5, 50)): - os.remove(f) - - # remove some dirs - for d in random.sample(all_dirs, random.randrange(1, 10)): - shutil.rmtree(d) - - # commit the changes - self._run([ - "git add -A", - "git commit -m 'an update'", - ], cwd=self.git_remote_dir) - - def _check_update_state(self, update_available): - # make sure LastUpdateTime is recent - last_update_time = self._read_param("LastUpdateTime") - td = datetime.datetime.now(datetime.UTC).replace(tzinfo=None) - last_update_time - assert td.total_seconds() < 10 - self.params.remove("LastUpdateTime") - - # wait a bit for the rest of the params to be written - time.sleep(0.1) - - # check params - update = self._read_param("UpdateAvailable") - assert update == "1" == update_available, f"UpdateAvailable: {repr(update)}" - assert self._read_param("UpdateFailedCount") == 0 - - # TODO: check that the finalized update actually matches remote - # check the .overlay_init and .overlay_consistent flags - assert os.path.isfile(os.path.join(self.basedir, ".overlay_init")) - assert os.path.isfile(os.path.join(self.finalized_dir, ".overlay_consistent")) == update_available - - - # *** test cases *** - - - # Run updated for 100 cycles with no update - def test_no_update(self): - self._start_updater() - for _ in range(100): - self._wait_for_update(clear_param=True) - self._check_update_state(False) - - # Let the updater run with no update for a cycle, then write an update - def test_update(self): - self._start_updater() - - # run for a cycle with no update - self._wait_for_update(clear_param=True) - self._check_update_state(False) - - # write an update to our remote - self._make_commit() - - # run for a cycle to get the update - self._wait_for_update(timeout=60, clear_param=True) - self._check_update_state(True) - - # run another cycle with no update - self._wait_for_update(clear_param=True) - self._check_update_state(True) - - # Let the updater run for 10 cycles, and write an update every cycle - @pytest.mark.skip("need to make this faster") - def test_update_loop(self): - self._start_updater() - - # run for a cycle with no update - self._wait_for_update(clear_param=True) - for _ in range(10): - time.sleep(0.5) - self._make_commit() - self._wait_for_update(timeout=90, clear_param=True) - self._check_update_state(True) - - # Test overlay re-creation after tracking a new file in basedir's git - def test_overlay_reinit(self): - self._start_updater() - - overlay_init_fn = os.path.join(self.basedir, ".overlay_init") - - # run for a cycle with no update - self._wait_for_update(clear_param=True) - self.params.remove("LastUpdateTime") - first_mtime = os.path.getmtime(overlay_init_fn) - - # touch a file in the basedir - self._run("touch new_file && git add new_file", cwd=self.basedir) - - # run another cycle, should have a new mtime - self._wait_for_update(clear_param=True) - second_mtime = os.path.getmtime(overlay_init_fn) - assert first_mtime != second_mtime - - # run another cycle, mtime should be same as last cycle - self._wait_for_update(clear_param=True) - new_mtime = os.path.getmtime(overlay_init_fn) - assert second_mtime == new_mtime - - # Make sure updated exits if another instance is running - def test_multiple_instances(self): - # start updated and let it run for a cycle - self._start_updater() - time.sleep(1) - self._wait_for_update(clear_param=True) - - # start another instance - second_updated = self._get_updated_proc() - ret_code = second_updated.wait(timeout=5) - assert ret_code is not None - - - # *** test cases with NEOS updates *** - - - # Run updated with no update, make sure it clears the old NEOS update - def test_clear_neos_cache(self): - # make the dir and some junk files - os.mkdir(self.neosupdate_dir) - for _ in range(15): - with tempfile.NamedTemporaryFile(dir=self.neosupdate_dir, delete=False) as f: - f.write(os.urandom(random.randrange(1, 1000000))) - - self._start_updater() - self._wait_for_update(clear_param=True) - self._check_update_state(False) - assert not os.path.isdir(self.neosupdate_dir) - - # Let the updater run with no update for a cycle, then write an update - @pytest.mark.skip("TODO: only runs on device") - def test_update_with_neos_update(self): - # bump the NEOS version and commit it - self._run([ - "echo 'export REQUIRED_NEOS_VERSION=3' >> launch_env.sh", - "git -c user.name='testy' -c user.email='testy@tester.test' \ - commit -am 'a neos update'", - ], cwd=self.git_remote_dir) - - # run for a cycle to get the update - self._start_updater() - self._wait_for_update(timeout=60, clear_param=True) - self._check_update_state(True) - - # TODO: more comprehensive check - assert os.path.isdir(self.neosupdate_dir) From ef3ec30fe2c3fe517c7243114090ae9f3a2a3dab Mon Sep 17 00:00:00 2001 From: Daniel Koepping Date: Mon, 8 Jun 2026 09:58:57 -0700 Subject: [PATCH 013/151] bump opendbc - ID.4 release (#38150) id4 release --- opendbc_repo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opendbc_repo b/opendbc_repo index e91d019968..e23d405ab3 160000 --- a/opendbc_repo +++ b/opendbc_repo @@ -1 +1 @@ -Subproject commit e91d0199680b096fcea94baf287f17cb852b7231 +Subproject commit e23d405ab3beb31de503400acd47d9c390564a8d From 7abe0205fd7bc2f9ae245d778524f3fdb0d0b353 Mon Sep 17 00:00:00 2001 From: Bruce Wayne Date: Mon, 8 Jun 2026 15:17:07 -0700 Subject: [PATCH 014/151] modeld test: 1ms extra buffer --- selfdrive/test/process_replay/model_replay.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/selfdrive/test/process_replay/model_replay.py b/selfdrive/test/process_replay/model_replay.py index 25ee6ac8d1..7cbdc73a61 100755 --- a/selfdrive/test/process_replay/model_replay.py +++ b/selfdrive/test/process_replay/model_replay.py @@ -34,7 +34,7 @@ GITHUB = GithubUtils(API_TOKEN, DATA_TOKEN) EXEC_TIMINGS = [ # model, instant max, average max - ("modelV2", 0.05, 0.032), + ("modelV2", 0.05, 0.033), ("driverStateV2", 0.05, 0.018), ] From 01a843e0acbe74d566a7eee9fe0f12f227ae81ed Mon Sep 17 00:00:00 2001 From: Jason Wen Date: Tue, 9 Jun 2026 02:15:42 -0400 Subject: [PATCH 015/151] ui: reset Enforce Torque Control and NNLC if both are enabled (#1863) * ui: reset Enforce Torque Control and NNLC if both are enabled * block --- selfdrive/ui/sunnypilot/layouts/settings/steering.py | 5 +++++ selfdrive/ui/sunnypilot/ui_state.py | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/selfdrive/ui/sunnypilot/layouts/settings/steering.py b/selfdrive/ui/sunnypilot/layouts/settings/steering.py index e31ee1891c..a5cd626483 100644 --- a/selfdrive/ui/sunnypilot/layouts/settings/steering.py +++ b/selfdrive/ui/sunnypilot/layouts/settings/steering.py @@ -134,6 +134,11 @@ class SteeringLayout(Widget): enforce_torque_enabled = self._torque_control_toggle.action_item.get_state() nnlc_enabled = self._nnlc_toggle.action_item.get_state() + if enforce_torque_enabled and nnlc_enabled: + self._torque_control_toggle.action_item.set_state(False) + self._nnlc_toggle.action_item.set_state(False) + enforce_torque_enabled = False + nnlc_enabled = False self._nnlc_toggle.action_item.set_enabled(ui_state.is_offroad() and torque_allowed and not enforce_torque_enabled) self._torque_control_toggle.action_item.set_enabled(ui_state.is_offroad() and torque_allowed and not nnlc_enabled) self._torque_customization_button.action_item.set_enabled(self._torque_control_toggle.action_item.get_state()) diff --git a/selfdrive/ui/sunnypilot/ui_state.py b/selfdrive/ui/sunnypilot/ui_state.py index 8cd37583f3..1c21c35c6f 100644 --- a/selfdrive/ui/sunnypilot/ui_state.py +++ b/selfdrive/ui/sunnypilot/ui_state.py @@ -179,6 +179,10 @@ class UIStateSP: CP = self.CP if CP is not None: + if self.params.get_bool("EnforceTorqueControl") and self.params.get_bool("NeuralNetworkLateralControl"): + self.params.put_bool("EnforceTorqueControl", False, block=True) + self.params.put_bool("NeuralNetworkLateralControl", False, block=True) + # Angle steering: no torque-based lateral controls if CP.steerControlType == car.CarParams.SteerControlType.angle: self.params.remove("EnforceTorqueControl") From 57b5eb3113a96797b11233a5733ef1ebb97f886b Mon Sep 17 00:00:00 2001 From: Trey Moen <50057480+greatgitsby@users.noreply.github.com> Date: Tue, 9 Jun 2026 11:44:57 -0700 Subject: [PATCH 016/151] op.sh: fix arg quoting so special chars survive eval (#37967) op.sh: don't eval CMD, run argv directly so special chars work Previously op_run_command joined "$@" into a single string and eval'd it, which broke on inputs containing shell metacharacters. For example, 'op esim --download "LPA:1$[rsp.truphone.com]($url)$QRF-SPEEDTEST" name' would fail with a syntax error on the unquoted parens. Run "$@" instead and only use $* for the printed display string. Also quote the unquoted $@ in the other op_run_command callers. --- tools/op.sh | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/tools/op.sh b/tools/op.sh index 538d689569..1188d21ac2 100755 --- a/tools/op.sh +++ b/tools/op.sh @@ -48,7 +48,7 @@ function retry() { } function op_run_command() { - CMD="$@" + CMD="$*" echo -e "${BOLD}Running command →${NC} $CMD │" for ((i=0; i<$((19 + ${#CMD})); i++)); do @@ -57,7 +57,7 @@ function op_run_command() { echo -e "┘\n" if [[ -z "$DRY" ]]; then - eval "$CMD" + "$@" fi } @@ -310,33 +310,33 @@ function op_build() { op_run_command system/manager/build.py else # scons is fine on PC - op_run_command scons $@ + op_run_command scons "$@" fi } function op_juggle() { op_before_cmd - op_run_command tools/plotjuggler/juggle.py $@ + op_run_command tools/plotjuggler/juggle.py "$@" } function op_lint() { op_before_cmd - op_run_command scripts/lint/lint.sh $@ + op_run_command scripts/lint/lint.sh "$@" } function op_test() { op_before_cmd - op_run_command pytest $@ + op_run_command pytest "$@" } function op_replay() { op_before_cmd - op_run_command tools/replay/replay $@ + op_run_command tools/replay/replay "$@" } function op_cabana() { op_before_cmd - op_run_command tools/cabana/cabana $@ + op_run_command tools/cabana/cabana "$@" } function op_sim() { @@ -347,7 +347,7 @@ function op_sim() { function op_clip() { op_before_cmd - op_run_command tools/clip/run.py $@ + op_run_command tools/clip/run.py "$@" } function op_switch() { @@ -489,4 +489,4 @@ function _op() { esac } -_op $@ +_op "$@" From 41390a95b85cd85dfd78abc3a031a10434450ad4 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Tue, 9 Jun 2026 16:15:54 -0700 Subject: [PATCH 017/151] Jenkinsfile: use SSH ControlMaster to multiplex device connections (#38157) --- Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index a7f46ce17a..92bc61521e 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -12,7 +12,7 @@ def retryWithDelay(int maxRetries, int delay, Closure body) { def device(String ip, String step_label, String cmd) { withCredentials([file(credentialsId: 'id_rsa', variable: 'key_file')]) { def ssh_cmd = """ -ssh -o ConnectTimeout=5 -o ServerAliveInterval=5 -o ServerAliveCountMax=2 -o BatchMode=yes -o StrictHostKeyChecking=no -i ${key_file} 'comma@${ip}' exec /usr/bin/bash <<'END' +ssh -o ControlMaster=auto -o ControlPath=/tmp/ssh_control_%C -o ControlPersist=yes -o ConnectTimeout=5 -o ServerAliveInterval=5 -o ServerAliveCountMax=2 -o BatchMode=yes -o StrictHostKeyChecking=no -i ${key_file} 'comma@${ip}' exec /usr/bin/bash <<'END' set -e From 24d373062d9c4bd488416bb29cdb9a130a94cc4e Mon Sep 17 00:00:00 2001 From: Daniel Koepping Date: Tue, 9 Jun 2026 16:37:45 -0700 Subject: [PATCH 018/151] soundd: fix long wav playback and mic feedback (#38155) fix soundd long duration playback and mic feedback --- selfdrive/ui/soundd.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/selfdrive/ui/soundd.py b/selfdrive/ui/soundd.py index 8225efabf9..a6f5d2fc27 100644 --- a/selfdrive/ui/soundd.py +++ b/selfdrive/ui/soundd.py @@ -110,6 +110,8 @@ class Soundd: ret[written_frames:written_frames+frames_to_write] = sound_data[current_sound_frame:current_sound_frame+frames_to_write] written_frames += frames_to_write self.current_sound_frame += frames_to_write + current_sound_frame = self.current_sound_frame % len(sound_data) + loops = self.current_sound_frame // len(sound_data) return ret * self.current_volume @@ -119,7 +121,7 @@ class Soundd: data_out[:frames, 0] = self.get_sound_data(frames) def update_alert(self, new_alert): - current_alert_played_once = self.current_alert == AudibleAlert.none or self.current_sound_frame > len(self.loaded_sounds[self.current_alert]) + current_alert_played_once = self.current_alert == AudibleAlert.none or self.current_sound_frame >= len(self.loaded_sounds[self.current_alert]) if self.current_alert != new_alert and (new_alert != AudibleAlert.none or current_alert_played_once): if new_alert == AudibleAlert.warningImmediate: self.ramp_start_volume = self.current_volume @@ -162,10 +164,11 @@ class Soundd: while True: sm.update(0) - # Always update volume, even when alert is playing + # freeze volume during alerts to avoid mic feedback increasing volume if sm.updated['soundPressure']: self.spl_filter_weighted.update(sm["soundPressure"].soundPressureWeightedDb) - self.current_volume = self.calculate_volume(float(self.spl_filter_weighted.x)) + if self.current_alert == AudibleAlert.none: + self.current_volume = self.calculate_volume(float(self.spl_filter_weighted.x)) self.get_audible_alert(sm) From 433c52f6237fb8dc934feac4c4b9da814200bc30 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Tue, 9 Jun 2026 16:56:48 -0700 Subject: [PATCH 019/151] radar errors: only gate enable if openpilot long (#38145) only prevent engagement for op long cars --- selfdrive/selfdrived/selfdrived.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/selfdrive/selfdrived/selfdrived.py b/selfdrive/selfdrived/selfdrived.py index d2fd0f099e..e376ea5c9c 100755 --- a/selfdrive/selfdrived/selfdrived.py +++ b/selfdrive/selfdrived/selfdrived.py @@ -331,12 +331,13 @@ class SelfdriveD: self.events.add(EventName.cameraFrameRate) if not REPLAY and self.rk.lagging: self.events.add(EventName.selfdrivedLagging) - if self.sm['radarState'].radarErrors.canError: - self.events.add(EventName.canError) - elif self.sm['radarState'].radarErrors.radarUnavailableTemporary: - self.events.add(EventName.radarTempUnavailable) - elif any(self.sm['radarState'].radarErrors.to_dict().values()): - self.events.add(EventName.radarFault) + if self.CP.openpilotLongitudinalControl: + if self.sm['radarState'].radarErrors.canError: + self.events.add(EventName.canError) + elif self.sm['radarState'].radarErrors.radarUnavailableTemporary: + self.events.add(EventName.radarTempUnavailable) + elif any(self.sm['radarState'].radarErrors.to_dict().values()): + self.events.add(EventName.radarFault) if not self.sm.valid['pandaStates']: self.events.add(EventName.usbError) if CS.canTimeout: From bdac9efa1e6b24bbc47203b05c75eeb5b56dd42a Mon Sep 17 00:00:00 2001 From: Armand du Parc Locmaria Date: Wed, 10 Jun 2026 17:06:09 -0700 Subject: [PATCH 020/151] modeld: compress modelV2 into drivingModelData (#38165) * modeld: compress modelV2 into drivingModelData * slightly better * less diff * whitespace * dedupe with migrate? * Revert "dedupe with migrate?" This reverts commit f31fe34994f4331f45e14a035df4847905d37540. --- selfdrive/modeld/fill_model_msg.py | 36 ++++++++++++++---------------- selfdrive/modeld/modeld.py | 7 +++--- 2 files changed, 20 insertions(+), 23 deletions(-) diff --git a/selfdrive/modeld/fill_model_msg.py b/selfdrive/modeld/fill_model_msg.py index 82c4c92b1d..8e63d29ea2 100644 --- a/selfdrive/modeld/fill_model_msg.py +++ b/selfdrive/modeld/fill_model_msg.py @@ -55,26 +55,29 @@ def fill_lane_line_meta(builder, lane_lines, lane_line_probs): builder.rightY = lane_lines[2].y[0] builder.rightProb = lane_line_probs[2] -def fill_model_msg(base_msg: capnp._DynamicStructBuilder, extended_msg: capnp._DynamicStructBuilder, - net_output_data: dict[str, np.ndarray], action: log.ModelDataV2.Action, +def fill_driving_model_data(msg: capnp._DynamicStructBuilder, modelv2_send: capnp._DynamicStructBuilder) -> None: + msg.valid = modelv2_send.valid + modelV2 = modelv2_send.modelV2 + driving_model_data = msg.drivingModelData + driving_model_data.frameId = modelV2.frameId + driving_model_data.frameIdExtra = modelV2.frameIdExtra + driving_model_data.frameDropPerc = modelV2.frameDropPerc + driving_model_data.modelExecutionTime = modelV2.modelExecutionTime + driving_model_data.action = modelV2.action + driving_model_data.meta.laneChangeState = modelV2.meta.laneChangeState + driving_model_data.meta.laneChangeDirection = modelV2.meta.laneChangeDirection + fill_lane_line_meta(driving_model_data.laneLineMeta, modelV2.laneLines, modelV2.laneLineProbs) + fill_xyz_poly(driving_model_data.path, ModelConstants.POLY_PATH_DEGREE, modelV2.position.x, modelV2.position.y, modelV2.position.z) + +def fill_model_msg(msg: capnp._DynamicStructBuilder, net_output_data: dict[str, np.ndarray], action: log.ModelDataV2.Action, publish_state: PublishState, vipc_frame_id: int, vipc_frame_id_extra: int, frame_id: int, frame_drop: float, timestamp_eof: int, model_execution_time: float, valid: bool) -> None: frame_age = frame_id - vipc_frame_id if frame_id > vipc_frame_id else 0 frame_drop_perc = frame_drop * 100 - extended_msg.valid = valid - base_msg.valid = valid + msg.valid = valid - driving_model_data = base_msg.drivingModelData - - driving_model_data.frameId = vipc_frame_id - driving_model_data.frameIdExtra = vipc_frame_id_extra - driving_model_data.frameDropPerc = frame_drop_perc - driving_model_data.modelExecutionTime = model_execution_time - - driving_model_data.action = action - - modelV2 = extended_msg.modelV2 + modelV2 = msg.modelV2 modelV2.frameId = vipc_frame_id modelV2.frameIdExtra = vipc_frame_id_extra modelV2.frameAge = frame_age @@ -89,9 +92,6 @@ def fill_model_msg(base_msg: capnp._DynamicStructBuilder, extended_msg: capnp._D fill_xyzt(modelV2.orientation, ModelConstants.T_IDXS, *net_output_data['plan'][0,:,Plan.T_FROM_CURRENT_EULER].T) fill_xyzt(modelV2.orientationRate, ModelConstants.T_IDXS, *net_output_data['plan'][0,:,Plan.ORIENTATION_RATE].T) - # poly path - fill_xyz_poly(driving_model_data.path, ModelConstants.POLY_PATH_DEGREE, *net_output_data['plan'][0,:,Plan.POSITION].T) - # action modelV2.action = action @@ -106,8 +106,6 @@ def fill_model_msg(base_msg: capnp._DynamicStructBuilder, extended_msg: capnp._D modelV2.laneLineStds = net_output_data['lane_lines_stds'][0,:,0,0].tolist() modelV2.laneLineProbs = net_output_data['lane_lines_prob'][0,1::2].tolist() - fill_lane_line_meta(driving_model_data.laneLineMeta, modelV2.laneLines, modelV2.laneLineProbs) - # road edges modelV2.init('roadEdges', 2) for i in range(2): diff --git a/selfdrive/modeld/modeld.py b/selfdrive/modeld/modeld.py index 49ea0d5cdf..cf53eb23d8 100755 --- a/selfdrive/modeld/modeld.py +++ b/selfdrive/modeld/modeld.py @@ -21,7 +21,7 @@ from openpilot.selfdrive.controls.lib.desire_helper import DesireHelper from openpilot.selfdrive.controls.lib.drive_helpers import get_accel_from_plan, smooth_value, get_curvature_from_plan from openpilot.selfdrive.modeld.parse_model_outputs import Parser from openpilot.selfdrive.modeld.compile_modeld import make_input_queues, WARP_INPUTS, POLICY_INPUTS -from openpilot.selfdrive.modeld.fill_model_msg import fill_model_msg, fill_pose_msg, PublishState +from openpilot.selfdrive.modeld.fill_model_msg import fill_model_msg, fill_driving_model_data, fill_pose_msg, PublishState from openpilot.common.file_chunker import read_file_chunked, get_manifest_path from openpilot.selfdrive.modeld.constants import ModelConstants, Plan from openpilot.selfdrive.modeld.helpers import usbgpu_present, modeld_pkl_path, get_tg_input_devices @@ -311,7 +311,7 @@ def main(demo=False): action = get_action_from_model(model_output, prev_action, lat_action_t, long_action_t, v_ego) prev_action = action - fill_model_msg(drivingdata_send, modelv2_send, model_output, action, + fill_model_msg(modelv2_send, model_output, action, publish_state, meta_main.frame_id, meta_extra.frame_id, frame_id, frame_drop_ratio, meta_main.timestamp_eof, model_execution_time, live_calib_seen) @@ -322,9 +322,8 @@ def main(demo=False): DH.update(sm['carState'], sm['carControl'].latActive, lane_change_prob) modelv2_send.modelV2.meta.laneChangeState = DH.lane_change_state modelv2_send.modelV2.meta.laneChangeDirection = DH.lane_change_direction - drivingdata_send.drivingModelData.meta.laneChangeState = DH.lane_change_state - drivingdata_send.drivingModelData.meta.laneChangeDirection = DH.lane_change_direction + fill_driving_model_data(drivingdata_send, modelv2_send) fill_pose_msg(posenet_send, model_output, meta_main.frame_id, vipc_dropped_frames, meta_main.timestamp_eof, live_calib_seen) pm.send('modelV2', modelv2_send) pm.send('drivingModelData', drivingdata_send) From 7661e03d1e3f666781f56feb48c031293757fdd3 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Wed, 10 Jun 2026 18:51:28 -0700 Subject: [PATCH 021/151] bump opendbc (#38167) bump --- opendbc_repo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opendbc_repo b/opendbc_repo index e23d405ab3..e5d654dac2 160000 --- a/opendbc_repo +++ b/opendbc_repo @@ -1 +1 @@ -Subproject commit e23d405ab3beb31de503400acd47d9c390564a8d +Subproject commit e5d654dac2dd52e4d02f6ba97d8d02bc089f8e00 From 5a7b710d9058ca3c889cb5e56da8b8cb9c088308 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20R=C4=85czy?= Date: Thu, 11 Jun 2026 02:25:23 +0000 Subject: [PATCH 022/151] lagd: invalidate cached estimates on major estimator update (#38162) * Versioning * comment * Tests * fix issues --- cereal/log.capnp | 1 + selfdrive/locationd/lagd.py | 6 +++++- selfdrive/locationd/test/test_lagd.py | 17 ++++++++++++++++- 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/cereal/log.capnp b/cereal/log.capnp index b7202dfcf7..6cf4781228 100644 --- a/cereal/log.capnp +++ b/cereal/log.capnp @@ -2259,6 +2259,7 @@ struct LiveDelayData { lateralDelayEstimateStd @5 :Float32; points @4 :List(Float32); calPerc @6 :Int8; + version @7 :Int32; enum Status { unestimated @0; diff --git a/selfdrive/locationd/lagd.py b/selfdrive/locationd/lagd.py index 2df3dc9ad9..0069bb51b9 100755 --- a/selfdrive/locationd/lagd.py +++ b/selfdrive/locationd/lagd.py @@ -36,6 +36,8 @@ LAG_CANDIDATE_CORR_THRESHOLD = 0.9 SMOOTH_K = 5 SMOOTH_SIGMA = 1.0 +VERSION = 1 # bump this to invalidate old parameter caches + def masked_symmetric_moving_average(x: np.ndarray, mask: np.ndarray, k: int, sigma: float) -> np.ndarray: assert k >= 1 and k % 2 == 1, "k must be positive and odd" @@ -248,6 +250,7 @@ class LateralLagEstimator: (self.min_valid_block_count * self.block_size), 100) if debug: liveDelay.points = self.block_avg.values.flatten().tolist() + liveDelay.version = VERSION return msg @@ -368,9 +371,10 @@ def retrieve_initial_lag(params: Params, CP: car.CarParams): if last_CP.carFingerprint != CP.carFingerprint: raise Exception("Car model mismatch") - lag, valid_blocks, status = ld.lateralDelayEstimate, ld.validBlocks, ld.status + lag, valid_blocks, status, version = ld.lateralDelayEstimate, ld.validBlocks, ld.status, ld.version assert valid_blocks <= BLOCK_NUM, "Invalid number of valid blocks" assert status != log.LiveDelayData.Status.invalid, "Lag estimate is invalid" + assert version == VERSION, f"Lag estimate is from a different version (got {version}, expected {VERSION})" return lag, valid_blocks except Exception as e: cloudlog.error(f"Failed to retrieve initial lag: {e}") diff --git a/selfdrive/locationd/test/test_lagd.py b/selfdrive/locationd/test/test_lagd.py index 7e8d79a7de..0c4e227192 100644 --- a/selfdrive/locationd/test/test_lagd.py +++ b/selfdrive/locationd/test/test_lagd.py @@ -5,7 +5,7 @@ import pytest from cereal import messaging, log, car from openpilot.selfdrive.locationd.lagd import LateralLagEstimator, retrieve_initial_lag, masked_normalized_cross_correlation, \ - BLOCK_NUM_NEEDED, BLOCK_SIZE, MIN_OKAY_WINDOW_SEC + BLOCK_NUM_NEEDED, BLOCK_SIZE, MIN_OKAY_WINDOW_SEC, VERSION from openpilot.selfdrive.test.process_replay.migration import migrate, migrate_carParams from openpilot.selfdrive.locationd.test.test_locationd_scenarios import TEST_ROUTE from openpilot.common.params import Params @@ -53,6 +53,7 @@ class TestLagd: msg = messaging.new_message('liveDelay') msg.liveDelay.lateralDelayEstimate = random.random() msg.liveDelay.validBlocks = random.randint(1, 10) + msg.liveDelay.version = VERSION params.put("LiveDelay", msg.to_bytes(), block=True) params.put("CarParamsPrevRoute", CP.as_builder().to_bytes(), block=True) @@ -63,6 +64,20 @@ class TestLagd: assert lag == msg.liveDelay.lateralDelayEstimate assert valid_blocks == msg.liveDelay.validBlocks + def test_read_invalid_saved_params(self, subtests): + params = Params() + + lr = migrate(LogReader(TEST_ROUTE), [migrate_carParams]) + CP = next(m for m in lr if m.which() == "carParams").carParams + + for msg_dict in [{'version': 0}, {'status': 'invalid'}, {'validBlocks': 100}]: + with subtests.test(msg=f"liveDelay={msg_dict}"): + msg = messaging.new_message('liveDelay') + msg.liveDelay = msg_dict + params.put("LiveDelay", msg.to_bytes(), block=True) + params.put("CarParamsPrevRoute", CP.as_builder().to_bytes(), block=True) + assert retrieve_initial_lag(params, CP) is None + def test_ncc(self): lag_frames = random.randint(1, 19) From 98e5f547ea1ca1302e729e2aab9d972738503e78 Mon Sep 17 00:00:00 2001 From: stef <19478336+stefpi@users.noreply.github.com> Date: Wed, 10 Jun 2026 22:28:26 -0400 Subject: [PATCH 023/151] fix(athena): outbound rpc stuck behind low prio queue timeout (#38160) * priority queue instead of 2 queues * add assert on priority instead of default * fix lint --- system/athena/athenad.py | 26 +++++++++++++++----------- system/athena/tests/test_athenad.py | 4 ++-- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/system/athena/athenad.py b/system/athena/athenad.py index 6bccaae63e..870d271624 100755 --- a/system/athena/athenad.py +++ b/system/athena/athenad.py @@ -4,6 +4,7 @@ from __future__ import annotations import base64 import hashlib import io +import itertools import json import os import queue @@ -57,6 +58,9 @@ WS_FRAME_SIZE = 4096 DEVICE_STATE_UPDATE_INTERVAL = 1.0 # in seconds DEFAULT_UPLOAD_PRIORITY = 99 # higher number = lower priority +SEND_PRIORITY_HIGH = 0 +SEND_PRIORITY_LOW = 1 + # https://bytesolutions.com/dscp-tos-cos-precedence-conversion-chart, # https://en.wikipedia.org/wiki/Differentiated_services UPLOAD_TOS = 0x20 # CS1, low priority background traffic @@ -126,14 +130,18 @@ class UploadItem: dispatcher["echo"] = lambda s: s recv_queue: Queue[str] = queue.Queue() -send_queue: Queue[str] = queue.Queue() +send_queue: Queue[tuple[int, int, str]] = queue.PriorityQueue() upload_queue: Queue[UploadItem] = queue.PriorityQueue() -low_priority_send_queue: Queue[str] = queue.Queue() log_recv_queue: Queue[str] = queue.Queue() cancelled_uploads: set[str] = set() cur_upload_items: dict[int, UploadItem | None] = {} +send_seq = itertools.count() +def send_queue_push(data: str, priority: int) -> None: + assert priority is not None, "send queue priority must be specified" + send_queue.put_nowait((priority, next(send_seq), data)) # tie-break with a monotonic counter + def strip_zst_extension(fn: str) -> str: if fn.endswith('.zst'): @@ -208,7 +216,7 @@ def jsonrpc_handler(end_event: threading.Event) -> None: if "method" in data: cloudlog.event("athena.jsonrpc_handler.call_method", data=data) response = JSONRPCResponseManager.handle(data, dispatcher) - send_queue.put_nowait(response.json) + send_queue_push(response.json, SEND_PRIORITY_HIGH) elif "id" in data and ("result" in data or "error" in data): log_recv_queue.put_nowait(data) else: @@ -217,7 +225,7 @@ def jsonrpc_handler(end_event: threading.Event) -> None: pass except Exception as e: cloudlog.exception("athena jsonrpc handler failed") - send_queue.put_nowait(json.dumps({"error": str(e)})) + send_queue_push(json.dumps({"error": str(e)}), SEND_PRIORITY_HIGH) def retry_upload(tid: int, end_event: threading.Event, increase_count: bool = True) -> None: @@ -596,7 +604,6 @@ def startStream(sdp: str) -> dict: except requests.ConnectionError as e: raise Exception("webrtc is not running. turn on comma body ignition.") from e - @dispatcher.add_method def takeSnapshot() -> str | dict[str, str] | None: from openpilot.system.camerad.snapshot import jpeg_write, snapshot @@ -666,7 +673,7 @@ def log_handler(end_event: threading.Event) -> None: "jsonrpc": "2.0", "id": log_entry } - low_priority_send_queue.put_nowait(json.dumps(jsonrpc)) + send_queue_push(json.dumps(jsonrpc), SEND_PRIORITY_LOW) curr_log = log_entry except OSError: pass # file could be deleted by log rotation @@ -717,7 +724,7 @@ def stat_handler(end_event: threading.Event) -> None: "jsonrpc": "2.0", "id": stat_filenames[0] } - low_priority_send_queue.put_nowait(json.dumps(jsonrpc)) + send_queue_push(json.dumps(jsonrpc), SEND_PRIORITY_LOW) os.remove(stat_path) last_scan = curr_scan except Exception: @@ -799,10 +806,7 @@ def ws_recv(ws: WebSocket, end_event: threading.Event) -> None: def ws_send(ws: WebSocket, end_event: threading.Event) -> None: while not end_event.is_set(): try: - try: - data = send_queue.get_nowait() - except queue.Empty: - data = low_priority_send_queue.get(timeout=1) + _, _, data = send_queue.get(timeout=1) for i in range(0, len(data), WS_FRAME_SIZE): frame = data[i:i+WS_FRAME_SIZE] last = i + WS_FRAME_SIZE >= len(data) diff --git a/system/athena/tests/test_athenad.py b/system/athena/tests/test_athenad.py index b0c20a26a9..33b0113b32 100644 --- a/system/athena/tests/test_athenad.py +++ b/system/athena/tests/test_athenad.py @@ -422,11 +422,11 @@ class TestAthenadMethods: try: # with params athenad.recv_queue.put_nowait(json.dumps({"method": "echo", "params": ["hello"], "jsonrpc": "2.0", "id": 0})) - resp = athenad.send_queue.get(timeout=3) + _, _, resp = athenad.send_queue.get(timeout=3) assert json.loads(resp) == {'result': 'hello', 'id': 0, 'jsonrpc': '2.0'} # without params athenad.recv_queue.put_nowait(json.dumps({"method": "getNetworkType", "jsonrpc": "2.0", "id": 0})) - resp = athenad.send_queue.get(timeout=3) + _, _, resp = athenad.send_queue.get(timeout=3) assert json.loads(resp) == {'result': 1, 'id': 0, 'jsonrpc': '2.0'} # log forwarding athenad.recv_queue.put_nowait(json.dumps({'result': {'success': 1}, 'id': 0, 'jsonrpc': '2.0'})) From b2bb71b4b76260b9df0456dd43418135564c9f90 Mon Sep 17 00:00:00 2001 From: Armand du Parc Locmaria Date: Wed, 10 Jun 2026 22:02:28 -0700 Subject: [PATCH 024/151] modeld: less cross device copies (#38168) * single copy for frames * single copy out * missed this * pack npy inputs to the policy * strict zip * strict zip --- selfdrive/modeld/compile_modeld.py | 46 ++++++++++++++++-------------- selfdrive/modeld/modeld.py | 8 +++--- 2 files changed, 29 insertions(+), 25 deletions(-) diff --git a/selfdrive/modeld/compile_modeld.py b/selfdrive/modeld/compile_modeld.py index 8d6058f39d..81d0a30033 100755 --- a/selfdrive/modeld/compile_modeld.py +++ b/selfdrive/modeld/compile_modeld.py @@ -1,6 +1,7 @@ #!/usr/bin/env python3 import argparse import atexit +import math import os import pickle import time @@ -33,7 +34,7 @@ from tinygrad.engine.jit import TinyJit NV12Frame = namedtuple("NV12Frame", ['width', 'height', 'stride', 'y_height', 'uv_height', 'size']) WARP_INPUTS = ['img_q', 'big_img_q', 'tfm', 'big_tfm'] -POLICY_INPUTS = ['feat_q', 'desire_q', 'desire', 'traffic_convention', 'action_t'] +POLICY_INPUTS = ['feat_q', 'desire_q', 'packed_npy_inputs'] UV_SCALE_MATRIX = np.array([[0.5, 0, 0], [0, 0.5, 0], [0, 0, 1]], dtype=np.float32) UV_SCALE_MATRIX_INV = np.linalg.inv(UV_SCALE_MATRIX) @@ -130,25 +131,28 @@ def make_warp_input_queues(vision_input_shapes, frame_skip, device): return input_queues, npy +def get_policy_npy_shapes(policy_input_shapes): + dp = policy_input_shapes['desire_pulse'] # (1, 25, 8) + tc = policy_input_shapes['traffic_convention'] # (1, 2) + #TODO action_t is hardcoded to match tc for future compatibility + shapes = {'desire': (dp[2],), 'traffic_convention': tuple(tc), 'action_t': tuple(tc)} + return shapes, [math.prod(s) for s in shapes.values()] + + def make_input_queues(vision_input_shapes, policy_input_shapes, frame_skip, device): input_queues, npy = make_warp_input_queues(vision_input_shapes, frame_skip, device) fb = policy_input_shapes['features_buffer'] # (1, 25, 512) dp = policy_input_shapes['desire_pulse'] # (1, 25, 8) - tc = policy_input_shapes['traffic_convention'] # (1, 2) - #TODO action_t is hardcoded to match tc for future compatibility - at = tc - policy_npy = { - 'desire': np.zeros(dp[2], dtype=np.float32), - 'traffic_convention': np.zeros(tc, dtype=np.float32), - 'action_t': np.zeros(at, dtype=np.float32), - } - npy.update(policy_npy) + shapes, sizes = get_policy_npy_shapes(policy_input_shapes) + packed_npy_inputs = np.zeros(sum(sizes), dtype=np.float32) + # views into the packed inputs, to be refilled at runtime + npy.update({k: v.reshape(s) for (k, s), v in zip(shapes.items(), np.split(packed_npy_inputs, np.cumsum(sizes[:-1])), strict=True)}) input_queues.update({ 'feat_q': Tensor(np.zeros((frame_skip * (fb[1] - 1) + 1, fb[0], fb[2]), dtype=np.float32), device=device).contiguous().realize(), 'desire_q': Tensor(np.zeros((frame_skip * dp[1], dp[0], dp[2]), dtype=np.float32), device=device).contiguous().realize(), - **{k: Tensor(v, device='NPY').realize() for k, v in policy_npy.items()}, + 'packed_npy_inputs': Tensor(packed_npy_inputs, device='NPY').realize(), }) return input_queues, npy @@ -175,10 +179,11 @@ def make_warp(nv12, model_w, model_h, frame_skip): big_tfm = big_tfm.to(WARP_DEV) Tensor.realize(tfm, big_tfm) - warped_frame = frame_prepare(frame, tfm).unsqueeze(0).to(Device.DEFAULT) - warped_big_frame = frame_prepare(big_frame, big_tfm).unsqueeze(0).to(Device.DEFAULT) - img = shift_and_sample(img_q, warped_frame, sample_skip_fn) - big_img = shift_and_sample(big_img_q, warped_big_frame, sample_skip_fn) + warped_frame = frame_prepare(frame, tfm).unsqueeze(0) + warped_big_frame = frame_prepare(big_frame, big_tfm).unsqueeze(0) + warped = Tensor.cat(warped_frame, warped_big_frame).to(Device.DEFAULT) + img = shift_and_sample(img_q, warped[0:1], sample_skip_fn) + big_img = shift_and_sample(big_img_q, warped[1:2], sample_skip_fn) return img, big_img return warp_enqueue @@ -187,12 +192,11 @@ def make_run_policy(model_runners, model_metadata, frame_skip): sample_desire_fn = partial(sample_desire, frame_skip=frame_skip) sample_skip_fn = partial(sample_skip, frame_skip=frame_skip) vision_features_slice = model_metadata['vision']['output_slices']['hidden_state'] + npy_shapes, npy_sizes = get_policy_npy_shapes(model_metadata['on_policy']['input_shapes']) - def run_policy(img, big_img, feat_q, desire_q, desire, traffic_convention, action_t): - desire = desire.to(Device.DEFAULT) - traffic_convention = traffic_convention.to(Device.DEFAULT) - action_t = action_t.to(Device.DEFAULT) - Tensor.realize(desire, traffic_convention, action_t) + def run_policy(img, big_img, feat_q, desire_q, packed_npy_inputs): + packed_npy_inputs = packed_npy_inputs.to(Device.DEFAULT).realize() + desire, traffic_convention, action_t = (t.reshape(s) for t, s in zip(packed_npy_inputs.split(npy_sizes), npy_shapes.values(), strict=True)) desire_buf = shift_and_sample(desire_q, desire.reshape(1, 1, -1), sample_desire_fn) vision_out = next(iter(model_runners['vision']({'img': img, 'big_img': big_img}).values())).cast('float32') @@ -207,7 +211,7 @@ def make_run_policy(model_runners, model_metadata, frame_skip): } on_policy_out = next(iter(model_runners['on_policy'](inputs).values())).cast('float32') off_policy_out = next(iter(model_runners['off_policy'](inputs).values())).cast('float32') - return vision_out, on_policy_out, off_policy_out + return Tensor.cat(vision_out, on_policy_out, off_policy_out, dim=1), return run_policy diff --git a/selfdrive/modeld/modeld.py b/selfdrive/modeld/modeld.py index cf53eb23d8..7e4976bf5e 100755 --- a/selfdrive/modeld/modeld.py +++ b/selfdrive/modeld/modeld.py @@ -83,6 +83,7 @@ class ModelState: self.vision_input_shapes = vision_metadata['input_shapes'] self.vision_input_names = list(self.vision_input_shapes.keys()) self.vision_output_slices = vision_metadata['output_slices'] + self.vision_output_len = vision_metadata['output_shapes']['outputs'][1] off_policy_metadata = jits['metadata']['off_policy'] self.off_policy_output_slices = off_policy_metadata['output_slices'] @@ -90,6 +91,7 @@ class ModelState: policy_metadata = jits['metadata']['on_policy'] self.policy_input_shapes = policy_metadata['input_shapes'] self.policy_output_slices = policy_metadata['output_slices'] + self.on_policy_output_len = policy_metadata['output_shapes']['outputs'][1] self.prev_desire = np.zeros(ModelConstants.DESIRE_LEN, dtype=np.float32) @@ -131,13 +133,11 @@ class ModelState: if prepare_only: return None - vision_output, on_policy_output, off_policy_output = self.run_policy( + outs, = self.run_policy( **{k: self.input_queues[k] for k in POLICY_INPUTS if k in self.input_queues}, img=img, big_img=big_img ) + vision_output, on_policy_output, off_policy_output = np.split(outs.numpy()[0], [self.vision_output_len, self.vision_output_len+self.on_policy_output_len]) - vision_output = vision_output.numpy().flatten() - off_policy_output = off_policy_output.numpy().flatten() - on_policy_output = on_policy_output.numpy().flatten() vision_outputs_dict = self.parser.parse_vision_outputs(self.slice_outputs(vision_output, self.vision_output_slices)) off_policy_outputs_dict = self.parser.parse_off_policy_outputs(self.slice_outputs(off_policy_output, self.off_policy_output_slices)) policy_outputs_dict = self.parser.parse_policy_outputs(self.slice_outputs(on_policy_output, self.policy_output_slices)) From 4024d13ddabbb23aca2399603957096b0921b4d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Harald=20Sch=C3=A4fer?= Date: Thu, 11 Jun 2026 09:32:24 -0700 Subject: [PATCH 025/151] Revert "Op model16 deep (#38073)" (#38166) This reverts commit f02d134f40f5e7be22b182af21b438915a47600e. --- selfdrive/modeld/SConscript | 3 +-- selfdrive/modeld/compile_modeld.py | 7 +------ selfdrive/modeld/modeld.py | 12 +++--------- .../modeld/models/big_driving_off_policy.onnx | 3 --- selfdrive/modeld/models/big_driving_on_policy.onnx | 4 ++-- selfdrive/modeld/models/big_driving_vision.onnx | 4 ++-- selfdrive/modeld/models/driving_off_policy.onnx | 3 --- selfdrive/modeld/models/driving_on_policy.onnx | 4 ++-- selfdrive/modeld/models/driving_vision.onnx | 4 ++-- selfdrive/modeld/parse_model_outputs.py | 14 ++++---------- selfdrive/test/process_replay/model_replay.py | 2 +- system/hardware/tici/tests/test_power_draw.py | 2 +- tinygrad_repo | 2 +- 13 files changed, 20 insertions(+), 44 deletions(-) delete mode 100644 selfdrive/modeld/models/big_driving_off_policy.onnx delete mode 100644 selfdrive/modeld/models/driving_off_policy.onnx diff --git a/selfdrive/modeld/SConscript b/selfdrive/modeld/SConscript index c13842115d..80a7df4515 100644 --- a/selfdrive/modeld/SConscript +++ b/selfdrive/modeld/SConscript @@ -87,14 +87,13 @@ frame_skip = ModelConstants.MODEL_RUN_FREQ // ModelConstants.MODEL_CONTEXT_FREQ for usbgpu in [False, True] if USBGPU else [False]: target_pkl_path = File(modeld_pkl_path(usbgpu)).abspath file_prefix, cmd_flags = ('big_', usbgpu_tg_flags) if usbgpu else ('', tg_flags) - driving_onnx_deps = [p for m in [f'{file_prefix}driving_vision', f'{file_prefix}driving_on_policy', f'{file_prefix}driving_off_policy'] + driving_onnx_deps = [p for m in [f'{file_prefix}driving_vision', f'{file_prefix}driving_on_policy'] for p in get_existing_chunks(File(f"models/{m}.onnx").abspath)] camera_res_args = ' '.join(f'{cw}x{ch}' for cw, ch in CAMERA_CONFIGS) cmd = (f'{cmd_flags} {mac_brew_string} python3 {modeld_dir}/compile_modeld.py ' f'--model-size {model_w}x{model_h} ' f'--camera-resolutions {camera_res_args} ' f'--vision-onnx {File(f"models/{file_prefix}driving_vision.onnx").abspath} ' - f'--off-policy-onnx {File(f"models/{file_prefix}driving_off_policy.onnx").abspath} ' f'--on-policy-onnx {File(f"models/{file_prefix}driving_on_policy.onnx").abspath} ' f'--output {target_pkl_path} --frame-skip {frame_skip}') onnx_sizes_sum = sum(os.path.getsize(f) for f in driving_onnx_deps) diff --git a/selfdrive/modeld/compile_modeld.py b/selfdrive/modeld/compile_modeld.py index 81d0a30033..1a137a34b6 100755 --- a/selfdrive/modeld/compile_modeld.py +++ b/selfdrive/modeld/compile_modeld.py @@ -210,8 +210,7 @@ def make_run_policy(model_runners, model_metadata, frame_skip): 'action_t': action_t, } on_policy_out = next(iter(model_runners['on_policy'](inputs).values())).cast('float32') - off_policy_out = next(iter(model_runners['off_policy'](inputs).values())).cast('float32') - return Tensor.cat(vision_out, on_policy_out, off_policy_out, dim=1), + return Tensor.cat(vision_out, on_policy_out, dim=1), return run_policy @@ -282,7 +281,6 @@ if __name__ == "__main__": p.add_argument('--camera-resolutions', type=_parse_size, nargs='+', required=True, help='camera resolutions WxH (one or more)') p.add_argument('--vision-onnx', required=True) - p.add_argument('--off-policy-onnx', required=True) p.add_argument('--on-policy-onnx', required=True) p.add_argument('--output', required=True) p.add_argument('--frame-skip', type=int, required=True) @@ -290,7 +288,6 @@ if __name__ == "__main__": model_paths = { 'vision': read_file_chunked_to_shm(args.vision_onnx), - 'off_policy': read_file_chunked_to_shm(args.off_policy_onnx), 'on_policy': read_file_chunked_to_shm(args.on_policy_onnx), } model_w, model_h = args.model_size @@ -298,8 +295,6 @@ if __name__ == "__main__": model_runners = {name: OnnxRunner(path) for name, path in model_paths.items()} out = {'metadata': {name: make_metadata_dict(path) for name, path in model_paths.items()}} - assert out['metadata']['off_policy']['input_shapes'] == out['metadata']['on_policy']['input_shapes'] - run_policy_jit = TinyJit(make_run_policy(model_runners, out['metadata'], args.frame_skip), prune=True) make_policy_queues = partial(make_input_queues, out['metadata']['vision']['input_shapes'], diff --git a/selfdrive/modeld/modeld.py b/selfdrive/modeld/modeld.py index 7e4976bf5e..7505ddf182 100755 --- a/selfdrive/modeld/modeld.py +++ b/selfdrive/modeld/modeld.py @@ -85,13 +85,9 @@ class ModelState: self.vision_output_slices = vision_metadata['output_slices'] self.vision_output_len = vision_metadata['output_shapes']['outputs'][1] - off_policy_metadata = jits['metadata']['off_policy'] - self.off_policy_output_slices = off_policy_metadata['output_slices'] - policy_metadata = jits['metadata']['on_policy'] self.policy_input_shapes = policy_metadata['input_shapes'] self.policy_output_slices = policy_metadata['output_slices'] - self.on_policy_output_len = policy_metadata['output_shapes']['outputs'][1] self.prev_desire = np.zeros(ModelConstants.DESIRE_LEN, dtype=np.float32) @@ -136,15 +132,13 @@ class ModelState: outs, = self.run_policy( **{k: self.input_queues[k] for k in POLICY_INPUTS if k in self.input_queues}, img=img, big_img=big_img ) - vision_output, on_policy_output, off_policy_output = np.split(outs.numpy()[0], [self.vision_output_len, self.vision_output_len+self.on_policy_output_len]) - + vision_output, on_policy_output = np.split(outs.numpy()[0], [self.vision_output_len]) vision_outputs_dict = self.parser.parse_vision_outputs(self.slice_outputs(vision_output, self.vision_output_slices)) - off_policy_outputs_dict = self.parser.parse_off_policy_outputs(self.slice_outputs(off_policy_output, self.off_policy_output_slices)) policy_outputs_dict = self.parser.parse_policy_outputs(self.slice_outputs(on_policy_output, self.policy_output_slices)) - combined_outputs_dict = {**vision_outputs_dict, **off_policy_outputs_dict, **policy_outputs_dict} + combined_outputs_dict = {**vision_outputs_dict, **policy_outputs_dict} if SEND_RAW_PRED: - combined_outputs_dict['raw_pred'] = np.concatenate([vision_output.copy(), on_policy_output.copy(), off_policy_output.copy()]) + combined_outputs_dict['raw_pred'] = np.concatenate([vision_output.copy(), on_policy_output.copy()]) return combined_outputs_dict diff --git a/selfdrive/modeld/models/big_driving_off_policy.onnx b/selfdrive/modeld/models/big_driving_off_policy.onnx deleted file mode 100644 index 715f9f9c99..0000000000 --- a/selfdrive/modeld/models/big_driving_off_policy.onnx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:8a26866121d1d3a1152bfce024ed7584b8569507d120d4bc8917320093dcd31a -size 41191256 diff --git a/selfdrive/modeld/models/big_driving_on_policy.onnx b/selfdrive/modeld/models/big_driving_on_policy.onnx index 6011d4be22..f7b49c018a 100644 --- a/selfdrive/modeld/models/big_driving_on_policy.onnx +++ b/selfdrive/modeld/models/big_driving_on_policy.onnx @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:94b07ef7a0f65d5c41ac696b4ae7bdc59e2d4c5f504460e2b0d720620892c2e8 -size 33679037 +oid sha256:565e53c38dcd64c50dd3fe4d5ee1530213aeefd66c3f6b67ea6a72a32612a6bf +size 14061419 diff --git a/selfdrive/modeld/models/big_driving_vision.onnx b/selfdrive/modeld/models/big_driving_vision.onnx index bfebd4f7a6..d14f1969e0 100644 --- a/selfdrive/modeld/models/big_driving_vision.onnx +++ b/selfdrive/modeld/models/big_driving_vision.onnx @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:eda005282417ffa825092ece5c16b5584142044cdbcf15b6d0246136ac6db601 -size 120584466 +oid sha256:1f0cab5033fe9e3bc5e174a2e790fa277f7d9fc44c65822d734064d2f899a9a0 +size 296203378 diff --git a/selfdrive/modeld/models/driving_off_policy.onnx b/selfdrive/modeld/models/driving_off_policy.onnx deleted file mode 100644 index 673f7949f8..0000000000 --- a/selfdrive/modeld/models/driving_off_policy.onnx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:6173be8a69b1d9633a09969c80b2a8bd990bfe7d3e76e192a0e537f6fd72222b -size 41192485 diff --git a/selfdrive/modeld/models/driving_on_policy.onnx b/selfdrive/modeld/models/driving_on_policy.onnx index dc9f587949..611ae9fe85 100644 --- a/selfdrive/modeld/models/driving_on_policy.onnx +++ b/selfdrive/modeld/models/driving_on_policy.onnx @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6b66ef783af3fa86190e85a6b4f729cd1443b20be41134aa258f9c376825a45c -size 33680163 +oid sha256:78477124cbf3ffe30fa951ebada8410b43c4242c6054584d656f1d329b067e15 +size 14060847 diff --git a/selfdrive/modeld/models/driving_vision.onnx b/selfdrive/modeld/models/driving_vision.onnx index 6bfff25c21..6c9fc4c84d 100644 --- a/selfdrive/modeld/models/driving_vision.onnx +++ b/selfdrive/modeld/models/driving_vision.onnx @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bbd0761201b3b161587d097f173c66bf82cd02966e5f0d1edd888c970d6f6d87 -size 21735970 +oid sha256:ee29ee5bce84d1ce23e9ff381280de9b4e4d96d2934cd751740354884e112c66 +size 46877473 diff --git a/selfdrive/modeld/parse_model_outputs.py b/selfdrive/modeld/parse_model_outputs.py index 3b35c15acb..26c138b8ec 100644 --- a/selfdrive/modeld/parse_model_outputs.py +++ b/selfdrive/modeld/parse_model_outputs.py @@ -96,17 +96,11 @@ class Parser: self.parse_mdn('pose', outs, in_N=0, out_N=0, out_shape=(ModelConstants.POSE_WIDTH,)) self.parse_mdn('wide_from_device_euler', outs, in_N=0, out_N=0, out_shape=(ModelConstants.WIDE_FROM_DEVICE_WIDTH,)) self.parse_mdn('road_transform', outs, in_N=0, out_N=0, out_shape=(ModelConstants.POSE_WIDTH,)) - self.parse_categorical_crossentropy('desire_pred', outs, out_shape=(ModelConstants.DESIRE_PRED_LEN,ModelConstants.DESIRE_PRED_WIDTH)) - self.parse_binary_crossentropy('meta', outs) self.parse_mdn('lane_lines', outs, in_N=0, out_N=0, out_shape=(ModelConstants.NUM_LANE_LINES,ModelConstants.IDX_N,ModelConstants.LANE_LINES_WIDTH)) self.parse_mdn('road_edges', outs, in_N=0, out_N=0, out_shape=(ModelConstants.NUM_ROAD_EDGES,ModelConstants.IDX_N,ModelConstants.LANE_LINES_WIDTH)) self.parse_binary_crossentropy('lane_lines_prob', outs) - return outs - - def parse_off_policy_outputs(self, outs: dict[str, np.ndarray]) -> dict[str, np.ndarray]: - plan_mhp = self.is_mhp(outs, 'plan', ModelConstants.IDX_N * ModelConstants.PLAN_WIDTH) - plan_in_N, plan_out_N = (ModelConstants.PLAN_MHP_N, ModelConstants.PLAN_MHP_SELECTION) if plan_mhp else (0, 0) - self.parse_mdn('plan', outs, in_N=plan_in_N, out_N=plan_out_N, out_shape=(ModelConstants.IDX_N, ModelConstants.PLAN_WIDTH)) + self.parse_categorical_crossentropy('desire_pred', outs, out_shape=(ModelConstants.DESIRE_PRED_LEN,ModelConstants.DESIRE_PRED_WIDTH)) + self.parse_binary_crossentropy('meta', outs) self.parse_binary_crossentropy('lead_prob', outs) lead_mhp = self.is_mhp(outs, 'lead', ModelConstants.LEAD_MHP_SELECTION * ModelConstants.LEAD_TRAJ_LEN * ModelConstants.LEAD_WIDTH) lead_in_N, lead_out_N = (ModelConstants.LEAD_MHP_N, ModelConstants.LEAD_MHP_SELECTION) if lead_mhp else (0, 0) @@ -116,11 +110,11 @@ class Parser: return outs def parse_policy_outputs(self, outs: dict[str, np.ndarray]) -> dict[str, np.ndarray]: - self.parse_mdn('action', outs, in_N=0, out_N=0, out_shape=(ModelConstants.ACTION_WIDTH,)) + self.parse_mdn('plan', outs, in_N=0, out_N=0, out_shape=(ModelConstants.IDX_N, ModelConstants.PLAN_WIDTH)) + self.parse_categorical_crossentropy('desire_state', outs, out_shape=(ModelConstants.DESIRE_PRED_WIDTH,)) return outs def parse_outputs(self, outs: dict[str, np.ndarray]) -> dict[str, np.ndarray]: outs = self.parse_vision_outputs(outs) - outs = self.parse_off_policy_outputs(outs) outs = self.parse_policy_outputs(outs) return outs diff --git a/selfdrive/test/process_replay/model_replay.py b/selfdrive/test/process_replay/model_replay.py index 7cbdc73a61..266f66aaf2 100755 --- a/selfdrive/test/process_replay/model_replay.py +++ b/selfdrive/test/process_replay/model_replay.py @@ -34,7 +34,7 @@ GITHUB = GithubUtils(API_TOKEN, DATA_TOKEN) EXEC_TIMINGS = [ # model, instant max, average max - ("modelV2", 0.05, 0.033), + ("modelV2", 0.05, 0.028), ("driverStateV2", 0.05, 0.018), ] diff --git a/system/hardware/tici/tests/test_power_draw.py b/system/hardware/tici/tests/test_power_draw.py index 2de2efe2d8..6656addf73 100644 --- a/system/hardware/tici/tests/test_power_draw.py +++ b/system/hardware/tici/tests/test_power_draw.py @@ -32,7 +32,7 @@ class Proc: PROCS = [ Proc(['camerad'], 1.65, atol=0.4, msgs=['roadCameraState', 'wideRoadCameraState', 'driverCameraState']), - Proc(['modeld'], 1.8, atol=0.2, msgs=['modelV2']), + Proc(['modeld'], 1.5, atol=0.2, msgs=['modelV2']), Proc(['dmonitoringmodeld'], 0.65, atol=0.35, msgs=['driverStateV2']), Proc(['encoderd'], 0.23, msgs=[]), ] diff --git a/tinygrad_repo b/tinygrad_repo index fd992d6684..556defa0f7 160000 --- a/tinygrad_repo +++ b/tinygrad_repo @@ -1 +1 @@ -Subproject commit fd992d668400ded1b0114f0a741fc37214fbc4a4 +Subproject commit 556defa0f78ed10b6ce675a2fa15a1c2521b5e93 From 9ef3cfdf9adef89dd169ab126e473ca329cb4ce8 Mon Sep 17 00:00:00 2001 From: YassineYousfi Date: Thu, 11 Jun 2026 12:29:56 -0700 Subject: [PATCH 026/151] compile modeld: use tmp file name (#38170) --- selfdrive/modeld/compile_modeld.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/selfdrive/modeld/compile_modeld.py b/selfdrive/modeld/compile_modeld.py index 1a137a34b6..bc8caca7e6 100755 --- a/selfdrive/modeld/compile_modeld.py +++ b/selfdrive/modeld/compile_modeld.py @@ -4,6 +4,7 @@ import atexit import math import os import pickle +import tempfile import time from functools import partial from collections import namedtuple @@ -265,11 +266,11 @@ def _parse_size(s): def read_file_chunked_to_shm(path): from openpilot.common.file_chunker import read_file_chunked from openpilot.system.hardware.hw import Paths - shm_path = os.path.join(Paths.shm_path(), os.path.basename(path)) - atexit.register(lambda: os.path.exists(shm_path) and os.remove(shm_path)) - with open(shm_path, 'wb') as f: + with tempfile.NamedTemporaryFile(prefix='compile_modeld_', dir=Paths.shm_path(), delete=False) as f: f.write(read_file_chunked(path)) - return shm_path + tmp_path = f.name + atexit.register(lambda: os.path.exists(tmp_path) and os.remove(tmp_path)) + return tmp_path if __name__ == "__main__": From 14cff000e9c21d5e8f8b7ffa74bd820dcda94ea9 Mon Sep 17 00:00:00 2001 From: stef <19478336+stefpi@users.noreply.github.com> Date: Thu, 11 Jun 2026 15:58:04 -0400 Subject: [PATCH 027/151] feat(webrtc): addIceCandidate dispatcher (#38161) * addIceCandidate dispatcher * clean * fix lint --- system/athena/athenad.py | 8 ++++++++ system/webrtc/webrtcd.py | 31 ++++++++++++++++++++++++++++++- 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/system/athena/athenad.py b/system/athena/athenad.py index 870d271624..27a9afe535 100755 --- a/system/athena/athenad.py +++ b/system/athena/athenad.py @@ -604,6 +604,14 @@ def startStream(sdp: str) -> dict: except requests.ConnectionError as e: raise Exception("webrtc is not running. turn on comma body ignition.") from e +@dispatcher.add_method +def addIceCandidate(session_id: str, candidate: dict | None) -> dict: + if session_id is None: + return Exception("cannot add ice candidate without session_id") + resp = requests.post(f"http://localhost:{WEBRTCD_PORT}/candidate", + json={"session_id": session_id, "candidate": candidate}, timeout=10) + return resp.json() + @dispatcher.add_method def takeSnapshot() -> str | dict[str, str] | None: from openpilot.system.camerad.snapshot import jpeg_write, snapshot diff --git a/system/webrtc/webrtcd.py b/system/webrtc/webrtcd.py index 38c30862f8..e86b8f17d5 100755 --- a/system/webrtc/webrtcd.py +++ b/system/webrtc/webrtcd.py @@ -251,6 +251,23 @@ class StreamSession: async def get_answer(self): return await self.stream.start() + async def add_ice_candidate(self, candidate_init: dict | None): + from aiortc.sdp import candidate_from_sdp + + pc = self.stream.peer_connection + if pc.iceConnectionState not in ("new", "checking"): + return + + # a null/empty candidate signals end-of-candidates per the WebRTC convention + if not candidate_init or not candidate_init.get("candidate"): + await pc.addIceCandidate(None) + return + + candidate = candidate_from_sdp(candidate_init["candidate"].split(":", 1)[1]) + candidate.sdpMid = candidate_init.get("sdpMid") + candidate.sdpMLineIndex = candidate_init.get("sdpMLineIndex") + await pc.addIceCandidate(candidate) + def message_handler(self, message: bytes): assert self.incoming_bridge is not None try: @@ -354,7 +371,18 @@ async def get_stream(request: 'web.Request'): stream_dict[session.identifier] = session - return web.json_response({"sdp": answer.sdp, "type": answer.type}) + return web.json_response({"sdp": answer.sdp, "type": answer.type, "session_id": session.identifier}) + + +async def post_candidate(request: 'web.Request'): + body = await request.json() + session = request.app.get('streams', {}).get(body.get("session_id")) + + try: + await session.add_ice_candidate(body.get("candidate")) + except Exception as e: + raise web.HTTPBadRequest(text=json.dumps({"error": "invalid_candidate", "message": str(e)}), content_type="application/json") from e + return web.Response(status=200, text="OK") async def get_schema(request: 'web.Request'): @@ -400,6 +428,7 @@ def webrtcd_thread(host: str, port: int, debug: bool): app['debug'] = debug app.on_shutdown.append(on_shutdown) app.router.add_post("/stream", get_stream) + app.router.add_post("/candidate", post_candidate) app.router.add_post("/notify", post_notify) app.router.add_get("/schema", get_schema) From cd052f124ee87e319bf0fb091e9646c96c6a8a26 Mon Sep 17 00:00:00 2001 From: stef <19478336+stefpi@users.noreply.github.com> Date: Thu, 11 Jun 2026 19:10:34 -0400 Subject: [PATCH 028/151] webrtc: speed ups (#38163) - patch `aioice` to only get host address of active network interface (wlan0 when on wifi, ppp0 when not) - use common webrtc session between `startStream` and `addIceCandidates` - first time connection speed ups - move imports to top of file to move delay to webrtcd server start up not first connection - warm up webrtc stack by creating a webrtc connection object to import all submodule classes --- system/athena/athenad.py | 13 ++++--- system/webrtc/device/video.py | 7 ++++ system/webrtc/webrtcd.py | 67 +++++++++++++++++++++++++++++++---- 3 files changed, 76 insertions(+), 11 deletions(-) diff --git a/system/athena/athenad.py b/system/athena/athenad.py index 27a9afe535..a03a150330 100755 --- a/system/athena/athenad.py +++ b/system/athena/athenad.py @@ -40,6 +40,7 @@ from openpilot.system.loggerd.xattr_cache import getxattr, setxattr from openpilot.common.swaglog import cloudlog from openpilot.system.version import get_build_metadata from openpilot.system.hardware.hw import Paths +from openpilot.system.webrtc.webrtcd import StreamRequestBody ATHENA_HOST = os.getenv('ATHENA_HOST', 'wss://athena.comma.ai') @@ -84,6 +85,9 @@ UPLOAD_SESS = requests.Session() UPLOAD_SESS.mount("http://", UploadTOSAdapter()) UPLOAD_SESS.mount("https://", UploadTOSAdapter()) +WEBRTCD_SESS = requests.Session() +WEBRTCD_SESS.mount("http://", HTTPAdapter(max_retries=0)) + @dataclass class UploadFile: @@ -578,7 +582,6 @@ def getNetworks(): @dispatcher.add_method def startStream(sdp: str) -> dict: - from openpilot.system.webrtc.webrtcd import StreamRequestBody bridge_services_in = [] # get live car params to avoid stale notCar edge case @@ -590,7 +593,7 @@ def startStream(sdp: str) -> dict: body = StreamRequestBody(sdp, "wideRoad", bridge_services_in, ["carState"]) try: - resp = requests.post(f"http://localhost:{WEBRTCD_PORT}/stream", + resp = WEBRTCD_SESS.post(f"http://localhost:{WEBRTCD_PORT}/stream", json=asdict(body), timeout=10) if not resp.ok: try: @@ -600,7 +603,7 @@ def startStream(sdp: str) -> dict: resp.raise_for_status() return resp.json() except requests.ConnectTimeout as e: - raise Exception("webrtc took too long to respond. is it on?") from e + raise Exception("webrtc took too long to respond. is the comma body on?") from e except requests.ConnectionError as e: raise Exception("webrtc is not running. turn on comma body ignition.") from e @@ -608,8 +611,8 @@ def startStream(sdp: str) -> dict: def addIceCandidate(session_id: str, candidate: dict | None) -> dict: if session_id is None: return Exception("cannot add ice candidate without session_id") - resp = requests.post(f"http://localhost:{WEBRTCD_PORT}/candidate", - json={"session_id": session_id, "candidate": candidate}, timeout=10) + resp = WEBRTCD_SESS.post(f"http://localhost:{WEBRTCD_PORT}/candidate", + json={"session_id": session_id, "candidate": candidate}, timeout=10) return resp.json() @dispatcher.add_method diff --git a/system/webrtc/device/video.py b/system/webrtc/device/video.py index 8a07c5b9be..2083233dc9 100644 --- a/system/webrtc/device/video.py +++ b/system/webrtc/device/video.py @@ -4,6 +4,7 @@ import time import av from teleoprtc.tracks import TiciVideoStreamTrack +from aiortc import MediaStreamError from cereal import messaging from openpilot.common.realtime import DT_MDL, DT_DMON @@ -32,6 +33,10 @@ class LiveStreamVideoStreamTrack(TiciVideoStreamTrack): self._t0_ns = time.monotonic_ns() self.timing_sei_enabled = False + def stop(self) -> None: + super().stop() + self._sock = None + def _make_sock(self, camera_type: str) -> messaging.SubSocket: return messaging.sub_sock(self.camera_to_sock_mapping[camera_type], conflate=True) @@ -54,6 +59,8 @@ class LiveStreamVideoStreamTrack(TiciVideoStreamTrack): async def recv(self): while True: + if self.readyState != "live": + raise MediaStreamError msg = messaging.recv_one_or_none(self._sock) if msg is not None: break diff --git a/system/webrtc/webrtcd.py b/system/webrtc/webrtcd.py index e86b8f17d5..14c39fcd37 100755 --- a/system/webrtc/webrtcd.py +++ b/system/webrtc/webrtcd.py @@ -2,6 +2,7 @@ from abc import abstractmethod import os +import socket import time import argparse import asyncio @@ -26,6 +27,36 @@ from openpilot.system.webrtc.schema import generate_field from openpilot.common.params import Params from cereal import messaging, log +from aiortc import RTCBundlePolicy, RTCConfiguration, RTCPeerConnection +from aiortc.mediastreams import VideoStreamTrack +from openpilot.system.webrtc.device.video import LiveStreamVideoStreamTrack +from teleoprtc import WebRTCAnswerBuilder + +import aioice.ice + + +# socket trick: route lookup for 8.8.8.8 (nothing is sent or actually connected to) +# return the source interfaces IP which is the default interface of the device +def _default_route_ip() -> str | None: + s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + try: + s.connect(("8.8.8.8", 53)) # selects a route, sends nothing + return s.getsockname()[0] + except OSError: + return None + finally: + s.close() + +# aioice patch: gather ICE candidates only on the default-route interface +_get_host_addresses = aioice.ice.get_host_addresses +def _primary_host_addresses(use_ipv4: bool, use_ipv6: bool) -> list[str]: + addresses = _get_host_addresses(use_ipv4, use_ipv6) + primary = _default_route_ip() + if primary not in addresses: + return addresses + return [a for a in addresses if a == primary] +aioice.ice.get_host_addresses = _primary_host_addresses + class AsyncTaskRunner: def __init__(self): @@ -206,10 +237,6 @@ class StreamSession: shared_pub_master = DynamicPubMaster([]) def __init__(self, sdp: str, init_camera: str, incoming_services: list[str], outgoing_services: list[str], debug_mode: bool = False): - from aiortc.mediastreams import VideoStreamTrack - from openpilot.system.webrtc.device.video import LiveStreamVideoStreamTrack - from teleoprtc import WebRTCAnswerBuilder - builder = WebRTCAnswerBuilder(sdp) self.video_track = LiveStreamVideoStreamTrack(init_camera) if not debug_mode else VideoStreamTrack() @@ -327,6 +354,8 @@ class StreamSession: await self.bitrate_controller.stop() if self.outgoing_bridge is not None: await self.outgoing_bridge.stop() + if self.video_track is not None: + self.video_track.stop() await self.stream.stop() @@ -353,7 +382,7 @@ async def get_stream(request: 'web.Request'): except Exception: pass await s.stop() - del stream_dict[sid] + stream_dict.pop(sid, None) session = StreamSession(body.sdp, body.initCamera, body.bridge_services_in, body.bridge_services_out, debug_mode) try: @@ -367,9 +396,14 @@ async def get_stream(request: 'web.Request'): except Exception: await session.stop() raise + stream_dict[session.identifier] = session session.start() - stream_dict[session.identifier] = session + session_id = session.identifier + + def remove_finished_session(_: asyncio.Task) -> None: + stream_dict.pop(session_id, None) + session.run_task.add_done_callback(remove_finished_session) return web.json_response({"sdp": answer.sdp, "type": answer.type, "session_id": session.identifier}) @@ -409,6 +443,26 @@ async def post_notify(request: 'web.Request'): return web.Response(status=200, text="OK") +async def on_startup(app: 'web.Application'): + logger = logging.getLogger("webrtcd") + start_time = time.monotonic() + pc = None + + # warmup imports for webrtc stack + try: + pc = RTCPeerConnection(RTCConfiguration(bundlePolicy=RTCBundlePolicy.MAX_BUNDLE)) + pc.addTransceiver("video", direction="recvonly") + pc.createDataChannel("data", ordered=True) + offer = await pc.createOffer() + await asyncio.wait_for(pc.setLocalDescription(offer), timeout=1.5) + logger.info("Warmed WebRTC stack in %.1f ms", (time.monotonic() - start_time) * 1000) + except Exception: + logger.exception("WebRTC stack warmup failed") + finally: + if pc is not None: + await pc.close() + + async def on_shutdown(app: 'web.Application'): for session in app['streams'].values(): await session.stop() @@ -426,6 +480,7 @@ def webrtcd_thread(host: str, port: int, debug: bool): app['streams'] = dict() app['stream_lock'] = asyncio.Lock() app['debug'] = debug + app.on_startup.append(on_startup) app.on_shutdown.append(on_shutdown) app.router.add_post("/stream", get_stream) app.router.add_post("/candidate", post_candidate) From f9cc67896c7ed0c3a59a30f5df3ddac55660896f Mon Sep 17 00:00:00 2001 From: Daniel Koepping Date: Thu, 11 Jun 2026 18:59:56 -0700 Subject: [PATCH 029/151] Improve lateral maneuvers (#38159) * improve lat maneuver report * rm torque jerk * add jitter maneuver * add to 30mph * add jerk * color * more state * override * abort reason * abort * rm text * pad for small text --- selfdrive/ui/layouts/settings/developer.py | 1 + .../ui/mici/layouts/settings/developer.py | 1 + tools/lateral_maneuvers/generate_report.py | 66 ++++++++++--------- tools/lateral_maneuvers/lateral_maneuversd.py | 29 +++++++- 4 files changed, 62 insertions(+), 35 deletions(-) diff --git a/selfdrive/ui/layouts/settings/developer.py b/selfdrive/ui/layouts/settings/developer.py index 6417909322..2b17436943 100644 --- a/selfdrive/ui/layouts/settings/developer.py +++ b/selfdrive/ui/layouts/settings/developer.py @@ -131,6 +131,7 @@ class DeveloperLayout(Widget): long_man_enabled = ui_state.has_longitudinal_control and ui_state.is_offroad() self._long_maneuver_toggle.action_item.set_enabled(long_man_enabled) + self._lat_maneuver_toggle.action_item.set_enabled(ui_state.is_offroad()) else: self._long_maneuver_toggle.action_item.set_enabled(False) self._lat_maneuver_toggle.action_item.set_enabled(False) diff --git a/selfdrive/ui/mici/layouts/settings/developer.py b/selfdrive/ui/mici/layouts/settings/developer.py index 2f0250ff5f..2d7dc0899d 100644 --- a/selfdrive/ui/mici/layouts/settings/developer.py +++ b/selfdrive/ui/mici/layouts/settings/developer.py @@ -152,6 +152,7 @@ class DeveloperLayoutMici(NavScroller): long_man_enabled = ui_state.has_longitudinal_control and ui_state.is_offroad() self._long_maneuver_toggle.set_enabled(long_man_enabled) + self._lat_maneuver_toggle.set_enabled(ui_state.is_offroad()) else: self._long_maneuver_toggle.set_enabled(False) self._lat_maneuver_toggle.set_enabled(False) diff --git a/tools/lateral_maneuvers/generate_report.py b/tools/lateral_maneuvers/generate_report.py index 9a6fe1b979..c2ef7e99ea 100755 --- a/tools/lateral_maneuvers/generate_report.py +++ b/tools/lateral_maneuvers/generate_report.py @@ -51,6 +51,8 @@ def report(platform, route, _description, CP, ID, maneuvers): builder.append("
\n") builder.append(f"

{description}

\n") for run, msgs in enumerate(completed_runs): + last_active = max(m.logMonoTime for m in msgs if m.which() == 'lateralManeuverPlan' and m.valid) + msgs = [m for m in msgs if m.logMonoTime <= last_active] t_carControl, carControl = zip(*[(m.logMonoTime, m.carControl) for m in msgs if m.which() == 'carControl'], strict=True) t_carState, carState = zip(*[(m.logMonoTime, m.carState) for m in msgs if m.which() == 'carState'], strict=True) t_controlsState, controlsState = zip(*[(m.logMonoTime, m.controlsState) for m in msgs if m.which() == 'controlsState'], strict=True) @@ -77,7 +79,7 @@ def report(platform, route, _description, CP, ID, maneuvers): v_ego = [m.vEgo for m in carState] cross_markers = [] - if description.startswith('sine'): + if description.startswith(('sine', 'jitter')): amplitude = max(abs(lat_accel(lp.desiredCurvature, v) - baseline_accel) for lp, v in zip(lateralPlan, v_ego, strict=False)) threshold = amplitude * 0.5 @@ -128,58 +130,58 @@ def report(platform, route, _description, CP, ID, maneuvers): target_cross_times.setdefault(description, []) plt.rcParams['font.size'] = 40 - fig = plt.figure(figsize=(30, 30)) - ax = fig.subplots(4, 1, sharex=True, gridspec_kw={'height_ratios': [5, 3, 3, 3]}) + fig = plt.figure(figsize=(30, 40)) + ax = fig.subplots(5, 1, sharex=True, gridspec_kw={'height_ratios': [5, 5, 3, 3, 3]}) ax[0].grid(linewidth=4) + desired_label = 'lateralManeuverPlan.desiredCurvature * vEgo^2' desired_lat_accel = [lat_accel(m.desiredCurvature, v) for m, v in zip(lateralPlan, v_ego, strict=False)] - if description.startswith('sine'): - ax[0].plot(t_lateralPlan[:len(desired_lat_accel)], desired_lat_accel, label='desired lat accel', linewidth=6) + if description.startswith(('sine', 'jitter')): + ax[0].plot(t_lateralPlan[:len(desired_lat_accel)], desired_lat_accel, 'C1', label=desired_label, linewidth=6) else: t_desired = [t_lateralPlan[0]] + t_lateralPlan[:len(desired_lat_accel)] desired_lat_accel = [baseline_accel] + desired_lat_accel - ax[0].step(t_desired, desired_lat_accel, label='desired lat accel', linewidth=6, where='post') + ax[0].step(t_desired, desired_lat_accel, 'C1', label=desired_label, linewidth=6, where='post') actual_lat_accel = [lat_accel(cs.curvature, v) for cs, v in zip(controlsState, v_ego, strict=False)] - ax[0].plot(t_controlsState[:len(actual_lat_accel)], actual_lat_accel, label='actual lat accel', linewidth=6) + ax[0].plot(t_controlsState[:len(actual_lat_accel)], actual_lat_accel, 'g', label='controlsState.curvature * vEgo^2', linewidth=6) ax[0].set_ylabel('Lateral Accel (m/s^2)') - for ct, cv in cross_markers: ax[0].plot(ct, cv, marker='o', markersize=50, markeredgewidth=7, markeredgecolor='black', markerfacecolor='None') - - ax2 = ax[0].twinx() - if CP.steerControlType == car.CarParams.SteerControlType.angle: - ax2.plot(t_carOutput, [-m.actuatorsOutput.steeringAngleDeg for m in carOutput], 'C2', label='steer angle', linewidth=6) - else: - ax2.plot(t_carOutput, [-m.actuatorsOutput.torque for m in carOutput], 'C2', label='steer torque', linewidth=6) - - h1, l1 = ax[0].get_legend_handles_labels() - h2, l2 = ax2.get_legend_handles_labels() - ax[0].legend(h1 + h2, l1 + l2, prop={'size': 30}) + ax[0].legend(prop={'size': 30}) ax[1].grid(linewidth=4) - ax[1].plot(t_carState, [v * CV.MS_TO_MPH for v in v_ego], label='vEgo', linewidth=6) - ax[1].set_ylabel('Velocity (mph)') - ax[1].yaxis.set_major_formatter(plt.FormatStrFormatter('%.1f')) - ax[1].legend() + if CP.steerControlType == car.CarParams.SteerControlType.angle: + steer_field, steer_ylabel = 'steeringAngleDeg', 'Steer angle (deg)' + elif CP.steerControlType == car.CarParams.SteerControlType.curvature: + steer_field, steer_ylabel = 'curvature', 'Curvature (1/m)' + else: + steer_field, steer_ylabel = 'torque', 'Steer torque' + ax[1].plot(t_carControl, [getattr(m.actuators, steer_field) for m in carControl], 'C1', label=f'carControl.actuators.{steer_field}', linewidth=6) + ax[1].plot(t_carOutput, [getattr(m.actuatorsOutput, steer_field) for m in carOutput], 'g', label=f'carOutput.actuatorsOutput.{steer_field}', linewidth=6) + ax[1].set_ylabel(steer_ylabel) + ax[1].legend(prop={'size': 30}) + + ax[2].grid(linewidth=4) + ax[2].plot(t_carState, [v * CV.MS_TO_MPH for v in v_ego], label='carState.vEgo', linewidth=6) + ax[2].set_ylabel('Velocity (mph)') + ax[2].yaxis.set_major_formatter(plt.FormatStrFormatter('%.1f')) + ax[2].legend() t_accel = np.array(t_controlsState[:len(actual_lat_accel)]) raw_jerk = np.gradient(actual_lat_accel, t_accel) dt_avg = np.mean(np.diff(t_accel)) jerk_filter = FirstOrderFilter(0.0, 1 / (2 * np.pi * LP_FILTER_CUTOFF_HZ), dt_avg) filtered_jerk = [jerk_filter.update(j) for j in raw_jerk] - ax[2].grid(linewidth=4) - ax[2].plot(t_accel, filtered_jerk, label='actual jerk', linewidth=6) - if CP.steerControlType == car.CarParams.SteerControlType.torque: - desired_jerk = [cs.lateralControlState.torqueState.desiredLateralJerk for cs in controlsState] - ax[2].plot(t_controlsState[:len(controlsState)], desired_jerk, label='desired jerk', linewidth=6) - ax[2].set_ylabel('Jerk (m/s^3)') - ax[2].legend() - ax[3].grid(linewidth=4) - ax[3].plot(t_carControl, [math.degrees(m.orientationNED[0]) for m in carControl], label='roll', linewidth=6) - ax[3].set_ylabel('Roll (deg)') + ax[3].plot(t_accel, filtered_jerk, label='d/dt(controlsState.curvature * vEgo^2)', linewidth=6) + ax[3].set_ylabel('Jerk (m/s^3)') ax[3].legend() + ax[4].grid(linewidth=4) + ax[4].plot(t_carControl, [math.degrees(m.orientationNED[0]) for m in carControl], label='carControl.orientationNED[0]', linewidth=6) + ax[4].set_ylabel('Roll (deg)') + ax[4].legend() + ax[-1].set_xlabel("Time (s)") fig.tight_layout() diff --git a/tools/lateral_maneuvers/lateral_maneuversd.py b/tools/lateral_maneuvers/lateral_maneuversd.py index 4f68d9be08..1cc2d3560e 100755 --- a/tools/lateral_maneuvers/lateral_maneuversd.py +++ b/tools/lateral_maneuvers/lateral_maneuversd.py @@ -12,7 +12,7 @@ from openpilot.tools.longitudinal_maneuvers.maneuversd import Action, Maneuver a # thresholds for starting maneuvers MAX_SPEED_DEV = 0.7 # deviation in m/s -MAX_CURV = 0.002 # 500 m radius +MAX_CURV = 0.004 # 250 m radius MAX_ROLL = 0.12 # 6.8° TIMER = 2.0 # sec stable conditions before starting maneuver @@ -66,6 +66,12 @@ MANEUVERS = [ repeat=2, initial_speed=20. * CV.MPH_TO_MS, ), + Maneuver( + "jitter 20mph", + [Action([-0.5 if i % 2 == 0 else 0.5], [0.1]) for i in range(10)], + repeat=2, + initial_speed=20. * CV.MPH_TO_MS, + ), Maneuver( "step right 30mph", [Action([0.5], [1.0]), Action([-0.5], [1.5])], @@ -84,6 +90,12 @@ MANEUVERS = [ repeat=2, initial_speed=30. * CV.MPH_TO_MS, ), + Maneuver( + "jitter 30mph", + [Action([-0.5 if i % 2 == 0 else 0.5], [0.1]) for i in range(10)], + repeat=2, + initial_speed=30. * CV.MPH_TO_MS, + ), ] @@ -98,6 +110,8 @@ def main(): maneuvers = iter(MANEUVERS) maneuver = None complete_cnt = 0 + aborted_cnt = 0 + abort_reason = '' display_holdoff = 0 prev_text = '' @@ -121,8 +135,14 @@ def main(): alert_msg.alertDebug.alertText1 = 'Completed' alert_msg.alertDebug.alertText2 = maneuver.description elif maneuver is not None: - # reset maneuver on steering override or out of range speed - if sm['carState'].steeringPressed or (maneuver.active and abs(v_ego - maneuver.initial_speed) > MAX_SPEED_DEV): + # any driver input aborts the maneuver + CS = sm['carState'] + if CS.steeringPressed or CS.gasPressed: + aborted_cnt = int(1.0 / DT_MDL) + abort_reason = ('steering pressed' if CS.steeringPressed else 'gas pressed').ljust(20) + aborted = aborted_cnt > 0 + speed_out_of_range = maneuver.active and abs(v_ego - maneuver.initial_speed) > MAX_SPEED_DEV + if aborted or speed_out_of_range: maneuver.reset() roll = sm['carControl'].orientationNED[0] if len(sm['carControl'].orientationNED) == 3 else 0.0 @@ -140,6 +160,9 @@ def main(): else: alert_msg.alertDebug.alertText1 = f'Active {accel:+.1f}m/s² {max(action_remaining, 0):.1f}s' alert_msg.alertDebug.alertText2 = maneuver.description + elif aborted_cnt > 0: + aborted_cnt -= 1 + alert_msg.alertDebug.alertText1 = abort_reason elif not (abs(v_ego - maneuver.initial_speed) < MAX_SPEED_DEV and sm['carControl'].latActive): alert_msg.alertDebug.alertText1 = f'Set speed to {maneuver.initial_speed * CV.MS_TO_MPH:0.0f} mph' elif maneuver._ready_cnt > 0: From a40fa3a0b0cfacb0010b50515bcd64aed3dbdac8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Harald=20Sch=C3=A4fer?= Date: Fri, 12 Jun 2026 18:35:52 -0700 Subject: [PATCH 030/151] modeld: run the driving model as a single combined onnx (#38173) --- scripts/reporter.py | 8 ++- selfdrive/modeld/SConscript | 9 ++- selfdrive/modeld/compile_modeld.py | 63 +++++++++---------- selfdrive/modeld/modeld.py | 26 +++----- .../modeld/models/big_driving_on_policy.onnx | 3 - .../modeld/models/big_driving_supercombo.onnx | 3 + .../modeld/models/big_driving_vision.onnx | 3 - .../modeld/models/driving_on_policy.onnx | 3 - .../modeld/models/driving_supercombo.onnx | 3 + selfdrive/modeld/models/driving_vision.onnx | 3 - tinygrad_repo | 2 +- 11 files changed, 55 insertions(+), 71 deletions(-) delete mode 100644 selfdrive/modeld/models/big_driving_on_policy.onnx create mode 100644 selfdrive/modeld/models/big_driving_supercombo.onnx delete mode 100644 selfdrive/modeld/models/big_driving_vision.onnx delete mode 100644 selfdrive/modeld/models/driving_on_policy.onnx create mode 100644 selfdrive/modeld/models/driving_supercombo.onnx delete mode 100644 selfdrive/modeld/models/driving_vision.onnx diff --git a/scripts/reporter.py b/scripts/reporter.py index 9821a47ccf..199f1fae58 100755 --- a/scripts/reporter.py +++ b/scripts/reporter.py @@ -25,7 +25,9 @@ class MetadataOnnxPBParser(OnnxPBParser): def get_checkpoint(f): model = MetadataOnnxPBParser(f).parse() metadata = {prop["key"]: prop["value"] for prop in model["metadata_props"]} - return metadata['model_checkpoint'].split('/')[0] + # "" or "...//"; combined models list vision then policy + parts = metadata['model_checkpoint'].split('/') + return parts[-2] if len(parts) > 1 else parts[0] if __name__ == "__main__": @@ -37,8 +39,8 @@ if __name__ == "__main__": master_path = MASTER_PATH + MODEL_PATH + fn if os.path.exists(master_path): master = get_checkpoint(master_path) - master_col = f"[{master}](https://reporter.comma.life/experiment/{master})" + master_col = f"[{master}](https://reporter.comma.life/{master})" else: master_col = "N/A (new model)" pr = get_checkpoint(BASEDIR + MODEL_PATH + fn) - print("|", fn, "|", master_col, "|", f"[{pr}](https://reporter.comma.life/experiment/{pr})", "|") + print("|", fn, "|", master_col, "|", f"[{pr}](https://reporter.comma.life/{pr})", "|") diff --git a/selfdrive/modeld/SConscript b/selfdrive/modeld/SConscript index 80a7df4515..74adf0d932 100644 --- a/selfdrive/modeld/SConscript +++ b/selfdrive/modeld/SConscript @@ -86,15 +86,14 @@ frame_skip = ModelConstants.MODEL_RUN_FREQ // ModelConstants.MODEL_CONTEXT_FREQ for usbgpu in [False, True] if USBGPU else [False]: target_pkl_path = File(modeld_pkl_path(usbgpu)).abspath - file_prefix, cmd_flags = ('big_', usbgpu_tg_flags) if usbgpu else ('', tg_flags) - driving_onnx_deps = [p for m in [f'{file_prefix}driving_vision', f'{file_prefix}driving_on_policy'] - for p in get_existing_chunks(File(f"models/{m}.onnx").abspath)] + # BIG_INTO_SMALL=1 builds the default target from the big model, e.g. to test it without a USB GPU + file_prefix, cmd_flags = ('big_', usbgpu_tg_flags) if usbgpu else ('big_' if os.getenv('BIG_INTO_SMALL') else '', tg_flags) + driving_onnx_deps = get_existing_chunks(File(f"models/{file_prefix}driving_supercombo.onnx").abspath) camera_res_args = ' '.join(f'{cw}x{ch}' for cw, ch in CAMERA_CONFIGS) cmd = (f'{cmd_flags} {mac_brew_string} python3 {modeld_dir}/compile_modeld.py ' f'--model-size {model_w}x{model_h} ' f'--camera-resolutions {camera_res_args} ' - f'--vision-onnx {File(f"models/{file_prefix}driving_vision.onnx").abspath} ' - f'--on-policy-onnx {File(f"models/{file_prefix}driving_on_policy.onnx").abspath} ' + f'--onnx {File(f"models/{file_prefix}driving_supercombo.onnx").abspath} ' f'--output {target_pkl_path} --frame-skip {frame_skip}') onnx_sizes_sum = sum(os.path.getsize(f) for f in driving_onnx_deps) chunk_targets = get_chunk_targets(target_pkl_path, estimate_pickle_max_size(onnx_sizes_sum)) diff --git a/selfdrive/modeld/compile_modeld.py b/selfdrive/modeld/compile_modeld.py index bc8caca7e6..09e8d06c7c 100755 --- a/selfdrive/modeld/compile_modeld.py +++ b/selfdrive/modeld/compile_modeld.py @@ -132,26 +132,28 @@ def make_warp_input_queues(vision_input_shapes, frame_skip, device): return input_queues, npy -def get_policy_npy_shapes(policy_input_shapes): - dp = policy_input_shapes['desire_pulse'] # (1, 25, 8) - tc = policy_input_shapes['traffic_convention'] # (1, 2) - #TODO action_t is hardcoded to match tc for future compatibility - shapes = {'desire': (dp[2],), 'traffic_convention': tuple(tc), 'action_t': tuple(tc)} +def get_policy_npy_shapes(input_shapes): + dp = input_shapes['desire_pulse'] # (1, 25, 8) + tc = input_shapes['traffic_convention'] # (1, 2) + at = input_shapes['action_t'] # (1, 2) + fb = input_shapes['features_buffer'] # (1, 24, 512) + # TODO prev_feat shouldn't exist and be handled inside the JIT, but corrupt on QCOM for now + shapes = {'desire': (dp[2],), 'traffic_convention': tuple(tc), 'action_t': tuple(at), 'prev_feat': (fb[0], fb[2])} return shapes, [math.prod(s) for s in shapes.values()] -def make_input_queues(vision_input_shapes, policy_input_shapes, frame_skip, device): - input_queues, npy = make_warp_input_queues(vision_input_shapes, frame_skip, device) +def make_input_queues(input_shapes, frame_skip, device): + input_queues, npy = make_warp_input_queues(input_shapes, frame_skip, device) - fb = policy_input_shapes['features_buffer'] # (1, 25, 512) - dp = policy_input_shapes['desire_pulse'] # (1, 25, 8) + fb = input_shapes['features_buffer'] # (1, 24, 512), past features only; the model appends the current frame's feature + dp = input_shapes['desire_pulse'] # (1, 25, 8) - shapes, sizes = get_policy_npy_shapes(policy_input_shapes) + shapes, sizes = get_policy_npy_shapes(input_shapes) packed_npy_inputs = np.zeros(sum(sizes), dtype=np.float32) # views into the packed inputs, to be refilled at runtime npy.update({k: v.reshape(s) for (k, s), v in zip(shapes.items(), np.split(packed_npy_inputs, np.cumsum(sizes[:-1])), strict=True)}) input_queues.update({ - 'feat_q': Tensor(np.zeros((frame_skip * (fb[1] - 1) + 1, fb[0], fb[2]), dtype=np.float32), device=device).contiguous().realize(), + 'feat_q': Tensor(np.zeros((frame_skip * fb[1], fb[0], fb[2]), dtype=np.float32), device=device).contiguous().realize(), 'desire_q': Tensor(np.zeros((frame_skip * dp[1], dp[0], dp[2]), dtype=np.float32), device=device).contiguous().realize(), 'packed_npy_inputs': Tensor(packed_npy_inputs, device='NPY').realize(), }) @@ -189,29 +191,27 @@ def make_warp(nv12, model_w, model_h, frame_skip): return warp_enqueue -def make_run_policy(model_runners, model_metadata, frame_skip): +def make_run_policy(model_runner, model_metadata, frame_skip): sample_desire_fn = partial(sample_desire, frame_skip=frame_skip) sample_skip_fn = partial(sample_skip, frame_skip=frame_skip) - vision_features_slice = model_metadata['vision']['output_slices']['hidden_state'] - npy_shapes, npy_sizes = get_policy_npy_shapes(model_metadata['on_policy']['input_shapes']) + npy_shapes, npy_sizes = get_policy_npy_shapes(model_metadata['input_shapes']) def run_policy(img, big_img, feat_q, desire_q, packed_npy_inputs): packed_npy_inputs = packed_npy_inputs.to(Device.DEFAULT).realize() - desire, traffic_convention, action_t = (t.reshape(s) for t, s in zip(packed_npy_inputs.split(npy_sizes), npy_shapes.values(), strict=True)) + desire, traffic_convention, action_t, prev_feat = (t.reshape(s) for t, s in zip(packed_npy_inputs.split(npy_sizes), npy_shapes.values(), strict=True)) desire_buf = shift_and_sample(desire_q, desire.reshape(1, 1, -1), sample_desire_fn) - vision_out = next(iter(model_runners['vision']({'img': img, 'big_img': big_img}).values())).cast('float32') - - new_feat = vision_out[:, vision_features_slice].reshape(1, -1).unsqueeze(0) - feat_buf = shift_and_sample(feat_q, new_feat, sample_skip_fn) + feat_buf = shift_and_sample(feat_q, prev_feat.reshape(1, 1, -1), sample_skip_fn) inputs = { + 'img': img, + 'big_img': big_img, 'features_buffer': feat_buf, 'desire_pulse': desire_buf, 'traffic_convention': traffic_convention, 'action_t': action_t, } - on_policy_out = next(iter(model_runners['on_policy'](inputs).values())).cast('float32') - return Tensor.cat(vision_out, on_policy_out, dim=1), + out = next(iter(model_runner(inputs).values())).cast('float32') + return out, return run_policy @@ -281,26 +281,21 @@ if __name__ == "__main__": p.add_argument('--model-size', type=_parse_size, required=True, help='model input WxH') p.add_argument('--camera-resolutions', type=_parse_size, nargs='+', required=True, help='camera resolutions WxH (one or more)') - p.add_argument('--vision-onnx', required=True) - p.add_argument('--on-policy-onnx', required=True) + p.add_argument('--onnx', required=True) p.add_argument('--output', required=True) p.add_argument('--frame-skip', type=int, required=True) args = p.parse_args() - model_paths = { - 'vision': read_file_chunked_to_shm(args.vision_onnx), - 'on_policy': read_file_chunked_to_shm(args.on_policy_onnx), - } + model_path = read_file_chunked_to_shm(args.onnx) model_w, model_h = args.model_size - model_runners = {name: OnnxRunner(path) for name, path in model_paths.items()} - out = {'metadata': {name: make_metadata_dict(path) for name, path in model_paths.items()}} + model_runner = OnnxRunner(model_path) + out = {'metadata': make_metadata_dict(model_path)} - run_policy_jit = TinyJit(make_run_policy(model_runners, out['metadata'], args.frame_skip), prune=True) + run_policy_jit = TinyJit(make_run_policy(model_runner, out['metadata'], args.frame_skip), prune=True) - make_policy_queues = partial(make_input_queues, out['metadata']['vision']['input_shapes'], - out['metadata']['on_policy']['input_shapes'], args.frame_skip) - make_random_model_inputs = partial(make_random_images, keys=['img', 'big_img'], shape=out['metadata']['vision']['input_shapes']['img']) + make_policy_queues = partial(make_input_queues, out['metadata']['input_shapes'], args.frame_skip) + make_random_model_inputs = partial(make_random_images, keys=['img', 'big_img'], shape=out['metadata']['input_shapes']['img']) out['run_policy'] = compile_jit(run_policy_jit, make_random_model_inputs, POLICY_INPUTS, make_policy_queues) @@ -308,7 +303,7 @@ if __name__ == "__main__": nv12 = NV12Frame(cam_w, cam_h, *get_nv12_info(cam_w, cam_h)) make_random_warp_inputs = partial(make_random_images, keys=['frame', 'big_frame'], shape=nv12.size, device=WARP_DEV) warp_enqueue = TinyJit(make_warp(nv12, model_w, model_h, args.frame_skip), prune=True) - make_warp_queues = partial(make_warp_input_queues, out['metadata']['vision']['input_shapes'], args.frame_skip) + make_warp_queues = partial(make_warp_input_queues, out['metadata']['input_shapes'], args.frame_skip) out[(cam_w,cam_h)] = compile_jit(warp_enqueue, make_random_warp_inputs, WARP_INPUTS, make_warp_queues) with open(args.output, "wb") as f: diff --git a/selfdrive/modeld/modeld.py b/selfdrive/modeld/modeld.py index 7505ddf182..372e8704a2 100755 --- a/selfdrive/modeld/modeld.py +++ b/selfdrive/modeld/modeld.py @@ -79,20 +79,15 @@ class ModelState: input_devices = get_tg_input_devices(PROCESS_NAME, usbgpu) self.WARP_DEV, self.QUEUE_DEV = input_devices['WARP_DEV'], input_devices['QUEUE_DEV'] jits = pickle.loads(read_file_chunked(modeld_pkl_path(usbgpu))) - vision_metadata = jits['metadata']['vision'] - self.vision_input_shapes = vision_metadata['input_shapes'] - self.vision_input_names = list(self.vision_input_shapes.keys()) - self.vision_output_slices = vision_metadata['output_slices'] - self.vision_output_len = vision_metadata['output_shapes']['outputs'][1] - - policy_metadata = jits['metadata']['on_policy'] - self.policy_input_shapes = policy_metadata['input_shapes'] - self.policy_output_slices = policy_metadata['output_slices'] + metadata = jits['metadata'] + self.input_shapes = metadata['input_shapes'] + self.vision_input_names = [k for k in self.input_shapes if 'img' in k] + self.output_slices = metadata['output_slices'] self.prev_desire = np.zeros(ModelConstants.DESIRE_LEN, dtype=np.float32) self.frame_skip = ModelConstants.MODEL_RUN_FREQ // ModelConstants.MODEL_CONTEXT_FREQ - self.input_queues, self.npy = make_input_queues(self.vision_input_shapes, self.policy_input_shapes, self.frame_skip, device=self.QUEUE_DEV) + self.input_queues, self.npy = make_input_queues(self.input_shapes, self.frame_skip, device=self.QUEUE_DEV) self.full_frames: dict[str, Tensor] = {} self._blob_cache: dict[int, Tensor] = {} self.parser = Parser() @@ -132,14 +127,13 @@ class ModelState: outs, = self.run_policy( **{k: self.input_queues[k] for k in POLICY_INPUTS if k in self.input_queues}, img=img, big_img=big_img ) - vision_output, on_policy_output = np.split(outs.numpy()[0], [self.vision_output_len]) - vision_outputs_dict = self.parser.parse_vision_outputs(self.slice_outputs(vision_output, self.vision_output_slices)) - policy_outputs_dict = self.parser.parse_policy_outputs(self.slice_outputs(on_policy_output, self.policy_output_slices)) - combined_outputs_dict = {**vision_outputs_dict, **policy_outputs_dict} + model_output = outs.numpy()[0] + outputs_dict = self.parser.parse_outputs(self.slice_outputs(model_output, self.output_slices)) + self.npy['prev_feat'][:] = model_output[self.output_slices['hidden_state']] if SEND_RAW_PRED: - combined_outputs_dict['raw_pred'] = np.concatenate([vision_output.copy(), on_policy_output.copy()]) - return combined_outputs_dict + outputs_dict['raw_pred'] = model_output.copy() + return outputs_dict def main(demo=False): diff --git a/selfdrive/modeld/models/big_driving_on_policy.onnx b/selfdrive/modeld/models/big_driving_on_policy.onnx deleted file mode 100644 index f7b49c018a..0000000000 --- a/selfdrive/modeld/models/big_driving_on_policy.onnx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:565e53c38dcd64c50dd3fe4d5ee1530213aeefd66c3f6b67ea6a72a32612a6bf -size 14061419 diff --git a/selfdrive/modeld/models/big_driving_supercombo.onnx b/selfdrive/modeld/models/big_driving_supercombo.onnx new file mode 100644 index 0000000000..de84325912 --- /dev/null +++ b/selfdrive/modeld/models/big_driving_supercombo.onnx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:471f372751d5931e939320c211e35b7255f8fa8015125b3b3fd48ef43020257e +size 195490097 diff --git a/selfdrive/modeld/models/big_driving_vision.onnx b/selfdrive/modeld/models/big_driving_vision.onnx deleted file mode 100644 index d14f1969e0..0000000000 --- a/selfdrive/modeld/models/big_driving_vision.onnx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:1f0cab5033fe9e3bc5e174a2e790fa277f7d9fc44c65822d734064d2f899a9a0 -size 296203378 diff --git a/selfdrive/modeld/models/driving_on_policy.onnx b/selfdrive/modeld/models/driving_on_policy.onnx deleted file mode 100644 index 611ae9fe85..0000000000 --- a/selfdrive/modeld/models/driving_on_policy.onnx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:78477124cbf3ffe30fa951ebada8410b43c4242c6054584d656f1d329b067e15 -size 14060847 diff --git a/selfdrive/modeld/models/driving_supercombo.onnx b/selfdrive/modeld/models/driving_supercombo.onnx new file mode 100644 index 0000000000..f0672eab48 --- /dev/null +++ b/selfdrive/modeld/models/driving_supercombo.onnx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:659727c4d4839adc4992a254409a54259a8756a743f2d567bf5fdc6579f8009b +size 60881999 diff --git a/selfdrive/modeld/models/driving_vision.onnx b/selfdrive/modeld/models/driving_vision.onnx deleted file mode 100644 index 6c9fc4c84d..0000000000 --- a/selfdrive/modeld/models/driving_vision.onnx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ee29ee5bce84d1ce23e9ff381280de9b4e4d96d2934cd751740354884e112c66 -size 46877473 diff --git a/tinygrad_repo b/tinygrad_repo index 556defa0f7..5039d954f2 160000 --- a/tinygrad_repo +++ b/tinygrad_repo @@ -1 +1 @@ -Subproject commit 556defa0f78ed10b6ce675a2fa15a1c2521b5e93 +Subproject commit 5039d954f27fd4d4ebeb76951e9933f17985c1a4 From 2feca929ab6d893abadaefe73433b9f09ebd3b57 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Fri, 12 Jun 2026 19:17:09 -0700 Subject: [PATCH 031/151] bump opendbc (#38175) bump --- opendbc_repo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opendbc_repo b/opendbc_repo index e5d654dac2..75889fd928 160000 --- a/opendbc_repo +++ b/opendbc_repo @@ -1 +1 @@ -Subproject commit e5d654dac2dd52e4d02f6ba97d8d02bc089f8e00 +Subproject commit 75889fd9283730feb6ec824a00975fda0807bbc5 From fafcee04f43a94194c886d7914ec25c6f7bb3ac9 Mon Sep 17 00:00:00 2001 From: Willem Melching Date: Mon, 15 Jun 2026 17:44:01 +0200 Subject: [PATCH 032/151] replay: fix current time (#38179) --- tools/replay/replay.cc | 2 +- tools/replay/replay.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/replay/replay.cc b/tools/replay/replay.cc index d8d59e41a4..d6d02b1a9f 100644 --- a/tools/replay/replay.cc +++ b/tools/replay/replay.cc @@ -193,7 +193,7 @@ void Replay::startStream(const std::shared_ptr segment) { auto event = reader.getRoot(); uint64_t wall_time = event.getInitData().getWallTimeNanos(); if (wall_time > 0) { - route_date_time_ = wall_time / 1e6; + route_date_time_ = wall_time / 1e9; } } diff --git a/tools/replay/replay.h b/tools/replay/replay.h index 3e2bc7c00e..ce6d75bd6d 100644 --- a/tools/replay/replay.h +++ b/tools/replay/replay.h @@ -100,7 +100,7 @@ private: std::atomic exit_ = false; std::atomic interrupt_requested_ = false; bool events_ready_ = false; - std::time_t route_date_time_; + std::time_t route_date_time_ = 0; uint64_t route_start_ts_ = 0; std::atomic cur_mono_time_ = 0; cereal::Event::Which cur_which_ = cereal::Event::Which::INIT_DATA; From 0240a62fd96c8b053304d358df32523cc2bc527f Mon Sep 17 00:00:00 2001 From: stef <19478336+stefpi@users.noreply.github.com> Date: Mon, 15 Jun 2026 17:48:13 -0400 Subject: [PATCH 033/151] encoder: add ability to request keyframes from livestream encoders (#38172) * add param that requests keyframe * set keyframe request to false on cleanup * clean * timing and errors * remove other changes * clean diff * clean diff * clean up live adaptation params and functions * better function names * fix syntax * remove unused var * clean diff --- common/params_keys.h | 1 + system/loggerd/encoder/encoder.h | 1 + system/loggerd/encoder/ffmpeg_encoder.cc | 4 ++++ system/loggerd/encoder/ffmpeg_encoder.h | 1 + system/loggerd/encoder/v4l_encoder.cc | 14 ++++++++++++-- system/loggerd/encoder/v4l_encoder.h | 2 +- system/loggerd/encoderd.cc | 22 +++++++++++++--------- system/loggerd/loggerd.h | 8 ++++---- system/webrtc/device/video.py | 10 ++++++++++ system/webrtc/webrtcd.py | 3 +++ 10 files changed, 50 insertions(+), 16 deletions(-) diff --git a/common/params_keys.h b/common/params_keys.h index 7a96da0be7..546a53c76c 100644 --- a/common/params_keys.h +++ b/common/params_keys.h @@ -81,6 +81,7 @@ inline static std::unordered_map keys = { {"LiveParameters", {PERSISTENT, JSON}}, {"LiveParametersV2", {PERSISTENT, BYTES}}, {"LivestreamEncoderBitrate", {CLEAR_ON_MANAGER_START | DONT_LOG, INT}}, + {"LivestreamRequestKeyframe", {CLEAR_ON_MANAGER_START | DONT_LOG, BOOL}}, {"LiveTorqueParameters", {PERSISTENT | DONT_LOG, BYTES}}, {"LocationFilterInitialState", {PERSISTENT, BYTES}}, {"LateralManeuverMode", {CLEAR_ON_MANAGER_START | CLEAR_ON_OFFROAD_TRANSITION, BOOL}}, diff --git a/system/loggerd/encoder/encoder.h b/system/loggerd/encoder/encoder.h index 0a136f769c..696cb86737 100644 --- a/system/loggerd/encoder/encoder.h +++ b/system/loggerd/encoder/encoder.h @@ -27,6 +27,7 @@ public: virtual void encoder_open() = 0; virtual void encoder_close() = 0; virtual void set_bitrate(int bitrate) = 0; + virtual void request_keyframe() = 0; void publisher_publish(int segment_num, uint32_t idx, VisionIpcBufExtra &extra, unsigned int flags, kj::ArrayPtr header, kj::ArrayPtr dat); diff --git a/system/loggerd/encoder/ffmpeg_encoder.cc b/system/loggerd/encoder/ffmpeg_encoder.cc index f6399659b4..40f3bdee42 100644 --- a/system/loggerd/encoder/ffmpeg_encoder.cc +++ b/system/loggerd/encoder/ffmpeg_encoder.cc @@ -76,6 +76,10 @@ void FfmpegEncoder::set_bitrate(int bitrate) { LOGE("adaptive bitrate is not supported for ffmpeg encoder %s", encoder_info.publish_name); } +void FfmpegEncoder::request_keyframe() { + LOGE("keyframe request is not supported for ffmpeg encoder %s", encoder_info.publish_name); +} + int FfmpegEncoder::encode_frame(VisionBuf* buf, VisionIpcBufExtra *extra) { assert(buf->width == this->in_width); assert(buf->height == this->in_height); diff --git a/system/loggerd/encoder/ffmpeg_encoder.h b/system/loggerd/encoder/ffmpeg_encoder.h index a85e1d3816..3f7c674db3 100644 --- a/system/loggerd/encoder/ffmpeg_encoder.h +++ b/system/loggerd/encoder/ffmpeg_encoder.h @@ -22,6 +22,7 @@ public: void encoder_open(); void encoder_close(); void set_bitrate(int bitrate); + void request_keyframe(); private: int segment_num = -1; diff --git a/system/loggerd/encoder/v4l_encoder.cc b/system/loggerd/encoder/v4l_encoder.cc index 96a565f4ae..1b4d976b93 100644 --- a/system/loggerd/encoder/v4l_encoder.cc +++ b/system/loggerd/encoder/v4l_encoder.cc @@ -156,7 +156,6 @@ V4LEncoder::V4LEncoder(const EncoderInfo &encoder_info, int in_width, int in_hei EncoderSettings encoder_settings = encoder_info.get_settings(in_width); current_bitrate = encoder_settings.bitrate; - adaptive_bitrate = encoder_info.adaptive_bitrate; bool is_h265 = encoder_settings.encode_type == cereal::EncodeIndex::Type::FULL_H_E_V_C; struct v4l2_format fmt_out = { @@ -307,7 +306,7 @@ void V4LEncoder::encoder_close() { } void V4LEncoder::set_bitrate(int bitrate) { - if (!adaptive_bitrate || bitrate == current_bitrate) return; + if (bitrate == current_bitrate) return; if (bitrate <= 0) { LOGE("invalid livestream encoder bitrate %d", bitrate); return; @@ -325,6 +324,17 @@ void V4LEncoder::set_bitrate(int bitrate) { current_bitrate = bitrate; } +void V4LEncoder::request_keyframe() { + struct v4l2_control ctrl = { + .id = V4L2_CID_MPEG_VIDC_VIDEO_REQUEST_IFRAME, + .value = 1, + }; + + if (util::safe_ioctl(fd, VIDIOC_S_CTRL, &ctrl) == -1) { + LOGE("failed to request keyframe for %s", encoder_info.publish_name); + } +} + V4LEncoder::~V4LEncoder() { encoder_close(); v4l2_buf_type buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; diff --git a/system/loggerd/encoder/v4l_encoder.h b/system/loggerd/encoder/v4l_encoder.h index 2985409605..b1a84e654f 100644 --- a/system/loggerd/encoder/v4l_encoder.h +++ b/system/loggerd/encoder/v4l_encoder.h @@ -14,6 +14,7 @@ public: void encoder_open(); void encoder_close(); void set_bitrate(int bitrate); + void request_keyframe(); private: int fd; @@ -22,7 +23,6 @@ private: int segment_num = -1; int counter = 0; int current_bitrate = -1; - bool adaptive_bitrate; SafeQueue extras; diff --git a/system/loggerd/encoderd.cc b/system/loggerd/encoderd.cc index 546990041a..11db07671d 100644 --- a/system/loggerd/encoderd.cc +++ b/system/loggerd/encoderd.cc @@ -44,14 +44,18 @@ bool sync_encoders(EncoderdState *s, VisionStreamType cam_type, uint32_t frame_i } } -void apply_bitrate(std::vector> &encoders) { +void encoder_set_bitrate(std::unique_ptr &e) { static Params params; std::string val = params.get("LivestreamEncoderBitrate"); if (val.empty()) return; int bitrate = std::stoi(val); - for (auto &e : encoders) { - e->set_bitrate(bitrate); - } + e->set_bitrate(bitrate); +} + +void encoder_request_keyframe(std::unique_ptr &e) { + static Params params; + if (!params.getBool("LivestreamRequestKeyframe")) return; + e->request_keyframe(); } void encoder_thread(EncoderdState *s, const LogCameraInfo &cam_info) { @@ -59,9 +63,6 @@ void encoder_thread(EncoderdState *s, const LogCameraInfo &cam_info) { std::vector> encoders; - bool has_adaptive = std::any_of(cam_info.encoder_infos.begin(), cam_info.encoder_infos.end(), - [](const auto &ei) { return ei.adaptive_bitrate; }); - VisionIpcClient vipc_client = VisionIpcClient("camerad", cam_info.stream_type, false); std::unique_ptr jpeg_encoder; @@ -121,10 +122,13 @@ void encoder_thread(EncoderdState *s, const LogCameraInfo &cam_info) { ++cur_seg; } - if (has_adaptive) apply_bitrate(encoders); - // encode a frame for (int i = 0; i < encoders.size(); ++i) { + if (cam_info.encoder_infos[i].is_live) { + encoder_set_bitrate(encoders[i]); + encoder_request_keyframe(encoders[i]); + } + int out_id = encoders[i]->encode_frame(buf, &extra); if (out_id == -1) { diff --git a/system/loggerd/loggerd.h b/system/loggerd/loggerd.h index 340e72e6fd..c5f253d8f5 100644 --- a/system/loggerd/loggerd.h +++ b/system/loggerd/loggerd.h @@ -59,7 +59,7 @@ public: const char *filename = NULL; bool record = true; bool include_audio = false; - bool adaptive_bitrate = false; + bool is_live = false; int frame_width = -1; int frame_height = -1; int fps = MAIN_FPS; @@ -105,7 +105,7 @@ const EncoderInfo stream_road_encoder_info = { .publish_name = "livestreamRoadEncodeData", //.thumbnail_name = "thumbnail", .record = false, - .adaptive_bitrate = true, + .is_live = true, .get_settings = [](int){return EncoderSettings::StreamEncoderSettings();}, INIT_ENCODE_FUNCTIONS(LivestreamRoadEncode), }; @@ -113,7 +113,7 @@ const EncoderInfo stream_road_encoder_info = { const EncoderInfo stream_wide_road_encoder_info = { .publish_name = "livestreamWideRoadEncodeData", .record = false, - .adaptive_bitrate = true, + .is_live = true, .get_settings = [](int){return EncoderSettings::StreamEncoderSettings();}, INIT_ENCODE_FUNCTIONS(LivestreamWideRoadEncode), }; @@ -121,7 +121,7 @@ const EncoderInfo stream_wide_road_encoder_info = { const EncoderInfo stream_driver_encoder_info = { .publish_name = "livestreamDriverEncodeData", .record = false, - .adaptive_bitrate = true, + .is_live = true, .get_settings = [](int){return EncoderSettings::StreamEncoderSettings();}, INIT_ENCODE_FUNCTIONS(LivestreamDriverEncode), }; diff --git a/system/webrtc/device/video.py b/system/webrtc/device/video.py index 2083233dc9..4973e28971 100644 --- a/system/webrtc/device/video.py +++ b/system/webrtc/device/video.py @@ -8,6 +8,11 @@ from aiortc import MediaStreamError from cereal import messaging from openpilot.common.realtime import DT_MDL, DT_DMON +from openpilot.common.params import Params + + +# v4l2 buffer flag marking an encoded keyframe (linux/videodev2.h) +V4L2_BUF_FLAG_KEYFRAME = 0x8 # arbitrary 16-byte UUID identifying openpilot frame-timing SEI messages TIMING_SEI_UUID = bytes([ @@ -32,6 +37,8 @@ class LiveStreamVideoStreamTrack(TiciVideoStreamTrack): self._pts = 0 self._t0_ns = time.monotonic_ns() self.timing_sei_enabled = False + self.params = Params() + self._seen_keyframe = False def stop(self) -> None: super().stop() @@ -63,6 +70,9 @@ class LiveStreamVideoStreamTrack(TiciVideoStreamTrack): raise MediaStreamError msg = messaging.recv_one_or_none(self._sock) if msg is not None: + if not self._seen_keyframe and (getattr(msg, msg.which()).idx.flags & V4L2_BUF_FLAG_KEYFRAME): + self._seen_keyframe = True + self.params.put("LivestreamRequestKeyframe", False, block=False) break await asyncio.sleep(0.005) diff --git a/system/webrtc/webrtcd.py b/system/webrtc/webrtcd.py index 14c39fcd37..eb1c21250b 100755 --- a/system/webrtc/webrtcd.py +++ b/system/webrtc/webrtcd.py @@ -245,6 +245,7 @@ class StreamSession: self.stream = builder.stream() self.identifier = str(uuid.uuid4()) + self.params = Params() self.incoming_bridge: CerealIncomingMessageProxy | None = None self.incoming_bridge_services = incoming_services self.outgoing_bridge: CerealOutgoingMessageProxy | None = None @@ -324,6 +325,7 @@ class StreamSession: async def run(self): try: + self.params.put("LivestreamRequestKeyframe", True) await self.stream.wait_for_connection() if self.stream.has_messaging_channel(): if self.incoming_bridge is not None: @@ -350,6 +352,7 @@ class StreamSession: if self._cleanup_done: return self._cleanup_done = True + self.params.put("LivestreamRequestKeyframe", False) if self.bitrate_controller is not None: await self.bitrate_controller.stop() if self.outgoing_bridge is not None: From 15fb1a809ded75a9699c460c0dc4e8e870a44fca Mon Sep 17 00:00:00 2001 From: stef <19478336+stefpi@users.noreply.github.com> Date: Mon, 15 Jun 2026 19:49:56 -0400 Subject: [PATCH 034/151] webrtc: revert prewarm and import movements (#38181) --- system/athena/athenad.py | 2 +- system/webrtc/webrtcd.py | 30 ++++-------------------------- 2 files changed, 5 insertions(+), 27 deletions(-) diff --git a/system/athena/athenad.py b/system/athena/athenad.py index a03a150330..28796adc1b 100755 --- a/system/athena/athenad.py +++ b/system/athena/athenad.py @@ -40,7 +40,6 @@ from openpilot.system.loggerd.xattr_cache import getxattr, setxattr from openpilot.common.swaglog import cloudlog from openpilot.system.version import get_build_metadata from openpilot.system.hardware.hw import Paths -from openpilot.system.webrtc.webrtcd import StreamRequestBody ATHENA_HOST = os.getenv('ATHENA_HOST', 'wss://athena.comma.ai') @@ -582,6 +581,7 @@ def getNetworks(): @dispatcher.add_method def startStream(sdp: str) -> dict: + from openpilot.system.webrtc.webrtcd import StreamRequestBody bridge_services_in = [] # get live car params to avoid stale notCar edge case diff --git a/system/webrtc/webrtcd.py b/system/webrtc/webrtcd.py index eb1c21250b..ce51ed5018 100755 --- a/system/webrtc/webrtcd.py +++ b/system/webrtc/webrtcd.py @@ -27,11 +27,6 @@ from openpilot.system.webrtc.schema import generate_field from openpilot.common.params import Params from cereal import messaging, log -from aiortc import RTCBundlePolicy, RTCConfiguration, RTCPeerConnection -from aiortc.mediastreams import VideoStreamTrack -from openpilot.system.webrtc.device.video import LiveStreamVideoStreamTrack -from teleoprtc import WebRTCAnswerBuilder - import aioice.ice @@ -237,6 +232,10 @@ class StreamSession: shared_pub_master = DynamicPubMaster([]) def __init__(self, sdp: str, init_camera: str, incoming_services: list[str], outgoing_services: list[str], debug_mode: bool = False): + from aiortc.mediastreams import VideoStreamTrack + from openpilot.system.webrtc.device.video import LiveStreamVideoStreamTrack + from teleoprtc import WebRTCAnswerBuilder + builder = WebRTCAnswerBuilder(sdp) self.video_track = LiveStreamVideoStreamTrack(init_camera) if not debug_mode else VideoStreamTrack() @@ -446,26 +445,6 @@ async def post_notify(request: 'web.Request'): return web.Response(status=200, text="OK") -async def on_startup(app: 'web.Application'): - logger = logging.getLogger("webrtcd") - start_time = time.monotonic() - pc = None - - # warmup imports for webrtc stack - try: - pc = RTCPeerConnection(RTCConfiguration(bundlePolicy=RTCBundlePolicy.MAX_BUNDLE)) - pc.addTransceiver("video", direction="recvonly") - pc.createDataChannel("data", ordered=True) - offer = await pc.createOffer() - await asyncio.wait_for(pc.setLocalDescription(offer), timeout=1.5) - logger.info("Warmed WebRTC stack in %.1f ms", (time.monotonic() - start_time) * 1000) - except Exception: - logger.exception("WebRTC stack warmup failed") - finally: - if pc is not None: - await pc.close() - - async def on_shutdown(app: 'web.Application'): for session in app['streams'].values(): await session.stop() @@ -483,7 +462,6 @@ def webrtcd_thread(host: str, port: int, debug: bool): app['streams'] = dict() app['stream_lock'] = asyncio.Lock() app['debug'] = debug - app.on_startup.append(on_startup) app.on_shutdown.append(on_shutdown) app.router.add_post("/stream", get_stream) app.router.add_post("/candidate", post_candidate) From 37390743c1940079782210d1a9e882537d2f80ef Mon Sep 17 00:00:00 2001 From: stef <19478336+stefpi@users.noreply.github.com> Date: Mon, 15 Jun 2026 19:50:07 -0400 Subject: [PATCH 035/151] webrtc/athena: revert addIceCandidate changes (#38180) * revert addIceCandidate changes * remove accidental file --- system/athena/athenad.py | 8 -------- system/webrtc/webrtcd.py | 35 ++--------------------------------- 2 files changed, 2 insertions(+), 41 deletions(-) diff --git a/system/athena/athenad.py b/system/athena/athenad.py index 28796adc1b..420396e891 100755 --- a/system/athena/athenad.py +++ b/system/athena/athenad.py @@ -607,14 +607,6 @@ def startStream(sdp: str) -> dict: except requests.ConnectionError as e: raise Exception("webrtc is not running. turn on comma body ignition.") from e -@dispatcher.add_method -def addIceCandidate(session_id: str, candidate: dict | None) -> dict: - if session_id is None: - return Exception("cannot add ice candidate without session_id") - resp = WEBRTCD_SESS.post(f"http://localhost:{WEBRTCD_PORT}/candidate", - json={"session_id": session_id, "candidate": candidate}, timeout=10) - return resp.json() - @dispatcher.add_method def takeSnapshot() -> str | dict[str, str] | None: from openpilot.system.camerad.snapshot import jpeg_write, snapshot diff --git a/system/webrtc/webrtcd.py b/system/webrtc/webrtcd.py index ce51ed5018..90fabc0715 100755 --- a/system/webrtc/webrtcd.py +++ b/system/webrtc/webrtcd.py @@ -278,23 +278,6 @@ class StreamSession: async def get_answer(self): return await self.stream.start() - async def add_ice_candidate(self, candidate_init: dict | None): - from aiortc.sdp import candidate_from_sdp - - pc = self.stream.peer_connection - if pc.iceConnectionState not in ("new", "checking"): - return - - # a null/empty candidate signals end-of-candidates per the WebRTC convention - if not candidate_init or not candidate_init.get("candidate"): - await pc.addIceCandidate(None) - return - - candidate = candidate_from_sdp(candidate_init["candidate"].split(":", 1)[1]) - candidate.sdpMid = candidate_init.get("sdpMid") - candidate.sdpMLineIndex = candidate_init.get("sdpMLineIndex") - await pc.addIceCandidate(candidate) - def message_handler(self, message: bytes): assert self.incoming_bridge is not None try: @@ -401,24 +384,11 @@ async def get_stream(request: 'web.Request'): stream_dict[session.identifier] = session session.start() - session_id = session.identifier - def remove_finished_session(_: asyncio.Task) -> None: - stream_dict.pop(session_id, None) + stream_dict.pop(session.identifier, None) session.run_task.add_done_callback(remove_finished_session) - return web.json_response({"sdp": answer.sdp, "type": answer.type, "session_id": session.identifier}) - - -async def post_candidate(request: 'web.Request'): - body = await request.json() - session = request.app.get('streams', {}).get(body.get("session_id")) - - try: - await session.add_ice_candidate(body.get("candidate")) - except Exception as e: - raise web.HTTPBadRequest(text=json.dumps({"error": "invalid_candidate", "message": str(e)}), content_type="application/json") from e - return web.Response(status=200, text="OK") + return web.json_response({"sdp": answer.sdp, "type": answer.type}) async def get_schema(request: 'web.Request'): @@ -464,7 +434,6 @@ def webrtcd_thread(host: str, port: int, debug: bool): app['debug'] = debug app.on_shutdown.append(on_shutdown) app.router.add_post("/stream", get_stream) - app.router.add_post("/candidate", post_candidate) app.router.add_post("/notify", post_notify) app.router.add_get("/schema", get_schema) From 291315ab258fc58658c3b76c8a9da3257019ed9d Mon Sep 17 00:00:00 2001 From: stef <19478336+stefpi@users.noreply.github.com> Date: Mon, 15 Jun 2026 22:11:28 -0400 Subject: [PATCH 036/151] webrtc/athena: allow webrtc connection with only data channel (#38177) * add param that requests keyframe * set keyframe request to false on cleanup * timing and errors * video_enabled option and ability to add video later * remove loggerd changes from this PR * video enabled default to on, clean identifier * request keyframe on start regardless of video enabled or not * move error handling additions to different PR --- system/athena/athenad.py | 13 ++-- system/webrtc/device/video.py | 14 ++++- system/webrtc/tests/test_stream_session.py | 5 +- system/webrtc/webrtcd.py | 73 +++++++++++++++------- 4 files changed, 74 insertions(+), 31 deletions(-) diff --git a/system/athena/athenad.py b/system/athena/athenad.py index 420396e891..e78fc89bd9 100755 --- a/system/athena/athenad.py +++ b/system/athena/athenad.py @@ -580,7 +580,7 @@ def getNetworks(): @dispatcher.add_method -def startStream(sdp: str) -> dict: +def startStream(sdp: str, video_enabled: bool | None = None) -> dict: from openpilot.system.webrtc.webrtcd import StreamRequestBody bridge_services_in = [] @@ -591,17 +591,20 @@ def startStream(sdp: str) -> dict: if CP.notCar: bridge_services_in.append("testJoystick") - body = StreamRequestBody(sdp, "wideRoad", bridge_services_in, ["carState"]) + t_start = time.monotonic() + body = StreamRequestBody(sdp=sdp, initCamera="wideRoad", bridge_services_in=bridge_services_in, bridge_services_out=["carState"], video_enabled=video_enabled) try: - resp = WEBRTCD_SESS.post(f"http://localhost:{WEBRTCD_PORT}/stream", - json=asdict(body), timeout=10) + resp = WEBRTCD_SESS.post(f"http://localhost:{WEBRTCD_PORT}/stream", json=asdict(body), timeout=10) + t_end = time.monotonic() if not resp.ok: try: error_body = resp.json() raise Exception(error_body.get("message", f"webrtcd returned {resp.status_code}")) except ValueError: resp.raise_for_status() - return resp.json() + ret = resp.json() + ret["time"] = (t_end - t_start) * 1000 + return ret except requests.ConnectTimeout as e: raise Exception("webrtc took too long to respond. is the comma body on?") from e except requests.ConnectionError as e: diff --git a/system/webrtc/device/video.py b/system/webrtc/device/video.py index 4973e28971..af492c829e 100644 --- a/system/webrtc/device/video.py +++ b/system/webrtc/device/video.py @@ -29,7 +29,7 @@ class LiveStreamVideoStreamTrack(TiciVideoStreamTrack): "road": "livestreamRoadEncodeData", } - def __init__(self, camera_type: str): + def __init__(self, camera_type: str, video_enabled: bool = True): dt = DT_DMON if camera_type == "driver" else DT_MDL super().__init__(camera_type, dt) @@ -39,6 +39,7 @@ class LiveStreamVideoStreamTrack(TiciVideoStreamTrack): self.timing_sei_enabled = False self.params = Params() self._seen_keyframe = False + self.video_enabled = video_enabled def stop(self) -> None: super().stop() @@ -50,6 +51,11 @@ class LiveStreamVideoStreamTrack(TiciVideoStreamTrack): def switch_camera(self, camera_type: str) -> None: self._sock = self._make_sock(camera_type) + def enable(self, enabled: bool): + self.video_enabled = enabled + if not enabled: + self._seen_keyframe = False + def _build_frame_data(self, msg) -> bytes: encode_data = getattr(msg, msg.which()) if not self.timing_sei_enabled: @@ -68,6 +74,12 @@ class LiveStreamVideoStreamTrack(TiciVideoStreamTrack): while True: if self.readyState != "live": raise MediaStreamError + + # while video is disabled, pause here without returning + if not self.video_enabled: + await asyncio.sleep(0.005) + continue + msg = messaging.recv_one_or_none(self._sock) if msg is not None: if not self._seen_keyframe and (getattr(msg, msg.which()).idx.flags & V4L2_BUF_FLAG_KEYFRAME): diff --git a/system/webrtc/tests/test_stream_session.py b/system/webrtc/tests/test_stream_session.py index f44d217d58..bf413eeeba 100644 --- a/system/webrtc/tests/test_stream_session.py +++ b/system/webrtc/tests/test_stream_session.py @@ -32,12 +32,11 @@ class TestStreamSession: expected_json = json.dumps(expected_dict).encode() channel = mocker.Mock(spec=RTCDataChannel) - mocked_submaster = messaging.SubMaster(["customReservedRawData0"]) + proxy = CerealOutgoingMessageProxy(["customReservedRawData0"]) def mocked_update(t): - mocked_submaster.update_msgs(0, [test_msg]) + proxy.sm.update_msgs(0, [test_msg]) mocker.patch.object(messaging.SubMaster, "update", side_effect=mocked_update) - proxy = CerealOutgoingMessageProxy(mocked_submaster) proxy.add_channel(channel) proxy.update() diff --git a/system/webrtc/webrtcd.py b/system/webrtc/webrtcd.py index 90fabc0715..f4f58c06d6 100755 --- a/system/webrtc/webrtcd.py +++ b/system/webrtc/webrtcd.py @@ -49,7 +49,7 @@ def _primary_host_addresses(use_ipv4: bool, use_ipv6: bool) -> list[str]: primary = _default_route_ip() if primary not in addresses: return addresses - return [a for a in addresses if a == primary] + return [primary, ] aioice.ice.get_host_addresses = _primary_host_addresses @@ -80,14 +80,19 @@ class AsyncTaskRunner: class CerealOutgoingMessageProxy(AsyncTaskRunner): - def __init__(self, sm: messaging.SubMaster): + def __init__(self, services: list[str], enabled: bool = True): super().__init__() - self.sm = sm + self.services = list(services) + self.sm = messaging.SubMaster(self.services) self.channels: list[RTCDataChannel] = [] + self._enabled = enabled def add_channel(self, channel: 'RTCDataChannel'): self.channels.append(channel) + def enable(self, enable: bool): + self._enabled = enable + def to_json(self, msg_content: Any): if isinstance(msg_content, capnp._DynamicStructReader): msg_dict = msg_content.to_dict() @@ -117,6 +122,9 @@ class CerealOutgoingMessageProxy(AsyncTaskRunner): from aiortc.exceptions import InvalidStateError while True: + if not self._enabled: + await asyncio.sleep(0.01) + continue try: self.update() except InvalidStateError: @@ -165,21 +173,27 @@ class LivestreamBitrateController(AsyncTaskRunner): down_samples = 5 # 1s param_name = "LivestreamEncoderBitrate" - def __init__(self, peer_connection: Any): + def __init__(self, peer_connection: Any, params: Params, enabled: bool = True): super().__init__() self.pc = peer_connection - self.params = Params() + self.params = params - self.level = 1 + self.level = 2 self._publish(self.bitrates[self.level]) self.prev_lost, self.prev_sent = None, None self.counter = 0 self.up_samples = 5 # 1s self._auto = True + self._enabled = enabled + + def enable(self, enable: bool): + self._enabled = enable async def run(self): while True: await asyncio.sleep(self.sample_interval) + if not self._enabled: + continue if not self._auto: continue @@ -231,20 +245,28 @@ class LivestreamBitrateController(AsyncTaskRunner): class StreamSession: shared_pub_master = DynamicPubMaster([]) - def __init__(self, sdp: str, init_camera: str, incoming_services: list[str], outgoing_services: list[str], debug_mode: bool = False): + def __init__( + self, + sdp: str, + init_camera: str, + incoming_services: list[str], + outgoing_services: list[str], + enabled: bool | None = None, + debug_mode: bool = False + ): from aiortc.mediastreams import VideoStreamTrack from openpilot.system.webrtc.device.video import LiveStreamVideoStreamTrack from teleoprtc import WebRTCAnswerBuilder + self.identifier = str(uuid.uuid4()) + self.params = Params() builder = WebRTCAnswerBuilder(sdp) - self.video_track = LiveStreamVideoStreamTrack(init_camera) if not debug_mode else VideoStreamTrack() + self.enabled = enabled if enabled else True # default to enabled + self.video_track = LiveStreamVideoStreamTrack(init_camera, self.enabled) if not debug_mode else VideoStreamTrack() builder.add_video_stream(init_camera, self.video_track) - self.stream = builder.stream() - self.identifier = str(uuid.uuid4()) - self.params = Params() self.incoming_bridge: CerealIncomingMessageProxy | None = None self.incoming_bridge_services = incoming_services self.outgoing_bridge: CerealOutgoingMessageProxy | None = None @@ -252,16 +274,16 @@ class StreamSession: if len(incoming_services) > 0: self.incoming_bridge = CerealIncomingMessageProxy(self.shared_pub_master) if len(outgoing_services) > 0: - self.outgoing_bridge = CerealOutgoingMessageProxy(messaging.SubMaster(outgoing_services)) - self.bitrate_controller = LivestreamBitrateController(self.stream.peer_connection) + self.outgoing_bridge = CerealOutgoingMessageProxy(outgoing_services, self.enabled) + self.bitrate_controller = LivestreamBitrateController(self.stream.peer_connection, self.params, self.enabled) self.run_task: asyncio.Task | None = None self._cleanup_lock = asyncio.Lock() self._cleanup_done = False self.logger = logging.getLogger("webrtcd") self.logger.info( - "New stream session (%s), init camera %s, incoming services %s, outgoing services %s", - self.identifier, init_camera, incoming_services, outgoing_services, + "New stream session (%s), init camera %s, video enabled %s, incoming services %s, outgoing services %s", + self.identifier, init_camera, enabled, incoming_services, outgoing_services, ) def start(self): @@ -279,7 +301,6 @@ class StreamSession: return await self.stream.start() def message_handler(self, message: bytes): - assert self.incoming_bridge is not None try: payload = json.loads(message) if isinstance(message, (bytes, str)) else None if isinstance(payload, dict): @@ -290,6 +311,13 @@ class StreamSession: self.video_track.switch_camera(payload["data"]["camera"]) case "livestreamSettings": self.bitrate_controller.set_quality(payload["data"]["quality"]) + case "livestreamVideoEnable": + enabled = payload["data"]["enabled"] + self.video_track.enable(enabled) + self.outgoing_bridge.enable(enabled) + self.bitrate_controller.enable(enabled) + if not enabled: + self.params.put("LivestreamRequestKeyframe", True) case "clockSync": pong = json.dumps({"type": "clockSync", "data": { "action": "pong", "browserSendTime": payload["data"]["browserSendTime"], "deviceTime": time.time() * 1000, # noqa: TID251 @@ -320,9 +348,7 @@ class StreamSession: self.bitrate_controller.start() self.logger.info("Stream session (%s) connected", self.identifier) - await self.stream.wait_for_disconnection() - self.logger.info("Stream session (%s) ended", self.identifier) except Exception: self.logger.exception("Stream session failure") @@ -335,12 +361,12 @@ class StreamSession: return self._cleanup_done = True self.params.put("LivestreamRequestKeyframe", False) - if self.bitrate_controller is not None: - await self.bitrate_controller.stop() + await self.bitrate_controller.stop() if self.outgoing_bridge is not None: await self.outgoing_bridge.stop() if self.video_track is not None: self.video_track.stop() + self.video_track = None await self.stream.stop() @@ -348,6 +374,7 @@ class StreamSession: class StreamRequestBody: sdp: str initCamera: str + video_enabled: bool = True bridge_services_in: list[str] = field(default_factory=list) bridge_services_out: list[str] = field(default_factory=list) @@ -369,7 +396,8 @@ async def get_stream(request: 'web.Request'): await s.stop() stream_dict.pop(sid, None) - session = StreamSession(body.sdp, body.initCamera, body.bridge_services_in, body.bridge_services_out, debug_mode) + session = StreamSession(body.sdp, body.initCamera, body.bridge_services_in, body.bridge_services_out, body.video_enabled, debug_mode) + stream_dict[session.identifier] = session try: answer = await session.get_answer() except ValueError as e: @@ -380,8 +408,9 @@ async def get_stream(request: 'web.Request'): ) from e except Exception: await session.stop() + stream_dict.pop(session.identifier, None) + logging.getLogger("webrtcd").exception("Failed to create stream answer") raise - stream_dict[session.identifier] = session session.start() def remove_finished_session(_: asyncio.Task) -> None: From 586dd4c6118b9820b07c1986a10aa8b584d130ea Mon Sep 17 00:00:00 2001 From: stef <19478336+stefpi@users.noreply.github.com> Date: Mon, 15 Jun 2026 22:19:07 -0400 Subject: [PATCH 037/151] webrtc: add error handling middleware (#38182) * webrtc add error handling middleware * clean diff --- system/athena/athenad.py | 6 +----- system/webrtc/webrtcd.py | 19 ++++++++++++------- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/system/athena/athenad.py b/system/athena/athenad.py index e78fc89bd9..c31f1ef281 100755 --- a/system/athena/athenad.py +++ b/system/athena/athenad.py @@ -597,11 +597,7 @@ def startStream(sdp: str, video_enabled: bool | None = None) -> dict: resp = WEBRTCD_SESS.post(f"http://localhost:{WEBRTCD_PORT}/stream", json=asdict(body), timeout=10) t_end = time.monotonic() if not resp.ok: - try: - error_body = resp.json() - raise Exception(error_body.get("message", f"webrtcd returned {resp.status_code}")) - except ValueError: - resp.raise_for_status() + raise Exception(resp.json().get("message", f"webrtcd returned {resp.status_code}")) ret = resp.json() ret["time"] = (t_end - t_start) * 1000 return ret diff --git a/system/webrtc/webrtcd.py b/system/webrtc/webrtcd.py index f4f58c06d6..8d29dafdd3 100755 --- a/system/webrtc/webrtcd.py +++ b/system/webrtc/webrtcd.py @@ -400,12 +400,6 @@ async def get_stream(request: 'web.Request'): stream_dict[session.identifier] = session try: answer = await session.get_answer() - except ValueError as e: - await session.stop() - raise web.HTTPBadRequest( - text=json.dumps({"error": "invalid_sdp", "message": str(e)}), - content_type="application/json", - ) from e except Exception: await session.stop() stream_dict.pop(session.identifier, None) @@ -450,13 +444,24 @@ async def on_shutdown(app: 'web.Application'): del app['streams'] +@web.middleware +async def error_middleware(request: 'web.Request', handler): + try: + return await handler(request) + except web.HTTPException: + raise # intentional responses (400/404/etc.) pass through untouched + except Exception as e: + logging.getLogger("webrtcd").exception("Unhandled error handling %s", request.path) + return web.json_response({"error": "exception", "message": f"{type(e).__name__}: {e}"}, status=500) + + def webrtcd_thread(host: str, port: int, debug: bool): logging.basicConfig(level=logging.CRITICAL, handlers=[logging.StreamHandler()]) logging_level = logging.DEBUG if debug else logging.INFO logging.getLogger("WebRTCStream").setLevel(logging_level) logging.getLogger("webrtcd").setLevel(logging_level) - app = web.Application() + app = web.Application(middlewares=[error_middleware]) app['streams'] = dict() app['stream_lock'] = asyncio.Lock() From 4cefe7239d7dc5b70d8031ebe5c744f64777d08f Mon Sep 17 00:00:00 2001 From: Apostolos Georgiadis Date: Tue, 16 Jun 2026 18:23:30 +0200 Subject: [PATCH 038/151] fetch_image_from_route: fix missing f-string in error message (#38183) --- tools/scripts/fetch_image_from_route.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/scripts/fetch_image_from_route.py b/tools/scripts/fetch_image_from_route.py index 77bf48f946..a053714801 100755 --- a/tools/scripts/fetch_image_from_route.py +++ b/tools/scripts/fetch_image_from_route.py @@ -35,7 +35,7 @@ if segment >= len(segments): fr = FrameReader(segments[segment]) if frame >= fr.frame_count: - raise Exception("frame {frame} not found, got {fr.frame_count} frames") + raise Exception(f"frame {frame} not found, got {fr.frame_count} frames") im = Image.fromarray(fr.get(frame)) fn = f"uxxx_{route.replace('|', '_')}_{segment}_{frame}.png" From f3b1f97afacc13d68d1fb3543c19b6ec9708a870 Mon Sep 17 00:00:00 2001 From: stef <19478336+stefpi@users.noreply.github.com> Date: Tue, 16 Jun 2026 16:48:16 -0400 Subject: [PATCH 039/151] webrtc/athena: speed up first time stream connection (#38184) * move streamrequest to models file, prewarm in webrtcd * cleanup * debug * change print to logger.info --- system/athena/athenad.py | 2 +- system/webrtc/device/video.py | 5 ++--- system/webrtc/models.py | 9 +++++++++ system/webrtc/webrtcd.py | 33 +++++++++++++++++++-------------- 4 files changed, 31 insertions(+), 18 deletions(-) create mode 100644 system/webrtc/models.py diff --git a/system/athena/athenad.py b/system/athena/athenad.py index c31f1ef281..4c9b536219 100755 --- a/system/athena/athenad.py +++ b/system/athena/athenad.py @@ -581,7 +581,7 @@ def getNetworks(): @dispatcher.add_method def startStream(sdp: str, video_enabled: bool | None = None) -> dict: - from openpilot.system.webrtc.webrtcd import StreamRequestBody + from openpilot.system.webrtc.models import StreamRequestBody bridge_services_in = [] # get live car params to avoid stale notCar edge case diff --git a/system/webrtc/device/video.py b/system/webrtc/device/video.py index af492c829e..69f628cb11 100644 --- a/system/webrtc/device/video.py +++ b/system/webrtc/device/video.py @@ -7,7 +7,7 @@ from teleoprtc.tracks import TiciVideoStreamTrack from aiortc import MediaStreamError from cereal import messaging -from openpilot.common.realtime import DT_MDL, DT_DMON +from openpilot.common.realtime import DT_MDL from openpilot.common.params import Params @@ -30,8 +30,7 @@ class LiveStreamVideoStreamTrack(TiciVideoStreamTrack): } def __init__(self, camera_type: str, video_enabled: bool = True): - dt = DT_DMON if camera_type == "driver" else DT_MDL - super().__init__(camera_type, dt) + super().__init__(camera_type, DT_MDL) self._sock = self._make_sock(camera_type) self._pts = 0 diff --git a/system/webrtc/models.py b/system/webrtc/models.py new file mode 100644 index 0000000000..fd74113049 --- /dev/null +++ b/system/webrtc/models.py @@ -0,0 +1,9 @@ +from dataclasses import dataclass, field + +@dataclass +class StreamRequestBody: + sdp: str + initCamera: str + video_enabled: bool = True + bridge_services_in: list[str] = field(default_factory=list) + bridge_services_out: list[str] = field(default_factory=list) diff --git a/system/webrtc/webrtcd.py b/system/webrtc/webrtcd.py index 8d29dafdd3..48b868de21 100755 --- a/system/webrtc/webrtcd.py +++ b/system/webrtc/webrtcd.py @@ -10,7 +10,6 @@ import contextlib import json import uuid import logging -from dataclasses import dataclass, field from typing import Any, TYPE_CHECKING # aiortc and its dependencies have lots of internal warnings :( @@ -22,13 +21,13 @@ import capnp from aiohttp import web if TYPE_CHECKING: from aiortc.rtcdatachannel import RTCDataChannel +import aioice.ice +from openpilot.system.webrtc.models import StreamRequestBody from openpilot.system.webrtc.schema import generate_field from openpilot.common.params import Params from cereal import messaging, log -import aioice.ice - # socket trick: route lookup for 8.8.8.8 (nothing is sent or actually connected to) # return the source interfaces IP which is the default interface of the device @@ -254,9 +253,10 @@ class StreamSession: enabled: bool | None = None, debug_mode: bool = False ): - from aiortc.mediastreams import VideoStreamTrack + if debug_mode: + from aiortc.mediastreams import VideoStreamTrack from openpilot.system.webrtc.device.video import LiveStreamVideoStreamTrack - from teleoprtc import WebRTCAnswerBuilder + from teleoprtc.builder import WebRTCAnswerBuilder self.identifier = str(uuid.uuid4()) self.params = Params() @@ -370,15 +370,6 @@ class StreamSession: await self.stream.stop() -@dataclass -class StreamRequestBody: - sdp: str - initCamera: str - video_enabled: bool = True - bridge_services_in: list[str] = field(default_factory=list) - bridge_services_out: list[str] = field(default_factory=list) - - async def get_stream(request: 'web.Request'): stream_dict, debug_mode = request.app['streams'], request.app['debug'] raw_body = await request.json() @@ -455,11 +446,25 @@ async def error_middleware(request: 'web.Request', handler): return web.json_response({"error": "exception", "message": f"{type(e).__name__}: {e}"}, status=500) +def prewarm_stream_session_imports(debug_mode: bool = False) -> None: + if debug_mode: + from aiortc.mediastreams import VideoStreamTrack + assert VideoStreamTrack + from openpilot.system.webrtc.device.video import LiveStreamVideoStreamTrack + from teleoprtc.builder import WebRTCAnswerBuilder + assert LiveStreamVideoStreamTrack + assert WebRTCAnswerBuilder + + def webrtcd_thread(host: str, port: int, debug: bool): logging.basicConfig(level=logging.CRITICAL, handlers=[logging.StreamHandler()]) logging_level = logging.DEBUG if debug else logging.INFO logging.getLogger("WebRTCStream").setLevel(logging_level) logging.getLogger("webrtcd").setLevel(logging_level) + prewarm_start = time.monotonic() + prewarm_stream_session_imports(debug) + prewarm_end = time.monotonic() + logging.getLogger("webrtcd").info(f"webrtc prewarm finished in {(prewarm_end - prewarm_start) * 1000} ms") app = web.Application(middlewares=[error_middleware]) From c0456590f62388cd0c918b706afe968aad459bba Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Tue, 16 Jun 2026 14:01:14 -0700 Subject: [PATCH 040/151] mici ui: add branch switcher (#38153) * mici ui: add branch switcher * add icon --- .../assets/icons_mici/settings/software.png | 3 + selfdrive/ui/mici/layouts/settings/device.py | 139 --------- .../ui/mici/layouts/settings/settings.py | 6 + .../ui/mici/layouts/settings/software.py | 274 ++++++++++++++++++ 4 files changed, 283 insertions(+), 139 deletions(-) create mode 100644 selfdrive/assets/icons_mici/settings/software.png create mode 100644 selfdrive/ui/mici/layouts/settings/software.py diff --git a/selfdrive/assets/icons_mici/settings/software.png b/selfdrive/assets/icons_mici/settings/software.png new file mode 100644 index 0000000000..5cf528cbdd --- /dev/null +++ b/selfdrive/assets/icons_mici/settings/software.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c4c38772e6080aa4b8bf5212d3619e949775468c64f3edb88a1a426d767c38d2 +size 1579 diff --git a/selfdrive/ui/mici/layouts/settings/device.py b/selfdrive/ui/mici/layouts/settings/device.py index 535f75d97f..fd8bacf441 100644 --- a/selfdrive/ui/mici/layouts/settings/device.py +++ b/selfdrive/ui/mici/layouts/settings/device.py @@ -1,7 +1,5 @@ import os -import threading import pyray as rl -from enum import IntEnum from collections.abc import Callable from openpilot.common.basedir import BASEDIR @@ -122,12 +120,6 @@ class DeviceInfoLayoutMici(Widget): self._serial_number_text_label.render() -class UpdaterState(IntEnum): - IDLE = 0 - WAITING_FOR_UPDATER = 1 - UPDATER_RESPONDING = 2 - - class PairBigButton(BigButton): def __init__(self): super().__init__("pair", "connect.comma.ai", gui_app.texture("icons_mici/settings/comma_icon.png", 33, 60)) @@ -164,128 +156,6 @@ class PairBigButton(BigButton): gui_app.push_widget(dlg) -UPDATER_TIMEOUT = 10.0 # seconds to wait for updater to respond - - -class UpdateOpenpilotBigButton(BigButton): - def __init__(self): - self._txt_update_icon = gui_app.texture("icons_mici/settings/device/update.png", 64, 75) - self._txt_reboot_icon = gui_app.texture("icons_mici/settings/device/reboot.png", 64, 70) - self._txt_up_to_date_icon = gui_app.texture("icons_mici/settings/device/up_to_date.png", 64, 64) - super().__init__("update openpilot", "", self._txt_update_icon) - - self._waiting_for_updater_t: float | None = None - self._hide_value_t: float | None = None - self._state: UpdaterState = UpdaterState.IDLE - - ui_state.add_offroad_transition_callback(self.offroad_transition) - - def offroad_transition(self): - if ui_state.is_offroad(): - self.set_enabled(True) - - def _handle_mouse_release(self, mouse_pos: MousePos): - super()._handle_mouse_release(mouse_pos) - - if not system_time_valid(): - dlg = BigDialog("", tr("Please connect to Wi-Fi to update.")) - gui_app.push_widget(dlg) - return - - self.set_enabled(False) - self._state = UpdaterState.WAITING_FOR_UPDATER - self.set_icon(self._txt_update_icon) - - def run(): - if self.get_value() == "download update": - os.system("pkill -SIGHUP -f system.updated.updated") - elif self.get_value() == "update now": - ui_state.params.put_bool("DoReboot", True, block=True) - else: - os.system("pkill -SIGUSR1 -f system.updated.updated") - - threading.Thread(target=run, daemon=True).start() - - def set_value(self, value: str): - super().set_value(value) - if value: - self.set_text("") - else: - self.set_text("update openpilot") - - def _update_state(self): - super()._update_state() - - if ui_state.started: - self.set_enabled(False) - return - - updater_state = ui_state.params.get("UpdaterState") or "" - failed_count = ui_state.params.get("UpdateFailedCount") - failed = False if failed_count is None else int(failed_count) > 0 - - if ui_state.params.get_bool("UpdateAvailable"): - self.set_rotate_icon(False) - self.set_enabled(True) - if self.get_value() != "update now": - self.set_value("update now") - self.set_icon(self._txt_reboot_icon) - - elif self._state == UpdaterState.WAITING_FOR_UPDATER: - self.set_rotate_icon(True) - if updater_state != "idle": - self._state = UpdaterState.UPDATER_RESPONDING - - # Recover from updater not responding (time invalid shortly after boot) - if self._waiting_for_updater_t is None: - self._waiting_for_updater_t = rl.get_time() - - if self._waiting_for_updater_t is not None and rl.get_time() - self._waiting_for_updater_t > UPDATER_TIMEOUT: - self.set_rotate_icon(False) - self.set_value("updater failed\nto respond") - self._state = UpdaterState.IDLE - self._hide_value_t = rl.get_time() - - elif self._state == UpdaterState.UPDATER_RESPONDING: - if updater_state == "idle": - self.set_rotate_icon(False) - self._state = UpdaterState.IDLE - self._hide_value_t = rl.get_time() - else: - if self.get_value() != updater_state: - self.set_value(updater_state) - - elif self._state == UpdaterState.IDLE: - self.set_rotate_icon(False) - if failed: - self.set_enabled(True) # allow retry when failure came from updater param - if self.get_value() != "failed to update": - self.set_value("failed to update") - - elif ui_state.params.get_bool("UpdaterFetchAvailable"): - self.set_enabled(True) - if self.get_value() != "download update": - self.set_value("download update") - - elif self._hide_value_t is not None: - self.set_enabled(True) - if self.get_value() == "checking...": - self.set_value("up to date") - self.set_icon(self._txt_up_to_date_icon) - - # Hide previous text after short amount of time (up to date or failed) - if rl.get_time() - self._hide_value_t > 3.0: - self._hide_value_t = None - self.set_value("") - self.set_icon(self._txt_update_icon) - else: - if self.get_value() != "": - self.set_value("") - - if self._state != UpdaterState.WAITING_FOR_UPDATER: - self._waiting_for_updater_t = None - - class DeviceLayoutMici(NavScroller): def __init__(self): super().__init__() @@ -307,16 +177,9 @@ class DeviceLayoutMici(NavScroller): params.remove("LiveDelay") params.put_bool("OnroadCycleRequested", True, block=True) - def uninstall_openpilot_callback(): - ui_state.params.put_bool("DoUninstall", True, block=True) - reset_calibration_btn = EngagedConfirmationButton("reset calibration", "reset", gui_app.texture("icons_mici/settings/device/lkas.png", 122, 64), reset_calibration_callback) - uninstall_openpilot_btn = EngagedConfirmationButton("uninstall openpilot", "uninstall", - gui_app.texture("icons_mici/settings/device/uninstall.png", 64, 64), - uninstall_openpilot_callback, exit_on_confirm=False) - reboot_btn = EngagedConfirmationCircleButton("reboot", gui_app.texture("icons_mici/settings/device/reboot.png", 64, 70), reboot_callback, exit_on_confirm=False) @@ -340,14 +203,12 @@ class DeviceLayoutMici(NavScroller): self._scroller.add_widgets([ DeviceInfoLayoutMici(), - UpdateOpenpilotBigButton(), PairBigButton(), review_training_guide_btn, driver_cam_btn, terms_btn, regulatory_btn, reset_calibration_btn, - uninstall_openpilot_btn, reboot_btn, self._power_off_btn, ]) diff --git a/selfdrive/ui/mici/layouts/settings/settings.py b/selfdrive/ui/mici/layouts/settings/settings.py index 4ccc5ba139..56a953a65d 100644 --- a/selfdrive/ui/mici/layouts/settings/settings.py +++ b/selfdrive/ui/mici/layouts/settings/settings.py @@ -5,6 +5,7 @@ from openpilot.selfdrive.ui.mici.layouts.settings.toggles import TogglesLayoutMi from openpilot.selfdrive.ui.mici.layouts.settings.network.network_layout import NetworkLayoutMici from openpilot.selfdrive.ui.mici.layouts.settings.device import DeviceLayoutMici, PairBigButton from openpilot.selfdrive.ui.mici.layouts.settings.developer import DeveloperLayoutMici +from openpilot.selfdrive.ui.mici.layouts.settings.software import SoftwareLayoutMici from openpilot.selfdrive.ui.mici.layouts.settings.firehose import FirehoseLayout from openpilot.system.ui.lib.application import gui_app, FontWeight @@ -31,6 +32,10 @@ class SettingsLayout(NavScroller): device_btn = SettingsBigButton("device", "", gui_app.texture("icons_mici/settings/device_icon.png", 72, 58)) device_btn.set_click_callback(lambda: gui_app.push_widget(device_panel)) + software_panel = SoftwareLayoutMici() + software_btn = SettingsBigButton("software", "", gui_app.texture("icons_mici/settings/software.png", 64, 75)) + software_btn.set_click_callback(lambda: gui_app.push_widget(software_panel)) + developer_panel = DeveloperLayoutMici() developer_btn = SettingsBigButton("developer", "", gui_app.texture("icons_mici/settings/developer_icon.png", 64, 60)) developer_btn.set_click_callback(lambda: gui_app.push_widget(developer_panel)) @@ -43,6 +48,7 @@ class SettingsLayout(NavScroller): toggles_btn, network_btn, device_btn, + software_btn, PairBigButton(), #BigDialogButton("manual", "", "icons_mici/settings/manual_icon.png", "Check out the mici user\nmanual at comma.ai/setup"), firehose_btn, diff --git a/selfdrive/ui/mici/layouts/settings/software.py b/selfdrive/ui/mici/layouts/settings/software.py new file mode 100644 index 0000000000..32f20256f4 --- /dev/null +++ b/selfdrive/ui/mici/layouts/settings/software.py @@ -0,0 +1,274 @@ +import os +import threading +import pyray as rl +from enum import IntEnum +from collections.abc import Callable + +from openpilot.common.time_helpers import system_time_valid +from openpilot.selfdrive.ui.mici.layouts.settings.device import EngagedConfirmationButton +from openpilot.selfdrive.ui.mici.widgets.button import BigButton +from openpilot.selfdrive.ui.mici.widgets.dialog import BigDialog +from openpilot.selfdrive.ui.ui_state import ui_state +from openpilot.system.ui.lib.application import gui_app, FontWeight, MousePos +from openpilot.system.ui.lib.multilang import tr +from openpilot.system.ui.widgets import Widget +from openpilot.system.ui.widgets.label import UnifiedLabel +from openpilot.system.ui.widgets.scroller import NavScroller + +UPDATER_TIMEOUT = 10.0 # seconds to wait for updater to respond + + +def _split_description(desc: str) -> tuple[str, str, str, str] | None: + # UpdaterCurrentDescription/UpdaterNewDescription format: "version / branch / commit / date" + parts = [p.strip() for p in desc.split(" / ")] + if len(parts) != 4: + return None + version, branch, commit, date = parts + return version, branch, commit, date + + +class UpdaterState(IntEnum): + IDLE = 0 + WAITING_FOR_UPDATER = 1 + UPDATER_RESPONDING = 2 + + +class SoftwareInfoLayoutMici(Widget): + def __init__(self): + super().__init__() + + self.set_rect(rl.Rectangle(0, 0, 360, 180)) + + subheader_color = rl.Color(255, 255, 255, int(255 * 0.9 * 0.65)) + max_width = int(self._rect.width - 20) + self._version_label = UnifiedLabel("version", 48, max_width=max_width, font_weight=FontWeight.DISPLAY, wrap_text=False) + self._version_text_label = UnifiedLabel("", 32, max_width=max_width, text_color=subheader_color, + font_weight=FontWeight.ROMAN, wrap_text=False) + + self._branch_label = UnifiedLabel("branch", 48, max_width=max_width, font_weight=FontWeight.DISPLAY, wrap_text=False) + self._branch_text_label = UnifiedLabel("", 32, max_width=max_width, text_color=subheader_color, + font_weight=FontWeight.ROMAN, wrap_text=False) + + def _update_state(self): + desc = _split_description(ui_state.params.get("UpdaterCurrentDescription") or "") + if desc is not None: + version, branch, commit, date = desc + self._version_text_label.set_text(f"{version} ({date})") + self._branch_text_label.set_text(f"{branch} ({commit})") + else: + self._version_text_label.set_text(ui_state.params.get("Version") or "N/A") + self._branch_text_label.set_text(ui_state.params.get("GitBranch") or "N/A") + + def _render(self, _): + self._version_label.set_position(self._rect.x + 20, self._rect.y - 10) + self._version_label.render() + + self._version_text_label.set_position(self._rect.x + 20, self._rect.y + 68 - 25) + self._version_text_label.render() + + self._branch_label.set_position(self._rect.x + 20, self._rect.y + 114 - 30) + self._branch_label.render() + + self._branch_text_label.set_position(self._rect.x + 20, self._rect.y + 161 - 25) + self._branch_text_label.render() + + +class CheckUpdateButton(BigButton): + def __init__(self): + self._txt_update_icon = gui_app.texture("icons_mici/settings/device/update.png", 64, 75) + self._txt_up_to_date_icon = gui_app.texture("icons_mici/settings/device/up_to_date.png", 64, 64) + super().__init__("check for update", "", self._txt_update_icon) + + self._waiting_for_updater_t: float | None = None + self._hide_value_t: float | None = None + self._state: UpdaterState = UpdaterState.IDLE + + ui_state.add_offroad_transition_callback(self.offroad_transition) + + def offroad_transition(self): + if ui_state.is_offroad(): + self.set_enabled(True) + + def _handle_mouse_release(self, mouse_pos: MousePos): + super()._handle_mouse_release(mouse_pos) + + if not system_time_valid(): + dlg = BigDialog("", tr("Please connect to Wi-Fi to update.")) + gui_app.push_widget(dlg) + return + + self.set_enabled(False) + self._state = UpdaterState.WAITING_FOR_UPDATER + self.set_icon(self._txt_update_icon) + + def run(): + if self.get_value() == "download update": + os.system("pkill -SIGHUP -f system.updated.updated") + else: + os.system("pkill -SIGUSR1 -f system.updated.updated") + + threading.Thread(target=run, daemon=True).start() + + def set_value(self, value: str): + super().set_value(value) + if value: + self.set_text("") + else: + self.set_text("check for update") + + def _update_state(self): + super()._update_state() + + if ui_state.started: + self.set_enabled(False) + return + + updater_state = ui_state.params.get("UpdaterState") or "" + failed_count = ui_state.params.get("UpdateFailedCount") or 0 + failed = int(failed_count) > 0 + + if self._state == UpdaterState.WAITING_FOR_UPDATER: + self.set_rotate_icon(True) + if updater_state != "idle": + self._state = UpdaterState.UPDATER_RESPONDING + + # Recover from updater not responding (time invalid shortly after boot) + if self._waiting_for_updater_t is None: + self._waiting_for_updater_t = rl.get_time() + + if self._waiting_for_updater_t is not None and rl.get_time() - self._waiting_for_updater_t > UPDATER_TIMEOUT: + self.set_rotate_icon(False) + self.set_value("updater failed\nto respond") + self._state = UpdaterState.IDLE + self._hide_value_t = rl.get_time() + + elif self._state == UpdaterState.UPDATER_RESPONDING: + if updater_state == "idle": + self.set_rotate_icon(False) + self._state = UpdaterState.IDLE + self._hide_value_t = rl.get_time() + else: + if self.get_value() != updater_state: + self.set_value(updater_state) + + elif self._state == UpdaterState.IDLE: + self.set_rotate_icon(False) + if failed: + self.set_enabled(True) # allow retry when failure came from updater param + if self.get_value() != "failed to update": + self.set_value("failed to update") + + elif ui_state.params.get_bool("UpdaterFetchAvailable"): + self.set_enabled(True) + if self.get_value() != "download update": + self.set_value("download update") + + elif self._hide_value_t is not None: + self.set_enabled(True) + if self.get_value() == "checking...": + self.set_value("up to date") + self.set_icon(self._txt_up_to_date_icon) + + # Hide previous text after short amount of time (up to date or failed) + if rl.get_time() - self._hide_value_t > 3.0: + self._hide_value_t = None + self.set_value("") + self.set_icon(self._txt_update_icon) + else: + if self.get_value() != "": + self.set_value("") + + if self._state != UpdaterState.WAITING_FOR_UPDATER: + self._waiting_for_updater_t = None + + +class InstallUpdateButton(BigButton): + def __init__(self): + super().__init__("install update", "", gui_app.texture("icons_mici/settings/device/reboot.png", 64, 70)) + self.set_visible(lambda: ui_state.is_offroad() and ui_state.params.get_bool("UpdateAvailable")) + + def _update_state(self): + super()._update_state() + + desc = _split_description(ui_state.params.get("UpdaterNewDescription") or "") + value = f"{desc[0]} ({desc[1]})" if desc is not None else "" + if self.get_value() != value: + self.set_value(value) + + def _handle_mouse_release(self, mouse_pos: MousePos): + super()._handle_mouse_release(mouse_pos) + + self.set_enabled(False) + + def run(): + ui_state.params.put_bool("DoReboot", True, block=True) + + threading.Thread(target=run, daemon=True).start() + + +class BranchSelectPage(NavScroller): + def __init__(self, on_select: Callable[[str], None]): + super().__init__() + + params = ui_state.params + current_git_branch = params.get("GitBranch") or "" + branches_str = params.get("UpdaterAvailableBranches") or "" + branches = [b for b in branches_str.split(",") if b] + + for b in [current_git_branch, "devel-staging", "devel", "nightly", "nightly-dev", "master"]: + if b in branches: + branches.remove(b) + branches.insert(0, b) + + current_target = params.get("UpdaterTargetBranch") or "" + check_icon = gui_app.texture("icons_mici/settings/device/up_to_date.png", 64, 64) + + buttons = [] + for branch in branches: + btn = BigButton(branch, "", check_icon if branch == current_target else None, scroll=True) + btn.set_click_callback(lambda b=branch: self.dismiss(lambda: on_select(b))) + buttons.append(btn) + self._scroller.add_widgets(buttons) + + +class TargetBranchButton(BigButton): + def __init__(self): + super().__init__("target branch", ui_state.params.get("UpdaterTargetBranch") or "") + self.set_click_callback(self._on_click) + self.set_visible(not ui_state.params.get_bool("IsTestedBranch")) + self.set_enabled(lambda: ui_state.is_offroad()) + + def _update_state(self): + super()._update_state() + + target = ui_state.params.get("UpdaterTargetBranch") or "" + if self.get_value() != target: + self.set_value(target) + + def _on_click(self): + gui_app.push_widget(BranchSelectPage(self._on_select)) + + def _on_select(self, branch: str): + ui_state.params.put("UpdaterTargetBranch", branch, block=True) + self.set_value(branch) + os.system("pkill -SIGUSR1 -f system.updated.updated") + + +class SoftwareLayoutMici(NavScroller): + def __init__(self): + super().__init__() + + def uninstall_openpilot_callback(): + ui_state.params.put_bool("DoUninstall", True, block=True) + + uninstall_openpilot_btn = EngagedConfirmationButton("uninstall openpilot", "uninstall", + gui_app.texture("icons_mici/settings/device/uninstall.png", 64, 64), + uninstall_openpilot_callback, exit_on_confirm=False) + + self._scroller.add_widgets([ + SoftwareInfoLayoutMici(), + CheckUpdateButton(), + InstallUpdateButton(), + TargetBranchButton(), + uninstall_openpilot_btn, + ]) From 3c4790c089a77594e6c04c337cae985a04e7b61d Mon Sep 17 00:00:00 2001 From: eFini Date: Wed, 17 Jun 2026 05:58:30 +0800 Subject: [PATCH 041/151] bugfix: should be Error not Exception (#38071) should be Error not Exception --- system/hardware/tici/hardware.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/hardware/tici/hardware.py b/system/hardware/tici/hardware.py index 35bed55721..10b6d7646c 100644 --- a/system/hardware/tici/hardware.py +++ b/system/hardware/tici/hardware.py @@ -383,7 +383,7 @@ class Tici(HardwareBase): pid = subprocess.check_output(["pgrep", "-f", "spi0"], encoding='utf8').strip() subprocess.call(["sudo", "chrt", "-f", "-p", "1", pid]) subprocess.call(["sudo", "taskset", "-pc", "3", pid]) - except subprocess.CalledProcessException as e: + except subprocess.CalledProcessError as e: print(str(e)) def get_networks(self): From 29e7f362edce1f86088a167b56cfb98ac70b2084 Mon Sep 17 00:00:00 2001 From: David <49467229+TheSecurityDev@users.noreply.github.com> Date: Tue, 16 Jun 2026 17:25:27 -0500 Subject: [PATCH 042/151] clip: add wide camera stream (#37677) clip: add support for wide camera frames in clip rendering --- tools/clip/run.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tools/clip/run.py b/tools/clip/run.py index d3a0496b1e..fa4b203862 100755 --- a/tools/clip/run.py +++ b/tools/clip/run.py @@ -312,8 +312,15 @@ def clip(route: Route, output: str, start: int, end: int, headless: bool = True, camera_paths = route.qcamera_paths() if use_qcam else route.camera_paths() frame_queue = FrameQueue(camera_paths, start, end, fps=FRAMERATE, use_qcam=use_qcam) + ecamera_paths = route.ecamera_paths() if not use_qcam else [] + wide_frame_queue: FrameQueue | None = None + if any(p for p in ecamera_paths[seg_start:seg_end] if p): + wide_frame_queue = FrameQueue(ecamera_paths, start, end, fps=FRAMERATE) + vipc = VisionIpcServer("camerad") vipc.create_buffers(VisionStreamType.VISION_STREAM_ROAD, 4, frame_queue.frame_w, frame_queue.frame_h) + if wide_frame_queue: + vipc.create_buffers(VisionStreamType.VISION_STREAM_WIDE_ROAD, 4, wide_frame_queue.frame_w, wide_frame_queue.frame_h) vipc.start_listener() patch_submaster(message_chunks, ui_state) @@ -331,6 +338,9 @@ def clip(route: Route, output: str, start: int, end: int, headless: bool = True, break _, frame_bytes = frame_queue.get() vipc.send(VisionStreamType.VISION_STREAM_ROAD, frame_bytes, frame_idx, int(frame_idx * 5e7), int(frame_idx * 5e7)) + if wide_frame_queue: + _, wide_bytes = wide_frame_queue.get() + vipc.send(VisionStreamType.VISION_STREAM_WIDE_ROAD, wide_bytes, frame_idx, int(frame_idx * 5e7), int(frame_idx * 5e7)) ui_state.update() if should_render: road_view.render() @@ -340,6 +350,8 @@ def clip(route: Route, output: str, start: int, end: int, headless: bool = True, timer.lap("render") frame_queue.stop() + if wide_frame_queue: + wide_frame_queue.stop() gui_app.close() timer.lap("ffmpeg") From 8a80bd70e7bd319a84425b7e31d15d3bade2cc8a Mon Sep 17 00:00:00 2001 From: Robbie Wadley Date: Tue, 16 Jun 2026 17:25:40 -0600 Subject: [PATCH 043/151] fix: cruise faults should not disable silently (#37557) Co-authored-by: Jason Young <46612682+jyoung8607@users.noreply.github.com> Co-authored-by: Adeeb Shihadeh --- selfdrive/selfdrived/state.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/selfdrive/selfdrived/state.py b/selfdrive/selfdrived/state.py index 073ddb56eb..25c22684ad 100644 --- a/selfdrive/selfdrived/state.py +++ b/selfdrive/selfdrived/state.py @@ -24,14 +24,14 @@ class StateMachine: # ENABLED, SOFT DISABLING, PRE ENABLING, OVERRIDING if self.state != State.disabled: # user and immediate disable always have priority in a non-disabled state - if events.contains(ET.USER_DISABLE): - self.state = State.disabled - self.current_alert_types.append(ET.USER_DISABLE) - - elif events.contains(ET.IMMEDIATE_DISABLE): + if events.contains(ET.IMMEDIATE_DISABLE): self.state = State.disabled self.current_alert_types.append(ET.IMMEDIATE_DISABLE) + elif events.contains(ET.USER_DISABLE): + self.state = State.disabled + self.current_alert_types.append(ET.USER_DISABLE) + else: # ENABLED if self.state == State.enabled: From 93224b3c051aacacca82e60d3937841c53b57425 Mon Sep 17 00:00:00 2001 From: hypery11 Date: Wed, 17 Jun 2026 07:28:37 +0800 Subject: [PATCH 044/151] speedup pytest collection (#37977) Co-authored-by: Adeeb Shihadeh --- conftest.py | 6 +++ pyproject.toml | 2 +- selfdrive/ui/mici/tests/test_widget_leaks.py | 43 ++++++++++---------- 3 files changed, 29 insertions(+), 22 deletions(-) diff --git a/conftest.py b/conftest.py index f2fd482be9..e368b01e83 100644 --- a/conftest.py +++ b/conftest.py @@ -17,6 +17,12 @@ collect_ignore_glob = [ ] +def pytest_sessionstart(session): + # TODO: fix tests and enable test order randomization + if session.config.pluginmanager.hasplugin('randomly'): + session.config.option.randomly_reorganize = False + + @pytest.hookimpl(hookwrapper=True, trylast=True) def pytest_runtest_call(item): # ensure we run as a hook after capturemanager's diff --git a/pyproject.toml b/pyproject.toml index 1e8ecb0232..2120e6a430 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -127,7 +127,7 @@ allow-direct-references = true [tool.pytest.ini_options] minversion = "6.0" -addopts = "--ignore=openpilot/ --ignore=opendbc/ --ignore=panda/ --ignore=rednose_repo/ --ignore=tinygrad_repo/ --ignore=teleoprtc_repo/ --ignore=msgq/ -Werror --strict-config --strict-markers --durations=10 -n auto --dist=loadgroup" +addopts = "--ignore=openpilot/ --ignore=opendbc/ --ignore=panda/ --ignore=rednose_repo/ --ignore=tinygrad_repo/ --ignore=teleoprtc_repo/ --ignore=msgq/ --ignore=selfdrive/modeld -Werror --strict-config --strict-markers --durations=10 -n auto --dist=loadgroup" cpp_files = "test_*" cpp_harness = "selfdrive/test/cpp_harness.py" python_files = "test_*.py" diff --git a/selfdrive/ui/mici/tests/test_widget_leaks.py b/selfdrive/ui/mici/tests/test_widget_leaks.py index e35cb44776..09142a8e11 100755 --- a/selfdrive/ui/mici/tests/test_widget_leaks.py +++ b/selfdrive/ui/mici/tests/test_widget_leaks.py @@ -1,26 +1,6 @@ -import pyray as rl -rl.set_config_flags(rl.ConfigFlags.FLAG_WINDOW_HIDDEN) import gc import weakref import pytest -from openpilot.system.ui.lib.application import gui_app -from openpilot.system.ui.widgets import Widget - -# mici dialogs -from openpilot.selfdrive.ui.mici.layouts.onboarding import TrainingGuide as MiciTrainingGuide, OnboardingWindow as MiciOnboardingWindow -from openpilot.selfdrive.ui.mici.onroad.driver_camera_dialog import DriverCameraDialog as MiciDriverCameraDialog -from openpilot.selfdrive.ui.mici.widgets.pairing_dialog import PairingDialog as MiciPairingDialog -from openpilot.selfdrive.ui.mici.widgets.dialog import BigDialog, BigConfirmationDialog, BigInputDialog -from openpilot.selfdrive.ui.mici.layouts.settings.device import MiciFccModal - -# tici dialogs -from openpilot.selfdrive.ui.onroad.driver_camera_dialog import DriverCameraDialog as TiciDriverCameraDialog -from openpilot.selfdrive.ui.layouts.onboarding import OnboardingWindow as TiciOnboardingWindow -from openpilot.selfdrive.ui.widgets.pairing_dialog import PairingDialog as TiciPairingDialog -from openpilot.system.ui.widgets.confirm_dialog import ConfirmDialog -from openpilot.system.ui.widgets.option_dialog import MultiOptionDialog -from openpilot.system.ui.widgets.html_render import HtmlModal -from openpilot.system.ui.widgets.keyboard import Keyboard # FIXME: known small leaks not worth worrying about at the moment KNOWN_LEAKS = { @@ -52,7 +32,8 @@ KNOWN_LEAKS = { } -def get_child_widgets(widget: Widget) -> list[Widget]: +def get_child_widgets(widget) -> list: + from openpilot.system.ui.widgets import Widget children = [] for val in widget.__dict__.values(): items = val if isinstance(val, (list, tuple)) else (val,) @@ -62,6 +43,26 @@ def get_child_widgets(widget: Widget) -> list[Widget]: @pytest.mark.skip(reason="segfaults") def test_dialogs_do_not_leak(): + import pyray as rl + rl.set_config_flags(rl.ConfigFlags.FLAG_WINDOW_HIDDEN) + from openpilot.system.ui.lib.application import gui_app + + # mici dialogs + from openpilot.selfdrive.ui.mici.layouts.onboarding import TrainingGuide as MiciTrainingGuide, OnboardingWindow as MiciOnboardingWindow + from openpilot.selfdrive.ui.mici.onroad.driver_camera_dialog import DriverCameraDialog as MiciDriverCameraDialog + from openpilot.selfdrive.ui.mici.widgets.pairing_dialog import PairingDialog as MiciPairingDialog + from openpilot.selfdrive.ui.mici.widgets.dialog import BigDialog, BigConfirmationDialog, BigInputDialog + from openpilot.selfdrive.ui.mici.layouts.settings.device import MiciFccModal + + # tici dialogs + from openpilot.selfdrive.ui.onroad.driver_camera_dialog import DriverCameraDialog as TiciDriverCameraDialog + from openpilot.selfdrive.ui.layouts.onboarding import OnboardingWindow as TiciOnboardingWindow + from openpilot.selfdrive.ui.widgets.pairing_dialog import PairingDialog as TiciPairingDialog + from openpilot.system.ui.widgets.confirm_dialog import ConfirmDialog + from openpilot.system.ui.widgets.option_dialog import MultiOptionDialog + from openpilot.system.ui.widgets.html_render import HtmlModal + from openpilot.system.ui.widgets.keyboard import Keyboard + gui_app.init_window("ref-test") leaked_widgets = set() From 82a945d14524c5f64e23455d180f39cf38d93723 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Tue, 16 Jun 2026 17:49:12 -0700 Subject: [PATCH 045/151] scons: enforce max file size for build products (#38077) * scons: enforce max file size for build products * only for minimal build * enable * fix build product size check --- SConstruct | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/SConstruct b/SConstruct index 0427d46294..31d4af801b 100644 --- a/SConstruct +++ b/SConstruct @@ -273,6 +273,8 @@ def count_scons_nodes(nodes): if node in seen: continue seen.add(node) + if hasattr(node, 'has_builder') and node.has_builder(): + build_product_nodes.add(node) executor = node.get_executor() if executor is not None: stack += executor.get_all_prerequisites() + executor.get_all_children() @@ -281,6 +283,7 @@ def count_scons_nodes(nodes): progress_interval = 5 progress_count = 0 +build_product_nodes = set() progress_total = max(1, count_scons_nodes(env.arg2nodes(BUILD_TARGETS or [Dir('.')], env.fs.Entry))) def progress_function(node): @@ -296,3 +299,11 @@ def progress_function(node): Progress(progress_function, interval=progress_interval) AddPostAction(BUILD_TARGETS or [Dir('.')], prune_cache_dir) + +def check_build_product_size(target, source, env): + limit = 50 * 1024 * 1024 # GitHub max size + for t in target: + if hasattr(t, 'isfile') and t.isfile() and (size := os.path.getsize(t.abspath)) > limit: + raise SCons.Errors.UserError(f"{t} is {size / (1024 * 1024):.1f} MiB, exceeding the {limit / (1024 * 1024):.1f} MiB limit") +if not GetOption('extras'): + AddPostAction(list(build_product_nodes), Action(check_build_product_size, None)) From 3939f1e92c92b1c15f7d3cbd59d386bfcbd8cdd0 Mon Sep 17 00:00:00 2001 From: stef <19478336+stefpi@users.noreply.github.com> Date: Tue, 16 Jun 2026 21:33:59 -0400 Subject: [PATCH 046/151] webrtc: signal shutdown over datachannel (#38185) signal shut down, fix enabled bug --- system/webrtc/webrtcd.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/system/webrtc/webrtcd.py b/system/webrtc/webrtcd.py index 48b868de21..f5e3d52ebb 100755 --- a/system/webrtc/webrtcd.py +++ b/system/webrtc/webrtcd.py @@ -262,7 +262,7 @@ class StreamSession: self.params = Params() builder = WebRTCAnswerBuilder(sdp) - self.enabled = enabled if enabled else True # default to enabled + self.enabled = enabled if enabled is not None else True # default to enabled self.video_track = LiveStreamVideoStreamTrack(init_camera, self.enabled) if not debug_mode else VideoStreamTrack() builder.add_video_stream(init_camera, self.video_track) self.stream = builder.stream() @@ -381,7 +381,7 @@ async def get_stream(request: 'web.Request'): if s.run_task and not s.run_task.done(): try: ch = s.stream.get_messaging_channel() - ch.send(json.dumps({"type": "connectionReplaced", "data": "Another device has connected, closing this session."})) + ch.send(json.dumps({"type": "disconnect", "data": "Another device has connected, closing this session."})) except Exception: pass await s.stop() @@ -431,6 +431,11 @@ async def post_notify(request: 'web.Request'): async def on_shutdown(app: 'web.Application'): for session in app['streams'].values(): + try: + ch = session.stream.get_messaging_channel() + ch.send(json.dumps({"type": "disconnect", "data": "device stream has been stopped."})) + except Exception: + pass await session.stop() del app['streams'] From e2e3703ae4630cb2ae9e61c4c94aef9011fcc108 Mon Sep 17 00:00:00 2001 From: Andi Radulescu Date: Wed, 17 Jun 2026 18:14:07 +0300 Subject: [PATCH 047/151] ui: fix false "NO PANDA" flash on screen wake (#37404) * ui: fix false "NO PANDA" flash on screen wake * ui: use recv_time for panda timeout instead of frame counting * ui: use sm.alive for panda timeout --- selfdrive/ui/ui_state.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/selfdrive/ui/ui_state.py b/selfdrive/ui/ui_state.py index 6309642fd2..643054e508 100644 --- a/selfdrive/ui/ui_state.py +++ b/selfdrive/ui/ui_state.py @@ -1,4 +1,3 @@ -import pyray as rl import numpy as np import time import threading @@ -141,7 +140,7 @@ class UIState: # Check ignition status across all pandas if self.panda_type != log.PandaState.PandaType.unknown: self.ignition = any(state.ignitionLine or state.ignitionCan for state in panda_states) - elif self.sm.frame - self.sm.recv_frame["pandaStates"] > 5 * rl.get_fps(): + elif not self.sm.alive["pandaStates"]: self.panda_type = log.PandaState.PandaType.unknown # Handle wide road camera state updates From 5ab7e484794da5a65f5875faffb9b29c2a9eaf85 Mon Sep 17 00:00:00 2001 From: David <49467229+TheSecurityDev@users.noreply.github.com> Date: Wed, 17 Jun 2026 11:54:24 -0500 Subject: [PATCH 048/151] fix(ui): fill and center onroad camera if too small (#37673) * ui: ensure zoom accommodates full view area in AugmentedRoadView * fix: use _content_rect --------- Co-authored-by: Adeeb Shihadeh --- selfdrive/ui/mici/onroad/augmented_road_view.py | 7 +++++-- selfdrive/ui/onroad/augmented_road_view.py | 9 ++++++--- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/selfdrive/ui/mici/onroad/augmented_road_view.py b/selfdrive/ui/mici/onroad/augmented_road_view.py index 0246a0e597..e6609f9c09 100644 --- a/selfdrive/ui/mici/onroad/augmented_road_view.py +++ b/selfdrive/ui/mici/onroad/augmented_road_view.py @@ -313,10 +313,13 @@ class AugmentedRoadView(CameraView): w, h = self._content_rect.width, self._content_rect.height cx, cy = intrinsic[0, 2], intrinsic[1, 2] + # Ensure zoom views the whole area + zoom = max(zoom, w / (2 * cx), h / (2 * cy)) + # Calculate max allowed offsets with margins margin = 5 - max_x_offset = cx * zoom - w / 2 - margin - max_y_offset = cy * zoom - h / 2 - margin + max_x_offset = max(0.0, cx * zoom - w / 2 - margin) + max_y_offset = max(0.0, cy * zoom - h / 2 - margin) # Calculate and clamp offsets to prevent out-of-bounds issues try: diff --git a/selfdrive/ui/onroad/augmented_road_view.py b/selfdrive/ui/onroad/augmented_road_view.py index 1a2181628e..d381c255ea 100644 --- a/selfdrive/ui/onroad/augmented_road_view.py +++ b/selfdrive/ui/onroad/augmented_road_view.py @@ -76,7 +76,7 @@ class AugmentedRoadView(CameraView): ) # Render the base camera view - super()._render(rect) + super()._render(self._content_rect) # Draw all UI overlays self.model_renderer.render(self._content_rect) @@ -175,10 +175,13 @@ class AugmentedRoadView(CameraView): w, h = self._content_rect.width, self._content_rect.height cx, cy = intrinsic[0, 2], intrinsic[1, 2] + # Ensure zoom views the whole area + zoom = max(zoom, w / (2 * cx), h / (2 * cy)) + # Calculate max allowed offsets with margins margin = 5 - max_x_offset = cx * zoom - w / 2 - margin - max_y_offset = cy * zoom - h / 2 - margin + max_x_offset = max(0.0, cx * zoom - w / 2 - margin) + max_y_offset = max(0.0, cy * zoom - h / 2 - margin) # Calculate and clamp offsets to prevent out-of-bounds issues try: From d4db600d4b8cedf68c0ea23d06c7acdd5cea002c Mon Sep 17 00:00:00 2001 From: David <49467229+TheSecurityDev@users.noreply.github.com> Date: Wed, 17 Jun 2026 12:27:46 -0500 Subject: [PATCH 049/151] ui diff: add multithreading and improve logging (split from #37328) (#37474) * split out and refactor * simplify * rm extra line * use threadpoolexecutor to handle exceptions * simplify * improve --------- Co-authored-by: Adeeb Shihadeh --- selfdrive/ui/tests/diff/diff.py | 108 ++++++++++++++++++-------------- 1 file changed, 60 insertions(+), 48 deletions(-) diff --git a/selfdrive/ui/tests/diff/diff.py b/selfdrive/ui/tests/diff/diff.py index 974edb42a3..b861d848eb 100755 --- a/selfdrive/ui/tests/diff/diff.py +++ b/selfdrive/ui/tests/diff/diff.py @@ -4,6 +4,7 @@ import sys import subprocess import webbrowser import argparse +from concurrent.futures import ThreadPoolExecutor from pathlib import Path from openpilot.common.basedir import BASEDIR @@ -11,8 +12,8 @@ DIFF_OUT_DIR = Path(BASEDIR) / "selfdrive" / "ui" / "tests" / "diff" / "report" HTML_TEMPLATE_PATH = Path(__file__).with_name("diff_template.html") -def extract_framehashes(video_path): - cmd = ['ffmpeg', '-i', video_path, '-map', '0:v:0', '-vsync', '0', '-f', 'framehash', '-hash', 'md5', '-'] +def extract_framehashes(video_path: Path) -> list[str]: + cmd = ['ffmpeg', '-nostdin', '-i', video_path, '-map', '0:v:0', '-vsync', '0', '-f', 'framehash', '-hash', 'md5', '-'] result = subprocess.run(cmd, capture_output=True, text=True, check=True) hashes = [] for line in result.stdout.splitlines(): @@ -25,42 +26,33 @@ def extract_framehashes(video_path): return hashes -def create_diff_video(video1, video2, output_path): - """Create a diff video using ffmpeg blend filter with difference mode.""" - print("Creating diff video...") - cmd = ['ffmpeg', '-i', video1, '-i', video2, '-filter_complex', '[0:v]blend=all_mode=difference', '-vsync', '0', '-y', output_path] +def get_video_frame_hashes(video1: Path, video2: Path) -> tuple[list[str], list[str]]: + """Hash every frame of both videos in parallel and return the two hash lists.""" + with ThreadPoolExecutor(max_workers=2) as executor: + print("Generating frame hashes for both videos...") + future1 = executor.submit(extract_framehashes, video1) + future2 = executor.submit(extract_framehashes, video2) + hashes1 = future1.result() + hashes2 = future2.result() + return hashes1, hashes2 + + +def create_diff_video(video1: Path, video2: Path, output: Path) -> None: + """Create a diff video of two clips using ffmpeg blend filter with difference mode.""" + cmd = ['ffmpeg', '-nostdin', '-i', video1, '-i', video2, '-filter_complex', 'blend=all_mode=difference', '-vsync', '0', '-y', output] subprocess.run(cmd, capture_output=True, check=True) -def find_differences(video1, video2) -> tuple[list[int], tuple[int, int]]: - print(f"Hashing frames from {video1}...") - hashes1 = extract_framehashes(video1) - - print(f"Hashing frames from {video2}...") - hashes2 = extract_framehashes(video2) - - print(f"Comparing {len(hashes1)} frames...") +def find_frame_differences(hashes1: list[str], hashes2: list[str]) -> list[int]: + """Compare two lists of frame hashes and return the indices of different frames.""" different_frames = [] - for i, (h1, h2) in enumerate(zip(hashes1, hashes2, strict=False)): if h1 != h2: different_frames.append(i) - - return different_frames, (len(hashes1), len(hashes2)) + return different_frames -def generate_html_report(videos: tuple[str, str], basedir: str, different_frames: list[int], frame_counts: tuple[int, int], diff_video_name): - chunks = [] - if different_frames: - current_chunk = [different_frames[0]] - for i in range(1, len(different_frames)): - if different_frames[i] == different_frames[i - 1] + 1: - current_chunk.append(different_frames[i]) - else: - chunks.append(current_chunk) - current_chunk = [different_frames[i]] - chunks.append(current_chunk) - +def generate_html_report(videos: tuple[Path, Path], basedir: str, different_frames: list[int], frame_counts: tuple[int, int], diff_video_name: str) -> str: total_frames = max(frame_counts) frame_delta = frame_counts[1] - frame_counts[0] different_total = len(different_frames) + abs(frame_delta) @@ -71,12 +63,13 @@ def generate_html_report(videos: tuple[str, str], basedir: str, different_frames else f"❌ Found {different_total} different frames out of {total_frames} total ({different_total / total_frames * 100:.1f}%)." + (f" Video {'2' if frame_delta > 0 else '1'} is longer by {abs(frame_delta)} frames." if frame_delta != 0 else "") ) + print(f" Results: {result_text}") # Load HTML template and replace placeholders html = HTML_TEMPLATE_PATH.read_text() placeholders = { - "VIDEO1_SRC": os.path.join(basedir, os.path.basename(videos[0])), - "VIDEO2_SRC": os.path.join(basedir, os.path.basename(videos[1])), + "VIDEO1_SRC": os.path.join(basedir, videos[0].name), + "VIDEO2_SRC": os.path.join(basedir, videos[1].name), "DIFF_SRC": os.path.join(basedir, diff_video_name), "RESULT_TEXT": result_text, } @@ -91,7 +84,7 @@ def main(): parser.add_argument('video1', help='First video file') parser.add_argument('video2', help='Second video file') parser.add_argument('output', nargs='?', default='diff.html', help='Output HTML file (default: diff.html)') - parser.add_argument("--basedir", type=str, help="Base directory for output", default="") + parser.add_argument("--basedir", type=str, help="Base path for files in HTML report", default="") parser.add_argument('--no-open', action='store_true', help='Do not open HTML report in browser') args = parser.parse_args() @@ -99,37 +92,56 @@ def main(): if not args.output.lower().endswith('.html'): args.output += '.html' + video1, video2 = Path(args.video1), Path(args.video2) + missing = [str(p) for p in (video1, video2) if not p.is_file()] + if missing: + parser.error(f"Video file(s) not found: {', '.join(missing)}") + + diff_video_name = f"{Path(args.output).stem}.mp4" # diff video name derived from output HTML name + os.makedirs(DIFF_OUT_DIR, exist_ok=True) print("=" * 60) - print("VIDEO DIFF - HTML REPORT") + print("UI VIDEO DIFF - HTML REPORT") print("=" * 60) - print(f"Video 1: {args.video1}") - print(f"Video 2: {args.video2}") - print(f"Output: {args.output}") + print(f"Video 1: {video1}") + print(f"Video 2: {video2}") + print(f"HTML output: {args.output}") + print(f"Diff video: {diff_video_name}") print() - # Create diff video with name derived from output HTML - diff_video_name = Path(args.output).stem + '.mp4' - diff_video_path = str(DIFF_OUT_DIR / diff_video_name) - create_diff_video(args.video1, args.video2, diff_video_path) + print("[1/4] Starting full video diff generation in background thread...") + diff_executor = ThreadPoolExecutor(max_workers=1) + diff_future = diff_executor.submit(create_diff_video, video1, video2, DIFF_OUT_DIR / diff_video_name) - different_frames, frame_counts = find_differences(args.video1, args.video2) + print("[2/4] Hashing frames...") + hashes1, hashes2 = get_video_frame_hashes(video1, video2) + frame_counts = (len(hashes1), len(hashes2)) + print(f" Found {frame_counts[0]} frames in video 1 and {frame_counts[1]} frames in video 2.") - if different_frames is None: - sys.exit(1) + print("[3/4] Finding different frames...") + different_frames = find_frame_differences(hashes1, hashes2) + print(f" Found {len(different_frames)} different frames.") - print() - print("Generating HTML report...") - html = generate_html_report((args.video1, args.video2), args.basedir, different_frames, frame_counts, diff_video_name) + print("[4/4] Generating HTML report...") + html = generate_html_report((video1, video2), args.basedir, different_frames, frame_counts, diff_video_name) - with open(DIFF_OUT_DIR / args.output, 'w') as f: + output_path = DIFF_OUT_DIR / args.output + with open(output_path, 'w') as f: f.write(html) + print(f" Report generated at: {output_path}") + # Open in browser by default if not args.no_open: print(f"Opening {args.output} in browser...") - webbrowser.open(f'file://{os.path.abspath(DIFF_OUT_DIR / args.output)}') + webbrowser.open(f'file://{os.path.abspath(output_path)}') + + # Wait for diff video generation to finish before exiting + if not diff_future.done(): + print("Waiting for diff video generation to finish...") + diff_future.result() + diff_executor.shutdown() extra_frames = abs(frame_counts[0] - frame_counts[1]) return 0 if (len(different_frames) + extra_frames) == 0 else 1 From ddc8d371363226708c2eaab5c67323a266e9e34f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Harald=20Sch=C3=A4fer?= Date: Wed, 17 Jun 2026 13:48:53 -0400 Subject: [PATCH 050/151] Desire keep pulsing is dead (#38187) --- selfdrive/controls/lib/desire_helper.py | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/selfdrive/controls/lib/desire_helper.py b/selfdrive/controls/lib/desire_helper.py index ee4567f1e9..659c0adc30 100644 --- a/selfdrive/controls/lib/desire_helper.py +++ b/selfdrive/controls/lib/desire_helper.py @@ -36,7 +36,6 @@ class DesireHelper: self.lane_change_direction = LaneChangeDirection.none self.lane_change_timer = 0.0 self.lane_change_ll_prob = 1.0 - self.keep_pulse_timer = 0.0 self.prev_one_blinker = False self.desire = log.Desire.none @@ -107,13 +106,3 @@ class DesireHelper: self.prev_one_blinker = one_blinker self.desire = DESIRES[self.lane_change_direction][self.lane_change_state] - - # Send keep pulse once per second during LaneChangeStart.preLaneChange - if self.lane_change_state in (LaneChangeState.off, LaneChangeState.laneChangeStarting): - self.keep_pulse_timer = 0.0 - elif self.lane_change_state == LaneChangeState.preLaneChange: - self.keep_pulse_timer += DT_MDL - if self.keep_pulse_timer > 1.0: - self.keep_pulse_timer = 0.0 - elif self.desire in (log.Desire.keepLeft, log.Desire.keepRight): - self.desire = log.Desire.none From cd2c590d50ee8301cdf10a9ae6565d488a1c03e8 Mon Sep 17 00:00:00 2001 From: Christopher Milan Date: Wed, 17 Jun 2026 11:24:11 -0700 Subject: [PATCH 051/151] bump tinygrad (#38176) * bump tinygrad * wip: try this * origin/master --------- Co-authored-by: Adeeb Shihadeh Co-authored-by: Comma Device --- selfdrive/modeld/compile_modeld.py | 4 ++-- tinygrad_repo | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/selfdrive/modeld/compile_modeld.py b/selfdrive/modeld/compile_modeld.py index 09e8d06c7c..069e39091a 100755 --- a/selfdrive/modeld/compile_modeld.py +++ b/selfdrive/modeld/compile_modeld.py @@ -51,8 +51,8 @@ def warp_perspective_tinygrad(src_flat, M_inv, dst_shape, src_shape, stride_pad, w_dst, h_dst = dst_shape h_src, w_src = src_shape - x = Tensor.arange(w_dst, device=WARP_DEV).reshape(1, w_dst).expand(h_dst, w_dst).reshape(-1) - y = Tensor.arange(h_dst, device=WARP_DEV).reshape(h_dst, 1).expand(h_dst, w_dst).reshape(-1) + x = Tensor.arange(w_dst).reshape(1, w_dst).expand(h_dst, w_dst).reshape(-1) + y = Tensor.arange(h_dst).reshape(h_dst, 1).expand(h_dst, w_dst).reshape(-1) # inline 3x3 matmul as elementwise to avoid reduce op (enables fusion with gather) src_x = M_inv[0, 0] * x + M_inv[0, 1] * y + M_inv[0, 2] diff --git a/tinygrad_repo b/tinygrad_repo index 5039d954f2..443f976305 160000 --- a/tinygrad_repo +++ b/tinygrad_repo @@ -1 +1 @@ -Subproject commit 5039d954f27fd4d4ebeb76951e9933f17985c1a4 +Subproject commit 443f976305038c113cc7836799967da738c5b77e From 0038d84e1399bba3a8b93870e9772177e1e51c6c Mon Sep 17 00:00:00 2001 From: stef <19478336+stefpi@users.noreply.github.com> Date: Wed, 17 Jun 2026 17:53:06 -0400 Subject: [PATCH 052/151] webrtc: do not replace connection on prewarm (#38190) * refactor * remove accidental change * clean error handler * clean structure * only is other stream is active and enabled * better structure * remove enabled None default * update comment --- system/athena/athenad.py | 6 ++---- system/webrtc/models.py | 4 ++-- system/webrtc/webrtcd.py | 39 +++++++++++++++++---------------------- 3 files changed, 21 insertions(+), 28 deletions(-) diff --git a/system/athena/athenad.py b/system/athena/athenad.py index 4c9b536219..d72745a389 100755 --- a/system/athena/athenad.py +++ b/system/athena/athenad.py @@ -580,7 +580,7 @@ def getNetworks(): @dispatcher.add_method -def startStream(sdp: str, video_enabled: bool | None = None) -> dict: +def startStream(sdp: str, enabled: bool) -> dict: from openpilot.system.webrtc.models import StreamRequestBody bridge_services_in = [] @@ -592,12 +592,10 @@ def startStream(sdp: str, video_enabled: bool | None = None) -> dict: bridge_services_in.append("testJoystick") t_start = time.monotonic() - body = StreamRequestBody(sdp=sdp, initCamera="wideRoad", bridge_services_in=bridge_services_in, bridge_services_out=["carState"], video_enabled=video_enabled) + body = StreamRequestBody(sdp=sdp, init_camera="wideRoad", bridge_services_in=bridge_services_in, bridge_services_out=["carState"], enabled=enabled) try: resp = WEBRTCD_SESS.post(f"http://localhost:{WEBRTCD_PORT}/stream", json=asdict(body), timeout=10) t_end = time.monotonic() - if not resp.ok: - raise Exception(resp.json().get("message", f"webrtcd returned {resp.status_code}")) ret = resp.json() ret["time"] = (t_end - t_start) * 1000 return ret diff --git a/system/webrtc/models.py b/system/webrtc/models.py index fd74113049..5a80576f7d 100644 --- a/system/webrtc/models.py +++ b/system/webrtc/models.py @@ -3,7 +3,7 @@ from dataclasses import dataclass, field @dataclass class StreamRequestBody: sdp: str - initCamera: str - video_enabled: bool = True + init_camera: str + enabled: bool bridge_services_in: list[str] = field(default_factory=list) bridge_services_out: list[str] = field(default_factory=list) diff --git a/system/webrtc/webrtcd.py b/system/webrtc/webrtcd.py index f5e3d52ebb..c2bceb5d90 100755 --- a/system/webrtc/webrtcd.py +++ b/system/webrtc/webrtcd.py @@ -244,15 +244,7 @@ class LivestreamBitrateController(AsyncTaskRunner): class StreamSession: shared_pub_master = DynamicPubMaster([]) - def __init__( - self, - sdp: str, - init_camera: str, - incoming_services: list[str], - outgoing_services: list[str], - enabled: bool | None = None, - debug_mode: bool = False - ): + def __init__(self, body: StreamRequestBody, debug_mode: bool = False): if debug_mode: from aiortc.mediastreams import VideoStreamTrack from openpilot.system.webrtc.device.video import LiveStreamVideoStreamTrack @@ -260,21 +252,21 @@ class StreamSession: self.identifier = str(uuid.uuid4()) self.params = Params() - builder = WebRTCAnswerBuilder(sdp) + builder = WebRTCAnswerBuilder(body.sdp) - self.enabled = enabled if enabled is not None else True # default to enabled - self.video_track = LiveStreamVideoStreamTrack(init_camera, self.enabled) if not debug_mode else VideoStreamTrack() - builder.add_video_stream(init_camera, self.video_track) + self.enabled = body.enabled + self.video_track = LiveStreamVideoStreamTrack(body.init_camera, self.enabled) if not debug_mode else VideoStreamTrack() + builder.add_video_stream(body.init_camera, self.video_track) self.stream = builder.stream() self.incoming_bridge: CerealIncomingMessageProxy | None = None - self.incoming_bridge_services = incoming_services + self.incoming_bridge_services = body.bridge_services_in self.outgoing_bridge: CerealOutgoingMessageProxy | None = None self.bitrate_controller: LivestreamBitrateController | None = None - if len(incoming_services) > 0: + if len(body.bridge_services_in) > 0: self.incoming_bridge = CerealIncomingMessageProxy(self.shared_pub_master) - if len(outgoing_services) > 0: - self.outgoing_bridge = CerealOutgoingMessageProxy(outgoing_services, self.enabled) + if len(body.bridge_services_out) > 0: + self.outgoing_bridge = CerealOutgoingMessageProxy(body.bridge_services_out, self.enabled) self.bitrate_controller = LivestreamBitrateController(self.stream.peer_connection, self.params, self.enabled) self.run_task: asyncio.Task | None = None @@ -283,7 +275,7 @@ class StreamSession: self.logger = logging.getLogger("webrtcd") self.logger.info( "New stream session (%s), init camera %s, video enabled %s, incoming services %s, outgoing services %s", - self.identifier, init_camera, enabled, incoming_services, outgoing_services, + self.identifier, body.init_camera, body.enabled, body.bridge_services_in, body.bridge_services_out, ) def start(self): @@ -313,6 +305,7 @@ class StreamSession: self.bitrate_controller.set_quality(payload["data"]["quality"]) case "livestreamVideoEnable": enabled = payload["data"]["enabled"] + self.enabled = enabled self.video_track.enable(enabled) self.outgoing_bridge.enable(enabled) self.bitrate_controller.enable(enabled) @@ -376,7 +369,11 @@ async def get_stream(request: 'web.Request'): body = StreamRequestBody(**raw_body) async with request.app['stream_lock']: - # Fully disconnect any other active stream before starting the replacement. + # don't remove existing connection on prewarm request + enabled = any(s.run_task and not s.run_task.done() and s.enabled for s in stream_dict.values()) + if enabled and not body.enabled: + return web.json_response({"error": "busy", "message": "someone else is connected."}) + for sid, s in list(stream_dict.items()): if s.run_task and not s.run_task.done(): try: @@ -387,7 +384,7 @@ async def get_stream(request: 'web.Request'): await s.stop() stream_dict.pop(sid, None) - session = StreamSession(body.sdp, body.initCamera, body.bridge_services_in, body.bridge_services_out, body.video_enabled, debug_mode) + session = StreamSession(body, debug_mode) stream_dict[session.identifier] = session try: answer = await session.get_answer() @@ -444,8 +441,6 @@ async def on_shutdown(app: 'web.Application'): async def error_middleware(request: 'web.Request', handler): try: return await handler(request) - except web.HTTPException: - raise # intentional responses (400/404/etc.) pass through untouched except Exception as e: logging.getLogger("webrtcd").exception("Unhandled error handling %s", request.path) return web.json_response({"error": "exception", "message": f"{type(e).__name__}: {e}"}, status=500) From 45d8bcd7f3f2da7e03d95f45218b49e00fb06963 Mon Sep 17 00:00:00 2001 From: stef <19478336+stefpi@users.noreply.github.com> Date: Fri, 19 Jun 2026 21:20:55 -0400 Subject: [PATCH 053/151] car livestream (#38193) * athenad and webrtcd updates * remove feature stream services from webrtcd split * stream encoder thread * reduce diff * wire webrtc to livestream camera encoder * request livestream camera switch service * remove camera list in favour of init camera field * remove cors * clean * remove unused * remove extra try except * add back exception trace * add stream road camera info to stream cameras * fix * clean diff * clean diff * add testJoystick only on body * fix camera list * remove reference to future service * encode all cameras and swap in video track in webrtc * clean * explicitly gate bridge send * clean leftover * initial idea * add a watchdog to kill the process after disconnect or onroad * start camerad and stream encoderd as well * add message handler even without bridge * remove carState when offroad * transition to onroad works for body, kill for car not working * turn off stream processes on started car * cereal messaging sub field allow list, carparamspersistent, ping webrtcd to see when awake * fix imports * fix and increase max retries * reduce max retries, increase timeout * timeout on wait for connection * remove cereal sub message and update process config to run on body ignition * debounce 5s on teardown * update error messages * fix tear down crash * clean * clean * fix lint --- common/params_keys.h | 1 + system/athena/athenad.py | 34 ++++++++++++--------------- system/manager/process_config.py | 12 +++++++--- system/webrtc/helpers.py | 40 ++++++++++++++++++++++++++++++++ system/webrtc/models.py | 9 ------- system/webrtc/webrtcd.py | 27 ++++++++++++++------- 6 files changed, 83 insertions(+), 40 deletions(-) create mode 100644 system/webrtc/helpers.py delete mode 100644 system/webrtc/models.py diff --git a/common/params_keys.h b/common/params_keys.h index 546a53c76c..01b051545a 100644 --- a/common/params_keys.h +++ b/common/params_keys.h @@ -58,6 +58,7 @@ inline static std::unordered_map keys = { {"IsDriverViewEnabled", {CLEAR_ON_MANAGER_START, BOOL}}, {"IsEngaged", {PERSISTENT, BOOL}}, {"IsLdwEnabled", {PERSISTENT, BOOL}}, + {"IsLiveStreaming", {CLEAR_ON_MANAGER_START, BOOL}}, {"IsMetric", {PERSISTENT, BOOL}}, {"IsOffroad", {CLEAR_ON_MANAGER_START, BOOL}}, {"IsOnroad", {PERSISTENT, BOOL}}, diff --git a/system/athena/athenad.py b/system/athena/athenad.py index d72745a389..8cadfb857a 100755 --- a/system/athena/athenad.py +++ b/system/athena/athenad.py @@ -45,7 +45,6 @@ from openpilot.system.hardware.hw import Paths ATHENA_HOST = os.getenv('ATHENA_HOST', 'wss://athena.comma.ai') HANDLER_THREADS = int(os.getenv('HANDLER_THREADS', "4")) LOCAL_PORT_WHITELIST = {22, } # SSH -WEBRTCD_PORT = 5001 LOG_ATTR_NAME = 'user.upload' LOG_ATTR_VALUE_MAX_UNIX_TIME = int.to_bytes(2147483647, 4, sys.byteorder) @@ -84,9 +83,6 @@ UPLOAD_SESS = requests.Session() UPLOAD_SESS.mount("http://", UploadTOSAdapter()) UPLOAD_SESS.mount("https://", UploadTOSAdapter()) -WEBRTCD_SESS = requests.Session() -WEBRTCD_SESS.mount("http://", HTTPAdapter(max_retries=0)) - @dataclass class UploadFile: @@ -581,28 +577,28 @@ def getNetworks(): @dispatcher.add_method def startStream(sdp: str, enabled: bool) -> dict: - from openpilot.system.webrtc.models import StreamRequestBody + from openpilot.system.webrtc.helpers import StreamRequestBody, post_stream_request, wait_for_webrtcd + params = Params() bridge_services_in = [] - # get live car params to avoid stale notCar edge case - cp_bytes = Params().get("CarParams") + # stale car params case taken care of by webrtcd being shut off on ignition + cp_bytes = Params().get("CarParamsPersistent") if cp_bytes is not None: with car.CarParams.from_bytes(cp_bytes) as CP: if CP.notCar: bridge_services_in.append("testJoystick") + else: + raise Exception("failed to get CarParamsPersistent") + + if not params.get_bool("IsOnroad"): + # manager owns camerad/stream_encoderd/webrtcd; flip the param and let it bring them up. + # webrtcd clears IsLiveStreaming when the session ends + params.put_bool("IsLiveStreaming", True) + # wait for webrtcd end points to wake up + wait_for_webrtcd() + + return post_stream_request(StreamRequestBody(sdp, "wideRoad", enabled, bridge_services_in, ["carState", "deviceState"])) - t_start = time.monotonic() - body = StreamRequestBody(sdp=sdp, init_camera="wideRoad", bridge_services_in=bridge_services_in, bridge_services_out=["carState"], enabled=enabled) - try: - resp = WEBRTCD_SESS.post(f"http://localhost:{WEBRTCD_PORT}/stream", json=asdict(body), timeout=10) - t_end = time.monotonic() - ret = resp.json() - ret["time"] = (t_end - t_start) * 1000 - return ret - except requests.ConnectTimeout as e: - raise Exception("webrtc took too long to respond. is the comma body on?") from e - except requests.ConnectionError as e: - raise Exception("webrtc is not running. turn on comma body ignition.") from e @dispatcher.add_method def takeSnapshot() -> str | dict[str, str] | None: diff --git a/system/manager/process_config.py b/system/manager/process_config.py index 7ed4a2dacb..84f0313714 100644 --- a/system/manager/process_config.py +++ b/system/manager/process_config.py @@ -58,21 +58,27 @@ def only_onroad(started: bool, params: Params, CP: car.CarParams) -> bool: def only_offroad(started: bool, params: Params, CP: car.CarParams) -> bool: return not started +def livestream(started: bool, params: Params, CP: car.CarParams) -> bool: + return params.get_bool("IsLiveStreaming") + def or_(*fns): return lambda *args: operator.or_(*(fn(*args) for fn in fns)) def and_(*fns): return lambda *args: operator.and_(*(fn(*args) for fn in fns)) +def not_(*fns): + return lambda *args: operator.not_(*(fn(*args) for fn in fns)) + procs = [ DaemonProcess("manage_athenad", "system.athena.manage_athenad", "AthenadPid"), NativeProcess("loggerd", "system/loggerd", ["./loggerd"], logging), NativeProcess("encoderd", "system/loggerd", ["./encoderd"], only_onroad), - NativeProcess("stream_encoderd", "system/loggerd", ["./encoderd", "--stream"], notcar), + NativeProcess("stream_encoderd", "system/loggerd", ["./encoderd", "--stream"], or_(and_(livestream, not_(iscar)), notcar)), PythonProcess("logmessaged", "system.logmessaged", always_run), - NativeProcess("camerad", "system/camerad", ["./camerad"], driverview, enabled=not WEBCAM), + NativeProcess("camerad", "system/camerad", ["./camerad"], or_(driverview, livestream), enabled=not WEBCAM), PythonProcess("webcamerad", "tools.webcam.camerad", driverview, enabled=WEBCAM), PythonProcess("proclogd", "system.proclogd", only_onroad, enabled=platform.system() != "Darwin"), PythonProcess("journald", "system.journald", only_onroad, platform.system() != "Darwin"), @@ -115,7 +121,7 @@ procs = [ # debug procs NativeProcess("bridge", "cereal/messaging", ["./bridge"], notcar), - PythonProcess("webrtcd", "system.webrtc.webrtcd", notcar), + PythonProcess("webrtcd", "system.webrtc.webrtcd", or_(and_(livestream, not_(iscar)), notcar)), PythonProcess("webjoystick", "tools.bodyteleop.web", notcar), PythonProcess("joystick", "tools.joystick.joystick_control", and_(joystick, iscar)), ] diff --git a/system/webrtc/helpers.py b/system/webrtc/helpers.py new file mode 100644 index 0000000000..776b64573e --- /dev/null +++ b/system/webrtc/helpers.py @@ -0,0 +1,40 @@ +import time +import requests +from dataclasses import asdict, dataclass, field + + +WEBRTCD_PORT = 5001 + +@dataclass +class StreamRequestBody: + sdp: str + init_camera: str + enabled: bool + bridge_services_in: list[str] = field(default_factory=list) + bridge_services_out: list[str] = field(default_factory=list) + + +def post_stream_request(body: StreamRequestBody) -> dict: + t_start = time.monotonic() + try: + resp = requests.post(f"http://localhost:{WEBRTCD_PORT}/stream", json=asdict(body), timeout=10) + t_end = time.monotonic() + ret = resp.json() + ret["time"] = (t_end - t_start) * 1000 + return ret + except requests.ConnectTimeout as e: + raise Exception("webrtc took too long to respond.") from e + except requests.ConnectionError as e: + raise Exception("webrtc server on device is not running.") from e + + +def wait_for_webrtcd(max_retries: float = 10) -> None: + attempts = 0 + while attempts < max_retries: + try: + if requests.get(f"http://localhost:{WEBRTCD_PORT}/schema", timeout=1).ok: + return + except requests.ConnectionError: + attempts += 1 + time.sleep(0.5) + raise TimeoutError("webrtcd did not initialize in time.") diff --git a/system/webrtc/models.py b/system/webrtc/models.py deleted file mode 100644 index 5a80576f7d..0000000000 --- a/system/webrtc/models.py +++ /dev/null @@ -1,9 +0,0 @@ -from dataclasses import dataclass, field - -@dataclass -class StreamRequestBody: - sdp: str - init_camera: str - enabled: bool - bridge_services_in: list[str] = field(default_factory=list) - bridge_services_out: list[str] = field(default_factory=list) diff --git a/system/webrtc/webrtcd.py b/system/webrtc/webrtcd.py index c2bceb5d90..da10855a59 100755 --- a/system/webrtc/webrtcd.py +++ b/system/webrtc/webrtcd.py @@ -23,7 +23,7 @@ if TYPE_CHECKING: from aiortc.rtcdatachannel import RTCDataChannel import aioice.ice -from openpilot.system.webrtc.models import StreamRequestBody +from openpilot.system.webrtc.helpers import StreamRequestBody from openpilot.system.webrtc.schema import generate_field from openpilot.common.params import Params from cereal import messaging, log @@ -329,11 +329,11 @@ class StreamSession: async def run(self): try: self.params.put("LivestreamRequestKeyframe", True) - await self.stream.wait_for_connection() + await asyncio.wait_for(self.stream.wait_for_connection(), timeout=15) if self.stream.has_messaging_channel(): + self.stream.set_message_handler(self.message_handler) if self.incoming_bridge is not None: await self.shared_pub_master.add_services_if_needed(self.incoming_bridge_services) - self.stream.set_message_handler(self.message_handler) if self.outgoing_bridge is not None: channel = self.stream.get_messaging_channel() self.outgoing_bridge.add_channel(channel) @@ -363,6 +363,17 @@ class StreamSession: await self.stream.stop() +def schedule_teardown(app): + # if nothing connects for 5 seconds, tear down livestreaming processes + h = app.get('teardown') + if h: + h.cancel() + def clear(): + if not app['streams']: + Params().put_bool("IsLiveStreaming", False) + app['teardown'] = asyncio.get_running_loop().call_later(5.0, clear) + + async def get_stream(request: 'web.Request'): stream_dict, debug_mode = request.app['streams'], request.app['debug'] raw_body = await request.json() @@ -397,13 +408,14 @@ async def get_stream(request: 'web.Request'): def remove_finished_session(_: asyncio.Task) -> None: stream_dict.pop(session.identifier, None) + schedule_teardown(request.app) session.run_task.add_done_callback(remove_finished_session) return web.json_response({"sdp": answer.sdp, "type": answer.type}) async def get_schema(request: 'web.Request'): - services = request.query["services"].split(",") + services = request.query.get("services", "").split(",") services = [s for s in services if s] assert all(s in log.Event.schema.fields and not s.endswith("DEPRECATED") for s in services), "Invalid service name" schema_dict = {s: generate_field(log.Event.schema.fields[s]) for s in services} @@ -427,10 +439,10 @@ async def post_notify(request: 'web.Request'): async def on_shutdown(app: 'web.Application'): - for session in app['streams'].values(): + for session in list(app['streams'].values()): try: ch = session.stream.get_messaging_channel() - ch.send(json.dumps({"type": "disconnect", "data": "device stream has been stopped."})) + ch.send(json.dumps({"type": "disconnect", "data": "device streaming has been stopped."})) except Exception: pass await session.stop() @@ -458,9 +470,6 @@ def prewarm_stream_session_imports(debug_mode: bool = False) -> None: def webrtcd_thread(host: str, port: int, debug: bool): logging.basicConfig(level=logging.CRITICAL, handlers=[logging.StreamHandler()]) - logging_level = logging.DEBUG if debug else logging.INFO - logging.getLogger("WebRTCStream").setLevel(logging_level) - logging.getLogger("webrtcd").setLevel(logging_level) prewarm_start = time.monotonic() prewarm_stream_session_imports(debug) prewarm_end = time.monotonic() From f257544f1b15ce04d0552691e77087d76963050f Mon Sep 17 00:00:00 2001 From: stef <19478336+stefpi@users.noreply.github.com> Date: Fri, 19 Jun 2026 22:08:21 -0400 Subject: [PATCH 054/151] tools: goodbye webjoystick (#38194) remove body web tool --- system/manager/process_config.py | 1 - tools/bodyteleop/static/index.html | 60 --------- tools/bodyteleop/static/js/controls.js | 20 --- tools/bodyteleop/static/js/jsmain.js | 21 --- tools/bodyteleop/static/js/plots.js | 53 -------- tools/bodyteleop/static/js/webrtc.js | 175 ------------------------ tools/bodyteleop/static/main.css | 178 ------------------------- tools/bodyteleop/static/poster.png | 3 - tools/bodyteleop/web.py | 86 ------------ 9 files changed, 597 deletions(-) delete mode 100644 tools/bodyteleop/static/index.html delete mode 100644 tools/bodyteleop/static/js/controls.js delete mode 100644 tools/bodyteleop/static/js/jsmain.js delete mode 100644 tools/bodyteleop/static/js/plots.js delete mode 100644 tools/bodyteleop/static/js/webrtc.js delete mode 100644 tools/bodyteleop/static/main.css delete mode 100644 tools/bodyteleop/static/poster.png delete mode 100644 tools/bodyteleop/web.py diff --git a/system/manager/process_config.py b/system/manager/process_config.py index 84f0313714..796e69eef6 100644 --- a/system/manager/process_config.py +++ b/system/manager/process_config.py @@ -122,7 +122,6 @@ procs = [ # debug procs NativeProcess("bridge", "cereal/messaging", ["./bridge"], notcar), PythonProcess("webrtcd", "system.webrtc.webrtcd", or_(and_(livestream, not_(iscar)), notcar)), - PythonProcess("webjoystick", "tools.bodyteleop.web", notcar), PythonProcess("joystick", "tools.joystick.joystick_control", and_(joystick, iscar)), ] diff --git a/tools/bodyteleop/static/index.html b/tools/bodyteleop/static/index.html deleted file mode 100644 index 48672dbbf0..0000000000 --- a/tools/bodyteleop/static/index.html +++ /dev/null @@ -1,60 +0,0 @@ - - - - - commabody - - - - - - - - - - -
-

comma body

- -
-
-
-
-
W
-
-
-
A
-
S
-
D
-
-
-
-
-
-
-
-
-
- - -
-

ping time

-
-
-
- - -
-

battery

-
-
-
-
-
-
-
-
-
-
-
- - - diff --git a/tools/bodyteleop/static/js/controls.js b/tools/bodyteleop/static/js/controls.js deleted file mode 100644 index 3a11f78b9e..0000000000 --- a/tools/bodyteleop/static/js/controls.js +++ /dev/null @@ -1,20 +0,0 @@ -const keyVals = {w: 0, a: 0, s: 0, d: 0} - -export function getXY() { - let x = -keyVals.w + keyVals.s - let y = -keyVals.d + keyVals.a - return {x, y} -} - -export const handleKeyX = (key, setValue) => { - if (['w', 'a', 's', 'd'].includes(key)){ - keyVals[key] = setValue; - let color = "#333"; - if (setValue === 1){ - color = "#e74c3c"; - } - $("#key-"+key).css('background', color); - const {x, y} = getXY(); - $("#pos-vals").text(x+","+y); - } -}; diff --git a/tools/bodyteleop/static/js/jsmain.js b/tools/bodyteleop/static/js/jsmain.js deleted file mode 100644 index 0db1dcd9b3..0000000000 --- a/tools/bodyteleop/static/js/jsmain.js +++ /dev/null @@ -1,21 +0,0 @@ -import { handleKeyX } from "./controls.js"; -import { start, stop, lastChannelMessageTime } from "./webrtc.js"; - -export var pc = null; -export var dc = null; - -document.addEventListener('keydown', (e)=>(handleKeyX(e.key.toLowerCase(), 1))); -document.addEventListener('keyup', (e)=>(handleKeyX(e.key.toLowerCase(), 0))); -$(".keys").bind("mousedown touchstart", (e)=>handleKeyX($(e.target).attr('id').replace('key-', ''), 1)); -$(".keys").bind("mouseup touchend", (e)=>handleKeyX($(e.target).attr('id').replace('key-', ''), 0)); -setInterval( () => { - const dt = new Date().getTime(); - if ((dt - lastChannelMessageTime) > 1000) { - $(".pre-blob").removeClass('blob'); - $("#battery").text("-"); - $("#ping-time").text('-'); - $("video")[0].load(); - } -}, 5000); - -start(pc, dc); diff --git a/tools/bodyteleop/static/js/plots.js b/tools/bodyteleop/static/js/plots.js deleted file mode 100644 index 5327bf71be..0000000000 --- a/tools/bodyteleop/static/js/plots.js +++ /dev/null @@ -1,53 +0,0 @@ -export const pingPoints = []; -export const batteryPoints = []; - -function getChartConfig(pts, color, title, ymax=100) { - return { - type: 'line', - data: { - datasets: [{ - label: title, - data: pts, - borderWidth: 1, - borderColor: color, - backgroundColor: color, - fill: 'origin' - }] - }, - options: { - scales: { - x: { - type: 'time', - time: { - unit: 'minute', - displayFormats: { - second: 'h:mm a' - } - }, - grid: { - color: '#222', // Grid lines color - }, - ticks: { - source: 'data', - fontColor: 'rgba(255, 255, 255, 1.0)', // Y-axis label color - } - }, - y: { - beginAtZero: true, - max: ymax, - grid: { - color: 'rgba(255, 255, 255, 0.1)', // Grid lines color - }, - ticks: { - fontColor: 'rgba(255, 255, 255, 0.7)', // Y-axis label color - } - } - } - } - } -} - -const ctxPing = document.getElementById('chart-ping'); -const ctxBattery = document.getElementById('chart-battery'); -export const chartPing = new Chart(ctxPing, getChartConfig(pingPoints, 'rgba(192, 57, 43, 0.7)', 'Controls Ping Time (ms)', 250)); -export const chartBattery = new Chart(ctxBattery, getChartConfig(batteryPoints, 'rgba(41, 128, 185, 0.7)', 'Battery %', 100)); diff --git a/tools/bodyteleop/static/js/webrtc.js b/tools/bodyteleop/static/js/webrtc.js deleted file mode 100644 index 28bea238e6..0000000000 --- a/tools/bodyteleop/static/js/webrtc.js +++ /dev/null @@ -1,175 +0,0 @@ -import { getXY } from "./controls.js"; -import { pingPoints, batteryPoints, chartPing, chartBattery } from "./plots.js"; - -export let controlCommandInterval = null; -export let latencyInterval = null; -export let lastChannelMessageTime = null; - - -export function offerRtcRequest(sdp, type) { - return fetch('/offer', { - body: JSON.stringify({sdp: sdp, type: type}), - headers: {'Content-Type': 'application/json'}, - method: 'POST' - }); -} - - -export function pingHeadRequest() { - return fetch('/', { - method: 'HEAD' - }); -} - - -export function createPeerConnection(pc) { - var config = { - sdpSemantics: 'unified-plan' - }; - - pc = new RTCPeerConnection(config); - - // connect video - pc.addEventListener('track', function(evt) { - console.log("Adding Tracks!") - if (evt.track.kind == 'video') - document.getElementById('video').srcObject = evt.streams[0]; - }); - return pc; -} - - -export function negotiate(pc) { - return pc.createOffer({offerToReceiveVideo:true}).then(function(offer) { - return pc.setLocalDescription(offer); - }).then(function() { - return new Promise(function(resolve) { - if (pc.iceGatheringState === 'complete') { - resolve(); - } - else { - function checkState() { - if (pc.iceGatheringState === 'complete') { - pc.removeEventListener('icegatheringstatechange', checkState); - resolve(); - } - } - pc.addEventListener('icegatheringstatechange', checkState); - } - }); - }).then(function() { - var offer = pc.localDescription; - return offerRtcRequest(offer.sdp, offer.type); - }).then(function(response) { - console.log(response); - return response.json(); - }).then(function(answer) { - return pc.setRemoteDescription(answer); - }).catch(function(e) { - alert(e); - }); -} - - -function isMobile() { - let check = false; - (function(a){if(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4))) check = true;})(navigator.userAgent||navigator.vendor||window.opera); - return check; -}; - - -export const constraints = { - video: isMobile() -}; - - -export function start(pc, dc) { - pc = createPeerConnection(pc); - - // add a local video track on mobile - (constraints.video ? navigator.mediaDevices.getUserMedia(constraints) : Promise.resolve(null)) - .then(function(stream) { - if (stream) { - stream.getTracks().forEach(function(track) { - pc.addTrack(track, stream); - }); - } - - return negotiate(pc); - }) - .catch(function(err) { - alert('Could not acquire media: ' + err); - }); - - var parameters = {"ordered": true}; - dc = pc.createDataChannel('data', parameters); - dc.onclose = function() { - clearInterval(controlCommandInterval); - clearInterval(latencyInterval); - }; - - function sendJoystickOverDataChannel() { - const {x, y} = getXY(); - var message = JSON.stringify({type: "testJoystick", data: {axes: [x, y], buttons: [false]}}) - dc.send(message); - } - function checkLatency() { - const initialTime = new Date().getTime(); - pingHeadRequest().then(function() { - const currentTime = new Date().getTime(); - if (Math.abs(currentTime - lastChannelMessageTime) < 1000) { - const pingtime = currentTime - initialTime; - pingPoints.push({'x': currentTime, 'y': pingtime}); - if (pingPoints.length > 1000) { - pingPoints.shift(); - } - chartPing.update(); - $("#ping-time").text((pingtime) + "ms"); - } - }) - } - dc.onopen = function() { - controlCommandInterval = setInterval(sendJoystickOverDataChannel, 50); - latencyInterval = setInterval(checkLatency, 1000); - sendJoystickOverDataChannel(); - }; - - const textDecoder = new TextDecoder(); - var carStaterIndex = 0; - dc.onmessage = function(evt) { - const text = textDecoder.decode(evt.data); - const msg = JSON.parse(text); - if (carStaterIndex % 100 == 0 && msg.type === 'carState') { - const batteryLevel = Math.round(msg.data.fuelGauge * 100); - $("#battery").text(batteryLevel + "%"); - batteryPoints.push({'x': new Date().getTime(), 'y': batteryLevel}); - if (batteryPoints.length > 1000) { - batteryPoints.shift(); - } - chartBattery.update(); - } - carStaterIndex += 1; - lastChannelMessageTime = new Date().getTime(); - $(".pre-blob").addClass('blob'); - }; -} - - -export function stop(pc, dc) { - if (dc) { - dc.close(); - } - if (pc.getTransceivers) { - pc.getTransceivers().forEach(function(transceiver) { - if (transceiver.stop) { - transceiver.stop(); - } - }); - } - pc.getSenders().forEach(function(sender) { - sender.track.stop(); - }); - setTimeout(function() { - pc.close(); - }, 500); -} diff --git a/tools/bodyteleop/static/main.css b/tools/bodyteleop/static/main.css deleted file mode 100644 index 79fe8052ff..0000000000 --- a/tools/bodyteleop/static/main.css +++ /dev/null @@ -1,178 +0,0 @@ -body { - background: #333 !important; - color: #fff !important; - display: flex; - justify-content: center; - align-items: start; -} - -p { - margin: 0px !important; -} - -i { - font-style: normal; -} - -.small { - font-size: 1em !important -} - -.jumbo { - font-size: 8rem; -} - - -@media (max-width: 600px) { - .small { - font-size: 0.5em !important - } - .jumbo { - display: none; - } - -} - -#main { - display: flex; - flex-direction: column; - align-content: center; - justify-content: center; - align-items: center; - font-size: 30px; - width: 100%; - max-width: 1200px; -} - -video { - width: 95%; -} - -.pre-blob { - display: flex; - background: #333; - border-radius: 50%; - margin: 10px; - height: 45px; - width: 45px; - justify-content: center; - align-items: center; - font-size: 1rem; -} - -.blob { - background: rgba(231, 76, 60,1.0); - box-shadow: 0 0 0 0 rgba(231, 76, 60,1.0); - animation: pulse 2s infinite; -} - -@keyframes pulse { - 0% { - box-shadow: 0 0 0 0px rgba(192, 57, 43, 1); - } - 100% { - box-shadow: 0 0 0 20px rgba(192, 57, 43, 0); - } -} - - -.icon-sup-panel { - display: flex; - flex-direction: row; - justify-content: space-around; - align-items: center; - background: #222; - border-radius: 10px; - padding: 5px; - margin: 5px 0px 5px 0px; -} - -.icon-sub-panel { - display: flex; - flex-direction: column; - justify-content: space-between; - align-items: center; -} - -#icon-panel { - display: flex; - width: 100%; - justify-content: space-between; - margin-top: 5px; -} - -.icon-sub-sub-panel { - display: flex; - flex-direction: row; -} - -.keys, #key-val { - background: #333; - padding: 2rem; - margin: 5px; - color: #fff; - display: flex; - justify-content: center; - align-items: center; - border-radius: 10px; - cursor: pointer; -} - -#key-val { - pointer-events: none; - background: #fff; - color: #333; - line-height: 1; - font-size: 20px; - flex-direction: column; -} - -.wasd-row { - display: flex; - flex-direction: row; - justify-content: center; - align-items: stretch; -} - -#wasd { - margin: 5px 0px 5px 0px; - background: #222; - border-radius: 10px; - width: 100%; - padding: 20px; - display: flex; - flex-direction: row; - justify-content: space-around; - align-items: stretch; - - user-select: none; - -webkit-touch-callout: none; - -webkit-user-select: none; - -khtml-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - touch-action: manipulation; -} - -.panel { - display: flex; - justify-content: center; - margin: 5px 0px 5px 0px !important; - background: #222; - border-radius: 10px; - width: 100%; - padding: 10px; -} - -#ping-time, #battery { - font-size: 25px; -} - -#stop { - display: none; -} - -.details { - display: flex; - padding: 0px 10px 0px 10px; -} diff --git a/tools/bodyteleop/static/poster.png b/tools/bodyteleop/static/poster.png deleted file mode 100644 index 2f2b02dd8a..0000000000 --- a/tools/bodyteleop/static/poster.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:8740da2be7faac198b5e10780c646166056a76ebbe3d64499e0cdc49280c8a4f -size 8297 diff --git a/tools/bodyteleop/web.py b/tools/bodyteleop/web.py deleted file mode 100644 index d357561b22..0000000000 --- a/tools/bodyteleop/web.py +++ /dev/null @@ -1,86 +0,0 @@ -import dataclasses -import json -import logging -import os -import ssl -import subprocess - -from aiohttp import web -from aiohttp import ClientSession - -from openpilot.common.basedir import BASEDIR -from openpilot.system.webrtc.webrtcd import StreamRequestBody -from openpilot.common.params import Params - -logger = logging.getLogger("bodyteleop") -logging.basicConfig(level=logging.INFO) - -TELEOPDIR = f"{BASEDIR}/tools/bodyteleop" -WEBRTCD_HOST, WEBRTCD_PORT = "localhost", 5001 - - -## SSL -def create_ssl_cert(cert_path: str, key_path: str): - try: - proc = subprocess.run(f'openssl req -x509 -newkey rsa:4096 -nodes -out {cert_path} -keyout {key_path} \ - -days 365 -subj "/C=US/ST=California/O=commaai/OU=comma body"', - capture_output=True, shell=True) - proc.check_returncode() - except subprocess.CalledProcessError as ex: - raise ValueError(f"Error creating SSL certificate:\n[stdout]\n{proc.stdout.decode()}\n[stderr]\n{proc.stderr.decode()}") from ex - - -def create_ssl_context(): - cert_path = os.path.join(TELEOPDIR, "cert.pem") - key_path = os.path.join(TELEOPDIR, "key.pem") - if not os.path.exists(cert_path) or not os.path.exists(key_path): - logger.info("Creating certificate...") - create_ssl_cert(cert_path, key_path) - else: - logger.info("Certificate exists!") - ssl_context = ssl.SSLContext(protocol=ssl.PROTOCOL_TLS_SERVER) - ssl_context.load_cert_chain(cert_path, key_path) - - return ssl_context - -## ENDPOINTS -async def index(request: 'web.Request'): - with open(os.path.join(TELEOPDIR, "static", "index.html")) as f: - content = f.read() - return web.Response(content_type="text/html", text=content) - - -async def ping(request: 'web.Request'): - return web.Response(text="pong") - - -async def offer(request: 'web.Request'): - params = await request.json() - body = StreamRequestBody(params["sdp"], "driver", ["testJoystick"], ["carState"]) - body_json = json.dumps(dataclasses.asdict(body)) - - logger.info("Sending offer to webrtcd...") - webrtcd_url = f"http://{WEBRTCD_HOST}:{WEBRTCD_PORT}/stream" - async with ClientSession() as session, session.post(webrtcd_url, data=body_json) as resp: - assert resp.status == 200 - answer = await resp.json() - return web.json_response(answer) - - -def main(): - # Enable joystick debug mode - Params().put_bool("JoystickDebugMode", True, block=True) - - # App needs to be HTTPS for WebRTC to work on the browser - ssl_context = create_ssl_context() - - app = web.Application() - app.router.add_get("/", index) - app.router.add_get("/ping", ping, allow_head=True) - app.router.add_post("/offer", offer) - app.router.add_static('/static', os.path.join(TELEOPDIR, 'static')) - web.run_app(app, access_log=None, host="0.0.0.0", port=5000, ssl_context=ssl_context) - - -if __name__ == "__main__": - main() From 62b97fabf79d848264c79f1fc44857b79851896f Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Sat, 20 Jun 2026 13:52:16 -0700 Subject: [PATCH 055/151] merge selfdrive/debug/ into tools/scripts/ (#38195) * merge selfdrive/debug/ into tools/scripts/ * rm unused * single timings script * lil more * profiling is scripts quality --- conftest.py | 3 - selfdrive/car/tests/test_docs.py | 10 -- selfdrive/debug/README.md | 59 --------- selfdrive/debug/analyze-msg-size.py | 82 ------------ .../debug/check_can_parser_performance.py | 36 ------ selfdrive/debug/check_freq.py | 50 -------- selfdrive/debug/check_lag.py | 27 ---- selfdrive/debug/check_timings.py | 36 ------ selfdrive/debug/dump_car_docs.py | 18 --- selfdrive/debug/print_docs_diff.py | 120 ------------------ selfdrive/debug/touch_replay.py | 54 -------- selfdrive/test/test_onroad.py | 2 +- tools/CTF.md | 2 +- .../debug => tools/scripts}/__init__.py | 0 .../scripts/car}/can_print_changes.py | 2 +- .../scripts/car}/can_printer.py | 0 .../debug => tools/scripts/car}/can_table.py | 0 .../debug => tools/scripts}/car/clear_dtc.py | 0 .../scripts}/car/disable_ecu.py | 0 .../debug => tools/scripts}/car/ecu_addrs.py | 0 .../scripts}/car/fw_versions.py | 0 .../car/hyundai_enable_radar_points.py | 0 .../scripts/car}/max_lat_accel.py | 0 .../car}/measure_torque_time_to_max.py | 0 .../scripts/car}/read_dtc_status.py | 0 .../scripts}/car/toyota_eps_factor.py | 0 {selfdrive/debug => tools/scripts}/car/vin.py | 0 .../scripts}/car/vw_mqb_config.py | 0 .../debug => tools/scripts}/count_events.py | 0 .../debug => tools/scripts}/cpu_usage_stat.py | 2 +- .../debug => tools/scripts}/cycle_alerts.py | 0 .../debug_fw_fingerprinting_offline.py | 0 {selfdrive/debug => tools/scripts}/dump.py | 0 tools/scripts/fetch_image_from_route.py | 43 ------- .../scripts}/filter_log_message.py | 0 .../scripts}/fingerprint_from_route.py | 0 .../scripts}/fuzz_fw_fingerprint.py | 0 .../scripts}/get_fingerprint.py | 0 .../scripts}/live_cpu_and_temp.py | 0 .../debug => tools/scripts}/mem_usage.py | 0 .../debug => tools/scripts}/print_flags.py | 0 .../{ => scripts}/profiling/clpeak/.gitignore | 0 tools/{ => scripts}/profiling/clpeak/build.sh | 0 .../profiling/clpeak/no_print.patch | 0 .../profiling/clpeak/run_continuously.patch | 0 tools/{ => scripts}/profiling/ftrace.sh | 0 .../profiling/palanteer/.gitignore | 0 .../profiling/palanteer/setup.sh | 0 .../profiling/perfetto/.gitignore | 0 .../{ => scripts}/profiling/perfetto/build.sh | 0 .../{ => scripts}/profiling/perfetto/copy.sh | 0 .../profiling/perfetto/record.sh | 0 .../profiling/perfetto/server.sh | 0 .../profiling/perfetto/traces.sh | 0 .../{ => scripts}/profiling/py-spy/profile.sh | 0 .../profiling/snapdragon/.gitignore | 0 .../profiling/snapdragon/README.md | 0 .../profiling/snapdragon/setup-agnos.sh | 0 .../profiling/snapdragon/setup-profiler.sh | 0 tools/{ => scripts}/profiling/watch-irqs.sh | 0 .../debug => tools/scripts}/qlog_size.py | 0 .../scripts}/run_process_on_route.py | 0 tools/scripts/save_ubloxraw_stream.py | 47 ------- .../debug => tools/scripts}/set_car_params.py | 0 .../scripts}/test_fw_query_on_routes.py | 0 {selfdrive/debug => tools/scripts}/uiview.py | 0 tools/scripts/watch_timings.py | 102 +++++++++++++++ 67 files changed, 106 insertions(+), 589 deletions(-) delete mode 100644 selfdrive/debug/README.md delete mode 100755 selfdrive/debug/analyze-msg-size.py delete mode 100755 selfdrive/debug/check_can_parser_performance.py delete mode 100755 selfdrive/debug/check_freq.py delete mode 100755 selfdrive/debug/check_lag.py delete mode 100755 selfdrive/debug/check_timings.py delete mode 100755 selfdrive/debug/dump_car_docs.py delete mode 100755 selfdrive/debug/print_docs_diff.py delete mode 100755 selfdrive/debug/touch_replay.py rename {selfdrive/debug => tools/scripts}/__init__.py (100%) rename {selfdrive/debug => tools/scripts/car}/can_print_changes.py (98%) rename {selfdrive/debug => tools/scripts/car}/can_printer.py (100%) rename {selfdrive/debug => tools/scripts/car}/can_table.py (100%) rename {selfdrive/debug => tools/scripts}/car/clear_dtc.py (100%) rename {selfdrive/debug => tools/scripts}/car/disable_ecu.py (100%) rename {selfdrive/debug => tools/scripts}/car/ecu_addrs.py (100%) rename {selfdrive/debug => tools/scripts}/car/fw_versions.py (100%) rename {selfdrive/debug => tools/scripts}/car/hyundai_enable_radar_points.py (100%) rename {selfdrive/debug => tools/scripts/car}/max_lat_accel.py (100%) rename {selfdrive/debug => tools/scripts/car}/measure_torque_time_to_max.py (100%) rename {selfdrive/debug => tools/scripts/car}/read_dtc_status.py (100%) rename {selfdrive/debug => tools/scripts}/car/toyota_eps_factor.py (100%) rename {selfdrive/debug => tools/scripts}/car/vin.py (100%) rename {selfdrive/debug => tools/scripts}/car/vw_mqb_config.py (100%) rename {selfdrive/debug => tools/scripts}/count_events.py (100%) rename {selfdrive/debug => tools/scripts}/cpu_usage_stat.py (98%) rename {selfdrive/debug => tools/scripts}/cycle_alerts.py (100%) rename {selfdrive/debug => tools/scripts}/debug_fw_fingerprinting_offline.py (100%) rename {selfdrive/debug => tools/scripts}/dump.py (100%) delete mode 100755 tools/scripts/fetch_image_from_route.py rename {selfdrive/debug => tools/scripts}/filter_log_message.py (100%) rename {selfdrive/debug => tools/scripts}/fingerprint_from_route.py (100%) rename {selfdrive/debug => tools/scripts}/fuzz_fw_fingerprint.py (100%) rename {selfdrive/debug => tools/scripts}/get_fingerprint.py (100%) rename {selfdrive/debug => tools/scripts}/live_cpu_and_temp.py (100%) rename {selfdrive/debug => tools/scripts}/mem_usage.py (100%) rename {selfdrive/debug => tools/scripts}/print_flags.py (100%) rename tools/{ => scripts}/profiling/clpeak/.gitignore (100%) rename tools/{ => scripts}/profiling/clpeak/build.sh (100%) rename tools/{ => scripts}/profiling/clpeak/no_print.patch (100%) rename tools/{ => scripts}/profiling/clpeak/run_continuously.patch (100%) rename tools/{ => scripts}/profiling/ftrace.sh (100%) rename tools/{ => scripts}/profiling/palanteer/.gitignore (100%) rename tools/{ => scripts}/profiling/palanteer/setup.sh (100%) rename tools/{ => scripts}/profiling/perfetto/.gitignore (100%) rename tools/{ => scripts}/profiling/perfetto/build.sh (100%) rename tools/{ => scripts}/profiling/perfetto/copy.sh (100%) rename tools/{ => scripts}/profiling/perfetto/record.sh (100%) rename tools/{ => scripts}/profiling/perfetto/server.sh (100%) rename tools/{ => scripts}/profiling/perfetto/traces.sh (100%) rename tools/{ => scripts}/profiling/py-spy/profile.sh (100%) rename tools/{ => scripts}/profiling/snapdragon/.gitignore (100%) rename tools/{ => scripts}/profiling/snapdragon/README.md (100%) rename tools/{ => scripts}/profiling/snapdragon/setup-agnos.sh (100%) rename tools/{ => scripts}/profiling/snapdragon/setup-profiler.sh (100%) rename tools/{ => scripts}/profiling/watch-irqs.sh (100%) rename {selfdrive/debug => tools/scripts}/qlog_size.py (100%) rename {selfdrive/debug => tools/scripts}/run_process_on_route.py (100%) delete mode 100755 tools/scripts/save_ubloxraw_stream.py rename {selfdrive/debug => tools/scripts}/set_car_params.py (100%) rename {selfdrive/debug => tools/scripts}/test_fw_query_on_routes.py (100%) rename {selfdrive/debug => tools/scripts}/uiview.py (100%) create mode 100755 tools/scripts/watch_timings.py diff --git a/conftest.py b/conftest.py index e368b01e83..dd159129b6 100644 --- a/conftest.py +++ b/conftest.py @@ -12,9 +12,6 @@ collect_ignore = [ "selfdrive/test/process_replay/test_processes.py", "selfdrive/test/process_replay/test_regen.py", ] -collect_ignore_glob = [ - "selfdrive/debug/*.py", -] def pytest_sessionstart(session): diff --git a/selfdrive/car/tests/test_docs.py b/selfdrive/car/tests/test_docs.py index 6e13d55b29..ef6795ef80 100644 --- a/selfdrive/car/tests/test_docs.py +++ b/selfdrive/car/tests/test_docs.py @@ -1,9 +1,5 @@ -import os -from openpilot.common.basedir import BASEDIR from opendbc.car.docs import generate_cars_md, get_all_car_docs -from openpilot.selfdrive.debug.dump_car_docs import dump_car_docs -from openpilot.selfdrive.debug.print_docs_diff import print_car_docs_diff from openpilot.selfdrive.car.docs import CARS_MD_TEMPLATE @@ -14,9 +10,3 @@ class TestCarDocs: def test_generator(self): generate_cars_md(self.all_cars, CARS_MD_TEMPLATE) - - def test_docs_diff(self): - dump_path = os.path.join(BASEDIR, "selfdrive", "car", "tests", "cars_dump") - dump_car_docs(dump_path) - print_car_docs_diff(dump_path) - os.remove(dump_path) diff --git a/selfdrive/debug/README.md b/selfdrive/debug/README.md deleted file mode 100644 index 83b8a994db..0000000000 --- a/selfdrive/debug/README.md +++ /dev/null @@ -1,59 +0,0 @@ -# debug scripts - -## [can_printer.py](can_printer.py) - -``` -usage: can_printer.py [-h] [--bus BUS] [--max_msg MAX_MSG] [--addr ADDR] - -simple CAN data viewer - -optional arguments: - -h, --help show this help message and exit - --bus BUS CAN bus to print out (default: 0) - --max_msg MAX_MSG max addr (default: None) - --addr ADDR -``` - -## [dump.py](dump.py) - -``` -usage: dump.py [-h] [--pipe] [--raw] [--json] [--dump-json] [--no-print] [--addr ADDR] [--values VALUES] [socket [socket ...]] - -Dump communication sockets. See cereal/services.py for a complete list of available sockets. - -positional arguments: - socket socket names to dump. defaults to all services defined in cereal - -optional arguments: - -h, --help show this help message and exit - --pipe - --raw - --json - --dump-json - --no-print - --addr ADDR - --values VALUES values to monitor (instead of entire event) -``` - -## [vw_mqb_config.py](vw_mqb_config.py) - -``` -usage: vw_mqb_config.py [-h] [--debug] {enable,show,disable} - -Shows Volkswagen EPS software and coding info, and enables or disables Heading Control -Assist (Lane Assist). Useful for enabling HCA on cars without factory Lane Assist that want -to use openpilot integrated at the CAN gateway (J533). - -positional arguments: - {enable,show,disable} - show or modify current EPS HCA config - -optional arguments: - -h, --help show this help message and exit - --debug enable ISO-TP/UDS stack debugging output - -This tool is meant to run directly on a vehicle-installed comma three, with -the openpilot/tmux processes stopped. It should also work on a separate PC with a USB- -attached comma panda. Vehicle ignition must be on. Recommend engine not be running when -making changes. Must turn ignition off and on again for any changes to take effect. -``` diff --git a/selfdrive/debug/analyze-msg-size.py b/selfdrive/debug/analyze-msg-size.py deleted file mode 100755 index 69015a6be2..0000000000 --- a/selfdrive/debug/analyze-msg-size.py +++ /dev/null @@ -1,82 +0,0 @@ -#!/usr/bin/env python3 -import argparse -from tqdm import tqdm - -from cereal.services import SERVICE_LIST, QueueSize -from openpilot.tools.lib.logreader import LogReader - - -if __name__ == "__main__": - parser = argparse.ArgumentParser(description="Analyze message sizes from a log route") - parser.add_argument("route", nargs="?", default="98395b7c5b27882e/000000a8--f87e7cd255", - help="Log route to analyze (default: 98395b7c5b27882e/000000a8--f87e7cd255)") - args = parser.parse_args() - - lr = LogReader(args.route) - - szs = {} - for msg in tqdm(lr): - sz = len(msg.as_builder().to_bytes()) - msg_type = msg.which() - if msg_type not in szs: - szs[msg_type] = {'min': sz, 'max': sz, 'sum': sz, 'count': 1} - else: - szs[msg_type]['min'] = min(szs[msg_type]['min'], sz) - szs[msg_type]['max'] = max(szs[msg_type]['max'], sz) - szs[msg_type]['sum'] += sz - szs[msg_type]['count'] += 1 - - print() - print(f"{'Service':<36} {'Min (KB)':>12} {'Max (KB)':>12} {'Avg (KB)':>12} {'KB/min':>12} {'KB/sec':>12} {'Minutes in 10MB':>18} {'Seconds in Queue':>18}") - print("-" * 132) - def sort_key(x): - k, v = x - avg = v['sum'] / v['count'] - freq = SERVICE_LIST.get(k, None) - freq_val = freq.frequency if freq else 0.0 - kb_per_min = (avg * freq_val * 60) / 1024 if freq_val > 0 else 0.0 - return kb_per_min - total_kb_per_min = 0.0 - RINGBUFFER_SIZE_KB = 10 * 1024 # 10MB old default - for k, v in sorted(szs.items(), key=sort_key, reverse=True): - avg = v['sum'] / v['count'] - service = SERVICE_LIST.get(k, None) - freq_val = service.frequency if service else 0.0 - queue_size_kb = (service.queue_size / 1024) if service else 250 # default to SMALL - kb_per_min = (avg * freq_val * 60) / 1024 if freq_val > 0 else 0.0 - kb_per_sec = kb_per_min / 60 - minutes_in_buffer = RINGBUFFER_SIZE_KB / kb_per_min if kb_per_min > 0 else float('inf') - seconds_in_queue = (queue_size_kb / kb_per_sec) if kb_per_sec > 0 else float('inf') - total_kb_per_min += kb_per_min - min_str = f"{minutes_in_buffer:.2f}" if minutes_in_buffer != float('inf') else "inf" - sec_queue_str = f"{seconds_in_queue:.2f}" if seconds_in_queue != float('inf') else "inf" - print(f"{k:<36} {v['min']/1024:>12.2f} {v['max']/1024:>12.2f} {avg/1024:>12.2f} {kb_per_min:>12.2f} {kb_per_sec:>12.2f} {min_str:>18} {sec_queue_str:>18}") - - # Summary section - print() - print(f"Total usage: {total_kb_per_min / 1024:.2f} MB/min") - - # Calculate memory usage: old (10MB for all) vs new (from services.py) - OLD_SIZE = 10 * 1024 * 1024 # 10MB was the old default - old_total = len(SERVICE_LIST) * OLD_SIZE - - new_total = sum(s.queue_size for s in SERVICE_LIST.values()) - - # Count by queue size - size_counts = {QueueSize.BIG: 0, QueueSize.MEDIUM: 0, QueueSize.SMALL: 0} - for s in SERVICE_LIST.values(): - size_counts[s.queue_size] += 1 - - savings_pct = (1 - new_total / old_total) * 100 - - print() - print(f"{'Queue Size Comparison':<40}") - print("-" * 60) - print(f"{'Old (10MB default):':<30} {old_total / 1024 / 1024:>10.2f} MB") - print(f"{'New (from services.py):':<30} {new_total / 1024 / 1024:>10.2f} MB") - print(f"{'Savings:':<30} {savings_pct:>10.1f}%") - print() - print(f"{'Breakdown:':<30}") - print(f" BIG (10MB): {size_counts[QueueSize.BIG]:>3} services") - print(f" MEDIUM (2MB): {size_counts[QueueSize.MEDIUM]:>3} services") - print(f" SMALL (250KB): {size_counts[QueueSize.SMALL]:>3} services") diff --git a/selfdrive/debug/check_can_parser_performance.py b/selfdrive/debug/check_can_parser_performance.py deleted file mode 100755 index 20987b3cf4..0000000000 --- a/selfdrive/debug/check_can_parser_performance.py +++ /dev/null @@ -1,36 +0,0 @@ -#!/usr/bin/env python3 -import numpy as np -import time -from tqdm import tqdm - -from cereal import car -from opendbc.car.tests.routes import CarTestRoute -from openpilot.selfdrive.car.tests.test_models import TestCarModelBase -from openpilot.tools.plotjuggler.juggle import DEMO_ROUTE - -N_RUNS = 10 - - -class CarModelTestCase(TestCarModelBase): - test_route = CarTestRoute(DEMO_ROUTE, None) - - -if __name__ == '__main__': - # Get CAN messages and parsers - tm = CarModelTestCase() - tm.setUpClass() - tm.setUp() - - CC = car.CarControl.new_message() - ets = [] - for _ in tqdm(range(N_RUNS)): - start_t = time.process_time_ns() - for msg in tm.can_msgs: - for cp in tm.CI.can_parsers.values(): - if cp is not None: - cp.update_strings(msg) - ets.append((time.process_time_ns() - start_t) * 1e-6) - - print(f'{len(tm.can_msgs)} CAN packets, {N_RUNS} runs') - print(f'{np.mean(ets):.2f} mean ms, {max(ets):.2f} max ms, {min(ets):.2f} min ms, {np.std(ets):.2f} std ms') - print(f'{np.mean(ets) / len(tm.can_msgs):.4f} mean ms / CAN packet') diff --git a/selfdrive/debug/check_freq.py b/selfdrive/debug/check_freq.py deleted file mode 100755 index 1765aeb86b..0000000000 --- a/selfdrive/debug/check_freq.py +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/env python3 -import argparse -import numpy as np -import time -from collections import defaultdict, deque -from collections.abc import MutableSequence - -import cereal.messaging as messaging - - -if __name__ == "__main__": - context = messaging.Context() - poller = messaging.Poller() - - parser = argparse.ArgumentParser() - parser.add_argument("socket", type=str, nargs='*', help="socket name") - args = parser.parse_args() - - socket_names = args.socket - sockets = {} - - rcv_times: defaultdict[str, MutableSequence[float]] = defaultdict(lambda: deque(maxlen=100)) - valids: defaultdict[str, deque[bool]] = defaultdict(lambda: deque(maxlen=100)) - - t = time.monotonic() - for name in socket_names: - sock = messaging.sub_sock(name, poller=poller) - sockets[sock] = name - - prev_print = t - while True: - for socket in poller.poll(100): - msg = messaging.recv_one(socket) - if msg is None: - continue - - name = msg.which() - - t = time.monotonic() - rcv_times[name].append(msg.logMonoTime / 1e9) - valids[name].append(msg.valid) - - if t - prev_print > 1: - print() - for name in socket_names: - dts = np.diff(rcv_times[name]) - mean = np.mean(dts) - print(f"{name}: Freq {1.0 / mean:.2f} Hz, Min {np.min(dts) / mean * 100:.2f}%, Max {np.max(dts) / mean * 100:.2f}%, valid ", all(valids[name])) - - prev_print = t diff --git a/selfdrive/debug/check_lag.py b/selfdrive/debug/check_lag.py deleted file mode 100755 index 341ae79c8b..0000000000 --- a/selfdrive/debug/check_lag.py +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env python3 - -import cereal.messaging as messaging -from cereal.services import SERVICE_LIST - -TO_CHECK = ['carState'] - - -if __name__ == "__main__": - sm = messaging.SubMaster(TO_CHECK) - - prev_t: dict[str, float] = {} - - while True: - sm.update() - - for s in TO_CHECK: - if sm.updated[s]: - t = sm.logMonoTime[s] / 1e9 - - if s in prev_t: - expected = 1.0 / (SERVICE_LIST[s].frequency) - dt = t - prev_t[s] - if dt > 10 * expected: - print(t, s, dt) - - prev_t[s] = t diff --git a/selfdrive/debug/check_timings.py b/selfdrive/debug/check_timings.py deleted file mode 100755 index fc527cd81b..0000000000 --- a/selfdrive/debug/check_timings.py +++ /dev/null @@ -1,36 +0,0 @@ -#!/usr/bin/env python3 -import sys -import time -import numpy as np -import datetime -from collections.abc import MutableSequence -from collections import defaultdict - -import cereal.messaging as messaging - - -if __name__ == "__main__": - ts: defaultdict[str, MutableSequence[float]] = defaultdict(list) - socks = {s: messaging.sub_sock(s, conflate=False) for s in sys.argv[1:]} - try: - st = time.monotonic() - while True: - print() - for s, sock in socks.items(): - msgs = messaging.drain_sock(sock) - for m in msgs: - ts[s].append(m.logMonoTime / 1e6) - - if len(ts[s]) > 2: - d = np.diff(ts[s])[-100:] - print(f"{s:25} {np.mean(d):7.2f} {np.std(d):7.2f} {np.max(d):7.2f} {np.min(d):7.2f}") - time.sleep(1) - except KeyboardInterrupt: - print("\n") - print("="*5, "timing summary", "="*5) - for s, sock in socks.items(): - msgs = messaging.drain_sock(sock) - if len(ts[s]) > 2: - d = np.diff(ts[s]) - print(f"{s:25} {np.mean(d):7.2f} {np.std(d):7.2f} {np.max(d):7.2f} {np.min(d):7.2f}") - print("="*5, datetime.timedelta(seconds=time.monotonic()-st), "="*5) diff --git a/selfdrive/debug/dump_car_docs.py b/selfdrive/debug/dump_car_docs.py deleted file mode 100755 index f0e99cda24..0000000000 --- a/selfdrive/debug/dump_car_docs.py +++ /dev/null @@ -1,18 +0,0 @@ -#!/usr/bin/env python3 -import argparse -import pickle - -from opendbc.car.docs import get_all_car_docs - - -def dump_car_docs(path): - with open(path, 'wb') as f: - pickle.dump(get_all_car_docs(), f) - print(f'Dumping car info to {path}') - - -if __name__ == "__main__": - parser = argparse.ArgumentParser() - parser.add_argument("--path", required=True) - args = parser.parse_args() - dump_car_docs(args.path) diff --git a/selfdrive/debug/print_docs_diff.py b/selfdrive/debug/print_docs_diff.py deleted file mode 100755 index c7850939f0..0000000000 --- a/selfdrive/debug/print_docs_diff.py +++ /dev/null @@ -1,120 +0,0 @@ -#!/usr/bin/env python3 -import argparse -from collections import defaultdict -import difflib -import pickle - -from opendbc.car.docs import get_all_car_docs -from opendbc.car.docs_definitions import Column - -FOOTNOTE_TAG = "{}" -STAR_ICON = '' -VIDEO_ICON = '' + \ - '' -COLUMNS = "|" + "|".join([column.value for column in Column]) + "|" -COLUMN_HEADER = "|---|---|---|{}|".format("|".join([":---:"] * (len(Column) - 3))) -ARROW_SYMBOL = "➡️" - - -def load_base_car_docs(path): - with open(path, "rb") as f: - return pickle.load(f) - - -def match_cars(base_cars, new_cars): - changes = [] - additions = [] - for new in new_cars: - # Addition if no close matches or close match already used - # Change if close match and not already used - matches = difflib.get_close_matches(new.name, [b.name for b in base_cars], cutoff=0.) - if not len(matches) or matches[0] in [c[1].name for c in changes]: - additions.append(new) - else: - changes.append((new, next(car for car in base_cars if car.name == matches[0]))) - - # Removal if base car not in changes - removals = [b for b in base_cars if b.name not in [c[1].name for c in changes]] - return changes, additions, removals - - -def build_column_diff(base_car, new_car): - row_builder = [] - for column in Column: - base_column = base_car.get_column(column, STAR_ICON, VIDEO_ICON, FOOTNOTE_TAG) - new_column = new_car.get_column(column, STAR_ICON, VIDEO_ICON, FOOTNOTE_TAG) - - if base_column != new_column: - row_builder.append(f"{base_column} {ARROW_SYMBOL} {new_column}") - else: - row_builder.append(new_column) - - return format_row(row_builder) - - -def format_row(builder): - return "|" + "|".join(builder) + "|" - - -def print_car_docs_diff(path): - base_car_docs = defaultdict(list) - new_car_docs = defaultdict(list) - - for car in load_base_car_docs(path): - base_car_docs[car.car_fingerprint].append(car) - for car in get_all_car_docs(): - new_car_docs[car.car_fingerprint].append(car) - - # Add new platforms to base cars so we can detect additions and removals in one pass - base_car_docs.update({car: [] for car in new_car_docs if car not in base_car_docs}) - - changes = defaultdict(list) - for base_car_model, base_cars in base_car_docs.items(): - # Match car info changes, and get additions and removals - new_cars = new_car_docs[base_car_model] - car_changes, car_additions, car_removals = match_cars(base_cars, new_cars) - - # Removals - for car_docs in car_removals: - changes["removals"].append(format_row([car_docs.get_column(column, STAR_ICON, VIDEO_ICON, FOOTNOTE_TAG) for column in Column])) - - # Additions - for car_docs in car_additions: - changes["additions"].append(format_row([car_docs.get_column(column, STAR_ICON, VIDEO_ICON, FOOTNOTE_TAG) for column in Column])) - - for new_car, base_car in car_changes: - # Column changes - row_diff = build_column_diff(base_car, new_car) - if ARROW_SYMBOL in row_diff: - changes["column"].append(row_diff) - - # Detail sentence changes - if base_car.detail_sentence != new_car.detail_sentence: - changes["detail"].append(f"- Sentence for {base_car.name} changed!\n" + - " ```diff\n" + - f" - {base_car.detail_sentence}\n" + - f" + {new_car.detail_sentence}\n" + - " ```") - - # Print diff - if any(len(c) for c in changes.values()): - markdown_builder = ["### ⚠️ This PR makes changes to [CARS.md](../blob/master/docs/CARS.md) ⚠️"] - - for title, category in (("## 🔀 Column Changes", "column"), ("## ❌ Removed", "removals"), - ("## ➕ Added", "additions"), ("## 📖 Detail Sentence Changes", "detail")): - if len(changes[category]): - markdown_builder.append(title) - if category not in ("detail",): - markdown_builder.append(COLUMNS) - markdown_builder.append(COLUMN_HEADER) - markdown_builder.extend(changes[category]) - - print("\n".join(markdown_builder)) - - -if __name__ == "__main__": - parser = argparse.ArgumentParser() - parser.add_argument("--path", required=True) - args = parser.parse_args() - print_car_docs_diff(args.path) diff --git a/selfdrive/debug/touch_replay.py b/selfdrive/debug/touch_replay.py deleted file mode 100755 index 6e5ecbbe5b..0000000000 --- a/selfdrive/debug/touch_replay.py +++ /dev/null @@ -1,54 +0,0 @@ -#!/usr/bin/env python3 -import argparse - -import numpy as np -import matplotlib.pyplot as plt - -from openpilot.tools.lib.logreader import LogReader - -if __name__ == '__main__': - parser = argparse.ArgumentParser() - parser.add_argument('--width', default=2160, type=int) - parser.add_argument('--height', default=1080, type=int) - parser.add_argument('--route', default='rlog', type=str) - args = parser.parse_args() - - w = args.width - h = args.height - route = args.route - - fingers = [[-1, -1]] * 5 - touch_points = [] - current_slot = 0 - - lr = list(LogReader(route)) - for msg in lr: - if msg.which() == 'touch': - for event in msg.touch: - if event.type == 3 and event.code == 47: - current_slot = event.value - elif event.type == 3 and event.code == 57 and event.value == -1: - fingers[current_slot] = [-1, -1] - elif event.type == 3 and event.code == 53: - fingers[current_slot][1] = event.value - if fingers[current_slot][0] != -1: - touch_points.append(fingers[current_slot].copy()) - elif event.type == 3 and event.code == 54: - fingers[current_slot][0] = w - event.value - if fingers[current_slot][1] != -1: - touch_points.append(fingers[current_slot].copy()) - - if not touch_points: - print(f'No touch events found for {route}') - quit() - - unique_points, counts = np.unique(touch_points, axis=0, return_counts=True) - - plt.figure(figsize=(10, 3)) - plt.scatter(unique_points[:, 0], unique_points[:, 1], c=counts, s=counts * 20, edgecolors='red') - plt.colorbar() - plt.title(f'Touches for {route}') - plt.xlim(0, w) - plt.ylim(0, h) - plt.grid(True) - plt.show() diff --git a/selfdrive/test/test_onroad.py b/selfdrive/test/test_onroad.py index 8161dca130..a08912fdef 100644 --- a/selfdrive/test/test_onroad.py +++ b/selfdrive/test/test_onroad.py @@ -284,7 +284,7 @@ class TestOnroad: print("--------------- Memory Usage -------------------") print("------------------------------------------------") - from openpilot.selfdrive.debug.mem_usage import print_report + from openpilot.tools.scripts.mem_usage import print_report print_report(self.msgs['procLog'], self.msgs['deviceState']) offset = int(SERVICE_LIST['deviceState'].frequency * LOG_OFFSET) diff --git a/tools/CTF.md b/tools/CTF.md index 32891cd389..609c82ad5a 100644 --- a/tools/CTF.md +++ b/tools/CTF.md @@ -6,7 +6,7 @@ Welcome to the first part of the comma CTF! * everything you'll need to find the flags is in the openpilot repo * grep is also your friend * first, [setup](https://github.com/commaai/openpilot/tree/master/tools#setup-your-pc) your PC - * read the docs & checkout out the tools in tools/ and selfdrive/debug/ + * read the docs & checkout out the tools in tools/ * tip: once you get the replay and UI up, start by familiarizing yourself with seeking in replay getting started diff --git a/selfdrive/debug/__init__.py b/tools/scripts/__init__.py similarity index 100% rename from selfdrive/debug/__init__.py rename to tools/scripts/__init__.py diff --git a/selfdrive/debug/can_print_changes.py b/tools/scripts/car/can_print_changes.py similarity index 98% rename from selfdrive/debug/can_print_changes.py rename to tools/scripts/car/can_print_changes.py index 97d60b2b05..c2e152e1e0 100755 --- a/selfdrive/debug/can_print_changes.py +++ b/tools/scripts/car/can_print_changes.py @@ -5,7 +5,7 @@ import time from collections import defaultdict import cereal.messaging as messaging -from openpilot.selfdrive.debug.can_table import can_table +from openpilot.tools.scripts.can_table import can_table from openpilot.tools.lib.logreader import LogIterable, LogReader RED = '\033[91m' diff --git a/selfdrive/debug/can_printer.py b/tools/scripts/car/can_printer.py similarity index 100% rename from selfdrive/debug/can_printer.py rename to tools/scripts/car/can_printer.py diff --git a/selfdrive/debug/can_table.py b/tools/scripts/car/can_table.py similarity index 100% rename from selfdrive/debug/can_table.py rename to tools/scripts/car/can_table.py diff --git a/selfdrive/debug/car/clear_dtc.py b/tools/scripts/car/clear_dtc.py similarity index 100% rename from selfdrive/debug/car/clear_dtc.py rename to tools/scripts/car/clear_dtc.py diff --git a/selfdrive/debug/car/disable_ecu.py b/tools/scripts/car/disable_ecu.py similarity index 100% rename from selfdrive/debug/car/disable_ecu.py rename to tools/scripts/car/disable_ecu.py diff --git a/selfdrive/debug/car/ecu_addrs.py b/tools/scripts/car/ecu_addrs.py similarity index 100% rename from selfdrive/debug/car/ecu_addrs.py rename to tools/scripts/car/ecu_addrs.py diff --git a/selfdrive/debug/car/fw_versions.py b/tools/scripts/car/fw_versions.py similarity index 100% rename from selfdrive/debug/car/fw_versions.py rename to tools/scripts/car/fw_versions.py diff --git a/selfdrive/debug/car/hyundai_enable_radar_points.py b/tools/scripts/car/hyundai_enable_radar_points.py similarity index 100% rename from selfdrive/debug/car/hyundai_enable_radar_points.py rename to tools/scripts/car/hyundai_enable_radar_points.py diff --git a/selfdrive/debug/max_lat_accel.py b/tools/scripts/car/max_lat_accel.py similarity index 100% rename from selfdrive/debug/max_lat_accel.py rename to tools/scripts/car/max_lat_accel.py diff --git a/selfdrive/debug/measure_torque_time_to_max.py b/tools/scripts/car/measure_torque_time_to_max.py similarity index 100% rename from selfdrive/debug/measure_torque_time_to_max.py rename to tools/scripts/car/measure_torque_time_to_max.py diff --git a/selfdrive/debug/read_dtc_status.py b/tools/scripts/car/read_dtc_status.py similarity index 100% rename from selfdrive/debug/read_dtc_status.py rename to tools/scripts/car/read_dtc_status.py diff --git a/selfdrive/debug/car/toyota_eps_factor.py b/tools/scripts/car/toyota_eps_factor.py similarity index 100% rename from selfdrive/debug/car/toyota_eps_factor.py rename to tools/scripts/car/toyota_eps_factor.py diff --git a/selfdrive/debug/car/vin.py b/tools/scripts/car/vin.py similarity index 100% rename from selfdrive/debug/car/vin.py rename to tools/scripts/car/vin.py diff --git a/selfdrive/debug/car/vw_mqb_config.py b/tools/scripts/car/vw_mqb_config.py similarity index 100% rename from selfdrive/debug/car/vw_mqb_config.py rename to tools/scripts/car/vw_mqb_config.py diff --git a/selfdrive/debug/count_events.py b/tools/scripts/count_events.py similarity index 100% rename from selfdrive/debug/count_events.py rename to tools/scripts/count_events.py diff --git a/selfdrive/debug/cpu_usage_stat.py b/tools/scripts/cpu_usage_stat.py similarity index 98% rename from selfdrive/debug/cpu_usage_stat.py rename to tools/scripts/cpu_usage_stat.py index 089685103f..5b72eacc65 100755 --- a/selfdrive/debug/cpu_usage_stat.py +++ b/tools/scripts/cpu_usage_stat.py @@ -8,7 +8,7 @@ System tools like top/htop can only show current cpu usage values, so I write th Calculate minumium/maximum/accumulated_average cpu usage as long term inspections. Monitor multiple processes simuteneously. Sample usage: - root@localhost:/data/openpilot$ python selfdrive/debug/cpu_usage_stat.py pandad,ubloxd + root@localhost:/data/openpilot$ python tools/scripts/cpu_usage_stat.py pandad,ubloxd ('Add monitored proc:', './pandad') ('Add monitored proc:', 'python locationd/ubloxd.py') pandad: 1.96%, min: 1.96%, max: 1.96%, acc: 1.96% diff --git a/selfdrive/debug/cycle_alerts.py b/tools/scripts/cycle_alerts.py similarity index 100% rename from selfdrive/debug/cycle_alerts.py rename to tools/scripts/cycle_alerts.py diff --git a/selfdrive/debug/debug_fw_fingerprinting_offline.py b/tools/scripts/debug_fw_fingerprinting_offline.py similarity index 100% rename from selfdrive/debug/debug_fw_fingerprinting_offline.py rename to tools/scripts/debug_fw_fingerprinting_offline.py diff --git a/selfdrive/debug/dump.py b/tools/scripts/dump.py similarity index 100% rename from selfdrive/debug/dump.py rename to tools/scripts/dump.py diff --git a/tools/scripts/fetch_image_from_route.py b/tools/scripts/fetch_image_from_route.py deleted file mode 100755 index a053714801..0000000000 --- a/tools/scripts/fetch_image_from_route.py +++ /dev/null @@ -1,43 +0,0 @@ -#!/usr/bin/env python3 -import sys - -if len(sys.argv) < 4: - print(f"{sys.argv[0]} [front|wide|driver]") - print('example: ./fetch_image_from_route.py "02c45f73a2e5c6e9|2020-06-01--18-03-08" 3 500 driver') - exit(0) - -cameras = { - "front": "cameras", - "wide": "ecameras", - "driver": "dcameras" -} - -import requests -from PIL import Image -from openpilot.tools.lib.auth_config import get_token -from openpilot.tools.lib.framereader import FrameReader - -jwt = get_token() - -route = sys.argv[1] -segment = int(sys.argv[2]) -frame = int(sys.argv[3]) -camera = cameras[sys.argv[4]] if len(sys.argv) > 4 and sys.argv[4] in cameras else "cameras" - -url = f'https://api.commadotai.com/v1/route/{route}/files' -r = requests.get(url, headers={"Authorization": f"JWT {jwt}"}, timeout=10) -assert r.status_code == 200 -print("got api response") - -segments = r.json()[camera] -if segment >= len(segments): - raise Exception(f"segment {segment} not found, got {len(segments)} segments") - -fr = FrameReader(segments[segment]) -if frame >= fr.frame_count: - raise Exception(f"frame {frame} not found, got {fr.frame_count} frames") - -im = Image.fromarray(fr.get(frame)) -fn = f"uxxx_{route.replace('|', '_')}_{segment}_{frame}.png" -im.save(fn) -print(f"saved {fn}") diff --git a/selfdrive/debug/filter_log_message.py b/tools/scripts/filter_log_message.py similarity index 100% rename from selfdrive/debug/filter_log_message.py rename to tools/scripts/filter_log_message.py diff --git a/selfdrive/debug/fingerprint_from_route.py b/tools/scripts/fingerprint_from_route.py similarity index 100% rename from selfdrive/debug/fingerprint_from_route.py rename to tools/scripts/fingerprint_from_route.py diff --git a/selfdrive/debug/fuzz_fw_fingerprint.py b/tools/scripts/fuzz_fw_fingerprint.py similarity index 100% rename from selfdrive/debug/fuzz_fw_fingerprint.py rename to tools/scripts/fuzz_fw_fingerprint.py diff --git a/selfdrive/debug/get_fingerprint.py b/tools/scripts/get_fingerprint.py similarity index 100% rename from selfdrive/debug/get_fingerprint.py rename to tools/scripts/get_fingerprint.py diff --git a/selfdrive/debug/live_cpu_and_temp.py b/tools/scripts/live_cpu_and_temp.py similarity index 100% rename from selfdrive/debug/live_cpu_and_temp.py rename to tools/scripts/live_cpu_and_temp.py diff --git a/selfdrive/debug/mem_usage.py b/tools/scripts/mem_usage.py similarity index 100% rename from selfdrive/debug/mem_usage.py rename to tools/scripts/mem_usage.py diff --git a/selfdrive/debug/print_flags.py b/tools/scripts/print_flags.py similarity index 100% rename from selfdrive/debug/print_flags.py rename to tools/scripts/print_flags.py diff --git a/tools/profiling/clpeak/.gitignore b/tools/scripts/profiling/clpeak/.gitignore similarity index 100% rename from tools/profiling/clpeak/.gitignore rename to tools/scripts/profiling/clpeak/.gitignore diff --git a/tools/profiling/clpeak/build.sh b/tools/scripts/profiling/clpeak/build.sh similarity index 100% rename from tools/profiling/clpeak/build.sh rename to tools/scripts/profiling/clpeak/build.sh diff --git a/tools/profiling/clpeak/no_print.patch b/tools/scripts/profiling/clpeak/no_print.patch similarity index 100% rename from tools/profiling/clpeak/no_print.patch rename to tools/scripts/profiling/clpeak/no_print.patch diff --git a/tools/profiling/clpeak/run_continuously.patch b/tools/scripts/profiling/clpeak/run_continuously.patch similarity index 100% rename from tools/profiling/clpeak/run_continuously.patch rename to tools/scripts/profiling/clpeak/run_continuously.patch diff --git a/tools/profiling/ftrace.sh b/tools/scripts/profiling/ftrace.sh similarity index 100% rename from tools/profiling/ftrace.sh rename to tools/scripts/profiling/ftrace.sh diff --git a/tools/profiling/palanteer/.gitignore b/tools/scripts/profiling/palanteer/.gitignore similarity index 100% rename from tools/profiling/palanteer/.gitignore rename to tools/scripts/profiling/palanteer/.gitignore diff --git a/tools/profiling/palanteer/setup.sh b/tools/scripts/profiling/palanteer/setup.sh similarity index 100% rename from tools/profiling/palanteer/setup.sh rename to tools/scripts/profiling/palanteer/setup.sh diff --git a/tools/profiling/perfetto/.gitignore b/tools/scripts/profiling/perfetto/.gitignore similarity index 100% rename from tools/profiling/perfetto/.gitignore rename to tools/scripts/profiling/perfetto/.gitignore diff --git a/tools/profiling/perfetto/build.sh b/tools/scripts/profiling/perfetto/build.sh similarity index 100% rename from tools/profiling/perfetto/build.sh rename to tools/scripts/profiling/perfetto/build.sh diff --git a/tools/profiling/perfetto/copy.sh b/tools/scripts/profiling/perfetto/copy.sh similarity index 100% rename from tools/profiling/perfetto/copy.sh rename to tools/scripts/profiling/perfetto/copy.sh diff --git a/tools/profiling/perfetto/record.sh b/tools/scripts/profiling/perfetto/record.sh similarity index 100% rename from tools/profiling/perfetto/record.sh rename to tools/scripts/profiling/perfetto/record.sh diff --git a/tools/profiling/perfetto/server.sh b/tools/scripts/profiling/perfetto/server.sh similarity index 100% rename from tools/profiling/perfetto/server.sh rename to tools/scripts/profiling/perfetto/server.sh diff --git a/tools/profiling/perfetto/traces.sh b/tools/scripts/profiling/perfetto/traces.sh similarity index 100% rename from tools/profiling/perfetto/traces.sh rename to tools/scripts/profiling/perfetto/traces.sh diff --git a/tools/profiling/py-spy/profile.sh b/tools/scripts/profiling/py-spy/profile.sh similarity index 100% rename from tools/profiling/py-spy/profile.sh rename to tools/scripts/profiling/py-spy/profile.sh diff --git a/tools/profiling/snapdragon/.gitignore b/tools/scripts/profiling/snapdragon/.gitignore similarity index 100% rename from tools/profiling/snapdragon/.gitignore rename to tools/scripts/profiling/snapdragon/.gitignore diff --git a/tools/profiling/snapdragon/README.md b/tools/scripts/profiling/snapdragon/README.md similarity index 100% rename from tools/profiling/snapdragon/README.md rename to tools/scripts/profiling/snapdragon/README.md diff --git a/tools/profiling/snapdragon/setup-agnos.sh b/tools/scripts/profiling/snapdragon/setup-agnos.sh similarity index 100% rename from tools/profiling/snapdragon/setup-agnos.sh rename to tools/scripts/profiling/snapdragon/setup-agnos.sh diff --git a/tools/profiling/snapdragon/setup-profiler.sh b/tools/scripts/profiling/snapdragon/setup-profiler.sh similarity index 100% rename from tools/profiling/snapdragon/setup-profiler.sh rename to tools/scripts/profiling/snapdragon/setup-profiler.sh diff --git a/tools/profiling/watch-irqs.sh b/tools/scripts/profiling/watch-irqs.sh similarity index 100% rename from tools/profiling/watch-irqs.sh rename to tools/scripts/profiling/watch-irqs.sh diff --git a/selfdrive/debug/qlog_size.py b/tools/scripts/qlog_size.py similarity index 100% rename from selfdrive/debug/qlog_size.py rename to tools/scripts/qlog_size.py diff --git a/selfdrive/debug/run_process_on_route.py b/tools/scripts/run_process_on_route.py similarity index 100% rename from selfdrive/debug/run_process_on_route.py rename to tools/scripts/run_process_on_route.py diff --git a/tools/scripts/save_ubloxraw_stream.py b/tools/scripts/save_ubloxraw_stream.py deleted file mode 100755 index b5354a7831..0000000000 --- a/tools/scripts/save_ubloxraw_stream.py +++ /dev/null @@ -1,47 +0,0 @@ -#!/usr/bin/env python3 -import argparse -import os -import sys -from openpilot.common.basedir import BASEDIR -from openpilot.tools.lib.logreader import LogReader - -os.environ['BASEDIR'] = BASEDIR - - -def get_arg_parser(): - parser = argparse.ArgumentParser( - description="Unlogging and save to file", - formatter_class=argparse.ArgumentDefaultsHelpFormatter) - - parser.add_argument("route", type=(lambda x: x.replace("#", "|")), nargs="?", - help="The route whose messages will be published.") - parser.add_argument("--out_path", nargs='?', default='/data/ubloxRaw.stream', - help="Output pickle file path") - return parser - - -def main(): - args = get_arg_parser().parse_args(sys.argv[1:]) - - lr = LogReader(args.route) - - with open(args.out_path, 'wb') as f: - try: - done = False - i = 0 - while not done: - msg = next(lr) - if not msg: - break - smsg = msg.as_builder() - typ = smsg.which() - if typ == 'ubloxRaw': - f.write(smsg.to_bytes()) - i += 1 - except StopIteration: - print('All done') - print(f'Writed {i} msgs') - - -if __name__ == "__main__": - main() diff --git a/selfdrive/debug/set_car_params.py b/tools/scripts/set_car_params.py similarity index 100% rename from selfdrive/debug/set_car_params.py rename to tools/scripts/set_car_params.py diff --git a/selfdrive/debug/test_fw_query_on_routes.py b/tools/scripts/test_fw_query_on_routes.py similarity index 100% rename from selfdrive/debug/test_fw_query_on_routes.py rename to tools/scripts/test_fw_query_on_routes.py diff --git a/selfdrive/debug/uiview.py b/tools/scripts/uiview.py similarity index 100% rename from selfdrive/debug/uiview.py rename to tools/scripts/uiview.py diff --git a/tools/scripts/watch_timings.py b/tools/scripts/watch_timings.py new file mode 100755 index 0000000000..874720dd22 --- /dev/null +++ b/tools/scripts/watch_timings.py @@ -0,0 +1,102 @@ +#!/usr/bin/env python3 +import argparse +import datetime +import time +from collections import deque +from dataclasses import dataclass, field + +import numpy as np + +import cereal.messaging as messaging +from cereal.services import SERVICE_LIST + + +@dataclass +class ServiceTiming: + times: list[float] = field(default_factory=list) + window: deque[float] = field(default_factory=lambda: deque(maxlen=100)) + valids: deque[bool] = field(default_factory=lambda: deque(maxlen=100)) + lag_events: list[tuple[float, float]] = field(default_factory=list) + + def add(self, mono_time: float, valid: bool, expected_interval: float | None, lag_threshold: float) -> None: + if self.times: + dt = mono_time - self.times[-1] + self.window.append(dt) + if expected_interval is not None and dt > lag_threshold * expected_interval: + self.lag_events.append((mono_time, dt)) + + self.times.append(mono_time) + self.valids.append(valid) + + def intervals(self, latest_only: bool) -> np.ndarray: + if latest_only: + return np.array(self.window) + return np.diff(self.times) + + +def format_row(name: str, timing: ServiceTiming, latest_only: bool) -> str: + dts = timing.intervals(latest_only) + if len(dts) == 0: + return f"{name:25} waiting for messages" + + mean = np.mean(dts) + hz = 1.0 / mean if mean > 0 else 0.0 + valid = all(timing.valids) if timing.valids else False + return f"{name:25} {hz:8.2f}Hz {mean * 1e3:8.2f}ms {np.std(dts) * 1e3:8.2f}ms {np.max(dts) * 1e3:8.2f}ms {np.min(dts) * 1e3:8.2f}ms valid={valid}" + + +def print_lag_events(name: str, timing: ServiceTiming, printed_lags: dict[str, int]) -> None: + start = printed_lags.get(name, 0) + for mono_time, dt in timing.lag_events[start:]: + print(f"{mono_time:.3f} {name} lag {dt:.3f}s", flush=True) + printed_lags[name] = len(timing.lag_events) + + +def monitor_services(socket_names: list[str], print_interval: float, lag_threshold: float, lag_only: bool) -> None: + sockets = {name: messaging.sub_sock(name, conflate=False) for name in socket_names} + timings = {name: ServiceTiming() for name in socket_names} + printed_lags: dict[str, int] = {} + + start_time = time.monotonic() + last_print = start_time + + try: + while True: + for name, sock in sockets.items(): + for msg in messaging.drain_sock(sock): + expected_interval = 1.0 / SERVICE_LIST[name].frequency if name in SERVICE_LIST else None + timings[name].add(msg.logMonoTime / 1e9, msg.valid, expected_interval, lag_threshold) + + now = time.monotonic() + if now - last_print < print_interval: + time.sleep(0.01) + continue + + if not lag_only: + print(flush=True) + print(f"{'service':25} {'freq':>10} {'mean':>10} {'std':>10} {'max':>10} {'min':>10} valid", flush=True) + for name in socket_names: + print(format_row(name, timings[name], latest_only=True), flush=True) + + for name in socket_names: + print_lag_events(name, timings[name], printed_lags) + + last_print = now + except KeyboardInterrupt: + print("\n", flush=True) + print("=" * 5, "timing summary", "=" * 5, flush=True) + print(f"{'service':25} {'freq':>10} {'mean':>10} {'std':>10} {'max':>10} {'min':>10} valid", flush=True) + for name in socket_names: + print(format_row(name, timings[name], latest_only=False), flush=True) + print("=" * 5, datetime.timedelta(seconds=time.monotonic() - start_time), "=" * 5, flush=True) + + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description="Check live service timing, frequency, validity, and lag") + parser.add_argument("socket", nargs="*", default=["carState"], help="service/socket name") + parser.add_argument("--lag-threshold", type=float, default=10.0, help="report intervals above this multiple of the expected service interval") + parser.add_argument("--lag-only", action="store_true", help="only print lag events") + parser.add_argument("--print-interval", type=float, default=1.0, help="seconds between table updates") + args = parser.parse_args() + + monitor_services(args.socket, args.print_interval, args.lag_threshold, args.lag_only) From b2a708490609efdcd6a3d7e4214eb030b844e48e Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Sat, 20 Jun 2026 13:54:47 -0700 Subject: [PATCH 056/151] move webcam to system/camerad/ (#38196) * move webcam to system/camerad/ * lil more --- {tools => system/camerad}/webcam/README.md | 9 +-------- {tools => system/camerad}/webcam/camera.py | 0 {tools => system/camerad}/webcam/camerad.py | 2 +- system/manager/process_config.py | 2 +- 4 files changed, 3 insertions(+), 10 deletions(-) rename {tools => system/camerad}/webcam/README.md (63%) rename {tools => system/camerad}/webcam/camera.py (100%) rename {tools => system/camerad}/webcam/camerad.py (97%) diff --git a/tools/webcam/README.md b/system/camerad/webcam/README.md similarity index 63% rename from tools/webcam/README.md rename to system/camerad/webcam/README.md index 6abbc47935..2c0ce6a8af 100644 --- a/tools/webcam/README.md +++ b/system/camerad/webcam/README.md @@ -1,13 +1,5 @@ # Run openpilot with webcam on PC -What's needed: -- Ubuntu 24.04 ([WSL2 is not supported](https://github.com/commaai/openpilot/issues/34216)) or macOS -- GPU (recommended) -- One USB webcam, at least 720p and 78 degrees FOV (e.g. Logitech C920/C615, NexiGo N60) -- [Car harness](https://comma.ai/shop/products/comma-car-harness) -- [panda](https://comma.ai/shop/panda) -- USB-A to USB-A cable to connect panda to your computer - ## Setup openpilot - Follow [this readme](../README.md) to install and build the requirements @@ -16,6 +8,7 @@ What's needed: - Connect your computer to panda ## GO + ``` USE_WEBCAM=1 system/manager/manager.py ``` diff --git a/tools/webcam/camera.py b/system/camerad/webcam/camera.py similarity index 100% rename from tools/webcam/camera.py rename to system/camerad/webcam/camera.py diff --git a/tools/webcam/camerad.py b/system/camerad/webcam/camerad.py similarity index 97% rename from tools/webcam/camerad.py rename to system/camerad/webcam/camerad.py index f1e70d948a..401eec106f 100755 --- a/tools/webcam/camerad.py +++ b/system/camerad/webcam/camerad.py @@ -7,7 +7,7 @@ from collections import namedtuple from msgq.visionipc import VisionIpcServer, VisionStreamType from cereal import messaging -from openpilot.tools.webcam.camera import Camera +from openpilot.system.camerad.webcam.camera import Camera from openpilot.common.realtime import Ratekeeper ROAD_CAM = os.getenv("ROAD_CAM", "0") diff --git a/system/manager/process_config.py b/system/manager/process_config.py index 796e69eef6..a442e4f860 100644 --- a/system/manager/process_config.py +++ b/system/manager/process_config.py @@ -79,7 +79,7 @@ procs = [ PythonProcess("logmessaged", "system.logmessaged", always_run), NativeProcess("camerad", "system/camerad", ["./camerad"], or_(driverview, livestream), enabled=not WEBCAM), - PythonProcess("webcamerad", "tools.webcam.camerad", driverview, enabled=WEBCAM), + PythonProcess("webcamerad", "system.camerad.webcam.camerad", driverview, enabled=WEBCAM), PythonProcess("proclogd", "system.proclogd", only_onroad, enabled=platform.system() != "Darwin"), PythonProcess("journald", "system.journald", only_onroad, platform.system() != "Darwin"), PythonProcess("micd", "system.micd", iscar), From f48e99b33537c823e97a2da588ec441c2d5f3a78 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Sat, 20 Jun 2026 14:19:25 -0700 Subject: [PATCH 057/151] updated: remove (never used) casync support (#38198) --- pyproject.toml | 2 +- system/hardware/tici/agnos.py | 52 +--- .../tici/tests/compare_casync_manifest.py | 73 ----- system/updated/casync/casync.py | 246 ---------------- system/updated/casync/common.py | 61 ---- system/updated/casync/tar.py | 39 --- system/updated/casync/tests/test_casync.py | 264 ------------------ 7 files changed, 2 insertions(+), 735 deletions(-) delete mode 100755 system/hardware/tici/tests/compare_casync_manifest.py delete mode 100755 system/updated/casync/casync.py delete mode 100644 system/updated/casync/common.py delete mode 100644 system/updated/casync/tar.py delete mode 100644 system/updated/casync/tests/test_casync.py diff --git a/pyproject.toml b/pyproject.toml index 2120e6a430..51844ef93c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -68,7 +68,7 @@ dependencies = [ # these should be removed "psutil", - "pycryptodome", # used in updated/casync, panda, body, and a test + "pycryptodome", # used in panda, body, and a test "setproctitle", # logreader diff --git a/system/hardware/tici/agnos.py b/system/hardware/tici/agnos.py index f5261953d5..c5ca7efb4a 100755 --- a/system/hardware/tici/agnos.py +++ b/system/hardware/tici/agnos.py @@ -10,10 +10,7 @@ from collections.abc import Generator import requests -import openpilot.system.updated.casync.casync as casync - SPARSE_CHUNK_FMT = struct.Struct('H2xI4x') -CAIBX_URL = "https://commadist.azureedge.net/agnosupdate/" AGNOS_MANIFEST_FILE = "system/hardware/tici/agnos.json" @@ -187,50 +184,6 @@ def extract_compressed_image(target_slot_number: int, partition: dict, cloudlog) os.sync() -def extract_casync_image(target_slot_number: int, partition: dict, cloudlog): - path = get_partition_path(target_slot_number, partition) - seed_path = path[:-1] + ('b' if path[-1] == 'a' else 'a') - - target = casync.parse_caibx(partition['casync_caibx']) - - sources: list[tuple[str, casync.ChunkReader, casync.ChunkDict]] = [] - - # First source is the current partition. - try: - raw_hash = get_raw_hash(seed_path, partition['size']) - caibx_url = f"{CAIBX_URL}{partition['name']}-{raw_hash}.caibx" - - try: - cloudlog.info(f"casync fetching {caibx_url}") - sources += [('seed', casync.FileChunkReader(seed_path), casync.build_chunk_dict(casync.parse_caibx(caibx_url)))] - except requests.RequestException: - cloudlog.error(f"casync failed to load {caibx_url}") - except Exception: - cloudlog.exception("casync failed to hash seed partition") - - # Second source is the target partition, this allows for resuming - sources += [('target', casync.FileChunkReader(path), casync.build_chunk_dict(target))] - - # Finally we add the remote source to download any missing chunks - sources += [('remote', casync.RemoteChunkReader(partition['casync_store']), casync.build_chunk_dict(target))] - - last_p = 0 - - def progress(cur): - nonlocal last_p - p = int(cur / partition['size'] * 100) - if p != last_p: - last_p = p - print(f"Installing {partition['name']}: {p}", flush=True) - - stats = casync.extract(target, sources, path, progress) - cloudlog.error(f'casync done {json.dumps(stats)}') - - os.sync() - if not verify_partition(target_slot_number, partition, force_full_check=True): - raise Exception(f"Raw hash mismatch '{partition['hash_raw'].lower()}'") - - def flash_partition(target_slot_number: int, partition: dict, cloudlog, standalone=False): cloudlog.info(f"Downloading and writing {partition['name']}") @@ -245,10 +198,7 @@ def flash_partition(target_slot_number: int, partition: dict, cloudlog, standalo path = get_partition_path(target_slot_number, partition) - if ('casync_caibx' in partition) and not standalone: - extract_casync_image(target_slot_number, partition, cloudlog) - else: - extract_compressed_image(target_slot_number, partition, cloudlog) + extract_compressed_image(target_slot_number, partition, cloudlog) # Write hash after successful flash if not full_check: diff --git a/system/hardware/tici/tests/compare_casync_manifest.py b/system/hardware/tici/tests/compare_casync_manifest.py deleted file mode 100755 index 7de66d91d0..0000000000 --- a/system/hardware/tici/tests/compare_casync_manifest.py +++ /dev/null @@ -1,73 +0,0 @@ -#!/usr/bin/env python3 -import argparse -import collections -import multiprocessing -import os - -import requests -from tqdm import tqdm - -import openpilot.system.hardware.tici.casync as casync - - -def get_chunk_download_size(chunk): - sha = chunk.sha.hex() - path = os.path.join(remote_url, sha[:4], sha + ".cacnk") - if os.path.isfile(path): - return os.path.getsize(path) - else: - r = requests.head(path, timeout=10) - r.raise_for_status() - return int(r.headers['content-length']) - - -if __name__ == "__main__": - - parser = argparse.ArgumentParser(description='Compute overlap between two casync manifests') - parser.add_argument('frm') - parser.add_argument('to') - args = parser.parse_args() - - frm = casync.parse_caibx(args.frm) - to = casync.parse_caibx(args.to) - remote_url = args.to.replace('.caibx', '') - - most_common = collections.Counter(t.sha for t in to).most_common(1)[0][0] - - frm_dict = casync.build_chunk_dict(frm) - - # Get content-length for each chunk - with multiprocessing.Pool() as pool: - szs = list(tqdm(pool.imap(get_chunk_download_size, to), total=len(to))) - chunk_sizes = {t.sha: sz for (t, sz) in zip(to, szs, strict=True)} - - sources: dict[str, list[int]] = { - 'seed': [], - 'remote_uncompressed': [], - 'remote_compressed': [], - } - - for chunk in to: - # Assume most common chunk is the zero chunk - if chunk.sha == most_common: - continue - - if chunk.sha in frm_dict: - sources['seed'].append(chunk.length) - else: - sources['remote_uncompressed'].append(chunk.length) - sources['remote_compressed'].append(chunk_sizes[chunk.sha]) - - print() - print("Update statistics (excluding zeros)") - print() - print("Download only with no seed:") - print(f" Remote (uncompressed)\t\t{sum(sources['seed'] + sources['remote_uncompressed']) / 1000 / 1000:.2f} MB\tn = {len(to)}") - print(f" Remote (compressed download)\t{sum(chunk_sizes.values()) / 1000 / 1000:.2f} MB\tn = {len(to)}") - print() - print("Upgrade with seed partition:") - print(f" Seed (uncompressed)\t\t{sum(sources['seed']) / 1000 / 1000:.2f} MB\t\t\t\tn = {len(sources['seed'])}") - sz, n = sum(sources['remote_uncompressed']), len(sources['remote_uncompressed']) - print(f" Remote (uncompressed)\t\t{sz / 1000 / 1000:.2f} MB\t(avg {sz / 1000 / 1000 / n:4f} MB)\tn = {n}") - sz, n = sum(sources['remote_compressed']), len(sources['remote_compressed']) - print(f" Remote (compressed download)\t{sz / 1000 / 1000:.2f} MB\t(avg {sz / 1000 / 1000 / n:4f} MB)\tn = {n}") diff --git a/system/updated/casync/casync.py b/system/updated/casync/casync.py deleted file mode 100755 index 2bd46a1ffb..0000000000 --- a/system/updated/casync/casync.py +++ /dev/null @@ -1,246 +0,0 @@ -#!/usr/bin/env python3 -import io -import lzma -import os -import pathlib -import struct -import sys -import time -from abc import ABC, abstractmethod -from collections import defaultdict, namedtuple -from collections.abc import Callable -from typing import IO - -import requests -from Crypto.Hash import SHA512 -from openpilot.system.updated.casync import tar -from openpilot.system.updated.casync.common import create_casync_tar_package - -CA_FORMAT_INDEX = 0x96824d9c7b129ff9 -CA_FORMAT_TABLE = 0xe75b9e112f17417d -CA_FORMAT_TABLE_TAIL_MARKER = 0xe75b9e112f17417 -FLAGS = 0xb000000000000000 - -CA_HEADER_LEN = 48 -CA_TABLE_HEADER_LEN = 16 -CA_TABLE_ENTRY_LEN = 40 -CA_TABLE_MIN_LEN = CA_TABLE_HEADER_LEN + CA_TABLE_ENTRY_LEN - -CHUNK_DOWNLOAD_TIMEOUT = 60 -CHUNK_DOWNLOAD_RETRIES = 3 - -CAIBX_DOWNLOAD_TIMEOUT = 120 - -Chunk = namedtuple('Chunk', ['sha', 'offset', 'length']) -ChunkDict = dict[bytes, Chunk] - - -class ChunkReader(ABC): - @abstractmethod - def read(self, chunk: Chunk) -> bytes: - ... - - -class BinaryChunkReader(ChunkReader): - """Reads chunks from a local file""" - def __init__(self, file_like: IO[bytes]) -> None: - super().__init__() - self.f = file_like - - def read(self, chunk: Chunk) -> bytes: - self.f.seek(chunk.offset) - return self.f.read(chunk.length) - - -class FileChunkReader(BinaryChunkReader): - def __init__(self, path: str) -> None: - super().__init__(open(path, 'rb')) - - def __del__(self): - self.f.close() - - -class RemoteChunkReader(ChunkReader): - """Reads lzma compressed chunks from a remote store""" - - def __init__(self, url: str) -> None: - super().__init__() - self.url = url - self.session = requests.Session() - - def read(self, chunk: Chunk) -> bytes: - sha_hex = chunk.sha.hex() - url = os.path.join(self.url, sha_hex[:4], sha_hex + ".cacnk") - - if os.path.isfile(url): - with open(url, 'rb') as f: - contents = f.read() - else: - for i in range(CHUNK_DOWNLOAD_RETRIES): - try: - resp = self.session.get(url, timeout=CHUNK_DOWNLOAD_TIMEOUT) - break - except Exception: - if i == CHUNK_DOWNLOAD_RETRIES - 1: - raise - time.sleep(CHUNK_DOWNLOAD_TIMEOUT) - - resp.raise_for_status() - contents = resp.content - - decompressor = lzma.LZMADecompressor(format=lzma.FORMAT_AUTO) - return decompressor.decompress(contents) - - -class DirectoryTarChunkReader(BinaryChunkReader): - """creates a tar archive of a directory and reads chunks from it""" - - def __init__(self, path: str, cache_file: str) -> None: - create_casync_tar_package(pathlib.Path(path), pathlib.Path(cache_file)) - - self.f = open(cache_file, "rb") - super().__init__(self.f) - - def __del__(self): - self.f.close() - os.unlink(self.f.name) - - -def parse_caibx(caibx_path: str) -> list[Chunk]: - """Parses the chunks from a caibx file. Can handle both local and remote files. - Returns a list of chunks with hash, offset and length""" - caibx: io.BufferedIOBase - if os.path.isfile(caibx_path): - caibx = open(caibx_path, 'rb') - else: - resp = requests.get(caibx_path, timeout=CAIBX_DOWNLOAD_TIMEOUT) - resp.raise_for_status() - caibx = io.BytesIO(resp.content) - - caibx.seek(0, os.SEEK_END) - caibx_len = caibx.tell() - caibx.seek(0, os.SEEK_SET) - - # Parse header - length, magic, flags, min_size, _, max_size = struct.unpack("= min_size - - chunks.append(Chunk(sha, offset, length)) - offset = new_offset - - caibx.close() - return chunks - - -def build_chunk_dict(chunks: list[Chunk]) -> ChunkDict: - """Turn a list of chunks into a dict for faster lookups based on hash. - Keep first chunk since it's more likely to be already downloaded.""" - r = {} - for c in chunks: - if c.sha not in r: - r[c.sha] = c - return r - - -def extract(target: list[Chunk], - sources: list[tuple[str, ChunkReader, ChunkDict]], - out_path: str, - progress: Callable[[int], None] | None = None): - stats: dict[str, int] = defaultdict(int) - - mode = 'rb+' if os.path.exists(out_path) else 'wb' - with open(out_path, mode) as out: - for cur_chunk in target: - - # Find source for desired chunk - for name, chunk_reader, store_chunks in sources: - if cur_chunk.sha in store_chunks: - bts = chunk_reader.read(store_chunks[cur_chunk.sha]) - - # Check length - if len(bts) != cur_chunk.length: - continue - - # Check hash - if SHA512.new(bts, truncate="256").digest() != cur_chunk.sha: - continue - - # Write to output - out.seek(cur_chunk.offset) - out.write(bts) - - stats[name] += cur_chunk.length - - if progress is not None: - progress(sum(stats.values())) - - break - else: - raise RuntimeError("Desired chunk not found in provided stores") - - return stats - - -def extract_directory(target: list[Chunk], - sources: list[tuple[str, ChunkReader, ChunkDict]], - out_path: str, - tmp_file: str, - progress: Callable[[int], None] | None = None): - """extract a directory stored as a casync tar archive""" - - stats = extract(target, sources, tmp_file, progress) - - with open(tmp_file, "rb") as f: - tar.extract_tar_archive(f, pathlib.Path(out_path)) - - return stats - - -def print_stats(stats: dict[str, int]): - total_bytes = sum(stats.values()) - print(f"Total size: {total_bytes / 1024 / 1024:.2f} MB") - for name, total in stats.items(): - print(f" {name}: {total / 1024 / 1024:.2f} MB ({total / total_bytes * 100:.1f}%)") - - -def extract_simple(caibx_path, out_path, store_path): - # (name, callback, chunks) - target = parse_caibx(caibx_path) - sources = [ - # (store_path, RemoteChunkReader(store_path), build_chunk_dict(target)), - (store_path, FileChunkReader(store_path), build_chunk_dict(target)), - ] - - return extract(target, sources, out_path) - - -if __name__ == "__main__": - caibx = sys.argv[1] - out = sys.argv[2] - store = sys.argv[3] - - stats = extract_simple(caibx, out, store) - print_stats(stats) diff --git a/system/updated/casync/common.py b/system/updated/casync/common.py deleted file mode 100644 index 6979f5cb06..0000000000 --- a/system/updated/casync/common.py +++ /dev/null @@ -1,61 +0,0 @@ -import dataclasses -import json -import pathlib -import subprocess - -from openpilot.system.version import BUILD_METADATA_FILENAME, BuildMetadata -from openpilot.system.updated.casync import tar - - -CASYNC_ARGS = ["--with=symlinks", "--with=permissions", "--compression=xz", "--chunk-size=16M"] -CASYNC_FILES = [BUILD_METADATA_FILENAME] - - -def run(cmd): - return subprocess.check_output(cmd) - - -def get_exclude_set(path) -> set[str]: - exclude_set = set(CASYNC_FILES) - - for file in path.rglob("*"): - if file.is_file() or file.is_symlink(): - - while file.resolve() != path.resolve(): - exclude_set.add(str(file.relative_to(path))) - - file = file.parent - - return exclude_set - - -def create_build_metadata_file(path: pathlib.Path, build_metadata: BuildMetadata): - with open(path / BUILD_METADATA_FILENAME, "w") as f: - build_metadata_dict = dataclasses.asdict(build_metadata) - build_metadata_dict["openpilot"].pop("is_dirty") # this is determined at runtime - build_metadata_dict.pop("channel") # channel is unrelated to the build itself - f.write(json.dumps(build_metadata_dict)) - - -def is_not_git(path: pathlib.Path) -> bool: - return ".git" not in path.parts - - -def create_casync_tar_package(target_dir: pathlib.Path, output_path: pathlib.Path): - tar.create_tar_archive(output_path, target_dir, is_not_git) - - -def create_casync_from_file(file: pathlib.Path, output_dir: pathlib.Path, caibx_name: str): - caibx_file = output_dir / f"{caibx_name}.caibx" - run(["casync", "make", *CASYNC_ARGS, caibx_file, str(file)]) - - return caibx_file - - -def create_casync_release(target_dir: pathlib.Path, output_dir: pathlib.Path, caibx_name: str): - tar_file = output_dir / f"{caibx_name}.tar" - create_casync_tar_package(target_dir, tar_file) - caibx_file = create_casync_from_file(tar_file, output_dir, caibx_name) - tar_file.unlink() - digest = run(["casync", "digest", *CASYNC_ARGS, target_dir]).decode("utf-8").strip() - return digest, caibx_file diff --git a/system/updated/casync/tar.py b/system/updated/casync/tar.py deleted file mode 100644 index a5a8238bba..0000000000 --- a/system/updated/casync/tar.py +++ /dev/null @@ -1,39 +0,0 @@ -import pathlib -import tarfile -from typing import IO -from collections.abc import Callable - - -def include_default(_) -> bool: - return True - - -def create_tar_archive(filename: pathlib.Path, directory: pathlib.Path, include: Callable[[pathlib.Path], bool] = include_default): - """Creates a tar archive of a directory""" - - with tarfile.open(filename, 'w') as tar: - for file in sorted(directory.rglob("*"), key=lambda f: f.stat().st_size if f.is_file() else 0, reverse=True): - if not include(file): - continue - relative_path = str(file.relative_to(directory)) - if file.is_symlink(): - info = tarfile.TarInfo(relative_path) - info.type = tarfile.SYMTYPE - info.linkpath = str(file.readlink()) - tar.addfile(info) - - elif file.is_file(): - info = tarfile.TarInfo(relative_path) - info.size = file.stat().st_size - info.type = tarfile.REGTYPE - info.mode = file.stat().st_mode - with file.open('rb') as f: - tar.addfile(info, f) - - -def extract_tar_archive(fh: IO[bytes], directory: pathlib.Path): - """Extracts a tar archive to a directory""" - - tar = tarfile.open(fileobj=fh, mode='r') - tar.extractall(str(directory), filter=lambda info, path: info) - tar.close() diff --git a/system/updated/casync/tests/test_casync.py b/system/updated/casync/tests/test_casync.py deleted file mode 100644 index bc171e7432..0000000000 --- a/system/updated/casync/tests/test_casync.py +++ /dev/null @@ -1,264 +0,0 @@ -import pytest -import os -import pathlib -import tempfile -import subprocess - -from openpilot.system.updated.casync import casync -from openpilot.system.updated.casync import tar - -# dd if=/dev/zero of=/tmp/img.raw bs=1M count=2 -# sudo losetup -f /tmp/img.raw -# losetup -a | grep img.raw -LOOPBACK = os.environ.get('LOOPBACK', None) - - -@pytest.mark.skip("not used yet") -class TestCasync: - @classmethod - def setup_class(cls): - cls.tmpdir = tempfile.TemporaryDirectory() - - # Build example contents - chunk_a = [i % 256 for i in range(1024)] * 512 - chunk_b = [(256 - i) % 256 for i in range(1024)] * 512 - zeroes = [0] * (1024 * 128) - contents = chunk_a + chunk_b + zeroes + chunk_a - - cls.contents = bytes(contents) - - # Write to file - cls.orig_fn = os.path.join(cls.tmpdir.name, 'orig.bin') - with open(cls.orig_fn, 'wb') as f: - f.write(cls.contents) - - # Create casync files - cls.manifest_fn = os.path.join(cls.tmpdir.name, 'orig.caibx') - cls.store_fn = os.path.join(cls.tmpdir.name, 'store') - subprocess.check_output(["casync", "make", "--compression=xz", "--store", cls.store_fn, cls.manifest_fn, cls.orig_fn]) - - target = casync.parse_caibx(cls.manifest_fn) - hashes = [c.sha.hex() for c in target] - - # Ensure we have chunk reuse - assert len(hashes) > len(set(hashes)) - - def setup_method(self): - # Clear target_lo - if LOOPBACK is not None: - self.target_lo = LOOPBACK - with open(self.target_lo, 'wb') as f: - f.write(b"0" * len(self.contents)) - - self.target_fn = os.path.join(self.tmpdir.name, next(tempfile._get_candidate_names())) - self.seed_fn = os.path.join(self.tmpdir.name, next(tempfile._get_candidate_names())) - - def teardown_method(self): - for fn in [self.target_fn, self.seed_fn]: - try: - os.unlink(fn) - except FileNotFoundError: - pass - - def test_simple_extract(self): - target = casync.parse_caibx(self.manifest_fn) - - sources = [('remote', casync.RemoteChunkReader(self.store_fn), casync.build_chunk_dict(target))] - stats = casync.extract(target, sources, self.target_fn) - - with open(self.target_fn, 'rb') as target_f: - assert target_f.read() == self.contents - - assert stats['remote'] == len(self.contents) - - def test_seed(self): - target = casync.parse_caibx(self.manifest_fn) - - # Populate seed with half of the target contents - with open(self.seed_fn, 'wb') as seed_f: - seed_f.write(self.contents[:len(self.contents) // 2]) - - sources = [('seed', casync.FileChunkReader(self.seed_fn), casync.build_chunk_dict(target))] - sources += [('remote', casync.RemoteChunkReader(self.store_fn), casync.build_chunk_dict(target))] - stats = casync.extract(target, sources, self.target_fn) - - with open(self.target_fn, 'rb') as target_f: - assert target_f.read() == self.contents - - assert stats['seed'] > 0 - assert stats['remote'] < len(self.contents) - - def test_already_done(self): - """Test that an already flashed target doesn't download any chunks""" - target = casync.parse_caibx(self.manifest_fn) - - with open(self.target_fn, 'wb') as f: - f.write(self.contents) - - sources = [('target', casync.FileChunkReader(self.target_fn), casync.build_chunk_dict(target))] - sources += [('remote', casync.RemoteChunkReader(self.store_fn), casync.build_chunk_dict(target))] - - stats = casync.extract(target, sources, self.target_fn) - - with open(self.target_fn, 'rb') as f: - assert f.read() == self.contents - - assert stats['target'] == len(self.contents) - - def test_chunk_reuse(self): - """Test that chunks that are reused are only downloaded once""" - target = casync.parse_caibx(self.manifest_fn) - - # Ensure target exists - with open(self.target_fn, 'wb'): - pass - - sources = [('target', casync.FileChunkReader(self.target_fn), casync.build_chunk_dict(target))] - sources += [('remote', casync.RemoteChunkReader(self.store_fn), casync.build_chunk_dict(target))] - - stats = casync.extract(target, sources, self.target_fn) - - with open(self.target_fn, 'rb') as f: - assert f.read() == self.contents - - assert stats['remote'] < len(self.contents) - - @pytest.mark.skipif(not LOOPBACK, reason="requires loopback device") - def test_lo_simple_extract(self): - target = casync.parse_caibx(self.manifest_fn) - sources = [('remote', casync.RemoteChunkReader(self.store_fn), casync.build_chunk_dict(target))] - - stats = casync.extract(target, sources, self.target_lo) - - with open(self.target_lo, 'rb') as target_f: - assert target_f.read(len(self.contents)) == self.contents - - assert stats['remote'] == len(self.contents) - - @pytest.mark.skipif(not LOOPBACK, reason="requires loopback device") - def test_lo_chunk_reuse(self): - """Test that chunks that are reused are only downloaded once""" - target = casync.parse_caibx(self.manifest_fn) - - sources = [('target', casync.FileChunkReader(self.target_lo), casync.build_chunk_dict(target))] - sources += [('remote', casync.RemoteChunkReader(self.store_fn), casync.build_chunk_dict(target))] - - stats = casync.extract(target, sources, self.target_lo) - - with open(self.target_lo, 'rb') as f: - assert f.read(len(self.contents)) == self.contents - - assert stats['remote'] < len(self.contents) - - -@pytest.mark.skip("not used yet") -class TestCasyncDirectory: - """Tests extracting a directory stored as a casync tar archive""" - - NUM_FILES = 16 - - @classmethod - def setup_cache(cls, directory, files=None): - if files is None: - files = range(cls.NUM_FILES) - - chunk_a = [i % 256 for i in range(1024)] * 512 - chunk_b = [(256 - i) % 256 for i in range(1024)] * 512 - zeroes = [0] * (1024 * 128) - cls.contents = chunk_a + chunk_b + zeroes + chunk_a - cls.contents = bytes(cls.contents) - - for i in files: - with open(os.path.join(directory, f"file_{i}.txt"), "wb") as f: - f.write(cls.contents) - - os.symlink(f"file_{i}.txt", os.path.join(directory, f"link_{i}.txt")) - - @classmethod - def setup_class(cls): - cls.tmpdir = tempfile.TemporaryDirectory() - - # Create casync files - cls.manifest_fn = os.path.join(cls.tmpdir.name, 'orig.caibx') - cls.store_fn = os.path.join(cls.tmpdir.name, 'store') - - cls.directory_to_extract = tempfile.TemporaryDirectory() - cls.setup_cache(cls.directory_to_extract.name) - - cls.orig_fn = os.path.join(cls.tmpdir.name, 'orig.tar') - tar.create_tar_archive(cls.orig_fn, pathlib.Path(cls.directory_to_extract.name)) - - subprocess.check_output(["casync", "make", "--compression=xz", "--store", cls.store_fn, cls.manifest_fn, cls.orig_fn]) - - @classmethod - def teardown_class(cls): - cls.tmpdir.cleanup() - cls.directory_to_extract.cleanup() - - def setup_method(self): - self.cache_dir = tempfile.TemporaryDirectory() - self.working_dir = tempfile.TemporaryDirectory() - self.out_dir = tempfile.TemporaryDirectory() - - def teardown_method(self): - self.cache_dir.cleanup() - self.working_dir.cleanup() - self.out_dir.cleanup() - - def run_test(self): - target = casync.parse_caibx(self.manifest_fn) - - cache_filename = os.path.join(self.working_dir.name, "cache.tar") - tmp_filename = os.path.join(self.working_dir.name, "tmp.tar") - - sources = [('cache', casync.DirectoryTarChunkReader(self.cache_dir.name, cache_filename), casync.build_chunk_dict(target))] - sources += [('remote', casync.RemoteChunkReader(self.store_fn), casync.build_chunk_dict(target))] - - stats = casync.extract_directory(target, sources, pathlib.Path(self.out_dir.name), tmp_filename) - - with open(os.path.join(self.out_dir.name, "file_0.txt"), "rb") as f: - assert f.read() == self.contents - - with open(os.path.join(self.out_dir.name, "link_0.txt"), "rb") as f: - assert f.read() == self.contents - assert os.readlink(os.path.join(self.out_dir.name, "link_0.txt")) == "file_0.txt" - - return stats - - def test_no_cache(self): - self.setup_cache(self.cache_dir.name, []) - stats = self.run_test() - assert stats['remote'] > 0 - assert stats['cache'] == 0 - - def test_full_cache(self): - self.setup_cache(self.cache_dir.name, range(self.NUM_FILES)) - stats = self.run_test() - assert stats['remote'] == 0 - assert stats['cache'] > 0 - - def test_one_file_cache(self): - self.setup_cache(self.cache_dir.name, range(1)) - stats = self.run_test() - assert stats['remote'] > 0 - assert stats['cache'] > 0 - assert stats['cache'] < stats['remote'] - - def test_one_file_incorrect_cache(self): - self.setup_cache(self.cache_dir.name, range(self.NUM_FILES)) - with open(os.path.join(self.cache_dir.name, "file_0.txt"), "wb") as f: - f.write(b"1234") - - stats = self.run_test() - assert stats['remote'] > 0 - assert stats['cache'] > 0 - assert stats['cache'] > stats['remote'] - - def test_one_file_missing_cache(self): - self.setup_cache(self.cache_dir.name, range(self.NUM_FILES)) - os.unlink(os.path.join(self.cache_dir.name, "file_12.txt")) - - stats = self.run_test() - assert stats['remote'] > 0 - assert stats['cache'] > 0 - assert stats['cache'] > stats['remote'] From cb6e422c913ce59edfc8d049eac3d6f3d4b74915 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Sat, 20 Jun 2026 15:16:48 -0700 Subject: [PATCH 058/151] move esim to common/ (#38199) * move esim to common/ * add pem --- common/esim/__init__.py | 3 + common/esim/base.py | 55 +++++++++++++++++++ {system/hardware => common/esim}/esim.py | 2 +- .../tici => common/esim}/gsma_ci_bundle.pem | 0 {system/hardware/tici => common/esim}/lpa.py | 2 +- system/hardware/base.py | 50 +---------------- system/hardware/tici/hardware.py | 5 +- tools/op.sh | 2 +- 8 files changed, 65 insertions(+), 54 deletions(-) create mode 100644 common/esim/__init__.py create mode 100644 common/esim/base.py rename {system/hardware => common/esim}/esim.py (97%) rename {system/hardware/tici => common/esim}/gsma_ci_bundle.pem (100%) rename {system/hardware/tici => common/esim}/lpa.py (99%) diff --git a/common/esim/__init__.py b/common/esim/__init__.py new file mode 100644 index 0000000000..5f83412c07 --- /dev/null +++ b/common/esim/__init__.py @@ -0,0 +1,3 @@ +from openpilot.common.esim.base import LPABase, LPAError, LPAProfileNotFoundError, Profile + +__all__ = ["LPABase", "LPAError", "LPAProfileNotFoundError", "Profile"] diff --git a/common/esim/base.py b/common/esim/base.py new file mode 100644 index 0000000000..b783a630b2 --- /dev/null +++ b/common/esim/base.py @@ -0,0 +1,55 @@ +from abc import ABC, abstractmethod +from dataclasses import dataclass + + +class LPAError(RuntimeError): + pass + + +class LPAProfileNotFoundError(LPAError): + pass + + +@dataclass +class Profile: + iccid: str + nickname: str + enabled: bool + provider: str + + @property + def is_comma(self) -> bool: + return self.provider == 'Webbing' and self.iccid.startswith('8985235') + + +class LPABase(ABC): + @abstractmethod + def list_profiles(self) -> list[Profile]: + pass + + @abstractmethod + def get_active_profile(self) -> Profile | None: + pass + + @abstractmethod + def delete_profile(self, iccid: str) -> None: + pass + + @abstractmethod + def download_profile(self, qr: str, nickname: str | None = None) -> None: + pass + + @abstractmethod + def nickname_profile(self, iccid: str, nickname: str) -> None: + pass + + @abstractmethod + def switch_profile(self, iccid: str) -> None: + pass + + def process_notifications(self) -> None: + pass + + @abstractmethod + def is_euicc(self) -> bool: + pass diff --git a/system/hardware/esim.py b/common/esim/esim.py similarity index 97% rename from system/hardware/esim.py rename to common/esim/esim.py index 18d84de983..788e944c43 100755 --- a/system/hardware/esim.py +++ b/common/esim/esim.py @@ -2,7 +2,7 @@ import argparse from openpilot.system.hardware import HARDWARE -from openpilot.system.hardware.base import LPABase, Profile +from openpilot.common.esim.base import LPABase, Profile def sorted_profiles(lpa: LPABase) -> list[Profile]: diff --git a/system/hardware/tici/gsma_ci_bundle.pem b/common/esim/gsma_ci_bundle.pem similarity index 100% rename from system/hardware/tici/gsma_ci_bundle.pem rename to common/esim/gsma_ci_bundle.pem diff --git a/system/hardware/tici/lpa.py b/common/esim/lpa.py similarity index 99% rename from system/hardware/tici/lpa.py rename to common/esim/lpa.py index 618d11e5d1..4009823323 100644 --- a/system/hardware/tici/lpa.py +++ b/common/esim/lpa.py @@ -19,7 +19,7 @@ from typing import Any from pathlib import Path from openpilot.common.time_helpers import system_time_valid -from openpilot.system.hardware.base import LPABase, LPAError, LPAProfileNotFoundError, Profile +from openpilot.common.esim.base import LPABase, LPAError, LPAProfileNotFoundError, Profile GSMA_CI_BUNDLE = str(Path(__file__).parent / "gsma_ci_bundle.pem") diff --git a/system/hardware/base.py b/system/hardware/base.py index 5bcf886ae8..dccb168935 100644 --- a/system/hardware/base.py +++ b/system/hardware/base.py @@ -3,27 +3,11 @@ from abc import abstractmethod, ABC from dataclasses import dataclass, fields from cereal import log +from openpilot.common.esim.base import LPABase NetworkType = log.DeviceState.NetworkType NetworkStrength = log.DeviceState.NetworkStrength -class LPAError(RuntimeError): - pass - -class LPAProfileNotFoundError(LPAError): - pass - -@dataclass -class Profile: - iccid: str - nickname: str - enabled: bool - provider: str - - @property - def is_comma(self) -> bool: - return self.provider == 'Webbing' and self.iccid.startswith('8985235') - @dataclass class ThermalZone: # a zone from /sys/class/thermal/thermal_zone* @@ -70,38 +54,6 @@ class ThermalConfig: ret[f.name + "TempC"] = v.read() return ret -class LPABase(ABC): - @abstractmethod - def list_profiles(self) -> list[Profile]: - pass - - @abstractmethod - def get_active_profile(self) -> Profile | None: - pass - - @abstractmethod - def delete_profile(self, iccid: str) -> None: - pass - - @abstractmethod - def download_profile(self, qr: str, nickname: str | None = None) -> None: - pass - - @abstractmethod - def nickname_profile(self, iccid: str, nickname: str) -> None: - pass - - @abstractmethod - def switch_profile(self, iccid: str) -> None: - pass - - def process_notifications(self) -> None: - pass - - @abstractmethod - def is_euicc(self) -> bool: - pass - class HardwareBase(ABC): @staticmethod def get_cmdline() -> dict[str, str]: diff --git a/system/hardware/tici/hardware.py b/system/hardware/tici/hardware.py index 10b6d7646c..252474e12c 100644 --- a/system/hardware/tici/hardware.py +++ b/system/hardware/tici/hardware.py @@ -10,9 +10,10 @@ from pathlib import Path from cereal import log from openpilot.common.utils import sudo_read, sudo_write from openpilot.common.gpio import gpio_set, gpio_init, get_irqs_for_action -from openpilot.system.hardware.base import HardwareBase, LPABase, ThermalConfig, ThermalZone +from openpilot.common.esim.base import LPABase +from openpilot.system.hardware.base import HardwareBase, ThermalConfig, ThermalZone from openpilot.system.hardware.tici import iwlist -from openpilot.system.hardware.tici.lpa import TiciLPA +from openpilot.common.esim.lpa import TiciLPA from openpilot.system.hardware.tici.pins import GPIO from openpilot.system.hardware.tici.amplifier import Amplifier diff --git a/tools/op.sh b/tools/op.sh index 1188d21ac2..ecef240b5b 100755 --- a/tools/op.sh +++ b/tools/op.sh @@ -298,7 +298,7 @@ function op_check() { function op_esim() { op_before_cmd - op_run_command system/hardware/esim.py "$@" + op_run_command common/esim/esim.py "$@" } function op_build() { From f0f7b877c374898881e20a2608883e77b1e7d562 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Sat, 20 Jun 2026 15:27:36 -0700 Subject: [PATCH 059/151] athena: remove getNetworks (#38200) --- system/athena/athenad.py | 5 ----- system/hardware/base.py | 3 --- system/hardware/tici/hardware.py | 28 ------------------------- system/hardware/tici/iwlist.py | 35 -------------------------------- 4 files changed, 71 deletions(-) delete mode 100644 system/hardware/tici/iwlist.py diff --git a/system/athena/athenad.py b/system/athena/athenad.py index 8cadfb857a..6350b8a891 100755 --- a/system/athena/athenad.py +++ b/system/athena/athenad.py @@ -570,11 +570,6 @@ def getNetworkMetered() -> bool: return HARDWARE.get_network_metered(network_type) -@dispatcher.add_method -def getNetworks(): - return HARDWARE.get_networks() - - @dispatcher.add_method def startStream(sdp: str, enabled: bool) -> dict: from openpilot.system.webrtc.helpers import StreamRequestBody, post_stream_request, wait_for_webrtcd diff --git a/system/hardware/base.py b/system/hardware/base.py index dccb168935..0e4fb0b615 100644 --- a/system/hardware/base.py +++ b/system/hardware/base.py @@ -151,9 +151,6 @@ class HardwareBase(ABC): def initialize_hardware(self): pass - def get_networks(self): - return None - def has_internal_panda(self) -> bool: return False diff --git a/system/hardware/tici/hardware.py b/system/hardware/tici/hardware.py index 252474e12c..6f3d7e870d 100644 --- a/system/hardware/tici/hardware.py +++ b/system/hardware/tici/hardware.py @@ -12,7 +12,6 @@ from openpilot.common.utils import sudo_read, sudo_write from openpilot.common.gpio import gpio_set, gpio_init, get_irqs_for_action from openpilot.common.esim.base import LPABase from openpilot.system.hardware.base import HardwareBase, ThermalConfig, ThermalZone -from openpilot.system.hardware.tici import iwlist from openpilot.common.esim.lpa import TiciLPA from openpilot.system.hardware.tici.pins import GPIO from openpilot.system.hardware.tici.amplifier import Amplifier @@ -387,33 +386,6 @@ class Tici(HardwareBase): except subprocess.CalledProcessError as e: print(str(e)) - def get_networks(self): - r = {} - - wlan = iwlist.scan() - if wlan is not None: - r['wlan'] = wlan - - lte_info = self.get_network_info() - if lte_info is not None: - extra = lte_info['extra'] - - # ,"LTE",,,,,,,, - # ,,,,,,, - if 'LTE' in extra: - extra = extra.split(',') - try: - r['lte'] = [{ - "mcc": int(extra[3]), - "mnc": int(extra[4]), - "cid": int(extra[5], 16), - "nmr": [{"pci": int(extra[6]), "earfcn": int(extra[7])}], - }] - except (ValueError, IndexError): - pass - - return r - def get_modem_data_usage(self): ms = self.get_modem_state() return ms.get('tx_bytes', -1), ms.get('rx_bytes', -1) diff --git a/system/hardware/tici/iwlist.py b/system/hardware/tici/iwlist.py deleted file mode 100644 index 1e7c428b40..0000000000 --- a/system/hardware/tici/iwlist.py +++ /dev/null @@ -1,35 +0,0 @@ -import subprocess - - -def scan(interface="wlan0"): - result = [] - try: - r = subprocess.check_output(["iwlist", interface, "scan"], encoding='utf8') - - mac = None - for line in r.split('\n'): - if "Address" in line: - # Based on the adapter eithere a percentage or dBm is returned - # Add previous network in case no dBm signal level was seen - if mac is not None: - result.append({"mac": mac}) - mac = None - - mac = line.split(' ')[-1] - elif "dBm" in line: - try: - level = line.split('Signal level=')[1] - rss = int(level.split(' ')[0]) - result.append({"mac": mac, "rss": rss}) - mac = None - except ValueError: - continue - - # Add last network if no dBm was found - if mac is not None: - result.append({"mac": mac}) - - return result - - except Exception: - return None From 3b4077d31be58eba4208ae4aa480b499e928cf49 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Sat, 20 Jun 2026 15:51:01 -0700 Subject: [PATCH 060/151] system/hardware/ cleanup (#38201) * imei cleanup * rm get_modem_version * cpp cleanup * that's not in the panda! --- selfdrive/pandad/pandad.cc | 51 +++---------------- system/athena/registration.py | 13 +++-- system/hardware/base.h | 4 -- system/hardware/base.py | 14 +---- system/hardware/hardwared.py | 11 +--- system/hardware/pc/hardware.h | 2 - system/hardware/pc/hardware.py | 6 +-- system/hardware/tici/hardware.h | 8 +-- system/hardware/tici/hardware.py | 10 +--- system/hardware/tici/precise_power_measure.py | 9 ---- 10 files changed, 18 insertions(+), 110 deletions(-) delete mode 100755 system/hardware/tici/precise_power_measure.py diff --git a/selfdrive/pandad/pandad.cc b/selfdrive/pandad/pandad.cc index 7c91fe3611..7fbfcb5b18 100644 --- a/selfdrive/pandad/pandad.cc +++ b/selfdrive/pandad/pandad.cc @@ -1,7 +1,6 @@ #include "selfdrive/pandad/pandad.h" #include -#include #include #include #include @@ -24,14 +23,6 @@ ExitHandler do_exit; -struct HwmonState { - std::atomic voltage{0}; - std::atomic current{0}; - std::atomic initialized{false}; -}; - -HwmonState hwmon_state; - bool check_connected(Panda *panda) { if (!panda->connected()) { do_exit = true; @@ -114,26 +105,6 @@ void can_recv(Panda *panda, PubMaster *pm) { } } -void hwmon_thread() { - util::set_thread_name("pandad_hwmon"); - - while (!do_exit) { - double read_time = millis_since_boot(); - uint32_t voltage = Hardware::get_voltage(); - uint32_t current = Hardware::get_current(); - read_time = millis_since_boot() - read_time; - if (read_time > 50) { - LOGW("reading hwmon took %lfms", read_time); - } - - hwmon_state.voltage.store(voltage); - hwmon_state.current.store(current); - hwmon_state.initialized.store(true); - - util::sleep_for(500); - } -} - void fill_panda_state(cereal::PandaState::Builder &ps, cereal::PandaState::PandaType hw_type, const health_t &health) { ps.setVoltage(health.voltage_pkt); ps.setCurrent(health.current_pkt); @@ -264,7 +235,8 @@ std::optional send_panda_states(PubMaster *pm, Panda *panda, bool is_onroa } void send_peripheral_state(Panda *panda, PubMaster *pm) { - if (!hwmon_state.initialized.load()) { + auto health_opt = panda->get_state(); + if (!health_opt) { return; } @@ -276,18 +248,9 @@ void send_peripheral_state(Panda *panda, PubMaster *pm) { auto ps = evt.initPeripheralState(); ps.setPandaType(panda->hw_type); - ps.setVoltage(hwmon_state.voltage.load()); - ps.setCurrent(hwmon_state.current.load()); - - // fall back to panda's voltage and current measurement - if (ps.getVoltage() == 0 && ps.getCurrent() == 0) { - auto health_opt = panda->get_state(); - if (health_opt) { - health_t health = *health_opt; - ps.setVoltage(health.voltage_pkt); - ps.setCurrent(health.current_pkt); - } - } + health_t health = *health_opt; + ps.setVoltage(health.voltage_pkt); + ps.setCurrent(health.current_pkt); uint16_t fan_speed_rpm = panda->get_fan_speed(); ps.setFanSpeedRpm(fan_speed_rpm); @@ -399,9 +362,8 @@ void pandad_run(Panda *panda) { const bool spoofing_started = getenv("STARTED") != nullptr; const bool fake_send = getenv("FAKESEND") != nullptr; - // Start helper threads for event-driven sendcan and slow non-Panda reads. + // Start helper thread for event-driven sendcan. std::thread send_thread(can_send_thread, panda, fake_send); - std::thread hardware_thread(hwmon_thread); RateKeeper rk("pandad", 100); SubMaster sm({"selfdriveState", "deviceState"}); @@ -457,7 +419,6 @@ void pandad_run(Panda *panda) { } send_thread.join(); - hardware_thread.join(); } void pandad_main_thread(std::string serial) { diff --git a/system/athena/registration.py b/system/athena/registration.py index ecc102edf9..8548a544f5 100755 --- a/system/athena/registration.py +++ b/system/athena/registration.py @@ -54,17 +54,16 @@ def register(show_spinner=False) -> str | None: # Block until we get the imei serial = HARDWARE.get_serial() start_time = time.monotonic() - imei1: str | None = None - imei2: str | None = None - while imei1 is None and imei2 is None: + imei: str | None = None + while imei is None: try: - imei1, imei2 = HARDWARE.get_imei(0), HARDWARE.get_imei(1) + imei = HARDWARE.get_imei() except Exception: cloudlog.exception("Error getting imei, trying again...") time.sleep(1) if time.monotonic() - start_time > 60 and show_spinner: - spinner.update(f"registering device - serial: {serial}, IMEI: ({imei1}, {imei2})") + spinner.update(f"registering device - serial: {serial}, IMEI: {imei}") backoff = 0 start_time = time.monotonic() @@ -74,7 +73,7 @@ def register(show_spinner=False) -> str | None: cast(str, private_key), algorithm=jwt_algo) cloudlog.info("getting pilotauth") resp = api_get("v2/pilotauth/", method='POST', timeout=15, - imei=imei1, imei2=imei2, serial=serial, public_key=public_key, register_token=register_token) + imei=imei, imei2="", serial=serial, public_key=public_key, register_token=register_token) if resp.status_code in (402, 403): cloudlog.info(f"Unable to register device, got {resp.status_code}") @@ -89,7 +88,7 @@ def register(show_spinner=False) -> str | None: time.sleep(backoff) if time.monotonic() - start_time > 60 and show_spinner: - spinner.update(f"registering device - serial: {serial}, IMEI: ({imei1}, {imei2})") + spinner.update(f"registering device - serial: {serial}, IMEI: {imei}") if show_spinner: spinner.close() diff --git a/system/hardware/base.h b/system/hardware/base.h index 3eded659ac..3cb8add783 100644 --- a/system/hardware/base.h +++ b/system/hardware/base.h @@ -12,8 +12,6 @@ class HardwareNone { public: static std::string get_name() { return ""; } static cereal::InitData::DeviceType get_device_type() { return cereal::InitData::DeviceType::UNKNOWN; } - static int get_voltage() { return 0; } - static int get_current() { return 0; } static std::string get_serial() { return "cccccc"; } @@ -24,6 +22,4 @@ public: static void set_ir_power(int percentage) {} static bool PC() { return false; } - static bool TICI() { return false; } - static bool AGNOS() { return false; } }; diff --git a/system/hardware/base.py b/system/hardware/base.py index 0e4fb0b615..bf6523db77 100644 --- a/system/hardware/base.py +++ b/system/hardware/base.py @@ -85,7 +85,7 @@ class HardwareBase(ABC): def get_device_type(self): pass - def get_imei(self, slot) -> str: + def get_imei(self) -> str: return "" def get_serial(self): @@ -142,18 +142,12 @@ class HardwareBase(ABC): def get_gpu_usage_percent(self): return 0 - def get_modem_version(self): - return None - def get_modem_temperatures(self): return [] def initialize_hardware(self): pass - def has_internal_panda(self) -> bool: - return False - def reset_internal_panda(self): pass @@ -163,11 +157,5 @@ class HardwareBase(ABC): def get_modem_data_usage(self): return -1, -1 - def get_voltage(self) -> float: - return 0. - - def get_current(self) -> float: - return 0. - def set_ir_power(self, percent: int): pass diff --git a/system/hardware/hardwared.py b/system/hardware/hardwared.py index 5db73403e1..d047ee37cd 100755 --- a/system/hardware/hardwared.py +++ b/system/hardware/hardwared.py @@ -17,7 +17,7 @@ from openpilot.common.filter_simple import FirstOrderFilter from openpilot.common.params import Params from openpilot.common.realtime import DT_HW from openpilot.selfdrive.selfdrived.alertmanager import set_offroad_alert -from openpilot.system.hardware import HARDWARE, TICI, AGNOS, PC +from openpilot.system.hardware import HARDWARE, TICI, PC from openpilot.system.loggerd.config import get_available_percent from openpilot.system.statsd import statlog from openpilot.common.swaglog import cloudlog @@ -107,8 +107,6 @@ def hw_state_thread(end_event, hw_queue): count = 0 prev_hw_state = None - modem_version = None - while not end_event.is_set(): # these are expensive calls. update every 10s if (count % int(10. / DT_HW)) == 0: @@ -118,13 +116,6 @@ def hw_state_thread(end_event, hw_queue): if len(modem_temps) == 0 and prev_hw_state is not None: modem_temps = prev_hw_state.modem_temps - # Log modem version once - if AGNOS and (modem_version is None): - modem_version = HARDWARE.get_modem_version() - - if modem_version is not None: - cloudlog.event("modem version", version=modem_version) - tx, rx = HARDWARE.get_modem_data_usage() hw_state = HardwareState( diff --git a/system/hardware/pc/hardware.h b/system/hardware/pc/hardware.h index 71f58b188b..c3545f3e5f 100644 --- a/system/hardware/pc/hardware.h +++ b/system/hardware/pc/hardware.h @@ -9,6 +9,4 @@ public: static std::string get_name() { return "pc"; } static cereal::InitData::DeviceType get_device_type() { return cereal::InitData::DeviceType::PC; } static bool PC() { return true; } - static bool TICI() { return util::getenv("TICI", 0) == 1; } - static bool AGNOS() { return util::getenv("TICI", 0) == 1; } }; diff --git a/system/hardware/pc/hardware.py b/system/hardware/pc/hardware.py index f3d527429c..37775d9bb0 100644 --- a/system/hardware/pc/hardware.py +++ b/system/hardware/pc/hardware.py @@ -1,12 +1,10 @@ from cereal import log from openpilot.system.hardware.base import HardwareBase -NetworkType = log.DeviceState.NetworkType - - class Pc(HardwareBase): def get_device_type(self): return "pc" def get_network_type(self): - return NetworkType.wifi + # some stuff is gated on wifi, so just assume for now + return log.DeviceState.NetworkType.wifi diff --git a/system/hardware/tici/hardware.h b/system/hardware/tici/hardware.h index a06ce43b35..95a6d4e011 100644 --- a/system/hardware/tici/hardware.h +++ b/system/hardware/tici/hardware.h @@ -1,6 +1,5 @@ #pragma once -#include #include #include #include @@ -22,7 +21,6 @@ public: static cereal::InitData::DeviceType get_device_type() { static const std::map device_map = { - {"tici", cereal::InitData::DeviceType::TICI}, {"tizi", cereal::InitData::DeviceType::TIZI}, {"mici", cereal::InitData::DeviceType::MICI} }; @@ -31,9 +29,6 @@ public: return it->second; } - static int get_voltage() { return std::atoi(util::read_file("/sys/class/hwmon/hwmon1/in1_input").c_str()); } - static int get_current() { return std::atoi(util::read_file("/sys/class/hwmon/hwmon1/curr1_input").c_str()); } - static std::string get_serial() { static std::string serial(""); if (serial.empty()) { @@ -54,8 +49,7 @@ public: static void set_ir_power(int percent) { auto device = get_device_type(); - if (device == cereal::InitData::DeviceType::TICI || - device == cereal::InitData::DeviceType::TIZI) { + if (device == cereal::InitData::DeviceType::TIZI) { return; } diff --git a/system/hardware/tici/hardware.py b/system/hardware/tici/hardware.py index 6f3d7e870d..35bf4cd08a 100644 --- a/system/hardware/tici/hardware.py +++ b/system/hardware/tici/hardware.py @@ -147,9 +147,7 @@ class Tici(HardwareBase): def get_sim_lpa(self) -> LPABase: return TiciLPA() - def get_imei(self, slot): - if slot != 0: - return "" + def get_imei(self): return self.get_modem_state().get('imei', '') def get_network_info(self): @@ -233,9 +231,6 @@ class Tici(HardwareBase): return super().get_network_metered(network_type) - def get_modem_version(self): - return self.get_modem_state().get('modem_version') or None - def get_modem_temperatures(self): return self.get_modem_state().get('temperatures', []) @@ -390,9 +385,6 @@ class Tici(HardwareBase): ms = self.get_modem_state() return ms.get('tx_bytes', -1), ms.get('rx_bytes', -1) - def has_internal_panda(self): - return True - def reset_internal_panda(self): gpio_init(GPIO.STM_RST_N, True) gpio_init(GPIO.STM_BOOT0, True) diff --git a/system/hardware/tici/precise_power_measure.py b/system/hardware/tici/precise_power_measure.py deleted file mode 100755 index 52fe0850ab..0000000000 --- a/system/hardware/tici/precise_power_measure.py +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/env python3 -import numpy as np -from openpilot.system.hardware.tici.power_monitor import sample_power - -if __name__ == '__main__': - print("measuring for 5 seconds") - for _ in range(3): - pwrs = sample_power() - print(f"mean {np.mean(pwrs):.2f} std {np.std(pwrs):.2f}") From 52e25ebe4e5e1786ce1310a35cb4e071987602d5 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Sat, 20 Jun 2026 16:08:24 -0700 Subject: [PATCH 061/151] we don't have this anymore --- selfdrive/pandad/tests/test_pandad_spi.py | 1 - 1 file changed, 1 deletion(-) diff --git a/selfdrive/pandad/tests/test_pandad_spi.py b/selfdrive/pandad/tests/test_pandad_spi.py index 69dfb67e93..50021d8998 100644 --- a/selfdrive/pandad/tests/test_pandad_spi.py +++ b/selfdrive/pandad/tests/test_pandad_spi.py @@ -80,7 +80,6 @@ class TestBoarddSpi: ps = m.peripheralState assert ps.pandaType == "tres" assert 4000 < ps.voltage < 14000 - assert 50 < ps.current < 1000 assert ps.fanSpeedRpm < 10000 time.sleep(0.5) From 160942dfde46786f3fa35ad3814cd6861d61d324 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Sat, 20 Jun 2026 16:09:22 -0700 Subject: [PATCH 062/151] move HAL to common/hardware/ (#38202) * move HAL to common/hardware/ * lint * rm shim --- .gitattributes | 2 +- Jenkinsfile | 4 +- common/api.py | 2 +- common/esim/esim.py | 2 +- {system => common}/hardware/__init__.py | 6 +- {system => common}/hardware/base.h | 0 {system => common}/hardware/base.py | 0 {system => common}/hardware/hw.h | 6 +- {system => common}/hardware/hw.py | 2 +- {system => common}/hardware/pc/__init__.py | 0 {system => common}/hardware/pc/hardware.h | 2 +- {system => common}/hardware/pc/hardware.py | 2 +- common/hardware/tici/__init__.py | 1 + common/hardware/tici/agnos.json | 84 ++++++++++++++++++ {system => common}/hardware/tici/agnos.py | 0 .../hardware/tici/all-partitions.json | 0 {system => common}/hardware/tici/amplifier.py | 0 {system => common}/hardware/tici/hardware.h | 2 +- {system => common}/hardware/tici/hardware.py | 6 +- {system => common}/hardware/tici/id_rsa | 0 {system => common}/hardware/tici/modem.py | 0 {system => common}/hardware/tici/pins.py | 0 .../hardware/tici/power_monitor.py | 0 common/hardware/tici/tests/__init__.py | 1 + .../hardware/tici/tests/test_agnos_updater.py | 0 .../hardware/tici/tests/test_amplifier.py | 4 +- .../hardware/tici/tests/test_power_draw.py | 2 +- {system => common}/hardware/tici/updater | 0 common/params.cc | 2 +- common/prefix.h | 2 +- common/prefix.py | 6 +- common/realtime.py | 2 +- common/swaglog.cc | 2 +- common/swaglog.py | 2 +- common/tests/test_swaglog.cc | 2 +- conftest.py | 2 +- launch_chffrplus.sh | 4 +- scripts/disable-powersave.py | 2 +- selfdrive/car/tests/test_models.py | 2 +- selfdrive/locationd/calibrationd.py | 2 +- selfdrive/locationd/test/test_lagd.py | 2 +- selfdrive/modeld/SConscript | 2 +- selfdrive/modeld/compile_modeld.py | 2 +- selfdrive/pandad/main.cc | 2 +- selfdrive/pandad/pandad.cc | 2 +- selfdrive/pandad/pandad.py | 2 +- selfdrive/pandad/tests/test_pandad.py | 4 +- selfdrive/selfdrived/events.py | 2 +- selfdrive/selfdrived/selfdrived.py | 2 +- selfdrive/test/process_replay/model_replay.py | 2 +- .../test/process_replay/process_replay.py | 2 +- selfdrive/test/test_onroad.py | 4 +- selfdrive/ui/installer/installer.cc | 2 +- selfdrive/ui/mici/layouts/offroad_alerts.py | 2 +- selfdrive/ui/mici/onroad/alert_renderer.py | 2 +- selfdrive/ui/mici/onroad/cameraview.py | 2 +- selfdrive/ui/onroad/alert_renderer.py | 2 +- selfdrive/ui/onroad/cameraview.py | 2 +- selfdrive/ui/soundd.py | 2 +- selfdrive/ui/ui.py | 2 +- selfdrive/ui/ui_state.py | 2 +- selfdrive/ui/widgets/offroad_alerts.py | 2 +- system/athena/athenad.py | 4 +- system/athena/manage_athenad.py | 2 +- system/athena/registration.py | 4 +- system/athena/tests/test_athenad.py | 2 +- system/athena/tests/test_athenad_ping.py | 2 +- system/athena/tests/test_registration.py | 2 +- system/camerad/snapshot.py | 2 +- system/hardware/fan_controller.py | 2 +- system/hardware/hardwared.py | 2 +- system/hardware/power_monitoring.py | 2 +- system/hardware/tici/__init__.py | 0 system/hardware/tici/agnos.json | 85 +------------------ system/hardware/tici/tests/__init__.py | 0 system/loggerd/config.py | 2 +- system/loggerd/deleter.py | 2 +- system/loggerd/logger.h | 2 +- system/loggerd/loggerd.h | 2 +- system/loggerd/tests/loggerd_tests_common.py | 2 +- system/loggerd/tests/test_encoder.py | 4 +- system/loggerd/tests/test_loggerd.py | 4 +- system/loggerd/tests/test_uploader.py | 2 +- system/loggerd/uploader.py | 2 +- system/logmessaged.py | 2 +- system/manager/build.py | 2 +- system/manager/manager.py | 4 +- system/manager/process_config.py | 4 +- system/manager/test/test_manager.py | 2 +- system/qcomgpsd/nmeaport.py | 2 +- system/qcomgpsd/qcomgpsd.py | 2 +- system/sentry.py | 2 +- system/statsd.py | 4 +- system/tests/test_logmessaged.py | 2 +- system/tombstoned.py | 2 +- system/ubloxd/pigeond.py | 4 +- system/ubloxd/tests/test_pigeond.py | 2 +- system/ui/lib/application.py | 2 +- system/ui/lib/scroll_panel2.py | 2 +- system/ui/mici_reset.py | 2 +- system/ui/mici_setup.py | 2 +- system/ui/mici_updater.py | 2 +- system/ui/text.py | 2 +- system/ui/tici_reset.py | 2 +- system/ui/tici_setup.py | 2 +- system/ui/tici_updater.py | 2 +- system/updated/tests/test_base.py | 8 +- system/updated/updated.py | 4 +- tools/jotpluggler/app.cc | 2 +- tools/jotpluggler/layout.cc | 2 +- tools/joystick/joystick_control.py | 2 +- tools/lateral_maneuvers/generate_report.py | 2 +- tools/lib/auth_config.py | 2 +- tools/lib/file_downloader.py | 2 +- tools/lib/tests/test_caching.py | 2 +- tools/lib/url_file.py | 2 +- .../longitudinal_maneuvers/generate_report.py | 2 +- tools/replay/framereader.cc | 2 +- tools/replay/route.cc | 2 +- tools/scripts/ssh.py | 2 +- tools/scripts/uiview.py | 2 +- 121 files changed, 215 insertions(+), 212 deletions(-) rename {system => common}/hardware/__init__.py (55%) rename {system => common}/hardware/base.h (100%) rename {system => common}/hardware/base.py (100%) rename {system => common}/hardware/hw.h (91%) rename {system => common}/hardware/hw.py (97%) rename {system => common}/hardware/pc/__init__.py (100%) rename {system => common}/hardware/pc/hardware.h (88%) rename {system => common}/hardware/pc/hardware.py (80%) create mode 100644 common/hardware/tici/__init__.py create mode 100644 common/hardware/tici/agnos.json rename {system => common}/hardware/tici/agnos.py (100%) rename {system => common}/hardware/tici/all-partitions.json (100%) rename {system => common}/hardware/tici/amplifier.py (100%) rename {system => common}/hardware/tici/hardware.h (98%) rename {system => common}/hardware/tici/hardware.py (98%) rename {system => common}/hardware/tici/id_rsa (100%) rename {system => common}/hardware/tici/modem.py (100%) rename {system => common}/hardware/tici/pins.py (100%) rename {system => common}/hardware/tici/power_monitor.py (100%) create mode 100644 common/hardware/tici/tests/__init__.py rename {system => common}/hardware/tici/tests/test_agnos_updater.py (100%) rename {system => common}/hardware/tici/tests/test_amplifier.py (93%) rename {system => common}/hardware/tici/tests/test_power_draw.py (98%) rename {system => common}/hardware/tici/updater (100%) delete mode 100644 system/hardware/tici/__init__.py mode change 100644 => 120000 system/hardware/tici/agnos.json delete mode 100644 system/hardware/tici/tests/__init__.py diff --git a/.gitattributes b/.gitattributes index efbe60f990..507eb73c13 100644 --- a/.gitattributes +++ b/.gitattributes @@ -11,4 +11,4 @@ *.wav filter=lfs diff=lfs merge=lfs -text selfdrive/car/tests/test_models_segs.txt filter=lfs diff=lfs merge=lfs -text -system/hardware/tici/updater filter=lfs diff=lfs merge=lfs -text +common/hardware/tici/updater filter=lfs diff=lfs merge=lfs -text diff --git a/Jenkinsfile b/Jenkinsfile index 92bc61521e..6291f5beb0 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -210,7 +210,7 @@ node { 'HW + Unit Tests': { deviceStage("tizi-hardware", "tizi-common", ["UNSAFE=1"], [ step("build", "cd system/manager && ./build.py"), - step("test power draw", "pytest -s system/hardware/tici/tests/test_power_draw.py"), + step("test power draw", "pytest -s common/hardware/tici/tests/test_power_draw.py"), step("test encoder", "LD_LIBRARY_PATH=/usr/local/lib pytest system/loggerd/tests/test_encoder.py", [diffPaths: ["system/loggerd/"]]), step("test manager", "pytest system/manager/test/test_manager.py"), ]) @@ -246,7 +246,7 @@ node { step("build openpilot", "cd system/manager && ./build.py"), step("test pandad loopback", "pytest selfdrive/pandad/tests/test_pandad_loopback.py"), step("test pandad spi", "pytest selfdrive/pandad/tests/test_pandad_spi.py"), - step("test amp", "pytest system/hardware/tici/tests/test_amplifier.py"), + step("test amp", "pytest common/hardware/tici/tests/test_amplifier.py"), ]) }, diff --git a/common/api.py b/common/api.py index ebf0290d15..521aac3fdd 100644 --- a/common/api.py +++ b/common/api.py @@ -2,7 +2,7 @@ import jwt import os import requests from datetime import datetime, timedelta, UTC -from openpilot.system.hardware.hw import Paths +from openpilot.common.hardware.hw import Paths from openpilot.system.version import get_version API_HOST = os.getenv('API_HOST', 'https://api.commadotai.com') diff --git a/common/esim/esim.py b/common/esim/esim.py index 788e944c43..8456d4dd47 100755 --- a/common/esim/esim.py +++ b/common/esim/esim.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 import argparse -from openpilot.system.hardware import HARDWARE +from openpilot.common.hardware import HARDWARE from openpilot.common.esim.base import LPABase, Profile diff --git a/system/hardware/__init__.py b/common/hardware/__init__.py similarity index 55% rename from system/hardware/__init__.py rename to common/hardware/__init__.py index 99079b5ef3..3387d8a0ca 100644 --- a/system/hardware/__init__.py +++ b/common/hardware/__init__.py @@ -1,9 +1,9 @@ import os from typing import cast -from openpilot.system.hardware.base import HardwareBase -from openpilot.system.hardware.tici.hardware import Tici -from openpilot.system.hardware.pc.hardware import Pc +from openpilot.common.hardware.base import HardwareBase +from openpilot.common.hardware.tici.hardware import Tici +from openpilot.common.hardware.pc.hardware import Pc TICI = os.path.isfile('/TICI') AGNOS = os.path.isfile('/AGNOS') diff --git a/system/hardware/base.h b/common/hardware/base.h similarity index 100% rename from system/hardware/base.h rename to common/hardware/base.h diff --git a/system/hardware/base.py b/common/hardware/base.py similarity index 100% rename from system/hardware/base.py rename to common/hardware/base.py diff --git a/system/hardware/hw.h b/common/hardware/hw.h similarity index 91% rename from system/hardware/hw.h rename to common/hardware/hw.h index a9058401ce..1e097d99b1 100644 --- a/system/hardware/hw.h +++ b/common/hardware/hw.h @@ -2,14 +2,14 @@ #include -#include "system/hardware/base.h" +#include "common/hardware/base.h" #include "common/util.h" #if __TICI__ -#include "system/hardware/tici/hardware.h" +#include "common/hardware/tici/hardware.h" #define Hardware HardwareTici #else -#include "system/hardware/pc/hardware.h" +#include "common/hardware/pc/hardware.h" #define Hardware HardwarePC #endif diff --git a/system/hardware/hw.py b/common/hardware/hw.py similarity index 97% rename from system/hardware/hw.py rename to common/hardware/hw.py index dc36dc0474..2c649db9eb 100644 --- a/system/hardware/hw.py +++ b/common/hardware/hw.py @@ -2,7 +2,7 @@ import os import platform from pathlib import Path -from openpilot.system.hardware import PC +from openpilot.common.hardware import PC DEFAULT_DOWNLOAD_CACHE_ROOT = "/tmp/comma_download_cache" diff --git a/system/hardware/pc/__init__.py b/common/hardware/pc/__init__.py similarity index 100% rename from system/hardware/pc/__init__.py rename to common/hardware/pc/__init__.py diff --git a/system/hardware/pc/hardware.h b/common/hardware/pc/hardware.h similarity index 88% rename from system/hardware/pc/hardware.h rename to common/hardware/pc/hardware.h index c3545f3e5f..2c43b43292 100644 --- a/system/hardware/pc/hardware.h +++ b/common/hardware/pc/hardware.h @@ -2,7 +2,7 @@ #include -#include "system/hardware/base.h" +#include "common/hardware/base.h" class HardwarePC : public HardwareNone { public: diff --git a/system/hardware/pc/hardware.py b/common/hardware/pc/hardware.py similarity index 80% rename from system/hardware/pc/hardware.py rename to common/hardware/pc/hardware.py index 37775d9bb0..b387f03127 100644 --- a/system/hardware/pc/hardware.py +++ b/common/hardware/pc/hardware.py @@ -1,5 +1,5 @@ from cereal import log -from openpilot.system.hardware.base import HardwareBase +from openpilot.common.hardware.base import HardwareBase class Pc(HardwareBase): def get_device_type(self): diff --git a/common/hardware/tici/__init__.py b/common/hardware/tici/__init__.py new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/common/hardware/tici/__init__.py @@ -0,0 +1 @@ + diff --git a/common/hardware/tici/agnos.json b/common/hardware/tici/agnos.json new file mode 100644 index 0000000000..07e2079ec9 --- /dev/null +++ b/common/hardware/tici/agnos.json @@ -0,0 +1,84 @@ +[ + { + "name": "xbl", + "url": "https://commadist.azureedge.net/agnosupdate/xbl-e8acf2a9cc7f0ce84cb803bfea9477f765c0d7b4daf26048e59651b9e6a7bfbb.img.xz", + "hash": "e8acf2a9cc7f0ce84cb803bfea9477f765c0d7b4daf26048e59651b9e6a7bfbb", + "hash_raw": "e8acf2a9cc7f0ce84cb803bfea9477f765c0d7b4daf26048e59651b9e6a7bfbb", + "size": 3282256, + "sparse": false, + "full_check": true, + "has_ab": true, + "ondevice_hash": "bea7f1a24428c3ededf672fa4fc78baf180cfbd8aafb77c974655b38517283e3" + }, + { + "name": "xbl_config", + "url": "https://commadist.azureedge.net/agnosupdate/xbl_config-758552ecf92b5569677197783bf0ccb73d7f961685308e45d3276ac9dd974f85.img.xz", + "hash": "758552ecf92b5569677197783bf0ccb73d7f961685308e45d3276ac9dd974f85", + "hash_raw": "758552ecf92b5569677197783bf0ccb73d7f961685308e45d3276ac9dd974f85", + "size": 98124, + "sparse": false, + "full_check": true, + "has_ab": true, + "ondevice_hash": "fb18cde08a98a168961ecd357e92474823046752b94e112f59fe51a6acd7197d" + }, + { + "name": "abl", + "url": "https://commadist.azureedge.net/agnosupdate/abl-b6fba807b9bcd66a31f2afb0eba5163ec239693ad32e2e4200f6c356adfe098c.img.xz", + "hash": "b6fba807b9bcd66a31f2afb0eba5163ec239693ad32e2e4200f6c356adfe098c", + "hash_raw": "b6fba807b9bcd66a31f2afb0eba5163ec239693ad32e2e4200f6c356adfe098c", + "size": 274432, + "sparse": false, + "full_check": true, + "has_ab": true, + "ondevice_hash": "b6fba807b9bcd66a31f2afb0eba5163ec239693ad32e2e4200f6c356adfe098c" + }, + { + "name": "aop", + "url": "https://commadist.azureedge.net/agnosupdate/aop-78b2287ca219a0811b3004c523fa0f4749e4d1fd92be3aba61699305b7943ad1.img.xz", + "hash": "78b2287ca219a0811b3004c523fa0f4749e4d1fd92be3aba61699305b7943ad1", + "hash_raw": "78b2287ca219a0811b3004c523fa0f4749e4d1fd92be3aba61699305b7943ad1", + "size": 184364, + "sparse": false, + "full_check": true, + "has_ab": true, + "ondevice_hash": "6c9135446bd3fc075fcee59b887a12e49029ab1f98ed8d6d1e32c73569d47de3" + }, + { + "name": "devcfg", + "url": "https://commadist.azureedge.net/agnosupdate/devcfg-f71df3a86958c093ba3969254c4db025187eef9385427f1ade946742939b43cc.img.xz", + "hash": "f71df3a86958c093ba3969254c4db025187eef9385427f1ade946742939b43cc", + "hash_raw": "f71df3a86958c093ba3969254c4db025187eef9385427f1ade946742939b43cc", + "size": 40336, + "sparse": false, + "full_check": true, + "has_ab": true, + "ondevice_hash": "2a67971602012c1b43544964709da13c322786b456a8e78568b117e8b1540ce3" + }, + { + "name": "boot", + "url": "https://commadist.azureedge.net/agnosupdate/boot-8806802b195a5b1396a3ae8dd92a8b7711dc522f6aceafd820e871bae5c8a6d8.img.xz", + "hash": "8806802b195a5b1396a3ae8dd92a8b7711dc522f6aceafd820e871bae5c8a6d8", + "hash_raw": "8806802b195a5b1396a3ae8dd92a8b7711dc522f6aceafd820e871bae5c8a6d8", + "size": 17487872, + "sparse": false, + "full_check": true, + "has_ab": true, + "ondevice_hash": "edca8bee1531e66953d107eeceeed2dc7b3ca46417e49d55508f94e58bf95db8" + }, + { + "name": "system", + "url": "https://commadist.azureedge.net/agnosupdate/system-ef0d879302cb29e72110e9c8d3f947c830fd7d37c8192744fc9dbea1af78501f.img.xz", + "hash": "78acfe16a7b62a3a91fc7a81f40a693e4468cec1c69df7d0b1e550aacc646113", + "hash_raw": "ef0d879302cb29e72110e9c8d3f947c830fd7d37c8192744fc9dbea1af78501f", + "size": 4718592000, + "sparse": true, + "full_check": false, + "has_ab": true, + "ondevice_hash": "743142c5a898f27b2a1029cca42c8a5d5d1fc0096414422b850fe84c8d0b8342", + "alt": { + "hash": "ef0d879302cb29e72110e9c8d3f947c830fd7d37c8192744fc9dbea1af78501f", + "url": "https://commadist.azureedge.net/agnosupdate/system-ef0d879302cb29e72110e9c8d3f947c830fd7d37c8192744fc9dbea1af78501f.img", + "size": 4718592000 + } + } +] \ No newline at end of file diff --git a/system/hardware/tici/agnos.py b/common/hardware/tici/agnos.py similarity index 100% rename from system/hardware/tici/agnos.py rename to common/hardware/tici/agnos.py diff --git a/system/hardware/tici/all-partitions.json b/common/hardware/tici/all-partitions.json similarity index 100% rename from system/hardware/tici/all-partitions.json rename to common/hardware/tici/all-partitions.json diff --git a/system/hardware/tici/amplifier.py b/common/hardware/tici/amplifier.py similarity index 100% rename from system/hardware/tici/amplifier.py rename to common/hardware/tici/amplifier.py diff --git a/system/hardware/tici/hardware.h b/common/hardware/tici/hardware.h similarity index 98% rename from system/hardware/tici/hardware.h rename to common/hardware/tici/hardware.h index 95a6d4e011..a1a8090c35 100644 --- a/system/hardware/tici/hardware.h +++ b/common/hardware/tici/hardware.h @@ -7,7 +7,7 @@ #include // for std::clamp #include "common/util.h" -#include "system/hardware/base.h" +#include "common/hardware/base.h" class HardwareTici : public HardwareNone { public: diff --git a/system/hardware/tici/hardware.py b/common/hardware/tici/hardware.py similarity index 98% rename from system/hardware/tici/hardware.py rename to common/hardware/tici/hardware.py index 35bf4cd08a..bec4c90423 100644 --- a/system/hardware/tici/hardware.py +++ b/common/hardware/tici/hardware.py @@ -11,10 +11,10 @@ from cereal import log from openpilot.common.utils import sudo_read, sudo_write from openpilot.common.gpio import gpio_set, gpio_init, get_irqs_for_action from openpilot.common.esim.base import LPABase -from openpilot.system.hardware.base import HardwareBase, ThermalConfig, ThermalZone +from openpilot.common.hardware.base import HardwareBase, ThermalConfig, ThermalZone from openpilot.common.esim.lpa import TiciLPA -from openpilot.system.hardware.tici.pins import GPIO -from openpilot.system.hardware.tici.amplifier import Amplifier +from openpilot.common.hardware.tici.pins import GPIO +from openpilot.common.hardware.tici.amplifier import Amplifier MODEM_STATE_PATH = "/dev/shm/modem" diff --git a/system/hardware/tici/id_rsa b/common/hardware/tici/id_rsa similarity index 100% rename from system/hardware/tici/id_rsa rename to common/hardware/tici/id_rsa diff --git a/system/hardware/tici/modem.py b/common/hardware/tici/modem.py similarity index 100% rename from system/hardware/tici/modem.py rename to common/hardware/tici/modem.py diff --git a/system/hardware/tici/pins.py b/common/hardware/tici/pins.py similarity index 100% rename from system/hardware/tici/pins.py rename to common/hardware/tici/pins.py diff --git a/system/hardware/tici/power_monitor.py b/common/hardware/tici/power_monitor.py similarity index 100% rename from system/hardware/tici/power_monitor.py rename to common/hardware/tici/power_monitor.py diff --git a/common/hardware/tici/tests/__init__.py b/common/hardware/tici/tests/__init__.py new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/common/hardware/tici/tests/__init__.py @@ -0,0 +1 @@ + diff --git a/system/hardware/tici/tests/test_agnos_updater.py b/common/hardware/tici/tests/test_agnos_updater.py similarity index 100% rename from system/hardware/tici/tests/test_agnos_updater.py rename to common/hardware/tici/tests/test_agnos_updater.py diff --git a/system/hardware/tici/tests/test_amplifier.py b/common/hardware/tici/tests/test_amplifier.py similarity index 93% rename from system/hardware/tici/tests/test_amplifier.py rename to common/hardware/tici/tests/test_amplifier.py index 9ce00c3ff2..39628b53cc 100644 --- a/system/hardware/tici/tests/test_amplifier.py +++ b/common/hardware/tici/tests/test_amplifier.py @@ -4,8 +4,8 @@ import random import subprocess from panda import Panda -from openpilot.system.hardware import TICI, HARDWARE -from openpilot.system.hardware.tici.amplifier import Amplifier +from openpilot.common.hardware import TICI, HARDWARE +from openpilot.common.hardware.tici.amplifier import Amplifier class TestAmplifier: diff --git a/system/hardware/tici/tests/test_power_draw.py b/common/hardware/tici/tests/test_power_draw.py similarity index 98% rename from system/hardware/tici/tests/test_power_draw.py rename to common/hardware/tici/tests/test_power_draw.py index 6656addf73..ad27292945 100644 --- a/system/hardware/tici/tests/test_power_draw.py +++ b/common/hardware/tici/tests/test_power_draw.py @@ -10,7 +10,7 @@ from cereal.services import SERVICE_LIST from opendbc.car.car_helpers import get_demo_car_params from openpilot.common.mock import mock_messages from openpilot.common.params import Params -from openpilot.system.hardware.tici.power_monitor import get_power +from openpilot.common.hardware.tici.power_monitor import get_power from openpilot.system.manager.process_config import managed_processes from openpilot.system.manager.manager import manager_cleanup diff --git a/system/hardware/tici/updater b/common/hardware/tici/updater similarity index 100% rename from system/hardware/tici/updater rename to common/hardware/tici/updater diff --git a/common/params.cc b/common/params.cc index 6af00fe95c..495feb0a99 100644 --- a/common/params.cc +++ b/common/params.cc @@ -12,7 +12,7 @@ #include "common/queue.h" #include "common/swaglog.h" #include "common/util.h" -#include "system/hardware/hw.h" +#include "common/hardware/hw.h" namespace { diff --git a/common/prefix.h b/common/prefix.h index de3a94d71f..89f346b9e5 100644 --- a/common/prefix.h +++ b/common/prefix.h @@ -5,7 +5,7 @@ #include "common/params.h" #include "common/util.h" -#include "system/hardware/hw.h" +#include "common/hardware/hw.h" class OpenpilotPrefix { public: diff --git a/common/prefix.py b/common/prefix.py index d0a5f92628..d0be8997ae 100644 --- a/common/prefix.py +++ b/common/prefix.py @@ -5,9 +5,9 @@ import uuid from openpilot.common.params import Params -from openpilot.system.hardware import PC -from openpilot.system.hardware.hw import Paths -from openpilot.system.hardware.hw import DEFAULT_DOWNLOAD_CACHE_ROOT +from openpilot.common.hardware import PC +from openpilot.common.hardware.hw import Paths +from openpilot.common.hardware.hw import DEFAULT_DOWNLOAD_CACHE_ROOT class OpenpilotPrefix: def __init__(self, prefix: str | None = None, create_dirs_on_enter: bool = True, clean_dirs_on_exit: bool = True, shared_download_cache: bool = False): diff --git a/common/realtime.py b/common/realtime.py index 91d2e165e9..e0b9e8a3a5 100644 --- a/common/realtime.py +++ b/common/realtime.py @@ -7,7 +7,7 @@ import time from setproctitle import getproctitle from openpilot.common.utils import MovingAverage -from openpilot.system.hardware import PC +from openpilot.common.hardware import PC # time step for each process diff --git a/common/swaglog.cc b/common/swaglog.cc index df7ce94c14..74c617fa61 100644 --- a/common/swaglog.cc +++ b/common/swaglog.cc @@ -13,7 +13,7 @@ #include #include "json11/json11.hpp" #include "common/version.h" -#include "system/hardware/hw.h" +#include "common/hardware/hw.h" class SwaglogState { public: diff --git a/common/swaglog.py b/common/swaglog.py index d009f00e76..ea72766fcb 100644 --- a/common/swaglog.py +++ b/common/swaglog.py @@ -8,7 +8,7 @@ from logging.handlers import BaseRotatingHandler import zmq from openpilot.common.logging_extra import SwagLogger, SwagFormatter, SwagLogFileFormatter -from openpilot.system.hardware.hw import Paths +from openpilot.common.hardware.hw import Paths def get_file_handler(): diff --git a/common/tests/test_swaglog.cc b/common/tests/test_swaglog.cc index 8142f8d63e..0c9cfcc1e6 100644 --- a/common/tests/test_swaglog.cc +++ b/common/tests/test_swaglog.cc @@ -6,7 +6,7 @@ #include "common/swaglog.h" #include "common/util.h" #include "common/version.h" -#include "system/hardware/hw.h" +#include "common/hardware/hw.h" #include "json11/json11.hpp" std::string daemon_name = "testy"; diff --git a/conftest.py b/conftest.py index dd159129b6..3719be93d3 100644 --- a/conftest.py +++ b/conftest.py @@ -5,7 +5,7 @@ import pytest from openpilot.common.prefix import OpenpilotPrefix from openpilot.system.manager import manager -from openpilot.system.hardware import TICI, HARDWARE +from openpilot.common.hardware import TICI, HARDWARE # these are heavy CI-only tests, invoked explicitly in .github/workflows/tests.yaml collect_ignore = [ diff --git a/launch_chffrplus.sh b/launch_chffrplus.sh index 5e7b4fa0db..46b0a5d079 100755 --- a/launch_chffrplus.sh +++ b/launch_chffrplus.sh @@ -19,12 +19,12 @@ function agnos_init { # Check if AGNOS update is required if [ $(< /VERSION) != "$AGNOS_VERSION" ]; then - AGNOS_PY="$DIR/system/hardware/tici/agnos.py" + AGNOS_PY="$DIR/common/hardware/tici/agnos.py" MANIFEST="$DIR/system/hardware/tici/agnos.json" if $AGNOS_PY --verify $MANIFEST; then sudo reboot fi - $DIR/system/hardware/tici/updater $AGNOS_PY $MANIFEST + $DIR/common/hardware/tici/updater $AGNOS_PY $MANIFEST fi } diff --git a/scripts/disable-powersave.py b/scripts/disable-powersave.py index 367b4108b0..093275fd77 100755 --- a/scripts/disable-powersave.py +++ b/scripts/disable-powersave.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -from openpilot.system.hardware import HARDWARE +from openpilot.common.hardware import HARDWARE if __name__ == "__main__": HARDWARE.set_power_save(False) diff --git a/selfdrive/car/tests/test_models.py b/selfdrive/car/tests/test_models.py index dd0826e513..035602b955 100644 --- a/selfdrive/car/tests/test_models.py +++ b/selfdrive/car/tests/test_models.py @@ -20,7 +20,7 @@ from opendbc.safety.tests.libsafety import libsafety_py from openpilot.common.basedir import BASEDIR from openpilot.selfdrive.pandad import can_capnp_to_list from openpilot.selfdrive.test.helpers import read_segment_list -from openpilot.system.hardware.hw import DEFAULT_DOWNLOAD_CACHE_ROOT +from openpilot.common.hardware.hw import DEFAULT_DOWNLOAD_CACHE_ROOT from openpilot.tools.lib.logreader import LogReader, LogsUnavailable, openpilotci_source, internal_source, comma_api_source from openpilot.tools.lib.route import SegmentName diff --git a/selfdrive/locationd/calibrationd.py b/selfdrive/locationd/calibrationd.py index 4423f39061..c444d43983 100755 --- a/selfdrive/locationd/calibrationd.py +++ b/selfdrive/locationd/calibrationd.py @@ -13,7 +13,7 @@ from typing import NoReturn from cereal import log, car import cereal.messaging as messaging -from openpilot.system.hardware import HARDWARE +from openpilot.common.hardware import HARDWARE from openpilot.common.constants import CV from openpilot.common.params import Params from openpilot.common.realtime import config_realtime_process diff --git a/selfdrive/locationd/test/test_lagd.py b/selfdrive/locationd/test/test_lagd.py index 0c4e227192..63ea2b5fab 100644 --- a/selfdrive/locationd/test/test_lagd.py +++ b/selfdrive/locationd/test/test_lagd.py @@ -10,7 +10,7 @@ from openpilot.selfdrive.test.process_replay.migration import migrate, migrate_c from openpilot.selfdrive.locationd.test.test_locationd_scenarios import TEST_ROUTE from openpilot.common.params import Params from openpilot.tools.lib.logreader import LogReader -from openpilot.system.hardware import PC +from openpilot.common.hardware import PC MAX_ERR_FRAMES = 1 DT = 0.05 diff --git a/selfdrive/modeld/SConscript b/selfdrive/modeld/SConscript index 74adf0d932..4a40173629 100644 --- a/selfdrive/modeld/SConscript +++ b/selfdrive/modeld/SConscript @@ -79,7 +79,7 @@ compile_modeld_script = [ File(f"{modeld_dir}/compile_modeld.py"), File(f"{modeld_dir}/get_model_metadata.py"), File("#system/camerad/cameras/nv12_info.py"), - File("#system/hardware/hw.py"), + File("#common/hardware/hw.py"), ] model_w, model_h = MEDMODEL_INPUT_SIZE frame_skip = ModelConstants.MODEL_RUN_FREQ // ModelConstants.MODEL_CONTEXT_FREQ diff --git a/selfdrive/modeld/compile_modeld.py b/selfdrive/modeld/compile_modeld.py index 069e39091a..35f92d344f 100755 --- a/selfdrive/modeld/compile_modeld.py +++ b/selfdrive/modeld/compile_modeld.py @@ -265,7 +265,7 @@ def _parse_size(s): def read_file_chunked_to_shm(path): from openpilot.common.file_chunker import read_file_chunked - from openpilot.system.hardware.hw import Paths + from openpilot.common.hardware.hw import Paths with tempfile.NamedTemporaryFile(prefix='compile_modeld_', dir=Paths.shm_path(), delete=False) as f: f.write(read_file_chunked(path)) tmp_path = f.name diff --git a/selfdrive/pandad/main.cc b/selfdrive/pandad/main.cc index ef30d6037c..08e88b6163 100644 --- a/selfdrive/pandad/main.cc +++ b/selfdrive/pandad/main.cc @@ -3,7 +3,7 @@ #include "selfdrive/pandad/pandad.h" #include "common/swaglog.h" #include "common/util.h" -#include "system/hardware/hw.h" +#include "common/hardware/hw.h" int main(int argc, char *argv[]) { LOGW("starting pandad"); diff --git a/selfdrive/pandad/pandad.cc b/selfdrive/pandad/pandad.cc index 7fbfcb5b18..657e36e6b8 100644 --- a/selfdrive/pandad/pandad.cc +++ b/selfdrive/pandad/pandad.cc @@ -15,7 +15,7 @@ #include "common/swaglog.h" #include "common/timing.h" #include "common/util.h" -#include "system/hardware/hw.h" +#include "common/hardware/hw.h" #define MAX_IR_PANDA_VAL 50 #define CUTOFF_IL 400 diff --git a/selfdrive/pandad/pandad.py b/selfdrive/pandad/pandad.py index 2400f8cd6c..443c25a7e5 100755 --- a/selfdrive/pandad/pandad.py +++ b/selfdrive/pandad/pandad.py @@ -9,7 +9,7 @@ import subprocess from panda import Panda, PandaDFU, PandaProtocolMismatch, McuType, FW_PATH from openpilot.common.basedir import BASEDIR from openpilot.common.params import Params -from openpilot.system.hardware import HARDWARE +from openpilot.common.hardware import HARDWARE from openpilot.common.swaglog import cloudlog diff --git a/selfdrive/pandad/tests/test_pandad.py b/selfdrive/pandad/tests/test_pandad.py index 9dacd3f5a8..88022dda8d 100644 --- a/selfdrive/pandad/tests/test_pandad.py +++ b/selfdrive/pandad/tests/test_pandad.py @@ -7,8 +7,8 @@ from cereal import log from openpilot.common.gpio import gpio_set, gpio_init from panda import Panda, PandaDFU from openpilot.system.manager.process_config import managed_processes -from openpilot.system.hardware import HARDWARE -from openpilot.system.hardware.tici.pins import GPIO +from openpilot.common.hardware import HARDWARE +from openpilot.common.hardware.tici.pins import GPIO HERE = os.path.dirname(os.path.realpath(__file__)) diff --git a/selfdrive/selfdrived/events.py b/selfdrive/selfdrived/events.py index 99e25571bd..9a31e6f6b3 100755 --- a/selfdrive/selfdrived/events.py +++ b/selfdrive/selfdrived/events.py @@ -13,7 +13,7 @@ from openpilot.common.realtime import DT_CTRL from openpilot.selfdrive.locationd.calibrationd import MIN_SPEED_FILTER from openpilot.system.micd import SAMPLE_RATE, SAMPLE_BUFFER from openpilot.selfdrive.ui.feedback.feedbackd import FEEDBACK_MAX_DURATION -from openpilot.system.hardware import HARDWARE +from openpilot.common.hardware import HARDWARE AlertSize = log.SelfdriveState.AlertSize AlertStatus = log.SelfdriveState.AlertStatus diff --git a/selfdrive/selfdrived/selfdrived.py b/selfdrive/selfdrived/selfdrived.py index e376ea5c9c..5fe45d9274 100755 --- a/selfdrive/selfdrived/selfdrived.py +++ b/selfdrive/selfdrived/selfdrived.py @@ -22,7 +22,7 @@ from openpilot.selfdrive.selfdrived.state import StateMachine from openpilot.selfdrive.selfdrived.alertmanager import AlertManager, set_offroad_alert from openpilot.system.version import get_build_metadata -from openpilot.system.hardware import HARDWARE +from openpilot.common.hardware import HARDWARE REPLAY = "REPLAY" in os.environ SIMULATION = "SIMULATION" in os.environ diff --git a/selfdrive/test/process_replay/model_replay.py b/selfdrive/test/process_replay/model_replay.py index 266f66aaf2..3e5616e702 100755 --- a/selfdrive/test/process_replay/model_replay.py +++ b/selfdrive/test/process_replay/model_replay.py @@ -12,7 +12,7 @@ import numpy as np from openpilot.common.utils import tabulate from openpilot.common.git import get_commit -from openpilot.system.hardware import PC +from openpilot.common.hardware import PC from openpilot.tools.lib.openpilotci import get_url from openpilot.selfdrive.test.process_replay.compare_logs import compare_logs, format_diff from openpilot.selfdrive.test.process_replay.process_replay import get_process_config, replay_process diff --git a/selfdrive/test/process_replay/process_replay.py b/selfdrive/test/process_replay/process_replay.py index 1edbc3e2d6..2f198b0476 100755 --- a/selfdrive/test/process_replay/process_replay.py +++ b/selfdrive/test/process_replay/process_replay.py @@ -12,7 +12,7 @@ from typing import Any from collections.abc import Callable, Iterable from tqdm import tqdm import capnp -from openpilot.system.hardware.hw import Paths +from openpilot.common.hardware.hw import Paths import cereal.messaging as messaging from cereal import car diff --git a/selfdrive/test/test_onroad.py b/selfdrive/test/test_onroad.py index a08912fdef..99d0279c4c 100644 --- a/selfdrive/test/test_onroad.py +++ b/selfdrive/test/test_onroad.py @@ -18,7 +18,7 @@ from openpilot.common.timeout import Timeout from openpilot.common.params import Params from openpilot.selfdrive.selfdrived.events import EVENTS, ET from openpilot.selfdrive.test.helpers import set_params_enabled, release_only -from openpilot.system.hardware.hw import Paths +from openpilot.common.hardware.hw import Paths from openpilot.tools.lib.logreader import LogReader from openpilot.tools.lib.log_time_series import msgs_to_time_series @@ -68,7 +68,7 @@ PROCS = { "system.loggerd.deleter": 1.0, "./pandad": 19.0, "system.qcomgpsd.qcomgpsd": 1.0, - "system.hardware.tici.modem": 10.0, + "common.hardware.tici.modem": 10.0, } TIMINGS = { diff --git a/selfdrive/ui/installer/installer.cc b/selfdrive/ui/installer/installer.cc index 176c2d510f..07e824c649 100644 --- a/selfdrive/ui/installer/installer.cc +++ b/selfdrive/ui/installer/installer.cc @@ -5,7 +5,7 @@ #include "common/swaglog.h" #include "common/util.h" -#include "system/hardware/hw.h" +#include "common/hardware/hw.h" #include "raylib.h" int freshClone(); diff --git a/selfdrive/ui/mici/layouts/offroad_alerts.py b/selfdrive/ui/mici/layouts/offroad_alerts.py index de631f686c..47a2ddde95 100644 --- a/selfdrive/ui/mici/layouts/offroad_alerts.py +++ b/selfdrive/ui/mici/layouts/offroad_alerts.py @@ -7,7 +7,7 @@ from enum import IntEnum from openpilot.common.params import Params from openpilot.common.realtime import drop_realtime from openpilot.selfdrive.selfdrived.alertmanager import OFFROAD_ALERTS -from openpilot.system.hardware import HARDWARE +from openpilot.common.hardware import HARDWARE from openpilot.system.ui.widgets import Widget from openpilot.system.ui.widgets.label import UnifiedLabel from openpilot.system.ui.widgets.scroller import Scroller diff --git a/selfdrive/ui/mici/onroad/alert_renderer.py b/selfdrive/ui/mici/onroad/alert_renderer.py index 7b006aaaea..6505ca47c8 100644 --- a/selfdrive/ui/mici/onroad/alert_renderer.py +++ b/selfdrive/ui/mici/onroad/alert_renderer.py @@ -8,7 +8,7 @@ from dataclasses import dataclass from cereal import messaging, log, car from openpilot.selfdrive.ui.ui_state import ui_state from openpilot.common.filter_simple import BounceFilter, FirstOrderFilter -from openpilot.system.hardware import TICI +from openpilot.common.hardware import TICI from openpilot.system.ui.lib.application import gui_app, FontWeight from openpilot.system.ui.widgets import Widget from openpilot.system.ui.widgets.label import UnifiedLabel diff --git a/selfdrive/ui/mici/onroad/cameraview.py b/selfdrive/ui/mici/onroad/cameraview.py index 86dd95f466..991349dbf0 100644 --- a/selfdrive/ui/mici/onroad/cameraview.py +++ b/selfdrive/ui/mici/onroad/cameraview.py @@ -4,7 +4,7 @@ import pyray as rl from msgq.visionipc import VisionIpcClient, VisionStreamType, VisionBuf from openpilot.common.swaglog import cloudlog -from openpilot.system.hardware import TICI +from openpilot.common.hardware import TICI from openpilot.system.ui.lib.application import gui_app from openpilot.system.ui.lib.egl import init_egl, create_egl_image, destroy_egl_image, bind_egl_image_to_texture, EGLImage from openpilot.system.ui.widgets import Widget diff --git a/selfdrive/ui/onroad/alert_renderer.py b/selfdrive/ui/onroad/alert_renderer.py index a81fbfc440..cfb4bf6616 100644 --- a/selfdrive/ui/onroad/alert_renderer.py +++ b/selfdrive/ui/onroad/alert_renderer.py @@ -3,7 +3,7 @@ import pyray as rl from dataclasses import dataclass from cereal import messaging, log from openpilot.selfdrive.ui.ui_state import ui_state -from openpilot.system.hardware import TICI +from openpilot.common.hardware import TICI from openpilot.system.ui.lib.application import gui_app, FontWeight from openpilot.system.ui.lib.multilang import tr from openpilot.system.ui.lib.text_measure import measure_text_cached diff --git a/selfdrive/ui/onroad/cameraview.py b/selfdrive/ui/onroad/cameraview.py index 53c2ff8b0b..846bf20bbc 100644 --- a/selfdrive/ui/onroad/cameraview.py +++ b/selfdrive/ui/onroad/cameraview.py @@ -4,7 +4,7 @@ import pyray as rl from msgq.visionipc import VisionIpcClient, VisionStreamType, VisionBuf from openpilot.common.swaglog import cloudlog -from openpilot.system.hardware import TICI +from openpilot.common.hardware import TICI from openpilot.system.ui.lib.application import gui_app from openpilot.system.ui.lib.egl import init_egl, create_egl_image, destroy_egl_image, bind_egl_image_to_texture, EGLImage from openpilot.system.ui.widgets import Widget diff --git a/selfdrive/ui/soundd.py b/selfdrive/ui/soundd.py index a6f5d2fc27..ca5c824c29 100644 --- a/selfdrive/ui/soundd.py +++ b/selfdrive/ui/soundd.py @@ -12,7 +12,7 @@ from openpilot.common.utils import retry from openpilot.common.swaglog import cloudlog from openpilot.system import micd -from openpilot.system.hardware import HARDWARE +from openpilot.common.hardware import HARDWARE SAMPLE_RATE = 48000 SAMPLE_BUFFER = 4096 # (approx 100ms) diff --git a/selfdrive/ui/ui.py b/selfdrive/ui/ui.py index e01ddb2513..fc7e40920a 100755 --- a/selfdrive/ui/ui.py +++ b/selfdrive/ui/ui.py @@ -3,7 +3,7 @@ import os import time from cereal import messaging -from openpilot.system.hardware import TICI +from openpilot.common.hardware import TICI from openpilot.common.realtime import Priority, config_realtime_process, set_core_affinity from openpilot.system.ui.lib.application import gui_app from openpilot.selfdrive.ui.layouts.main import MainLayout diff --git a/selfdrive/ui/ui_state.py b/selfdrive/ui/ui_state.py index 643054e508..d5b0142744 100644 --- a/selfdrive/ui/ui_state.py +++ b/selfdrive/ui/ui_state.py @@ -10,7 +10,7 @@ from openpilot.common.realtime import drop_realtime from openpilot.common.swaglog import cloudlog from openpilot.selfdrive.ui.lib.prime_state import PrimeState from openpilot.system.ui.lib.application import gui_app -from openpilot.system.hardware import HARDWARE, PC +from openpilot.common.hardware import HARDWARE, PC BACKLIGHT_OFFROAD = 65 if HARDWARE.get_device_type() == "mici" else 50 PARAM_UPDATE_TIME = 1 / 5.0 diff --git a/selfdrive/ui/widgets/offroad_alerts.py b/selfdrive/ui/widgets/offroad_alerts.py index 110ca714a9..88ccc5df7e 100644 --- a/selfdrive/ui/widgets/offroad_alerts.py +++ b/selfdrive/ui/widgets/offroad_alerts.py @@ -4,7 +4,7 @@ from abc import ABC, abstractmethod from collections.abc import Callable from dataclasses import dataclass from openpilot.common.params import Params -from openpilot.system.hardware import HARDWARE +from openpilot.common.hardware import HARDWARE from openpilot.system.ui.lib.application import gui_app, FontWeight, FONT_SCALE from openpilot.system.ui.lib.multilang import tr from openpilot.system.ui.lib.scroll_panel import GuiScrollPanel diff --git a/system/athena/athenad.py b/system/athena/athenad.py index 6350b8a891..697819d0ad 100755 --- a/system/athena/athenad.py +++ b/system/athena/athenad.py @@ -35,11 +35,11 @@ from openpilot.common.api import Api, get_key_pair from openpilot.common.utils import CallbackReader, get_upload_stream from openpilot.common.params import Params from openpilot.common.realtime import set_core_affinity -from openpilot.system.hardware import HARDWARE, PC +from openpilot.common.hardware import HARDWARE, PC from openpilot.system.loggerd.xattr_cache import getxattr, setxattr from openpilot.common.swaglog import cloudlog from openpilot.system.version import get_build_metadata -from openpilot.system.hardware.hw import Paths +from openpilot.common.hardware.hw import Paths ATHENA_HOST = os.getenv('ATHENA_HOST', 'wss://athena.comma.ai') diff --git a/system/athena/manage_athenad.py b/system/athena/manage_athenad.py index ee63606b66..11fd11d431 100755 --- a/system/athena/manage_athenad.py +++ b/system/athena/manage_athenad.py @@ -6,7 +6,7 @@ from multiprocessing import Process from openpilot.common.params import Params from openpilot.system.manager.process import launcher from openpilot.common.swaglog import cloudlog -from openpilot.system.hardware import HARDWARE +from openpilot.common.hardware import HARDWARE from openpilot.system.version import get_build_metadata ATHENA_MGR_PID_PARAM = "AthenadPid" diff --git a/system/athena/registration.py b/system/athena/registration.py index 8548a544f5..0e8d4bc49e 100755 --- a/system/athena/registration.py +++ b/system/athena/registration.py @@ -10,8 +10,8 @@ from openpilot.common.api import api_get, get_key_pair from openpilot.common.params import Params from openpilot.common.spinner import Spinner from openpilot.selfdrive.selfdrived.alertmanager import set_offroad_alert -from openpilot.system.hardware import HARDWARE, PC -from openpilot.system.hardware.hw import Paths +from openpilot.common.hardware import HARDWARE, PC +from openpilot.common.hardware.hw import Paths from openpilot.common.swaglog import cloudlog diff --git a/system/athena/tests/test_athenad.py b/system/athena/tests/test_athenad.py index 33b0113b32..0e3ae68d4e 100644 --- a/system/athena/tests/test_athenad.py +++ b/system/athena/tests/test_athenad.py @@ -22,7 +22,7 @@ from openpilot.system.athena import athenad from openpilot.system.athena.athenad import MAX_RETRY_COUNT, UPLOAD_SESS, dispatcher from openpilot.system.athena.tests.helpers import HTTPRequestHandler, MockWebsocket, MockApi, EchoSocket from openpilot.selfdrive.test.helpers import http_server_context -from openpilot.system.hardware.hw import Paths +from openpilot.common.hardware.hw import Paths def seed_athena_server(host, port): diff --git a/system/athena/tests/test_athenad_ping.py b/system/athena/tests/test_athenad_ping.py index 8ff1e37a5d..7f44263162 100644 --- a/system/athena/tests/test_athenad_ping.py +++ b/system/athena/tests/test_athenad_ping.py @@ -8,7 +8,7 @@ from openpilot.common.params import Params from openpilot.common.timeout import Timeout from openpilot.system.athena import athenad from openpilot.system.manager.helpers import write_onroad_params -from openpilot.system.hardware import TICI +from openpilot.common.hardware import TICI TIMEOUT_TOLERANCE = 20 # seconds diff --git a/system/athena/tests/test_registration.py b/system/athena/tests/test_registration.py index f5d900d4db..bb1523de80 100644 --- a/system/athena/tests/test_registration.py +++ b/system/athena/tests/test_registration.py @@ -5,7 +5,7 @@ from pathlib import Path from openpilot.common.params import Params from openpilot.system.athena.registration import register, UNREGISTERED_DONGLE_ID from openpilot.system.athena.tests.helpers import MockResponse -from openpilot.system.hardware.hw import Paths +from openpilot.common.hardware.hw import Paths class TestRegistration: diff --git a/system/camerad/snapshot.py b/system/camerad/snapshot.py index ec6cbc8ad3..241f027044 100755 --- a/system/camerad/snapshot.py +++ b/system/camerad/snapshot.py @@ -9,7 +9,7 @@ import cereal.messaging as messaging from msgq.visionipc import VisionIpcClient, VisionStreamType from openpilot.common.params import Params from openpilot.common.realtime import DT_MDL -from openpilot.system.hardware import PC +from openpilot.common.hardware import PC from openpilot.selfdrive.selfdrived.alertmanager import set_offroad_alert from openpilot.system.manager.process_config import managed_processes diff --git a/system/hardware/fan_controller.py b/system/hardware/fan_controller.py index eafde599ad..869fe19c3d 100755 --- a/system/hardware/fan_controller.py +++ b/system/hardware/fan_controller.py @@ -2,7 +2,7 @@ import numpy as np from openpilot.common.pid import PIDController -from openpilot.system.hardware import HARDWARE +from openpilot.common.hardware import HARDWARE # raise fan setpoint on tici/tizi to reduce noise # after raising LMH threshold in AGNOS 18.1 to prevent CPU throttling diff --git a/system/hardware/hardwared.py b/system/hardware/hardwared.py index d047ee37cd..f8a9d3adde 100755 --- a/system/hardware/hardwared.py +++ b/system/hardware/hardwared.py @@ -17,7 +17,7 @@ from openpilot.common.filter_simple import FirstOrderFilter from openpilot.common.params import Params from openpilot.common.realtime import DT_HW from openpilot.selfdrive.selfdrived.alertmanager import set_offroad_alert -from openpilot.system.hardware import HARDWARE, TICI, PC +from openpilot.common.hardware import HARDWARE, TICI, PC from openpilot.system.loggerd.config import get_available_percent from openpilot.system.statsd import statlog from openpilot.common.swaglog import cloudlog diff --git a/system/hardware/power_monitoring.py b/system/hardware/power_monitoring.py index 161b5d23ef..ca43d9007b 100644 --- a/system/hardware/power_monitoring.py +++ b/system/hardware/power_monitoring.py @@ -2,7 +2,7 @@ import time import threading from openpilot.common.params import Params -from openpilot.system.hardware import HARDWARE +from openpilot.common.hardware import HARDWARE from openpilot.common.swaglog import cloudlog from openpilot.system.statsd import statlog diff --git a/system/hardware/tici/__init__.py b/system/hardware/tici/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/system/hardware/tici/agnos.json b/system/hardware/tici/agnos.json deleted file mode 100644 index 07e2079ec9..0000000000 --- a/system/hardware/tici/agnos.json +++ /dev/null @@ -1,84 +0,0 @@ -[ - { - "name": "xbl", - "url": "https://commadist.azureedge.net/agnosupdate/xbl-e8acf2a9cc7f0ce84cb803bfea9477f765c0d7b4daf26048e59651b9e6a7bfbb.img.xz", - "hash": "e8acf2a9cc7f0ce84cb803bfea9477f765c0d7b4daf26048e59651b9e6a7bfbb", - "hash_raw": "e8acf2a9cc7f0ce84cb803bfea9477f765c0d7b4daf26048e59651b9e6a7bfbb", - "size": 3282256, - "sparse": false, - "full_check": true, - "has_ab": true, - "ondevice_hash": "bea7f1a24428c3ededf672fa4fc78baf180cfbd8aafb77c974655b38517283e3" - }, - { - "name": "xbl_config", - "url": "https://commadist.azureedge.net/agnosupdate/xbl_config-758552ecf92b5569677197783bf0ccb73d7f961685308e45d3276ac9dd974f85.img.xz", - "hash": "758552ecf92b5569677197783bf0ccb73d7f961685308e45d3276ac9dd974f85", - "hash_raw": "758552ecf92b5569677197783bf0ccb73d7f961685308e45d3276ac9dd974f85", - "size": 98124, - "sparse": false, - "full_check": true, - "has_ab": true, - "ondevice_hash": "fb18cde08a98a168961ecd357e92474823046752b94e112f59fe51a6acd7197d" - }, - { - "name": "abl", - "url": "https://commadist.azureedge.net/agnosupdate/abl-b6fba807b9bcd66a31f2afb0eba5163ec239693ad32e2e4200f6c356adfe098c.img.xz", - "hash": "b6fba807b9bcd66a31f2afb0eba5163ec239693ad32e2e4200f6c356adfe098c", - "hash_raw": "b6fba807b9bcd66a31f2afb0eba5163ec239693ad32e2e4200f6c356adfe098c", - "size": 274432, - "sparse": false, - "full_check": true, - "has_ab": true, - "ondevice_hash": "b6fba807b9bcd66a31f2afb0eba5163ec239693ad32e2e4200f6c356adfe098c" - }, - { - "name": "aop", - "url": "https://commadist.azureedge.net/agnosupdate/aop-78b2287ca219a0811b3004c523fa0f4749e4d1fd92be3aba61699305b7943ad1.img.xz", - "hash": "78b2287ca219a0811b3004c523fa0f4749e4d1fd92be3aba61699305b7943ad1", - "hash_raw": "78b2287ca219a0811b3004c523fa0f4749e4d1fd92be3aba61699305b7943ad1", - "size": 184364, - "sparse": false, - "full_check": true, - "has_ab": true, - "ondevice_hash": "6c9135446bd3fc075fcee59b887a12e49029ab1f98ed8d6d1e32c73569d47de3" - }, - { - "name": "devcfg", - "url": "https://commadist.azureedge.net/agnosupdate/devcfg-f71df3a86958c093ba3969254c4db025187eef9385427f1ade946742939b43cc.img.xz", - "hash": "f71df3a86958c093ba3969254c4db025187eef9385427f1ade946742939b43cc", - "hash_raw": "f71df3a86958c093ba3969254c4db025187eef9385427f1ade946742939b43cc", - "size": 40336, - "sparse": false, - "full_check": true, - "has_ab": true, - "ondevice_hash": "2a67971602012c1b43544964709da13c322786b456a8e78568b117e8b1540ce3" - }, - { - "name": "boot", - "url": "https://commadist.azureedge.net/agnosupdate/boot-8806802b195a5b1396a3ae8dd92a8b7711dc522f6aceafd820e871bae5c8a6d8.img.xz", - "hash": "8806802b195a5b1396a3ae8dd92a8b7711dc522f6aceafd820e871bae5c8a6d8", - "hash_raw": "8806802b195a5b1396a3ae8dd92a8b7711dc522f6aceafd820e871bae5c8a6d8", - "size": 17487872, - "sparse": false, - "full_check": true, - "has_ab": true, - "ondevice_hash": "edca8bee1531e66953d107eeceeed2dc7b3ca46417e49d55508f94e58bf95db8" - }, - { - "name": "system", - "url": "https://commadist.azureedge.net/agnosupdate/system-ef0d879302cb29e72110e9c8d3f947c830fd7d37c8192744fc9dbea1af78501f.img.xz", - "hash": "78acfe16a7b62a3a91fc7a81f40a693e4468cec1c69df7d0b1e550aacc646113", - "hash_raw": "ef0d879302cb29e72110e9c8d3f947c830fd7d37c8192744fc9dbea1af78501f", - "size": 4718592000, - "sparse": true, - "full_check": false, - "has_ab": true, - "ondevice_hash": "743142c5a898f27b2a1029cca42c8a5d5d1fc0096414422b850fe84c8d0b8342", - "alt": { - "hash": "ef0d879302cb29e72110e9c8d3f947c830fd7d37c8192744fc9dbea1af78501f", - "url": "https://commadist.azureedge.net/agnosupdate/system-ef0d879302cb29e72110e9c8d3f947c830fd7d37c8192744fc9dbea1af78501f.img", - "size": 4718592000 - } - } -] \ No newline at end of file diff --git a/system/hardware/tici/agnos.json b/system/hardware/tici/agnos.json new file mode 120000 index 0000000000..ffee992f25 --- /dev/null +++ b/system/hardware/tici/agnos.json @@ -0,0 +1 @@ +../../../common/hardware/tici/agnos.json \ No newline at end of file diff --git a/system/hardware/tici/tests/__init__.py b/system/hardware/tici/tests/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/system/loggerd/config.py b/system/loggerd/config.py index e1c47c768d..0a8ee98390 100644 --- a/system/loggerd/config.py +++ b/system/loggerd/config.py @@ -1,5 +1,5 @@ import os -from openpilot.system.hardware.hw import Paths +from openpilot.common.hardware.hw import Paths CAMERA_FPS = 20 diff --git a/system/loggerd/deleter.py b/system/loggerd/deleter.py index eb8fd35f21..6e9ac3657b 100755 --- a/system/loggerd/deleter.py +++ b/system/loggerd/deleter.py @@ -2,7 +2,7 @@ import os import shutil import threading -from openpilot.system.hardware.hw import Paths +from openpilot.common.hardware.hw import Paths from openpilot.common.swaglog import cloudlog from openpilot.system.loggerd.config import get_available_bytes, get_available_percent from openpilot.system.loggerd.uploader import listdir_by_creation diff --git a/system/loggerd/logger.h b/system/loggerd/logger.h index 18d07b5f38..dba7c2f44c 100644 --- a/system/loggerd/logger.h +++ b/system/loggerd/logger.h @@ -6,7 +6,7 @@ #include "cereal/messaging/messaging.h" #include "common/util.h" -#include "system/hardware/hw.h" +#include "common/hardware/hw.h" #include "system/loggerd/zstd_writer.h" constexpr int LOG_COMPRESSION_LEVEL = 10; diff --git a/system/loggerd/loggerd.h b/system/loggerd/loggerd.h index c5f253d8f5..7877e9dbb8 100644 --- a/system/loggerd/loggerd.h +++ b/system/loggerd/loggerd.h @@ -6,7 +6,7 @@ #include "cereal/messaging/messaging.h" #include "cereal/services.h" #include "msgq/visionipc/visionipc_client.h" -#include "system/hardware/hw.h" +#include "common/hardware/hw.h" #include "common/params.h" #include "common/swaglog.h" #include "common/util.h" diff --git a/system/loggerd/tests/loggerd_tests_common.py b/system/loggerd/tests/loggerd_tests_common.py index fd071486df..757b61d17e 100644 --- a/system/loggerd/tests/loggerd_tests_common.py +++ b/system/loggerd/tests/loggerd_tests_common.py @@ -6,7 +6,7 @@ from pathlib import Path import openpilot.system.loggerd.deleter as deleter import openpilot.system.loggerd.uploader as uploader from openpilot.common.params import Params -from openpilot.system.hardware.hw import Paths +from openpilot.common.hardware.hw import Paths from openpilot.system.loggerd.xattr_cache import setxattr diff --git a/system/loggerd/tests/test_encoder.py b/system/loggerd/tests/test_encoder.py index 2b74fe2276..416c158ed3 100644 --- a/system/loggerd/tests/test_encoder.py +++ b/system/loggerd/tests/test_encoder.py @@ -12,10 +12,10 @@ from tqdm import trange from openpilot.common.params import Params from openpilot.common.timeout import Timeout -from openpilot.system.hardware import TICI +from openpilot.common.hardware import TICI from openpilot.system.manager.process_config import managed_processes from openpilot.tools.lib.logreader import LogReader -from openpilot.system.hardware.hw import Paths +from openpilot.common.hardware.hw import Paths SEGMENT_LENGTH = 2 FULL_SIZE = 2507572 diff --git a/system/loggerd/tests/test_loggerd.py b/system/loggerd/tests/test_loggerd.py index 9fd1b2d434..882de583b4 100644 --- a/system/loggerd/tests/test_loggerd.py +++ b/system/loggerd/tests/test_loggerd.py @@ -15,8 +15,8 @@ from cereal.services import SERVICE_LIST from openpilot.common.basedir import BASEDIR from openpilot.common.params import Params from openpilot.common.timeout import Timeout -from openpilot.system.hardware.hw import Paths -from openpilot.system.hardware import TICI +from openpilot.common.hardware.hw import Paths +from openpilot.common.hardware import TICI from openpilot.system.loggerd.xattr_cache import getxattr from openpilot.system.loggerd.deleter import PRESERVE_ATTR_NAME, PRESERVE_ATTR_VALUE from openpilot.system.manager.process_config import managed_processes diff --git a/system/loggerd/tests/test_uploader.py b/system/loggerd/tests/test_uploader.py index 562bc068eb..eec85eda2e 100644 --- a/system/loggerd/tests/test_uploader.py +++ b/system/loggerd/tests/test_uploader.py @@ -4,7 +4,7 @@ import threading import logging import json from pathlib import Path -from openpilot.system.hardware.hw import Paths +from openpilot.common.hardware.hw import Paths from openpilot.common.swaglog import cloudlog from openpilot.system.loggerd.uploader import main, UPLOAD_ATTR_NAME, UPLOAD_ATTR_VALUE diff --git a/system/loggerd/uploader.py b/system/loggerd/uploader.py index 8ac38b6df6..809a302b6f 100755 --- a/system/loggerd/uploader.py +++ b/system/loggerd/uploader.py @@ -15,7 +15,7 @@ from openpilot.common.api import Api from openpilot.common.utils import get_upload_stream from openpilot.common.params import Params from openpilot.common.realtime import set_core_affinity -from openpilot.system.hardware.hw import Paths +from openpilot.common.hardware.hw import Paths from openpilot.system.loggerd.xattr_cache import getxattr, setxattr from openpilot.common.swaglog import cloudlog diff --git a/system/logmessaged.py b/system/logmessaged.py index c095c26192..a64a849b02 100755 --- a/system/logmessaged.py +++ b/system/logmessaged.py @@ -4,7 +4,7 @@ from typing import NoReturn import cereal.messaging as messaging from openpilot.common.logging_extra import SwagLogFileFormatter -from openpilot.system.hardware.hw import Paths +from openpilot.common.hardware.hw import Paths from openpilot.common.swaglog import get_file_handler diff --git a/system/manager/build.py b/system/manager/build.py index 470cfccdaa..75a7dc63eb 100755 --- a/system/manager/build.py +++ b/system/manager/build.py @@ -6,7 +6,7 @@ import subprocess from openpilot.common.basedir import BASEDIR from openpilot.common.spinner import Spinner from openpilot.common.text_window import TextWindow -from openpilot.system.hardware import HARDWARE, AGNOS +from openpilot.common.hardware import HARDWARE, AGNOS def build() -> None: spinner = Spinner() diff --git a/system/manager/manager.py b/system/manager/manager.py index d8f9a3d8fa..cb84b9b8ca 100755 --- a/system/manager/manager.py +++ b/system/manager/manager.py @@ -12,14 +12,14 @@ import openpilot.system.sentry as sentry from openpilot.common.utils import atomic_write from openpilot.common.params import Params, ParamKeyFlag from openpilot.common.text_window import TextWindow -from openpilot.system.hardware import HARDWARE +from openpilot.common.hardware import HARDWARE from openpilot.system.manager.helpers import unblock_stdout, write_onroad_params, save_bootlog from openpilot.system.manager.process import ensure_running from openpilot.system.manager.process_config import managed_processes from openpilot.system.athena.registration import register, UNREGISTERED_DONGLE_ID from openpilot.common.swaglog import cloudlog, add_file_handler from openpilot.system.version import get_build_metadata -from openpilot.system.hardware.hw import Paths +from openpilot.common.hardware.hw import Paths def manager_init() -> None: diff --git a/system/manager/process_config.py b/system/manager/process_config.py index a442e4f860..a099bc753a 100644 --- a/system/manager/process_config.py +++ b/system/manager/process_config.py @@ -4,7 +4,7 @@ import platform from cereal import car from openpilot.common.params import Params -from openpilot.system.hardware import PC, TICI +from openpilot.common.hardware import PC, TICI from openpilot.system.manager.process import PythonProcess, NativeProcess, DaemonProcess WEBCAM = os.getenv("USE_WEBCAM") is not None @@ -112,7 +112,7 @@ procs = [ PythonProcess("lateral_maneuversd", "tools.lateral_maneuvers.lateral_maneuversd", lat_maneuver), PythonProcess("radard", "selfdrive.controls.radard", only_onroad), PythonProcess("hardwared", "system.hardware.hardwared", always_run), - PythonProcess("modem", "system.hardware.tici.modem", always_run, enabled=TICI), + PythonProcess("modem", "common.hardware.tici.modem", always_run, enabled=TICI), PythonProcess("tombstoned", "system.tombstoned", always_run, enabled=not PC), PythonProcess("updated", "system.updated.updated", only_offroad, enabled=not PC), PythonProcess("uploader", "system.loggerd.uploader", always_run), diff --git a/system/manager/test/test_manager.py b/system/manager/test/test_manager.py index 34d07c6724..73c66ff3fc 100644 --- a/system/manager/test/test_manager.py +++ b/system/manager/test/test_manager.py @@ -8,7 +8,7 @@ from openpilot.common.params import Params import openpilot.system.manager.manager as manager from openpilot.system.manager.process import ensure_running from openpilot.system.manager.process_config import managed_processes, procs -from openpilot.system.hardware import HARDWARE +from openpilot.common.hardware import HARDWARE os.environ['FAKEUPLOAD'] = "1" diff --git a/system/qcomgpsd/nmeaport.py b/system/qcomgpsd/nmeaport.py index 10b8516ed0..0e695b65e5 100644 --- a/system/qcomgpsd/nmeaport.py +++ b/system/qcomgpsd/nmeaport.py @@ -119,7 +119,7 @@ def process_nmea_port_messages(device:str="/dev/ttyUSB1") -> NoReturn: def main() -> NoReturn: from openpilot.common.gpio import gpio_init, gpio_set - from openpilot.system.hardware.tici.pins import GPIO + from openpilot.common.hardware.tici.pins import GPIO from openpilot.system.qcomgpsd.qcomgpsd import at_cmd try: diff --git a/system/qcomgpsd/qcomgpsd.py b/system/qcomgpsd/qcomgpsd.py index 7e0d304872..78731f434b 100755 --- a/system/qcomgpsd/qcomgpsd.py +++ b/system/qcomgpsd/qcomgpsd.py @@ -16,7 +16,7 @@ import cereal.messaging as messaging from openpilot.common.gpio import gpio_init, gpio_set from openpilot.common.utils import retry from openpilot.common.time_helpers import system_time_valid -from openpilot.system.hardware.tici.pins import GPIO +from openpilot.common.hardware.tici.pins import GPIO from openpilot.common.swaglog import cloudlog from openpilot.system.qcomgpsd.modemdiag import ModemDiag, DIAG_LOG_F, setup_logs, send_recv from openpilot.system.qcomgpsd.structs import (dict_unpacker, position_report, relist, diff --git a/system/sentry.py b/system/sentry.py index 47d64ba0fd..ee9f813e25 100644 --- a/system/sentry.py +++ b/system/sentry.py @@ -5,7 +5,7 @@ from sentry_sdk.integrations.threading import ThreadingIntegration from openpilot.common.params import Params from openpilot.system.athena.registration import is_registered_device -from openpilot.system.hardware import HARDWARE, PC +from openpilot.common.hardware import HARDWARE, PC from openpilot.common.swaglog import cloudlog from openpilot.system.version import get_build_metadata, get_version diff --git a/system/statsd.py b/system/statsd.py index 33e9e9912d..250780e018 100755 --- a/system/statsd.py +++ b/system/statsd.py @@ -10,9 +10,9 @@ from typing import NoReturn from openpilot.common.params import Params from cereal.messaging import SubMaster -from openpilot.system.hardware.hw import Paths +from openpilot.common.hardware.hw import Paths from openpilot.common.swaglog import cloudlog -from openpilot.system.hardware import HARDWARE +from openpilot.common.hardware import HARDWARE from openpilot.common.utils import atomic_write from openpilot.system.version import get_build_metadata from openpilot.system.loggerd.config import STATS_DIR_FILE_LIMIT, STATS_SOCKET, STATS_FLUSH_TIME_S diff --git a/system/tests/test_logmessaged.py b/system/tests/test_logmessaged.py index 9ccc8ef53b..92bcd9d1ad 100644 --- a/system/tests/test_logmessaged.py +++ b/system/tests/test_logmessaged.py @@ -4,7 +4,7 @@ import time import cereal.messaging as messaging from openpilot.system.manager.process_config import managed_processes -from openpilot.system.hardware.hw import Paths +from openpilot.common.hardware.hw import Paths from openpilot.common.swaglog import cloudlog, ipchandler diff --git a/system/tombstoned.py b/system/tombstoned.py index 5bcced2666..88a2a879ed 100755 --- a/system/tombstoned.py +++ b/system/tombstoned.py @@ -10,7 +10,7 @@ import glob from typing import NoReturn import openpilot.system.sentry as sentry -from openpilot.system.hardware.hw import Paths +from openpilot.common.hardware.hw import Paths from openpilot.common.swaglog import cloudlog from openpilot.system.version import get_build_metadata diff --git a/system/ubloxd/pigeond.py b/system/ubloxd/pigeond.py index e458a9d65f..fe2634e333 100755 --- a/system/ubloxd/pigeond.py +++ b/system/ubloxd/pigeond.py @@ -12,9 +12,9 @@ from cereal import messaging from openpilot.common.time_helpers import system_time_valid from openpilot.common.params import Params from openpilot.common.swaglog import cloudlog -from openpilot.system.hardware import TICI +from openpilot.common.hardware import TICI from openpilot.common.gpio import gpio_init, gpio_set -from openpilot.system.hardware.tici.pins import GPIO +from openpilot.common.hardware.tici.pins import GPIO UBLOX_TTY = "/dev/ttyHS0" diff --git a/system/ubloxd/tests/test_pigeond.py b/system/ubloxd/tests/test_pigeond.py index 202820e412..fb979a9372 100644 --- a/system/ubloxd/tests/test_pigeond.py +++ b/system/ubloxd/tests/test_pigeond.py @@ -6,7 +6,7 @@ from cereal.services import SERVICE_LIST from openpilot.common.gpio import gpio_read from openpilot.selfdrive.test.helpers import with_processes from openpilot.system.manager.process_config import managed_processes -from openpilot.system.hardware.tici.pins import GPIO +from openpilot.common.hardware.tici.pins import GPIO # TODO: test TTFF when we have good A-GNSS diff --git a/system/ui/lib/application.py b/system/ui/lib/application.py index 2513086edd..bd2c9dfcd3 100644 --- a/system/ui/lib/application.py +++ b/system/ui/lib/application.py @@ -18,7 +18,7 @@ from pathlib import Path from typing import NamedTuple from importlib.resources import as_file, files from openpilot.common.swaglog import cloudlog -from openpilot.system.hardware import HARDWARE, PC +from openpilot.common.hardware import HARDWARE, PC from openpilot.system.ui.lib.multilang import multilang from openpilot.common.realtime import Ratekeeper diff --git a/system/ui/lib/scroll_panel2.py b/system/ui/lib/scroll_panel2.py index 7fae60119c..b6193672c4 100644 --- a/system/ui/lib/scroll_panel2.py +++ b/system/ui/lib/scroll_panel2.py @@ -5,7 +5,7 @@ from collections.abc import Callable from enum import Enum from typing import cast from openpilot.system.ui.lib.application import gui_app, MouseEvent -from openpilot.system.hardware import TICI +from openpilot.common.hardware import TICI from collections import deque MIN_VELOCITY = 10 # px/s, changes from auto scroll to steady state diff --git a/system/ui/mici_reset.py b/system/ui/mici_reset.py index 9cc6e7f3f8..90de7843f9 100755 --- a/system/ui/mici_reset.py +++ b/system/ui/mici_reset.py @@ -7,7 +7,7 @@ from enum import IntEnum import pyray as rl -from openpilot.system.hardware import HARDWARE, PC +from openpilot.common.hardware import HARDWARE, PC from openpilot.system.ui.lib.application import gui_app from openpilot.system.ui.widgets.scroller import Scroller from openpilot.system.ui.mici_setup import GreyBigButton, FailedPage diff --git a/system/ui/mici_setup.py b/system/ui/mici_setup.py index 2a23e4c4fd..4df127f1b5 100755 --- a/system/ui/mici_setup.py +++ b/system/ui/mici_setup.py @@ -13,7 +13,7 @@ import pyray as rl from cereal import log from openpilot.common.filter_simple import BounceFilter -from openpilot.system.hardware import HARDWARE, TICI +from openpilot.common.hardware import HARDWARE, TICI from openpilot.common.realtime import config_realtime_process, set_core_affinity from openpilot.common.swaglog import cloudlog from openpilot.common.time_helpers import system_time_valid diff --git a/system/ui/mici_updater.py b/system/ui/mici_updater.py index 8437e6fa60..a072354cf0 100755 --- a/system/ui/mici_updater.py +++ b/system/ui/mici_updater.py @@ -5,7 +5,7 @@ import threading import pyray as rl from openpilot.common.realtime import config_realtime_process, set_core_affinity -from openpilot.system.hardware import HARDWARE, TICI +from openpilot.common.hardware import HARDWARE, TICI from openpilot.common.swaglog import cloudlog from openpilot.system.ui.lib.application import gui_app, FontWeight from openpilot.system.ui.widgets.nav_widget import NavWidget diff --git a/system/ui/text.py b/system/ui/text.py index 17e8a507cb..f6bcf4eddf 100755 --- a/system/ui/text.py +++ b/system/ui/text.py @@ -2,7 +2,7 @@ import re import sys import pyray as rl -from openpilot.system.hardware import HARDWARE, PC +from openpilot.common.hardware import HARDWARE, PC from openpilot.system.ui.lib.application import BIG_UI, gui_app from openpilot.system.ui.lib.scroll_panel import GuiScrollPanel from openpilot.system.ui.lib.text_measure import measure_text_cached diff --git a/system/ui/tici_reset.py b/system/ui/tici_reset.py index a6603d547e..cb5441a406 100755 --- a/system/ui/tici_reset.py +++ b/system/ui/tici_reset.py @@ -7,7 +7,7 @@ from enum import IntEnum import pyray as rl -from openpilot.system.hardware import PC +from openpilot.common.hardware import PC from openpilot.system.ui.lib.application import gui_app, FontWeight, FONT_SCALE from openpilot.system.ui.widgets import Widget from openpilot.system.ui.widgets.button import Button, ButtonStyle diff --git a/system/ui/tici_setup.py b/system/ui/tici_setup.py index 9eefb6af53..0e0c6fdc7c 100755 --- a/system/ui/tici_setup.py +++ b/system/ui/tici_setup.py @@ -11,7 +11,7 @@ from enum import IntEnum import pyray as rl from cereal import log -from openpilot.system.hardware import HARDWARE +from openpilot.common.hardware import HARDWARE from openpilot.system.ui.lib.scroll_panel import GuiScrollPanel from openpilot.system.ui.lib.application import gui_app, FontWeight, FONT_SCALE from openpilot.system.ui.widgets import DialogResult, Widget diff --git a/system/ui/tici_updater.py b/system/ui/tici_updater.py index 3a3b0987d0..27cf6579a8 100755 --- a/system/ui/tici_updater.py +++ b/system/ui/tici_updater.py @@ -5,7 +5,7 @@ import threading import pyray as rl from enum import IntEnum -from openpilot.system.hardware import HARDWARE +from openpilot.common.hardware import HARDWARE from openpilot.system.ui.lib.application import gui_app, FontWeight, FONT_SCALE from openpilot.system.ui.lib.wifi_manager import WifiManager from openpilot.system.ui.widgets import Widget diff --git a/system/updated/tests/test_base.py b/system/updated/tests/test_base.py index db38bfa840..315aebbbe6 100644 --- a/system/updated/tests/test_base.py +++ b/system/updated/tests/test_base.py @@ -233,10 +233,10 @@ class ParamsBaseUpdateTest(TestBaseUpdate): self.setup_basedir_release("release3") with self.additional_context(), processes_context(["updated"]) as [updated]: - mocker.patch("openpilot.system.hardware.AGNOS", "True") - mocker.patch("openpilot.system.hardware.tici.hardware.Tici.get_os_version", "1.2") - mocker.patch("openpilot.system.hardware.tici.agnos.get_target_slot_number") - mocker.patch("openpilot.system.hardware.tici.agnos.flash_agnos_update") + mocker.patch("openpilot.common.hardware.AGNOS", "True") + mocker.patch("openpilot.common.hardware.tici.hardware.Tici.get_os_version", "1.2") + mocker.patch("openpilot.common.hardware.tici.agnos.get_target_slot_number") + mocker.patch("openpilot.common.hardware.tici.agnos.flash_agnos_update") self._test_params("release3", False, False) self.wait_for_idle() diff --git a/system/updated/updated.py b/system/updated/updated.py index 25821e3732..e40bc44e76 100755 --- a/system/updated/updated.py +++ b/system/updated/updated.py @@ -18,7 +18,7 @@ from openpilot.common.time_helpers import system_time_valid from openpilot.common.markdown import parse_markdown from openpilot.common.swaglog import cloudlog from openpilot.selfdrive.selfdrived.alertmanager import set_offroad_alert -from openpilot.system.hardware import AGNOS, HARDWARE +from openpilot.common.hardware import AGNOS, HARDWARE from openpilot.system.version import get_build_metadata LOCK_FILE = os.getenv("UPDATER_LOCK_FILE", "/tmp/safe_staging_overlay.lock") @@ -204,7 +204,7 @@ def finalize_update() -> None: def handle_agnos_update() -> None: - from openpilot.system.hardware.tici.agnos import flash_agnos_update, get_target_slot_number + from openpilot.common.hardware.tici.agnos import flash_agnos_update, get_target_slot_number cur_version = HARDWARE.get_os_version() updated_version = run(["bash", "-c", r"unset AGNOS_VERSION && source launch_env.sh && \ diff --git a/tools/jotpluggler/app.cc b/tools/jotpluggler/app.cc index 22a9f9021c..f80443e569 100644 --- a/tools/jotpluggler/app.cc +++ b/tools/jotpluggler/app.cc @@ -3,7 +3,7 @@ #include "tools/jotpluggler/common.h" #include "tools/jotpluggler/internal.h" #include "tools/jotpluggler/map.h" -#include "system/hardware/hw.h" +#include "common/hardware/hw.h" #include "imgui_impl_glfw.h" #include "imgui_internal.h" diff --git a/tools/jotpluggler/layout.cc b/tools/jotpluggler/layout.cc index 0d3b82c254..bf2a3f208c 100644 --- a/tools/jotpluggler/layout.cc +++ b/tools/jotpluggler/layout.cc @@ -1,5 +1,5 @@ #include "tools/jotpluggler/internal.h" -#include "system/hardware/hw.h" +#include "common/hardware/hw.h" #include diff --git a/tools/joystick/joystick_control.py b/tools/joystick/joystick_control.py index b1f14043b7..d9d4f0156f 100755 --- a/tools/joystick/joystick_control.py +++ b/tools/joystick/joystick_control.py @@ -8,7 +8,7 @@ from inputs import UnpluggedError, get_gamepad from cereal import messaging from openpilot.common.params import Params from openpilot.common.realtime import Ratekeeper -from openpilot.system.hardware import HARDWARE +from openpilot.common.hardware import HARDWARE from openpilot.tools.lib.kbhit import KBHit EXPO = 0.4 diff --git a/tools/lateral_maneuvers/generate_report.py b/tools/lateral_maneuvers/generate_report.py index c2ef7e99ea..5db486a70d 100755 --- a/tools/lateral_maneuvers/generate_report.py +++ b/tools/lateral_maneuvers/generate_report.py @@ -15,7 +15,7 @@ from cereal import car from openpilot.common.filter_simple import FirstOrderFilter from openpilot.selfdrive.controls.lib.latcontrol_torque import LP_FILTER_CUTOFF_HZ from openpilot.tools.lib.logreader import LogReader -from openpilot.system.hardware.hw import Paths +from openpilot.common.hardware.hw import Paths from openpilot.common.constants import CV from openpilot.tools.longitudinal_maneuvers.generate_report import format_car_params diff --git a/tools/lib/auth_config.py b/tools/lib/auth_config.py index c4e7b6261b..5966bd34a9 100644 --- a/tools/lib/auth_config.py +++ b/tools/lib/auth_config.py @@ -1,6 +1,6 @@ import json import os -from openpilot.system.hardware.hw import Paths +from openpilot.common.hardware.hw import Paths class MissingAuthConfigError(Exception): diff --git a/tools/lib/file_downloader.py b/tools/lib/file_downloader.py index 5b31a5894c..68061b201e 100755 --- a/tools/lib/file_downloader.py +++ b/tools/lib/file_downloader.py @@ -17,7 +17,7 @@ import sys import tempfile import shutil -from openpilot.system.hardware.hw import Paths +from openpilot.common.hardware.hw import Paths from openpilot.tools.lib.api import CommaApi, UnauthorizedError, APIError from openpilot.tools.lib.auth_config import get_token from openpilot.tools.lib.url_file import URLFile diff --git a/tools/lib/tests/test_caching.py b/tools/lib/tests/test_caching.py index cb14098e6d..0753ef1d3c 100644 --- a/tools/lib/tests/test_caching.py +++ b/tools/lib/tests/test_caching.py @@ -6,7 +6,7 @@ import tempfile import pytest from openpilot.selfdrive.test.helpers import http_server_context -from openpilot.system.hardware.hw import Paths +from openpilot.common.hardware.hw import Paths from openpilot.tools.lib.url_file import URLFile, prune_cache import openpilot.tools.lib.url_file as url_file_module diff --git a/tools/lib/url_file.py b/tools/lib/url_file.py index de12070465..3f72429b94 100644 --- a/tools/lib/url_file.py +++ b/tools/lib/url_file.py @@ -9,7 +9,7 @@ from urllib3.response import BaseHTTPResponse from urllib3.util import Timeout from openpilot.common.utils import atomic_write -from openpilot.system.hardware.hw import Paths +from openpilot.common.hardware.hw import Paths from urllib3.exceptions import MaxRetryError # Cache chunk size diff --git a/tools/longitudinal_maneuvers/generate_report.py b/tools/longitudinal_maneuvers/generate_report.py index 32bdb5b1c4..dbd9f6db91 100755 --- a/tools/longitudinal_maneuvers/generate_report.py +++ b/tools/longitudinal_maneuvers/generate_report.py @@ -12,7 +12,7 @@ import matplotlib.pyplot as plt from openpilot.common.utils import tabulate from openpilot.tools.lib.logreader import LogReader -from openpilot.system.hardware.hw import Paths +from openpilot.common.hardware.hw import Paths def format_car_params(CP): diff --git a/tools/replay/framereader.cc b/tools/replay/framereader.cc index a643f0d3a7..52db658add 100644 --- a/tools/replay/framereader.cc +++ b/tools/replay/framereader.cc @@ -9,7 +9,7 @@ #include "libyuv.h" #include "tools/replay/py_downloader.h" #include "tools/replay/util.h" -#include "system/hardware/hw.h" +#include "common/hardware/hw.h" #ifdef __APPLE__ #define HW_DEVICE_TYPE AV_HWDEVICE_TYPE_VIDEOTOOLBOX diff --git a/tools/replay/route.cc b/tools/replay/route.cc index df4fa813cf..1560f1dce8 100644 --- a/tools/replay/route.cc +++ b/tools/replay/route.cc @@ -5,7 +5,7 @@ #include #include "json11/json11.hpp" -#include "system/hardware/hw.h" +#include "common/hardware/hw.h" #include "tools/replay/py_downloader.h" #include "tools/replay/replay.h" #include "tools/replay/util.h" diff --git a/tools/scripts/ssh.py b/tools/scripts/ssh.py index e454afb691..33eac4081d 100755 --- a/tools/scripts/ssh.py +++ b/tools/scripts/ssh.py @@ -14,7 +14,7 @@ if __name__ == "__main__": parser.add_argument("device", help="device name or dongle id") parser.add_argument("--host", help="ssh jump server host", default="ssh.comma.ai") parser.add_argument("--port", help="ssh jump server port", default=22, type=int) - parser.add_argument("--key", help="ssh key", default=os.path.join(BASEDIR, "system/hardware/tici/id_rsa")) + parser.add_argument("--key", help="ssh key", default=os.path.join(BASEDIR, "common/hardware/tici/id_rsa")) parser.add_argument("--debug", help="enable debug output", action="store_true") args = parser.parse_args() diff --git a/tools/scripts/uiview.py b/tools/scripts/uiview.py index e558406b09..a8d50e7f99 100755 --- a/tools/scripts/uiview.py +++ b/tools/scripts/uiview.py @@ -4,7 +4,7 @@ import time from cereal import car, log, messaging from openpilot.common.params import Params from openpilot.system.manager.process_config import managed_processes -from openpilot.system.hardware import HARDWARE +from openpilot.common.hardware import HARDWARE if __name__ == "__main__": CP = car.CarParams(notCar=True, wheelbase=1, steerRatio=10) From e0e9f1a4d3a81be461e960e804f85735faa40fed Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Sat, 20 Jun 2026 16:12:54 -0700 Subject: [PATCH 063/151] move test_power_draw.py --- Jenkinsfile | 2 +- .../hardware/tici/tests => selfdrive/test}/test_power_draw.py | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename {common/hardware/tici/tests => selfdrive/test}/test_power_draw.py (100%) diff --git a/Jenkinsfile b/Jenkinsfile index 6291f5beb0..90f86b1967 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -210,7 +210,7 @@ node { 'HW + Unit Tests': { deviceStage("tizi-hardware", "tizi-common", ["UNSAFE=1"], [ step("build", "cd system/manager && ./build.py"), - step("test power draw", "pytest -s common/hardware/tici/tests/test_power_draw.py"), + step("test power draw", "pytest -s selfdrive/test//test_power_draw.py"), step("test encoder", "LD_LIBRARY_PATH=/usr/local/lib pytest system/loggerd/tests/test_encoder.py", [diffPaths: ["system/loggerd/"]]), step("test manager", "pytest system/manager/test/test_manager.py"), ]) diff --git a/common/hardware/tici/tests/test_power_draw.py b/selfdrive/test/test_power_draw.py similarity index 100% rename from common/hardware/tici/tests/test_power_draw.py rename to selfdrive/test/test_power_draw.py From 7cee534b722799aa067166987efef99d634c7c99 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Sat, 20 Jun 2026 16:16:15 -0700 Subject: [PATCH 064/151] rm dead scripts --- scripts/cell.sh | 3 --- scripts/stop_updater.sh | 7 ------- scripts/usb.sh | 12 ------------ scripts/usbgpu/benchmark.sh | 26 -------------------------- 4 files changed, 48 deletions(-) delete mode 100755 scripts/cell.sh delete mode 100755 scripts/stop_updater.sh delete mode 100755 scripts/usb.sh delete mode 100755 scripts/usbgpu/benchmark.sh diff --git a/scripts/cell.sh b/scripts/cell.sh deleted file mode 100755 index 310a9694fd..0000000000 --- a/scripts/cell.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env bash -nmcli connection modify --temporary esim ipv4.route-metric 1 ipv6.route-metric 1 -nmcli con up esim diff --git a/scripts/stop_updater.sh b/scripts/stop_updater.sh deleted file mode 100755 index 703b363928..0000000000 --- a/scripts/stop_updater.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env sh - -# Stop updater -pkill -2 -f system.updated.updated - -# Remove pending update -rm -f /data/safe_staging/finalized/.overlay_consistent diff --git a/scripts/usb.sh b/scripts/usb.sh deleted file mode 100755 index 5796cfa028..0000000000 --- a/scripts/usb.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env bash - -# testing the GPU box - -export XDG_CACHE_HOME=/data/tinycache -mkdir -p $XDG_CACHE_HOME - -cd /data/openpilot/tinygrad_repo/examples -while true; do - AMD=1 AMD_IFACE=usb python ./beautiful_cartpole.py - sleep 1 -done diff --git a/scripts/usbgpu/benchmark.sh b/scripts/usbgpu/benchmark.sh deleted file mode 100755 index 04a76d054e..0000000000 --- a/scripts/usbgpu/benchmark.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env bash -set -e - -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" -cd $DIR/../../tinygrad_repo - -GREEN='\033[0;32m' -NC='\033[0m' - - -#export DEBUG=2 -export PYTHONPATH=. -export AM_RESET=1 -export AMD=1 -export AMD_IFACE=USB -export AMD_LLVM=1 - -python3 -m unittest -q --buffer test.test_tiny.TestTiny.test_plus \ - > /tmp/test_tiny.log 2>&1 || (cat /tmp/test_tiny.log; exit 1) -printf "${GREEN}Booted in ${SECONDS}s${NC}\n" -printf "${GREEN}=============${NC}\n" - -printf "\n\n" -printf "${GREEN}Transfer speeds:${NC}\n" -printf "${GREEN}================${NC}\n" -python3 test/external/external_test_usb_asm24.py TestDevCopySpeeds From f0831e549b4a015eb60f5740453b12b88da886b3 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Sat, 20 Jun 2026 16:20:05 -0700 Subject: [PATCH 065/151] rm dead updated tests --- system/updated/tests/test_base.py | 259 --------------------------- system/updated/tests/test_git.py | 22 --- system/updated/tests/test_updated.py | 38 ---- 3 files changed, 319 deletions(-) delete mode 100644 system/updated/tests/test_base.py delete mode 100644 system/updated/tests/test_git.py delete mode 100644 system/updated/tests/test_updated.py diff --git a/system/updated/tests/test_base.py b/system/updated/tests/test_base.py deleted file mode 100644 index 315aebbbe6..0000000000 --- a/system/updated/tests/test_base.py +++ /dev/null @@ -1,259 +0,0 @@ -import os -import pathlib -import shutil -import signal -import stat -import subprocess -import tempfile -import time -import pytest - -from openpilot.common.params import Params -from openpilot.system.manager.process import ManagerProcess -from openpilot.selfdrive.test.helpers import processes_context - - -def get_consistent_flag(path: str) -> bool: - consistent_file = pathlib.Path(os.path.join(path, ".overlay_consistent")) - return consistent_file.is_file() - - -def run(args, **kwargs): - return subprocess.check_output(args, **kwargs) - - -def update_release(directory, name, version, agnos_version, release_notes): - with open(directory / "RELEASES.md", "w") as f: - f.write(release_notes) - - (directory / "common").mkdir(exist_ok=True) - - with open(directory / "common" / "version.h", "w") as f: - f.write(f'#define COMMA_VERSION "{version}"') - - launch_env = directory / "launch_env.sh" - with open(launch_env, "w") as f: - f.write(f'export AGNOS_VERSION="{agnos_version}"') - - st = os.stat(launch_env) - os.chmod(launch_env, st.st_mode | stat.S_IEXEC) - - test_symlink = directory / "test_symlink" - if not os.path.exists(str(test_symlink)): - os.symlink("common/version.h", test_symlink) - - -def get_version(path: str) -> str: - with open(os.path.join(path, "common", "version.h")) as f: - return f.read().split('"')[1] - - -@pytest.mark.slow # TODO: can we test overlayfs in GHA? -class TestBaseUpdate: - @classmethod - def setup_class(cls): - if "Base" in cls.__name__: - pytest.skip() - - def setup_method(self): - self.tmpdir = tempfile.mkdtemp() - - run(["sudo", "mount", "-t", "tmpfs", "tmpfs", self.tmpdir]) # overlayfs doesn't work inside of docker unless this is a tmpfs - - self.mock_update_path = pathlib.Path(self.tmpdir) - - self.params = Params() - - self.basedir = self.mock_update_path / "openpilot" - self.basedir.mkdir() - - self.staging_root = self.mock_update_path / "safe_staging" - self.staging_root.mkdir() - - self.remote_dir = self.mock_update_path / "remote" - self.remote_dir.mkdir() - - os.environ["UPDATER_STAGING_ROOT"] = str(self.staging_root) - os.environ["UPDATER_LOCK_FILE"] = str(self.mock_update_path / "safe_staging_overlay.lock") - - self.MOCK_RELEASES = { - "release3": ("0.1.2", "1.2", "0.1.2 release notes"), - "master": ("0.1.3", "1.2", "0.1.3 release notes"), - } - - @pytest.fixture(autouse=True) - def mock_basedir(self, mocker): - mocker.patch("openpilot.common.basedir.BASEDIR", self.basedir) - - def set_target_branch(self, branch): - self.params.put("UpdaterTargetBranch", branch, block=True) - - def setup_basedir_release(self, release): - self.params = Params() - self.set_target_branch(release) - - def update_remote_release(self, release): - raise NotImplementedError("") - - def setup_remote_release(self, release): - raise NotImplementedError("") - - def additional_context(self): - raise NotImplementedError("") - - def teardown_method(self): - try: - run(["sudo", "umount", "-l", str(self.staging_root / "merged")]) - run(["sudo", "umount", "-l", self.tmpdir]) - shutil.rmtree(self.tmpdir) - except Exception: - print("cleanup failed...") - - def wait_for_condition(self, condition, timeout=12): - start = time.monotonic() - while True: - waited = time.monotonic() - start - if condition(): - print(f"waited {waited}s for condition ") - return waited - - if waited > timeout: - raise TimeoutError("timed out waiting for condition") - - time.sleep(1) - - def _test_finalized_update(self, branch, version, agnos_version, release_notes): - assert get_version(str(self.staging_root / "finalized")) == version - assert get_consistent_flag(str(self.staging_root / "finalized")) - assert os.access(str(self.staging_root / "finalized" / "launch_env.sh"), os.X_OK) - - with open(self.staging_root / "finalized" / "test_symlink") as f: - assert version in f.read() - -class ParamsBaseUpdateTest(TestBaseUpdate): - def _test_finalized_update(self, branch, version, agnos_version, release_notes): - assert self.params.get("UpdaterNewDescription").startswith(f"{version} / {branch}") - assert self.params.get("UpdaterNewReleaseNotes") == f"{release_notes}\n".encode() - super()._test_finalized_update(branch, version, agnos_version, release_notes) - - def send_check_for_updates_signal(self, updated: ManagerProcess): - updated.signal(signal.SIGUSR1.value) - - def send_download_signal(self, updated: ManagerProcess): - updated.signal(signal.SIGHUP.value) - - def _test_params(self, branch, fetch_available, update_available): - assert self.params.get("UpdaterTargetBranch") == branch - assert self.params.get_bool("UpdaterFetchAvailable") == fetch_available - assert self.params.get_bool("UpdateAvailable") == update_available - - def wait_for_idle(self): - self.wait_for_condition(lambda: self.params.get("UpdaterState") == "idle") - - def wait_for_failed(self): - self.wait_for_condition(lambda: self.params.get("UpdateFailedCount") is not None and \ - self.params.get("UpdateFailedCount") > 0) - - def wait_for_fetch_available(self): - self.wait_for_condition(lambda: self.params.get_bool("UpdaterFetchAvailable")) - - def wait_for_update_available(self): - self.wait_for_condition(lambda: self.params.get_bool("UpdateAvailable")) - - def test_no_update(self): - # Start on release3, ensure we don't fetch any updates - self.setup_remote_release("release3") - self.setup_basedir_release("release3") - - with self.additional_context(), processes_context(["updated"]) as [updated]: - self._test_params("release3", False, False) - self.wait_for_idle() - self._test_params("release3", False, False) - - self.send_check_for_updates_signal(updated) - - self.wait_for_idle() - - self._test_params("release3", False, False) - - def test_new_release(self): - # Start on release3, simulate a release3 commit, ensure we fetch that update properly - self.setup_remote_release("release3") - self.setup_basedir_release("release3") - - with self.additional_context(), processes_context(["updated"]) as [updated]: - self._test_params("release3", False, False) - self.wait_for_idle() - self._test_params("release3", False, False) - - self.MOCK_RELEASES["release3"] = ("0.1.3", "1.2", "0.1.3 release notes") - self.update_remote_release("release3") - - self.send_check_for_updates_signal(updated) - - self.wait_for_fetch_available() - - self._test_params("release3", True, False) - - self.send_download_signal(updated) - - self.wait_for_update_available() - - self._test_params("release3", False, True) - self._test_finalized_update("release3", *self.MOCK_RELEASES["release3"]) - - def test_switch_branches(self): - # Start on release3, request to switch to master manually, ensure we switched - self.setup_remote_release("release3") - self.setup_remote_release("master") - self.setup_basedir_release("release3") - - with self.additional_context(), processes_context(["updated"]) as [updated]: - self._test_params("release3", False, False) - self.wait_for_idle() - self._test_params("release3", False, False) - - self.set_target_branch("master") - self.send_check_for_updates_signal(updated) - - self.wait_for_fetch_available() - - self._test_params("master", True, False) - - self.send_download_signal(updated) - - self.wait_for_update_available() - - self._test_params("master", False, True) - self._test_finalized_update("master", *self.MOCK_RELEASES["master"]) - - def test_agnos_update(self, mocker): - # Start on release3, push an update with an agnos change - self.setup_remote_release("release3") - self.setup_basedir_release("release3") - - with self.additional_context(), processes_context(["updated"]) as [updated]: - mocker.patch("openpilot.common.hardware.AGNOS", "True") - mocker.patch("openpilot.common.hardware.tici.hardware.Tici.get_os_version", "1.2") - mocker.patch("openpilot.common.hardware.tici.agnos.get_target_slot_number") - mocker.patch("openpilot.common.hardware.tici.agnos.flash_agnos_update") - - self._test_params("release3", False, False) - self.wait_for_idle() - self._test_params("release3", False, False) - - self.MOCK_RELEASES["release3"] = ("0.1.3", "1.3", "0.1.3 release notes") - self.update_remote_release("release3") - - self.send_check_for_updates_signal(updated) - - self.wait_for_fetch_available() - - self._test_params("release3", True, False) - - self.send_download_signal(updated) - - self.wait_for_update_available() - - self._test_params("release3", False, True) - self._test_finalized_update("release3", *self.MOCK_RELEASES["release3"]) diff --git a/system/updated/tests/test_git.py b/system/updated/tests/test_git.py deleted file mode 100644 index 5a5a27000b..0000000000 --- a/system/updated/tests/test_git.py +++ /dev/null @@ -1,22 +0,0 @@ -import contextlib -from openpilot.system.updated.tests.test_base import ParamsBaseUpdateTest, run, update_release - - -class TestUpdateDGitStrategy(ParamsBaseUpdateTest): - def update_remote_release(self, release): - update_release(self.remote_dir, release, *self.MOCK_RELEASES[release]) - run(["git", "add", "."], cwd=self.remote_dir) - run(["git", "commit", "-m", f"openpilot release {release}"], cwd=self.remote_dir) - - def setup_remote_release(self, release): - run(["git", "init"], cwd=self.remote_dir) - run(["git", "checkout", "-b", release], cwd=self.remote_dir) - self.update_remote_release(release) - - def setup_basedir_release(self, release): - super().setup_basedir_release(release) - run(["git", "clone", "-b", release, self.remote_dir, self.basedir]) - - @contextlib.contextmanager - def additional_context(self): - yield diff --git a/system/updated/tests/test_updated.py b/system/updated/tests/test_updated.py deleted file mode 100644 index 18ee0e706a..0000000000 --- a/system/updated/tests/test_updated.py +++ /dev/null @@ -1,38 +0,0 @@ -import pytest - -from openpilot.common.params import Params -from openpilot.system.updated.updated import Updater - - -@pytest.mark.parametrize(("device_type", "branch", "expected"), [ - ("tizi", "release3", "release-tizi"), - ("tizi", "release3-staging", "release-tizi-staging"), - ("mici", "release3", "release-mici"), - ("mici", "release3-staging", "release-mici-staging"), -]) -def test_target_branch_migration_from_current_branch(mocker, device_type, branch, expected): - params = Params() - params.remove("UpdaterTargetBranch") - - mocker.patch("openpilot.system.updated.updated.HARDWARE.get_device_type", return_value=device_type) - mocker.patch.object(Updater, "get_branch", return_value=branch) - - assert Updater().target_branch == expected - - -@pytest.mark.parametrize(("device_type", "branch", "expected"), [ - ("tizi", "release3", "release-tizi"), - ("tizi", "release3-staging", "release-tizi-staging"), - ("mici", "release3", "release-mici"), - ("mici", "release3-staging", "release-mici-staging"), -]) -def test_target_branch_migration_from_param(mocker, device_type, branch, expected): - params = Params() - params.put("UpdaterTargetBranch", branch, block=True) - - mocker.patch("openpilot.system.updated.updated.HARDWARE.get_device_type", return_value=device_type) - - try: - assert Updater().target_branch == expected - finally: - params.remove("UpdaterTargetBranch") From b871364e1f48af04113f05c0f6604a9c42f57ac7 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Sat, 20 Jun 2026 16:22:37 -0700 Subject: [PATCH 066/151] remove rest of docker (#38203) --- .dockerignore | 18 --------------- .github/workflows/prebuilt.yaml | 39 --------------------------------- Dockerfile.openpilot | 38 -------------------------------- selfdrive/test/.gitignore | 1 - selfdrive/test/docker_build.sh | 30 ------------------------- 5 files changed, 126 deletions(-) delete mode 100644 .dockerignore delete mode 100644 .github/workflows/prebuilt.yaml delete mode 100644 Dockerfile.openpilot delete mode 100755 selfdrive/test/docker_build.sh diff --git a/.dockerignore b/.dockerignore deleted file mode 100644 index 631ea04840..0000000000 --- a/.dockerignore +++ /dev/null @@ -1,18 +0,0 @@ -**/.git -.DS_Store -*.dylib -*.DSYM -*.d -*.pyc -*.pyo -.*.swp -.*.swo -.*.un~ -*.tmp -*.o -*.o-* -*.os -*.os-* - -venv/ -.venv/ diff --git a/.github/workflows/prebuilt.yaml b/.github/workflows/prebuilt.yaml deleted file mode 100644 index ecf1e8503a..0000000000 --- a/.github/workflows/prebuilt.yaml +++ /dev/null @@ -1,39 +0,0 @@ -name: prebuilt -on: - schedule: - - cron: '0 * * * *' - workflow_dispatch: - -env: - DOCKER_LOGIN: docker login ghcr.io -u ${{ github.actor }} -p ${{ secrets.GITHUB_TOKEN }} - BUILD: selfdrive/test/docker_build.sh - -jobs: - build_prebuilt: - name: build prebuilt - runs-on: ubuntu-latest - if: github.repository == 'commaai/openpilot' - env: - PUSH_IMAGE: true - permissions: - checks: read - contents: read - packages: write - steps: - - name: Wait for green check mark - if: ${{ github.event_name != 'workflow_dispatch' }} - uses: lewagon/wait-on-check-action@ccfb013c15c8afb7bf2b7c028fb74dc5a068cccc - with: - ref: master - wait-interval: 30 - running-workflow-name: 'build prebuilt' - repo-token: ${{ secrets.GITHUB_TOKEN }} - check-regexp: ^((?!.*(build master-ci|create badges).*).)*$ - - uses: actions/checkout@v6 - with: - submodules: true - - run: git lfs pull - - name: Build and Push docker image - run: | - $DOCKER_LOGIN - eval "$BUILD" diff --git a/Dockerfile.openpilot b/Dockerfile.openpilot deleted file mode 100644 index 72d874b022..0000000000 --- a/Dockerfile.openpilot +++ /dev/null @@ -1,38 +0,0 @@ -FROM ubuntu:24.04 - -ENV PYTHONUNBUFFERED=1 - -ENV DEBIAN_FRONTEND=noninteractive -RUN apt-get update && \ - apt-get install -y --no-install-recommends sudo tzdata locales && \ - rm -rf /var/lib/apt/lists/* - -RUN sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && locale-gen -ENV LANG=en_US.UTF-8 -ENV LANGUAGE=en_US:en -ENV LC_ALL=en_US.UTF-8 - -ENV NVIDIA_VISIBLE_DEVICES=all -ENV NVIDIA_DRIVER_CAPABILITIES=graphics,utility,compute - -ARG USER=batman -ARG USER_UID=1001 -RUN useradd -m -s /bin/bash -u $USER_UID $USER -RUN usermod -aG sudo $USER -RUN echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers -USER $USER - -ENV OPENPILOT_PATH=/home/$USER/openpilot -RUN mkdir -p ${OPENPILOT_PATH} -WORKDIR ${OPENPILOT_PATH} - -COPY --chown=$USER . ${OPENPILOT_PATH}/ - -ENV UV_BIN="/home/$USER/.local/bin/" -ENV VIRTUAL_ENV=${OPENPILOT_PATH}/.venv -ENV PATH="$UV_BIN:$VIRTUAL_ENV/bin:$PATH" -RUN tools/setup_dependencies.sh && \ - sudo rm -rf /var/lib/apt/lists/* - -USER root -RUN git config --global --add safe.directory '*' diff --git a/selfdrive/test/.gitignore b/selfdrive/test/.gitignore index b8c6bebd95..377696afae 100644 --- a/selfdrive/test/.gitignore +++ b/selfdrive/test/.gitignore @@ -1,5 +1,4 @@ out/ -docker_out/ process_replay/diff.txt process_replay/model_diff.txt diff --git a/selfdrive/test/docker_build.sh b/selfdrive/test/docker_build.sh deleted file mode 100755 index 8d1fa82249..0000000000 --- a/selfdrive/test/docker_build.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/env bash -set -e - -SCRIPT_DIR=$(dirname "$0") -OPENPILOT_DIR=$SCRIPT_DIR/../../ - -DOCKER_IMAGE=openpilot -DOCKER_FILE=Dockerfile.openpilot -DOCKER_REGISTRY=ghcr.io/commaai -COMMIT_SHA=$(git rev-parse HEAD) - -if [ -n "$TARGET_ARCHITECTURE" ]; then - PLATFORM="linux/$TARGET_ARCHITECTURE" - TAG_SUFFIX="-$TARGET_ARCHITECTURE" -else - PLATFORM="linux/$(uname -m)" - TAG_SUFFIX="" -fi - -LOCAL_TAG=$DOCKER_IMAGE$TAG_SUFFIX -REMOTE_TAG=$DOCKER_REGISTRY/$LOCAL_TAG -REMOTE_SHA_TAG=$DOCKER_REGISTRY/$LOCAL_TAG:$COMMIT_SHA - -DOCKER_BUILDKIT=1 docker buildx build --provenance false --pull --platform $PLATFORM --load -t $DOCKER_IMAGE:latest -t $REMOTE_TAG -t $LOCAL_TAG -f $OPENPILOT_DIR/$DOCKER_FILE $OPENPILOT_DIR - -if [ -n "$PUSH_IMAGE" ]; then - docker push $REMOTE_TAG - docker tag $REMOTE_TAG $REMOTE_SHA_TAG - docker push $REMOTE_SHA_TAG -fi From fddb9fb31c406081a33d9f86d933d2ce880156a0 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Sat, 20 Jun 2026 16:35:28 -0700 Subject: [PATCH 067/151] remove statsd (#38204) --- common/hardware/hw.py | 7 -- selfdrive/test/test_onroad.py | 1 - system/athena/athenad.py | 30 ----- system/hardware/hardwared.py | 21 ---- system/hardware/power_monitoring.py | 2 - system/loggerd/config.py | 4 - system/manager/process_config.py | 1 - system/statsd.py | 183 ---------------------------- 8 files changed, 249 deletions(-) delete mode 100755 system/statsd.py diff --git a/common/hardware/hw.py b/common/hardware/hw.py index 2c649db9eb..1041a17c1c 100644 --- a/common/hardware/hw.py +++ b/common/hardware/hw.py @@ -44,13 +44,6 @@ class Paths: else: return "/persist/" - @staticmethod - def stats_root() -> str: - if PC: - return str(Path(Paths.comma_home()) / "stats") - else: - return "/data/stats/" - @staticmethod def config_root() -> str: if PC: diff --git a/selfdrive/test/test_onroad.py b/selfdrive/test/test_onroad.py index 99d0279c4c..974859a23c 100644 --- a/selfdrive/test/test_onroad.py +++ b/selfdrive/test/test_onroad.py @@ -63,7 +63,6 @@ PROCS = { "system.micd": 5.0, "system.timed": 0, "selfdrive.pandad.pandad": 0, - "system.statsd": 1.0, "system.loggerd.uploader": 15.0, "system.loggerd.deleter": 1.0, "./pandad": 19.0, diff --git a/system/athena/athenad.py b/system/athena/athenad.py index 697819d0ad..a322652e3e 100755 --- a/system/athena/athenad.py +++ b/system/athena/athenad.py @@ -12,7 +12,6 @@ import random import select import socket import sys -import tempfile import threading import time from dataclasses import asdict, dataclass, replace @@ -186,7 +185,6 @@ def handle_long_poll(ws: WebSocket, exit_event: threading.Event | None) -> None: threading.Thread(target=upload_handler, args=(end_event,), name='upload_handler3'), threading.Thread(target=upload_handler, args=(end_event,), name='upload_handler4'), threading.Thread(target=log_handler, args=(end_event,), name='log_handler'), - threading.Thread(target=stat_handler, args=(end_event,), name='stat_handler'), ] + [ threading.Thread(target=jsonrpc_handler, args=(end_event,), name=f'worker_{x}') for x in range(HANDLER_THREADS) @@ -695,34 +693,6 @@ def log_handler(end_event: threading.Event) -> None: cloudlog.exception("athena.log_handler.exception") -def stat_handler(end_event: threading.Event) -> None: - STATS_DIR = Paths.stats_root() - last_scan = 0.0 - - while not end_event.is_set(): - curr_scan = time.monotonic() - try: - if curr_scan - last_scan > 10: - stat_filenames = list(filter(lambda name: not name.startswith(tempfile.gettempprefix()), os.listdir(STATS_DIR))) - if len(stat_filenames) > 0: - stat_path = os.path.join(STATS_DIR, stat_filenames[0]) - with open(stat_path) as f: - jsonrpc = { - "method": "storeStats", - "params": { - "stats": f.read() - }, - "jsonrpc": "2.0", - "id": stat_filenames[0] - } - send_queue_push(json.dumps(jsonrpc), SEND_PRIORITY_LOW) - os.remove(stat_path) - last_scan = curr_scan - except Exception: - cloudlog.exception("athena.stat_handler.exception") - time.sleep(0.1) - - def ws_proxy_recv(ws: WebSocket, local_sock: socket.socket, ssock: socket.socket, end_event: threading.Event, global_end_event: threading.Event) -> None: while not (end_event.is_set() or global_end_event.is_set()): try: diff --git a/system/hardware/hardwared.py b/system/hardware/hardwared.py index f8a9d3adde..70f31d5f7d 100755 --- a/system/hardware/hardwared.py +++ b/system/hardware/hardwared.py @@ -19,7 +19,6 @@ from openpilot.common.realtime import DT_HW from openpilot.selfdrive.selfdrived.alertmanager import set_offroad_alert from openpilot.common.hardware import HARDWARE, TICI, PC from openpilot.system.loggerd.config import get_available_percent -from openpilot.system.statsd import statlog from openpilot.common.swaglog import cloudlog from openpilot.system.hardware.power_monitoring import PowerMonitoring from openpilot.system.hardware.fan_controller import FanController @@ -361,11 +360,9 @@ def hardware_thread(end_event, hw_queue) -> None: msg.deviceState.offroadPowerUsageUwh = power_monitor.get_power_used() msg.deviceState.carBatteryCapacityUwh = max(0, power_monitor.get_car_battery_capacity()) current_power_draw = HARDWARE.get_current_power_draw() - statlog.sample("power_draw", current_power_draw) msg.deviceState.powerDrawW = current_power_draw som_power_draw = HARDWARE.get_som_power_draw() - statlog.sample("som_power_draw", som_power_draw) msg.deviceState.somPowerDrawW = som_power_draw # Check if we need to shut down @@ -383,24 +380,6 @@ def hardware_thread(end_event, hw_queue) -> None: msg.deviceState.thermalStatus = thermal_status pm.send("deviceState", msg) - # Log to statsd - statlog.gauge("free_space_percent", msg.deviceState.freeSpacePercent) - statlog.gauge("gpu_usage_percent", msg.deviceState.gpuUsagePercent) - statlog.gauge("memory_usage_percent", msg.deviceState.memoryUsagePercent) - for i, usage in enumerate(msg.deviceState.cpuUsagePercent): - statlog.gauge(f"cpu{i}_usage_percent", usage) - for i, temp in enumerate(msg.deviceState.cpuTempC): - statlog.gauge(f"cpu{i}_temperature", temp) - for i, temp in enumerate(msg.deviceState.gpuTempC): - statlog.gauge(f"gpu{i}_temperature", temp) - statlog.gauge("memory_temperature", msg.deviceState.memoryTempC) - for i, temp in enumerate(msg.deviceState.pmicTempC): - statlog.gauge(f"pmic{i}_temperature", temp) - for i, temp in enumerate(last_hw_state.modem_temps): - statlog.gauge(f"modem_temperature{i}", temp) - statlog.gauge("fan_speed_percent_desired", msg.deviceState.fanSpeedPercentDesired) - statlog.gauge("screen_brightness_percent", msg.deviceState.screenBrightnessPercent) - # report to server once every 10 minutes, or every 1s when thermally blocked rising_edge_started = should_start and not should_start_prev status_packet_interval = 1. if show_alert else 600. diff --git a/system/hardware/power_monitoring.py b/system/hardware/power_monitoring.py index ca43d9007b..72a8c6848c 100644 --- a/system/hardware/power_monitoring.py +++ b/system/hardware/power_monitoring.py @@ -4,7 +4,6 @@ import threading from openpilot.common.params import Params from openpilot.common.hardware import HARDWARE from openpilot.common.swaglog import cloudlog -from openpilot.system.statsd import statlog CAR_VOLTAGE_LOW_PASS_K = 0.011 # LPF gain for 45s tau (dt/tau / (dt/tau + 1)) @@ -50,7 +49,6 @@ class PowerMonitoring: # Low-pass battery voltage self.car_voltage_instant_mV = voltage self.car_voltage_mV = ((voltage * CAR_VOLTAGE_LOW_PASS_K) + (self.car_voltage_mV * (1 - CAR_VOLTAGE_LOW_PASS_K))) - statlog.gauge("car_voltage", self.car_voltage_mV / 1e3) # Cap the car battery power and save it in a param every 10-ish seconds self.car_battery_capacity_uWh = max(self.car_battery_capacity_uWh, 0) diff --git a/system/loggerd/config.py b/system/loggerd/config.py index 0a8ee98390..c2d213e906 100644 --- a/system/loggerd/config.py +++ b/system/loggerd/config.py @@ -5,10 +5,6 @@ from openpilot.common.hardware.hw import Paths CAMERA_FPS = 20 SEGMENT_LENGTH = 60 -STATS_DIR_FILE_LIMIT = 10000 -STATS_SOCKET = "ipc:///tmp/stats" -STATS_FLUSH_TIME_S = 60 - def get_available_percent(default: float) -> float: try: statvfs = os.statvfs(Paths.log_root()) diff --git a/system/manager/process_config.py b/system/manager/process_config.py index a099bc753a..f610d1c786 100644 --- a/system/manager/process_config.py +++ b/system/manager/process_config.py @@ -116,7 +116,6 @@ procs = [ PythonProcess("tombstoned", "system.tombstoned", always_run, enabled=not PC), PythonProcess("updated", "system.updated.updated", only_offroad, enabled=not PC), PythonProcess("uploader", "system.loggerd.uploader", always_run), - PythonProcess("statsd", "system.statsd", always_run), PythonProcess("feedbackd", "selfdrive.ui.feedback.feedbackd", only_onroad), # debug procs diff --git a/system/statsd.py b/system/statsd.py deleted file mode 100755 index 250780e018..0000000000 --- a/system/statsd.py +++ /dev/null @@ -1,183 +0,0 @@ -#!/usr/bin/env python3 -import os -import zmq -import time -import uuid -from pathlib import Path -from collections import defaultdict -from datetime import datetime, UTC -from typing import NoReturn - -from openpilot.common.params import Params -from cereal.messaging import SubMaster -from openpilot.common.hardware.hw import Paths -from openpilot.common.swaglog import cloudlog -from openpilot.common.hardware import HARDWARE -from openpilot.common.utils import atomic_write -from openpilot.system.version import get_build_metadata -from openpilot.system.loggerd.config import STATS_DIR_FILE_LIMIT, STATS_SOCKET, STATS_FLUSH_TIME_S - - -class METRIC_TYPE: - GAUGE = 'g' - SAMPLE = 'sa' - -class StatLog: - def __init__(self): - self.pid = None - self.zctx = None - self.sock = None - - def connect(self) -> None: - self.zctx = zmq.Context() - self.sock = self.zctx.socket(zmq.PUSH) - self.sock.setsockopt(zmq.LINGER, 10) - self.sock.connect(STATS_SOCKET) - self.pid = os.getpid() - - def __del__(self): - if self.sock is not None: - self.sock.close() - if self.zctx is not None: - self.zctx.term() - - def _send(self, metric: str) -> None: - if os.getpid() != self.pid: - self.connect() - - try: - self.sock.send_string(metric, zmq.NOBLOCK) - except zmq.error.Again: - # drop :/ - pass - - def gauge(self, name: str, value: float) -> None: - self._send(f"{name}:{value}|{METRIC_TYPE.GAUGE}") - - # Samples will be recorded in a buffer and at aggregation time, - # statistical properties will be logged (mean, count, percentiles, ...) - def sample(self, name: str, value: float): - self._send(f"{name}:{value}|{METRIC_TYPE.SAMPLE}") - - -def main() -> NoReturn: - dongle_id = Params().get("DongleId") - def get_influxdb_line(measurement: str, value: float | dict[str, float], timestamp: datetime, tags: dict) -> str: - res = f"{measurement}" - for k, v in tags.items(): - res += f",{k}={str(v)}" - res += " " - - if isinstance(value, float): - value = {'value': value} - - for k, v in value.items(): - res += f"{k}={v}," - - res += f"dongle_id=\"{dongle_id}\" {int(timestamp.timestamp() * 1e9)}\n" - return res - - # open statistics socket - ctx = zmq.Context.instance() - sock = ctx.socket(zmq.PULL) - sock.bind(STATS_SOCKET) - - STATS_DIR = Paths.stats_root() - - # initialize stats directory - Path(STATS_DIR).mkdir(parents=True, exist_ok=True) - - build_metadata = get_build_metadata() - - # initialize tags - tags = { - 'started': False, - 'version': build_metadata.openpilot.version, - 'branch': build_metadata.channel, - 'dirty': build_metadata.openpilot.is_dirty, - 'origin': build_metadata.openpilot.git_normalized_origin, - 'deviceType': HARDWARE.get_device_type(), - } - - # subscribe to deviceState for started state - sm = SubMaster(['deviceState']) - - idx = 0 - boot_uid = str(uuid.uuid4())[:8] - last_flush_time = time.monotonic() - gauges = {} - samples: dict[str, list[float]] = defaultdict(list) - try: - while True: - started_prev = sm['deviceState'].started - sm.update() - - # Update metrics - while True: - try: - metric = sock.recv_string(zmq.NOBLOCK) - try: - metric_type = metric.split('|')[1] - metric_name = metric.split(':')[0] - metric_value = float(metric.split('|')[0].split(':')[1]) - - if metric_type == METRIC_TYPE.GAUGE: - gauges[metric_name] = metric_value - elif metric_type == METRIC_TYPE.SAMPLE: - samples[metric_name].append(metric_value) - else: - cloudlog.event("unknown metric type", metric_type=metric_type) - except Exception: - cloudlog.event("malformed metric", metric=metric) - except zmq.error.Again: - break - - # flush when started state changes or after FLUSH_TIME_S - if (time.monotonic() > last_flush_time + STATS_FLUSH_TIME_S) or (sm['deviceState'].started != started_prev): - result = "" - current_time = datetime.now(UTC) - tags['started'] = sm['deviceState'].started - - for key, value in gauges.items(): - result += get_influxdb_line(f"gauge.{key}", value, current_time, tags) - - for key, values in samples.items(): - values.sort() - sample_count = len(values) - sample_sum = sum(values) - - stats = { - 'count': sample_count, - 'min': values[0], - 'max': values[-1], - 'mean': sample_sum / sample_count, - } - for percentile in [0.05, 0.5, 0.95]: - value = values[int(round(percentile * (sample_count - 1)))] - stats[f"p{int(percentile * 100)}"] = value - - result += get_influxdb_line(f"sample.{key}", stats, current_time, tags) - - # clear intermediate data - gauges.clear() - samples.clear() - last_flush_time = time.monotonic() - - # check that we aren't filling up the drive - if len(os.listdir(STATS_DIR)) < STATS_DIR_FILE_LIMIT: - if len(result) > 0: - stats_path = os.path.join(STATS_DIR, f"{boot_uid}_{idx}") - with atomic_write(stats_path) as f: - f.write(result) - idx += 1 - else: - cloudlog.error("stats dir full") - finally: - sock.close() - ctx.term() - - -if __name__ == "__main__": - main() -else: - statlog = StatLog() From ad5151b38b540e08a01c87029c3ddb0979ba4fdf Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Sat, 20 Jun 2026 16:55:48 -0700 Subject: [PATCH 068/151] single IsOffroad param (#38205) --- common/params_keys.h | 1 - system/athena/athenad.py | 4 ++-- system/athena/tests/test_athenad_ping.py | 5 ++--- system/manager/helpers.py | 6 ------ system/manager/manager.py | 8 ++++---- tools/scripts/car/ecu_addrs.py | 4 ++-- tools/scripts/car/fw_versions.py | 4 ++-- 7 files changed, 12 insertions(+), 20 deletions(-) diff --git a/common/params_keys.h b/common/params_keys.h index 01b051545a..5b0f6e99c9 100644 --- a/common/params_keys.h +++ b/common/params_keys.h @@ -61,7 +61,6 @@ inline static std::unordered_map keys = { {"IsLiveStreaming", {CLEAR_ON_MANAGER_START, BOOL}}, {"IsMetric", {PERSISTENT, BOOL}}, {"IsOffroad", {CLEAR_ON_MANAGER_START, BOOL}}, - {"IsOnroad", {PERSISTENT, BOOL}}, {"IsRhdDetected", {PERSISTENT, BOOL}}, {"IsReleaseBranch", {CLEAR_ON_MANAGER_START, BOOL}}, {"IsTakingSnapshot", {CLEAR_ON_MANAGER_START, BOOL}}, diff --git a/system/athena/athenad.py b/system/athena/athenad.py index a322652e3e..e94a0dd0ca 100755 --- a/system/athena/athenad.py +++ b/system/athena/athenad.py @@ -583,7 +583,7 @@ def startStream(sdp: str, enabled: bool) -> dict: else: raise Exception("failed to get CarParamsPersistent") - if not params.get_bool("IsOnroad"): + if params.get_bool("IsOffroad"): # manager owns camerad/stream_encoderd/webrtcd; flip the param and let it bring them up. # webrtcd clears IsLiveStreaming when the session ends params.put_bool("IsLiveStreaming", True) @@ -786,7 +786,7 @@ def ws_manage(ws: WebSocket, end_event: threading.Event) -> None: sock = ws.sock while True: - onroad = params.get_bool("IsOnroad") + onroad = not params.get_bool("IsOffroad") if onroad != onroad_prev: onroad_prev = onroad diff --git a/system/athena/tests/test_athenad_ping.py b/system/athena/tests/test_athenad_ping.py index 7f44263162..44a6b8a56b 100644 --- a/system/athena/tests/test_athenad_ping.py +++ b/system/athena/tests/test_athenad_ping.py @@ -7,7 +7,6 @@ from typing import cast from openpilot.common.params import Params from openpilot.common.timeout import Timeout from openpilot.system.athena import athenad -from openpilot.system.manager.helpers import write_onroad_params from openpilot.common.hardware import TICI TIMEOUT_TOLERANCE = 20 # seconds @@ -93,10 +92,10 @@ class TestAthenadPing: @pytest.mark.skipif(not TICI, reason="only run on desk") def test_offroad(self, subtests, mocker) -> None: - write_onroad_params(False, self.params) + self.params.put_bool("IsOffroad", True, block=True) self.assertTimeout(60 + TIMEOUT_TOLERANCE, subtests, mocker) # based using TCP keepalive settings @pytest.mark.skipif(not TICI, reason="only run on desk") def test_onroad(self, subtests, mocker) -> None: - write_onroad_params(True, self.params) + self.params.put_bool("IsOffroad", False, block=True) self.assertTimeout(21 + TIMEOUT_TOLERANCE, subtests, mocker) diff --git a/system/manager/helpers.py b/system/manager/helpers.py index 6af4a799e4..b07aec0c81 100644 --- a/system/manager/helpers.py +++ b/system/manager/helpers.py @@ -44,12 +44,6 @@ def unblock_stdout() -> None: exit_status = os.wait()[1] >> 8 os._exit(exit_status) - -def write_onroad_params(started, params): - params.put_bool("IsOnroad", started, block=True) - params.put_bool("IsOffroad", not started, block=True) - - def save_bootlog(): # copy current params tmp = tempfile.mkdtemp() diff --git a/system/manager/manager.py b/system/manager/manager.py index cb84b9b8ca..e129e64f13 100755 --- a/system/manager/manager.py +++ b/system/manager/manager.py @@ -13,7 +13,7 @@ from openpilot.common.utils import atomic_write from openpilot.common.params import Params, ParamKeyFlag from openpilot.common.text_window import TextWindow from openpilot.common.hardware import HARDWARE -from openpilot.system.manager.helpers import unblock_stdout, write_onroad_params, save_bootlog +from openpilot.system.manager.helpers import unblock_stdout, save_bootlog from openpilot.system.manager.process import ensure_running from openpilot.system.manager.process_config import managed_processes from openpilot.system.athena.registration import register, UNREGISTERED_DONGLE_ID @@ -121,7 +121,7 @@ def manager_thread() -> None: sm = messaging.SubMaster(['deviceState', 'carParams', 'pandaStates'], poll='deviceState') pm = messaging.PubMaster(['managerState']) - write_onroad_params(False, params) + params.put_bool("IsOffroad", True, block=True) ensure_running(managed_processes.values(), False, params=params, CP=sm['carParams'], not_run=ignore) started_prev = False @@ -141,9 +141,9 @@ def manager_thread() -> None: if ignition and not ignition_prev: params.clear_all(ParamKeyFlag.CLEAR_ON_IGNITION_ON) - # update onroad params, which drives pandad's safety setter thread + # update offroad state for services that don't subscribe to deviceState if started != started_prev: - write_onroad_params(started, params) + params.put_bool("IsOffroad", not started, block=True) started_prev = started ignition_prev = ignition diff --git a/tools/scripts/car/ecu_addrs.py b/tools/scripts/car/ecu_addrs.py index f3f06406c0..b0e7a8f2dc 100755 --- a/tools/scripts/car/ecu_addrs.py +++ b/tools/scripts/car/ecu_addrs.py @@ -26,9 +26,9 @@ if __name__ == "__main__": # Set up params for pandad params = Params() params.remove("FirmwareQueryDone") - params.put_bool("IsOnroad", False, block=True) + params.put_bool("IsOffroad", True, block=True) time.sleep(0.2) # thread is 10 Hz - params.put_bool("IsOnroad", True, block=True) + params.put_bool("IsOffroad", False, block=True) obd_callback(params)(not args.no_obd) diff --git a/tools/scripts/car/fw_versions.py b/tools/scripts/car/fw_versions.py index b04f9cd2a6..81692147f0 100755 --- a/tools/scripts/car/fw_versions.py +++ b/tools/scripts/car/fw_versions.py @@ -30,9 +30,9 @@ if __name__ == "__main__": # Set up params for pandad params = Params() params.remove("FirmwareQueryDone") - params.put_bool("IsOnroad", False, block=True) + params.put_bool("IsOffroad", True, block=True) time.sleep(0.2) # thread is 10 Hz - params.put_bool("IsOnroad", True, block=True) + params.put_bool("IsOffroad", False, block=True) set_obd_multiplexing = obd_callback(params) extra: Any = None From d8bd6c784e1386cc61d3c6e51291a4d75a4ab911 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Sun, 21 Jun 2026 09:11:04 -0700 Subject: [PATCH 069/151] rename androidLog -> operatingSystemLog (#38209) not android --- cereal/log.capnp | 4 ++-- cereal/services.py | 2 +- system/journald.py | 8 ++++---- tools/jotpluggler/app.h | 2 +- tools/jotpluggler/sketch_layout.cc | 24 ++++++++++++------------ tools/scripts/filter_log_message.py | 16 ++++++++-------- 6 files changed, 28 insertions(+), 28 deletions(-) diff --git a/cereal/log.capnp b/cereal/log.capnp index 6cf4781228..ec7a065eb7 100644 --- a/cereal/log.capnp +++ b/cereal/log.capnp @@ -1132,7 +1132,7 @@ struct EncodeIndex { } } -struct AndroidLogEntry { +struct OperatingSystemLogEntry { id @0 :UInt8; ts @1 :UInt64; priority @2 :UInt8; @@ -2517,7 +2517,7 @@ struct Event { rawAudioData @147 :AudioData; # systems stuff - androidLog @20 :AndroidLogEntry; + operatingSystemLog @20 :OperatingSystemLogEntry; managerState @78 :ManagerState; procLog @33 :ProcLog; clocks @35 :Clocks; diff --git a/cereal/services.py b/cereal/services.py index c2d38d852d..0f5e50f31f 100755 --- a/cereal/services.py +++ b/cereal/services.py @@ -41,7 +41,7 @@ _services: dict[str, tuple] = { "liveCalibration": (True, 4., 4), "liveTorqueParameters": (True, 4., 1), "liveDelay": (True, 4., 1), - "androidLog": (True, 0.), + "operatingSystemLog": (True, 0.), "carState": (True, 100., 10), "carControl": (True, 100., 10), "carOutput": (True, 100., 10), diff --git a/system/journald.py b/system/journald.py index 37158b9251..7c656d3b13 100755 --- a/system/journald.py +++ b/system/journald.py @@ -7,7 +7,7 @@ from openpilot.common.swaglog import cloudlog def main(): - pm = messaging.PubMaster(['androidLog']) + pm = messaging.PubMaster(['operatingSystemLog']) cmd = ['journalctl', '-f', '-o', 'json'] proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, text=True) assert proc.stdout is not None @@ -22,8 +22,8 @@ def main(): cloudlog.exception("failed to parse journalctl output") continue - msg = messaging.new_message('androidLog') - entry = msg.androidLog + msg = messaging.new_message('operatingSystemLog') + entry = msg.operatingSystemLog entry.ts = int(kv.get('__REALTIME_TIMESTAMP', 0)) entry.message = json.dumps(kv) if '_PID' in kv: @@ -33,7 +33,7 @@ def main(): if 'SYSLOG_IDENTIFIER' in kv: entry.tag = kv['SYSLOG_IDENTIFIER'] - pm.send('androidLog', msg) + pm.send('operatingSystemLog', msg) finally: proc.terminate() proc.wait() diff --git a/tools/jotpluggler/app.h b/tools/jotpluggler/app.h index 872a6973d7..a059d94c08 100644 --- a/tools/jotpluggler/app.h +++ b/tools/jotpluggler/app.h @@ -143,7 +143,7 @@ struct CameraFeedIndex { enum class LogOrigin : uint8_t { Log, - Android, + OperatingSystem, Alert, }; diff --git a/tools/jotpluggler/sketch_layout.cc b/tools/jotpluggler/sketch_layout.cc index 2091280169..143a6f5a1d 100644 --- a/tools/jotpluggler/sketch_layout.cc +++ b/tools/jotpluggler/sketch_layout.cc @@ -432,7 +432,7 @@ std::array parse_color(std::string_view color) { return out; } -uint8_t android_priority_to_level(uint8_t priority) { +uint8_t operating_system_priority_to_level(uint8_t priority) { switch (priority) { case 2: case 3: @@ -491,7 +491,7 @@ void append_timeline_entry(std::vector *timeline, double mono_tim }); } -double android_wall_time_seconds(uint64_t timestamp) { +double operating_system_wall_time_seconds(uint64_t timestamp) { if (timestamp == 0) return 0.0; if (timestamp > 1000000000000ULL) return static_cast(timestamp) / 1.0e9; if (timestamp > 1000000000ULL) return static_cast(timestamp) / 1.0e6; @@ -609,13 +609,13 @@ void append_log_event(cereal::Event::Which which, logs->push_back(std::move(entry)); break; } - case cereal::Event::Which::ANDROID_LOG: { - const auto android = event.getAndroidLog(); - auto entry = make_entry(LogOrigin::Android, android_priority_to_level(android.getPriority())); - entry.wall_time = android_wall_time_seconds(android.getTs()); - entry.source = android.hasTag() ? android.getTag().cStr() : "android"; - entry.message = android.hasMessage() ? android.getMessage().cStr() : std::string(); - entry.context = "pid=" + std::to_string(android.getPid()) + ", tid=" + std::to_string(android.getTid()); + case cereal::Event::Which::OPERATING_SYSTEM_LOG: { + const auto operating_system_log = event.getOperatingSystemLog(); + auto entry = make_entry(LogOrigin::OperatingSystem, operating_system_priority_to_level(operating_system_log.getPriority())); + entry.wall_time = operating_system_wall_time_seconds(operating_system_log.getTs()); + entry.source = operating_system_log.hasTag() ? operating_system_log.getTag().cStr() : "operating_system"; + entry.message = operating_system_log.hasMessage() ? operating_system_log.getMessage().cStr() : std::string(); + entry.context = "pid=" + std::to_string(operating_system_log.getPid()) + ", tid=" + std::to_string(operating_system_log.getTid()); if (!entry.message.empty()) { std::string err; if (const auto p = json11::Json::parse(entry.message, err); err.empty() && p.is_object()) { @@ -623,10 +623,10 @@ void append_log_event(cereal::Event::Which which, if (p["SYSLOG_IDENTIFIER"].is_string() && !p["SYSLOG_IDENTIFIER"].string_value().empty()) entry.source = p["SYSLOG_IDENTIFIER"].string_value(); if (auto pri = json_int_value(p["PRIORITY"]); pri.has_value()) - entry.level = android_priority_to_level(*pri); + entry.level = operating_system_priority_to_level(*pri); if (auto ts = json_u64_value(p["__REALTIME_TIMESTAMP"]); ts.has_value()) - entry.wall_time = android_wall_time_seconds(*ts); - entry.context = format_journal_context(p, android.getPid(), android.getTid()); + entry.wall_time = operating_system_wall_time_seconds(*ts); + entry.context = format_journal_context(p, operating_system_log.getPid(), operating_system_log.getTid()); } } logs->push_back(std::move(entry)); diff --git a/tools/scripts/filter_log_message.py b/tools/scripts/filter_log_message.py index 9cbab0b41f..38904aaa07 100755 --- a/tools/scripts/filter_log_message.py +++ b/tools/scripts/filter_log_message.py @@ -13,7 +13,7 @@ LEVELS = { "CRITICAL": 50, } -ANDROID_LOG_SOURCE = { +OPERATING_SYSTEM_LOG_SOURCE = { 0: "MAIN", 1: "RADIO", 2: "EVENTS", @@ -34,8 +34,8 @@ def print_logmessage(t, msg, min_level): print(f"[{t / 1e9:.6f}] decode error: {msg}") -def print_androidlog(t, msg): - source = ANDROID_LOG_SOURCE[msg.id] +def print_operating_system_log(t, msg): + source = msg.tag or OPERATING_SYSTEM_LOG_SOURCE.get(msg.id, "SYSTEM") try: m = json.loads(msg.message)['MESSAGE'] except Exception: @@ -65,15 +65,15 @@ if __name__ == "__main__": print_logmessage(m.logMonoTime-st, m.logMessage, min_level) elif m.which() == 'errorLogMessage': print_logmessage(m.logMonoTime-st, m.errorLogMessage, min_level) - elif m.which() == 'androidLog': - print_androidlog(m.logMonoTime-st, m.androidLog) + elif m.which() == 'operatingSystemLog': + print_operating_system_log(m.logMonoTime-st, m.operatingSystemLog) else: - sm = messaging.SubMaster(['logMessage', 'androidLog'], addr=args.addr) + sm = messaging.SubMaster(['logMessage', 'operatingSystemLog'], addr=args.addr) while True: sm.update() if sm.updated['logMessage']: print_logmessage(sm.logMonoTime['logMessage'], sm['logMessage'], min_level) - if sm.updated['androidLog']: - print_androidlog(sm.logMonoTime['androidLog'], sm['androidLog']) + if sm.updated['operatingSystemLog']: + print_operating_system_log(sm.logMonoTime['operatingSystemLog'], sm['operatingSystemLog']) From cea5273f1f40ac8e1ccbc438cadf29de42c157af Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Sun, 21 Jun 2026 09:43:53 -0700 Subject: [PATCH 070/151] move version to common/ (#38210) --- common/api.py | 2 +- {system => common}/version.py | 0 selfdrive/selfdrived/selfdrived.py | 2 +- selfdrive/test/helpers.py | 2 +- selfdrive/ui/layouts/onboarding.py | 2 +- selfdrive/ui/mici/layouts/home.py | 2 +- selfdrive/ui/mici/layouts/onboarding.py | 2 +- selfdrive/ui/tests/diff/replay.py | 2 +- system/athena/athenad.py | 2 +- system/athena/manage_athenad.py | 2 +- system/hardware/hardwared.py | 2 +- system/loggerd/tests/test_loggerd.py | 2 +- system/manager/manager.py | 2 +- system/sentry.py | 2 +- system/tombstoned.py | 2 +- system/updated/updated.py | 2 +- 16 files changed, 15 insertions(+), 15 deletions(-) rename {system => common}/version.py (100%) diff --git a/common/api.py b/common/api.py index 521aac3fdd..c97f56c4b5 100644 --- a/common/api.py +++ b/common/api.py @@ -3,7 +3,7 @@ import os import requests from datetime import datetime, timedelta, UTC from openpilot.common.hardware.hw import Paths -from openpilot.system.version import get_version +from openpilot.common.version import get_version API_HOST = os.getenv('API_HOST', 'https://api.commadotai.com') diff --git a/system/version.py b/common/version.py similarity index 100% rename from system/version.py rename to common/version.py diff --git a/selfdrive/selfdrived/selfdrived.py b/selfdrive/selfdrived/selfdrived.py index 5fe45d9274..b4bd2a7b90 100755 --- a/selfdrive/selfdrived/selfdrived.py +++ b/selfdrive/selfdrived/selfdrived.py @@ -21,7 +21,7 @@ from openpilot.selfdrive.selfdrived.helpers import ExcessiveActuationCheck from openpilot.selfdrive.selfdrived.state import StateMachine from openpilot.selfdrive.selfdrived.alertmanager import AlertManager, set_offroad_alert -from openpilot.system.version import get_build_metadata +from openpilot.common.version import get_build_metadata from openpilot.common.hardware import HARDWARE REPLAY = "REPLAY" in os.environ diff --git a/selfdrive/test/helpers.py b/selfdrive/test/helpers.py index 49a8ec60a3..615ea5d8ac 100644 --- a/selfdrive/test/helpers.py +++ b/selfdrive/test/helpers.py @@ -10,7 +10,7 @@ from functools import wraps import cereal.messaging as messaging from openpilot.common.params import Params from openpilot.system.manager.process_config import managed_processes -from openpilot.system.version import training_version, terms_version +from openpilot.common.version import training_version, terms_version def set_params_enabled(): diff --git a/selfdrive/ui/layouts/onboarding.py b/selfdrive/ui/layouts/onboarding.py index c75abac1a2..4ef9c13f27 100644 --- a/selfdrive/ui/layouts/onboarding.py +++ b/selfdrive/ui/layouts/onboarding.py @@ -11,7 +11,7 @@ from openpilot.system.ui.widgets import Widget from openpilot.system.ui.widgets.button import Button, ButtonStyle from openpilot.system.ui.widgets.label import Label from openpilot.selfdrive.ui.ui_state import ui_state -from openpilot.system.version import terms_version, training_version +from openpilot.common.version import terms_version, training_version DEBUG = False diff --git a/selfdrive/ui/mici/layouts/home.py b/selfdrive/ui/mici/layouts/home.py index 1cc61c6478..997ca6276f 100644 --- a/selfdrive/ui/mici/layouts/home.py +++ b/selfdrive/ui/mici/layouts/home.py @@ -10,7 +10,7 @@ from openpilot.system.ui.widgets.icon_widget import IconWidget from openpilot.system.ui.widgets.label import UnifiedLabel, gui_label from openpilot.system.ui.lib.application import gui_app, FontWeight, MousePos from openpilot.selfdrive.ui.ui_state import ui_state -from openpilot.system.version import RELEASE_BRANCHES +from openpilot.common.version import RELEASE_BRANCHES HEAD_BUTTON_FONT_SIZE = 40 HOME_PADDING = 8 diff --git a/selfdrive/ui/mici/layouts/onboarding.py b/selfdrive/ui/mici/layouts/onboarding.py index 2d6acf60d6..8d80df3a89 100644 --- a/selfdrive/ui/mici/layouts/onboarding.py +++ b/selfdrive/ui/mici/layouts/onboarding.py @@ -12,7 +12,7 @@ from openpilot.system.ui.widgets.nav_widget import NavWidget from openpilot.system.ui.mici_setup import GreyBigButton, BigPillButton from openpilot.system.ui.widgets.label import gui_label from openpilot.system.ui.lib.multilang import tr -from openpilot.system.version import terms_version, training_version +from openpilot.common.version import terms_version, training_version from openpilot.selfdrive.ui.ui_state import ui_state, device from openpilot.selfdrive.ui.mici.widgets.dialog import BigConfirmationCircleButton from openpilot.selfdrive.ui.mici.onroad.driver_state import DriverStateRenderer diff --git a/selfdrive/ui/tests/diff/replay.py b/selfdrive/ui/tests/diff/replay.py index 25920b67fb..6f3dd8f040 100755 --- a/selfdrive/ui/tests/diff/replay.py +++ b/selfdrive/ui/tests/diff/replay.py @@ -14,7 +14,7 @@ from openpilot.common.params import Params from openpilot.common.prefix import OpenpilotPrefix from openpilot.selfdrive.ui.tests.diff.diff import DIFF_OUT_DIR from openpilot.system.updated.updated import parse_release_notes -from openpilot.system.version import terms_version, training_version +from openpilot.common.version import terms_version, training_version LayoutVariant = Literal["mici", "tizi"] diff --git a/system/athena/athenad.py b/system/athena/athenad.py index e94a0dd0ca..6d1325dac6 100755 --- a/system/athena/athenad.py +++ b/system/athena/athenad.py @@ -37,7 +37,7 @@ from openpilot.common.realtime import set_core_affinity from openpilot.common.hardware import HARDWARE, PC from openpilot.system.loggerd.xattr_cache import getxattr, setxattr from openpilot.common.swaglog import cloudlog -from openpilot.system.version import get_build_metadata +from openpilot.common.version import get_build_metadata from openpilot.common.hardware.hw import Paths diff --git a/system/athena/manage_athenad.py b/system/athena/manage_athenad.py index 11fd11d431..3faad546b2 100755 --- a/system/athena/manage_athenad.py +++ b/system/athena/manage_athenad.py @@ -7,7 +7,7 @@ from openpilot.common.params import Params from openpilot.system.manager.process import launcher from openpilot.common.swaglog import cloudlog from openpilot.common.hardware import HARDWARE -from openpilot.system.version import get_build_metadata +from openpilot.common.version import get_build_metadata ATHENA_MGR_PID_PARAM = "AthenadPid" diff --git a/system/hardware/hardwared.py b/system/hardware/hardwared.py index 70f31d5f7d..c7b7befd55 100755 --- a/system/hardware/hardwared.py +++ b/system/hardware/hardwared.py @@ -22,7 +22,7 @@ from openpilot.system.loggerd.config import get_available_percent from openpilot.common.swaglog import cloudlog from openpilot.system.hardware.power_monitoring import PowerMonitoring from openpilot.system.hardware.fan_controller import FanController -from openpilot.system.version import terms_version, training_version +from openpilot.common.version import terms_version, training_version from openpilot.system.athena.registration import UNREGISTERED_DONGLE_ID ThermalStatus = log.DeviceState.ThermalStatus diff --git a/system/loggerd/tests/test_loggerd.py b/system/loggerd/tests/test_loggerd.py index 882de583b4..217de649eb 100644 --- a/system/loggerd/tests/test_loggerd.py +++ b/system/loggerd/tests/test_loggerd.py @@ -20,7 +20,7 @@ from openpilot.common.hardware import TICI from openpilot.system.loggerd.xattr_cache import getxattr from openpilot.system.loggerd.deleter import PRESERVE_ATTR_NAME, PRESERVE_ATTR_VALUE from openpilot.system.manager.process_config import managed_processes -from openpilot.system.version import get_version +from openpilot.common.version import get_version from openpilot.tools.lib.helpers import RE from openpilot.tools.lib.logreader import LogReader from msgq.visionipc import VisionIpcServer, VisionStreamType diff --git a/system/manager/manager.py b/system/manager/manager.py index e129e64f13..179108b9b1 100755 --- a/system/manager/manager.py +++ b/system/manager/manager.py @@ -18,7 +18,7 @@ from openpilot.system.manager.process import ensure_running from openpilot.system.manager.process_config import managed_processes from openpilot.system.athena.registration import register, UNREGISTERED_DONGLE_ID from openpilot.common.swaglog import cloudlog, add_file_handler -from openpilot.system.version import get_build_metadata +from openpilot.common.version import get_build_metadata from openpilot.common.hardware.hw import Paths diff --git a/system/sentry.py b/system/sentry.py index ee9f813e25..8a4e1bb9f2 100644 --- a/system/sentry.py +++ b/system/sentry.py @@ -7,7 +7,7 @@ from openpilot.common.params import Params from openpilot.system.athena.registration import is_registered_device from openpilot.common.hardware import HARDWARE, PC from openpilot.common.swaglog import cloudlog -from openpilot.system.version import get_build_metadata, get_version +from openpilot.common.version import get_build_metadata, get_version class SentryProject(Enum): diff --git a/system/tombstoned.py b/system/tombstoned.py index 88a2a879ed..349a71cc19 100755 --- a/system/tombstoned.py +++ b/system/tombstoned.py @@ -12,7 +12,7 @@ from typing import NoReturn import openpilot.system.sentry as sentry from openpilot.common.hardware.hw import Paths from openpilot.common.swaglog import cloudlog -from openpilot.system.version import get_build_metadata +from openpilot.common.version import get_build_metadata MAX_SIZE = 1_000_000 * 100 # allow up to 100M MAX_TOMBSTONE_FN_LEN = 62 # 85 - 23 ("/crash/") diff --git a/system/updated/updated.py b/system/updated/updated.py index e40bc44e76..affacd0f2d 100755 --- a/system/updated/updated.py +++ b/system/updated/updated.py @@ -19,7 +19,7 @@ from openpilot.common.markdown import parse_markdown from openpilot.common.swaglog import cloudlog from openpilot.selfdrive.selfdrived.alertmanager import set_offroad_alert from openpilot.common.hardware import AGNOS, HARDWARE -from openpilot.system.version import get_build_metadata +from openpilot.common.version import get_build_metadata LOCK_FILE = os.getenv("UPDATER_LOCK_FILE", "/tmp/safe_staging_overlay.lock") STAGING_ROOT = os.getenv("UPDATER_STAGING_ROOT", "/data/safe_staging") From d79267fa22ce280c0ff7762596a071136ddc491f Mon Sep 17 00:00:00 2001 From: Fang Li Date: Sun, 21 Jun 2026 12:37:56 -0700 Subject: [PATCH 071/151] modem: fall back when cellular DNS is missing (#38213) * modem: fall back when cellular DNS is missing * rm test * comment --------- Co-authored-by: Adeeb Shihadeh --- common/hardware/tici/modem.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/common/hardware/tici/modem.py b/common/hardware/tici/modem.py index 39266be122..78f4e2a492 100755 --- a/common/hardware/tici/modem.py +++ b/common/hardware/tici/modem.py @@ -505,7 +505,11 @@ class Modem: except (AddressValueError, ValueError): pass if not dns_servers: - logging.warning(f"no cellular DNS servers reported by modem: {v!r}") + dns_servers = [ + "8.8.8.8", # Google + "1.1.1.1", # Cloudflare + ] + logging.warning(f"no cellular DNS servers reported by modem: {v!r}; using fallback {dns_servers}") return dns_servers def _poll_byte_counters(self) -> dict: From bc168bb33a856c4298d8bc6a56a9a2a496518ff9 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Sun, 21 Jun 2026 12:49:12 -0700 Subject: [PATCH 072/151] rm opencv-python-headless (#38214) * rm opencv-python-headless * and metadrive * skip sim --- conftest.py | 2 ++ pyproject.toml | 5 ++-- uv.lock | 71 -------------------------------------------------- 3 files changed, 5 insertions(+), 73 deletions(-) diff --git a/conftest.py b/conftest.py index 3719be93d3..6307f8304c 100644 --- a/conftest.py +++ b/conftest.py @@ -11,6 +11,8 @@ from openpilot.common.hardware import TICI, HARDWARE collect_ignore = [ "selfdrive/test/process_replay/test_processes.py", "selfdrive/test/process_replay/test_regen.py", + + "tools/sim/", ] diff --git a/pyproject.toml b/pyproject.toml index 51844ef93c..b146138ae7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -104,12 +104,13 @@ testing = [ dev = [ "matplotlib", - "opencv-python-headless", ] tools = [ "imgui @ git+https://github.com/commaai/dependencies.git@release-imgui#subdirectory=imgui", - "metadrive-simulator @ git+https://github.com/commaai/metadrive.git@minimal ; (platform_machine != 'aarch64')", + + # this can be added back once it's stripped down some more + #"metadrive-simulator @ git+https://github.com/commaai/metadrive.git@minimal ; (platform_machine != 'aarch64')", ] [project.urls] diff --git a/uv.lock b/uv.lock index dc51d2a45e..e95c49f497 100644 --- a/uv.lock +++ b/uv.lock @@ -658,16 +658,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/4b/d0/2269edb12aa30c13c8bcc9382892e39943ce1d28aab4ec296e0381798e81/matplotlib-3.10.9-cp312-cp312-win_arm64.whl", hash = "sha256:10cc5ce06d10231c36f40e875f3c7e8050362a4ee8f0ee5d29a6b3277d57bb42", size = 8136688, upload-time = "2026-04-24T00:12:37.442Z" }, ] -[[package]] -name = "metadrive-simulator" -version = "0.4.2.3" -source = { git = "https://github.com/commaai/metadrive.git?rev=minimal#2716f55a9c7b928ce957a497a15c2c19840c08bc" } -dependencies = [ - { name = "numpy" }, - { name = "panda3d" }, - { name = "panda3d-gltf" }, -] - [[package]] name = "mpmath" version = "1.3.0" @@ -728,24 +718,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/63/cf/5a6d34850a39d1093558564f77ee8e8e0bee5061151b8f05a55711001ec7/numpy-2.4.6-cp312-cp312-win_arm64.whl", hash = "sha256:4081eb135ac24158bd51cdfbef16f1c64df7063b1143f24731387137c092bec8", size = 10221482, upload-time = "2026-05-18T23:34:25.876Z" }, ] -[[package]] -name = "opencv-python-headless" -version = "4.13.0.92" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "numpy" }, -] -wheels = [ - { url = "https://files.pythonhosted.org/packages/79/42/2310883be3b8826ac58c3f2787b9358a2d46923d61f88fedf930bc59c60c/opencv_python_headless-4.13.0.92-cp37-abi3-macosx_13_0_arm64.whl", hash = "sha256:1a7d040ac656c11b8c38677cc8cccdc149f98535089dbe5b081e80a4e5903209", size = 46247192, upload-time = "2026-02-05T07:01:35.187Z" }, - { url = "https://files.pythonhosted.org/packages/2d/1e/6f9e38005a6f7f22af785df42a43139d0e20f169eb5787ce8be37ee7fcc9/opencv_python_headless-4.13.0.92-cp37-abi3-macosx_14_0_x86_64.whl", hash = "sha256:3e0a6f0a37994ec6ce5f59e936be21d5d6384a4556f2d2da9c2f9c5dc948394c", size = 32568914, upload-time = "2026-02-05T07:01:51.989Z" }, - { url = "https://files.pythonhosted.org/packages/21/76/9417a6aef9def70e467a5bf560579f816148a4c658b7d525581b356eda9e/opencv_python_headless-4.13.0.92-cp37-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:5c8cfc8e87ed452b5cecb9419473ee5560a989859fe1d10d1ce11ae87b09a2cb", size = 33703709, upload-time = "2026-02-05T10:24:46.469Z" }, - { url = "https://files.pythonhosted.org/packages/92/ce/bd17ff5772938267fd49716e94ca24f616ff4cb1ff4c6be13085108037be/opencv_python_headless-4.13.0.92-cp37-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:0525a3d2c0b46c611e2130b5fdebc94cf404845d8fa64d2f3a3b679572a5bd22", size = 56016764, upload-time = "2026-02-05T10:26:48.904Z" }, - { url = "https://files.pythonhosted.org/packages/8f/b4/b7bcbf7c874665825a8c8e1097e93ea25d1f1d210a3e20d4451d01da30aa/opencv_python_headless-4.13.0.92-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:eb60e36b237b1ebd40a912da5384b348df8ed534f6f644d8e0b4f103e272ba7d", size = 35010236, upload-time = "2026-02-05T10:28:11.031Z" }, - { url = "https://files.pythonhosted.org/packages/4b/33/b5db29a6c00eb8f50708110d8d453747ca125c8b805bc437b289dbdcc057/opencv_python_headless-4.13.0.92-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:0bd48544f77c68b2941392fcdf9bcd2b9cdf00e98cb8c29b2455d194763cf99e", size = 60391106, upload-time = "2026-02-05T10:30:14.236Z" }, - { url = "https://files.pythonhosted.org/packages/fb/c3/52cfea47cd33e53e8c0fbd6e7c800b457245c1fda7d61660b4ffe9596a7f/opencv_python_headless-4.13.0.92-cp37-abi3-win32.whl", hash = "sha256:a7cf08e5b191f4ebb530791acc0825a7986e0d0dee2a3c491184bd8599848a4b", size = 30812232, upload-time = "2026-02-05T07:02:29.594Z" }, - { url = "https://files.pythonhosted.org/packages/4a/90/b338326131ccb2aaa3c2c85d00f41822c0050139a4bfe723cfd95455bd2d/opencv_python_headless-4.13.0.92-cp37-abi3-win_amd64.whl", hash = "sha256:77a82fe35ddcec0f62c15f2ba8a12ecc2ed4207c17b0902c7a3151ae29f37fb6", size = 40070414, upload-time = "2026-02-05T07:02:26.448Z" }, -] - [[package]] name = "openpilot" version = "0.1.0" @@ -805,7 +777,6 @@ dependencies = [ [package.optional-dependencies] dev = [ { name = "matplotlib" }, - { name = "opencv-python-headless" }, ] docs = [ { name = "jinja2" }, @@ -826,7 +797,6 @@ testing = [ ] tools = [ { name = "imgui" }, - { name = "metadrive-simulator", marker = "platform_machine != 'aarch64'" }, ] [package.metadata] @@ -860,10 +830,8 @@ requires-dist = [ { name = "libusb1" }, { name = "libyuv", git = "https://github.com/commaai/dependencies.git?subdirectory=libyuv&rev=release-libyuv" }, { name = "matplotlib", marker = "extra == 'dev'" }, - { name = "metadrive-simulator", marker = "platform_machine != 'aarch64' and extra == 'tools'", git = "https://github.com/commaai/metadrive.git?rev=minimal" }, { name = "ncurses", git = "https://github.com/commaai/dependencies.git?subdirectory=ncurses&rev=release-ncurses" }, { name = "numpy", specifier = ">=2.0" }, - { name = "opencv-python-headless", marker = "extra == 'dev'" }, { name = "pillow" }, { name = "pre-commit-hooks", marker = "extra == 'testing'" }, { name = "psutil" }, @@ -909,45 +877,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/df/b2/87e62e8c3e2f4b32e5fe99e0b86d576da1312593b39f47d8ceef365e95ed/packaging-26.2-py3-none-any.whl", hash = "sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e", size = 100195, upload-time = "2026-04-24T20:15:22.081Z" }, ] -[[package]] -name = "panda3d" -version = "1.10.14" -source = { registry = "https://pypi.org/simple" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/5a/d4/90e98993b1a3f3c9fae83267f8c51186e676a8c1365c4180dfc65cd7ba62/panda3d-1.10.14-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:1bfbcee77779f12ecce6a3d5a856e573b25d6343f8c4b107e814d9702e70a65d", size = 67839196, upload-time = "2024-01-08T19:01:00.417Z" }, - { url = "https://files.pythonhosted.org/packages/dc/e5/862821575073863ce49cc57b8349b47cb25ce11feae0e419b3d023ac1a69/panda3d-1.10.14-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:bc6540c5559d7e14a8992eff7de0157b7c42406b7ba221941ed224289496841c", size = 119271341, upload-time = "2024-01-08T19:01:09.455Z" }, - { url = "https://files.pythonhosted.org/packages/f4/20/f16d91805777825e530037177d9075c83da7384f12b778b133e3164a31f3/panda3d-1.10.14-cp312-cp312-manylinux2014_aarch64.whl", hash = "sha256:143daab1ce6bedcba711ea3f6cab0ebe5082f22c5f43e7178fadd2dd01209da7", size = 47604077, upload-time = "2024-05-28T20:25:37.118Z" }, - { url = "https://files.pythonhosted.org/packages/11/69/806dcdbaee3e8deee1956abeea0d3d3e504315d2e9814de82a44809a8617/panda3d-1.10.14-cp312-cp312-manylinux2014_x86_64.whl", hash = "sha256:3c4399a286a142de7ff86f9356d7e526bbbd38892d7f7d39fecb5c33064972bc", size = 55539594, upload-time = "2024-01-08T19:01:15.979Z" }, - { url = "https://files.pythonhosted.org/packages/ad/25/005de5e2b6d0acd546f8b3f2b547cd29e308cdd04a397f0ea68046e26571/panda3d-1.10.14-cp312-cp312-win32.whl", hash = "sha256:e92e0dd907e2af33085a2c31ca2263dc8023b1b7bc70ce1b9fbc84631e130e51", size = 53479813, upload-time = "2024-01-08T19:01:20.923Z" }, - { url = "https://files.pythonhosted.org/packages/74/bb/cb57563855da994614a33f57bd5691fbcd69f12e5ccddd30d387d0be287f/panda3d-1.10.14-cp312-cp312-win_amd64.whl", hash = "sha256:a5f2defd822d38848f8ae1956115adcb6cc7f464f03a67e73681cc72df125ef4", size = 64893222, upload-time = "2024-01-08T19:01:26.347Z" }, -] - -[[package]] -name = "panda3d-gltf" -version = "0.13" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "panda3d" }, - { name = "panda3d-simplepbr" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/07/7f/9f18fc3fa843a080acb891af6bcc12262e7bdf1d194a530f7042bebfc81f/panda3d-gltf-0.13.tar.gz", hash = "sha256:d06d373bdd91cf530909b669f43080e599463bbf6d3ef00c3558bad6c6b19675", size = 25573, upload-time = "2021-05-21T05:46:32.738Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/70/94/98ed1f81ca0f5daf6de80533805cc1e98ac162abe4e3e1d382caa7ba5c3c/panda3d_gltf-0.13-py3-none-any.whl", hash = "sha256:02d1a980f447bb1895ff4b48c667f289ba78f07a28ef308d8839b665a621efe2", size = 25568, upload-time = "2021-05-21T05:46:31.28Z" }, -] - -[[package]] -name = "panda3d-simplepbr" -version = "0.13.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "panda3d" }, - { name = "typing-extensions" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/0d/be/c4d1ded04c22b357277cf6e6a44c1ab4abb285a700bd1991460460e05b99/panda3d_simplepbr-0.13.1.tar.gz", hash = "sha256:c83766d7c8f47499f365a07fe1dff078fc8b3054c2689bdc8dceabddfe7f1a35", size = 6216055, upload-time = "2025-03-30T16:57:41.087Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/11/5d/3744c6550dddf933785a37cdd4a9921fe13284e6d115b5a2637fe390f158/panda3d_simplepbr-0.13.1-py3-none-any.whl", hash = "sha256:cda41cb57cff035b851646956cfbdcc408bee42511dabd4f2d7bd4fbf48c57a9", size = 2457097, upload-time = "2025-03-30T16:57:39.729Z" }, -] - [[package]] name = "pillow" version = "12.2.0" From df1663c58d6e72b46fc9b731fd905c03b6d30a74 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Sun, 21 Jun 2026 17:32:19 -0700 Subject: [PATCH 073/151] the one true car.capnp (#38221) * the one true car.capnp * fix jotpluggler capnp import path * bump to master --- SConstruct | 1 + cereal/SConscript | 12 +++++++----- cereal/__init__.py | 8 ++++---- cereal/car.capnp | 1 - cereal/custom.capnp | 2 +- cereal/deprecated.capnp | 2 +- cereal/log.capnp | 4 ++-- cereal/messaging/tests/test_messaging.py | 3 ++- opendbc_repo | 2 +- selfdrive/car/car_specific.py | 3 ++- selfdrive/car/card.py | 3 ++- selfdrive/car/cruise.py | 2 +- selfdrive/car/tests/test_car_interfaces.py | 2 +- selfdrive/car/tests/test_cruise_speed.py | 2 +- selfdrive/controls/controlsd.py | 3 ++- selfdrive/controls/lib/longcontrol.py | 2 +- selfdrive/controls/plannerd.py | 2 +- selfdrive/controls/radard.py | 3 ++- selfdrive/controls/tests/test_latcontrol.py | 3 ++- .../controls/tests/test_latcontrol_torque_buffer.py | 3 ++- selfdrive/controls/tests/test_longcontrol.py | 2 +- .../controls/tests/test_torqued_lat_accel_offset.py | 3 ++- selfdrive/locationd/calibrationd.py | 3 ++- selfdrive/locationd/lagd.py | 3 ++- selfdrive/locationd/paramsd.py | 3 ++- selfdrive/locationd/test/test_lagd.py | 3 ++- selfdrive/locationd/test/test_torqued.py | 2 +- selfdrive/locationd/torqued.py | 3 ++- selfdrive/modeld/modeld.py | 3 ++- selfdrive/monitoring/policy.py | 3 ++- selfdrive/pandad/tests/test_pandad_loopback.py | 3 ++- selfdrive/selfdrived/events.py | 3 ++- selfdrive/selfdrived/helpers.py | 3 ++- selfdrive/selfdrived/selfdrived.py | 3 ++- selfdrive/selfdrived/tests/test_alerts.py | 3 ++- selfdrive/test/process_replay/migration.py | 3 ++- selfdrive/test/process_replay/process_replay.py | 2 +- selfdrive/ui/feedback/feedbackd.py | 2 +- selfdrive/ui/mici/onroad/alert_renderer.py | 3 ++- selfdrive/ui/mici/onroad/augmented_road_view.py | 3 ++- selfdrive/ui/mici/onroad/driver_camera_dialog.py | 3 ++- selfdrive/ui/mici/onroad/model_renderer.py | 3 ++- selfdrive/ui/onroad/model_renderer.py | 3 ++- selfdrive/ui/soundd.py | 3 ++- selfdrive/ui/tests/diff/replay_script.py | 3 ++- selfdrive/ui/tests/test_feedbackd.py | 2 +- selfdrive/ui/tests/test_soundd.py | 2 +- selfdrive/ui/ui_state.py | 3 ++- system/athena/athenad.py | 3 ++- system/manager/process.py | 3 ++- system/manager/process_config.py | 2 +- system/manager/test/test_manager.py | 2 +- tools/jotpluggler/SConscript | 2 ++ tools/jotpluggler/generate_event_extractors.py | 2 +- tools/joystick/joystickd.py | 3 ++- tools/lateral_maneuvers/generate_report.py | 2 +- tools/lateral_maneuvers/lateral_maneuversd.py | 3 ++- tools/longitudinal_maneuvers/maneuversd.py | 3 ++- tools/scripts/car/fw_versions.py | 2 +- tools/scripts/cycle_alerts.py | 3 ++- tools/scripts/set_car_params.py | 2 +- tools/scripts/uiview.py | 3 ++- 62 files changed, 108 insertions(+), 68 deletions(-) delete mode 120000 cereal/car.capnp diff --git a/SConstruct b/SConstruct index 31d4af801b..9429daea15 100644 --- a/SConstruct +++ b/SConstruct @@ -114,6 +114,7 @@ env = Environment( CPPPATH=[ "#", "#msgq", + "#cereal/gen/cpp", acados_include_dirs, [x.INCLUDE_DIR for x in pkgs], ], diff --git a/cereal/SConscript b/cereal/SConscript index de7ca0d721..bee7620b1e 100644 --- a/cereal/SConscript +++ b/cereal/SConscript @@ -4,12 +4,14 @@ cereal_dir = Dir('.') gen_dir = Dir('gen') # Build cereal -schema_files = ['log.capnp', 'car.capnp', 'deprecated.capnp', 'custom.capnp'] -env.Command([f'gen/cpp/{s}.c++' for s in schema_files] + [f'gen/cpp/{s}.h' for s in schema_files], - schema_files, - f"capnpc --src-prefix={cereal_dir.path} $SOURCES -o c++:{gen_dir.path}/cpp/") +schema_files = ['log.capnp', 'deprecated.capnp', 'custom.capnp'] +car_capnp = '#opendbc_repo/opendbc/car/car.capnp' +all_output = schema_files + ['car.capnp'] +env.Command([f'gen/cpp/{s}.c++' for s in all_output] + [f'gen/cpp/{s}.h' for s in all_output], + schema_files + [car_capnp], + f"capnpc --src-prefix={cereal_dir.path} --src-prefix=opendbc_repo/opendbc/car --import-path=opendbc_repo/opendbc/car $SOURCES -o c++:{gen_dir.path}/cpp/") -cereal = env.Library('cereal', [f'gen/cpp/{s}.c++' for s in schema_files]) +cereal = env.Library('cereal', [f'gen/cpp/{s}.c++' for s in all_output]) # Build messaging services_h = env.Command(['services.h'], ['services.py'], 'python3 ' + cereal_dir.path + '/services.py > $TARGET') diff --git a/cereal/__init__.py b/cereal/__init__.py index 93f4d77227..d4f6504652 100644 --- a/cereal/__init__.py +++ b/cereal/__init__.py @@ -4,8 +4,8 @@ from importlib.resources import as_file, files capnp.remove_import_hook() -with as_file(files("cereal")) as fspath: +with as_file(files("cereal")) as fspath, as_file(files("opendbc")) as opendbc_path: CEREAL_PATH = fspath.as_posix() - log = capnp.load(os.path.join(CEREAL_PATH, "log.capnp")) - car = capnp.load(os.path.join(CEREAL_PATH, "car.capnp")) - custom = capnp.load(os.path.join(CEREAL_PATH, "custom.capnp")) + opendbc_import_path = os.path.join(os.path.realpath(opendbc_path.as_posix()), 'car') + log = capnp.load(os.path.join(CEREAL_PATH, "log.capnp"), imports=[opendbc_import_path]) + custom = capnp.load(os.path.join(CEREAL_PATH, "custom.capnp"), imports=[opendbc_import_path]) diff --git a/cereal/car.capnp b/cereal/car.capnp deleted file mode 120000 index 4bc7f89b1f..0000000000 --- a/cereal/car.capnp +++ /dev/null @@ -1 +0,0 @@ -../opendbc_repo/opendbc/car/car.capnp \ No newline at end of file diff --git a/cereal/custom.capnp b/cereal/custom.capnp index 3348e859ef..42804e0a97 100644 --- a/cereal/custom.capnp +++ b/cereal/custom.capnp @@ -1,4 +1,4 @@ -using Cxx = import "./include/c++.capnp"; +using Cxx = import "/include/c++.capnp"; $Cxx.namespace("cereal"); @0xb526ba661d550a59; diff --git a/cereal/deprecated.capnp b/cereal/deprecated.capnp index 5e4b0b4de0..37153e4d62 100644 --- a/cereal/deprecated.capnp +++ b/cereal/deprecated.capnp @@ -1,4 +1,4 @@ -using Cxx = import "./include/c++.capnp"; +using Cxx = import "/include/c++.capnp"; $Cxx.namespace("cereal"); @0x80ef1ec4889c2a63; diff --git a/cereal/log.capnp b/cereal/log.capnp index ec7a065eb7..02536e46b1 100644 --- a/cereal/log.capnp +++ b/cereal/log.capnp @@ -1,7 +1,7 @@ -using Cxx = import "./include/c++.capnp"; +using Cxx = import "/include/c++.capnp"; $Cxx.namespace("cereal"); -using Car = import "car.capnp"; +using Car = import "/car.capnp"; using Deprecated = import "deprecated.capnp"; using Custom = import "custom.capnp"; diff --git a/cereal/messaging/tests/test_messaging.py b/cereal/messaging/tests/test_messaging.py index 97388446f4..22601158a6 100644 --- a/cereal/messaging/tests/test_messaging.py +++ b/cereal/messaging/tests/test_messaging.py @@ -8,7 +8,8 @@ import time from openpilot.common.parameterized import parameterized import pytest -from cereal import log, car +from cereal import log +from opendbc.car.structs import car import cereal.messaging as messaging from cereal.services import SERVICE_LIST diff --git a/opendbc_repo b/opendbc_repo index 75889fd928..7e3a0703b9 160000 --- a/opendbc_repo +++ b/opendbc_repo @@ -1 +1 @@ -Subproject commit 75889fd9283730feb6ec824a00975fda0807bbc5 +Subproject commit 7e3a0703b9d254812151f3660b6f8549432c954e diff --git a/selfdrive/car/car_specific.py b/selfdrive/car/car_specific.py index baa29978e3..1487f4380c 100644 --- a/selfdrive/car/car_specific.py +++ b/selfdrive/car/car_specific.py @@ -1,4 +1,5 @@ -from cereal import car, log +from cereal import log +from opendbc.car.structs import car from opendbc.car import DT_CTRL, structs from opendbc.car.car_helpers import interfaces from opendbc.car.interfaces import MAX_CTRL_SPEED diff --git a/selfdrive/car/card.py b/selfdrive/car/card.py index 1660881a9a..f5186699ac 100755 --- a/selfdrive/car/card.py +++ b/selfdrive/car/card.py @@ -5,7 +5,8 @@ import threading import cereal.messaging as messaging -from cereal import car, log +from cereal import log +from opendbc.car.structs import car from openpilot.common.params import Params from openpilot.common.realtime import config_realtime_process, Priority, Ratekeeper diff --git a/selfdrive/car/cruise.py b/selfdrive/car/cruise.py index 0d761844b5..5e2f9db306 100644 --- a/selfdrive/car/cruise.py +++ b/selfdrive/car/cruise.py @@ -1,7 +1,7 @@ import math import numpy as np -from cereal import car +from opendbc.car.structs import car from openpilot.common.constants import CV diff --git a/selfdrive/car/tests/test_car_interfaces.py b/selfdrive/car/tests/test_car_interfaces.py index 1bc59326a2..7ddd73c2d8 100644 --- a/selfdrive/car/tests/test_car_interfaces.py +++ b/selfdrive/car/tests/test_car_interfaces.py @@ -3,7 +3,7 @@ import hypothesis.strategies as st from hypothesis import Phase, given, settings from openpilot.common.parameterized import parameterized -from cereal import car +from opendbc.car.structs import car from opendbc.car import DT_CTRL from opendbc.car.structs import CarParams from opendbc.car.tests.test_car_interfaces import get_fuzzy_car_interface diff --git a/selfdrive/car/tests/test_cruise_speed.py b/selfdrive/car/tests/test_cruise_speed.py index bfb060874d..3b3fb115ba 100644 --- a/selfdrive/car/tests/test_cruise_speed.py +++ b/selfdrive/car/tests/test_cruise_speed.py @@ -5,7 +5,7 @@ import numpy as np from openpilot.common.parameterized import parameterized_class from cereal import log from openpilot.selfdrive.car.cruise import VCruiseHelper, V_CRUISE_MIN, V_CRUISE_MAX, V_CRUISE_INITIAL, IMPERIAL_INCREMENT -from cereal import car +from opendbc.car.structs import car from openpilot.common.constants import CV from openpilot.selfdrive.test.longitudinal_maneuvers.maneuver import Maneuver diff --git a/selfdrive/controls/controlsd.py b/selfdrive/controls/controlsd.py index 5e3817c298..67566cf0a7 100755 --- a/selfdrive/controls/controlsd.py +++ b/selfdrive/controls/controlsd.py @@ -2,7 +2,8 @@ import math from numbers import Number -from cereal import car, log +from cereal import log +from opendbc.car.structs import car import cereal.messaging as messaging from openpilot.common.constants import CV from openpilot.common.params import Params diff --git a/selfdrive/controls/lib/longcontrol.py b/selfdrive/controls/lib/longcontrol.py index 62dbc842c5..1132fedda6 100644 --- a/selfdrive/controls/lib/longcontrol.py +++ b/selfdrive/controls/lib/longcontrol.py @@ -1,5 +1,5 @@ import numpy as np -from cereal import car +from opendbc.car.structs import car from openpilot.common.realtime import DT_CTRL from openpilot.selfdrive.controls.lib.drive_helpers import CONTROL_N from openpilot.common.pid import PIDController diff --git a/selfdrive/controls/plannerd.py b/selfdrive/controls/plannerd.py index bec7eede0b..49c4473590 100755 --- a/selfdrive/controls/plannerd.py +++ b/selfdrive/controls/plannerd.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -from cereal import car +from opendbc.car.structs import car from openpilot.common.params import Params from openpilot.common.realtime import Priority, config_realtime_process from openpilot.common.swaglog import cloudlog diff --git a/selfdrive/controls/radard.py b/selfdrive/controls/radard.py index 6450ff416a..9d438661b3 100755 --- a/selfdrive/controls/radard.py +++ b/selfdrive/controls/radard.py @@ -5,7 +5,8 @@ from collections import deque from typing import Any import capnp -from cereal import messaging, log, car +from cereal import messaging, log +from opendbc.car.structs import car from openpilot.common.filter_simple import FirstOrderFilter from openpilot.common.params import Params from openpilot.common.realtime import DT_MDL, Priority, config_realtime_process diff --git a/selfdrive/controls/tests/test_latcontrol.py b/selfdrive/controls/tests/test_latcontrol.py index 5c3381edce..9cd5e6307c 100644 --- a/selfdrive/controls/tests/test_latcontrol.py +++ b/selfdrive/controls/tests/test_latcontrol.py @@ -1,6 +1,7 @@ from openpilot.common.parameterized import parameterized -from cereal import car, log +from cereal import log +from opendbc.car.structs import car from opendbc.car.car_helpers import interfaces from opendbc.car.honda.values import CAR as HONDA from opendbc.car.toyota.values import CAR as TOYOTA diff --git a/selfdrive/controls/tests/test_latcontrol_torque_buffer.py b/selfdrive/controls/tests/test_latcontrol_torque_buffer.py index ab1d2c7b36..6a7ed5419e 100644 --- a/selfdrive/controls/tests/test_latcontrol_torque_buffer.py +++ b/selfdrive/controls/tests/test_latcontrol_torque_buffer.py @@ -1,6 +1,7 @@ from openpilot.common.parameterized import parameterized -from cereal import car, log +from cereal import log +from opendbc.car.structs import car from opendbc.car.car_helpers import interfaces from opendbc.car.toyota.values import CAR as TOYOTA from opendbc.car.vehicle_model import VehicleModel diff --git a/selfdrive/controls/tests/test_longcontrol.py b/selfdrive/controls/tests/test_longcontrol.py index ab50810d89..da916b156f 100644 --- a/selfdrive/controls/tests/test_longcontrol.py +++ b/selfdrive/controls/tests/test_longcontrol.py @@ -1,4 +1,4 @@ -from cereal import car +from opendbc.car.structs import car from openpilot.selfdrive.controls.lib.longcontrol import LongCtrlState, long_control_state_trans diff --git a/selfdrive/controls/tests/test_torqued_lat_accel_offset.py b/selfdrive/controls/tests/test_torqued_lat_accel_offset.py index 2f95d7c14f..f1ca0c5f49 100644 --- a/selfdrive/controls/tests/test_torqued_lat_accel_offset.py +++ b/selfdrive/controls/tests/test_torqued_lat_accel_offset.py @@ -1,5 +1,6 @@ import numpy as np -from cereal import car, messaging +from cereal import messaging +from opendbc.car.structs import car from opendbc.car import ACCELERATION_DUE_TO_GRAVITY from opendbc.car import structs from opendbc.car.lateral import get_friction, FRICTION_THRESHOLD diff --git a/selfdrive/locationd/calibrationd.py b/selfdrive/locationd/calibrationd.py index c444d43983..23dacf6821 100755 --- a/selfdrive/locationd/calibrationd.py +++ b/selfdrive/locationd/calibrationd.py @@ -11,7 +11,8 @@ import capnp import numpy as np from typing import NoReturn -from cereal import log, car +from cereal import log +from opendbc.car.structs import car import cereal.messaging as messaging from openpilot.common.hardware import HARDWARE from openpilot.common.constants import CV diff --git a/selfdrive/locationd/lagd.py b/selfdrive/locationd/lagd.py index 0069bb51b9..17aa0a4303 100755 --- a/selfdrive/locationd/lagd.py +++ b/selfdrive/locationd/lagd.py @@ -6,7 +6,8 @@ from collections import deque from functools import partial import cereal.messaging as messaging -from cereal import car, log +from cereal import log +from opendbc.car.structs import car from cereal.services import SERVICE_LIST from openpilot.common.constants import CV from openpilot.common.params import Params diff --git a/selfdrive/locationd/paramsd.py b/selfdrive/locationd/paramsd.py index 02d09c506e..6acf335178 100755 --- a/selfdrive/locationd/paramsd.py +++ b/selfdrive/locationd/paramsd.py @@ -4,7 +4,8 @@ import numpy as np import capnp import cereal.messaging as messaging -from cereal import car, log +from cereal import log +from opendbc.car.structs import car from openpilot.common.params import Params from openpilot.common.realtime import config_realtime_process, DT_MDL from openpilot.selfdrive.locationd.models.car_kf import CarKalman, ObservationKind, States diff --git a/selfdrive/locationd/test/test_lagd.py b/selfdrive/locationd/test/test_lagd.py index 63ea2b5fab..a0e4ee31fa 100644 --- a/selfdrive/locationd/test/test_lagd.py +++ b/selfdrive/locationd/test/test_lagd.py @@ -3,7 +3,8 @@ import numpy as np import time import pytest -from cereal import messaging, log, car +from cereal import messaging, log +from opendbc.car.structs import car from openpilot.selfdrive.locationd.lagd import LateralLagEstimator, retrieve_initial_lag, masked_normalized_cross_correlation, \ BLOCK_NUM_NEEDED, BLOCK_SIZE, MIN_OKAY_WINDOW_SEC, VERSION from openpilot.selfdrive.test.process_replay.migration import migrate, migrate_carParams diff --git a/selfdrive/locationd/test/test_torqued.py b/selfdrive/locationd/test/test_torqued.py index 53f3120c36..ac8e40fc30 100644 --- a/selfdrive/locationd/test/test_torqued.py +++ b/selfdrive/locationd/test/test_torqued.py @@ -1,4 +1,4 @@ -from cereal import car +from opendbc.car.structs import car from openpilot.selfdrive.locationd.torqued import TorqueEstimator diff --git a/selfdrive/locationd/torqued.py b/selfdrive/locationd/torqued.py index 16468f7055..fdd50d3eb6 100755 --- a/selfdrive/locationd/torqued.py +++ b/selfdrive/locationd/torqued.py @@ -4,7 +4,8 @@ import numpy as np from collections import deque, defaultdict import cereal.messaging as messaging -from cereal import car, log +from cereal import log +from opendbc.car.structs import car from openpilot.common.constants import ACCELERATION_DUE_TO_GRAVITY from openpilot.common.params import Params from openpilot.common.realtime import config_realtime_process, DT_MDL diff --git a/selfdrive/modeld/modeld.py b/selfdrive/modeld/modeld.py index 372e8704a2..18f665529c 100755 --- a/selfdrive/modeld/modeld.py +++ b/selfdrive/modeld/modeld.py @@ -6,7 +6,8 @@ import time import pickle import numpy as np import cereal.messaging as messaging -from cereal import car, log +from cereal import log +from opendbc.car.structs import car from cereal.messaging import PubMaster, SubMaster from msgq.visionipc import VisionIpcClient, VisionStreamType, VisionBuf from opendbc.car.car_helpers import get_demo_car_params diff --git a/selfdrive/monitoring/policy.py b/selfdrive/monitoring/policy.py index cf784818ee..146717349d 100644 --- a/selfdrive/monitoring/policy.py +++ b/selfdrive/monitoring/policy.py @@ -2,7 +2,8 @@ from collections import defaultdict from math import atan2, radians import numpy as np -from cereal import car, log +from cereal import log +from opendbc.car.structs import car import cereal.messaging as messaging from openpilot.common.realtime import DT_DMON from openpilot.common.filter_simple import FirstOrderFilter diff --git a/selfdrive/pandad/tests/test_pandad_loopback.py b/selfdrive/pandad/tests/test_pandad_loopback.py index bc90f42a83..5543b6d03c 100644 --- a/selfdrive/pandad/tests/test_pandad_loopback.py +++ b/selfdrive/pandad/tests/test_pandad_loopback.py @@ -7,7 +7,8 @@ from collections import defaultdict from pprint import pprint import cereal.messaging as messaging -from cereal import car, log +from cereal import log +from opendbc.car.structs import car from opendbc.car.can_definitions import CanData from openpilot.common.utils import retry from openpilot.common.params import Params diff --git a/selfdrive/selfdrived/events.py b/selfdrive/selfdrived/events.py index 9a31e6f6b3..efdbd35d7b 100755 --- a/selfdrive/selfdrived/events.py +++ b/selfdrive/selfdrived/events.py @@ -5,7 +5,8 @@ import os from enum import IntEnum from collections.abc import Callable -from cereal import log, car +from cereal import log +from opendbc.car.structs import car import cereal.messaging as messaging from openpilot.common.constants import CV from openpilot.common.git import get_short_branch diff --git a/selfdrive/selfdrived/helpers.py b/selfdrive/selfdrived/helpers.py index f7468cbe43..3182d23403 100644 --- a/selfdrive/selfdrived/helpers.py +++ b/selfdrive/selfdrived/helpers.py @@ -1,7 +1,8 @@ import math from enum import StrEnum, auto -from cereal import car, messaging +from cereal import messaging +from opendbc.car.structs import car from openpilot.common.realtime import DT_CTRL from openpilot.selfdrive.locationd.helpers import Pose from opendbc.car import ACCELERATION_DUE_TO_GRAVITY diff --git a/selfdrive/selfdrived/selfdrived.py b/selfdrive/selfdrived/selfdrived.py index b4bd2a7b90..261a62ff6a 100755 --- a/selfdrive/selfdrived/selfdrived.py +++ b/selfdrive/selfdrived/selfdrived.py @@ -5,7 +5,8 @@ import threading import cereal.messaging as messaging -from cereal import car, log +from cereal import log +from opendbc.car.structs import car from msgq.visionipc import VisionIpcClient, VisionStreamType diff --git a/selfdrive/selfdrived/tests/test_alerts.py b/selfdrive/selfdrived/tests/test_alerts.py index 5d5a1733e7..3cd137d586 100644 --- a/selfdrive/selfdrived/tests/test_alerts.py +++ b/selfdrive/selfdrived/tests/test_alerts.py @@ -4,7 +4,8 @@ import os import random from PIL import Image, ImageDraw, ImageFont -from cereal import log, car +from cereal import log +from opendbc.car.structs import car from cereal.messaging import SubMaster from openpilot.common.basedir import BASEDIR from openpilot.common.params import Params diff --git a/selfdrive/test/process_replay/migration.py b/selfdrive/test/process_replay/migration.py index 5a3403c925..e10db26e79 100644 --- a/selfdrive/test/process_replay/migration.py +++ b/selfdrive/test/process_replay/migration.py @@ -5,7 +5,8 @@ import capnp import functools import traceback -from cereal import messaging, car, log +from cereal import messaging, log +from opendbc.car.structs import car from opendbc.car.fingerprints import MIGRATION from opendbc.car.toyota.values import EPS_SCALE, ToyotaSafetyFlags from opendbc.car.ford.values import CAR as FORD, FordFlags, FordSafetyFlags diff --git a/selfdrive/test/process_replay/process_replay.py b/selfdrive/test/process_replay/process_replay.py index 2f198b0476..110b0101a5 100755 --- a/selfdrive/test/process_replay/process_replay.py +++ b/selfdrive/test/process_replay/process_replay.py @@ -15,7 +15,7 @@ import capnp from openpilot.common.hardware.hw import Paths import cereal.messaging as messaging -from cereal import car +from opendbc.car.structs import car from cereal.services import SERVICE_LIST from msgq.visionipc import VisionIpcServer, get_endpoint_name as vipc_get_endpoint_name from opendbc.car.can_definitions import CanData diff --git a/selfdrive/ui/feedback/feedbackd.py b/selfdrive/ui/feedback/feedbackd.py index 2d131a0d5e..b59954926c 100755 --- a/selfdrive/ui/feedback/feedbackd.py +++ b/selfdrive/ui/feedback/feedbackd.py @@ -2,7 +2,7 @@ import cereal.messaging as messaging from openpilot.common.params import Params from openpilot.common.swaglog import cloudlog -from cereal import car +from opendbc.car.structs import car from openpilot.system.micd import SAMPLE_RATE, SAMPLE_BUFFER FEEDBACK_MAX_DURATION = 10.0 diff --git a/selfdrive/ui/mici/onroad/alert_renderer.py b/selfdrive/ui/mici/onroad/alert_renderer.py index 6505ca47c8..a9cb5790d2 100644 --- a/selfdrive/ui/mici/onroad/alert_renderer.py +++ b/selfdrive/ui/mici/onroad/alert_renderer.py @@ -5,7 +5,8 @@ import pyray as rl import random import string from dataclasses import dataclass -from cereal import messaging, log, car +from cereal import messaging, log +from opendbc.car.structs import car from openpilot.selfdrive.ui.ui_state import ui_state from openpilot.common.filter_simple import BounceFilter, FirstOrderFilter from openpilot.common.hardware import TICI diff --git a/selfdrive/ui/mici/onroad/augmented_road_view.py b/selfdrive/ui/mici/onroad/augmented_road_view.py index e6609f9c09..0fe5875b8d 100644 --- a/selfdrive/ui/mici/onroad/augmented_road_view.py +++ b/selfdrive/ui/mici/onroad/augmented_road_view.py @@ -1,6 +1,7 @@ import numpy as np import pyray as rl -from cereal import car, log +from cereal import log +from opendbc.car.structs import car from msgq.visionipc import VisionStreamType from openpilot.selfdrive.ui.ui_state import ui_state, UIStatus from openpilot.selfdrive.ui.mici.onroad import SIDE_PANEL_WIDTH diff --git a/selfdrive/ui/mici/onroad/driver_camera_dialog.py b/selfdrive/ui/mici/onroad/driver_camera_dialog.py index df5afe2e7c..f45cf33912 100644 --- a/selfdrive/ui/mici/onroad/driver_camera_dialog.py +++ b/selfdrive/ui/mici/onroad/driver_camera_dialog.py @@ -1,5 +1,6 @@ import pyray as rl -from cereal import car, log, messaging +from cereal import log, messaging +from opendbc.car.structs import car from msgq.visionipc import VisionStreamType from openpilot.selfdrive.ui.mici.onroad.cameraview import CameraView from openpilot.selfdrive.ui.mici.onroad.driver_state import DriverStateRenderer diff --git a/selfdrive/ui/mici/onroad/model_renderer.py b/selfdrive/ui/mici/onroad/model_renderer.py index 12500bdcd4..6e335b0af2 100644 --- a/selfdrive/ui/mici/onroad/model_renderer.py +++ b/selfdrive/ui/mici/onroad/model_renderer.py @@ -1,7 +1,8 @@ import colorsys import numpy as np import pyray as rl -from cereal import messaging, car +from cereal import messaging +from opendbc.car.structs import car from dataclasses import dataclass, field from openpilot.common.params import Params from openpilot.common.filter_simple import FirstOrderFilter diff --git a/selfdrive/ui/onroad/model_renderer.py b/selfdrive/ui/onroad/model_renderer.py index b9f601f8fb..94e5637a09 100644 --- a/selfdrive/ui/onroad/model_renderer.py +++ b/selfdrive/ui/onroad/model_renderer.py @@ -1,7 +1,8 @@ import colorsys import numpy as np import pyray as rl -from cereal import messaging, car +from cereal import messaging +from opendbc.car.structs import car from dataclasses import dataclass, field from openpilot.common.filter_simple import FirstOrderFilter from openpilot.common.params import Params diff --git a/selfdrive/ui/soundd.py b/selfdrive/ui/soundd.py index ca5c824c29..7766d0321b 100644 --- a/selfdrive/ui/soundd.py +++ b/selfdrive/ui/soundd.py @@ -4,7 +4,8 @@ import time import wave -from cereal import car, messaging +from cereal import messaging +from opendbc.car.structs import car from openpilot.common.basedir import BASEDIR from openpilot.common.filter_simple import FirstOrderFilter from openpilot.common.realtime import Ratekeeper diff --git a/selfdrive/ui/tests/diff/replay_script.py b/selfdrive/ui/tests/diff/replay_script.py index ad7e8952d6..f4c97a223f 100644 --- a/selfdrive/ui/tests/diff/replay_script.py +++ b/selfdrive/ui/tests/diff/replay_script.py @@ -5,7 +5,8 @@ from dataclasses import dataclass import math -from cereal import car, log, messaging +from cereal import log, messaging +from opendbc.car.structs import car from cereal.messaging import PubMaster from openpilot.common.basedir import BASEDIR from openpilot.common.params import Params diff --git a/selfdrive/ui/tests/test_feedbackd.py b/selfdrive/ui/tests/test_feedbackd.py index 0f7148de04..ada2c4763e 100644 --- a/selfdrive/ui/tests/test_feedbackd.py +++ b/selfdrive/ui/tests/test_feedbackd.py @@ -1,6 +1,6 @@ import pytest import cereal.messaging as messaging -from cereal import car +from opendbc.car.structs import car from openpilot.common.params import Params from openpilot.system.manager.process_config import managed_processes diff --git a/selfdrive/ui/tests/test_soundd.py b/selfdrive/ui/tests/test_soundd.py index a9da8455eb..ca153b6eef 100644 --- a/selfdrive/ui/tests/test_soundd.py +++ b/selfdrive/ui/tests/test_soundd.py @@ -1,4 +1,4 @@ -from cereal import car +from opendbc.car.structs import car from cereal import messaging from cereal.messaging import SubMaster, PubMaster from openpilot.selfdrive.ui.soundd import SELFDRIVE_STATE_TIMEOUT, check_selfdrive_timeout_alert diff --git a/selfdrive/ui/ui_state.py b/selfdrive/ui/ui_state.py index d5b0142744..4cc5810bb9 100644 --- a/selfdrive/ui/ui_state.py +++ b/selfdrive/ui/ui_state.py @@ -3,7 +3,8 @@ import time import threading from collections.abc import Callable from enum import Enum -from cereal import messaging, car, log +from cereal import messaging, log +from opendbc.car.structs import car from openpilot.common.filter_simple import FirstOrderFilter from openpilot.common.params import Params from openpilot.common.realtime import drop_realtime diff --git a/system/athena/athenad.py b/system/athena/athenad.py index 6d1325dac6..d5bcc92f13 100755 --- a/system/athena/athenad.py +++ b/system/athena/athenad.py @@ -28,7 +28,8 @@ from websocket import (ABNF, WebSocket, WebSocketException, WebSocketTimeoutExce create_connection) import cereal.messaging as messaging -from cereal import car, log +from cereal import log +from opendbc.car.structs import car from cereal.services import SERVICE_LIST from openpilot.common.api import Api, get_key_pair from openpilot.common.utils import CallbackReader, get_upload_stream diff --git a/system/manager/process.py b/system/manager/process.py index cdb316e1a1..63dbb35eb1 100644 --- a/system/manager/process.py +++ b/system/manager/process.py @@ -9,7 +9,8 @@ from multiprocessing import Process from setproctitle import setproctitle -from cereal import car, log +from cereal import log +from opendbc.car.structs import car import cereal.messaging as messaging import openpilot.system.sentry as sentry from openpilot.common.basedir import BASEDIR diff --git a/system/manager/process_config.py b/system/manager/process_config.py index f610d1c786..c4cf834560 100644 --- a/system/manager/process_config.py +++ b/system/manager/process_config.py @@ -2,7 +2,7 @@ import os import operator import platform -from cereal import car +from opendbc.car.structs import car from openpilot.common.params import Params from openpilot.common.hardware import PC, TICI from openpilot.system.manager.process import PythonProcess, NativeProcess, DaemonProcess diff --git a/system/manager/test/test_manager.py b/system/manager/test/test_manager.py index 73c66ff3fc..273ddc8fd9 100644 --- a/system/manager/test/test_manager.py +++ b/system/manager/test/test_manager.py @@ -3,7 +3,7 @@ import pytest import signal import time -from cereal import car +from opendbc.car.structs import car from openpilot.common.params import Params import openpilot.system.manager.manager as manager from openpilot.system.manager.process import ensure_running diff --git a/tools/jotpluggler/SConscript b/tools/jotpluggler/SConscript index 078e173959..d65b8c02e3 100644 --- a/tools/jotpluggler/SConscript +++ b/tools/jotpluggler/SConscript @@ -95,6 +95,8 @@ event_extractors = jot_env.Command("generated_event_extractors.h", [ "generate_event_extractors.py", jot_env.Glob("#cereal/*.capnp"), jot_env.Glob("#cereal/include/*.capnp"), + "#opendbc_repo/opendbc/car/car.capnp", + "#opendbc_repo/opendbc/car/include/c++.capnp", ], generate_event_extractors, ) diff --git a/tools/jotpluggler/generate_event_extractors.py b/tools/jotpluggler/generate_event_extractors.py index 1aba9578cd..0ffa11c36c 100644 --- a/tools/jotpluggler/generate_event_extractors.py +++ b/tools/jotpluggler/generate_event_extractors.py @@ -321,7 +321,7 @@ if __name__ == "__main__": repo_root = Path(sys.argv[1]).resolve() output = Path(sys.argv[2]) capnp.remove_import_hook() - log = capnp.load(str(repo_root / "cereal" / "log.capnp")) + log = capnp.load(str(repo_root / "cereal" / "log.capnp"), imports=[str(repo_root / "opendbc_repo" / "opendbc" / "car")]) generated = Generator(log.Event.schema).generate() output.parent.mkdir(parents=True, exist_ok=True) output.write_text(generated) diff --git a/tools/joystick/joystickd.py b/tools/joystick/joystickd.py index 789dad5623..f06097658a 100755 --- a/tools/joystick/joystickd.py +++ b/tools/joystick/joystickd.py @@ -3,7 +3,8 @@ import math import numpy as np -from cereal import messaging, car +from cereal import messaging +from opendbc.car.structs import car from opendbc.car.vehicle_model import VehicleModel from openpilot.common.realtime import DT_CTRL, Ratekeeper from openpilot.common.params import Params diff --git a/tools/lateral_maneuvers/generate_report.py b/tools/lateral_maneuvers/generate_report.py index 5db486a70d..e26690e2da 100755 --- a/tools/lateral_maneuvers/generate_report.py +++ b/tools/lateral_maneuvers/generate_report.py @@ -11,7 +11,7 @@ from pathlib import Path import matplotlib.pyplot as plt from openpilot.common.utils import tabulate -from cereal import car +from opendbc.car.structs import car from openpilot.common.filter_simple import FirstOrderFilter from openpilot.selfdrive.controls.lib.latcontrol_torque import LP_FILTER_CUTOFF_HZ from openpilot.tools.lib.logreader import LogReader diff --git a/tools/lateral_maneuvers/lateral_maneuversd.py b/tools/lateral_maneuvers/lateral_maneuversd.py index 1cc2d3560e..61f51145df 100755 --- a/tools/lateral_maneuvers/lateral_maneuversd.py +++ b/tools/lateral_maneuvers/lateral_maneuversd.py @@ -2,7 +2,8 @@ import numpy as np from dataclasses import dataclass -from cereal import messaging, car +from cereal import messaging +from opendbc.car.structs import car from openpilot.common.constants import CV from openpilot.common.realtime import DT_MDL from openpilot.common.params import Params diff --git a/tools/longitudinal_maneuvers/maneuversd.py b/tools/longitudinal_maneuvers/maneuversd.py index f8dc6787cc..cf53f8e85a 100755 --- a/tools/longitudinal_maneuvers/maneuversd.py +++ b/tools/longitudinal_maneuvers/maneuversd.py @@ -2,7 +2,8 @@ import numpy as np from dataclasses import dataclass -from cereal import messaging, car +from cereal import messaging +from opendbc.car.structs import car from openpilot.common.constants import CV from openpilot.common.realtime import DT_MDL from openpilot.common.params import Params diff --git a/tools/scripts/car/fw_versions.py b/tools/scripts/car/fw_versions.py index 81692147f0..6fdac5e46d 100755 --- a/tools/scripts/car/fw_versions.py +++ b/tools/scripts/car/fw_versions.py @@ -2,7 +2,7 @@ import time import argparse import cereal.messaging as messaging -from cereal import car +from opendbc.car.structs import car from opendbc.car.carlog import carlog from opendbc.car.fw_versions import get_fw_versions, match_fw_to_car from opendbc.car.vin import get_vin diff --git a/tools/scripts/cycle_alerts.py b/tools/scripts/cycle_alerts.py index 4b1def4fc6..7dc963aafd 100755 --- a/tools/scripts/cycle_alerts.py +++ b/tools/scripts/cycle_alerts.py @@ -2,7 +2,8 @@ import time import random -from cereal import car, log +from cereal import log +from opendbc.car.structs import car import cereal.messaging as messaging from opendbc.car.honda.interface import CarInterface from openpilot.common.realtime import DT_CTRL diff --git a/tools/scripts/set_car_params.py b/tools/scripts/set_car_params.py index dabb6b7065..3864de0838 100755 --- a/tools/scripts/set_car_params.py +++ b/tools/scripts/set_car_params.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 import sys -from cereal import car +from opendbc.car.structs import car from openpilot.common.params import Params from openpilot.tools.lib.route import Route from openpilot.tools.lib.logreader import LogReader diff --git a/tools/scripts/uiview.py b/tools/scripts/uiview.py index a8d50e7f99..3a81f2f84f 100755 --- a/tools/scripts/uiview.py +++ b/tools/scripts/uiview.py @@ -1,7 +1,8 @@ #!/usr/bin/env python3 import time -from cereal import car, log, messaging +from cereal import log, messaging +from opendbc.car.structs import car from openpilot.common.params import Params from openpilot.system.manager.process_config import managed_processes from openpilot.common.hardware import HARDWARE From 37eda06c95cf808770ad7b3a2ae30d1eae1b12c0 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Sun, 21 Jun 2026 17:55:17 -0700 Subject: [PATCH 074/151] move cereal/ into nested openpilot (#38220) --- .gitignore | 6 +++--- RELEASES.md | 2 +- SConstruct | 4 ++-- common/hardware/base.h | 2 +- common/hardware/base.py | 2 +- common/hardware/pc/hardware.py | 2 +- common/hardware/tici/hardware.py | 2 +- common/mock/__init__.py | 4 ++-- common/mock/generators.py | 2 +- common/params_keys.h | 2 +- docs/CONTRIBUTING.md | 2 +- docs/concepts/logs.md | 4 ++-- {cereal => openpilot/cereal}/README.md | 2 +- {cereal => openpilot/cereal}/SConscript | 0 {cereal => openpilot/cereal}/__init__.py | 2 +- {cereal => openpilot/cereal}/custom.capnp | 0 {cereal => openpilot/cereal}/deprecated.capnp | 0 {cereal => openpilot/cereal}/include/c++.capnp | 0 {cereal => openpilot/cereal}/log.capnp | 0 .../cereal}/messaging/__init__.py | 4 ++-- .../cereal}/messaging/bridge.cc | 4 ++-- .../cereal}/messaging/bridge_zmq.cc | 2 +- .../cereal}/messaging/bridge_zmq.h | 0 .../cereal}/messaging/messaging.h | 2 +- .../cereal}/messaging/msgq_to_zmq.cc | 4 ++-- .../cereal}/messaging/msgq_to_zmq.h | 2 +- .../cereal}/messaging/socketmaster.cc | 4 ++-- .../cereal}/messaging/tests/__init__.py | 0 .../cereal}/messaging/tests/test_messaging.py | 6 +++--- .../messaging/tests/test_pub_sub_master.py | 6 +++--- .../cereal}/messaging/tests/test_services.py | 4 ++-- {cereal => openpilot/cereal}/services.py | 0 pyproject.toml | 8 ++++---- release/pack.py | 2 +- scripts/lint/lint.sh | 2 +- selfdrive/car/car_specific.py | 2 +- selfdrive/car/card.py | 4 ++-- selfdrive/car/tests/test_cruise_speed.py | 2 +- selfdrive/car/tests/test_docs.py | 1 - selfdrive/car/tests/test_models.py | 1 - selfdrive/controls/controlsd.py | 4 ++-- selfdrive/controls/lib/desire_helper.py | 2 +- selfdrive/controls/lib/latcontrol_angle.py | 2 +- selfdrive/controls/lib/latcontrol_curvature.py | 2 +- selfdrive/controls/lib/latcontrol_pid.py | 2 +- selfdrive/controls/lib/latcontrol_torque.py | 2 +- selfdrive/controls/lib/ldw.py | 2 +- .../lib/longitudinal_mpc_lib/long_mpc.py | 2 +- selfdrive/controls/lib/longitudinal_planner.py | 2 +- selfdrive/controls/plannerd.py | 2 +- selfdrive/controls/radard.py | 2 +- .../controls/tests/test_following_distance.py | 2 +- selfdrive/controls/tests/test_latcontrol.py | 2 +- .../tests/test_latcontrol_torque_buffer.py | 2 +- selfdrive/controls/tests/test_leads.py | 2 +- .../tests/test_torqued_lat_accel_offset.py | 2 +- selfdrive/locationd/calibrationd.py | 4 ++-- selfdrive/locationd/helpers.py | 2 +- selfdrive/locationd/lagd.py | 6 +++--- selfdrive/locationd/locationd.py | 4 ++-- selfdrive/locationd/paramsd.py | 4 ++-- selfdrive/locationd/test/test_calibrationd.py | 4 ++-- selfdrive/locationd/test/test_lagd.py | 2 +- selfdrive/locationd/test/test_paramsd.py | 2 +- selfdrive/locationd/torqued.py | 4 ++-- selfdrive/modeld/dmonitoringmodeld.py | 4 ++-- selfdrive/modeld/fill_model_msg.py | 2 +- selfdrive/modeld/modeld.py | 6 +++--- selfdrive/monitoring/dmonitoringd.py | 2 +- selfdrive/monitoring/policy.py | 4 ++-- selfdrive/monitoring/test_monitoring.py | 2 +- selfdrive/pandad/panda.cc | 2 +- selfdrive/pandad/panda.h | 4 ++-- selfdrive/pandad/panda_safety.cc | 2 +- selfdrive/pandad/pandad.cc | 6 +++--- selfdrive/pandad/pandad_api_impl.py | 2 +- selfdrive/pandad/tests/test_pandad.py | 4 ++-- .../pandad/tests/test_pandad_canprotocol.cc | 2 +- selfdrive/pandad/tests/test_pandad_loopback.py | 4 ++-- selfdrive/pandad/tests/test_pandad_spi.py | 4 ++-- selfdrive/selfdrived/events.py | 6 +++--- selfdrive/selfdrived/helpers.py | 2 +- selfdrive/selfdrived/selfdrived.py | 4 ++-- selfdrive/selfdrived/state.py | 2 +- selfdrive/selfdrived/tests/test_alerts.py | 4 ++-- .../selfdrived/tests/test_state_machine.py | 2 +- selfdrive/test/fuzzy_generation.py | 2 +- selfdrive/test/helpers.py | 2 +- selfdrive/test/longitudinal_maneuvers/plant.py | 4 ++-- selfdrive/test/process_replay/diff_report.py | 1 - selfdrive/test/process_replay/migration.py | 2 +- selfdrive/test/process_replay/process_replay.py | 4 ++-- selfdrive/test/process_replay/test_fuzzy.py | 2 +- selfdrive/test/process_replay/test_processes.py | 1 - selfdrive/test/test_onroad.py | 6 +++--- selfdrive/test/test_power_draw.py | 4 ++-- selfdrive/test/update_ci_routes.py | 1 - selfdrive/ui/feedback/feedbackd.py | 2 +- selfdrive/ui/layouts/main.py | 2 +- selfdrive/ui/layouts/settings/device.py | 2 +- selfdrive/ui/layouts/settings/toggles.py | 2 +- selfdrive/ui/layouts/sidebar.py | 2 +- selfdrive/ui/mici/layouts/home.py | 2 +- selfdrive/ui/mici/layouts/main.py | 2 +- selfdrive/ui/mici/layouts/settings/toggles.py | 2 +- selfdrive/ui/mici/onroad/alert_renderer.py | 2 +- selfdrive/ui/mici/onroad/augmented_road_view.py | 2 +- .../ui/mici/onroad/driver_camera_dialog.py | 2 +- selfdrive/ui/mici/onroad/driver_state.py | 2 +- selfdrive/ui/mici/onroad/hud_renderer.py | 2 +- selfdrive/ui/mici/onroad/model_renderer.py | 2 +- selfdrive/ui/onroad/alert_renderer.py | 2 +- selfdrive/ui/onroad/augmented_road_view.py | 2 +- selfdrive/ui/onroad/driver_state.py | 2 +- selfdrive/ui/onroad/model_renderer.py | 2 +- selfdrive/ui/soundd.py | 2 +- selfdrive/ui/tests/body.py | 2 +- selfdrive/ui/tests/diff/replay.py | 2 +- selfdrive/ui/tests/diff/replay_script.py | 4 ++-- selfdrive/ui/tests/test_feedbackd.py | 2 +- selfdrive/ui/tests/test_soundd.py | 4 ++-- selfdrive/ui/ui.py | 2 +- selfdrive/ui/ui_state.py | 2 +- system/athena/athenad.py | 6 +++--- system/athena/tests/test_athenad.py | 2 +- system/camerad/cameras/camera_common.h | 2 +- system/camerad/cameras/hw.h | 2 +- system/camerad/sensors/sensor.h | 2 +- system/camerad/snapshot.py | 2 +- system/camerad/test/test_camerad.py | 2 +- system/camerad/webcam/camerad.py | 2 +- system/hardware/hardwared.py | 6 +++--- system/journald.py | 2 +- system/loggerd/bootlog.cc | 4 ++-- system/loggerd/encoder/encoder.h | 2 +- system/loggerd/encoder/jpeg_encoder.h | 2 +- system/loggerd/logger.h | 2 +- system/loggerd/loggerd.h | 4 ++-- system/loggerd/tests/test_loggerd.py | 6 +++--- system/loggerd/uploader.py | 4 ++-- system/loggerd/video_writer.h | 2 +- system/logmessaged.py | 2 +- system/manager/manager.py | 4 ++-- system/manager/process.py | 4 ++-- system/manager/process_config.py | 2 +- system/micd.py | 2 +- system/proclogd.py | 2 +- system/qcomgpsd/qcomgpsd.py | 4 ++-- system/sensord/sensord.py | 4 ++-- system/sensord/sensors/i2c_sensor.py | 2 +- system/sensord/sensors/lsm6ds3_accel.py | 2 +- system/sensord/sensors/lsm6ds3_gyro.py | 2 +- system/sensord/sensors/lsm6ds3_temp.py | 2 +- system/sensord/tests/test_sensord.py | 4 ++-- system/tests/test_logmessaged.py | 2 +- system/timed.py | 2 +- system/ubloxd/pigeond.py | 2 +- system/ubloxd/tests/test_pigeond.py | 4 ++-- system/ubloxd/ubloxd.py | 4 ++-- system/ui/mici_setup.py | 2 +- system/ui/tici_setup.py | 2 +- system/webrtc/device/video.py | 2 +- system/webrtc/tests/test_stream_session.py | 2 +- system/webrtc/webrtcd.py | 2 +- tools/cabana/README.md | 4 ++-- tools/cabana/SConscript | 2 +- tools/cabana/cabana | 2 +- tools/cabana/dbc/generate_dbc_json.py | 1 - tools/cabana/panda.cc | 2 +- tools/cabana/panda.h | 4 ++-- tools/cabana/streams/abstractstream.h | 2 +- tools/cabana/streams/devicestream.cc | 4 ++-- tools/camerastream/README.md | 6 +++--- tools/camerastream/compressed_vipc.py | 2 +- tools/car_porting/measure_steering_accuracy.py | 2 +- tools/car_porting/test_car_model.py | 1 - tools/jotpluggler/SConscript | 4 ++-- tools/jotpluggler/app.h | 2 +- tools/jotpluggler/generate_event_extractors.py | 2 +- tools/jotpluggler/runtime.cc | 2 +- tools/joystick/README.md | 2 +- tools/joystick/joystick_control.py | 4 ++-- tools/joystick/joystickd.py | 2 +- tools/lateral_maneuvers/lateral_maneuversd.py | 2 +- tools/lib/live_logreader.py | 4 ++-- tools/lib/logreader.py | 2 +- tools/lib/tests/test_logreader.py | 2 +- tools/longitudinal_maneuvers/maneuversd.py | 2 +- tools/plotjuggler/README.md | 2 +- tools/plotjuggler/juggle.py | 17 ++++++++++++++--- tools/replay/logreader.h | 2 +- tools/replay/replay.cc | 2 +- tools/replay/timeline.cc | 2 +- tools/replay/ui.py | 2 +- tools/replay/util.h | 2 +- tools/scripts/adb_ssh.sh | 2 +- tools/scripts/car/can_print_changes.py | 2 +- tools/scripts/car/can_printer.py | 2 +- tools/scripts/car/can_table.py | 2 +- tools/scripts/car/disable_ecu.py | 2 +- tools/scripts/car/ecu_addrs.py | 2 +- tools/scripts/car/fw_versions.py | 2 +- .../scripts/car/hyundai_enable_radar_points.py | 1 - tools/scripts/car/measure_torque_time_to_max.py | 4 ++-- tools/scripts/car/vin.py | 2 +- tools/scripts/count_events.py | 2 +- tools/scripts/cycle_alerts.py | 4 ++-- .../scripts/debug_fw_fingerprinting_offline.py | 1 - tools/scripts/dump.py | 6 +++--- tools/scripts/filter_log_message.py | 2 +- tools/scripts/fuzz_fw_fingerprint.py | 1 - tools/scripts/get_fingerprint.py | 2 +- tools/scripts/live_cpu_and_temp.py | 2 +- tools/scripts/qlog_size.py | 2 +- tools/scripts/uiview.py | 2 +- tools/scripts/watch_timings.py | 4 ++-- tools/sim/bridge/common.py | 1 - tools/sim/lib/camerad.py | 2 +- tools/sim/lib/simulated_car.py | 2 +- tools/sim/lib/simulated_sensors.py | 4 ++-- tools/sim/tests/test_sim_bridge.py | 2 +- 221 files changed, 292 insertions(+), 292 deletions(-) rename {cereal => openpilot/cereal}/README.md (98%) rename {cereal => openpilot/cereal}/SConscript (100%) rename {cereal => openpilot/cereal}/__init__.py (81%) rename {cereal => openpilot/cereal}/custom.capnp (100%) rename {cereal => openpilot/cereal}/deprecated.capnp (100%) rename {cereal => openpilot/cereal}/include/c++.capnp (100%) rename {cereal => openpilot/cereal}/log.capnp (100%) rename {cereal => openpilot/cereal}/messaging/__init__.py (99%) rename {cereal => openpilot/cereal}/messaging/bridge.cc (95%) rename {cereal => openpilot/cereal}/messaging/bridge_zmq.cc (98%) rename {cereal => openpilot/cereal}/messaging/bridge_zmq.h (100%) rename {cereal => openpilot/cereal}/messaging/messaging.h (98%) rename {cereal => openpilot/cereal}/messaging/msgq_to_zmq.cc (98%) rename {cereal => openpilot/cereal}/messaging/msgq_to_zmq.h (94%) rename {cereal => openpilot/cereal}/messaging/socketmaster.cc (98%) rename {cereal => openpilot/cereal}/messaging/tests/__init__.py (100%) rename {cereal => openpilot/cereal}/messaging/tests/test_messaging.py (97%) rename {cereal => openpilot/cereal}/messaging/tests/test_pub_sub_master.py (96%) rename {cereal => openpilot/cereal}/messaging/tests/test_services.py (85%) rename {cereal => openpilot/cereal}/services.py (100%) diff --git a/.gitignore b/.gitignore index 8f4442e522..35a2fe8c5e 100644 --- a/.gitignore +++ b/.gitignore @@ -49,9 +49,9 @@ selfdrive/modeld/models/tg_input_devices.json # build artifacts docs_site/ selfdrive/pandad/pandad -cereal/services.h -cereal/gen -cereal/messaging/bridge +openpilot/cereal/services.h +openpilot/cereal/gen +openpilot/cereal/messaging/bridge selfdrive/ui/translations/tmp selfdrive/car/tests/cars_dump system/camerad/camerad diff --git a/RELEASES.md b/RELEASES.md index 7946fce019..770a7c40fe 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1104,7 +1104,7 @@ Version 0.2.1 (2016-12-14) Version 0.2 (2016-12-12) ========================= - * Car/Radar abstraction layers have shipped, see cereal/car.capnp + * Car/Radar abstraction layers have shipped, see openpilot/cereal/car.capnp * controlsd has been refactored * Shipped plant model and testing maneuvers * visiond exits more gracefully now diff --git a/SConstruct b/SConstruct index 9429daea15..41bc5d7d0d 100644 --- a/SConstruct +++ b/SConstruct @@ -114,7 +114,7 @@ env = Environment( CPPPATH=[ "#", "#msgq", - "#cereal/gen/cpp", + "#openpilot/cereal/gen/cpp", acados_include_dirs, [x.INCLUDE_DIR for x in pkgs], ], @@ -222,7 +222,7 @@ env_swaglog = env.Clone() env_swaglog['CXXFLAGS'].append('-DSWAGLOG="\\"common/swaglog.h\\""') SConscript(['msgq_repo/SConscript'], exports={'env': env_swaglog}) -SConscript(['cereal/SConscript']) +SConscript(['openpilot/cereal/SConscript']) Import('socketmaster', 'msgq') messaging = [socketmaster, msgq, 'capnp', 'kj',] diff --git a/common/hardware/base.h b/common/hardware/base.h index 3cb8add783..f4546adfa8 100644 --- a/common/hardware/base.h +++ b/common/hardware/base.h @@ -5,7 +5,7 @@ #include #include -#include "cereal/gen/cpp/log.capnp.h" +#include "openpilot/cereal/gen/cpp/log.capnp.h" // no-op base hw class class HardwareNone { diff --git a/common/hardware/base.py b/common/hardware/base.py index bf6523db77..5d8f7770dc 100644 --- a/common/hardware/base.py +++ b/common/hardware/base.py @@ -2,7 +2,7 @@ import os from abc import abstractmethod, ABC from dataclasses import dataclass, fields -from cereal import log +from openpilot.cereal import log from openpilot.common.esim.base import LPABase NetworkType = log.DeviceState.NetworkType diff --git a/common/hardware/pc/hardware.py b/common/hardware/pc/hardware.py index b387f03127..b4aa56c904 100644 --- a/common/hardware/pc/hardware.py +++ b/common/hardware/pc/hardware.py @@ -1,4 +1,4 @@ -from cereal import log +from openpilot.cereal import log from openpilot.common.hardware.base import HardwareBase class Pc(HardwareBase): diff --git a/common/hardware/tici/hardware.py b/common/hardware/tici/hardware.py index bec4c90423..1a2cb51d05 100644 --- a/common/hardware/tici/hardware.py +++ b/common/hardware/tici/hardware.py @@ -7,7 +7,7 @@ import time from functools import cached_property, lru_cache from pathlib import Path -from cereal import log +from openpilot.cereal import log from openpilot.common.utils import sudo_read, sudo_write from openpilot.common.gpio import gpio_set, gpio_init, get_irqs_for_action from openpilot.common.esim.base import LPABase diff --git a/common/mock/__init__.py b/common/mock/__init__.py index 4b01dfe841..673513fdd9 100644 --- a/common/mock/__init__.py +++ b/common/mock/__init__.py @@ -6,8 +6,8 @@ example in common/tests/test_mock.py import functools import threading -from cereal.messaging import PubMaster -from cereal.services import SERVICE_LIST +from openpilot.cereal.messaging import PubMaster +from openpilot.cereal.services import SERVICE_LIST from openpilot.common.mock.generators import generate_livePose from openpilot.common.realtime import Ratekeeper diff --git a/common/mock/generators.py b/common/mock/generators.py index 5cd9c88a56..28a3b98e58 100644 --- a/common/mock/generators.py +++ b/common/mock/generators.py @@ -1,4 +1,4 @@ -from cereal import messaging +from openpilot.cereal import messaging def generate_livePose(): diff --git a/common/params_keys.h b/common/params_keys.h index 5b0f6e99c9..02bdc616da 100644 --- a/common/params_keys.h +++ b/common/params_keys.h @@ -3,7 +3,7 @@ #include #include -#include "cereal/gen/cpp/log.capnp.h" +#include "openpilot/cereal/gen/cpp/log.capnp.h" inline static std::unordered_map keys = { {"AccessToken", {CLEAR_ON_MANAGER_START | DONT_LOG, STRING}}, diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md index 3d39420c01..cbeb5f6d3a 100644 --- a/docs/CONTRIBUTING.md +++ b/docs/CONTRIBUTING.md @@ -68,6 +68,6 @@ A good pull request has all of the following: ### A guide for forks In order for your fork's data to be eligible for the training set: -* **Your cereal messaging structs must be [compatible](../cereal#custom-forks)** +* **Your cereal messaging structs must be [compatible](../openpilot/cereal#custom-forks)** * **The definitions of all the stock messaging structs must not change**: Do not change how any of the fields are set, including everything from `selfdriveState.enabled` to `carState.steeringAngleDeg`. Instead, create your own structs and set them however you'd like. * **Do not include cars that are not supported in upstream platforms**: Instead, create new opendbc platforms for cars that you'd like to support outside of upstream, even if it's just a trim-level difference. diff --git a/docs/concepts/logs.md b/docs/concepts/logs.md index e533d36297..4fa720ddde 100644 --- a/docs/concepts/logs.md +++ b/docs/concepts/logs.md @@ -8,7 +8,7 @@ For each segment, openpilot records the following log types: ## rlog.zst -rlogs contain all the messages passed amongst openpilot's processes. See [cereal/services.py](https://github.com/commaai/openpilot/blob/master/cereal/services.py) for a list of all the logged services. They're a zstd archive of the serialized [Cap’n Proto](https://capnproto.org/) messages. +rlogs contain all the messages passed amongst openpilot's processes. See [openpilot/cereal/services.py](https://github.com/commaai/openpilot/blob/master/openpilot/cereal/services.py) for a list of all the logged services. They're a zstd archive of the serialized [Cap’n Proto](https://capnproto.org/) messages. ## {f,e,d}camera.hevc @@ -20,7 +20,7 @@ Each camera stream is H.265 encoded and written to its respective file. ## qlog.zst & qcamera.ts -qlogs are a decimated subset of the rlogs. Check out [cereal/services.py](https://github.com/commaai/cereal/blob/master/services.py) for the decimation. +qlogs are a decimated subset of the rlogs. Check out [openpilot/cereal/services.py](https://github.com/commaai/openpilot/blob/master/openpilot/cereal/services.py) for the decimation. qcameras are H.264 encoded, lower res versions of the fcamera.hevc. The video shown in [comma connect](https://connect.comma.ai/) is from the qcameras. diff --git a/cereal/README.md b/openpilot/cereal/README.md similarity index 98% rename from cereal/README.md rename to openpilot/cereal/README.md index 45e859c09c..419d380882 100644 --- a/cereal/README.md +++ b/openpilot/cereal/README.md @@ -76,7 +76,7 @@ index 1209f3fd9..b189f58b6 100644 Example --- ```python -import cereal.messaging as messaging +import openpilot.cereal.messaging as messaging # in subscriber sm = messaging.SubMaster(['sensorEvents']) diff --git a/cereal/SConscript b/openpilot/cereal/SConscript similarity index 100% rename from cereal/SConscript rename to openpilot/cereal/SConscript diff --git a/cereal/__init__.py b/openpilot/cereal/__init__.py similarity index 81% rename from cereal/__init__.py rename to openpilot/cereal/__init__.py index d4f6504652..d4a43a8474 100644 --- a/cereal/__init__.py +++ b/openpilot/cereal/__init__.py @@ -4,7 +4,7 @@ from importlib.resources import as_file, files capnp.remove_import_hook() -with as_file(files("cereal")) as fspath, as_file(files("opendbc")) as opendbc_path: +with as_file(files("openpilot.cereal")) as fspath, as_file(files("opendbc")) as opendbc_path: CEREAL_PATH = fspath.as_posix() opendbc_import_path = os.path.join(os.path.realpath(opendbc_path.as_posix()), 'car') log = capnp.load(os.path.join(CEREAL_PATH, "log.capnp"), imports=[opendbc_import_path]) diff --git a/cereal/custom.capnp b/openpilot/cereal/custom.capnp similarity index 100% rename from cereal/custom.capnp rename to openpilot/cereal/custom.capnp diff --git a/cereal/deprecated.capnp b/openpilot/cereal/deprecated.capnp similarity index 100% rename from cereal/deprecated.capnp rename to openpilot/cereal/deprecated.capnp diff --git a/cereal/include/c++.capnp b/openpilot/cereal/include/c++.capnp similarity index 100% rename from cereal/include/c++.capnp rename to openpilot/cereal/include/c++.capnp diff --git a/cereal/log.capnp b/openpilot/cereal/log.capnp similarity index 100% rename from cereal/log.capnp rename to openpilot/cereal/log.capnp diff --git a/cereal/messaging/__init__.py b/openpilot/cereal/messaging/__init__.py similarity index 99% rename from cereal/messaging/__init__.py rename to openpilot/cereal/messaging/__init__.py index ae32bfd4cb..cb5f090095 100644 --- a/cereal/messaging/__init__.py +++ b/openpilot/cereal/messaging/__init__.py @@ -9,8 +9,8 @@ import time from typing import Optional, List, Union, Dict -from cereal import log -from cereal.services import SERVICE_LIST +from openpilot.cereal import log +from openpilot.cereal.services import SERVICE_LIST from openpilot.common.utils import MovingAverage NO_TRAVERSAL_LIMIT = 2**64-1 diff --git a/cereal/messaging/bridge.cc b/openpilot/cereal/messaging/bridge.cc similarity index 95% rename from cereal/messaging/bridge.cc rename to openpilot/cereal/messaging/bridge.cc index 77823c413a..ee3d5e93ca 100644 --- a/cereal/messaging/bridge.cc +++ b/openpilot/cereal/messaging/bridge.cc @@ -1,7 +1,7 @@ #include -#include "cereal/messaging/msgq_to_zmq.h" -#include "cereal/services.h" +#include "openpilot/cereal/messaging/msgq_to_zmq.h" +#include "openpilot/cereal/services.h" #include "common/util.h" ExitHandler do_exit; diff --git a/cereal/messaging/bridge_zmq.cc b/openpilot/cereal/messaging/bridge_zmq.cc similarity index 98% rename from cereal/messaging/bridge_zmq.cc rename to openpilot/cereal/messaging/bridge_zmq.cc index 5c56673b47..72d4345d03 100644 --- a/cereal/messaging/bridge_zmq.cc +++ b/openpilot/cereal/messaging/bridge_zmq.cc @@ -1,4 +1,4 @@ -#include "cereal/messaging/bridge_zmq.h" +#include "openpilot/cereal/messaging/bridge_zmq.h" #include #include diff --git a/cereal/messaging/bridge_zmq.h b/openpilot/cereal/messaging/bridge_zmq.h similarity index 100% rename from cereal/messaging/bridge_zmq.h rename to openpilot/cereal/messaging/bridge_zmq.h diff --git a/cereal/messaging/messaging.h b/openpilot/cereal/messaging/messaging.h similarity index 98% rename from cereal/messaging/messaging.h rename to openpilot/cereal/messaging/messaging.h index fb9c261f2b..933e0b9f15 100644 --- a/cereal/messaging/messaging.h +++ b/openpilot/cereal/messaging/messaging.h @@ -8,7 +8,7 @@ #include -#include "cereal/gen/cpp/log.capnp.h" +#include "openpilot/cereal/gen/cpp/log.capnp.h" #include "common/timing.h" #include "msgq/ipc.h" diff --git a/cereal/messaging/msgq_to_zmq.cc b/openpilot/cereal/messaging/msgq_to_zmq.cc similarity index 98% rename from cereal/messaging/msgq_to_zmq.cc rename to openpilot/cereal/messaging/msgq_to_zmq.cc index 5e7ea22273..adea00f923 100644 --- a/cereal/messaging/msgq_to_zmq.cc +++ b/openpilot/cereal/messaging/msgq_to_zmq.cc @@ -1,8 +1,8 @@ -#include "cereal/messaging/msgq_to_zmq.h" +#include "openpilot/cereal/messaging/msgq_to_zmq.h" #include -#include "cereal/services.h" +#include "openpilot/cereal/services.h" #include "common/util.h" extern ExitHandler do_exit; diff --git a/cereal/messaging/msgq_to_zmq.h b/openpilot/cereal/messaging/msgq_to_zmq.h similarity index 94% rename from cereal/messaging/msgq_to_zmq.h rename to openpilot/cereal/messaging/msgq_to_zmq.h index 64f3a2173e..a34f0ebbf0 100644 --- a/cereal/messaging/msgq_to_zmq.h +++ b/openpilot/cereal/messaging/msgq_to_zmq.h @@ -8,7 +8,7 @@ #include #include "msgq/impl_msgq.h" -#include "cereal/messaging/bridge_zmq.h" +#include "openpilot/cereal/messaging/bridge_zmq.h" class MsgqToZmq { public: diff --git a/cereal/messaging/socketmaster.cc b/openpilot/cereal/messaging/socketmaster.cc similarity index 98% rename from cereal/messaging/socketmaster.cc rename to openpilot/cereal/messaging/socketmaster.cc index dfeeb807ee..dd285a0c8e 100644 --- a/cereal/messaging/socketmaster.cc +++ b/openpilot/cereal/messaging/socketmaster.cc @@ -3,8 +3,8 @@ #include #include -#include "cereal/services.h" -#include "cereal/messaging/messaging.h" +#include "openpilot/cereal/services.h" +#include "openpilot/cereal/messaging/messaging.h" const bool SIMULATION = (getenv("SIMULATION") != nullptr) && (std::string(getenv("SIMULATION")) == "1"); diff --git a/cereal/messaging/tests/__init__.py b/openpilot/cereal/messaging/tests/__init__.py similarity index 100% rename from cereal/messaging/tests/__init__.py rename to openpilot/cereal/messaging/tests/__init__.py diff --git a/cereal/messaging/tests/test_messaging.py b/openpilot/cereal/messaging/tests/test_messaging.py similarity index 97% rename from cereal/messaging/tests/test_messaging.py rename to openpilot/cereal/messaging/tests/test_messaging.py index 22601158a6..c2ac1578d4 100644 --- a/cereal/messaging/tests/test_messaging.py +++ b/openpilot/cereal/messaging/tests/test_messaging.py @@ -8,10 +8,10 @@ import time from openpilot.common.parameterized import parameterized import pytest -from cereal import log +from openpilot.cereal import log from opendbc.car.structs import car -import cereal.messaging as messaging -from cereal.services import SERVICE_LIST +import openpilot.cereal.messaging as messaging +from openpilot.cereal.services import SERVICE_LIST events = [evt for evt in log.Event.schema.union_fields if evt in SERVICE_LIST.keys()] diff --git a/cereal/messaging/tests/test_pub_sub_master.py b/openpilot/cereal/messaging/tests/test_pub_sub_master.py similarity index 96% rename from cereal/messaging/tests/test_pub_sub_master.py rename to openpilot/cereal/messaging/tests/test_pub_sub_master.py index 5e26b49701..eb8f62140b 100644 --- a/cereal/messaging/tests/test_pub_sub_master.py +++ b/openpilot/cereal/messaging/tests/test_pub_sub_master.py @@ -2,11 +2,11 @@ import random import time from typing import Sized, cast -import cereal.messaging as messaging -from cereal.messaging.tests.test_messaging import events, random_sock, random_socks, \ +import openpilot.cereal.messaging as messaging +from openpilot.cereal.messaging.tests.test_messaging import events, random_sock, random_socks, \ random_bytes, random_carstate, assert_carstate, \ zmq_sleep -from cereal.services import SERVICE_LIST +from openpilot.cereal.services import SERVICE_LIST class TestSubMaster: diff --git a/cereal/messaging/tests/test_services.py b/openpilot/cereal/messaging/tests/test_services.py similarity index 85% rename from cereal/messaging/tests/test_services.py rename to openpilot/cereal/messaging/tests/test_services.py index 3320723fec..debe891375 100644 --- a/cereal/messaging/tests/test_services.py +++ b/openpilot/cereal/messaging/tests/test_services.py @@ -3,8 +3,8 @@ import tempfile from typing import Dict from openpilot.common.parameterized import parameterized -import cereal.services as services -from cereal.services import SERVICE_LIST +import openpilot.cereal.services as services +from openpilot.cereal.services import SERVICE_LIST class TestServices: diff --git a/cereal/services.py b/openpilot/cereal/services.py similarity index 100% rename from cereal/services.py rename to openpilot/cereal/services.py diff --git a/pyproject.toml b/pyproject.toml index b146138ae7..53a237a22c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -128,7 +128,7 @@ allow-direct-references = true [tool.pytest.ini_options] minversion = "6.0" -addopts = "--ignore=openpilot/ --ignore=opendbc/ --ignore=panda/ --ignore=rednose_repo/ --ignore=tinygrad_repo/ --ignore=teleoprtc_repo/ --ignore=msgq/ --ignore=selfdrive/modeld -Werror --strict-config --strict-markers --durations=10 -n auto --dist=loadgroup" +addopts = "--ignore=openpilot/common --ignore=openpilot/selfdrive --ignore=openpilot/system --ignore=openpilot/tools --ignore=opendbc/ --ignore=panda/ --ignore=rednose_repo/ --ignore=tinygrad_repo/ --ignore=teleoprtc_repo/ --ignore=msgq/ --ignore=selfdrive/modeld -Werror --strict-config --strict-markers --durations=10 -n auto --dist=loadgroup" cpp_files = "test_*" cpp_harness = "selfdrive/test/cpp_harness.py" python_files = "test_*.py" @@ -145,7 +145,7 @@ testpaths = [ "selfdrive", "system", "tools", - "cereal", + "openpilot/cereal", ] [tool.codespell] @@ -153,7 +153,7 @@ quiet-level = 3 # if you've got a short variable name that's getting flagged, add it here ignore-words-list = "bu,ro,te,ue,alo,hda,ois,nam,nams,ned,som,parm,setts,inout,warmup,bumb,nd,sie,preints,whit,indexIn,ws,uint,grey,deque,stdio,amin,BA,LITE,atEnd,UIs,errorString,arange,FocusIn,od,tim,relA,hist,copyable,jupyter,thead,TGE,abl,lite,ser" builtin = "clear,rare,informal,code,names,en-GB_to_en-US" -skip = "../tinygrad/*, ./tinygrad_repo/*, ./msgq/*, ./panda/*, ./opendbc/*, ./opendbc_repo/*, ./rednose/*, ./rednose_repo/*, ./teleoprtc/*, ./teleoprtc_repo/*, *.po, uv.lock, *.onnx, *.pem, ./cereal/gen/*, */c_generated_code/*, docs/assets/*, tools/plotjuggler/layouts/*, selfdrive/assets/offroad/mici_fcc.html" +skip = "../tinygrad/*, ./tinygrad_repo/*, ./msgq/*, ./panda/*, ./opendbc/*, ./opendbc_repo/*, ./rednose/*, ./rednose_repo/*, ./teleoprtc/*, ./teleoprtc_repo/*, *.po, uv.lock, *.onnx, *.pem, ./openpilot/cereal/gen/*, */c_generated_code/*, docs/assets/*, tools/plotjuggler/layouts/*, selfdrive/assets/offroad/mici_fcc.html" # https://docs.astral.sh/ruff/configuration/#using-pyprojecttoml [tool.ruff] @@ -179,7 +179,7 @@ lint.ignore = [ ] line-length = 160 exclude = [ - "cereal", + "openpilot/cereal", "panda", "opendbc", "opendbc_repo", diff --git a/release/pack.py b/release/pack.py index 560500e7a7..dd29de4256 100755 --- a/release/pack.py +++ b/release/pack.py @@ -11,7 +11,7 @@ from pathlib import Path from openpilot.common.basedir import BASEDIR -DIRS = ['cereal', 'openpilot'] +DIRS = ['openpilot'] EXTS = ['.png', '.py', '.ttf', '.capnp', '.json', '.fnt', '.mo', '.po'] EXCLUDE = ['selfdrive/assets/training'] INTERPRETER = '/usr/bin/env python3' diff --git a/scripts/lint/lint.sh b/scripts/lint/lint.sh index 4b6838449f..0f236377ed 100755 --- a/scripts/lint/lint.sh +++ b/scripts/lint/lint.sh @@ -14,7 +14,7 @@ cd $ROOT FAILED=0 IGNORED_FILES="uv\.lock|docs\/CARS.md" -IGNORED_DIRS="^msgq.*|^msgq_repo.*|^opendbc.*|^opendbc_repo.*|^cereal.*|^panda.*|^rednose.*|^rednose_repo.*|^tinygrad.*|^tinygrad_repo.*|^teleoprtc.*|^teleoprtc_repo.*" +IGNORED_DIRS="^msgq.*|^msgq_repo.*|^opendbc.*|^opendbc_repo.*|^cereal.*|^openpilot\/cereal.*|^panda.*|^rednose.*|^rednose_repo.*|^tinygrad.*|^tinygrad_repo.*|^teleoprtc.*|^teleoprtc_repo.*" function run() { shopt -s extglob diff --git a/selfdrive/car/car_specific.py b/selfdrive/car/car_specific.py index 1487f4380c..244a8e3b07 100644 --- a/selfdrive/car/car_specific.py +++ b/selfdrive/car/car_specific.py @@ -1,4 +1,4 @@ -from cereal import log +from openpilot.cereal import log from opendbc.car.structs import car from opendbc.car import DT_CTRL, structs from opendbc.car.car_helpers import interfaces diff --git a/selfdrive/car/card.py b/selfdrive/car/card.py index f5186699ac..96c169a1da 100755 --- a/selfdrive/car/card.py +++ b/selfdrive/car/card.py @@ -3,9 +3,9 @@ import os import time import threading -import cereal.messaging as messaging +import openpilot.cereal.messaging as messaging -from cereal import log +from openpilot.cereal import log from opendbc.car.structs import car from openpilot.common.params import Params diff --git a/selfdrive/car/tests/test_cruise_speed.py b/selfdrive/car/tests/test_cruise_speed.py index 3b3fb115ba..57e89a1117 100644 --- a/selfdrive/car/tests/test_cruise_speed.py +++ b/selfdrive/car/tests/test_cruise_speed.py @@ -3,7 +3,7 @@ import itertools import numpy as np from openpilot.common.parameterized import parameterized_class -from cereal import log +from openpilot.cereal import log from openpilot.selfdrive.car.cruise import VCruiseHelper, V_CRUISE_MIN, V_CRUISE_MAX, V_CRUISE_INITIAL, IMPERIAL_INCREMENT from opendbc.car.structs import car from openpilot.common.constants import CV diff --git a/selfdrive/car/tests/test_docs.py b/selfdrive/car/tests/test_docs.py index ef6795ef80..8ccbfb5a79 100644 --- a/selfdrive/car/tests/test_docs.py +++ b/selfdrive/car/tests/test_docs.py @@ -1,4 +1,3 @@ - from opendbc.car.docs import generate_cars_md, get_all_car_docs from openpilot.selfdrive.car.docs import CARS_MD_TEMPLATE diff --git a/selfdrive/car/tests/test_models.py b/selfdrive/car/tests/test_models.py index 035602b955..ac2cd3ec7e 100644 --- a/selfdrive/car/tests/test_models.py +++ b/selfdrive/car/tests/test_models.py @@ -7,7 +7,6 @@ from collections import defaultdict, Counter import hypothesis.strategies as st from hypothesis import Phase, given, settings from openpilot.common.parameterized import parameterized_class - from opendbc.car import DT_CTRL, gen_empty_fingerprint, structs from opendbc.car.can_definitions import CanData from opendbc.car.car_helpers import FRAME_FINGERPRINT, interfaces diff --git a/selfdrive/controls/controlsd.py b/selfdrive/controls/controlsd.py index 67566cf0a7..fe3b0f66c0 100755 --- a/selfdrive/controls/controlsd.py +++ b/selfdrive/controls/controlsd.py @@ -2,9 +2,9 @@ import math from numbers import Number -from cereal import log +from openpilot.cereal import log from opendbc.car.structs import car -import cereal.messaging as messaging +import openpilot.cereal.messaging as messaging from openpilot.common.constants import CV from openpilot.common.params import Params from openpilot.common.realtime import config_realtime_process, DT_CTRL, Priority, Ratekeeper diff --git a/selfdrive/controls/lib/desire_helper.py b/selfdrive/controls/lib/desire_helper.py index 659c0adc30..68ddc3861e 100644 --- a/selfdrive/controls/lib/desire_helper.py +++ b/selfdrive/controls/lib/desire_helper.py @@ -1,4 +1,4 @@ -from cereal import log +from openpilot.cereal import log from openpilot.common.constants import CV from openpilot.common.realtime import DT_MDL diff --git a/selfdrive/controls/lib/latcontrol_angle.py b/selfdrive/controls/lib/latcontrol_angle.py index a7d0403248..517c77f569 100644 --- a/selfdrive/controls/lib/latcontrol_angle.py +++ b/selfdrive/controls/lib/latcontrol_angle.py @@ -1,6 +1,6 @@ import math -from cereal import log +from openpilot.cereal import log from openpilot.selfdrive.controls.lib.latcontrol import LatControl # TODO This is speed dependent diff --git a/selfdrive/controls/lib/latcontrol_curvature.py b/selfdrive/controls/lib/latcontrol_curvature.py index cd2d8e3284..ec3ad1bf16 100644 --- a/selfdrive/controls/lib/latcontrol_curvature.py +++ b/selfdrive/controls/lib/latcontrol_curvature.py @@ -1,6 +1,6 @@ import math -from cereal import log +from openpilot.cereal import log from openpilot.common.pid import PIDController from openpilot.selfdrive.controls.lib.latcontrol import LatControl from openpilot.selfdrive.controls.lib.drive_helpers import MAX_CURVATURE diff --git a/selfdrive/controls/lib/latcontrol_pid.py b/selfdrive/controls/lib/latcontrol_pid.py index 14ab9f21b5..48074c823d 100644 --- a/selfdrive/controls/lib/latcontrol_pid.py +++ b/selfdrive/controls/lib/latcontrol_pid.py @@ -1,6 +1,6 @@ import math -from cereal import log +from openpilot.cereal import log from openpilot.selfdrive.controls.lib.latcontrol import LatControl from openpilot.common.pid import PIDController diff --git a/selfdrive/controls/lib/latcontrol_torque.py b/selfdrive/controls/lib/latcontrol_torque.py index 903700d4b3..846f1daf00 100644 --- a/selfdrive/controls/lib/latcontrol_torque.py +++ b/selfdrive/controls/lib/latcontrol_torque.py @@ -2,7 +2,7 @@ import math import numpy as np from collections import deque -from cereal import log +from openpilot.cereal import log from opendbc.car.lateral import FRICTION_THRESHOLD, get_friction from openpilot.common.constants import ACCELERATION_DUE_TO_GRAVITY from openpilot.common.filter_simple import FirstOrderFilter diff --git a/selfdrive/controls/lib/ldw.py b/selfdrive/controls/lib/ldw.py index 78a6d6cf6e..6db59791cc 100644 --- a/selfdrive/controls/lib/ldw.py +++ b/selfdrive/controls/lib/ldw.py @@ -1,4 +1,4 @@ -from cereal import log +from openpilot.cereal import log from openpilot.common.realtime import DT_CTRL from openpilot.common.constants import CV diff --git a/selfdrive/controls/lib/longitudinal_mpc_lib/long_mpc.py b/selfdrive/controls/lib/longitudinal_mpc_lib/long_mpc.py index deae416489..02a424c4c2 100755 --- a/selfdrive/controls/lib/longitudinal_mpc_lib/long_mpc.py +++ b/selfdrive/controls/lib/longitudinal_mpc_lib/long_mpc.py @@ -2,7 +2,7 @@ import os import time import numpy as np -from cereal import log +from openpilot.cereal import log from opendbc.car.interfaces import ACCEL_MIN, ACCEL_MAX from openpilot.common.realtime import DT_MDL from openpilot.common.swaglog import cloudlog diff --git a/selfdrive/controls/lib/longitudinal_planner.py b/selfdrive/controls/lib/longitudinal_planner.py index 64de1a8fda..a2547f99bf 100755 --- a/selfdrive/controls/lib/longitudinal_planner.py +++ b/selfdrive/controls/lib/longitudinal_planner.py @@ -2,7 +2,7 @@ import math import numpy as np -import cereal.messaging as messaging +import openpilot.cereal.messaging as messaging from opendbc.car.interfaces import ACCEL_MIN, ACCEL_MAX from openpilot.common.constants import CV from openpilot.common.filter_simple import FirstOrderFilter diff --git a/selfdrive/controls/plannerd.py b/selfdrive/controls/plannerd.py index 49c4473590..e8ee4395b8 100755 --- a/selfdrive/controls/plannerd.py +++ b/selfdrive/controls/plannerd.py @@ -5,7 +5,7 @@ from openpilot.common.realtime import Priority, config_realtime_process from openpilot.common.swaglog import cloudlog from openpilot.selfdrive.controls.lib.ldw import LaneDepartureWarning from openpilot.selfdrive.controls.lib.longitudinal_planner import LongitudinalPlanner -import cereal.messaging as messaging +import openpilot.cereal.messaging as messaging def main(): diff --git a/selfdrive/controls/radard.py b/selfdrive/controls/radard.py index 9d438661b3..94400f3357 100755 --- a/selfdrive/controls/radard.py +++ b/selfdrive/controls/radard.py @@ -5,7 +5,7 @@ from collections import deque from typing import Any import capnp -from cereal import messaging, log +from openpilot.cereal import messaging, log from opendbc.car.structs import car from openpilot.common.filter_simple import FirstOrderFilter from openpilot.common.params import Params diff --git a/selfdrive/controls/tests/test_following_distance.py b/selfdrive/controls/tests/test_following_distance.py index 1eb88d7206..fcabce0387 100644 --- a/selfdrive/controls/tests/test_following_distance.py +++ b/selfdrive/controls/tests/test_following_distance.py @@ -2,7 +2,7 @@ import pytest import itertools from openpilot.common.parameterized import parameterized_class -from cereal import log +from openpilot.cereal import log from openpilot.selfdrive.controls.lib.longitudinal_mpc_lib.long_mpc import get_safe_obstacle_distance, get_stopped_equivalence_factor, get_T_FOLLOW from openpilot.selfdrive.test.longitudinal_maneuvers.maneuver import Maneuver diff --git a/selfdrive/controls/tests/test_latcontrol.py b/selfdrive/controls/tests/test_latcontrol.py index 9cd5e6307c..8389a1e31a 100644 --- a/selfdrive/controls/tests/test_latcontrol.py +++ b/selfdrive/controls/tests/test_latcontrol.py @@ -1,6 +1,6 @@ from openpilot.common.parameterized import parameterized -from cereal import log +from openpilot.cereal import log from opendbc.car.structs import car from opendbc.car.car_helpers import interfaces from opendbc.car.honda.values import CAR as HONDA diff --git a/selfdrive/controls/tests/test_latcontrol_torque_buffer.py b/selfdrive/controls/tests/test_latcontrol_torque_buffer.py index 6a7ed5419e..9e04316798 100644 --- a/selfdrive/controls/tests/test_latcontrol_torque_buffer.py +++ b/selfdrive/controls/tests/test_latcontrol_torque_buffer.py @@ -1,6 +1,6 @@ from openpilot.common.parameterized import parameterized -from cereal import log +from openpilot.cereal import log from opendbc.car.structs import car from opendbc.car.car_helpers import interfaces from opendbc.car.toyota.values import CAR as TOYOTA diff --git a/selfdrive/controls/tests/test_leads.py b/selfdrive/controls/tests/test_leads.py index 77384fea20..1956bb34ec 100644 --- a/selfdrive/controls/tests/test_leads.py +++ b/selfdrive/controls/tests/test_leads.py @@ -1,4 +1,4 @@ -import cereal.messaging as messaging +import openpilot.cereal.messaging as messaging from opendbc.car.toyota.values import CAR as TOYOTA from openpilot.selfdrive.test.process_replay import replay_process_with_name diff --git a/selfdrive/controls/tests/test_torqued_lat_accel_offset.py b/selfdrive/controls/tests/test_torqued_lat_accel_offset.py index f1ca0c5f49..93a57d7f60 100644 --- a/selfdrive/controls/tests/test_torqued_lat_accel_offset.py +++ b/selfdrive/controls/tests/test_torqued_lat_accel_offset.py @@ -1,5 +1,5 @@ import numpy as np -from cereal import messaging +from openpilot.cereal import messaging from opendbc.car.structs import car from opendbc.car import ACCELERATION_DUE_TO_GRAVITY from opendbc.car import structs diff --git a/selfdrive/locationd/calibrationd.py b/selfdrive/locationd/calibrationd.py index 23dacf6821..4e3eb7b0fa 100755 --- a/selfdrive/locationd/calibrationd.py +++ b/selfdrive/locationd/calibrationd.py @@ -11,9 +11,9 @@ import capnp import numpy as np from typing import NoReturn -from cereal import log +from openpilot.cereal import log from opendbc.car.structs import car -import cereal.messaging as messaging +import openpilot.cereal.messaging as messaging from openpilot.common.hardware import HARDWARE from openpilot.common.constants import CV from openpilot.common.params import Params diff --git a/selfdrive/locationd/helpers.py b/selfdrive/locationd/helpers.py index 73c4d8bf35..fe7930c509 100644 --- a/selfdrive/locationd/helpers.py +++ b/selfdrive/locationd/helpers.py @@ -2,7 +2,7 @@ import numpy as np from typing import Any from functools import cache -from cereal import log +from openpilot.cereal import log from openpilot.common.transformations.orientation import rot_from_euler, euler_from_rot diff --git a/selfdrive/locationd/lagd.py b/selfdrive/locationd/lagd.py index 17aa0a4303..78c673a3bd 100755 --- a/selfdrive/locationd/lagd.py +++ b/selfdrive/locationd/lagd.py @@ -5,10 +5,10 @@ import capnp from collections import deque from functools import partial -import cereal.messaging as messaging -from cereal import log +import openpilot.cereal.messaging as messaging +from openpilot.cereal import log from opendbc.car.structs import car -from cereal.services import SERVICE_LIST +from openpilot.cereal.services import SERVICE_LIST from openpilot.common.constants import CV from openpilot.common.params import Params from openpilot.common.realtime import config_realtime_process diff --git a/selfdrive/locationd/locationd.py b/selfdrive/locationd/locationd.py index 41b80a1c41..8e03995d13 100755 --- a/selfdrive/locationd/locationd.py +++ b/selfdrive/locationd/locationd.py @@ -6,8 +6,8 @@ import numpy as np from enum import Enum from collections import defaultdict -from cereal import log, messaging -from cereal.services import SERVICE_LIST +from openpilot.cereal import log, messaging +from openpilot.cereal.services import SERVICE_LIST from openpilot.common.transformations.orientation import rot_from_euler from openpilot.common.realtime import config_realtime_process from openpilot.common.params import Params diff --git a/selfdrive/locationd/paramsd.py b/selfdrive/locationd/paramsd.py index 6acf335178..a32773bf0c 100755 --- a/selfdrive/locationd/paramsd.py +++ b/selfdrive/locationd/paramsd.py @@ -3,8 +3,8 @@ import os import numpy as np import capnp -import cereal.messaging as messaging -from cereal import log +import openpilot.cereal.messaging as messaging +from openpilot.cereal import log from opendbc.car.structs import car from openpilot.common.params import Params from openpilot.common.realtime import config_realtime_process, DT_MDL diff --git a/selfdrive/locationd/test/test_calibrationd.py b/selfdrive/locationd/test/test_calibrationd.py index c90ce506ab..f862b369fe 100644 --- a/selfdrive/locationd/test/test_calibrationd.py +++ b/selfdrive/locationd/test/test_calibrationd.py @@ -2,8 +2,8 @@ import random import numpy as np -import cereal.messaging as messaging -from cereal import log +import openpilot.cereal.messaging as messaging +from openpilot.cereal import log from openpilot.common.params import Params from openpilot.selfdrive.locationd.calibrationd import Calibrator, INPUTS_NEEDED, INPUTS_WANTED, BLOCK_SIZE, MIN_SPEED_FILTER, \ MAX_YAW_RATE_FILTER, SMOOTH_CYCLES, HEIGHT_INIT, MAX_ALLOWED_PITCH_SPREAD, MAX_ALLOWED_YAW_SPREAD diff --git a/selfdrive/locationd/test/test_lagd.py b/selfdrive/locationd/test/test_lagd.py index a0e4ee31fa..af401187f5 100644 --- a/selfdrive/locationd/test/test_lagd.py +++ b/selfdrive/locationd/test/test_lagd.py @@ -3,7 +3,7 @@ import numpy as np import time import pytest -from cereal import messaging, log +from openpilot.cereal import messaging, log from opendbc.car.structs import car from openpilot.selfdrive.locationd.lagd import LateralLagEstimator, retrieve_initial_lag, masked_normalized_cross_correlation, \ BLOCK_NUM_NEEDED, BLOCK_SIZE, MIN_OKAY_WINDOW_SEC, VERSION diff --git a/selfdrive/locationd/test/test_paramsd.py b/selfdrive/locationd/test/test_paramsd.py index 1a4d348e94..28c3f4acf7 100644 --- a/selfdrive/locationd/test/test_paramsd.py +++ b/selfdrive/locationd/test/test_paramsd.py @@ -1,7 +1,7 @@ import random import numpy as np -from cereal import messaging +from openpilot.cereal import messaging from openpilot.selfdrive.locationd.paramsd import retrieve_initial_vehicle_params, migrate_cached_vehicle_params_if_needed from openpilot.selfdrive.locationd.models.car_kf import CarKalman from openpilot.selfdrive.locationd.test.test_locationd_scenarios import TEST_ROUTE diff --git a/selfdrive/locationd/torqued.py b/selfdrive/locationd/torqued.py index fdd50d3eb6..6321461e8b 100755 --- a/selfdrive/locationd/torqued.py +++ b/selfdrive/locationd/torqued.py @@ -3,8 +3,8 @@ import os import numpy as np from collections import deque, defaultdict -import cereal.messaging as messaging -from cereal import log +import openpilot.cereal.messaging as messaging +from openpilot.cereal import log from opendbc.car.structs import car from openpilot.common.constants import ACCELERATION_DUE_TO_GRAVITY from openpilot.common.params import Params diff --git a/selfdrive/modeld/dmonitoringmodeld.py b/selfdrive/modeld/dmonitoringmodeld.py index eaf423e7be..a022e3c3c0 100755 --- a/selfdrive/modeld/dmonitoringmodeld.py +++ b/selfdrive/modeld/dmonitoringmodeld.py @@ -6,8 +6,8 @@ import time import pickle import numpy as np -from cereal import messaging -from cereal.messaging import PubMaster, SubMaster +from openpilot.cereal import messaging +from openpilot.cereal.messaging import PubMaster, SubMaster from msgq.visionipc import VisionIpcClient, VisionStreamType, VisionBuf from openpilot.common.swaglog import cloudlog from openpilot.common.realtime import config_realtime_process diff --git a/selfdrive/modeld/fill_model_msg.py b/selfdrive/modeld/fill_model_msg.py index 8e63d29ea2..d926ace3da 100644 --- a/selfdrive/modeld/fill_model_msg.py +++ b/selfdrive/modeld/fill_model_msg.py @@ -1,7 +1,7 @@ import os import capnp import numpy as np -from cereal import log +from openpilot.cereal import log from openpilot.selfdrive.modeld.constants import ModelConstants, Plan, Meta SEND_RAW_PRED = os.getenv('SEND_RAW_PRED') diff --git a/selfdrive/modeld/modeld.py b/selfdrive/modeld/modeld.py index 18f665529c..590d0f103e 100755 --- a/selfdrive/modeld/modeld.py +++ b/selfdrive/modeld/modeld.py @@ -5,10 +5,10 @@ from tinygrad.tensor import Tensor import time import pickle import numpy as np -import cereal.messaging as messaging -from cereal import log +import openpilot.cereal.messaging as messaging +from openpilot.cereal import log from opendbc.car.structs import car -from cereal.messaging import PubMaster, SubMaster +from openpilot.cereal.messaging import PubMaster, SubMaster from msgq.visionipc import VisionIpcClient, VisionStreamType, VisionBuf from opendbc.car.car_helpers import get_demo_car_params from openpilot.common.swaglog import cloudlog diff --git a/selfdrive/monitoring/dmonitoringd.py b/selfdrive/monitoring/dmonitoringd.py index c81245a815..a70659cb06 100755 --- a/selfdrive/monitoring/dmonitoringd.py +++ b/selfdrive/monitoring/dmonitoringd.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -import cereal.messaging as messaging +import openpilot.cereal.messaging as messaging from openpilot.common.params import Params from openpilot.common.realtime import config_realtime_process from openpilot.selfdrive.monitoring.policy import DriverMonitoring diff --git a/selfdrive/monitoring/policy.py b/selfdrive/monitoring/policy.py index 146717349d..adb61b0a38 100644 --- a/selfdrive/monitoring/policy.py +++ b/selfdrive/monitoring/policy.py @@ -2,9 +2,9 @@ from collections import defaultdict from math import atan2, radians import numpy as np -from cereal import log +from openpilot.cereal import log from opendbc.car.structs import car -import cereal.messaging as messaging +import openpilot.cereal.messaging as messaging from openpilot.common.realtime import DT_DMON from openpilot.common.filter_simple import FirstOrderFilter from openpilot.common.params import Params diff --git a/selfdrive/monitoring/test_monitoring.py b/selfdrive/monitoring/test_monitoring.py index 05ab4bfd91..c13f043ce9 100644 --- a/selfdrive/monitoring/test_monitoring.py +++ b/selfdrive/monitoring/test_monitoring.py @@ -1,6 +1,6 @@ import numpy as np -from cereal import log +from openpilot.cereal import log from openpilot.common.realtime import DT_DMON from openpilot.selfdrive.monitoring.policy import DriverMonitoring, DRIVER_MONITOR_SETTINGS diff --git a/selfdrive/pandad/panda.cc b/selfdrive/pandad/panda.cc index edc2228c0c..730ce59b6e 100644 --- a/selfdrive/pandad/panda.cc +++ b/selfdrive/pandad/panda.cc @@ -6,7 +6,7 @@ #include #include -#include "cereal/messaging/messaging.h" +#include "openpilot/cereal/messaging/messaging.h" #include "common/swaglog.h" #include "common/util.h" diff --git a/selfdrive/pandad/panda.h b/selfdrive/pandad/panda.h index 1a066dc5fb..b0fb637b6b 100644 --- a/selfdrive/pandad/panda.h +++ b/selfdrive/pandad/panda.h @@ -9,8 +9,8 @@ #include #include -#include "cereal/gen/cpp/car.capnp.h" -#include "cereal/gen/cpp/log.capnp.h" +#include "openpilot/cereal/gen/cpp/car.capnp.h" +#include "openpilot/cereal/gen/cpp/log.capnp.h" #include "panda/board/health.h" #include "panda/board/can.h" #include "selfdrive/pandad/panda_comms.h" diff --git a/selfdrive/pandad/panda_safety.cc b/selfdrive/pandad/panda_safety.cc index 32d129bc2e..a0e1fdbe7b 100644 --- a/selfdrive/pandad/panda_safety.cc +++ b/selfdrive/pandad/panda_safety.cc @@ -1,5 +1,5 @@ #include "selfdrive/pandad/pandad.h" -#include "cereal/messaging/messaging.h" +#include "openpilot/cereal/messaging/messaging.h" #include "common/swaglog.h" void PandaSafety::configureSafetyMode(bool is_onroad) { diff --git a/selfdrive/pandad/pandad.cc b/selfdrive/pandad/pandad.cc index 657e36e6b8..68d74f81a1 100644 --- a/selfdrive/pandad/pandad.cc +++ b/selfdrive/pandad/pandad.cc @@ -8,9 +8,9 @@ #include #include -#include "cereal/gen/cpp/car.capnp.h" -#include "cereal/messaging/messaging.h" -#include "cereal/services.h" +#include "openpilot/cereal/gen/cpp/car.capnp.h" +#include "openpilot/cereal/messaging/messaging.h" +#include "openpilot/cereal/services.h" #include "common/ratekeeper.h" #include "common/swaglog.h" #include "common/timing.h" diff --git a/selfdrive/pandad/pandad_api_impl.py b/selfdrive/pandad/pandad_api_impl.py index 75a7ba484e..9da277d73a 100644 --- a/selfdrive/pandad/pandad_api_impl.py +++ b/selfdrive/pandad/pandad_api_impl.py @@ -1,5 +1,5 @@ import time -from cereal import log +from openpilot.cereal import log NO_TRAVERSAL_LIMIT = 2**64 - 1 diff --git a/selfdrive/pandad/tests/test_pandad.py b/selfdrive/pandad/tests/test_pandad.py index 88022dda8d..e7a7107dcd 100644 --- a/selfdrive/pandad/tests/test_pandad.py +++ b/selfdrive/pandad/tests/test_pandad.py @@ -2,8 +2,8 @@ import os import pytest import time -import cereal.messaging as messaging -from cereal import log +import openpilot.cereal.messaging as messaging +from openpilot.cereal import log from openpilot.common.gpio import gpio_set, gpio_init from panda import Panda, PandaDFU from openpilot.system.manager.process_config import managed_processes diff --git a/selfdrive/pandad/tests/test_pandad_canprotocol.cc b/selfdrive/pandad/tests/test_pandad_canprotocol.cc index 8499a1aab8..83339a4c1c 100644 --- a/selfdrive/pandad/tests/test_pandad_canprotocol.cc +++ b/selfdrive/pandad/tests/test_pandad_canprotocol.cc @@ -4,7 +4,7 @@ #include #include "catch2/catch.hpp" -#include "cereal/messaging/messaging.h" +#include "openpilot/cereal/messaging/messaging.h" #include "common/util.h" #include "selfdrive/pandad/panda.h" diff --git a/selfdrive/pandad/tests/test_pandad_loopback.py b/selfdrive/pandad/tests/test_pandad_loopback.py index 5543b6d03c..0d0aa80046 100644 --- a/selfdrive/pandad/tests/test_pandad_loopback.py +++ b/selfdrive/pandad/tests/test_pandad_loopback.py @@ -6,8 +6,8 @@ import pytest from collections import defaultdict from pprint import pprint -import cereal.messaging as messaging -from cereal import log +import openpilot.cereal.messaging as messaging +from openpilot.cereal import log from opendbc.car.structs import car from opendbc.car.can_definitions import CanData from openpilot.common.utils import retry diff --git a/selfdrive/pandad/tests/test_pandad_spi.py b/selfdrive/pandad/tests/test_pandad_spi.py index 50021d8998..672244026f 100644 --- a/selfdrive/pandad/tests/test_pandad_spi.py +++ b/selfdrive/pandad/tests/test_pandad_spi.py @@ -4,8 +4,8 @@ import numpy as np import pytest import random -import cereal.messaging as messaging -from cereal.services import SERVICE_LIST +import openpilot.cereal.messaging as messaging +from openpilot.cereal.services import SERVICE_LIST from openpilot.selfdrive.test.helpers import with_processes from openpilot.selfdrive.pandad.tests.test_pandad_loopback import setup_pandad, send_random_can_messages diff --git a/selfdrive/selfdrived/events.py b/selfdrive/selfdrived/events.py index efdbd35d7b..cc841accaf 100755 --- a/selfdrive/selfdrived/events.py +++ b/selfdrive/selfdrived/events.py @@ -5,9 +5,9 @@ import os from enum import IntEnum from collections.abc import Callable -from cereal import log +from openpilot.cereal import log from opendbc.car.structs import car -import cereal.messaging as messaging +import openpilot.cereal.messaging as messaging from openpilot.common.constants import CV from openpilot.common.git import get_short_branch from openpilot.common.realtime import DT_CTRL @@ -1101,7 +1101,7 @@ if HARDWARE.get_device_type() == 'mici': if __name__ == '__main__': # print all alerts by type and priority - from cereal.services import SERVICE_LIST + from openpilot.cereal.services import SERVICE_LIST from collections import defaultdict event_names = {v: k for k, v in EventName.schema.enumerants.items()} diff --git a/selfdrive/selfdrived/helpers.py b/selfdrive/selfdrived/helpers.py index 3182d23403..3b3c44ecaf 100644 --- a/selfdrive/selfdrived/helpers.py +++ b/selfdrive/selfdrived/helpers.py @@ -1,7 +1,7 @@ import math from enum import StrEnum, auto -from cereal import messaging +from openpilot.cereal import messaging from opendbc.car.structs import car from openpilot.common.realtime import DT_CTRL from openpilot.selfdrive.locationd.helpers import Pose diff --git a/selfdrive/selfdrived/selfdrived.py b/selfdrive/selfdrived/selfdrived.py index 261a62ff6a..064789dae8 100755 --- a/selfdrive/selfdrived/selfdrived.py +++ b/selfdrive/selfdrived/selfdrived.py @@ -3,9 +3,9 @@ import os import time import threading -import cereal.messaging as messaging +import openpilot.cereal.messaging as messaging -from cereal import log +from openpilot.cereal import log from opendbc.car.structs import car from msgq.visionipc import VisionIpcClient, VisionStreamType diff --git a/selfdrive/selfdrived/state.py b/selfdrive/selfdrived/state.py index 25c22684ad..eca0019503 100644 --- a/selfdrive/selfdrived/state.py +++ b/selfdrive/selfdrived/state.py @@ -1,4 +1,4 @@ -from cereal import log +from openpilot.cereal import log from openpilot.selfdrive.selfdrived.events import Events, ET from openpilot.common.realtime import DT_CTRL diff --git a/selfdrive/selfdrived/tests/test_alerts.py b/selfdrive/selfdrived/tests/test_alerts.py index 3cd137d586..38db9981f6 100644 --- a/selfdrive/selfdrived/tests/test_alerts.py +++ b/selfdrive/selfdrived/tests/test_alerts.py @@ -4,9 +4,9 @@ import os import random from PIL import Image, ImageDraw, ImageFont -from cereal import log +from openpilot.cereal import log from opendbc.car.structs import car -from cereal.messaging import SubMaster +from openpilot.cereal.messaging import SubMaster from openpilot.common.basedir import BASEDIR from openpilot.common.params import Params from openpilot.selfdrive.selfdrived.events import Alert, EVENTS, ET diff --git a/selfdrive/selfdrived/tests/test_state_machine.py b/selfdrive/selfdrived/tests/test_state_machine.py index b720f48f1e..8139e53d2e 100644 --- a/selfdrive/selfdrived/tests/test_state_machine.py +++ b/selfdrive/selfdrived/tests/test_state_machine.py @@ -1,4 +1,4 @@ -from cereal import log +from openpilot.cereal import log from openpilot.common.realtime import DT_CTRL from openpilot.selfdrive.selfdrived.state import StateMachine, SOFT_DISABLE_TIME from openpilot.selfdrive.selfdrived.events import Events, ET, EVENTS, NormalPermanentAlert diff --git a/selfdrive/test/fuzzy_generation.py b/selfdrive/test/fuzzy_generation.py index 9f028a8fc8..c97221ae9e 100644 --- a/selfdrive/test/fuzzy_generation.py +++ b/selfdrive/test/fuzzy_generation.py @@ -4,7 +4,7 @@ from typing import Any from collections.abc import Callable from functools import cache -from cereal import log +from openpilot.cereal import log DrawType = Callable[[st.SearchStrategy], Any] diff --git a/selfdrive/test/helpers.py b/selfdrive/test/helpers.py index 615ea5d8ac..9d954216b8 100644 --- a/selfdrive/test/helpers.py +++ b/selfdrive/test/helpers.py @@ -7,7 +7,7 @@ import pytest from functools import wraps -import cereal.messaging as messaging +import openpilot.cereal.messaging as messaging from openpilot.common.params import Params from openpilot.system.manager.process_config import managed_processes from openpilot.common.version import training_version, terms_version diff --git a/selfdrive/test/longitudinal_maneuvers/plant.py b/selfdrive/test/longitudinal_maneuvers/plant.py index 5f768a1fb9..fbffde911a 100755 --- a/selfdrive/test/longitudinal_maneuvers/plant.py +++ b/selfdrive/test/longitudinal_maneuvers/plant.py @@ -2,8 +2,8 @@ import time import numpy as np -from cereal import log -import cereal.messaging as messaging +from openpilot.cereal import log +import openpilot.cereal.messaging as messaging from openpilot.common.realtime import Ratekeeper, DT_MDL from openpilot.selfdrive.controls.lib.longcontrol import LongCtrlState from openpilot.selfdrive.modeld.constants import ModelConstants diff --git a/selfdrive/test/process_replay/diff_report.py b/selfdrive/test/process_replay/diff_report.py index 5da78657f4..c6c1f01abd 100644 --- a/selfdrive/test/process_replay/diff_report.py +++ b/selfdrive/test/process_replay/diff_report.py @@ -1,6 +1,5 @@ import os from collections import defaultdict - from opendbc.car.tests.car_diff import format_diff, format_numeric_diffs from openpilot.selfdrive.test.process_replay.compare_logs import compare_logs from openpilot.selfdrive.test.process_replay.process_replay import PROC_REPLAY_DIR diff --git a/selfdrive/test/process_replay/migration.py b/selfdrive/test/process_replay/migration.py index e10db26e79..0045fa8a87 100644 --- a/selfdrive/test/process_replay/migration.py +++ b/selfdrive/test/process_replay/migration.py @@ -5,7 +5,7 @@ import capnp import functools import traceback -from cereal import messaging, log +from openpilot.cereal import messaging, log from opendbc.car.structs import car from opendbc.car.fingerprints import MIGRATION from opendbc.car.toyota.values import EPS_SCALE, ToyotaSafetyFlags diff --git a/selfdrive/test/process_replay/process_replay.py b/selfdrive/test/process_replay/process_replay.py index 110b0101a5..b34535e96b 100755 --- a/selfdrive/test/process_replay/process_replay.py +++ b/selfdrive/test/process_replay/process_replay.py @@ -14,9 +14,9 @@ from tqdm import tqdm import capnp from openpilot.common.hardware.hw import Paths -import cereal.messaging as messaging +import openpilot.cereal.messaging as messaging from opendbc.car.structs import car -from cereal.services import SERVICE_LIST +from openpilot.cereal.services import SERVICE_LIST from msgq.visionipc import VisionIpcServer, get_endpoint_name as vipc_get_endpoint_name from opendbc.car.can_definitions import CanData from opendbc.car.car_helpers import get_car, interfaces diff --git a/selfdrive/test/process_replay/test_fuzzy.py b/selfdrive/test/process_replay/test_fuzzy.py index 6989f8957f..372b368608 100644 --- a/selfdrive/test/process_replay/test_fuzzy.py +++ b/selfdrive/test/process_replay/test_fuzzy.py @@ -4,7 +4,7 @@ from hypothesis import given, HealthCheck, Phase, settings import hypothesis.strategies as st from openpilot.common.parameterized import parameterized -from cereal import log +from openpilot.cereal import log from opendbc.car.toyota.values import CAR as TOYOTA from openpilot.selfdrive.test.fuzzy_generation import FuzzyGenerator import openpilot.selfdrive.test.process_replay.process_replay as pr diff --git a/selfdrive/test/process_replay/test_processes.py b/selfdrive/test/process_replay/test_processes.py index bc0085534c..d9d827add5 100755 --- a/selfdrive/test/process_replay/test_processes.py +++ b/selfdrive/test/process_replay/test_processes.py @@ -7,7 +7,6 @@ import traceback from collections import defaultdict from tqdm import tqdm from typing import Any - from opendbc.car.car_helpers import interface_names from openpilot.common.git import get_commit from openpilot.tools.lib.openpilotci import get_url diff --git a/selfdrive/test/test_onroad.py b/selfdrive/test/test_onroad.py index 974859a23c..f64bc3b027 100644 --- a/selfdrive/test/test_onroad.py +++ b/selfdrive/test/test_onroad.py @@ -10,9 +10,9 @@ from collections import Counter, defaultdict from pathlib import Path from openpilot.common.utils import tabulate -from cereal import log -import cereal.messaging as messaging -from cereal.services import SERVICE_LIST +from openpilot.cereal import log +import openpilot.cereal.messaging as messaging +from openpilot.cereal.services import SERVICE_LIST from openpilot.common.basedir import BASEDIR from openpilot.common.timeout import Timeout from openpilot.common.params import Params diff --git a/selfdrive/test/test_power_draw.py b/selfdrive/test/test_power_draw.py index ad27292945..d5bb3d324d 100644 --- a/selfdrive/test/test_power_draw.py +++ b/selfdrive/test/test_power_draw.py @@ -5,8 +5,8 @@ import numpy as np from dataclasses import dataclass from openpilot.common.utils import tabulate -import cereal.messaging as messaging -from cereal.services import SERVICE_LIST +import openpilot.cereal.messaging as messaging +from openpilot.cereal.services import SERVICE_LIST from opendbc.car.car_helpers import get_demo_car_params from openpilot.common.mock import mock_messages from openpilot.common.params import Params diff --git a/selfdrive/test/update_ci_routes.py b/selfdrive/test/update_ci_routes.py index 54e1c88718..40f74ee93c 100755 --- a/selfdrive/test/update_ci_routes.py +++ b/selfdrive/test/update_ci_routes.py @@ -6,7 +6,6 @@ import sys from collections.abc import Iterable from tqdm import tqdm - from opendbc.car.tests.routes import routes as test_car_models_routes from openpilot.selfdrive.test.process_replay.test_processes import source_segments as replay_segments from openpilot.tools.lib.azure_container import AzureContainer diff --git a/selfdrive/ui/feedback/feedbackd.py b/selfdrive/ui/feedback/feedbackd.py index b59954926c..57f6b881e4 100755 --- a/selfdrive/ui/feedback/feedbackd.py +++ b/selfdrive/ui/feedback/feedbackd.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -import cereal.messaging as messaging +import openpilot.cereal.messaging as messaging from openpilot.common.params import Params from openpilot.common.swaglog import cloudlog from opendbc.car.structs import car diff --git a/selfdrive/ui/layouts/main.py b/selfdrive/ui/layouts/main.py index 672f5463d9..47a52280f2 100644 --- a/selfdrive/ui/layouts/main.py +++ b/selfdrive/ui/layouts/main.py @@ -1,6 +1,6 @@ import pyray as rl from enum import IntEnum -import cereal.messaging as messaging +import openpilot.cereal.messaging as messaging from openpilot.system.ui.lib.application import gui_app from openpilot.system.ui.widgets import Widget from openpilot.selfdrive.ui.layouts.sidebar import Sidebar, SIDEBAR_WIDTH diff --git a/selfdrive/ui/layouts/settings/device.py b/selfdrive/ui/layouts/settings/device.py index 845fca3e83..0930616e19 100644 --- a/selfdrive/ui/layouts/settings/device.py +++ b/selfdrive/ui/layouts/settings/device.py @@ -1,7 +1,7 @@ import os import math -from cereal import messaging, log +from openpilot.cereal import messaging, log from openpilot.common.basedir import BASEDIR from openpilot.common.params import Params from openpilot.common.swaglog import cloudlog diff --git a/selfdrive/ui/layouts/settings/toggles.py b/selfdrive/ui/layouts/settings/toggles.py index f342175a82..b03ecd10ec 100644 --- a/selfdrive/ui/layouts/settings/toggles.py +++ b/selfdrive/ui/layouts/settings/toggles.py @@ -1,4 +1,4 @@ -from cereal import log +from openpilot.cereal import log from openpilot.common.params import Params, UnknownKeyName from openpilot.system.ui.widgets import Widget from openpilot.system.ui.widgets.list_view import multiple_button_item, toggle_item diff --git a/selfdrive/ui/layouts/sidebar.py b/selfdrive/ui/layouts/sidebar.py index 3b45c994c0..eabf5cc008 100644 --- a/selfdrive/ui/layouts/sidebar.py +++ b/selfdrive/ui/layouts/sidebar.py @@ -2,7 +2,7 @@ import pyray as rl import time from dataclasses import dataclass from collections.abc import Callable -from cereal import log +from openpilot.cereal import log from openpilot.selfdrive.ui.ui_state import ui_state from openpilot.system.ui.lib.application import gui_app, FontWeight, MousePos, FONT_SCALE from openpilot.system.ui.lib.multilang import tr, tr_noop diff --git a/selfdrive/ui/mici/layouts/home.py b/selfdrive/ui/mici/layouts/home.py index 997ca6276f..adb02fb731 100644 --- a/selfdrive/ui/mici/layouts/home.py +++ b/selfdrive/ui/mici/layouts/home.py @@ -1,7 +1,7 @@ import datetime import time -from cereal import log +from openpilot.cereal import log import pyray as rl from collections.abc import Callable from openpilot.system.ui.widgets import Widget diff --git a/selfdrive/ui/mici/layouts/main.py b/selfdrive/ui/mici/layouts/main.py index 9b4bcb5cc4..26ec5555be 100644 --- a/selfdrive/ui/mici/layouts/main.py +++ b/selfdrive/ui/mici/layouts/main.py @@ -1,5 +1,5 @@ import pyray as rl -import cereal.messaging as messaging +import openpilot.cereal.messaging as messaging from openpilot.selfdrive.ui.mici.layouts.home import MiciHomeLayout from openpilot.selfdrive.ui.mici.layouts.settings.settings import SettingsLayout from openpilot.selfdrive.ui.mici.layouts.offroad_alerts import MiciOffroadAlerts diff --git a/selfdrive/ui/mici/layouts/settings/toggles.py b/selfdrive/ui/mici/layouts/settings/toggles.py index acb502fda0..5f75ef8903 100644 --- a/selfdrive/ui/mici/layouts/settings/toggles.py +++ b/selfdrive/ui/mici/layouts/settings/toggles.py @@ -1,4 +1,4 @@ -from cereal import log +from openpilot.cereal import log from openpilot.system.ui.widgets.scroller import NavScroller from openpilot.selfdrive.ui.mici.widgets.button import BigParamControl, BigMultiParamToggle diff --git a/selfdrive/ui/mici/onroad/alert_renderer.py b/selfdrive/ui/mici/onroad/alert_renderer.py index a9cb5790d2..e2e398a4e1 100644 --- a/selfdrive/ui/mici/onroad/alert_renderer.py +++ b/selfdrive/ui/mici/onroad/alert_renderer.py @@ -5,7 +5,7 @@ import pyray as rl import random import string from dataclasses import dataclass -from cereal import messaging, log +from openpilot.cereal import messaging, log from opendbc.car.structs import car from openpilot.selfdrive.ui.ui_state import ui_state from openpilot.common.filter_simple import BounceFilter, FirstOrderFilter diff --git a/selfdrive/ui/mici/onroad/augmented_road_view.py b/selfdrive/ui/mici/onroad/augmented_road_view.py index 0fe5875b8d..25061f12ae 100644 --- a/selfdrive/ui/mici/onroad/augmented_road_view.py +++ b/selfdrive/ui/mici/onroad/augmented_road_view.py @@ -1,6 +1,6 @@ import numpy as np import pyray as rl -from cereal import log +from openpilot.cereal import log from opendbc.car.structs import car from msgq.visionipc import VisionStreamType from openpilot.selfdrive.ui.ui_state import ui_state, UIStatus diff --git a/selfdrive/ui/mici/onroad/driver_camera_dialog.py b/selfdrive/ui/mici/onroad/driver_camera_dialog.py index f45cf33912..d880189412 100644 --- a/selfdrive/ui/mici/onroad/driver_camera_dialog.py +++ b/selfdrive/ui/mici/onroad/driver_camera_dialog.py @@ -1,5 +1,5 @@ import pyray as rl -from cereal import log, messaging +from openpilot.cereal import log, messaging from opendbc.car.structs import car from msgq.visionipc import VisionStreamType from openpilot.selfdrive.ui.mici.onroad.cameraview import CameraView diff --git a/selfdrive/ui/mici/onroad/driver_state.py b/selfdrive/ui/mici/onroad/driver_state.py index 1855d77b77..85b90704ac 100644 --- a/selfdrive/ui/mici/onroad/driver_state.py +++ b/selfdrive/ui/mici/onroad/driver_state.py @@ -1,7 +1,7 @@ import pyray as rl import numpy as np import math -from cereal import log +from openpilot.cereal import log from openpilot.common.filter_simple import FirstOrderFilter from openpilot.system.ui.lib.application import gui_app from openpilot.system.ui.widgets import Widget diff --git a/selfdrive/ui/mici/onroad/hud_renderer.py b/selfdrive/ui/mici/onroad/hud_renderer.py index 620dc543b7..27bb815590 100644 --- a/selfdrive/ui/mici/onroad/hud_renderer.py +++ b/selfdrive/ui/mici/onroad/hud_renderer.py @@ -8,7 +8,7 @@ from openpilot.system.ui.lib.multilang import tr from openpilot.system.ui.lib.text_measure import measure_text_cached from openpilot.system.ui.widgets import Widget from openpilot.common.filter_simple import FirstOrderFilter -from cereal import log +from openpilot.cereal import log EventName = log.OnroadEvent.EventName diff --git a/selfdrive/ui/mici/onroad/model_renderer.py b/selfdrive/ui/mici/onroad/model_renderer.py index 6e335b0af2..0442aa2b65 100644 --- a/selfdrive/ui/mici/onroad/model_renderer.py +++ b/selfdrive/ui/mici/onroad/model_renderer.py @@ -1,7 +1,7 @@ import colorsys import numpy as np import pyray as rl -from cereal import messaging +from openpilot.cereal import messaging from opendbc.car.structs import car from dataclasses import dataclass, field from openpilot.common.params import Params diff --git a/selfdrive/ui/onroad/alert_renderer.py b/selfdrive/ui/onroad/alert_renderer.py index cfb4bf6616..0ce404bec3 100644 --- a/selfdrive/ui/onroad/alert_renderer.py +++ b/selfdrive/ui/onroad/alert_renderer.py @@ -1,7 +1,7 @@ import time import pyray as rl from dataclasses import dataclass -from cereal import messaging, log +from openpilot.cereal import messaging, log from openpilot.selfdrive.ui.ui_state import ui_state from openpilot.common.hardware import TICI from openpilot.system.ui.lib.application import gui_app, FontWeight diff --git a/selfdrive/ui/onroad/augmented_road_view.py b/selfdrive/ui/onroad/augmented_road_view.py index d381c255ea..1b0c84f0fe 100644 --- a/selfdrive/ui/onroad/augmented_road_view.py +++ b/selfdrive/ui/onroad/augmented_road_view.py @@ -1,6 +1,6 @@ import numpy as np import pyray as rl -from cereal import log +from openpilot.cereal import log from msgq.visionipc import VisionStreamType from openpilot.selfdrive.ui import UI_BORDER_SIZE from openpilot.selfdrive.ui.ui_state import ui_state, UIStatus diff --git a/selfdrive/ui/onroad/driver_state.py b/selfdrive/ui/onroad/driver_state.py index 5b09e471b5..6b11f0b10b 100644 --- a/selfdrive/ui/onroad/driver_state.py +++ b/selfdrive/ui/onroad/driver_state.py @@ -1,6 +1,6 @@ import numpy as np import pyray as rl -from cereal import log +from openpilot.cereal import log from dataclasses import dataclass from openpilot.selfdrive.ui import UI_BORDER_SIZE from openpilot.selfdrive.ui.ui_state import ui_state diff --git a/selfdrive/ui/onroad/model_renderer.py b/selfdrive/ui/onroad/model_renderer.py index 94e5637a09..e21ca4f271 100644 --- a/selfdrive/ui/onroad/model_renderer.py +++ b/selfdrive/ui/onroad/model_renderer.py @@ -1,7 +1,7 @@ import colorsys import numpy as np import pyray as rl -from cereal import messaging +from openpilot.cereal import messaging from opendbc.car.structs import car from dataclasses import dataclass, field from openpilot.common.filter_simple import FirstOrderFilter diff --git a/selfdrive/ui/soundd.py b/selfdrive/ui/soundd.py index 7766d0321b..f8c364e2c5 100644 --- a/selfdrive/ui/soundd.py +++ b/selfdrive/ui/soundd.py @@ -4,7 +4,7 @@ import time import wave -from cereal import messaging +from openpilot.cereal import messaging from opendbc.car.structs import car from openpilot.common.basedir import BASEDIR from openpilot.common.filter_simple import FirstOrderFilter diff --git a/selfdrive/ui/tests/body.py b/selfdrive/ui/tests/body.py index 07a2ef5128..b9f5c2d18c 100755 --- a/selfdrive/ui/tests/body.py +++ b/selfdrive/ui/tests/body.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 import time -import cereal.messaging as messaging +import openpilot.cereal.messaging as messaging if __name__ == "__main__": while True: diff --git a/selfdrive/ui/tests/diff/replay.py b/selfdrive/ui/tests/diff/replay.py index 6f3dd8f040..5e189e3d94 100755 --- a/selfdrive/ui/tests/diff/replay.py +++ b/selfdrive/ui/tests/diff/replay.py @@ -7,7 +7,7 @@ import pyray as rl from tqdm import tqdm from typing import Literal from collections.abc import Callable -from cereal.messaging import PubMaster +from openpilot.cereal.messaging import PubMaster from openpilot.common.api import Api from openpilot.common.basedir import BASEDIR from openpilot.common.params import Params diff --git a/selfdrive/ui/tests/diff/replay_script.py b/selfdrive/ui/tests/diff/replay_script.py index f4c97a223f..60c4a21ce4 100644 --- a/selfdrive/ui/tests/diff/replay_script.py +++ b/selfdrive/ui/tests/diff/replay_script.py @@ -5,9 +5,9 @@ from dataclasses import dataclass import math -from cereal import log, messaging +from openpilot.cereal import log, messaging from opendbc.car.structs import car -from cereal.messaging import PubMaster +from openpilot.cereal.messaging import PubMaster from openpilot.common.basedir import BASEDIR from openpilot.common.params import Params from openpilot.selfdrive.selfdrived.alertmanager import set_offroad_alert diff --git a/selfdrive/ui/tests/test_feedbackd.py b/selfdrive/ui/tests/test_feedbackd.py index ada2c4763e..72bd499081 100644 --- a/selfdrive/ui/tests/test_feedbackd.py +++ b/selfdrive/ui/tests/test_feedbackd.py @@ -1,5 +1,5 @@ import pytest -import cereal.messaging as messaging +import openpilot.cereal.messaging as messaging from opendbc.car.structs import car from openpilot.common.params import Params from openpilot.system.manager.process_config import managed_processes diff --git a/selfdrive/ui/tests/test_soundd.py b/selfdrive/ui/tests/test_soundd.py index ca153b6eef..2890d4ae78 100644 --- a/selfdrive/ui/tests/test_soundd.py +++ b/selfdrive/ui/tests/test_soundd.py @@ -1,6 +1,6 @@ from opendbc.car.structs import car -from cereal import messaging -from cereal.messaging import SubMaster, PubMaster +from openpilot.cereal import messaging +from openpilot.cereal.messaging import SubMaster, PubMaster from openpilot.selfdrive.ui.soundd import SELFDRIVE_STATE_TIMEOUT, check_selfdrive_timeout_alert import time diff --git a/selfdrive/ui/ui.py b/selfdrive/ui/ui.py index fc7e40920a..ff2bc7d3ce 100755 --- a/selfdrive/ui/ui.py +++ b/selfdrive/ui/ui.py @@ -2,7 +2,7 @@ import os import time -from cereal import messaging +from openpilot.cereal import messaging from openpilot.common.hardware import TICI from openpilot.common.realtime import Priority, config_realtime_process, set_core_affinity from openpilot.system.ui.lib.application import gui_app diff --git a/selfdrive/ui/ui_state.py b/selfdrive/ui/ui_state.py index 4cc5810bb9..78388593c8 100644 --- a/selfdrive/ui/ui_state.py +++ b/selfdrive/ui/ui_state.py @@ -3,7 +3,7 @@ import time import threading from collections.abc import Callable from enum import Enum -from cereal import messaging, log +from openpilot.cereal import messaging, log from opendbc.car.structs import car from openpilot.common.filter_simple import FirstOrderFilter from openpilot.common.params import Params diff --git a/system/athena/athenad.py b/system/athena/athenad.py index d5bcc92f13..3949a7b201 100755 --- a/system/athena/athenad.py +++ b/system/athena/athenad.py @@ -27,10 +27,10 @@ from jsonrpc import JSONRPCResponseManager, dispatcher from websocket import (ABNF, WebSocket, WebSocketException, WebSocketTimeoutException, create_connection) -import cereal.messaging as messaging -from cereal import log +import openpilot.cereal.messaging as messaging +from openpilot.cereal import log from opendbc.car.structs import car -from cereal.services import SERVICE_LIST +from openpilot.cereal.services import SERVICE_LIST from openpilot.common.api import Api, get_key_pair from openpilot.common.utils import CallbackReader, get_upload_stream from openpilot.common.params import Params diff --git a/system/athena/tests/test_athenad.py b/system/athena/tests/test_athenad.py index 0e3ae68d4e..253a057b91 100644 --- a/system/athena/tests/test_athenad.py +++ b/system/athena/tests/test_athenad.py @@ -14,7 +14,7 @@ from datetime import datetime, timedelta from websocket import ABNF from websocket._exceptions import WebSocketConnectionClosedException -from cereal import messaging +from openpilot.cereal import messaging from openpilot.common.params import Params from openpilot.common.timeout import Timeout diff --git a/system/camerad/cameras/camera_common.h b/system/camerad/cameras/camera_common.h index 7f35e06a83..24f70dbcf3 100644 --- a/system/camerad/cameras/camera_common.h +++ b/system/camerad/cameras/camera_common.h @@ -2,7 +2,7 @@ #include -#include "cereal/messaging/messaging.h" +#include "openpilot/cereal/messaging/messaging.h" #include "msgq/visionipc/visionipc_server.h" #include "common/util.h" diff --git a/system/camerad/cameras/hw.h b/system/camerad/cameras/hw.h index defe878e89..be0bea872d 100644 --- a/system/camerad/cameras/hw.h +++ b/system/camerad/cameras/hw.h @@ -1,7 +1,7 @@ #pragma once #include "common/util.h" -#include "cereal/gen/cpp/log.capnp.h" +#include "openpilot/cereal/gen/cpp/log.capnp.h" #include "msgq/visionipc/visionipc_server.h" #include "media/cam_isp_ife.h" diff --git a/system/camerad/sensors/sensor.h b/system/camerad/sensors/sensor.h index 1a647d1528..251f5d64b4 100644 --- a/system/camerad/sensors/sensor.h +++ b/system/camerad/sensors/sensor.h @@ -9,7 +9,7 @@ #include "media/cam_isp.h" #include "media/cam_sensor.h" -#include "cereal/gen/cpp/log.capnp.h" +#include "openpilot/cereal/gen/cpp/log.capnp.h" #include "system/camerad/sensors/ox03c10_registers.h" #include "system/camerad/sensors/os04c10_registers.h" diff --git a/system/camerad/snapshot.py b/system/camerad/snapshot.py index 241f027044..1e73718abd 100755 --- a/system/camerad/snapshot.py +++ b/system/camerad/snapshot.py @@ -5,7 +5,7 @@ import time import numpy as np from PIL import Image -import cereal.messaging as messaging +import openpilot.cereal.messaging as messaging from msgq.visionipc import VisionIpcClient, VisionStreamType from openpilot.common.params import Params from openpilot.common.realtime import DT_MDL diff --git a/system/camerad/test/test_camerad.py b/system/camerad/test/test_camerad.py index 3abe4db654..afc49c02bf 100644 --- a/system/camerad/test/test_camerad.py +++ b/system/camerad/test/test_camerad.py @@ -3,7 +3,7 @@ import time import pytest import numpy as np -from cereal.services import SERVICE_LIST +from openpilot.cereal.services import SERVICE_LIST from openpilot.tools.lib.log_time_series import msgs_to_time_series from openpilot.system.camerad.snapshot import get_snapshots from openpilot.selfdrive.test.helpers import collect_logs, log_collector, processes_context diff --git a/system/camerad/webcam/camerad.py b/system/camerad/webcam/camerad.py index 401eec106f..c46482360d 100755 --- a/system/camerad/webcam/camerad.py +++ b/system/camerad/webcam/camerad.py @@ -5,7 +5,7 @@ import platform from collections import namedtuple from msgq.visionipc import VisionIpcServer, VisionStreamType -from cereal import messaging +from openpilot.cereal import messaging from openpilot.system.camerad.webcam.camera import Camera from openpilot.common.realtime import Ratekeeper diff --git a/system/hardware/hardwared.py b/system/hardware/hardwared.py index c7b7befd55..c56c37082f 100755 --- a/system/hardware/hardwared.py +++ b/system/hardware/hardwared.py @@ -9,9 +9,9 @@ from collections import OrderedDict, namedtuple import psutil -import cereal.messaging as messaging -from cereal import log -from cereal.services import SERVICE_LIST +import openpilot.cereal.messaging as messaging +from openpilot.cereal import log +from openpilot.cereal.services import SERVICE_LIST from openpilot.common.utils import strip_deprecated_keys from openpilot.common.filter_simple import FirstOrderFilter from openpilot.common.params import Params diff --git a/system/journald.py b/system/journald.py index 7c656d3b13..091494b652 100755 --- a/system/journald.py +++ b/system/journald.py @@ -2,7 +2,7 @@ import json import subprocess -import cereal.messaging as messaging +import openpilot.cereal.messaging as messaging from openpilot.common.swaglog import cloudlog diff --git a/system/loggerd/bootlog.cc b/system/loggerd/bootlog.cc index 1b87ce394f..b2e3abfcf1 100644 --- a/system/loggerd/bootlog.cc +++ b/system/loggerd/bootlog.cc @@ -1,7 +1,7 @@ #include #include -#include "cereal/messaging/messaging.h" +#include "openpilot/cereal/messaging/messaging.h" #include "common/params.h" #include "common/swaglog.h" #include "system/loggerd/logger.h" @@ -28,7 +28,7 @@ static kj::Array build_boot_log() { // Gather output of commands std::vector bootlog_commands = { - "[ -x \"$(command -v journalctl)\" ] && journalctl -o short-monotonic", + "[ -x \"$(command -v journalctl)\" ] && journalctl -b -n 2000 -o short-monotonic --no-pager", }; diff --git a/system/loggerd/encoder/encoder.h b/system/loggerd/encoder/encoder.h index 696cb86737..d333351cb4 100644 --- a/system/loggerd/encoder/encoder.h +++ b/system/loggerd/encoder/encoder.h @@ -14,7 +14,7 @@ #include #include -#include "cereal/messaging/messaging.h" +#include "openpilot/cereal/messaging/messaging.h" #include "msgq/visionipc/visionipc.h" #include "common/queue.h" #include "system/loggerd/loggerd.h" diff --git a/system/loggerd/encoder/jpeg_encoder.h b/system/loggerd/encoder/jpeg_encoder.h index af1427c19a..3bd1308b4b 100644 --- a/system/loggerd/encoder/jpeg_encoder.h +++ b/system/loggerd/encoder/jpeg_encoder.h @@ -7,7 +7,7 @@ #include #include #include -#include "cereal/messaging/messaging.h" +#include "openpilot/cereal/messaging/messaging.h" #include "msgq/visionipc/visionbuf.h" class JpegEncoder { diff --git a/system/loggerd/logger.h b/system/loggerd/logger.h index dba7c2f44c..419becfe5d 100644 --- a/system/loggerd/logger.h +++ b/system/loggerd/logger.h @@ -4,7 +4,7 @@ #include #include -#include "cereal/messaging/messaging.h" +#include "openpilot/cereal/messaging/messaging.h" #include "common/util.h" #include "common/hardware/hw.h" #include "system/loggerd/zstd_writer.h" diff --git a/system/loggerd/loggerd.h b/system/loggerd/loggerd.h index 7877e9dbb8..110dbe4fd2 100644 --- a/system/loggerd/loggerd.h +++ b/system/loggerd/loggerd.h @@ -3,8 +3,8 @@ #include #include -#include "cereal/messaging/messaging.h" -#include "cereal/services.h" +#include "openpilot/cereal/messaging/messaging.h" +#include "openpilot/cereal/services.h" #include "msgq/visionipc/visionipc_client.h" #include "common/hardware/hw.h" #include "common/params.h" diff --git a/system/loggerd/tests/test_loggerd.py b/system/loggerd/tests/test_loggerd.py index 217de649eb..7a6a741aa4 100644 --- a/system/loggerd/tests/test_loggerd.py +++ b/system/loggerd/tests/test_loggerd.py @@ -9,9 +9,9 @@ from collections import defaultdict from pathlib import Path import pytest -import cereal.messaging as messaging -from cereal import log -from cereal.services import SERVICE_LIST +import openpilot.cereal.messaging as messaging +from openpilot.cereal import log +from openpilot.cereal.services import SERVICE_LIST from openpilot.common.basedir import BASEDIR from openpilot.common.params import Params from openpilot.common.timeout import Timeout diff --git a/system/loggerd/uploader.py b/system/loggerd/uploader.py index 809a302b6f..e36b12ed6a 100755 --- a/system/loggerd/uploader.py +++ b/system/loggerd/uploader.py @@ -9,8 +9,8 @@ import traceback import datetime from collections.abc import Iterator -from cereal import log -import cereal.messaging as messaging +from openpilot.cereal import log +import openpilot.cereal.messaging as messaging from openpilot.common.api import Api from openpilot.common.utils import get_upload_stream from openpilot.common.params import Params diff --git a/system/loggerd/video_writer.h b/system/loggerd/video_writer.h index e973c5d811..fdec606058 100644 --- a/system/loggerd/video_writer.h +++ b/system/loggerd/video_writer.h @@ -8,7 +8,7 @@ extern "C" { #include } -#include "cereal/messaging/messaging.h" +#include "openpilot/cereal/messaging/messaging.h" class VideoWriter { public: diff --git a/system/logmessaged.py b/system/logmessaged.py index a64a849b02..937a0741d0 100755 --- a/system/logmessaged.py +++ b/system/logmessaged.py @@ -2,7 +2,7 @@ import zmq from typing import NoReturn -import cereal.messaging as messaging +import openpilot.cereal.messaging as messaging from openpilot.common.logging_extra import SwagLogFileFormatter from openpilot.common.hardware.hw import Paths from openpilot.common.swaglog import get_file_handler diff --git a/system/manager/manager.py b/system/manager/manager.py index 179108b9b1..2d090b37f0 100755 --- a/system/manager/manager.py +++ b/system/manager/manager.py @@ -6,8 +6,8 @@ import sys import time import traceback -from cereal import log -import cereal.messaging as messaging +from openpilot.cereal import log +import openpilot.cereal.messaging as messaging import openpilot.system.sentry as sentry from openpilot.common.utils import atomic_write from openpilot.common.params import Params, ParamKeyFlag diff --git a/system/manager/process.py b/system/manager/process.py index 63dbb35eb1..a0b878d0f2 100644 --- a/system/manager/process.py +++ b/system/manager/process.py @@ -9,9 +9,9 @@ from multiprocessing import Process from setproctitle import setproctitle -from cereal import log +from openpilot.cereal import log from opendbc.car.structs import car -import cereal.messaging as messaging +import openpilot.cereal.messaging as messaging import openpilot.system.sentry as sentry from openpilot.common.basedir import BASEDIR from openpilot.common.params import Params diff --git a/system/manager/process_config.py b/system/manager/process_config.py index c4cf834560..0bf11b4b59 100644 --- a/system/manager/process_config.py +++ b/system/manager/process_config.py @@ -119,7 +119,7 @@ procs = [ PythonProcess("feedbackd", "selfdrive.ui.feedback.feedbackd", only_onroad), # debug procs - NativeProcess("bridge", "cereal/messaging", ["./bridge"], notcar), + NativeProcess("bridge", "openpilot/cereal/messaging", ["./bridge"], notcar), PythonProcess("webrtcd", "system.webrtc.webrtcd", or_(and_(livestream, not_(iscar)), notcar)), PythonProcess("joystick", "tools.joystick.joystick_control", and_(joystick, iscar)), ] diff --git a/system/micd.py b/system/micd.py index 9b3ccc8d29..a3a93c8c1a 100755 --- a/system/micd.py +++ b/system/micd.py @@ -3,7 +3,7 @@ import numpy as np from functools import cache import threading -from cereal import messaging +from openpilot.cereal import messaging from openpilot.common.realtime import Ratekeeper from openpilot.common.utils import retry from openpilot.common.swaglog import cloudlog diff --git a/system/proclogd.py b/system/proclogd.py index b008f8ed9b..9979b3a401 100755 --- a/system/proclogd.py +++ b/system/proclogd.py @@ -2,7 +2,7 @@ import os from typing import NoReturn, TypedDict -from cereal import messaging +from openpilot.cereal import messaging from openpilot.common.realtime import Ratekeeper from openpilot.common.swaglog import cloudlog diff --git a/system/qcomgpsd/qcomgpsd.py b/system/qcomgpsd/qcomgpsd.py index 78731f434b..e1a7dc39c9 100755 --- a/system/qcomgpsd/qcomgpsd.py +++ b/system/qcomgpsd/qcomgpsd.py @@ -11,8 +11,8 @@ import datetime from typing import NoReturn from struct import unpack_from, calcsize, pack -from cereal import log -import cereal.messaging as messaging +from openpilot.cereal import log +import openpilot.cereal.messaging as messaging from openpilot.common.gpio import gpio_init, gpio_set from openpilot.common.utils import retry from openpilot.common.time_helpers import system_time_valid diff --git a/system/sensord/sensord.py b/system/sensord/sensord.py index ce6fb9ccb2..6942b284df 100755 --- a/system/sensord/sensord.py +++ b/system/sensord/sensord.py @@ -5,8 +5,8 @@ import ctypes import select import threading -import cereal.messaging as messaging -from cereal.services import SERVICE_LIST +import openpilot.cereal.messaging as messaging +from openpilot.cereal.services import SERVICE_LIST from openpilot.common.utils import sudo_write from openpilot.common.realtime import config_realtime_process, Ratekeeper from openpilot.common.swaglog import cloudlog diff --git a/system/sensord/sensors/i2c_sensor.py b/system/sensord/sensors/i2c_sensor.py index 57edcc52d9..e0e8087258 100644 --- a/system/sensord/sensors/i2c_sensor.py +++ b/system/sensord/sensors/i2c_sensor.py @@ -2,7 +2,7 @@ import time import ctypes from collections.abc import Iterable -from cereal import log +from openpilot.cereal import log from openpilot.common.i2c import SMBus diff --git a/system/sensord/sensors/lsm6ds3_accel.py b/system/sensord/sensors/lsm6ds3_accel.py index 761ae828bb..e47db15250 100644 --- a/system/sensord/sensors/lsm6ds3_accel.py +++ b/system/sensord/sensors/lsm6ds3_accel.py @@ -1,7 +1,7 @@ import os import time -from cereal import log +from openpilot.cereal import log from openpilot.system.sensord.sensors.i2c_sensor import Sensor class LSM6DS3_Accel(Sensor): diff --git a/system/sensord/sensors/lsm6ds3_gyro.py b/system/sensord/sensors/lsm6ds3_gyro.py index 654cff9da8..a82827ccb4 100644 --- a/system/sensord/sensors/lsm6ds3_gyro.py +++ b/system/sensord/sensors/lsm6ds3_gyro.py @@ -2,7 +2,7 @@ import os import math import time -from cereal import log +from openpilot.cereal import log from openpilot.system.sensord.sensors.i2c_sensor import Sensor class LSM6DS3_Gyro(Sensor): diff --git a/system/sensord/sensors/lsm6ds3_temp.py b/system/sensord/sensors/lsm6ds3_temp.py index ffe970c22c..0a5e85a2b9 100644 --- a/system/sensord/sensors/lsm6ds3_temp.py +++ b/system/sensord/sensors/lsm6ds3_temp.py @@ -1,6 +1,6 @@ import time -from cereal import log +from openpilot.cereal import log from openpilot.system.sensord.sensors.i2c_sensor import Sensor # https://content.arduino.cc/assets/st_imu_lsm6ds3_datasheet.pdf diff --git a/system/sensord/tests/test_sensord.py b/system/sensord/tests/test_sensord.py index 3d7d26f9fa..27c2365602 100644 --- a/system/sensord/tests/test_sensord.py +++ b/system/sensord/tests/test_sensord.py @@ -4,8 +4,8 @@ import time import numpy as np from collections import namedtuple, defaultdict -import cereal.messaging as messaging -from cereal.services import SERVICE_LIST +import openpilot.cereal.messaging as messaging +from openpilot.cereal.services import SERVICE_LIST from openpilot.common.gpio import get_irqs_for_action from openpilot.common.timeout import Timeout from openpilot.system.manager.process_config import managed_processes diff --git a/system/tests/test_logmessaged.py b/system/tests/test_logmessaged.py index 92bcd9d1ad..e2637fb0e6 100644 --- a/system/tests/test_logmessaged.py +++ b/system/tests/test_logmessaged.py @@ -2,7 +2,7 @@ import glob import os import time -import cereal.messaging as messaging +import openpilot.cereal.messaging as messaging from openpilot.system.manager.process_config import managed_processes from openpilot.common.hardware.hw import Paths from openpilot.common.swaglog import cloudlog, ipchandler diff --git a/system/timed.py b/system/timed.py index c74ba51da5..0413f645e3 100755 --- a/system/timed.py +++ b/system/timed.py @@ -4,7 +4,7 @@ import subprocess import time from typing import NoReturn -import cereal.messaging as messaging +import openpilot.cereal.messaging as messaging from openpilot.common.time_helpers import min_date, MAX_DATE, system_time_valid from openpilot.common.swaglog import cloudlog from openpilot.common.params import Params diff --git a/system/ubloxd/pigeond.py b/system/ubloxd/pigeond.py index fe2634e333..ce9c71db61 100755 --- a/system/ubloxd/pigeond.py +++ b/system/ubloxd/pigeond.py @@ -8,7 +8,7 @@ import requests import urllib.parse from datetime import datetime, UTC -from cereal import messaging +from openpilot.cereal import messaging from openpilot.common.time_helpers import system_time_valid from openpilot.common.params import Params from openpilot.common.swaglog import cloudlog diff --git a/system/ubloxd/tests/test_pigeond.py b/system/ubloxd/tests/test_pigeond.py index fb979a9372..b894ed718b 100644 --- a/system/ubloxd/tests/test_pigeond.py +++ b/system/ubloxd/tests/test_pigeond.py @@ -1,8 +1,8 @@ import pytest import time -import cereal.messaging as messaging -from cereal.services import SERVICE_LIST +import openpilot.cereal.messaging as messaging +from openpilot.cereal.services import SERVICE_LIST from openpilot.common.gpio import gpio_read from openpilot.selfdrive.test.helpers import with_processes from openpilot.system.manager.process_config import managed_processes diff --git a/system/ubloxd/ubloxd.py b/system/ubloxd/ubloxd.py index 78429a847b..3b32f70657 100755 --- a/system/ubloxd/ubloxd.py +++ b/system/ubloxd/ubloxd.py @@ -6,8 +6,8 @@ import numpy as np from collections import defaultdict from dataclasses import dataclass -from cereal import log -from cereal import messaging +from openpilot.cereal import log +from openpilot.cereal import messaging from openpilot.system.ubloxd.ubx import Ubx from openpilot.system.ubloxd.gps import Gps from openpilot.system.ubloxd.glonass import Glonass diff --git a/system/ui/mici_setup.py b/system/ui/mici_setup.py index 4df127f1b5..465cadda0b 100755 --- a/system/ui/mici_setup.py +++ b/system/ui/mici_setup.py @@ -11,7 +11,7 @@ from collections.abc import Callable import pyray as rl -from cereal import log +from openpilot.cereal import log from openpilot.common.filter_simple import BounceFilter from openpilot.common.hardware import HARDWARE, TICI from openpilot.common.realtime import config_realtime_process, set_core_affinity diff --git a/system/ui/tici_setup.py b/system/ui/tici_setup.py index 0e0c6fdc7c..2b2c1c39f8 100755 --- a/system/ui/tici_setup.py +++ b/system/ui/tici_setup.py @@ -10,7 +10,7 @@ from enum import IntEnum import pyray as rl -from cereal import log +from openpilot.cereal import log from openpilot.common.hardware import HARDWARE from openpilot.system.ui.lib.scroll_panel import GuiScrollPanel from openpilot.system.ui.lib.application import gui_app, FontWeight, FONT_SCALE diff --git a/system/webrtc/device/video.py b/system/webrtc/device/video.py index 69f628cb11..3c8a7b93c2 100644 --- a/system/webrtc/device/video.py +++ b/system/webrtc/device/video.py @@ -6,7 +6,7 @@ import av from teleoprtc.tracks import TiciVideoStreamTrack from aiortc import MediaStreamError -from cereal import messaging +from openpilot.cereal import messaging from openpilot.common.realtime import DT_MDL from openpilot.common.params import Params diff --git a/system/webrtc/tests/test_stream_session.py b/system/webrtc/tests/test_stream_session.py index bf413eeeba..e03932f7b2 100644 --- a/system/webrtc/tests/test_stream_session.py +++ b/system/webrtc/tests/test_stream_session.py @@ -9,7 +9,7 @@ warnings.filterwarnings("ignore", category=RuntimeWarning) # TODO: remove this w from aiortc import RTCDataChannel from aiortc.mediastreams import VIDEO_CLOCK_RATE, VIDEO_TIME_BASE import capnp -from cereal import messaging, log +from openpilot.cereal import messaging, log from openpilot.system.webrtc.webrtcd import CerealOutgoingMessageProxy, CerealIncomingMessageProxy from openpilot.system.webrtc.device.video import LiveStreamVideoStreamTrack diff --git a/system/webrtc/webrtcd.py b/system/webrtc/webrtcd.py index da10855a59..72d949f551 100755 --- a/system/webrtc/webrtcd.py +++ b/system/webrtc/webrtcd.py @@ -26,7 +26,7 @@ import aioice.ice from openpilot.system.webrtc.helpers import StreamRequestBody from openpilot.system.webrtc.schema import generate_field from openpilot.common.params import Params -from cereal import messaging, log +from openpilot.cereal import messaging, log # socket trick: route lookup for 8.8.8.8 (nothing is sent or actually connected to) diff --git a/tools/cabana/README.md b/tools/cabana/README.md index a721b1aa13..b30c29640e 100644 --- a/tools/cabana/README.md +++ b/tools/cabana/README.md @@ -63,8 +63,8 @@ cabana "5beb9b58bd12b691/0000010a--a51155e496" --dcam --ecam [SSH into your device](https://github.com/commaai/openpilot/wiki/SSH) and start the bridge with the following command: ```shell -cd /data/openpilot/cereal/messaging/ -./bridge & +cd /data/openpilot +./openpilot/cereal/messaging/bridge & ``` Then Run Cabana with the device's IP address: diff --git a/tools/cabana/SConscript b/tools/cabana/SConscript index 04389a9ebf..2bc8675339 100644 --- a/tools/cabana/SConscript +++ b/tools/cabana/SConscript @@ -116,4 +116,4 @@ output_json_file = 'tools/cabana/dbc/car_fingerprint_to_dbc.json' generate_dbc = cabana_env.Command('#' + output_json_file, ['dbc/generate_dbc_json.py'], "python3 tools/cabana/dbc/generate_dbc_json.py --out " + output_json_file) -cabana_env.Depends(generate_dbc, ["#common", '#opendbc_repo', "#cereal", "#msgq_repo"]) +cabana_env.Depends(generate_dbc, ["#common", '#opendbc_repo', "#openpilot/cereal", "#msgq_repo"]) diff --git a/tools/cabana/cabana b/tools/cabana/cabana index 5eb15eabf0..e175633534 100755 --- a/tools/cabana/cabana +++ b/tools/cabana/cabana @@ -33,6 +33,6 @@ fi # Build _cabana cd "$ROOT" -scons tools/cabana/_cabana cereal/messaging/bridge +scons tools/cabana/_cabana openpilot/cereal/messaging/bridge exec "$DIR/_cabana" "$@" diff --git a/tools/cabana/dbc/generate_dbc_json.py b/tools/cabana/dbc/generate_dbc_json.py index d002a50ef8..13b6799ffb 100755 --- a/tools/cabana/dbc/generate_dbc_json.py +++ b/tools/cabana/dbc/generate_dbc_json.py @@ -1,7 +1,6 @@ #!/usr/bin/env python3 import argparse import json - from opendbc.car import Bus from opendbc.car.fingerprints import MIGRATION from opendbc.car.values import PLATFORMS diff --git a/tools/cabana/panda.cc b/tools/cabana/panda.cc index 0612d67746..9bb5320eac 100644 --- a/tools/cabana/panda.cc +++ b/tools/cabana/panda.cc @@ -6,7 +6,7 @@ #include #include -#include "cereal/messaging/messaging.h" +#include "openpilot/cereal/messaging/messaging.h" #include "common/swaglog.h" #include "common/util.h" diff --git a/tools/cabana/panda.h b/tools/cabana/panda.h index d318c33f4d..c99be1f5cf 100644 --- a/tools/cabana/panda.h +++ b/tools/cabana/panda.h @@ -13,8 +13,8 @@ #include #include -#include "cereal/gen/cpp/car.capnp.h" -#include "cereal/gen/cpp/log.capnp.h" +#include "openpilot/cereal/gen/cpp/car.capnp.h" +#include "openpilot/cereal/gen/cpp/log.capnp.h" #include "panda/board/health.h" #include "panda/board/can.h" diff --git a/tools/cabana/streams/abstractstream.h b/tools/cabana/streams/abstractstream.h index 7d66a420dc..2f3b26fe2a 100644 --- a/tools/cabana/streams/abstractstream.h +++ b/tools/cabana/streams/abstractstream.h @@ -14,7 +14,7 @@ #include #include -#include "cereal/messaging/messaging.h" +#include "openpilot/cereal/messaging/messaging.h" #include "tools/cabana/dbc/dbcmanager.h" #include "tools/cabana/utils/util.h" #include "tools/replay/util.h" diff --git a/tools/cabana/streams/devicestream.cc b/tools/cabana/streams/devicestream.cc index 20eaa70cd6..96fae908ba 100644 --- a/tools/cabana/streams/devicestream.cc +++ b/tools/cabana/streams/devicestream.cc @@ -3,7 +3,7 @@ #include #include -#include "cereal/services.h" +#include "openpilot/cereal/services.h" #include #include @@ -33,7 +33,7 @@ DeviceStream::~DeviceStream() { void DeviceStream::start() { if (!zmq_address.isEmpty()) { bridge_process = new QProcess(this); - QString bridge_path = QCoreApplication::applicationDirPath() + "/../../cereal/messaging/bridge"; + QString bridge_path = QCoreApplication::applicationDirPath() + "/../../openpilot/cereal/messaging/bridge"; bridge_process->start(QFileInfo(bridge_path).absoluteFilePath(), QStringList { zmq_address, "/\"can/\"" }); if (!bridge_process->waitForStarted()) { diff --git a/tools/camerastream/README.md b/tools/camerastream/README.md index 2f7498a07c..8b77fc5990 100644 --- a/tools/camerastream/README.md +++ b/tools/camerastream/README.md @@ -7,7 +7,7 @@ ### On the device SSH into the device and run following in separate terminals: -`cd /data/openpilot/cereal/messaging && ./bridge` +`cd /data/openpilot && ./openpilot/cereal/messaging/bridge` `cd /data/openpilot/system/loggerd && ./encoderd` @@ -18,8 +18,8 @@ Note that both the device and your PC must be on the same openpilot commit. Alternatively paste this as a single command: ``` ( - cd /data/openpilot/cereal/messaging/ - ./bridge & + cd /data/openpilot + ./openpilot/cereal/messaging/bridge & cd /data/openpilot/system/camerad/ ./camerad & diff --git a/tools/camerastream/compressed_vipc.py b/tools/camerastream/compressed_vipc.py index 4dc74272ea..0b96223e8e 100755 --- a/tools/camerastream/compressed_vipc.py +++ b/tools/camerastream/compressed_vipc.py @@ -9,7 +9,7 @@ import time import signal -import cereal.messaging as messaging +import openpilot.cereal.messaging as messaging from msgq.visionipc import VisionIpcServer, VisionStreamType V4L2_BUF_FLAG_KEYFRAME = 8 diff --git a/tools/car_porting/measure_steering_accuracy.py b/tools/car_porting/measure_steering_accuracy.py index ae3344c2eb..fa1da959a7 100755 --- a/tools/car_porting/measure_steering_accuracy.py +++ b/tools/car_porting/measure_steering_accuracy.py @@ -6,7 +6,7 @@ import argparse import signal from collections import defaultdict -import cereal.messaging as messaging +import openpilot.cereal.messaging as messaging from openpilot.tools.lib.logreader import LogReader def sigint_handler(signal, frame): diff --git a/tools/car_porting/test_car_model.py b/tools/car_porting/test_car_model.py index dd248f562e..78784a4299 100755 --- a/tools/car_porting/test_car_model.py +++ b/tools/car_porting/test_car_model.py @@ -2,7 +2,6 @@ import argparse import sys import unittest # noqa: TID251 - from opendbc.car.tests.routes import CarTestRoute from openpilot.selfdrive.car.tests.test_models import TestCarModel from openpilot.tools.lib.route import SegmentRange diff --git a/tools/jotpluggler/SConscript b/tools/jotpluggler/SConscript index d65b8c02e3..36d709621d 100644 --- a/tools/jotpluggler/SConscript +++ b/tools/jotpluggler/SConscript @@ -93,8 +93,8 @@ generated_dbc_stamp = jot_env.Command(f"generated_dbcs/.stamp", [], materialize_ car_fingerprint_to_dbc = jot_env.Command("car_fingerprint_to_dbc.h", [], write_car_fingerprint_to_dbc_header) event_extractors = jot_env.Command("generated_event_extractors.h", [ "generate_event_extractors.py", - jot_env.Glob("#cereal/*.capnp"), - jot_env.Glob("#cereal/include/*.capnp"), + jot_env.Glob("#openpilot/cereal/*.capnp"), + jot_env.Glob("#openpilot/cereal/include/*.capnp"), "#opendbc_repo/opendbc/car/car.capnp", "#opendbc_repo/opendbc/car/include/c++.capnp", ], diff --git a/tools/jotpluggler/app.h b/tools/jotpluggler/app.h index a059d94c08..a38f889687 100644 --- a/tools/jotpluggler/app.h +++ b/tools/jotpluggler/app.h @@ -1,6 +1,6 @@ #pragma once -#include "cereal/gen/cpp/log.capnp.h" +#include "openpilot/cereal/gen/cpp/log.capnp.h" #include "imgui.h" #include "tools/jotpluggler/dbc.h" #include "tools/jotpluggler/util.h" diff --git a/tools/jotpluggler/generate_event_extractors.py b/tools/jotpluggler/generate_event_extractors.py index 0ffa11c36c..25f121f0b9 100644 --- a/tools/jotpluggler/generate_event_extractors.py +++ b/tools/jotpluggler/generate_event_extractors.py @@ -321,7 +321,7 @@ if __name__ == "__main__": repo_root = Path(sys.argv[1]).resolve() output = Path(sys.argv[2]) capnp.remove_import_hook() - log = capnp.load(str(repo_root / "cereal" / "log.capnp"), imports=[str(repo_root / "opendbc_repo" / "opendbc" / "car")]) + log = capnp.load(str(repo_root / "openpilot" / "cereal" / "log.capnp"), imports=[str(repo_root / "opendbc_repo" / "opendbc" / "car")]) generated = Generator(log.Event.schema).generate() output.parent.mkdir(parents=True, exist_ok=True) output.write_text(generated) diff --git a/tools/jotpluggler/runtime.cc b/tools/jotpluggler/runtime.cc index 3247a5d01d..4e98f96c3d 100644 --- a/tools/jotpluggler/runtime.cc +++ b/tools/jotpluggler/runtime.cc @@ -1,7 +1,7 @@ #include "tools/jotpluggler/app.h" #include "tools/jotpluggler/common.h" -#include "cereal/services.h" +#include "openpilot/cereal/services.h" #include "common/timing.h" #include "imgui_impl_glfw.h" #include "imgui_impl_opengl3.h" diff --git a/tools/joystick/README.md b/tools/joystick/README.md index eb67060ca8..bc09688094 100644 --- a/tools/joystick/README.md +++ b/tools/joystick/README.md @@ -36,7 +36,7 @@ In order to use a joystick over the network, we need to run joystick_control loc 3. Run bridge with your laptop's IP address. This republishes the `testJoystick` packets sent from your laptop so that openpilot can receive them: ```shell # on your comma device - cereal/messaging/bridge {LAPTOP_IP} testJoystick + openpilot/cereal/messaging/bridge {LAPTOP_IP} testJoystick ``` 4. Start joystick_control on your laptop in ZMQ mode. ```shell diff --git a/tools/joystick/joystick_control.py b/tools/joystick/joystick_control.py index d9d4f0156f..9a39d564db 100755 --- a/tools/joystick/joystick_control.py +++ b/tools/joystick/joystick_control.py @@ -5,7 +5,7 @@ import threading import numpy as np from inputs import UnpluggedError, get_gamepad -from cereal import messaging +from openpilot.cereal import messaging from openpilot.common.params import Params from openpilot.common.realtime import Ratekeeper from openpilot.common.hardware import HARDWARE @@ -140,7 +140,7 @@ if __name__ == '__main__': print('- `R`: Resets axes') print('- `C`: Cancel cruise control') else: - print('Using joystick, make sure to run cereal/messaging/bridge on your device if running over the network!') + print('Using joystick, make sure to run openpilot/cereal/messaging/bridge on your device if running over the network!') print('If not running on a comma device, the mapping may need to be adjusted.') joystick = Keyboard() if args.keyboard else Joystick() diff --git a/tools/joystick/joystickd.py b/tools/joystick/joystickd.py index f06097658a..a1c00746b6 100755 --- a/tools/joystick/joystickd.py +++ b/tools/joystick/joystickd.py @@ -3,7 +3,7 @@ import math import numpy as np -from cereal import messaging +from openpilot.cereal import messaging from opendbc.car.structs import car from opendbc.car.vehicle_model import VehicleModel from openpilot.common.realtime import DT_CTRL, Ratekeeper diff --git a/tools/lateral_maneuvers/lateral_maneuversd.py b/tools/lateral_maneuvers/lateral_maneuversd.py index 61f51145df..ed07c896f9 100755 --- a/tools/lateral_maneuvers/lateral_maneuversd.py +++ b/tools/lateral_maneuvers/lateral_maneuversd.py @@ -2,7 +2,7 @@ import numpy as np from dataclasses import dataclass -from cereal import messaging +from openpilot.cereal import messaging from opendbc.car.structs import car from openpilot.common.constants import CV from openpilot.common.realtime import DT_MDL diff --git a/tools/lib/live_logreader.py b/tools/lib/live_logreader.py index edc4ac1611..20f8c3502c 100644 --- a/tools/lib/live_logreader.py +++ b/tools/lib/live_logreader.py @@ -1,6 +1,6 @@ import os -from cereal import log as capnp_log, messaging -from cereal.services import SERVICE_LIST +from openpilot.cereal import log as capnp_log, messaging +from openpilot.cereal.services import SERVICE_LIST from openpilot.tools.lib.logreader import LogIterable, RawLogIterable diff --git a/tools/lib/logreader.py b/tools/lib/logreader.py index 9696c8524d..805e411b53 100755 --- a/tools/lib/logreader.py +++ b/tools/lib/logreader.py @@ -15,7 +15,7 @@ import zstandard as zstd from collections.abc import Iterable, Iterator from urllib.parse import parse_qs, urlparse -from cereal import log as capnp_log +from openpilot.cereal import log as capnp_log from openpilot.common.swaglog import cloudlog from openpilot.tools.lib.filereader import FileReader from openpilot.tools.lib.file_sources import comma_api_source, internal_source, openpilotci_source, comma_car_segments_source, Source diff --git a/tools/lib/tests/test_logreader.py b/tools/lib/tests/test_logreader.py index 123f142383..a27a348d9e 100644 --- a/tools/lib/tests/test_logreader.py +++ b/tools/lib/tests/test_logreader.py @@ -9,7 +9,7 @@ import requests from openpilot.common.parameterized import parameterized -from cereal import log as capnp_log +from openpilot.cereal import log as capnp_log from openpilot.tools.lib.logreader import LogsUnavailable, LogIterable, LogReader, parse_indirect, ReadMode from openpilot.tools.lib.file_sources import comma_api_source, InternalUnavailableException from openpilot.tools.lib.route import SegmentRange diff --git a/tools/longitudinal_maneuvers/maneuversd.py b/tools/longitudinal_maneuvers/maneuversd.py index cf53f8e85a..a9a5ba6304 100755 --- a/tools/longitudinal_maneuvers/maneuversd.py +++ b/tools/longitudinal_maneuvers/maneuversd.py @@ -2,7 +2,7 @@ import numpy as np from dataclasses import dataclass -from cereal import messaging +from openpilot.cereal import messaging from opendbc.car.structs import car from openpilot.common.constants import CV from openpilot.common.realtime import DT_MDL diff --git a/tools/plotjuggler/README.md b/tools/plotjuggler/README.md index 3249971bfc..9a40ac798d 100644 --- a/tools/plotjuggler/README.md +++ b/tools/plotjuggler/README.md @@ -51,7 +51,7 @@ Example using segment range: Explore live data from your car! Follow these steps to stream from your comma device to your laptop: - Enable wifi tethering on your comma device -- [SSH into your device](https://github.com/commaai/openpilot/wiki/SSH) and run `cd /data/openpilot && ./cereal/messaging/bridge` +- [SSH into your device](https://github.com/commaai/openpilot/wiki/SSH) and run `cd /data/openpilot && ./openpilot/cereal/messaging/bridge` - On your laptop, connect to the device's wifi hotspot - Start PlotJuggler with `ZMQ=1 ./juggle.py --stream`, find the `Cereal Subscriber` plugin in the dropdown under Streaming, and click `Start`. diff --git a/tools/plotjuggler/juggle.py b/tools/plotjuggler/juggle.py index a31c62c940..e1143a3cd4 100755 --- a/tools/plotjuggler/juggle.py +++ b/tools/plotjuggler/juggle.py @@ -9,7 +9,6 @@ import tempfile import requests import argparse from functools import partial - from opendbc.car.fingerprints import MIGRATION from openpilot.common.basedir import BASEDIR from openpilot.common.swaglog import cloudlog @@ -70,7 +69,6 @@ def get_plotjuggler_version(): def start_juggler(fn=None, dbc=None, layout=None, route_or_segment_name=None, platform=None): env = os.environ.copy() - env["BASEDIR"] = BASEDIR env["PATH"] = f"{INSTALL_DIR}:{os.getenv('PATH', '')}" if dbc: if os.path.exists(dbc): @@ -86,7 +84,20 @@ def start_juggler(fn=None, dbc=None, layout=None, route_or_segment_name=None, pl extra_args += f" --window_title \"{route_or_segment_name}{f' ({platform})' if platform is not None else ''}\"" cmd = f'{PLOTJUGGLER_BIN} --buffer_size {MAX_STREAMING_BUFFER_SIZE} --plugin_folders {INSTALL_DIR}{extra_args}' - subprocess.call(cmd, shell=True, env=env, cwd=juggle_dir) + with tempfile.TemporaryDirectory() as schema_root: + tmp_cereal = os.path.join(schema_root, "cereal") + os.mkdir(tmp_cereal) + for schema in ("log.capnp", "deprecated.capnp", "custom.capnp"): + with open(os.path.join(BASEDIR, "openpilot", "cereal", schema)) as src: + contents = src.read() + contents = contents.replace('import "/include/c++.capnp"', 'import "./include/c++.capnp"') + contents = contents.replace('import "/car.capnp"', 'import "car.capnp"') + with open(os.path.join(tmp_cereal, schema), "w") as dst: + dst.write(contents) + os.symlink(os.path.join(BASEDIR, "openpilot", "cereal", "include"), os.path.join(tmp_cereal, "include"), target_is_directory=True) + os.symlink(os.path.join(BASEDIR, "opendbc_repo", "opendbc", "car", "car.capnp"), os.path.join(tmp_cereal, "car.capnp")) + env["BASEDIR"] = schema_root + subprocess.call(cmd, shell=True, env=env, cwd=juggle_dir) def process(can, lr): diff --git a/tools/replay/logreader.h b/tools/replay/logreader.h index fe11ab0f77..63f7468401 100644 --- a/tools/replay/logreader.h +++ b/tools/replay/logreader.h @@ -5,7 +5,7 @@ #include #include -#include "cereal/gen/cpp/log.capnp.h" +#include "openpilot/cereal/gen/cpp/log.capnp.h" #include "tools/replay/util.h" const CameraType ALL_CAMERAS[] = {RoadCam, DriverCam, WideRoadCam}; diff --git a/tools/replay/replay.cc b/tools/replay/replay.cc index d6d02b1a9f..75aecfd0c2 100644 --- a/tools/replay/replay.cc +++ b/tools/replay/replay.cc @@ -4,7 +4,7 @@ #include #include #include -#include "cereal/services.h" +#include "openpilot/cereal/services.h" #include "common/params.h" #include "tools/replay/util.h" diff --git a/tools/replay/timeline.cc b/tools/replay/timeline.cc index 08dca5c89e..34729f5214 100644 --- a/tools/replay/timeline.cc +++ b/tools/replay/timeline.cc @@ -3,7 +3,7 @@ #include #include -#include "cereal/gen/cpp/log.capnp.h" +#include "openpilot/cereal/gen/cpp/log.capnp.h" Timeline::~Timeline() { should_exit_.store(true); diff --git a/tools/replay/ui.py b/tools/replay/ui.py index 405c79f425..838b7ab15a 100755 --- a/tools/replay/ui.py +++ b/tools/replay/ui.py @@ -6,7 +6,7 @@ import sys import numpy as np import pyray as rl -import cereal.messaging as messaging +import openpilot.cereal.messaging as messaging from openpilot.common.basedir import BASEDIR from openpilot.common.transformations.camera import DEVICE_CAMERAS from openpilot.tools.replay.lib.ui_helpers import ( diff --git a/tools/replay/util.h b/tools/replay/util.h index a2d0f6203a..03a15787b2 100644 --- a/tools/replay/util.h +++ b/tools/replay/util.h @@ -7,7 +7,7 @@ #include #include #include -#include "cereal/messaging/messaging.h" +#include "openpilot/cereal/messaging/messaging.h" enum CameraType { RoadCam = 0, diff --git a/tools/scripts/adb_ssh.sh b/tools/scripts/adb_ssh.sh index b9668e7e0b..c584a72f2b 100755 --- a/tools/scripts/adb_ssh.sh +++ b/tools/scripts/adb_ssh.sh @@ -5,7 +5,7 @@ set -euo pipefail while IFS=' ' read -r name port; do adb forward "tcp:${port}" "tcp:${port}" > /dev/null done < <(python3 - <<'PY' -from cereal.services import SERVICE_LIST +from openpilot.cereal.services import SERVICE_LIST FNV_PRIME = 0x100000001b3 FNV_OFFSET_BASIS = 0xcbf29ce484222325 diff --git a/tools/scripts/car/can_print_changes.py b/tools/scripts/car/can_print_changes.py index c2e152e1e0..1db29c3d37 100755 --- a/tools/scripts/car/can_print_changes.py +++ b/tools/scripts/car/can_print_changes.py @@ -4,7 +4,7 @@ import binascii import time from collections import defaultdict -import cereal.messaging as messaging +import openpilot.cereal.messaging as messaging from openpilot.tools.scripts.can_table import can_table from openpilot.tools.lib.logreader import LogIterable, LogReader diff --git a/tools/scripts/car/can_printer.py b/tools/scripts/car/can_printer.py index f2ed6730d3..85f129f795 100755 --- a/tools/scripts/car/can_printer.py +++ b/tools/scripts/car/can_printer.py @@ -4,7 +4,7 @@ import binascii import time from collections import defaultdict -import cereal.messaging as messaging +import openpilot.cereal.messaging as messaging def can_printer(bus, max_msg, addr, ascii_decode): diff --git a/tools/scripts/car/can_table.py b/tools/scripts/car/can_table.py index 11d070e708..e2d9874fec 100755 --- a/tools/scripts/car/can_table.py +++ b/tools/scripts/car/can_table.py @@ -2,7 +2,7 @@ import argparse import pandas as pd -import cereal.messaging as messaging +import openpilot.cereal.messaging as messaging def can_table(dat): diff --git a/tools/scripts/car/disable_ecu.py b/tools/scripts/car/disable_ecu.py index 14d0cbb9cf..884b86896b 100755 --- a/tools/scripts/car/disable_ecu.py +++ b/tools/scripts/car/disable_ecu.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 import time -import cereal.messaging as messaging +import openpilot.cereal.messaging as messaging from opendbc.car.disable_ecu import disable_ecu from openpilot.selfdrive.car.card import can_comm_callbacks diff --git a/tools/scripts/car/ecu_addrs.py b/tools/scripts/car/ecu_addrs.py index b0e7a8f2dc..0dfce880b0 100755 --- a/tools/scripts/car/ecu_addrs.py +++ b/tools/scripts/car/ecu_addrs.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 import argparse import time -import cereal.messaging as messaging +import openpilot.cereal.messaging as messaging from opendbc.car.carlog import carlog from opendbc.car.ecu_addrs import get_all_ecu_addrs from openpilot.common.params import Params diff --git a/tools/scripts/car/fw_versions.py b/tools/scripts/car/fw_versions.py index 6fdac5e46d..e68447d69e 100755 --- a/tools/scripts/car/fw_versions.py +++ b/tools/scripts/car/fw_versions.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 import time import argparse -import cereal.messaging as messaging +import openpilot.cereal.messaging as messaging from opendbc.car.structs import car from opendbc.car.carlog import carlog from opendbc.car.fw_versions import get_fw_versions, match_fw_to_car diff --git a/tools/scripts/car/hyundai_enable_radar_points.py b/tools/scripts/car/hyundai_enable_radar_points.py index df150a5224..f9ae29f817 100755 --- a/tools/scripts/car/hyundai_enable_radar_points.py +++ b/tools/scripts/car/hyundai_enable_radar_points.py @@ -15,7 +15,6 @@ import sys import argparse from typing import NamedTuple from subprocess import check_output, CalledProcessError - from opendbc.car.carlog import carlog from opendbc.car.uds import UdsClient, SESSION_TYPE, DATA_IDENTIFIER_TYPE from opendbc.car.structs import CarParams diff --git a/tools/scripts/car/measure_torque_time_to_max.py b/tools/scripts/car/measure_torque_time_to_max.py index e99aeae464..df41e5738e 100755 --- a/tools/scripts/car/measure_torque_time_to_max.py +++ b/tools/scripts/car/measure_torque_time_to_max.py @@ -6,8 +6,8 @@ import struct from collections import deque from statistics import mean -from cereal import log -import cereal.messaging as messaging +from openpilot.cereal import log +import openpilot.cereal.messaging as messaging if __name__ == "__main__": diff --git a/tools/scripts/car/vin.py b/tools/scripts/car/vin.py index 9b1d6528cc..732d3d3f4a 100755 --- a/tools/scripts/car/vin.py +++ b/tools/scripts/car/vin.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 import argparse import time -import cereal.messaging as messaging +import openpilot.cereal.messaging as messaging from opendbc.car.carlog import carlog from opendbc.car.vin import get_vin from openpilot.selfdrive.car.card import can_comm_callbacks diff --git a/tools/scripts/count_events.py b/tools/scripts/count_events.py index 76e02d414e..a7e71210ac 100755 --- a/tools/scripts/count_events.py +++ b/tools/scripts/count_events.py @@ -6,7 +6,7 @@ from collections import Counter from pprint import pprint from typing import cast -from cereal.services import SERVICE_LIST +from openpilot.cereal.services import SERVICE_LIST from openpilot.tools.lib.logreader import LogReader, ReadMode from openpilot.selfdrive.test.process_replay.migration import migrate_all diff --git a/tools/scripts/cycle_alerts.py b/tools/scripts/cycle_alerts.py index 7dc963aafd..0bd42bcd3f 100755 --- a/tools/scripts/cycle_alerts.py +++ b/tools/scripts/cycle_alerts.py @@ -2,9 +2,9 @@ import time import random -from cereal import log +from openpilot.cereal import log from opendbc.car.structs import car -import cereal.messaging as messaging +import openpilot.cereal.messaging as messaging from opendbc.car.honda.interface import CarInterface from openpilot.common.realtime import DT_CTRL from openpilot.selfdrive.selfdrived.events import ET, Events diff --git a/tools/scripts/debug_fw_fingerprinting_offline.py b/tools/scripts/debug_fw_fingerprinting_offline.py index d36b350bbc..b33817e944 100755 --- a/tools/scripts/debug_fw_fingerprinting_offline.py +++ b/tools/scripts/debug_fw_fingerprinting_offline.py @@ -1,6 +1,5 @@ #!/usr/bin/env python3 import argparse - from opendbc.car import uds from openpilot.tools.lib.live_logreader import live_logreader from openpilot.tools.lib.logreader import LogReader, ReadMode diff --git a/tools/scripts/dump.py b/tools/scripts/dump.py index 78cf51e3db..e4f5495f9b 100755 --- a/tools/scripts/dump.py +++ b/tools/scripts/dump.py @@ -4,8 +4,8 @@ import argparse import json import codecs -from cereal import log -from cereal.services import SERVICE_LIST +from openpilot.cereal import log +from openpilot.cereal.services import SERVICE_LIST from openpilot.tools.lib.live_logreader import raw_live_logreader @@ -25,7 +25,7 @@ def hexdump(msg): if __name__ == "__main__": - parser = argparse.ArgumentParser(description='Dump communication sockets. See cereal/services.py for a complete list of available sockets.') + parser = argparse.ArgumentParser(description='Dump communication sockets. See openpilot/cereal/services.py for a complete list of available sockets.') parser.add_argument('--pipe', action='store_true') parser.add_argument('--raw', action='store_true') parser.add_argument('--json', action='store_true') diff --git a/tools/scripts/filter_log_message.py b/tools/scripts/filter_log_message.py index 38904aaa07..1ec0333169 100755 --- a/tools/scripts/filter_log_message.py +++ b/tools/scripts/filter_log_message.py @@ -2,7 +2,7 @@ import argparse import json -import cereal.messaging as messaging +import openpilot.cereal.messaging as messaging from openpilot.tools.lib.logreader import LogReader LEVELS = { diff --git a/tools/scripts/fuzz_fw_fingerprint.py b/tools/scripts/fuzz_fw_fingerprint.py index b4276c0c1a..5b0ba9cfd0 100755 --- a/tools/scripts/fuzz_fw_fingerprint.py +++ b/tools/scripts/fuzz_fw_fingerprint.py @@ -3,7 +3,6 @@ import random from collections import defaultdict from tqdm import tqdm - from opendbc.car.fw_versions import match_fw_to_car_fuzzy from opendbc.car.toyota.values import FW_VERSIONS as TOYOTA_FW_VERSIONS from opendbc.car.honda.values import FW_VERSIONS as HONDA_FW_VERSIONS diff --git a/tools/scripts/get_fingerprint.py b/tools/scripts/get_fingerprint.py index 75c3d5579f..1cdf8534d9 100755 --- a/tools/scripts/get_fingerprint.py +++ b/tools/scripts/get_fingerprint.py @@ -10,7 +10,7 @@ # - since some messages are published at low frequency, keep this script running for at least 30s, # until all messages are received at least once -import cereal.messaging as messaging +import openpilot.cereal.messaging as messaging logcan = messaging.sub_sock('can') msgs = {} diff --git a/tools/scripts/live_cpu_and_temp.py b/tools/scripts/live_cpu_and_temp.py index ee0524ec9d..484207d0fe 100755 --- a/tools/scripts/live_cpu_and_temp.py +++ b/tools/scripts/live_cpu_and_temp.py @@ -4,7 +4,7 @@ import numpy as np import capnp from collections import defaultdict -from cereal.messaging import SubMaster +from openpilot.cereal.messaging import SubMaster def cputime_total(ct): return ct.user + ct.nice + ct.system + ct.idle + ct.iowait + ct.irq + ct.softirq diff --git a/tools/scripts/qlog_size.py b/tools/scripts/qlog_size.py index 2b54cfeebf..46ef4b8be0 100755 --- a/tools/scripts/qlog_size.py +++ b/tools/scripts/qlog_size.py @@ -5,7 +5,7 @@ from collections import defaultdict import matplotlib.pyplot as plt -from cereal.services import SERVICE_LIST +from openpilot.cereal.services import SERVICE_LIST from openpilot.common.utils import LOG_COMPRESSION_LEVEL from openpilot.tools.lib.logreader import LogReader from tqdm import tqdm diff --git a/tools/scripts/uiview.py b/tools/scripts/uiview.py index 3a81f2f84f..8611a861b3 100755 --- a/tools/scripts/uiview.py +++ b/tools/scripts/uiview.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 import time -from cereal import log, messaging +from openpilot.cereal import log, messaging from opendbc.car.structs import car from openpilot.common.params import Params from openpilot.system.manager.process_config import managed_processes diff --git a/tools/scripts/watch_timings.py b/tools/scripts/watch_timings.py index 874720dd22..0df9db2033 100755 --- a/tools/scripts/watch_timings.py +++ b/tools/scripts/watch_timings.py @@ -7,8 +7,8 @@ from dataclasses import dataclass, field import numpy as np -import cereal.messaging as messaging -from cereal.services import SERVICE_LIST +import openpilot.cereal.messaging as messaging +from openpilot.cereal.services import SERVICE_LIST @dataclass diff --git a/tools/sim/bridge/common.py b/tools/sim/bridge/common.py index 499420ec4b..048bf6cb11 100644 --- a/tools/sim/bridge/common.py +++ b/tools/sim/bridge/common.py @@ -7,7 +7,6 @@ from collections import namedtuple from enum import Enum from multiprocessing import Process, Queue, Value from abc import ABC, abstractmethod - from opendbc.car.honda.values import CruiseButtons from openpilot.common.params import Params from openpilot.common.realtime import Ratekeeper diff --git a/tools/sim/lib/camerad.py b/tools/sim/lib/camerad.py index 7634b8524d..8efb3e5dab 100644 --- a/tools/sim/lib/camerad.py +++ b/tools/sim/lib/camerad.py @@ -1,7 +1,7 @@ import numpy as np from msgq.visionipc import VisionIpcServer, VisionStreamType -from cereal import messaging +from openpilot.cereal import messaging from openpilot.tools.sim.lib.common import W, H diff --git a/tools/sim/lib/simulated_car.py b/tools/sim/lib/simulated_car.py index 03da594769..4e04ecd513 100644 --- a/tools/sim/lib/simulated_car.py +++ b/tools/sim/lib/simulated_car.py @@ -1,5 +1,5 @@ import traceback -import cereal.messaging as messaging +import openpilot.cereal.messaging as messaging from opendbc.can.packer import CANPacker from opendbc.can.parser import CANParser diff --git a/tools/sim/lib/simulated_sensors.py b/tools/sim/lib/simulated_sensors.py index d6d822c582..63935d3068 100644 --- a/tools/sim/lib/simulated_sensors.py +++ b/tools/sim/lib/simulated_sensors.py @@ -1,7 +1,7 @@ import time -from cereal import log -import cereal.messaging as messaging +from openpilot.cereal import log +import openpilot.cereal.messaging as messaging from openpilot.common.realtime import DT_DMON from openpilot.tools.sim.lib.camerad import Camerad diff --git a/tools/sim/tests/test_sim_bridge.py b/tools/sim/tests/test_sim_bridge.py index d58cddff7f..0b3650e0a3 100644 --- a/tools/sim/tests/test_sim_bridge.py +++ b/tools/sim/tests/test_sim_bridge.py @@ -5,7 +5,7 @@ import pytest from multiprocessing import Queue -from cereal import messaging +from openpilot.cereal import messaging from openpilot.common.basedir import BASEDIR from openpilot.tools.sim.bridge.common import QueueMessageType From 20e0f21b5853b4675adc5c1879fe02871a160a3c Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Sun, 21 Jun 2026 18:28:35 -0700 Subject: [PATCH 075/151] prefix paths with openpilot (#38223) * prefix paths with openpilot * fix setup root detection * fix split branch codespell skips --- .github/labeler.yaml | 12 +-- .github/pull_request_template.md | 4 +- .github/workflows/model_review.yaml | 2 +- .github/workflows/release.yaml | 2 +- .github/workflows/repo-maintenance.yaml | 4 +- .github/workflows/tests.yaml | 44 +++++----- .github/workflows/ui_preview.yaml | 14 +-- Jenkinsfile | 42 ++++----- README.md | 2 +- SConstruct | 29 +++--- common/hardware/tici/agnos.py | 2 +- common/mock/__init__.py | 2 +- common/spinner.py | 2 +- common/text_window.py | 2 +- common/version.py | 2 +- conftest.py | 6 +- docs/CARS.md | 2 +- docs/CONTRIBUTING.md | 2 +- docs/SAFETY.md | 4 +- docs/concepts/logs.md | 2 +- docs/how-to/car-port.md | 2 +- docs/how-to/replay-a-drive.md | 2 +- docs/how-to/turn-the-speed-blue.md | 10 +-- launch_chffrplus.sh | 8 +- openpilot/cereal/README.md | 16 ++-- openpilot/cereal/log.capnp | 4 +- pyproject.toml | 34 +------ release/README.md | 2 +- release/build_release.sh | 8 +- release/build_stripped.sh | 4 +- release/pack.py | 2 +- scripts/lint/lint.sh | 9 +- scripts/post-commit | 2 +- scripts/reporter.py | 2 +- scripts/waste.c | 3 +- selfdrive/car/CARS_template.md | 2 +- selfdrive/car/docs.py | 2 +- selfdrive/car/tests/big_cars_test.sh | 4 +- .../controls/lib/lateral_mpc_lib/SConscript | 2 +- .../lib/longitudinal_mpc_lib/SConscript | 2 +- selfdrive/locationd/calibrationd.py | 2 +- selfdrive/modeld/SConscript | 16 ++-- selfdrive/modeld/dmonitoringmodeld.py | 2 +- selfdrive/modeld/modeld.py | 2 +- selfdrive/modeld/models/README.md | 2 +- selfdrive/pandad/pandad.py | 2 +- selfdrive/selfdrived/alertmanager.py | 2 +- selfdrive/selfdrived/tests/test_alerts.py | 4 +- selfdrive/test/test_onroad.py | 60 ++++++------- selfdrive/ui/SConscript | 4 +- selfdrive/ui/layouts/onboarding.py | 4 +- selfdrive/ui/layouts/settings/device.py | 2 +- selfdrive/ui/layouts/settings/software.py | 6 +- selfdrive/ui/mici/layouts/settings/device.py | 2 +- .../ui/mici/layouts/settings/software.py | 6 +- selfdrive/ui/soundd.py | 2 +- selfdrive/ui/tests/cycle_offroad_alerts.py | 2 +- selfdrive/ui/tests/diff/diff.py | 2 +- selfdrive/ui/translations/app.pot | 74 ++++++++-------- selfdrive/ui/translations/auto_translate.sh | 2 +- system/athena/manage_athenad.py | 2 +- system/camerad/cameras/nv12_info.py | 2 +- system/camerad/webcam/README.md | 4 +- system/loggerd/tests/test_loggerd.py | 2 +- system/manager/helpers.py | 2 +- system/manager/process_config.py | 88 +++++++++---------- system/tombstoned.py | 2 +- system/ui/README.md | 2 +- system/ui/lib/multilang.py | 2 +- system/updated/updated.py | 4 +- tools/CTF.md | 6 +- tools/README.md | 4 +- tools/cabana/SConscript | 8 +- tools/cabana/cabana | 2 +- tools/cabana/streams/replaystream.cc | 2 +- tools/cabana/streams/routes.cc | 2 +- tools/car_porting/README.md | 30 +++---- tools/car_porting/test_car_model.py | 2 +- tools/jotpluggler/SConscript | 2 +- .../jotpluggler/generate_event_extractors.py | 2 +- tools/joystick/README.md | 4 +- tools/lateral_maneuvers/README.md | 2 +- tools/lib/README.md | 2 +- tools/lib/api.py | 2 +- tools/longitudinal_maneuvers/README.md | 2 +- tools/op.sh | 26 +++--- tools/plotjuggler/README.md | 2 +- tools/plotjuggler/juggle.py | 2 +- tools/plotjuggler/test_plotjuggler.py | 2 +- tools/replay/README.md | 30 +++---- tools/replay/route.cc | 2 +- tools/replay/ui.py | 2 +- tools/scripts/cpu_usage_stat.py | 2 +- tools/scripts/get_fingerprint.py | 2 +- tools/scripts/profiling/snapdragon/README.md | 4 +- tools/scripts/ssh.py | 2 +- tools/setup.sh | 6 +- tools/setup_dependencies.sh | 2 +- tools/sim/README.md | 4 +- tools/sim/tests/test_sim_bridge.py | 2 +- 100 files changed, 371 insertions(+), 400 deletions(-) diff --git a/.github/labeler.yaml b/.github/labeler.yaml index 63d41d5b73..2481a112ce 100644 --- a/.github/labeler.yaml +++ b/.github/labeler.yaml @@ -4,24 +4,24 @@ CI / testing: car: - changed-files: - - any-glob-to-all-files: '{selfdrive/car/**,opendbc_repo}' + - any-glob-to-all-files: '{openpilot/selfdrive/car/**,opendbc_repo}' simulation: - changed-files: - - any-glob-to-all-files: 'tools/sim/**' + - any-glob-to-all-files: 'openpilot/tools/sim/**' ui: - changed-files: - - any-glob-to-all-files: '{selfdrive/assets/**,selfdrive/ui/**,system/ui/**}' + - any-glob-to-all-files: '{openpilot/selfdrive/assets/**,openpilot/selfdrive/ui/**,openpilot/system/ui/**}' tools: - changed-files: - - any-glob-to-all-files: 'tools/**' + - any-glob-to-all-files: 'openpilot/tools/**' multilanguage: - changed-files: - - any-glob-to-all-files: 'selfdrive/ui/translations/**' + - any-glob-to-all-files: 'openpilot/selfdrive/ui/translations/**' autonomy: - changed-files: - - any-glob-to-all-files: "{selfdrive/modeld/models/**,selfdrive/test/process_replay/model_replay_ref_commit}" + - any-glob-to-all-files: "{openpilot/selfdrive/modeld/models/**,openpilot/selfdrive/test/process_replay/model_replay_ref_commit}" diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 2b4a5ed48f..b986273097 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -44,8 +44,8 @@ Explain how you tested this bug fix. **Checklist** -- [ ] added entry to CAR in selfdrive/car/*/values.py and ran `selfdrive/car/docs.py` to generate new docs -- [ ] test route added to [routes.py](https://github.com/commaai/openpilot/blob/master/selfdrive/car/tests/routes.py) +- [ ] added entry to CAR in openpilot/selfdrive/car/*/values.py and ran `openpilot/selfdrive/car/docs.py` to generate new docs +- [ ] test route added to [routes.py](https://github.com/commaai/openpilot/blob/master/openpilot/selfdrive/car/tests/routes.py) - [ ] route with openpilot: - [ ] route with stock system: - [ ] car harness used (if comma doesn't sell it, put N/A): diff --git a/.github/workflows/model_review.yaml b/.github/workflows/model_review.yaml index 2775dbc574..66f0398d09 100644 --- a/.github/workflows/model_review.yaml +++ b/.github/workflows/model_review.yaml @@ -4,7 +4,7 @@ on: pull_request: types: [opened, reopened, synchronize] paths: - - 'selfdrive/modeld/models/*.onnx' + - 'openpilot/selfdrive/modeld/models/*.onnx' workflow_dispatch: jobs: diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index a90f064b82..ae6a2655a4 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -26,6 +26,6 @@ jobs: with: submodules: true fetch-depth: 0 - - run: ./tools/op.sh setup + - run: ./openpilot/tools/op.sh setup - name: Push master-ci run: BRANCH=__nightly release/build_stripped.sh diff --git a/.github/workflows/repo-maintenance.yaml b/.github/workflows/repo-maintenance.yaml index f829415f4e..14c613fbe4 100644 --- a/.github/workflows/repo-maintenance.yaml +++ b/.github/workflows/repo-maintenance.yaml @@ -17,7 +17,7 @@ jobs: - uses: actions/checkout@v6 with: submodules: true - - run: ./tools/op.sh setup + - run: ./openpilot/tools/op.sh setup - name: uv lock run: uv lock --upgrade - name: uv pip tree @@ -46,7 +46,7 @@ jobs: git add . - name: update car docs run: | - python selfdrive/car/docs.py + python openpilot/selfdrive/car/docs.py git add docs/CARS.md - name: Create Pull Request uses: peter-evans/create-pull-request@c0f553fe549906ede9cf27b5156039d195d2ece0 diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index bccc6b5726..3ed0829a26 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -47,11 +47,11 @@ jobs: - name: Build devel timeout-minutes: 1 run: TARGET_DIR=$STRIPPED_DIR release/build_stripped.sh - - run: ./tools/op.sh setup + - run: ./openpilot/tools/op.sh setup - name: Build openpilot and run checks timeout-minutes: 30 working-directory: ${{ env.STRIPPED_DIR }} - run: python3 system/manager/build.py + run: python3 openpilot/system/manager/build.py - name: Run tests timeout-minutes: 1 working-directory: ${{ env.STRIPPED_DIR }} @@ -72,7 +72,7 @@ jobs: run: | FILTERED=$(echo "$PATH" | tr ':' '\n' | grep -v '/opt/homebrew' | tr '\n' ':') echo "PATH=${FILTERED}/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin" >> $GITHUB_ENV - - run: ./tools/op.sh setup + - run: ./openpilot/tools/op.sh setup - name: Building openpilot run: scons @@ -88,7 +88,7 @@ jobs: - uses: actions/checkout@v6 with: submodules: true - - run: ./tools/op.sh setup + - run: ./openpilot/tools/op.sh setup - name: Static analysis timeout-minutes: 1 run: scripts/lint/lint.sh @@ -105,13 +105,13 @@ jobs: - uses: actions/checkout@v6 with: submodules: true - - run: ./tools/op.sh setup + - run: ./openpilot/tools/op.sh setup - name: Build openpilot run: scons - name: Run unit tests timeout-minutes: ${{ contains(runner.name, 'nsc') && 2 || 20 }} run: | - source selfdrive/test/setup_xvfb.sh + source openpilot/selfdrive/test/setup_xvfb.sh # Pre-compile Python bytecode so each pytest worker doesn't need to $PYTEST --collect-only -m 'not slow' -qq MAX_EXAMPLES=1 $PYTEST -m 'not slow' @@ -128,33 +128,33 @@ jobs: - uses: actions/checkout@v6 with: submodules: true - - run: ./tools/op.sh setup + - run: ./openpilot/tools/op.sh setup - name: Build openpilot run: scons - name: Run replay timeout-minutes: ${{ contains(runner.name, 'nsc') && 2 || 20 }} continue-on-error: ${{ github.ref == 'refs/heads/master' }} - run: selfdrive/test/process_replay/test_processes.py -j$(nproc) + run: openpilot/selfdrive/test/process_replay/test_processes.py -j$(nproc) - name: Print diff id: print-diff if: always() - run: cat selfdrive/test/process_replay/diff.txt + run: cat openpilot/selfdrive/test/process_replay/diff.txt - name: Print diff report if: always() - run: cat selfdrive/test/process_replay/diff_report.txt + run: cat openpilot/selfdrive/test/process_replay/diff_report.txt - uses: actions/upload-artifact@v6 if: always() continue-on-error: true with: name: process_replay_diff.txt - path: selfdrive/test/process_replay/diff.txt + path: openpilot/selfdrive/test/process_replay/diff.txt - name: Upload diff report uses: actions/upload-artifact@v6 if: always() && github.event_name == 'pull_request' continue-on-error: true with: name: diff_report_${{ github.event.number }} - path: selfdrive/test/process_replay/diff_report.txt + path: openpilot/selfdrive/test/process_replay/diff_report.txt - name: Checkout ci-artifacts if: github.repository == 'commaai/openpilot' && github.ref == 'refs/heads/master' uses: actions/checkout@v4 @@ -170,7 +170,7 @@ jobs: git config user.email "<>" git fetch origin process-replay || true git checkout process-replay 2>/dev/null || git checkout --orphan process-replay - cp ${{ github.workspace }}/selfdrive/test/process_replay/fakedata/*.zst . + cp ${{ github.workspace }}/openpilot/selfdrive/test/process_replay/fakedata/*.zst . echo "${{ github.sha }}" > ref_commit git add . git commit -m "process-replay refs for ${{ github.repository }}@${{ github.sha }}" || echo "No changes to commit" @@ -186,7 +186,7 @@ jobs: timeout-minutes: 4 env: ONNXCPU: 1 - run: $PYTEST selfdrive/test/process_replay/test_regen.py + run: $PYTEST openpilot/selfdrive/test/process_replay/test_regen.py simulator_driving: name: simulator driving @@ -201,14 +201,14 @@ jobs: - uses: actions/checkout@v6 with: submodules: true - - run: ./tools/op.sh setup + - run: ./openpilot/tools/op.sh setup - name: Build openpilot run: scons - name: Driving test timeout-minutes: 2 run: | - source selfdrive/test/setup_xvfb.sh - pytest -s tools/sim/tests/test_metadrive_bridge.py + source openpilot/selfdrive/test/setup_xvfb.sh + pytest -s openpilot/tools/sim/tests/test_metadrive_bridge.py create_ui_report: name: Create UI Report @@ -222,16 +222,16 @@ jobs: - uses: actions/checkout@v6 with: submodules: true - - run: ./tools/op.sh setup + - run: ./openpilot/tools/op.sh setup - name: Build openpilot run: scons - name: Create UI Report run: | - source selfdrive/test/setup_xvfb.sh - python3 selfdrive/ui/tests/diff/replay.py - python3 selfdrive/ui/tests/diff/replay.py --big + source openpilot/selfdrive/test/setup_xvfb.sh + python3 openpilot/selfdrive/ui/tests/diff/replay.py + python3 openpilot/selfdrive/ui/tests/diff/replay.py --big - name: Upload UI Report uses: actions/upload-artifact@v6 with: name: ui-report-${{ inputs.run_number || '1' }}-${{ github.event_name == 'push' && github.ref == 'refs/heads/master' && 'master' || github.event.number }} - path: selfdrive/ui/tests/diff/report + path: openpilot/selfdrive/ui/tests/diff/report diff --git a/.github/workflows/ui_preview.yaml b/.github/workflows/ui_preview.yaml index 72ced49852..7bfaea63aa 100644 --- a/.github/workflows/ui_preview.yaml +++ b/.github/workflows/ui_preview.yaml @@ -8,9 +8,9 @@ on: branches: - 'master' paths: - - 'selfdrive/assets/**' - - 'selfdrive/ui/**' - - 'system/ui/**' + - 'openpilot/selfdrive/assets/**' + - 'openpilot/selfdrive/ui/**' + - 'openpilot/system/ui/**' workflow_dispatch: env: @@ -115,13 +115,13 @@ jobs: cp "${{ github.workspace }}/master_${name}/${video}.mp4" "${{ github.workspace }}/pr_ui/${video}_master.mp4" diff_exit_code=0 - python3 ${{ github.workspace }}/selfdrive/ui/tests/diff/diff.py \ + python3 ${{ github.workspace }}/openpilot/selfdrive/ui/tests/diff/diff.py \ "${{ github.workspace }}/pr_ui/${video}_master.mp4" \ "${{ github.workspace }}/pr_ui/${video}_proposed.mp4" \ "${diff_name}.html" --basedir "$baseurl" --no-open || diff_exit_code=$? - cp "${{ github.workspace }}/selfdrive/ui/tests/diff/report/${diff_name}.html" "${{ github.workspace }}/pr_ui/" - cp "${{ github.workspace }}/selfdrive/ui/tests/diff/report/${diff_name}.mp4" "${{ github.workspace }}/pr_ui/" + cp "${{ github.workspace }}/openpilot/selfdrive/ui/tests/diff/report/${diff_name}.html" "${{ github.workspace }}/pr_ui/" + cp "${{ github.workspace }}/openpilot/selfdrive/ui/tests/diff/report/${diff_name}.mp4" "${{ github.workspace }}/pr_ui/" REPORT_URL="https://commaai.github.io/ci-artifacts/${diff_name}_pr_${{ github.event.number }}.html" if [ $diff_exit_code -eq 0 ]; then @@ -156,7 +156,7 @@ jobs: for variant in $VARIANTS; do IFS=':' read -r name _ _ <<< "$variant" diff_name="${name}_diff" - cp "${{ github.workspace }}/selfdrive/ui/tests/diff/report/${diff_name}.html" "${diff_name}_pr_${{ github.event.number }}.html" + cp "${{ github.workspace }}/openpilot/selfdrive/ui/tests/diff/report/${diff_name}.html" "${diff_name}_pr_${{ github.event.number }}.html" git add "${diff_name}_pr_${{ github.event.number }}.html" done git commit -m "ui diff reports for PR #${{ github.event.number }}" || echo "No changes to commit" diff --git a/Jenkinsfile b/Jenkinsfile index 90f86b1967..c06674a5c5 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -93,7 +93,7 @@ def deviceStage(String stageName, String deviceType, List extra_env, def steps) retry (3) { def date = sh(script: 'date', returnStdout: true).trim(); device(device_ip, "set time", "date -s '" + date + "'") - device(device_ip, "git checkout", extra + "\n" + readFile("selfdrive/test/setup_device_ci.sh")) + device(device_ip, "git checkout", extra + "\n" + readFile("openpilot/selfdrive/test/setup_device_ci.sh")) } steps.each { item -> def name = item[0] @@ -202,51 +202,51 @@ node { parallel ( 'onroad tests': { deviceStage("onroad", "tizi-needs-can", ["UNSAFE=1"], [ - step("build openpilot", "cd system/manager && ./build.py"), + step("build openpilot", "cd openpilot/system/manager && ./build.py"), step("check dirty", "release/check-dirty.sh"), - step("onroad tests", "pytest selfdrive/test/test_onroad.py -s", [timeout: 60]), + step("onroad tests", "pytest openpilot/selfdrive/test/test_onroad.py -s", [timeout: 60]), ]) }, 'HW + Unit Tests': { deviceStage("tizi-hardware", "tizi-common", ["UNSAFE=1"], [ - step("build", "cd system/manager && ./build.py"), - step("test power draw", "pytest -s selfdrive/test//test_power_draw.py"), - step("test encoder", "LD_LIBRARY_PATH=/usr/local/lib pytest system/loggerd/tests/test_encoder.py", [diffPaths: ["system/loggerd/"]]), - step("test manager", "pytest system/manager/test/test_manager.py"), + step("build", "cd openpilot/system/manager && ./build.py"), + step("test power draw", "pytest -s openpilot/selfdrive/test//test_power_draw.py"), + step("test encoder", "LD_LIBRARY_PATH=/usr/local/lib pytest openpilot/system/loggerd/tests/test_encoder.py", [diffPaths: ["openpilot/system/loggerd/"]]), + step("test manager", "pytest openpilot/system/manager/test/test_manager.py"), ]) }, 'camerad OX03C10': { deviceStage("OX03C10", "tizi-ox03c10", ["UNSAFE=1"], [ - step("build", "cd system/manager && ./build.py"), - step("test pandad", "pytest selfdrive/pandad/tests/test_pandad.py"), - step("test camerad", "pytest system/camerad/test/test_camerad.py", [timeout: 90]), + step("build", "cd openpilot/system/manager && ./build.py"), + step("test pandad", "pytest openpilot/selfdrive/pandad/tests/test_pandad.py"), + step("test camerad", "pytest openpilot/system/camerad/test/test_camerad.py", [timeout: 90]), ]) }, 'camerad OS04C10': { deviceStage("OS04C10", "tici-os04c10", ["UNSAFE=1"], [ - step("build", "cd system/manager && ./build.py"), - step("test pandad", "pytest selfdrive/pandad/tests/test_pandad.py"), - step("test camerad", "pytest system/camerad/test/test_camerad.py", [timeout: 90]), + step("build", "cd openpilot/system/manager && ./build.py"), + step("test pandad", "pytest openpilot/selfdrive/pandad/tests/test_pandad.py"), + step("test camerad", "pytest openpilot/system/camerad/test/test_camerad.py", [timeout: 90]), ]) }, 'sensord': { deviceStage("LSM + MMC", "tizi-lsmc", ["UNSAFE=1"], [ - step("build", "cd system/manager && ./build.py"), - step("test sensord", "pytest system/sensord/tests/test_sensord.py"), + step("build", "cd openpilot/system/manager && ./build.py"), + step("test sensord", "pytest openpilot/system/sensord/tests/test_sensord.py"), ]) }, 'replay': { deviceStage("model-replay", "tizi-replay", ["UNSAFE=1"], [ - step("build", "cd system/manager && ./build.py", [diffPaths: ["selfdrive/modeld/", "tinygrad_repo", "selfdrive/test/process_replay/model_replay.py"]]), - step("model replay", "selfdrive/test/process_replay/model_replay.py", [diffPaths: ["selfdrive/modeld/", "tinygrad_repo", "selfdrive/test/process_replay/model_replay.py"]]), + step("build", "cd openpilot/system/manager && ./build.py", [diffPaths: ["openpilot/selfdrive/modeld/", "tinygrad_repo", "openpilot/selfdrive/test/process_replay/model_replay.py"]]), + step("model replay", "openpilot/selfdrive/test/process_replay/model_replay.py", [diffPaths: ["openpilot/selfdrive/modeld/", "tinygrad_repo", "openpilot/selfdrive/test/process_replay/model_replay.py"]]), ]) }, 'tizi': { deviceStage("tizi", "tizi", ["UNSAFE=1"], [ - step("build openpilot", "cd system/manager && ./build.py"), - step("test pandad loopback", "pytest selfdrive/pandad/tests/test_pandad_loopback.py"), - step("test pandad spi", "pytest selfdrive/pandad/tests/test_pandad_spi.py"), - step("test amp", "pytest common/hardware/tici/tests/test_amplifier.py"), + step("build openpilot", "cd openpilot/system/manager && ./build.py"), + step("test pandad loopback", "pytest openpilot/selfdrive/pandad/tests/test_pandad_loopback.py"), + step("test pandad spi", "pytest openpilot/selfdrive/pandad/tests/test_pandad_spi.py"), + step("test amp", "pytest openpilot/common/hardware/tici/tests/test_amplifier.py"), ]) }, diff --git a/README.md b/README.md index 480b140036..0f248cf35a 100644 --- a/README.md +++ b/README.md @@ -68,7 +68,7 @@ openpilot is developed by [comma](https://comma.ai/) and by users like you. We w * Join the [community Discord](https://discord.comma.ai) * Check out [the contributing docs](docs/CONTRIBUTING.md) -* Check out the [openpilot tools](tools/) +* Check out the [openpilot tools](openpilot/tools/) * Code documentation lives at https://docs.comma.ai * Information about running openpilot lives on the [community wiki](https://github.com/commaai/openpilot/wiki) diff --git a/SConstruct b/SConstruct index 41bc5d7d0d..2e4002f1f2 100644 --- a/SConstruct +++ b/SConstruct @@ -113,15 +113,16 @@ env = Environment( CXXFLAGS=["-std=c++1z"], CPPPATH=[ "#", + "#openpilot", "#msgq", "#openpilot/cereal/gen/cpp", acados_include_dirs, [x.INCLUDE_DIR for x in pkgs], ], LIBPATH=[ - "#common", + "#openpilot/common", "#msgq_repo", - "#selfdrive/pandad", + "#openpilot/selfdrive/pandad", "#rednose/helpers", [x.LIB_DIR for x in pkgs], ], @@ -211,7 +212,7 @@ def prune_cache_dir(target=None, source=None, env=None): # ********** start building stuff ********** # Build common module -SConscript(['common/SConscript']) +SConscript(['openpilot/common/SConscript']) Import('_common') common = [_common, 'json11', 'zmq'] Export('common') @@ -237,28 +238,28 @@ SConscript(['rednose/SConscript']) # Build system services SConscript([ - 'system/loggerd/SConscript', + 'openpilot/system/loggerd/SConscript', ]) if arch == "larch64": - SConscript(['system/camerad/SConscript']) + SConscript(['openpilot/system/camerad/SConscript']) # Build selfdrive SConscript([ - 'selfdrive/pandad/SConscript', - 'selfdrive/controls/lib/lateral_mpc_lib/SConscript', - 'selfdrive/controls/lib/longitudinal_mpc_lib/SConscript', - 'selfdrive/locationd/SConscript', - 'selfdrive/modeld/SConscript', - 'selfdrive/ui/SConscript', + 'openpilot/selfdrive/pandad/SConscript', + 'openpilot/selfdrive/controls/lib/lateral_mpc_lib/SConscript', + 'openpilot/selfdrive/controls/lib/longitudinal_mpc_lib/SConscript', + 'openpilot/selfdrive/locationd/SConscript', + 'openpilot/selfdrive/modeld/SConscript', + 'openpilot/selfdrive/ui/SConscript', ]) # Build desktop-only tools if GetOption('extras') and arch != "larch64": SConscript([ - 'tools/replay/SConscript', - 'tools/cabana/SConscript', - 'tools/jotpluggler/SConscript', + 'openpilot/tools/replay/SConscript', + 'openpilot/tools/cabana/SConscript', + 'openpilot/tools/jotpluggler/SConscript', ]) diff --git a/common/hardware/tici/agnos.py b/common/hardware/tici/agnos.py index c5ca7efb4a..0210821a0d 100755 --- a/common/hardware/tici/agnos.py +++ b/common/hardware/tici/agnos.py @@ -12,7 +12,7 @@ import requests SPARSE_CHUNK_FMT = struct.Struct('H2xI4x') -AGNOS_MANIFEST_FILE = "system/hardware/tici/agnos.json" +AGNOS_MANIFEST_FILE = "openpilot/system/hardware/tici/agnos.json" class StreamingDecompressor: diff --git a/common/mock/__init__.py b/common/mock/__init__.py index 673513fdd9..ff4dd32b92 100644 --- a/common/mock/__init__.py +++ b/common/mock/__init__.py @@ -1,6 +1,6 @@ """ Utilities for generating mock messages for testing. -example in common/tests/test_mock.py +example in openpilot/common/tests/test_mock.py """ diff --git a/common/spinner.py b/common/spinner.py index 12a816eaf8..f152285138 100755 --- a/common/spinner.py +++ b/common/spinner.py @@ -8,7 +8,7 @@ class Spinner: try: self.spinner_proc = subprocess.Popen(["./spinner.py"], stdin=subprocess.PIPE, - cwd=os.path.join(BASEDIR, "system", "ui"), + cwd=os.path.join(BASEDIR, "openpilot/system", "ui"), close_fds=True) except OSError: self.spinner_proc = None diff --git a/common/text_window.py b/common/text_window.py index 358243d1f1..94cfa7811e 100755 --- a/common/text_window.py +++ b/common/text_window.py @@ -10,7 +10,7 @@ class TextWindow: try: self.text_proc = subprocess.Popen(["./text.py", text], stdin=subprocess.PIPE, - cwd=os.path.join(BASEDIR, "system", "ui"), + cwd=os.path.join(BASEDIR, "openpilot/system", "ui"), close_fds=True) except OSError: self.text_proc = None diff --git a/common/version.py b/common/version.py index 0cea616d23..011161b99d 100755 --- a/common/version.py +++ b/common/version.py @@ -20,7 +20,7 @@ terms_version: str = "2" def get_version(path: str = BASEDIR) -> str: - with open(os.path.join(path, "common", "version.h")) as _versionf: + with open(os.path.join(path, "openpilot", "common", "version.h")) as _versionf: version = _versionf.read().split('"')[1] return version diff --git a/conftest.py b/conftest.py index 6307f8304c..48d42aed86 100644 --- a/conftest.py +++ b/conftest.py @@ -9,10 +9,10 @@ from openpilot.common.hardware import TICI, HARDWARE # these are heavy CI-only tests, invoked explicitly in .github/workflows/tests.yaml collect_ignore = [ - "selfdrive/test/process_replay/test_processes.py", - "selfdrive/test/process_replay/test_regen.py", + "openpilot/selfdrive/test/process_replay/test_processes.py", + "openpilot/selfdrive/test/process_replay/test_regen.py", - "tools/sim/", + "openpilot/tools/sim/", ] diff --git a/docs/CARS.md b/docs/CARS.md index 1f86abb4f8..b0891b8366 100644 --- a/docs/CARS.md +++ b/docs/CARS.md @@ -1,4 +1,4 @@ - + # Supported Cars diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md index cbeb5f6d3a..393819830b 100644 --- a/docs/CONTRIBUTING.md +++ b/docs/CONTRIBUTING.md @@ -6,7 +6,7 @@ Development is coordinated through [Discord](https://discord.comma.ai) and GitHu ### Getting Started -* Set up your [development environment](/tools/) +* Set up your [development environment](/openpilot/tools/) * Join our [Discord](https://discord.comma.ai) * Docs are at https://docs.comma.ai and https://blog.comma.ai diff --git a/docs/SAFETY.md b/docs/SAFETY.md index 0a662ac6cd..5857c6d5b5 100644 --- a/docs/SAFETY.md +++ b/docs/SAFETY.md @@ -35,8 +35,8 @@ For additional safety implementation details, refer to [panda safety model](http ### Forks of openpilot -* Do not disable or nerf [driver monitoring](https://github.com/commaai/openpilot/tree/master/selfdrive/monitoring) -* Do not disable or nerf [excessive actuation checks](https://github.com/commaai/openpilot/tree/master/selfdrive/selfdrived/helpers.py) +* Do not disable or nerf [driver monitoring](https://github.com/commaai/openpilot/tree/master/openpilot/selfdrive/monitoring) +* Do not disable or nerf [excessive actuation checks](https://github.com/commaai/openpilot/tree/master/openpilot/selfdrive/selfdrived/helpers.py) * If your fork modifies any of the code in `opendbc/safety/`: * your fork cannot use the openpilot trademark * your fork must preserve the full [safety test suite](https://github.com/commaai/opendbc/tree/master/opendbc/safety/tests) and all tests must pass, including any new coverage required by the fork's changes diff --git a/docs/concepts/logs.md b/docs/concepts/logs.md index 4fa720ddde..8ba2486ab5 100644 --- a/docs/concepts/logs.md +++ b/docs/concepts/logs.md @@ -2,7 +2,7 @@ openpilot records routes in one minute chunks called segments. A route starts on the rising edge of ignition and ends on the falling edge. -Check out our [Python library](https://github.com/commaai/openpilot/blob/master/tools/lib/logreader.py) for reading openpilot logs. Also checkout our [tools](https://github.com/commaai/openpilot/tree/master/tools) to replay and view your data. These are the same tools we use to debug and develop openpilot. +Check out our [Python library](https://github.com/commaai/openpilot/blob/master/openpilot/tools/lib/logreader.py) for reading openpilot logs. Also checkout our [tools](https://github.com/commaai/openpilot/tree/master/tools) to replay and view your data. These are the same tools we use to debug and develop openpilot. For each segment, openpilot records the following log types: diff --git a/docs/how-to/car-port.md b/docs/how-to/car-port.md index ca565e53f6..c4106f91a7 100644 --- a/docs/how-to/car-port.md +++ b/docs/how-to/car-port.md @@ -30,7 +30,7 @@ Each car brand is supported by a standard interface structure in `opendbc/car/[b For historical reasons, openpilot still contains a small amount of car-specific logic. This will eventually be migrated to opendbc or otherwise removed. -* `selfdrive/car/car_specific.py`: Brand-specific event logic +* `openpilot/selfdrive/car/car_specific.py`: Brand-specific event logic # How do I port car? diff --git a/docs/how-to/replay-a-drive.md b/docs/how-to/replay-a-drive.md index a11b29dcc4..129e7b8301 100644 --- a/docs/how-to/replay-a-drive.md +++ b/docs/how-to/replay-a-drive.md @@ -5,7 +5,7 @@ Replaying is a critical tool for openpilot development and debugging. ## Replaying a route *Hardware required: none* -Just run `tools/replay/replay --demo`. +Just run `openpilot/tools/replay/replay --demo`. ## Replaying CAN data *Hardware required: jungle and comma four* diff --git a/docs/how-to/turn-the-speed-blue.md b/docs/how-to/turn-the-speed-blue.md index b5692daff7..5cfa8e176a 100644 --- a/docs/how-to/turn-the-speed-blue.md +++ b/docs/how-to/turn-the-speed-blue.md @@ -28,10 +28,10 @@ scons We'll run the `replay` tool with the demo route to get data streaming for testing our UI changes. ```bash # in terminal 1 -tools/replay/replay --demo +openpilot/tools/replay/replay --demo # in terminal 2 -./selfdrive/ui/ui.py +./openpilot/selfdrive/ui/ui.py ``` The openpilot UI should launch and show a replay of the demo route. @@ -45,10 +45,10 @@ Now let’s update the speed display color in the UI. Search for the function responsible for rendering the current speed: ```bash -git grep "_draw_current_speed" selfdrive/ui/onroad/hud_renderer.py +git grep "_draw_current_speed" openpilot/selfdrive/ui/onroad/hud_renderer.py ``` -You'll find the relevant code inside `selfdrive/ui/onroad/hud_renderer.py`, in this function: +You'll find the relevant code inside `openpilot/selfdrive/ui/onroad/hud_renderer.py`, in this function: ```python def _draw_current_speed(self, rect: rl.Rectangle) -> None: @@ -72,7 +72,7 @@ Change `COLORS.white` to make it **blue** instead of white. A nice soft blue is After making changes, re-run the UI to see your new UI: ```bash -./selfdrive/ui/ui.py +./openpilot/selfdrive/ui/ui.py ``` ![](https://blog.comma.ai/img/blue_speed_ui.png) diff --git a/launch_chffrplus.sh b/launch_chffrplus.sh index 46b0a5d079..17a765e076 100755 --- a/launch_chffrplus.sh +++ b/launch_chffrplus.sh @@ -19,12 +19,12 @@ function agnos_init { # Check if AGNOS update is required if [ $(< /VERSION) != "$AGNOS_VERSION" ]; then - AGNOS_PY="$DIR/common/hardware/tici/agnos.py" - MANIFEST="$DIR/system/hardware/tici/agnos.json" + AGNOS_PY="$DIR/openpilot/common/hardware/tici/agnos.py" + MANIFEST="$DIR/openpilot/system/hardware/tici/agnos.json" if $AGNOS_PY --verify $MANIFEST; then sudo reboot fi - $DIR/common/hardware/tici/updater $AGNOS_PY $MANIFEST + $DIR/openpilot/common/hardware/tici/updater $AGNOS_PY $MANIFEST fi } @@ -79,7 +79,7 @@ function launch { tmux capture-pane -pq -S-1000 > /tmp/launch_log # start manager - cd system/manager + cd openpilot/system/manager if [ ! -f $DIR/prebuilt ]; then ./build.py fi diff --git a/openpilot/cereal/README.md b/openpilot/cereal/README.md index 419d380882..17f27fd742 100644 --- a/openpilot/cereal/README.md +++ b/openpilot/cereal/README.md @@ -24,17 +24,17 @@ things are not. Read more details [here](https://capnproto.org/language.html). ### Custom forks Forks of [openpilot](https://github.com/commaai/openpilot) might want to add things to the messaging -spec, however this could conflict with future changes made in mainline cereal/openpilot. Rebasing against mainline openpilot +spec, however this could conflict with future changes made in mainline openpilot's cereal spec. Rebasing against mainline openpilot then means breaking backwards-compatibility with all old logs of your fork. So we added reserved events in -[custom.capnp](custom.capnp) that we will leave empty in mainline cereal/openpilot. **If you only modify those, you can ensure your +[custom.capnp](custom.capnp) that we will leave empty in mainline openpilot's cereal spec. **If you only modify those, you can ensure your fork will remain backwards-compatible with all versions of mainline openpilot and your fork.** An example of compatible changes: ```diff -diff --git a/cereal/custom.capnp b/cereal/custom.capnp +diff --git a/openpilot/cereal/custom.capnp b/openpilot/cereal/custom.capnp index 3348e859e..3365c7b98 100644 ---- a/cereal/custom.capnp -+++ b/cereal/custom.capnp +--- a/openpilot/cereal/custom.capnp ++++ b/openpilot/cereal/custom.capnp @@ -10,7 +10,11 @@ $Cxx.namespace("cereal"); # DO rename the structs # DON'T change the identifier (e.g. @0x81c2f05a394cf4af) @@ -48,10 +48,10 @@ index 3348e859e..3365c7b98 100644 } struct CustomReserved1 @0xaedffd8f31e7b55d { -diff --git a/cereal/log.capnp b/cereal/log.capnp +diff --git a/openpilot/cereal/log.capnp b/openpilot/cereal/log.capnp index 1209f3fd9..b189f58b6 100644 ---- a/cereal/log.capnp -+++ b/cereal/log.capnp +--- a/openpilot/cereal/log.capnp ++++ b/openpilot/cereal/log.capnp @@ -2558,14 +2558,14 @@ struct Event { # DO change the name of the field diff --git a/openpilot/cereal/log.capnp b/openpilot/cereal/log.capnp index 02536e46b1..beb71c8da8 100644 --- a/openpilot/cereal/log.capnp +++ b/openpilot/cereal/log.capnp @@ -1270,7 +1270,7 @@ struct LateralPlan @0xe1e9318e2ae8b51e { struct LiveLocationKalman { # More info on reference frames: - # https://github.com/commaai/openpilot/tree/master/common/transformations + # https://github.com/commaai/openpilot/tree/master/openpilot/common/transformations positionECEF @0 : Measurement; positionGeodetic @1 : Measurement; @@ -1327,7 +1327,7 @@ struct LiveLocationKalman { struct LivePose { # More info on reference frames: - # https://github.com/commaai/openpilot/tree/master/common/transformations + # https://github.com/commaai/openpilot/tree/master/openpilot/common/transformations orientationNED @0 :XYZMeasurement; velocityDevice @1 :XYZMeasurement; accelerationDevice @2 :XYZMeasurement; diff --git a/pyproject.toml b/pyproject.toml index 53a237a22c..8cff68a176 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -128,9 +128,9 @@ allow-direct-references = true [tool.pytest.ini_options] minversion = "6.0" -addopts = "--ignore=openpilot/common --ignore=openpilot/selfdrive --ignore=openpilot/system --ignore=openpilot/tools --ignore=opendbc/ --ignore=panda/ --ignore=rednose_repo/ --ignore=tinygrad_repo/ --ignore=teleoprtc_repo/ --ignore=msgq/ --ignore=selfdrive/modeld -Werror --strict-config --strict-markers --durations=10 -n auto --dist=loadgroup" +addopts = "-Werror --strict-config --strict-markers --durations=10 -n auto --dist=loadgroup" cpp_files = "test_*" -cpp_harness = "selfdrive/test/cpp_harness.py" +cpp_harness = "openpilot/selfdrive/test/cpp_harness.py" python_files = "test_*.py" markers = [ "slow: tests that take awhile to run and can be skipped with -m 'not slow'", @@ -141,11 +141,7 @@ markers = [ "xdist_group_class_property: group tests by a property of the class that contains them", ] testpaths = [ - "common", - "selfdrive", - "system", - "tools", - "openpilot/cereal", + "openpilot", ] [tool.codespell] @@ -153,7 +149,7 @@ quiet-level = 3 # if you've got a short variable name that's getting flagged, add it here ignore-words-list = "bu,ro,te,ue,alo,hda,ois,nam,nams,ned,som,parm,setts,inout,warmup,bumb,nd,sie,preints,whit,indexIn,ws,uint,grey,deque,stdio,amin,BA,LITE,atEnd,UIs,errorString,arange,FocusIn,od,tim,relA,hist,copyable,jupyter,thead,TGE,abl,lite,ser" builtin = "clear,rare,informal,code,names,en-GB_to_en-US" -skip = "../tinygrad/*, ./tinygrad_repo/*, ./msgq/*, ./panda/*, ./opendbc/*, ./opendbc_repo/*, ./rednose/*, ./rednose_repo/*, ./teleoprtc/*, ./teleoprtc_repo/*, *.po, uv.lock, *.onnx, *.pem, ./openpilot/cereal/gen/*, */c_generated_code/*, docs/assets/*, tools/plotjuggler/layouts/*, selfdrive/assets/offroad/mici_fcc.html" +skip = "*.po, uv.lock, *.onnx, *.pem, */c_generated_code/*, docs/assets/*, tools/plotjuggler/layouts/*, openpilot/tools/plotjuggler/layouts/*, selfdrive/assets/offroad/mici_fcc.html, openpilot/selfdrive/assets/offroad/mici_fcc.html" # https://docs.astral.sh/ruff/configuration/#using-pyprojecttoml [tool.ruff] @@ -180,13 +176,6 @@ lint.ignore = [ line-length = 160 exclude = [ "openpilot/cereal", - "panda", - "opendbc", - "opendbc_repo", - "rednose_repo", - "tinygrad_repo", - "teleoprtc", - "teleoprtc_repo", "*.ipynb", "generated", ] @@ -211,21 +200,6 @@ lint.flake8-implicit-str-concat.allow-multiline = false [tool.ruff.format] quote-style = "preserve" -[tool.ty.src] -exclude = [ - "msgq/", - "msgq_repo/", - "opendbc/", - "opendbc_repo/", - "panda/", - "rednose/", - "rednose_repo/", - "tinygrad/", - "tinygrad_repo/", - "teleoprtc/", - "teleoprtc_repo/", -] - [tool.ty.rules] unresolved-import = "ignore" # Cython-compiled modules (.pyx) unresolved-attribute = "ignore" # many from capnp and Cython modules diff --git a/release/README.md b/release/README.md index 7aeea9fe4a..f3dcefd587 100644 --- a/release/README.md +++ b/release/README.md @@ -12,7 +12,7 @@ - [ ] push to staging: - [ ] make sure you are on the newly created release master branch (`zerotentwo`) - [ ] run `BRANCH=devel-staging release/build_stripped.sh`. Jenkins will then automatically build staging on device, run `test_onroad` and update the staging branch -- [ ] bump version on master: `common/version.h` and `RELEASES.md` +- [ ] bump version on master: `openpilot/common/version.h` and `RELEASES.md` - [ ] post on Discord, tag `@release crew` ### Go to release diff --git a/release/build_release.sh b/release/build_release.sh index cec6f4ecdc..4f609aea3f 100755 --- a/release/build_release.sh +++ b/release/build_release.sh @@ -41,7 +41,7 @@ cd $BUILD_DIR rm -f panda/board/obj/panda.bin.signed rm -f panda/board/obj/panda_h7.bin.signed -VERSION=$(cat common/version.h | awk -F[\"-] '{print $2}') +VERSION=$(cat openpilot/common/version.h | awk -F[\"-] '{print $2}') echo "[-] committing version $VERSION T=$SECONDS" git add -f . git commit -a -m "openpilot v$VERSION release" @@ -74,7 +74,7 @@ find . -name '*.pyc' -delete find . -name 'moc_*' -delete find . -name '__pycache__' -delete rm -rf .sconsign.dblite Jenkinsfile release/ -rm -f selfdrive/modeld/models/*.onnx* +rm -f openpilot/selfdrive/modeld/models/*.onnx* # Mark as prebuilt release touch prebuilt @@ -85,8 +85,8 @@ git commit --amend -m "openpilot v$VERSION" # Run tests cd $BUILD_DIR -RELEASE=1 pytest -n0 -s selfdrive/test/test_onroad.py -#pytest selfdrive/car/tests/test_car_interfaces.py +RELEASE=1 pytest -n0 -s openpilot/selfdrive/test/test_onroad.py +#pytest openpilot/selfdrive/car/tests/test_car_interfaces.py echo "[-] pushing release T=$SECONDS" REFS=() diff --git a/release/build_stripped.sh b/release/build_stripped.sh index 91c94b44a0..ea74aac859 100755 --- a/release/build_stripped.sh +++ b/release/build_stripped.sh @@ -45,13 +45,13 @@ cd $TARGET_DIR rm -rf .git/modules/ rm -f panda/board/obj/panda.bin.signed -find selfdrive/modeld/models -name '*.onnx' -size +95M -exec ./common/file_chunker.py {} \; +find openpilot/selfdrive/modeld/models -name '*.onnx' -size +95M -exec ./openpilot/common/file_chunker.py {} \; # include source commit hash and build date in commit GIT_HASH=$(git --git-dir=$SOURCE_DIR/.git rev-parse HEAD) GIT_COMMIT_DATE=$(git --git-dir=$SOURCE_DIR/.git show --no-patch --format='%ct %ci' HEAD) DATETIME=$(date '+%Y-%m-%dT%H:%M:%S') -VERSION=$(cat $SOURCE_DIR/common/version.h | awk -F\" '{print $2}') +VERSION=$(cat $SOURCE_DIR/openpilot/common/version.h | awk -F\" '{print $2}') echo -n "$GIT_HASH" > git_src_commit echo -n "$GIT_COMMIT_DATE" > git_src_commit_date diff --git a/release/pack.py b/release/pack.py index dd29de4256..f29ea034db 100755 --- a/release/pack.py +++ b/release/pack.py @@ -13,7 +13,7 @@ from openpilot.common.basedir import BASEDIR DIRS = ['openpilot'] EXTS = ['.png', '.py', '.ttf', '.capnp', '.json', '.fnt', '.mo', '.po'] -EXCLUDE = ['selfdrive/assets/training'] +EXCLUDE = ['openpilot/selfdrive/assets/training'] INTERPRETER = '/usr/bin/env python3' diff --git a/scripts/lint/lint.sh b/scripts/lint/lint.sh index 0f236377ed..77d29e7092 100755 --- a/scripts/lint/lint.sh +++ b/scripts/lint/lint.sh @@ -13,9 +13,6 @@ cd $ROOT FAILED=0 -IGNORED_FILES="uv\.lock|docs\/CARS.md" -IGNORED_DIRS="^msgq.*|^msgq_repo.*|^opendbc.*|^opendbc_repo.*|^cereal.*|^openpilot\/cereal.*|^panda.*|^rednose.*|^rednose_repo.*|^tinygrad.*|^tinygrad_repo.*|^teleoprtc.*|^teleoprtc_repo.*" - function run() { shopt -s extglob case $1 in @@ -48,14 +45,14 @@ function run_tests() { ALL_FILES=$1 PYTHON_FILES=$2 - run "ruff" ruff check $ROOT --quiet + run "ruff" ruff check openpilot --quiet run "check_added_large_files" python3 -m pre_commit_hooks.check_added_large_files --enforce-all $ALL_FILES --maxkb=120 run "check_shebang_scripts_are_executable" python3 -m pre_commit_hooks.check_shebang_scripts_are_executable $ALL_FILES run "check_shebang_format" $DIR/check_shebang_format.sh $ALL_FILES run "check_nomerge_comments" $DIR/check_nomerge_comments.sh $ALL_FILES if [[ -z "$FAST" ]]; then - run "ty" ty check + run "ty" ty check openpilot run "codespell" codespell $ALL_FILES fi @@ -105,7 +102,7 @@ done RUN=$([ -z "$RUN" ] && echo "" || echo "!($(echo $RUN | sed 's/ /|/g'))") SKIP="@($(echo $SKIP | sed 's/ /|/g'))" -GIT_FILES="$(git ls-files | sed -E "s/$IGNORED_FILES|$IGNORED_DIRS//g")" +GIT_FILES="$(git ls-files openpilot common selfdrive system tools)" ALL_FILES="" for f in $GIT_FILES; do if [[ -f $f ]]; then diff --git a/scripts/post-commit b/scripts/post-commit index f9964639de..399b73c523 100755 --- a/scripts/post-commit +++ b/scripts/post-commit @@ -3,5 +3,5 @@ set -e if [[ -f .git/hooks/post-commit.d/post-commit ]]; then .git/hooks/post-commit.d/post-commit fi -tools/op.sh lint --fast +openpilot/tools/op.sh lint --fast echo "" diff --git a/scripts/reporter.py b/scripts/reporter.py index 199f1fae58..5de5521835 100755 --- a/scripts/reporter.py +++ b/scripts/reporter.py @@ -7,7 +7,7 @@ from tinygrad.nn.onnx import OnnxPBParser BASEDIR = os.path.abspath(os.path.join(os.path.dirname(os.path.realpath(__file__)), "../")) MASTER_PATH = os.getenv("MASTER_PATH", BASEDIR) -MODEL_PATH = "/selfdrive/modeld/models/" +MODEL_PATH = "/openpilot/selfdrive/modeld/models/" class MetadataOnnxPBParser(OnnxPBParser): diff --git a/scripts/waste.c b/scripts/waste.c index 2e492916a7..fc230846f2 100644 --- a/scripts/waste.c +++ b/scripts/waste.c @@ -11,7 +11,7 @@ #include #include #include -#include "../common/timing.h" +#include "../openpilot/common/timing.h" int get_nprocs(void); double *ttime, *oout; @@ -86,4 +86,3 @@ int main() { sleep(1); } } - diff --git a/selfdrive/car/CARS_template.md b/selfdrive/car/CARS_template.md index bc335b6bd3..35804ff1fa 100644 --- a/selfdrive/car/CARS_template.md +++ b/selfdrive/car/CARS_template.md @@ -6,7 +6,7 @@ {% set hardware_col_name = 'Hardware Needed' %} {% set wide_hardware_col_name = width_tag|format(hardware_col_name) -%} - + # Supported Cars diff --git a/selfdrive/car/docs.py b/selfdrive/car/docs.py index f807fc320e..ea7a70688e 100755 --- a/selfdrive/car/docs.py +++ b/selfdrive/car/docs.py @@ -6,7 +6,7 @@ from openpilot.common.basedir import BASEDIR from opendbc.car.docs import get_all_car_docs, generate_cars_md CARS_MD_OUT = os.path.join(BASEDIR, "docs", "CARS.md") -CARS_MD_TEMPLATE = os.path.join(BASEDIR, "selfdrive", "car", "CARS_template.md") +CARS_MD_TEMPLATE = os.path.join(BASEDIR, "openpilot/selfdrive", "car", "CARS_template.md") if __name__ == "__main__": parser = argparse.ArgumentParser(description="Auto generates supported cars documentation", diff --git a/selfdrive/car/tests/big_cars_test.sh b/selfdrive/car/tests/big_cars_test.sh index bb6e82dd0e..1c3da2e9e7 100755 --- a/selfdrive/car/tests/big_cars_test.sh +++ b/selfdrive/car/tests/big_cars_test.sh @@ -6,6 +6,6 @@ cd $BASEDIR export MAX_EXAMPLES=300 export INTERNAL_SEG_CNT=300 -export INTERNAL_SEG_LIST=selfdrive/car/tests/test_models_segs.txt +export INTERNAL_SEG_LIST=openpilot/selfdrive/car/tests/test_models_segs.txt -cd selfdrive/car/tests && pytest test_models.py test_car_interfaces.py +cd openpilot/selfdrive/car/tests && pytest test_models.py test_car_interfaces.py diff --git a/selfdrive/controls/lib/lateral_mpc_lib/SConscript b/selfdrive/controls/lib/lateral_mpc_lib/SConscript index 5ff526ae83..575e5c1af5 100644 --- a/selfdrive/controls/lib/lateral_mpc_lib/SConscript +++ b/selfdrive/controls/lib/lateral_mpc_lib/SConscript @@ -49,7 +49,7 @@ acados_include_dir = Dir(acados.INCLUDE_DIR) acados_template_dir = Dir(acados.TEMPLATE_DIR) source_list = ['lat_mpc.py', - '#selfdrive/modeld/constants.py', + '#openpilot/selfdrive/modeld/constants.py', acados_include_dir.File('acados_c/ocp_nlp_interface.h'), acados_template_dir.File('c_templates_tera/acados_solver.in.c'), ] diff --git a/selfdrive/controls/lib/longitudinal_mpc_lib/SConscript b/selfdrive/controls/lib/longitudinal_mpc_lib/SConscript index a3218e9f34..636ef0fb21 100644 --- a/selfdrive/controls/lib/longitudinal_mpc_lib/SConscript +++ b/selfdrive/controls/lib/longitudinal_mpc_lib/SConscript @@ -55,7 +55,7 @@ acados_include_dir = Dir(acados.INCLUDE_DIR) acados_template_dir = Dir(acados.TEMPLATE_DIR) source_list = ['long_mpc.py', - '#selfdrive/modeld/constants.py', + '#openpilot/selfdrive/modeld/constants.py', acados_include_dir.File('acados_c/ocp_nlp_interface.h'), acados_template_dir.File('c_templates_tera/acados_solver.in.c'), ] diff --git a/selfdrive/locationd/calibrationd.py b/selfdrive/locationd/calibrationd.py index 4e3eb7b0fa..b9616bf632 100755 --- a/selfdrive/locationd/calibrationd.py +++ b/selfdrive/locationd/calibrationd.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 ''' This process finds calibration values. More info on what these calibration values -are can be found here https://github.com/commaai/openpilot/tree/master/common/transformations +are can be found here https://github.com/commaai/openpilot/tree/master/openpilot/common/transformations While the roll calibration is a real value that can be estimated, here we assume it's zero, and the image input into the neural network is not corrected for roll. ''' diff --git a/selfdrive/modeld/SConscript b/selfdrive/modeld/SConscript index 4a40173629..5f6281556f 100644 --- a/selfdrive/modeld/SConscript +++ b/selfdrive/modeld/SConscript @@ -16,7 +16,7 @@ CAMERA_CONFIGS = [ ] Import('env', 'arch') -chunker_file = File("#common/file_chunker.py") +chunker_file = File("#openpilot/common/file_chunker.py") lenv = env.Clone() tinygrad_root = env.Dir("#").abspath @@ -45,11 +45,11 @@ else: tg_flags = f'DEV=CPU' if arch == 'Darwin' else 'DEV=CPU:LLVM' tg_devices = { # which device to put jit inputs to at runtime - 'selfdrive.modeld.modeld': { + 'openpilot.selfdrive.modeld.modeld': { 'default': {'WARP_DEV': tg_backend, 'QUEUE_DEV': tg_backend}, 'usbgpu': {'WARP_DEV': tg_backend, 'QUEUE_DEV': 'AMD'} }, - 'selfdrive.modeld.dmonitoringmodeld': { + 'openpilot.selfdrive.modeld.dmonitoringmodeld': { 'default': {'DEV': tg_backend} }, } @@ -74,12 +74,12 @@ tg_devices_node = lenv.Command( # tinygrad calls brew which needs a $HOME in the env mac_brew_string = f'HOME={os.path.expanduser("~")}' if arch == 'Darwin' else '' -modeld_dir = Dir("#selfdrive/modeld").abspath +modeld_dir = Dir("#openpilot/selfdrive/modeld").abspath compile_modeld_script = [ File(f"{modeld_dir}/compile_modeld.py"), File(f"{modeld_dir}/get_model_metadata.py"), - File("#system/camerad/cameras/nv12_info.py"), - File("#common/hardware/hw.py"), + File("#openpilot/system/camerad/cameras/nv12_info.py"), + File("#openpilot/common/hardware/hw.py"), ] model_w, model_h = MEDMODEL_INPUT_SIZE frame_skip = ModelConstants.MODEL_RUN_FREQ // ModelConstants.MODEL_CONTEXT_FREQ @@ -109,8 +109,8 @@ for usbgpu in [False, True] if USBGPU else [False]: # get model metadata fn = File(f"models/dmonitoring_model").abspath -script_files = [File(Dir("#selfdrive/modeld").File("get_model_metadata.py").abspath)] -cmd = f'{tg_flags} {mac_brew_string} python3 {Dir("#selfdrive/modeld").abspath}/get_model_metadata.py {fn}.onnx' +script_files = [File(Dir("#openpilot/selfdrive/modeld").File("get_model_metadata.py").abspath)] +cmd = f'{tg_flags} {mac_brew_string} python3 {Dir("#openpilot/selfdrive/modeld").abspath}/get_model_metadata.py {fn}.onnx' lenv.Command(fn + "_metadata.pkl", [fn + ".onnx"] + tinygrad_files + script_files + [tg_devices_node], cmd) dm_w, dm_h = DM_INPUT_SIZE diff --git a/selfdrive/modeld/dmonitoringmodeld.py b/selfdrive/modeld/dmonitoringmodeld.py index a022e3c3c0..2c659d9ac6 100755 --- a/selfdrive/modeld/dmonitoringmodeld.py +++ b/selfdrive/modeld/dmonitoringmodeld.py @@ -17,7 +17,7 @@ from openpilot.system.camerad.cameras.nv12_info import get_nv12_info from openpilot.common.file_chunker import read_file_chunked from openpilot.selfdrive.modeld.parse_model_outputs import sigmoid, safe_exp -PROCESS_NAME = "selfdrive.modeld.dmonitoringmodeld" +PROCESS_NAME = "openpilot.selfdrive.modeld.dmonitoringmodeld" SEND_RAW_PRED = os.getenv('SEND_RAW_PRED') MODEL_PKL_PATH = MODELS_DIR / 'dmonitoring_model_tinygrad.pkl' METADATA_PATH = MODELS_DIR / 'dmonitoring_model_metadata.pkl' diff --git a/selfdrive/modeld/modeld.py b/selfdrive/modeld/modeld.py index 590d0f103e..9722538b33 100755 --- a/selfdrive/modeld/modeld.py +++ b/selfdrive/modeld/modeld.py @@ -27,7 +27,7 @@ from openpilot.common.file_chunker import read_file_chunked, get_manifest_path from openpilot.selfdrive.modeld.constants import ModelConstants, Plan from openpilot.selfdrive.modeld.helpers import usbgpu_present, modeld_pkl_path, get_tg_input_devices -PROCESS_NAME = "selfdrive.modeld.modeld" +PROCESS_NAME = "openpilot.selfdrive.modeld.modeld" SEND_RAW_PRED = os.getenv('SEND_RAW_PRED') LAT_SMOOTH_SECONDS = 0.0 diff --git a/selfdrive/modeld/models/README.md b/selfdrive/modeld/models/README.md index 04b69c61c3..ce84b1e28f 100644 --- a/selfdrive/modeld/models/README.md +++ b/selfdrive/modeld/models/README.md @@ -43,7 +43,7 @@ Refer to **slice_outputs** and **parse_vision_outputs/parse_policy_outputs** in * camera calibration angles (roll, pitch, yaw) from liveCalibration: 3 x float32 inputs ### output format -* 84 x float32 outputs = 2 + 41 * 2 ([parsing example](https://github.com/commaai/openpilot/blob/22ce4e17ba0d3bfcf37f8255a4dd1dc683fe0c38/selfdrive/modeld/models/dmonitoring.cc#L33)) +* 84 x float32 outputs = 2 + 41 * 2 ([parsing example](https://github.com/commaai/openpilot/blob/22ce4e17ba0d3bfcf37f8255a4dd1dc683fe0c38/openpilot/selfdrive/modeld/models/dmonitoring.cc#L33)) * for each person in the front seats (2 * 41) * face pose: 12 = 6 + 6 * face orientation [pitch, yaw, roll] in camera frame: 3 diff --git a/selfdrive/pandad/pandad.py b/selfdrive/pandad/pandad.py index 443c25a7e5..6dbb398eed 100755 --- a/selfdrive/pandad/pandad.py +++ b/selfdrive/pandad/pandad.py @@ -99,7 +99,7 @@ def main() -> None: # run real pandad os.environ['MANAGER_DAEMON'] = 'pandad' - process = subprocess.Popen(["./pandad"], cwd=os.path.join(BASEDIR, "selfdrive/pandad")) + process = subprocess.Popen(["./pandad"], cwd=os.path.join(BASEDIR, "openpilot/selfdrive/pandad")) process.wait() # TODO: wrap all panda exceptions in a base panda exception except (usb1.USBErrorNoDevice, usb1.USBErrorPipe): diff --git a/selfdrive/selfdrived/alertmanager.py b/selfdrive/selfdrived/alertmanager.py index c166ff591c..7ba3d8034c 100644 --- a/selfdrive/selfdrived/alertmanager.py +++ b/selfdrive/selfdrived/alertmanager.py @@ -9,7 +9,7 @@ from openpilot.common.params import Params from openpilot.selfdrive.selfdrived.events import Alert, EmptyAlert -with open(os.path.join(BASEDIR, "selfdrive/selfdrived/alerts_offroad.json")) as f: +with open(os.path.join(BASEDIR, "openpilot/selfdrive/selfdrived/alerts_offroad.json")) as f: OFFROAD_ALERTS = json.load(f) diff --git a/selfdrive/selfdrived/tests/test_alerts.py b/selfdrive/selfdrived/tests/test_alerts.py index 38db9981f6..276de2a6a9 100644 --- a/selfdrive/selfdrived/tests/test_alerts.py +++ b/selfdrive/selfdrived/tests/test_alerts.py @@ -15,7 +15,7 @@ from openpilot.selfdrive.test.process_replay.process_replay import CONFIGS AlertSize = log.SelfdriveState.AlertSize -OFFROAD_ALERTS_PATH = os.path.join(BASEDIR, "selfdrive/selfdrived/alerts_offroad.json") +OFFROAD_ALERTS_PATH = os.path.join(BASEDIR, "openpilot/selfdrive/selfdrived/alerts_offroad.json") # TODO: add callback alerts ALERTS = [] @@ -48,7 +48,7 @@ class TestAlerts: # ensure alert text doesn't exceed allowed width def test_alert_text_length(self): - font_path = os.path.join(BASEDIR, "selfdrive/assets/fonts") + font_path = os.path.join(BASEDIR, "openpilot/selfdrive/assets/fonts") regular_font_path = os.path.join(font_path, "Inter-SemiBold.ttf") bold_font_path = os.path.join(font_path, "Inter-Bold.ttf") semibold_font_path = os.path.join(font_path, "Inter-SemiBold.ttf") diff --git a/selfdrive/test/test_onroad.py b/selfdrive/test/test_onroad.py index f64bc3b027..56ea9dbd06 100644 --- a/selfdrive/test/test_onroad.py +++ b/selfdrive/test/test_onroad.py @@ -35,39 +35,39 @@ LOG_OFFSET = 8 MAX_TOTAL_CPU = 350. # total for all 8 cores PROCS = { # Baseline CPU usage by process - "selfdrive.controls.controlsd": 16.0, - "selfdrive.selfdrived.selfdrived": 16.0, - "selfdrive.car.card": 26.0, + "openpilot.selfdrive.controls.controlsd": 16.0, + "openpilot.selfdrive.selfdrived.selfdrived": 16.0, + "openpilot.selfdrive.car.card": 26.0, "./loggerd": 14.0, "./encoderd": 13.0, "./camerad": 10.0, - "selfdrive.controls.plannerd": 8.0, - "selfdrive.ui.ui": 40.0, - "system.sensord.sensord": 13.0, - "selfdrive.controls.radard": 2.0, - "selfdrive.modeld.modeld": 22.0, - "selfdrive.modeld.dmonitoringmodeld": 18.0, - "system.hardware.hardwared": 4.0, - "selfdrive.locationd.calibrationd": 2.0, - "selfdrive.locationd.torqued": 5.0, - "selfdrive.locationd.locationd": 25.0, - "selfdrive.locationd.paramsd": 9.0, - "selfdrive.locationd.lagd": 11.0, - "selfdrive.ui.soundd": 3.0, - "selfdrive.ui.feedback.feedbackd": 1.0, - "selfdrive.monitoring.dmonitoringd": 4.0, - "system.proclogd": 7.0, - "system.logmessaged": 1.0, - "system.tombstoned": 0, - "system.journald": 1.0, - "system.micd": 5.0, - "system.timed": 0, - "selfdrive.pandad.pandad": 0, - "system.loggerd.uploader": 15.0, - "system.loggerd.deleter": 1.0, + "openpilot.selfdrive.controls.plannerd": 8.0, + "openpilot.selfdrive.ui.ui": 40.0, + "openpilot.system.sensord.sensord": 13.0, + "openpilot.selfdrive.controls.radard": 2.0, + "openpilot.selfdrive.modeld.modeld": 22.0, + "openpilot.selfdrive.modeld.dmonitoringmodeld": 18.0, + "openpilot.system.hardware.hardwared": 4.0, + "openpilot.selfdrive.locationd.calibrationd": 2.0, + "openpilot.selfdrive.locationd.torqued": 5.0, + "openpilot.selfdrive.locationd.locationd": 25.0, + "openpilot.selfdrive.locationd.paramsd": 9.0, + "openpilot.selfdrive.locationd.lagd": 11.0, + "openpilot.selfdrive.ui.soundd": 3.0, + "openpilot.selfdrive.ui.feedback.feedbackd": 1.0, + "openpilot.selfdrive.monitoring.dmonitoringd": 4.0, + "openpilot.system.proclogd": 7.0, + "openpilot.system.logmessaged": 1.0, + "openpilot.system.tombstoned": 0, + "openpilot.system.journald": 1.0, + "openpilot.system.micd": 5.0, + "openpilot.system.timed": 0, + "openpilot.selfdrive.pandad.pandad": 0, + "openpilot.system.loggerd.uploader": 15.0, + "openpilot.system.loggerd.deleter": 1.0, "./pandad": 19.0, - "system.qcomgpsd.qcomgpsd": 1.0, - "common.hardware.tici.modem": 10.0, + "openpilot.system.qcomgpsd.qcomgpsd": 1.0, + "openpilot.common.hardware.tici.modem": 10.0, } TIMINGS = { @@ -129,7 +129,7 @@ class TestOnroad: # start manager and run openpilot for TEST_DURATION proc = None try: - manager_path = os.path.join(BASEDIR, "system/manager/manager.py") + manager_path = os.path.join(BASEDIR, "openpilot/system/manager/manager.py") cls.manager_st = time.monotonic() proc = subprocess.Popen(["python", manager_path]) diff --git a/selfdrive/ui/SConscript b/selfdrive/ui/SConscript index 3d668aef8f..d187b4ca3c 100644 --- a/selfdrive/ui/SConscript +++ b/selfdrive/ui/SConscript @@ -4,8 +4,8 @@ import importlib.util Import('env', 'arch', 'common') # build the fonts -generator = File("#selfdrive/assets/fonts/process.py") -source_files = Glob("#selfdrive/assets/fonts/*.ttf") + Glob("#selfdrive/assets/fonts/*.otf") +generator = File("#openpilot/selfdrive/assets/fonts/process.py") +source_files = Glob("#openpilot/selfdrive/assets/fonts/*.ttf") + Glob("#openpilot/selfdrive/assets/fonts/*.otf") output_files = [ (f"#{Path(f.path).with_suffix('.fnt')}", f"#{Path(f.path).with_suffix('.png')}") for f in source_files diff --git a/selfdrive/ui/layouts/onboarding.py b/selfdrive/ui/layouts/onboarding.py index 4ef9c13f27..97ca89b50c 100644 --- a/selfdrive/ui/layouts/onboarding.py +++ b/selfdrive/ui/layouts/onboarding.py @@ -50,9 +50,9 @@ class TrainingGuide(Widget): threading.Thread(target=self._preload_thread, daemon=True).start() def _load_image_paths(self): - paths = [fn for fn in os.listdir(os.path.join(BASEDIR, "selfdrive/assets/training")) if re.match(r'^step\d*\.png$', fn)] + paths = [fn for fn in os.listdir(os.path.join(BASEDIR, "openpilot/selfdrive/assets/training")) if re.match(r'^step\d*\.png$', fn)] paths = sorted(paths, key=lambda x: int(re.search(r'\d+', x).group())) - self._image_paths = [os.path.join(BASEDIR, "selfdrive/assets/training", fn) for fn in paths] + self._image_paths = [os.path.join(BASEDIR, "openpilot/selfdrive/assets/training", fn) for fn in paths] def _preload_thread(self): # PNG loading is slow in raylib, so we preload in a thread and upload to GPU in main thread diff --git a/selfdrive/ui/layouts/settings/device.py b/selfdrive/ui/layouts/settings/device.py index 0930616e19..aa15899ac2 100644 --- a/selfdrive/ui/layouts/settings/device.py +++ b/selfdrive/ui/layouts/settings/device.py @@ -185,7 +185,7 @@ class DeviceLayout(Widget): def _on_regulatory(self): if not self._fcc_dialog: - self._fcc_dialog = HtmlModal(os.path.join(BASEDIR, "selfdrive/assets/offroad/fcc.html")) + self._fcc_dialog = HtmlModal(os.path.join(BASEDIR, "openpilot/selfdrive/assets/offroad/fcc.html")) gui_app.push_widget(self._fcc_dialog) def _on_review_training_guide(self): diff --git a/selfdrive/ui/layouts/settings/software.py b/selfdrive/ui/layouts/settings/software.py index 3bf271052d..3b05eef549 100644 --- a/selfdrive/ui/layouts/settings/software.py +++ b/selfdrive/ui/layouts/settings/software.py @@ -158,12 +158,12 @@ class SoftwareLayout(Widget): # Start checking for updates self._waiting_for_updater = True self._waiting_start_ts = time.monotonic() - os.system("pkill -SIGUSR1 -f system.updated.updated") + os.system("pkill -SIGUSR1 -f openpilot.system.updated.updated") else: # Start downloading self._waiting_for_updater = True self._waiting_start_ts = time.monotonic() - os.system("pkill -SIGHUP -f system.updated.updated") + os.system("pkill -SIGHUP -f openpilot.system.updated.updated") def _on_uninstall(self): def handle_uninstall_confirmation(result: DialogResult): @@ -197,7 +197,7 @@ class SoftwareLayout(Widget): selection = self._branch_dialog.selection ui_state.params.put("UpdaterTargetBranch", selection, block=True) self._branch_btn.action_item.set_value(selection) - os.system("pkill -SIGUSR1 -f system.updated.updated") + os.system("pkill -SIGUSR1 -f openpilot.system.updated.updated") self._branch_dialog = None self._branch_dialog = MultiOptionDialog(tr("Select a branch"), branches, current_target, callback=handle_selection) diff --git a/selfdrive/ui/mici/layouts/settings/device.py b/selfdrive/ui/mici/layouts/settings/device.py index fd8bacf441..0adcf53752 100644 --- a/selfdrive/ui/mici/layouts/settings/device.py +++ b/selfdrive/ui/mici/layouts/settings/device.py @@ -215,5 +215,5 @@ class DeviceLayoutMici(NavScroller): def _on_regulatory(self): if not self._fcc_dialog: - self._fcc_dialog = MiciFccModal(os.path.join(BASEDIR, "selfdrive/assets/offroad/mici_fcc.html")) + self._fcc_dialog = MiciFccModal(os.path.join(BASEDIR, "openpilot/selfdrive/assets/offroad/mici_fcc.html")) gui_app.push_widget(self._fcc_dialog) diff --git a/selfdrive/ui/mici/layouts/settings/software.py b/selfdrive/ui/mici/layouts/settings/software.py index 32f20256f4..115b560cc5 100644 --- a/selfdrive/ui/mici/layouts/settings/software.py +++ b/selfdrive/ui/mici/layouts/settings/software.py @@ -103,9 +103,9 @@ class CheckUpdateButton(BigButton): def run(): if self.get_value() == "download update": - os.system("pkill -SIGHUP -f system.updated.updated") + os.system("pkill -SIGHUP -f openpilot.system.updated.updated") else: - os.system("pkill -SIGUSR1 -f system.updated.updated") + os.system("pkill -SIGUSR1 -f openpilot.system.updated.updated") threading.Thread(target=run, daemon=True).start() @@ -251,7 +251,7 @@ class TargetBranchButton(BigButton): def _on_select(self, branch: str): ui_state.params.put("UpdaterTargetBranch", branch, block=True) self.set_value(branch) - os.system("pkill -SIGUSR1 -f system.updated.updated") + os.system("pkill -SIGUSR1 -f openpilot.system.updated.updated") class SoftwareLayoutMici(NavScroller): diff --git a/selfdrive/ui/soundd.py b/selfdrive/ui/soundd.py index f8c364e2c5..901e2b56cb 100644 --- a/selfdrive/ui/soundd.py +++ b/selfdrive/ui/soundd.py @@ -85,7 +85,7 @@ class Soundd: for sound in sound_list: filename, play_count, volume = sound_list[sound] - with wave.open(BASEDIR + "/selfdrive/assets/sounds/" + filename, 'r') as wavefile: + with wave.open(BASEDIR + "/openpilot/selfdrive/assets/sounds/" + filename, 'r') as wavefile: assert wavefile.getnchannels() == 1 assert wavefile.getsampwidth() == 2 assert wavefile.getframerate() == SAMPLE_RATE diff --git a/selfdrive/ui/tests/cycle_offroad_alerts.py b/selfdrive/ui/tests/cycle_offroad_alerts.py index fcb4a72c77..c2690edf7d 100755 --- a/selfdrive/ui/tests/cycle_offroad_alerts.py +++ b/selfdrive/ui/tests/cycle_offroad_alerts.py @@ -12,7 +12,7 @@ from openpilot.system.updated.updated import parse_release_notes if __name__ == "__main__": params = Params() - with open(os.path.join(BASEDIR, "selfdrive/selfdrived/alerts_offroad.json")) as f: + with open(os.path.join(BASEDIR, "openpilot/selfdrive/selfdrived/alerts_offroad.json")) as f: offroad_alerts = json.load(f) t = 10 if len(sys.argv) < 2 else int(sys.argv[1]) diff --git a/selfdrive/ui/tests/diff/diff.py b/selfdrive/ui/tests/diff/diff.py index b861d848eb..9dd7c3bc0e 100755 --- a/selfdrive/ui/tests/diff/diff.py +++ b/selfdrive/ui/tests/diff/diff.py @@ -8,7 +8,7 @@ from concurrent.futures import ThreadPoolExecutor from pathlib import Path from openpilot.common.basedir import BASEDIR -DIFF_OUT_DIR = Path(BASEDIR) / "selfdrive" / "ui" / "tests" / "diff" / "report" +DIFF_OUT_DIR = Path(BASEDIR) / "openpilot" / "selfdrive" / "ui" / "tests" / "diff" / "report" HTML_TEMPLATE_PATH = Path(__file__).with_name("diff_template.html") diff --git a/selfdrive/ui/translations/app.pot b/selfdrive/ui/translations/app.pot index 0872ed538e..3f9f86af8e 100644 --- a/selfdrive/ui/translations/app.pot +++ b/selfdrive/ui/translations/app.pot @@ -3,141 +3,141 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" #: openpilot/selfdrive/ui/layouts/sidebar.py -#: system/ui/widgets/confirm_dialog.py -#: system/ui/widgets/html_render.py +#: openpilot/system/ui/widgets/confirm_dialog.py +#: openpilot/system/ui/widgets/html_render.py msgid "OK" msgstr "" -#: system/ui/widgets/confirm_dialog.py -#: system/ui/widgets/keyboard.py -#: system/ui/widgets/network.py -#: system/ui/widgets/option_dialog.py +#: openpilot/system/ui/widgets/confirm_dialog.py +#: openpilot/system/ui/widgets/keyboard.py +#: openpilot/system/ui/widgets/network.py +#: openpilot/system/ui/widgets/option_dialog.py msgid "Cancel" msgstr "" -#: system/ui/widgets/network.py +#: openpilot/system/ui/widgets/network.py msgid "Advanced" msgstr "" #: openpilot/selfdrive/ui/layouts/onboarding.py -#: system/ui/widgets/network.py +#: openpilot/system/ui/widgets/network.py msgid "Back" msgstr "" -#: system/ui/widgets/network.py +#: openpilot/system/ui/widgets/network.py msgid "Enter APN" msgstr "" -#: system/ui/widgets/network.py +#: openpilot/system/ui/widgets/network.py msgid "leave blank for automatic configuration" msgstr "" -#: system/ui/widgets/network.py +#: openpilot/system/ui/widgets/network.py msgid "Enter SSID" msgstr "" -#: system/ui/widgets/network.py +#: openpilot/system/ui/widgets/network.py msgid "Enter new tethering password" msgstr "" -#: system/ui/widgets/network.py +#: openpilot/system/ui/widgets/network.py msgid "Enable Tethering" msgstr "" -#: system/ui/widgets/network.py +#: openpilot/system/ui/widgets/network.py msgid "EDIT" msgstr "" -#: system/ui/widgets/network.py +#: openpilot/system/ui/widgets/network.py msgid "Tethering Password" msgstr "" -#: system/ui/widgets/network.py +#: openpilot/system/ui/widgets/network.py msgid "Enable Roaming" msgstr "" -#: system/ui/widgets/network.py +#: openpilot/system/ui/widgets/network.py msgid "Cellular Metered" msgstr "" -#: system/ui/widgets/network.py +#: openpilot/system/ui/widgets/network.py msgid "APN Setting" msgstr "" -#: system/ui/widgets/network.py +#: openpilot/system/ui/widgets/network.py msgid "Wi-Fi Network Metered" msgstr "" -#: system/ui/widgets/network.py +#: openpilot/system/ui/widgets/network.py msgid "Enter password" msgstr "" -#: system/ui/widgets/network.py +#: openpilot/system/ui/widgets/network.py msgid "Scanning Wi-Fi networks..." msgstr "" -#: system/ui/widgets/network.py +#: openpilot/system/ui/widgets/network.py msgid "CONNECTING..." msgstr "" -#: system/ui/widgets/network.py +#: openpilot/system/ui/widgets/network.py msgid "Forget" msgstr "" -#: system/ui/widgets/network.py +#: openpilot/system/ui/widgets/network.py msgid "Prevent large data uploads when on a metered cellular connection" msgstr "" -#: system/ui/widgets/network.py +#: openpilot/system/ui/widgets/network.py msgid "default" msgstr "" -#: system/ui/widgets/network.py +#: openpilot/system/ui/widgets/network.py msgid "metered" msgstr "" -#: system/ui/widgets/network.py +#: openpilot/system/ui/widgets/network.py msgid "unmetered" msgstr "" -#: system/ui/widgets/network.py +#: openpilot/system/ui/widgets/network.py msgid "Prevent large data uploads when on a metered Wi-Fi connection" msgstr "" -#: system/ui/widgets/network.py +#: openpilot/system/ui/widgets/network.py msgid "IP Address" msgstr "" -#: system/ui/widgets/network.py +#: openpilot/system/ui/widgets/network.py msgid "Hidden Network" msgstr "" #: openpilot/selfdrive/ui/layouts/sidebar.py -#: system/ui/widgets/network.py +#: openpilot/system/ui/widgets/network.py msgid "CONNECT" msgstr "" -#: system/ui/widgets/network.py +#: openpilot/system/ui/widgets/network.py msgid "Wrong password" msgstr "" -#: system/ui/widgets/network.py +#: openpilot/system/ui/widgets/network.py msgid "FORGETTING..." msgstr "" -#: system/ui/widgets/network.py +#: openpilot/system/ui/widgets/network.py msgid "for \"{}\"" msgstr "" -#: system/ui/widgets/network.py +#: openpilot/system/ui/widgets/network.py msgid "Forget Wi-Fi Network \"{}\"?" msgstr "" -#: system/ui/widgets/list_view.py +#: openpilot/system/ui/widgets/list_view.py msgid "Error" msgstr "" -#: system/ui/widgets/option_dialog.py +#: openpilot/system/ui/widgets/option_dialog.py msgid "Select" msgstr "" diff --git a/selfdrive/ui/translations/auto_translate.sh b/selfdrive/ui/translations/auto_translate.sh index 03a207ca3c..7238426c75 100755 --- a/selfdrive/ui/translations/auto_translate.sh +++ b/selfdrive/ui/translations/auto_translate.sh @@ -15,7 +15,7 @@ command -v codex >/dev/null || { } codex exec --cd "$ROOT" -c 'model_reasoning_effort="low"' --dangerously-bypass-approvals-and-sandbox "$(cat < int: diff --git a/system/camerad/webcam/README.md b/system/camerad/webcam/README.md index 2c0ce6a8af..17d7ee6d80 100644 --- a/system/camerad/webcam/README.md +++ b/system/camerad/webcam/README.md @@ -10,7 +10,7 @@ ## GO ``` -USE_WEBCAM=1 system/manager/manager.py +USE_WEBCAM=1 openpilot/system/manager/manager.py ``` - Start the car, then the UI should show the road webcam's view - Adjust and secure the webcam @@ -20,5 +20,5 @@ USE_WEBCAM=1 system/manager/manager.py Use the `ROAD_CAM` (default 0) and optional `DRIVER_CAM`, `WIDE_CAM` environment variables to specify which camera is which (ie. `ROAD_CAM=1` uses `/dev/video1`, on Ubuntu, for the road camera): ``` -USE_WEBCAM=1 ROAD_CAM=1 system/manager/manager.py +USE_WEBCAM=1 ROAD_CAM=1 openpilot/system/manager/manager.py ``` diff --git a/system/loggerd/tests/test_loggerd.py b/system/loggerd/tests/test_loggerd.py index 7a6a741aa4..5d8f635d96 100644 --- a/system/loggerd/tests/test_loggerd.py +++ b/system/loggerd/tests/test_loggerd.py @@ -54,7 +54,7 @@ class TestLoggerd: def _gen_bootlog(self): with Timeout(5): - out = subprocess.check_output("./bootlog", cwd=os.path.join(BASEDIR, "system/loggerd"), encoding='utf-8') + out = subprocess.check_output("./bootlog", cwd=os.path.join(BASEDIR, "openpilot/system/loggerd"), encoding='utf-8') log_fn = self._get_log_fn(out) diff --git a/system/manager/helpers.py b/system/manager/helpers.py index b07aec0c81..453e13184d 100644 --- a/system/manager/helpers.py +++ b/system/manager/helpers.py @@ -54,7 +54,7 @@ def save_bootlog(): def fn(tmpdir): env = os.environ.copy() env['PARAMS_COPY_PATH'] = tmpdir - subprocess.call("./bootlog", cwd=os.path.join(BASEDIR, "system/loggerd"), env=env) + subprocess.call("./bootlog", cwd=os.path.join(BASEDIR, "openpilot/system/loggerd"), env=env) shutil.rmtree(tmpdir) t = threading.Thread(target=fn, args=(tmp, )) t.daemon = True diff --git a/system/manager/process_config.py b/system/manager/process_config.py index 0bf11b4b59..655d1c4e29 100644 --- a/system/manager/process_config.py +++ b/system/manager/process_config.py @@ -71,57 +71,57 @@ def not_(*fns): return lambda *args: operator.not_(*(fn(*args) for fn in fns)) procs = [ - DaemonProcess("manage_athenad", "system.athena.manage_athenad", "AthenadPid"), + DaemonProcess("manage_athenad", "openpilot.system.athena.manage_athenad", "AthenadPid"), - NativeProcess("loggerd", "system/loggerd", ["./loggerd"], logging), - NativeProcess("encoderd", "system/loggerd", ["./encoderd"], only_onroad), - NativeProcess("stream_encoderd", "system/loggerd", ["./encoderd", "--stream"], or_(and_(livestream, not_(iscar)), notcar)), - PythonProcess("logmessaged", "system.logmessaged", always_run), + NativeProcess("loggerd", "openpilot/system/loggerd", ["./loggerd"], logging), + NativeProcess("encoderd", "openpilot/system/loggerd", ["./encoderd"], only_onroad), + NativeProcess("stream_encoderd", "openpilot/system/loggerd", ["./encoderd", "--stream"], or_(and_(livestream, not_(iscar)), notcar)), + PythonProcess("logmessaged", "openpilot.system.logmessaged", always_run), - NativeProcess("camerad", "system/camerad", ["./camerad"], or_(driverview, livestream), enabled=not WEBCAM), - PythonProcess("webcamerad", "system.camerad.webcam.camerad", driverview, enabled=WEBCAM), - PythonProcess("proclogd", "system.proclogd", only_onroad, enabled=platform.system() != "Darwin"), - PythonProcess("journald", "system.journald", only_onroad, platform.system() != "Darwin"), - PythonProcess("micd", "system.micd", iscar), - PythonProcess("timed", "system.timed", always_run, enabled=not PC), + NativeProcess("camerad", "openpilot/system/camerad", ["./camerad"], or_(driverview, livestream), enabled=not WEBCAM), + PythonProcess("webcamerad", "openpilot.system.camerad.webcam.camerad", driverview, enabled=WEBCAM), + PythonProcess("proclogd", "openpilot.system.proclogd", only_onroad, enabled=platform.system() != "Darwin"), + PythonProcess("journald", "openpilot.system.journald", only_onroad, platform.system() != "Darwin"), + PythonProcess("micd", "openpilot.system.micd", iscar), + PythonProcess("timed", "openpilot.system.timed", always_run, enabled=not PC), - PythonProcess("modeld", "selfdrive.modeld.modeld", only_onroad), - PythonProcess("dmonitoringmodeld", "selfdrive.modeld.dmonitoringmodeld", driverview, enabled=(WEBCAM or not PC)), + PythonProcess("modeld", "openpilot.selfdrive.modeld.modeld", only_onroad), + PythonProcess("dmonitoringmodeld", "openpilot.selfdrive.modeld.dmonitoringmodeld", driverview, enabled=(WEBCAM or not PC)), - PythonProcess("sensord", "system.sensord.sensord", only_onroad, enabled=not PC), - PythonProcess("ui", "selfdrive.ui.ui", always_run, restart_if_crash=True), - PythonProcess("soundd", "selfdrive.ui.soundd", driverview), - PythonProcess("locationd", "selfdrive.locationd.locationd", only_onroad), - NativeProcess("_pandad", "selfdrive/pandad", ["./pandad"], always_run, enabled=False), - PythonProcess("calibrationd", "selfdrive.locationd.calibrationd", only_onroad), - PythonProcess("torqued", "selfdrive.locationd.torqued", only_onroad), - PythonProcess("controlsd", "selfdrive.controls.controlsd", and_(not_joystick, iscar)), - PythonProcess("joystickd", "tools.joystick.joystickd", or_(joystick, notcar)), - PythonProcess("selfdrived", "selfdrive.selfdrived.selfdrived", only_onroad), - PythonProcess("card", "selfdrive.car.card", only_onroad), - PythonProcess("deleter", "system.loggerd.deleter", always_run), - PythonProcess("dmonitoringd", "selfdrive.monitoring.dmonitoringd", driverview, enabled=(WEBCAM or not PC)), - PythonProcess("qcomgpsd", "system.qcomgpsd.qcomgpsd", qcomgps, enabled=TICI), - PythonProcess("pandad", "selfdrive.pandad.pandad", always_run), - PythonProcess("paramsd", "selfdrive.locationd.paramsd", only_onroad), - PythonProcess("lagd", "selfdrive.locationd.lagd", only_onroad), - PythonProcess("ubloxd", "system.ubloxd.ubloxd", ublox, enabled=TICI), - PythonProcess("pigeond", "system.ubloxd.pigeond", ublox, enabled=TICI), - PythonProcess("plannerd", "selfdrive.controls.plannerd", not_long_maneuver), - PythonProcess("maneuversd", "tools.longitudinal_maneuvers.maneuversd", long_maneuver), - PythonProcess("lateral_maneuversd", "tools.lateral_maneuvers.lateral_maneuversd", lat_maneuver), - PythonProcess("radard", "selfdrive.controls.radard", only_onroad), - PythonProcess("hardwared", "system.hardware.hardwared", always_run), - PythonProcess("modem", "common.hardware.tici.modem", always_run, enabled=TICI), - PythonProcess("tombstoned", "system.tombstoned", always_run, enabled=not PC), - PythonProcess("updated", "system.updated.updated", only_offroad, enabled=not PC), - PythonProcess("uploader", "system.loggerd.uploader", always_run), - PythonProcess("feedbackd", "selfdrive.ui.feedback.feedbackd", only_onroad), + PythonProcess("sensord", "openpilot.system.sensord.sensord", only_onroad, enabled=not PC), + PythonProcess("ui", "openpilot.selfdrive.ui.ui", always_run, restart_if_crash=True), + PythonProcess("soundd", "openpilot.selfdrive.ui.soundd", driverview), + PythonProcess("locationd", "openpilot.selfdrive.locationd.locationd", only_onroad), + NativeProcess("_pandad", "openpilot/selfdrive/pandad", ["./pandad"], always_run, enabled=False), + PythonProcess("calibrationd", "openpilot.selfdrive.locationd.calibrationd", only_onroad), + PythonProcess("torqued", "openpilot.selfdrive.locationd.torqued", only_onroad), + PythonProcess("controlsd", "openpilot.selfdrive.controls.controlsd", and_(not_joystick, iscar)), + PythonProcess("joystickd", "openpilot.tools.joystick.joystickd", or_(joystick, notcar)), + PythonProcess("selfdrived", "openpilot.selfdrive.selfdrived.selfdrived", only_onroad), + PythonProcess("card", "openpilot.selfdrive.car.card", only_onroad), + PythonProcess("deleter", "openpilot.system.loggerd.deleter", always_run), + PythonProcess("dmonitoringd", "openpilot.selfdrive.monitoring.dmonitoringd", driverview, enabled=(WEBCAM or not PC)), + PythonProcess("qcomgpsd", "openpilot.system.qcomgpsd.qcomgpsd", qcomgps, enabled=TICI), + PythonProcess("pandad", "openpilot.selfdrive.pandad.pandad", always_run), + PythonProcess("paramsd", "openpilot.selfdrive.locationd.paramsd", only_onroad), + PythonProcess("lagd", "openpilot.selfdrive.locationd.lagd", only_onroad), + PythonProcess("ubloxd", "openpilot.system.ubloxd.ubloxd", ublox, enabled=TICI), + PythonProcess("pigeond", "openpilot.system.ubloxd.pigeond", ublox, enabled=TICI), + PythonProcess("plannerd", "openpilot.selfdrive.controls.plannerd", not_long_maneuver), + PythonProcess("maneuversd", "openpilot.tools.longitudinal_maneuvers.maneuversd", long_maneuver), + PythonProcess("lateral_maneuversd", "openpilot.tools.lateral_maneuvers.lateral_maneuversd", lat_maneuver), + PythonProcess("radard", "openpilot.selfdrive.controls.radard", only_onroad), + PythonProcess("hardwared", "openpilot.system.hardware.hardwared", always_run), + PythonProcess("modem", "openpilot.common.hardware.tici.modem", always_run, enabled=TICI), + PythonProcess("tombstoned", "openpilot.system.tombstoned", always_run, enabled=not PC), + PythonProcess("updated", "openpilot.system.updated.updated", only_offroad, enabled=not PC), + PythonProcess("uploader", "openpilot.system.loggerd.uploader", always_run), + PythonProcess("feedbackd", "openpilot.selfdrive.ui.feedback.feedbackd", only_onroad), # debug procs NativeProcess("bridge", "openpilot/cereal/messaging", ["./bridge"], notcar), - PythonProcess("webrtcd", "system.webrtc.webrtcd", or_(and_(livestream, not_(iscar)), notcar)), - PythonProcess("joystick", "tools.joystick.joystick_control", and_(joystick, iscar)), + PythonProcess("webrtcd", "openpilot.system.webrtc.webrtcd", or_(and_(livestream, not_(iscar)), notcar)), + PythonProcess("joystick", "openpilot.tools.joystick.joystick_control", and_(joystick, iscar)), ] managed_processes = {p.name: p for p in procs} diff --git a/system/tombstoned.py b/system/tombstoned.py index 349a71cc19..7741a923cd 100755 --- a/system/tombstoned.py +++ b/system/tombstoned.py @@ -104,7 +104,7 @@ def report_tombstone_apport(fn): # Try to find first entry in openpilot, fall back to first line for line in stacktrace_s: - if "at selfdrive/" in line: + if "at openpilot/selfdrive/" in line or "at selfdrive/" in line: crash_function = line found = True break diff --git a/system/ui/README.md b/system/ui/README.md index 79a4dd32ea..3624c8d1ce 100644 --- a/system/ui/README.md +++ b/system/ui/README.md @@ -15,6 +15,6 @@ Quick start: * https://electronstudio.github.io/raylib-python-cffi/README.html#quickstart Style guide: -* All graphical elements should subclass [`Widget`](/system/ui/widgets/__init__.py). +* All graphical elements should subclass [`Widget`](/openpilot/system/ui/widgets/__init__.py). * Prefer a stateful widget over a function for easy migration from QT * All internal class variables and functions should be prefixed with `_` diff --git a/system/ui/lib/multilang.py b/system/ui/lib/multilang.py index 06c54f6e9f..2305404679 100644 --- a/system/ui/lib/multilang.py +++ b/system/ui/lib/multilang.py @@ -10,7 +10,7 @@ try: except ImportError: Params = None -SYSTEM_UI_DIR = os.path.join(BASEDIR, "system", "ui") +SYSTEM_UI_DIR = os.path.join(BASEDIR, "openpilot/system", "ui") UI_DIR = files("openpilot.selfdrive.ui") TRANSLATIONS_DIR = UI_DIR.joinpath("translations") LANGUAGES_FILE = TRANSLATIONS_DIR.joinpath("languages.json") diff --git a/system/updated/updated.py b/system/updated/updated.py index affacd0f2d..c8f45fdb56 100755 --- a/system/updated/updated.py +++ b/system/updated/updated.py @@ -220,7 +220,7 @@ def handle_agnos_update() -> None: cloudlog.info(f"Beginning background installation for AGNOS {updated_version}") set_offroad_alert("Offroad_NeosUpdate", True) - manifest_path = os.path.join(OVERLAY_MERGED, "system/hardware/tici/agnos.json") + manifest_path = os.path.join(OVERLAY_MERGED, "openpilot/system/hardware/tici/agnos.json") target_slot_number = get_target_slot_number() flash_agnos_update(manifest_path, target_slot_number, cloudlog) set_offroad_alert("Offroad_NeosUpdate", False) @@ -309,7 +309,7 @@ class Updater: try: branch = self.get_branch(basedir) commit = self.get_commit_hash(basedir)[:7] - with open(os.path.join(basedir, "common", "version.h")) as f: + with open(os.path.join(basedir, "openpilot", "common", "version.h")) as f: version = f.read().split('"')[1] commit_unix_ts = run(["git", "show", "-s", "--format=%ct", "HEAD"], basedir).rstrip() diff --git a/tools/CTF.md b/tools/CTF.md index 609c82ad5a..b8acc46fef 100644 --- a/tools/CTF.md +++ b/tools/CTF.md @@ -6,15 +6,15 @@ Welcome to the first part of the comma CTF! * everything you'll need to find the flags is in the openpilot repo * grep is also your friend * first, [setup](https://github.com/commaai/openpilot/tree/master/tools#setup-your-pc) your PC - * read the docs & checkout out the tools in tools/ + * read the docs & checkout out the tools in openpilot/tools/ * tip: once you get the replay and UI up, start by familiarizing yourself with seeking in replay getting started ```bash # start the route replay -cd tools/replay +cd openpilot/tools/replay ./replay '0c7f0c7f0c7f0c7f|2021-10-13--13-00-00' --dcam --ecam # start the UI in another terminal -selfdrive/ui/ui +openpilot/selfdrive/ui/ui ``` diff --git a/tools/README.md b/tools/README.md index 1ea42bbe1d..522bb38868 100644 --- a/tools/README.md +++ b/tools/README.md @@ -18,7 +18,7 @@ git clone https://github.com/commaai/openpilot.git **2. Run the setup script** ``` bash cd openpilot -tools/op.sh setup +openpilot/tools/op.sh setup ``` **3. Activate a Python shell** @@ -41,7 +41,7 @@ Follow [these instructions](https://docs.microsoft.com/en-us/windows/wsl/install **NOTE**: If you are running WSL 2 and experiencing performance issues with the UI or simulator, you may need to explicitly enable hardware acceleration by setting `GALLIUM_DRIVER=d3d12` before commands. Add `export GALLIUM_DRIVER=d3d12` to your `~/.bashrc` file to make it automatic for future sessions. ## CTF -Learn about the openpilot ecosystem and tools by playing our [CTF](/tools/CTF.md). +Learn about the openpilot ecosystem and tools by playing our [CTF](/openpilot/tools/CTF.md). ## Directory Structure diff --git a/tools/cabana/SConscript b/tools/cabana/SConscript index 2bc8675339..92e95d3cc2 100644 --- a/tools/cabana/SConscript +++ b/tools/cabana/SConscript @@ -60,7 +60,7 @@ qt_flags = [ "-DQT_MESSAGELOGCONTEXT", ] qt_env['CXXFLAGS'] += qt_flags -qt_env['LIBPATH'] += ['#selfdrive/ui', ] +qt_env['LIBPATH'] += ['#openpilot/selfdrive/ui', ] qt_env['LIBS'] = qt_libs base_frameworks = qt_env['FRAMEWORKS'] @@ -112,8 +112,8 @@ cabana_env.Program('_cabana', ['cabana.cc', cabana_lib, assets], LIBS=cabana_lib if GetOption('extras'): cabana_env.Program('tests/test_cabana', ['tests/test_runner.cc', 'tests/test_cabana.cc', cabana_lib], LIBS=[cabana_libs]) -output_json_file = 'tools/cabana/dbc/car_fingerprint_to_dbc.json' +output_json_file = 'openpilot/tools/cabana/dbc/car_fingerprint_to_dbc.json' generate_dbc = cabana_env.Command('#' + output_json_file, ['dbc/generate_dbc_json.py'], - "python3 tools/cabana/dbc/generate_dbc_json.py --out " + output_json_file) -cabana_env.Depends(generate_dbc, ["#common", '#opendbc_repo', "#openpilot/cereal", "#msgq_repo"]) + "python3 openpilot/tools/cabana/dbc/generate_dbc_json.py --out " + output_json_file) +cabana_env.Depends(generate_dbc, ["#openpilot/common", '#opendbc_repo', "#openpilot/cereal", "#msgq_repo"]) diff --git a/tools/cabana/cabana b/tools/cabana/cabana index e175633534..a51b395090 100755 --- a/tools/cabana/cabana +++ b/tools/cabana/cabana @@ -33,6 +33,6 @@ fi # Build _cabana cd "$ROOT" -scons tools/cabana/_cabana openpilot/cereal/messaging/bridge +scons openpilot/tools/cabana/_cabana openpilot/cereal/messaging/bridge exec "$DIR/_cabana" "$@" diff --git a/tools/cabana/streams/replaystream.cc b/tools/cabana/streams/replaystream.cc index f42bf2601c..b00c6e52c6 100644 --- a/tools/cabana/streams/replaystream.cc +++ b/tools/cabana/streams/replaystream.cc @@ -68,7 +68,7 @@ bool ReplayStream::loadRoute(const std::string &route, const std::string &data_d QString message; if (auth_content.empty()) { message = "Authentication Required. Please run the following command to authenticate:\n\n" - "python3 tools/lib/auth.py\n\n" + "python3 openpilot/tools/lib/auth.py\n\n" "This will grant access to routes from your comma account."; } else { message = tr("Access Denied. You do not have permission to access route:\n\n%1\n\n" diff --git a/tools/cabana/streams/routes.cc b/tools/cabana/streams/routes.cc index 1e69a45cea..e3e5cb1b6e 100644 --- a/tools/cabana/streams/routes.cc +++ b/tools/cabana/streams/routes.cc @@ -88,7 +88,7 @@ void RoutesDialog::parseDeviceList(const QString &json, bool success, int error_ device_list_->addItem(dongle_id, dongle_id); } } else { - QMessageBox::warning(this, tr("Error"), error_code == 401 ? tr("Unauthorized. Authenticate with tools/lib/auth.py") : tr("Network error")); + QMessageBox::warning(this, tr("Error"), error_code == 401 ? tr("Unauthorized. Authenticate with openpilot/tools/lib/auth.py") : tr("Network error")); reject(); } } diff --git a/tools/car_porting/README.md b/tools/car_porting/README.md index 77492035ca..3766978e97 100644 --- a/tools/car_porting/README.md +++ b/tools/car_porting/README.md @@ -1,4 +1,4 @@ -# tools/car_porting +# openpilot/tools/car_porting Check out [this blog post](https://blog.comma.ai/how-to-write-a-car-port-for-openpilot/) for a high-level overview of porting a car. @@ -6,46 +6,46 @@ Check out [this blog post](https://blog.comma.ai/how-to-write-a-car-port-for-ope Testing car ports in your car is very time-consuming. Check out these utilities to do basic checks on your work before running it in your car. -### [Cabana](/tools/cabana/README.md) +### [Cabana](/openpilot/tools/cabana/README.md) View your car's CAN signals through DBC files, which openpilot uses to parse and create messages that talk to the car. Example: ```bash -> tools/cabana/cabana '1bbe6bf2d62f58a8|2022-07-14--17-11-43' +> openpilot/tools/cabana/cabana '1bbe6bf2d62f58a8|2022-07-14--17-11-43' ``` -### [tools/car_porting/auto_fingerprint.py](/tools/car_porting/auto_fingerprint.py) +### [openpilot/tools/car_porting/auto_fingerprint.py](/openpilot/tools/car_porting/auto_fingerprint.py) Given a route and platform, automatically inserts FW fingerprints from the platform into the correct place in fingerprints.py Example: ```bash -> python3 tools/car_porting/auto_fingerprint.py '1bbe6bf2d62f58a8|2022-07-14--17-11-43' 'OUTBACK' +> python3 openpilot/tools/car_porting/auto_fingerprint.py '1bbe6bf2d62f58a8|2022-07-14--17-11-43' 'OUTBACK' Attempting to add fw version for: OUTBACK ``` -### [selfdrive/car/tests/test_car_interfaces.py](/selfdrive/car/tests/test_car_interfaces.py) +### [openpilot/selfdrive/car/tests/test_car_interfaces.py](/openpilot/selfdrive/car/tests/test_car_interfaces.py) Finds common bugs for car interfaces, without even requiring a route. #### Example: Typo in signal name ```bash -> pytest selfdrive/car/tests/test_car_interfaces.py -k subaru # replace with the brand you are working on +> pytest openpilot/selfdrive/car/tests/test_car_interfaces.py -k subaru # replace with the brand you are working on ===================================================================== -FAILED selfdrive/car/tests/test_car_interfaces.py::TestCarInterfaces::test_car_interfaces_165_SUBARU_LEGACY_7TH_GEN - KeyError: 'CruiseControlOOPS' +FAILED openpilot/selfdrive/car/tests/test_car_interfaces.py::TestCarInterfaces::test_car_interfaces_165_SUBARU_LEGACY_7TH_GEN - KeyError: 'CruiseControlOOPS' ``` -### [tools/car_porting/test_car_model.py](/tools/car_porting/test_car_model.py) +### [openpilot/tools/car_porting/test_car_model.py](/openpilot/tools/car_porting/test_car_model.py) Given a route, runs most of the car interface to check for common errors like missing signals, blocked panda messages, and safety mismatches. #### Example: panda safety mismatch for gasPressed ```bash -> python3 tools/car_porting/test_car_model.py '4822a427b188122a|2023-08-14--16-22-21' +> python3 openpilot/tools/car_porting/test_car_model.py '4822a427b188122a|2023-08-14--16-22-21' ===================================================================== FAIL: test_panda_safety_carstate (__main__.CarModelTestCase.test_panda_safety_carstate) @@ -59,7 +59,7 @@ AssertionError: 1 is not false : panda safety doesn't agree with openpilot: {'ga ## Jupyter notebooks -To use these notebooks, install Jupyter within your [openpilot virtual environment](/tools/README.md). +To use these notebooks, install Jupyter within your [openpilot virtual environment](/openpilot/tools/README.md). ```bash uv pip install jupyter ipykernel @@ -71,7 +71,7 @@ Launching: jupyter notebook ``` -### [examples/subaru_steer_temp_fault.ipynb](/tools/car_porting/examples/subaru_steer_temp_fault.ipynb) +### [examples/subaru_steer_temp_fault.ipynb](/openpilot/tools/car_porting/examples/subaru_steer_temp_fault.ipynb) An example of searching through a database of segments for a specific condition, and plotting the results. @@ -79,7 +79,7 @@ An example of searching through a database of segments for a specific condition, *a plot of the steer_warning vs steering angle, where we can see it is clearly caused by a large steering angle change* -### [examples/subaru_long_accel.ipynb](/tools/car_porting/examples/subaru_long_accel.ipynb) +### [examples/subaru_long_accel.ipynb](/openpilot/tools/car_porting/examples/subaru_long_accel.ipynb) An example of plotting the response of an actuator when it is active. @@ -87,7 +87,7 @@ An example of plotting the response of an actuator when it is active. *a plot of the brake_pressure vs acceleration, where we can see it is a fairly linear response.* -### [examples/ford_vin_fingerprint.ipynb](/tools/car_porting/examples/ford_vin_fingerprint.ipynb) +### [examples/ford_vin_fingerprint.ipynb](/openpilot/tools/car_porting/examples/ford_vin_fingerprint.ipynb) In this example, we use the public comma car segments database to check if vin fingerprinting is feasible for ford. @@ -109,7 +109,7 @@ vin: 3FTTW8E31PRXXXXXX real platform: FORD MAVERICK 1ST GEN determi vin: 3FTTW8E99NRXXXXXX real platform: FORD MAVERICK 1ST GEN determined platform: mock correct: False ``` -### [examples/find_segments_with_message.ipynb](/tools/car_porting/examples/find_segments_with_message.ipynb) +### [examples/find_segments_with_message.ipynb](/openpilot/tools/car_porting/examples/find_segments_with_message.ipynb) Searches for segments where a set of given CAN message IDs are present. In the example, we search for all messages used for CAN-based ignition detection. diff --git a/tools/car_porting/test_car_model.py b/tools/car_porting/test_car_model.py index 78784a4299..20e7d136ea 100755 --- a/tools/car_porting/test_car_model.py +++ b/tools/car_porting/test_car_model.py @@ -19,7 +19,7 @@ def create_test_models_suite(routes: list[CarTestRoute]) -> unittest.TestSuite: if __name__ == "__main__": parser = argparse.ArgumentParser(description="Test any route against common issues with a new car port. " + - "Uses selfdrive/car/tests/test_models.py") + "Uses openpilot/selfdrive/car/tests/test_models.py") parser.add_argument("route_or_segment_name", help="Specify route to run tests on") parser.add_argument("--car", help="Specify car model for test route") args = parser.parse_args() diff --git a/tools/jotpluggler/SConscript b/tools/jotpluggler/SConscript index 36d709621d..3e235bb07a 100644 --- a/tools/jotpluggler/SConscript +++ b/tools/jotpluggler/SConscript @@ -83,7 +83,7 @@ def write_car_fingerprint_to_dbc_header(target, source, env): def generate_event_extractors(target, source, env): subprocess.check_call([ "python3", - "tools/jotpluggler/generate_event_extractors.py", + "openpilot/tools/jotpluggler/generate_event_extractors.py", os.path.realpath(BASEDIR), str(target[0]), ]) diff --git a/tools/jotpluggler/generate_event_extractors.py b/tools/jotpluggler/generate_event_extractors.py index 25f121f0b9..be9bd49003 100644 --- a/tools/jotpluggler/generate_event_extractors.py +++ b/tools/jotpluggler/generate_event_extractors.py @@ -275,7 +275,7 @@ class Generator: def generate(self): self.lines = [] - self.emit(0, "// Generated by tools/jotpluggler/generate_event_extractors.py; do not edit.") + self.emit(0, "// Generated by openpilot/tools/jotpluggler/generate_event_extractors.py; do not edit.") self.emit(0, "") self.emit(0, "const std::vector &static_event_fixed_paths() {") self.emit(2, "static const std::vector paths = {") diff --git a/tools/joystick/README.md b/tools/joystick/README.md index bc09688094..3ce308927c 100644 --- a/tools/joystick/README.md +++ b/tools/joystick/README.md @@ -14,7 +14,7 @@ The car must be off, and openpilot must be offroad before starting `joystick_con SSH into your comma device and start joystick_control with the following command: ```shell -tools/joystick/joystick_control.py --keyboard +openpilot/tools/joystick/joystick_control.py --keyboard ``` The available buttons and axes will print showing their key mappings. In general, the WASD keys control gas and brakes and steering torque in 5% increments. @@ -42,7 +42,7 @@ In order to use a joystick over the network, we need to run joystick_control loc ```shell # on your laptop export ZMQ=1 - tools/joystick/joystick_control.py + openpilot/tools/joystick/joystick_control.py ``` --- diff --git a/tools/lateral_maneuvers/README.md b/tools/lateral_maneuvers/README.md index 3a54bc7409..7a4c381b15 100644 --- a/tools/lateral_maneuvers/README.md +++ b/tools/lateral_maneuvers/README.md @@ -28,7 +28,7 @@ Test your vehicle's lateral control tuning with this tool. The tool will test th 8. Gather the route ID and then run the report generator. The file will be exported to the same directory: ```sh - $ python tools/lateral_maneuvers/generate_report.py 98395b7c5b27882e/000001cc--5a73bde686 + $ python openpilot/tools/lateral_maneuvers/generate_report.py 98395b7c5b27882e/000001cc--5a73bde686 processing report for KIA_EV6 plotting maneuver: step right 20mph, runs: 3 diff --git a/tools/lib/README.md b/tools/lib/README.md index af1ad0de22..17e24816ec 100644 --- a/tools/lib/README.md +++ b/tools/lib/README.md @@ -1,6 +1,6 @@ ## LogReader -Route is a class for conveniently accessing all the [logs](/system/loggerd/) from your routes. The LogReader class reads the non-video logs, i.e. rlog.bz2 and qlog.bz2. There's also a matching FrameReader class for reading the videos. +Route is a class for conveniently accessing all the [logs](/openpilot/system/loggerd/) from your routes. The LogReader class reads the non-video logs, i.e. rlog.bz2 and qlog.bz2. There's also a matching FrameReader class for reading the videos. ```python from openpilot.tools.lib.route import Route diff --git a/tools/lib/api.py b/tools/lib/api.py index f84fe75869..7fca9b320f 100644 --- a/tools/lib/api.py +++ b/tools/lib/api.py @@ -20,7 +20,7 @@ class CommaApi: resp_json = resp.json() if isinstance(resp_json, dict) and resp_json.get('error'): if resp.status_code in [401, 403]: - raise UnauthorizedError('Unauthorized. Authenticate with tools/lib/auth.py') + raise UnauthorizedError('Unauthorized. Authenticate with openpilot/tools/lib/auth.py') e = APIError(str(resp.status_code) + ":" + resp_json.get('description', str(resp_json['error']))) e.status_code = resp.status_code diff --git a/tools/longitudinal_maneuvers/README.md b/tools/longitudinal_maneuvers/README.md index 643af7fd82..96b989b555 100644 --- a/tools/longitudinal_maneuvers/README.md +++ b/tools/longitudinal_maneuvers/README.md @@ -35,7 +35,7 @@ Test your vehicle's longitudinal control tuning with this tool. The tool will te 8. Gather the route ID and then run the report generator. The file will be exported to the same directory: ```sh - $ python tools/longitudinal_maneuvers/generate_report.py 57048cfce01d9625/0000010e--5b26bc3be7 'pcm accel compensation' + $ python openpilot/tools/longitudinal_maneuvers/generate_report.py 57048cfce01d9625/0000010e--5b26bc3be7 'pcm accel compensation' processing report for LEXUS_ES_TSS2 plotting maneuver: start from stop, runs: 4 diff --git a/tools/op.sh b/tools/op.sh index ecef240b5b..3b766b61ee 100755 --- a/tools/op.sh +++ b/tools/op.sh @@ -116,7 +116,7 @@ function op_check_git() { fi echo "Checking for git lfs files..." - if [[ $(file -b $OPENPILOT_ROOT/selfdrive/modeld/models/dmonitoring_model.onnx) == "data" ]]; then + if [[ $(file -b $OPENPILOT_ROOT/openpilot/selfdrive/modeld/models/dmonitoring_model.onnx) == "data" ]]; then echo -e " ↳ [${GREEN}✔${NC}] git lfs files found." else echo -e " ↳ [${RED}✗${NC}] git lfs files not found! Run 'git lfs pull'" @@ -201,7 +201,7 @@ function op_setup() { echo "Installing dependencies..." st="$(date +%s)" - SETUP_SCRIPT="tools/setup_dependencies.sh" + SETUP_SCRIPT="openpilot/tools/setup_dependencies.sh" if ! $OPENPILOT_ROOT/$SETUP_SCRIPT; then echo -e " ↳ [${RED}✗${NC}] Dependencies installation failed!" return 1 @@ -234,7 +234,7 @@ function op_setup() { function op_auth() { op_before_cmd - op_run_command tools/lib/auth.py "$@" + op_run_command openpilot/tools/lib/auth.py "$@" } function op_activate_venv() { @@ -269,12 +269,12 @@ function op_venv() { function op_adb() { op_before_cmd - op_run_command tools/scripts/adb_ssh.sh "$@" + op_run_command openpilot/tools/scripts/adb_ssh.sh "$@" } function op_ssh() { op_before_cmd - op_run_command tools/scripts/ssh.py "$@" + op_run_command openpilot/tools/scripts/ssh.py "$@" } function op_script() { @@ -298,7 +298,7 @@ function op_check() { function op_esim() { op_before_cmd - op_run_command common/esim/esim.py "$@" + op_run_command openpilot/common/esim/esim.py "$@" } function op_build() { @@ -307,7 +307,7 @@ function op_build() { cd "$CDIR" if [[ -f "/AGNOS" ]]; then # needed on AGNOS to not run out of memory - op_run_command system/manager/build.py + op_run_command openpilot/system/manager/build.py else # scons is fine on PC op_run_command scons "$@" @@ -316,7 +316,7 @@ function op_build() { function op_juggle() { op_before_cmd - op_run_command tools/plotjuggler/juggle.py "$@" + op_run_command openpilot/tools/plotjuggler/juggle.py "$@" } function op_lint() { @@ -331,23 +331,23 @@ function op_test() { function op_replay() { op_before_cmd - op_run_command tools/replay/replay "$@" + op_run_command openpilot/tools/replay/replay "$@" } function op_cabana() { op_before_cmd - op_run_command tools/cabana/cabana "$@" + op_run_command openpilot/tools/cabana/cabana "$@" } function op_sim() { op_before_cmd - op_run_command exec tools/sim/run_bridge.py & - op_run_command exec tools/sim/launch_openpilot.sh + op_run_command exec openpilot/tools/sim/run_bridge.py & + op_run_command exec openpilot/tools/sim/launch_openpilot.sh } function op_clip() { op_before_cmd - op_run_command tools/clip/run.py "$@" + op_run_command openpilot/tools/clip/run.py "$@" } function op_switch() { diff --git a/tools/plotjuggler/README.md b/tools/plotjuggler/README.md index 9a40ac798d..efccbdc0bd 100644 --- a/tools/plotjuggler/README.md +++ b/tools/plotjuggler/README.md @@ -6,7 +6,7 @@ Once you've [set up the openpilot environment](../README.md), this command will download PlotJuggler and install our plugins: -`cd tools/plotjuggler && ./juggle.py --install` +`cd openpilot/tools/plotjuggler && ./juggle.py --install` ## Usage diff --git a/tools/plotjuggler/juggle.py b/tools/plotjuggler/juggle.py index e1143a3cd4..593192ed30 100755 --- a/tools/plotjuggler/juggle.py +++ b/tools/plotjuggler/juggle.py @@ -33,7 +33,7 @@ def print_jotpluggler_banner(): reset = "\033[0m" if purple else "" print(f"{purple}+-------------------------------------------------------------+{reset}") print(f"{purple}|{reset} JotPluggler is the future! Try it like this: {purple}|{reset}") - print(f"{purple}|{reset} ./tools/jotpluggler/jotpluggler --demo --layout tuning {purple}|{reset}") + print(f"{purple}|{reset} ./openpilot/tools/jotpluggler/jotpluggler --demo --layout tuning {purple}|{reset}") print(f"{purple}|{reset} {purple}|{reset}") print(f"{purple}|{reset} PlotJuggler will be deleted soon. {purple}|{reset}") print(f"{purple}|{reset} Missing a feature? Open an issue or post in #dev-openpilot. {purple}|{reset}") diff --git a/tools/plotjuggler/test_plotjuggler.py b/tools/plotjuggler/test_plotjuggler.py index 26bad25c3e..d55aafe9be 100644 --- a/tools/plotjuggler/test_plotjuggler.py +++ b/tools/plotjuggler/test_plotjuggler.py @@ -11,7 +11,7 @@ from openpilot.common.basedir import BASEDIR from openpilot.common.timeout import Timeout from openpilot.tools.plotjuggler.juggle import DEMO_ROUTE, install -PJ_DIR = os.path.join(BASEDIR, "tools/plotjuggler") +PJ_DIR = os.path.join(BASEDIR, "openpilot/tools/plotjuggler") class TestPlotJuggler: diff --git a/tools/replay/README.md b/tools/replay/README.md index d2beda9940..108df08935 100644 --- a/tools/replay/README.md +++ b/tools/replay/README.md @@ -8,7 +8,7 @@ Before starting a replay, you need to authenticate with your comma account using ```bash # Authenticate to access routes from your comma account: -python3 tools/lib/auth.py +python3 openpilot/tools/lib/auth.py ``` ## Replay a Remote Route @@ -16,13 +16,13 @@ You can replay a route from your comma account by specifying the route name. ```bash # Start a replay with a specific route: -tools/replay/replay +openpilot/tools/replay/replay # Example: -tools/replay/replay '5beb9b58bd12b691/0000010a--a51155e496' +openpilot/tools/replay/replay '5beb9b58bd12b691/0000010a--a51155e496' # Replay the default demo route: -tools/replay/replay --demo +openpilot/tools/replay/replay --demo ``` ## Replay a Local Route @@ -30,14 +30,14 @@ To replay a route stored locally on your machine, specify the route name and pro ```bash # Replay a local route -tools/replay/replay --data_dir="/path_to/route" +openpilot/tools/replay/replay --data_dir="/path_to/route" # Example: # If you have a local route stored at /path_to_routes with segments like: # 5beb9b58bd12b691/0000010a--a51155e496--0 # 5beb9b58bd12b691/0000010a--a51155e496--1 # You can replay it like this: -tools/replay/replay "5beb9b58bd12b691/0000010a--a51155e496" --data_dir="/path_to_routes" +openpilot/tools/replay/replay "5beb9b58bd12b691/0000010a--a51155e496" --data_dir="/path_to_routes" ``` ## Send Messages via ZMQ @@ -45,15 +45,15 @@ By default, replay sends messages via MSGQ. To switch to ZMQ, set the ZMQ enviro ```bash # Start replay and send messages via ZMQ: -ZMQ=1 tools/replay/replay +ZMQ=1 openpilot/tools/replay/replay ``` ## Usage For more information on available options and arguments, use the help command: ``` bash -$ tools/replay/replay -h -Usage: tools/replay/replay [options] route +$ openpilot/tools/replay/replay -h +Usage: openpilot/tools/replay/replay [options] route Mock openpilot components by publishing logged messages. Options: @@ -87,16 +87,16 @@ Arguments: To visualize the replay within the openpilot UI, run the following commands: ```bash -tools/replay/replay -cd selfdrive/ui && ./ui.py +openpilot/tools/replay/replay +cd openpilot/selfdrive/ui && ./ui.py ``` ## Work with plotjuggler If you want to use replay with plotjuggler, you can stream messages by running: ```bash -tools/replay/replay -tools/plotjuggler/juggle.py --stream +openpilot/tools/replay/replay +openpilot/tools/plotjuggler/juggle.py --stream ``` ## watch3 @@ -107,10 +107,10 @@ simply replay a route using the `--dcam` and `--ecam` flags: ```bash # start a replay -cd tools/replay && ./replay --demo --dcam --ecam +cd openpilot/tools/replay && ./replay --demo --dcam --ecam # then start watch3 -cd selfdrive/ui && ./watch3.py +cd openpilot/selfdrive/ui && ./watch3.py ``` ![](https://i.imgur.com/IeaOdAb.png) diff --git a/tools/replay/route.cc b/tools/replay/route.cc index 1560f1dce8..326d28d726 100644 --- a/tools/replay/route.cc +++ b/tools/replay/route.cc @@ -123,7 +123,7 @@ bool Route::loadFromServer() { if (json.is_object() && json["error"].is_string()) { const std::string &error = json["error"].string_value(); if (error == "unauthorized") { - rWarning(">> Unauthorized. Authenticate with tools/lib/auth.py <<"); + rWarning(">> Unauthorized. Authenticate with openpilot/tools/lib/auth.py <<"); err_ = RouteLoadError::Unauthorized; } else if (error == "not_found") { rWarning("The specified route could not be found on the server."); diff --git a/tools/replay/ui.py b/tools/replay/ui.py index 838b7ab15a..932b3f9b8c 100755 --- a/tools/replay/ui.py +++ b/tools/replay/ui.py @@ -54,7 +54,7 @@ def ui_thread(addr): rl.set_target_fps(60) # Load font - font_path = os.path.join(BASEDIR, "selfdrive/assets/fonts/JetBrainsMono-Medium.ttf") + font_path = os.path.join(BASEDIR, "openpilot/selfdrive/assets/fonts/JetBrainsMono-Medium.ttf") font = rl.load_font_ex(font_path, 32, None, 0) camera_view = CameraView("camerad", VisionStreamType.VISION_STREAM_ROAD) diff --git a/tools/scripts/cpu_usage_stat.py b/tools/scripts/cpu_usage_stat.py index 5b72eacc65..902df1c778 100755 --- a/tools/scripts/cpu_usage_stat.py +++ b/tools/scripts/cpu_usage_stat.py @@ -8,7 +8,7 @@ System tools like top/htop can only show current cpu usage values, so I write th Calculate minumium/maximum/accumulated_average cpu usage as long term inspections. Monitor multiple processes simuteneously. Sample usage: - root@localhost:/data/openpilot$ python tools/scripts/cpu_usage_stat.py pandad,ubloxd + root@localhost:/data/openpilot$ python openpilot/tools/scripts/cpu_usage_stat.py pandad,ubloxd ('Add monitored proc:', './pandad') ('Add monitored proc:', 'python locationd/ubloxd.py') pandad: 1.96%, min: 1.96%, max: 1.96%, acc: 1.96% diff --git a/tools/scripts/get_fingerprint.py b/tools/scripts/get_fingerprint.py index 1cdf8534d9..1e5e8eca5a 100755 --- a/tools/scripts/get_fingerprint.py +++ b/tools/scripts/get_fingerprint.py @@ -4,7 +4,7 @@ # Instructions: # - connect to a Panda -# - run selfdrive/pandad/pandad +# - run openpilot/selfdrive/pandad/pandad # - launching this script # Note: it's very important that the car is in stock mode, in order to collect a complete fingerprint # - since some messages are published at low frequency, keep this script running for at least 30s, diff --git a/tools/scripts/profiling/snapdragon/README.md b/tools/scripts/profiling/snapdragon/README.md index f56ca182a7..383d83ba9b 100644 --- a/tools/scripts/profiling/snapdragon/README.md +++ b/tools/scripts/profiling/snapdragon/README.md @@ -4,10 +4,10 @@ snapdragon profiler * download from https://developer.qualcomm.com/software/snapdragon-profiler/tools-archive (need a qc developer account) * choose v2021.5 (verified working with 24.04 dev environment) -* unzip to selfdrive/debug/profiling/snapdragon/SnapdragonProfiler +* unzip to openpilot/selfdrive/debug/profiling/snapdragon/SnapdragonProfiler * run ```./setup-profiler.sh``` * run ```./setup-agnos.sh``` -* run ```selfdrive/debug/adb.sh``` on device +* run ```openpilot/selfdrive/debug/adb.sh``` on device * run the ```adb connect xxx``` command that was given to you on local pc * cd to SnapdragonProfiler and run ```./run_sdp.sh``` * connect to device -> choose device you just setup diff --git a/tools/scripts/ssh.py b/tools/scripts/ssh.py index 33eac4081d..86e86c7eed 100755 --- a/tools/scripts/ssh.py +++ b/tools/scripts/ssh.py @@ -14,7 +14,7 @@ if __name__ == "__main__": parser.add_argument("device", help="device name or dongle id") parser.add_argument("--host", help="ssh jump server host", default="ssh.comma.ai") parser.add_argument("--port", help="ssh jump server port", default=22, type=int) - parser.add_argument("--key", help="ssh key", default=os.path.join(BASEDIR, "common/hardware/tici/id_rsa")) + parser.add_argument("--key", help="ssh key", default=os.path.join(BASEDIR, "openpilot/common/hardware/tici/id_rsa")) parser.add_argument("--debug", help="enable debug output", action="store_true") args = parser.parse_args() diff --git a/tools/setup.sh b/tools/setup.sh index dafd466ef9..1437a1d686 100755 --- a/tools/setup.sh +++ b/tools/setup.sh @@ -121,10 +121,10 @@ function git_clone() { function install_with_op() { cd $OPENPILOT_ROOT - $OPENPILOT_ROOT/tools/op.sh install - $OPENPILOT_ROOT/tools/op.sh post-commit + $OPENPILOT_ROOT/openpilot/tools/op.sh install + $OPENPILOT_ROOT/openpilot/tools/op.sh post-commit - if ! $OPENPILOT_ROOT/tools/op.sh setup; then + if ! $OPENPILOT_ROOT/openpilot/tools/op.sh setup; then echo -e "\n[${RED}✗${NC}] failed to install openpilot!" return 1 fi diff --git a/tools/setup_dependencies.sh b/tools/setup_dependencies.sh index 6cfd75ce17..80f3ac4e45 100755 --- a/tools/setup_dependencies.sh +++ b/tools/setup_dependencies.sh @@ -2,7 +2,7 @@ set -e DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" -ROOT="$(cd "$DIR/../" && pwd)" +ROOT="$(git -C "$DIR" rev-parse --show-toplevel)" function retry() { local attempts=$1 diff --git a/tools/sim/README.md b/tools/sim/README.md index f6ddde2580..b3e60a119b 100644 --- a/tools/sim/README.md +++ b/tools/sim/README.md @@ -7,7 +7,7 @@ openpilot implements a [bridge](run_bridge.py) that allows it to run in the [Met First, start openpilot. ``` bash # Run locally -./tools/sim/launch_openpilot.sh +./openpilot/tools/sim/launch_openpilot.sh ``` ## Bridge usage @@ -44,7 +44,7 @@ options: ## MetaDrive ### Launching Metadrive -Start bridge processes located in tools/sim: +Start bridge processes located in openpilot/tools/sim: ``` bash ./run_bridge.py ``` \ No newline at end of file diff --git a/tools/sim/tests/test_sim_bridge.py b/tools/sim/tests/test_sim_bridge.py index 0b3650e0a3..f93cc2ef50 100644 --- a/tools/sim/tests/test_sim_bridge.py +++ b/tools/sim/tests/test_sim_bridge.py @@ -9,7 +9,7 @@ from openpilot.cereal import messaging from openpilot.common.basedir import BASEDIR from openpilot.tools.sim.bridge.common import QueueMessageType -SIM_DIR = os.path.join(BASEDIR, "tools/sim") +SIM_DIR = os.path.join(BASEDIR, "openpilot/tools/sim") class TestSimBridgeBase: @classmethod From 5edc0bd89d0830bc1ac86ee923d1d08d2915b770 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Sun, 21 Jun 2026 18:49:46 -0700 Subject: [PATCH 076/151] mv root dirs into nested openpilot (#38219) --- .gitattributes | 4 ++-- .gitignore | 12 ++++++------ openpilot/common | 1 - {common => openpilot/common}/SConscript | 0 {common => openpilot/common}/__init__.py | 0 {common => openpilot/common}/api.py | 0 {common => openpilot/common}/basedir.py | 2 +- {common => openpilot/common}/constants.py | 0 {common => openpilot/common}/esim/__init__.py | 0 {common => openpilot/common}/esim/base.py | 0 {common => openpilot/common}/esim/esim.py | 0 .../common}/esim/gsma_ci_bundle.pem | 0 {common => openpilot/common}/esim/lpa.py | 0 {common => openpilot/common}/file_chunker.py | 0 {common => openpilot/common}/filter_simple.py | 0 {common => openpilot/common}/git.py | 0 {common => openpilot/common}/gpio.py | 0 {common => openpilot/common}/gps.py | 0 {common => openpilot/common}/hardware/__init__.py | 0 {common => openpilot/common}/hardware/base.h | 0 {common => openpilot/common}/hardware/base.py | 0 {common => openpilot/common}/hardware/hw.h | 0 {common => openpilot/common}/hardware/hw.py | 0 .../common}/hardware/pc/__init__.py | 0 {common => openpilot/common}/hardware/pc/hardware.h | 0 .../common}/hardware/pc/hardware.py | 0 .../common}/hardware/tici/__init__.py | 0 .../common}/hardware/tici/agnos.json | 0 {common => openpilot/common}/hardware/tici/agnos.py | 0 .../common}/hardware/tici/all-partitions.json | 0 .../common}/hardware/tici/amplifier.py | 0 .../common}/hardware/tici/hardware.h | 0 .../common}/hardware/tici/hardware.py | 0 {common => openpilot/common}/hardware/tici/id_rsa | 0 {common => openpilot/common}/hardware/tici/modem.py | 0 {common => openpilot/common}/hardware/tici/pins.py | 0 .../common}/hardware/tici/power_monitor.py | 0 .../common}/hardware/tici/tests/__init__.py | 0 .../hardware/tici/tests/test_agnos_updater.py | 0 .../common}/hardware/tici/tests/test_amplifier.py | 0 {common => openpilot/common}/hardware/tici/updater | 0 {common => openpilot/common}/i2c.py | 0 {common => openpilot/common}/logging_extra.py | 0 {common => openpilot/common}/markdown.py | 0 {common => openpilot/common}/mock/__init__.py | 0 {common => openpilot/common}/mock/generators.py | 0 {common => openpilot/common}/parameterized.py | 0 {common => openpilot/common}/params.cc | 0 {common => openpilot/common}/params.h | 0 {common => openpilot/common}/params.py | 0 {common => openpilot/common}/params_keys.h | 0 {common => openpilot/common}/params_pyx.pyx | 0 {common => openpilot/common}/pid.py | 0 {common => openpilot/common}/prefix.h | 0 {common => openpilot/common}/prefix.py | 0 {common => openpilot/common}/queue.h | 0 {common => openpilot/common}/ratekeeper.cc | 0 {common => openpilot/common}/ratekeeper.h | 0 {common => openpilot/common}/realtime.py | 0 {common => openpilot/common}/simple_kalman.py | 0 {common => openpilot/common}/spinner.py | 0 {common => openpilot/common}/stat_live.py | 0 {common => openpilot/common}/swaglog.cc | 0 {common => openpilot/common}/swaglog.h | 0 {common => openpilot/common}/swaglog.py | 0 {common => openpilot/common}/tests/.gitignore | 0 {common => openpilot/common}/tests/__init__.py | 0 .../common}/tests/test_file_helpers.py | 0 {common => openpilot/common}/tests/test_markdown.py | 0 {common => openpilot/common}/tests/test_params.cc | 0 {common => openpilot/common}/tests/test_params.py | 0 {common => openpilot/common}/tests/test_runner.cc | 0 .../common}/tests/test_simple_kalman.py | 0 {common => openpilot/common}/tests/test_swaglog.cc | 0 {common => openpilot/common}/tests/test_util.cc | 0 {common => openpilot/common}/text_window.py | 0 {common => openpilot/common}/time_helpers.py | 0 {common => openpilot/common}/timeout.py | 0 {common => openpilot/common}/timing.h | 0 .../common}/transformations/README.md | 0 .../common}/transformations/__init__.py | 0 .../common}/transformations/camera.py | 0 .../common}/transformations/coordinates.py | 0 .../common}/transformations/model.py | 0 .../common}/transformations/orientation.py | 0 .../common}/transformations/tests/__init__.py | 0 .../transformations/tests/test_coordinates.py | 0 .../transformations/tests/test_orientation.py | 0 .../common}/transformations/transformations.py | 0 {common => openpilot/common}/util.cc | 0 {common => openpilot/common}/util.h | 0 {common => openpilot/common}/utils.py | 0 {common => openpilot/common}/version.h | 0 {common => openpilot/common}/version.py | 0 openpilot/selfdrive | 1 - {selfdrive => openpilot/selfdrive}/__init__.py | 0 .../selfdrive}/assets/.gitignore | 0 .../selfdrive}/assets/assets.qrc | 0 .../selfdrive}/assets/body/awake.gif | 0 .../selfdrive}/assets/body/sleep.gif | 0 .../selfdrive}/assets/compress-images.sh | 0 .../selfdrive}/assets/fonts/Inter-Black.ttf | 0 .../selfdrive}/assets/fonts/Inter-Bold.ttf | 0 .../selfdrive}/assets/fonts/Inter-ExtraBold.ttf | 0 .../selfdrive}/assets/fonts/Inter-ExtraLight.ttf | 0 .../selfdrive}/assets/fonts/Inter-Light.ttf | 0 .../selfdrive}/assets/fonts/Inter-Medium.ttf | 0 .../selfdrive}/assets/fonts/Inter-Regular.ttf | 0 .../selfdrive}/assets/fonts/Inter-SemiBold.ttf | 0 .../selfdrive}/assets/fonts/Inter-Thin.ttf | 0 .../assets/fonts/JetBrainsMono-Medium.ttf | 0 .../selfdrive}/assets/fonts/NotoColorEmoji.ttf | 0 .../selfdrive}/assets/fonts/process.py | 0 .../selfdrive}/assets/fonts/unifont.otf | 0 .../selfdrive}/assets/icons/arrow-right.png | 0 .../selfdrive}/assets/icons/backspace.png | 0 .../selfdrive}/assets/icons/calibration.png | 0 .../selfdrive}/assets/icons/capslock-fill.png | 0 .../selfdrive}/assets/icons/checkmark.png | 0 .../selfdrive}/assets/icons/checkmark.svg | 0 .../selfdrive}/assets/icons/chevron_right.png | 0 .../selfdrive}/assets/icons/chffr_wheel.png | 0 .../selfdrive}/assets/icons/circled_check.png | 0 .../selfdrive}/assets/icons/circled_check.svg | 0 .../selfdrive}/assets/icons/circled_slash.png | 0 .../selfdrive}/assets/icons/circled_slash.svg | 0 .../selfdrive}/assets/icons/close.png | 0 .../selfdrive}/assets/icons/close.svg | 0 .../selfdrive}/assets/icons/close2.png | 0 .../selfdrive}/assets/icons/close2.svg | 0 .../selfdrive}/assets/icons/couch.png | 0 .../selfdrive}/assets/icons/couch.svg | 0 .../assets/icons/disengage_on_accelerator.png | 0 .../assets/icons/disengage_on_accelerator.svg | 0 .../selfdrive}/assets/icons/driver_face.png | 0 .../selfdrive}/assets/icons/experimental.png | 0 .../selfdrive}/assets/icons/experimental.svg | 0 .../selfdrive}/assets/icons/experimental_grey.png | 0 .../selfdrive}/assets/icons/experimental_grey.svg | 0 .../selfdrive}/assets/icons/experimental_white.png | 0 .../selfdrive}/assets/icons/experimental_white.svg | 0 .../selfdrive}/assets/icons/eye_closed.png | 0 .../selfdrive}/assets/icons/eye_closed.svg | 0 .../selfdrive}/assets/icons/eye_open.png | 0 .../selfdrive}/assets/icons/eye_open.svg | 0 .../selfdrive}/assets/icons/eyes_crossed.png | 0 .../selfdrive}/assets/icons/eyes_open.png | 0 .../selfdrive}/assets/icons/link.png | 0 .../selfdrive}/assets/icons/lock_closed.png | 0 .../selfdrive}/assets/icons/lock_closed.svg | 0 .../selfdrive}/assets/icons/menu.png | 0 .../selfdrive}/assets/icons/metric.png | 0 .../selfdrive}/assets/icons/microphone.png | 0 .../selfdrive}/assets/icons/minus.png | 0 .../selfdrive}/assets/icons/monitoring.png | 0 .../selfdrive}/assets/icons/network.png | 0 .../selfdrive}/assets/icons/road.png | 0 .../selfdrive}/assets/icons/settings.png | 0 .../selfdrive}/assets/icons/shell.png | 0 .../selfdrive}/assets/icons/shift-fill.png | 0 .../selfdrive}/assets/icons/shift.png | 0 .../selfdrive}/assets/icons/speed_limit.png | 0 .../selfdrive}/assets/icons/triangle.png | 0 .../selfdrive}/assets/icons/triangle.svg | 0 .../selfdrive}/assets/icons/warning.png | 0 .../selfdrive}/assets/icons/wifi_strength_full.png | 0 .../selfdrive}/assets/icons/wifi_strength_full.svg | 0 .../selfdrive}/assets/icons/wifi_strength_high.png | 0 .../selfdrive}/assets/icons/wifi_strength_high.svg | 0 .../selfdrive}/assets/icons/wifi_strength_low.png | 0 .../selfdrive}/assets/icons/wifi_strength_low.svg | 0 .../assets/icons/wifi_strength_medium.png | 0 .../assets/icons/wifi_strength_medium.svg | 0 .../selfdrive}/assets/icons/wifi_uploading.png | 0 .../selfdrive}/assets/icons/wifi_uploading.svg | 0 .../selfdrive}/assets/icons_mici/adb_short.png | 0 .../selfdrive}/assets/icons_mici/alerts_bell.png | 0 .../selfdrive}/assets/icons_mici/alerts_pill.png | 0 .../selfdrive}/assets/icons_mici/body.png | 0 .../assets/icons_mici/buttons/button_circle.png | 0 .../icons_mici/buttons/button_circle_disabled.png | 0 .../icons_mici/buttons/button_circle_pressed.png | 0 .../assets/icons_mici/buttons/button_circle_red.png | 0 .../buttons/button_circle_red_pressed.png | 0 .../assets/icons_mici/buttons/button_rectangle.png | 0 .../buttons/button_rectangle_disabled.png | 0 .../icons_mici/buttons/button_rectangle_pressed.png | 0 .../assets/icons_mici/buttons/slider_bg.png | 0 .../icons_mici/buttons/toggle_dot_disabled.png | 0 .../icons_mici/buttons/toggle_dot_enabled.png | 0 .../icons_mici/buttons/toggle_pill_disabled.png | 0 .../icons_mici/buttons/toggle_pill_enabled.png | 0 .../selfdrive}/assets/icons_mici/egpu.png | 0 .../selfdrive}/assets/icons_mici/egpu_gray.png | 0 .../assets/icons_mici/exclamation_point.png | 0 .../assets/icons_mici/experimental_mode.png | 0 .../selfdrive}/assets/icons_mici/microphone.png | 0 .../assets/icons_mici/offroad_alerts/big_alert.png | 0 .../icons_mici/offroad_alerts/big_alert_pressed.png | 0 .../icons_mici/offroad_alerts/green_wheel.png | 0 .../icons_mici/offroad_alerts/medium_alert.png | 0 .../offroad_alerts/medium_alert_pressed.png | 0 .../icons_mici/offroad_alerts/orange_warning.png | 0 .../icons_mici/offroad_alerts/red_warning.png | 0 .../icons_mici/offroad_alerts/small_alert.png | 0 .../offroad_alerts/small_alert_pressed.png | 0 .../assets/icons_mici/onroad/blind_spot_left.png | 0 .../assets/icons_mici/onroad/bookmark.png | 0 .../onroad/driver_monitoring/dm_background.png | 0 .../icons_mici/onroad/driver_monitoring/dm_cone.png | 0 .../onroad/driver_monitoring/dm_person.png | 0 .../assets/icons_mici/onroad/eye_fill.png | 0 .../assets/icons_mici/onroad/eye_orange.png | 0 .../selfdrive}/assets/icons_mici/onroad/glasses.png | 0 .../assets/icons_mici/onroad/onroad_fade.png | 0 .../assets/icons_mici/onroad/turn_signal_left.png | 0 .../selfdrive}/assets/icons_mici/settings.png | 0 .../assets/icons_mici/settings/comma_icon.png | 0 .../assets/icons_mici/settings/developer/ssh.png | 0 .../assets/icons_mici/settings/developer_icon.png | 0 .../assets/icons_mici/settings/device/cameras.png | 0 .../assets/icons_mici/settings/device/fcc_logo.png | 0 .../assets/icons_mici/settings/device/info.png | 0 .../assets/icons_mici/settings/device/lkas.png | 0 .../assets/icons_mici/settings/device/pair.png | 0 .../assets/icons_mici/settings/device/power.png | 0 .../assets/icons_mici/settings/device/reboot.png | 0 .../assets/icons_mici/settings/device/uninstall.png | 0 .../icons_mici/settings/device/up_to_date.png | 0 .../assets/icons_mici/settings/device/update.png | 0 .../assets/icons_mici/settings/device_icon.png | 0 .../assets/icons_mici/settings/firehose.png | 0 .../settings/horizontal_scroll_indicator.png | 0 .../icons_mici/settings/keyboard/backspace.png | 0 .../icons_mici/settings/keyboard/caps_lock.png | 0 .../icons_mici/settings/keyboard/caps_lower.png | 0 .../icons_mici/settings/keyboard/caps_upper.png | 0 .../assets/icons_mici/settings/keyboard/enter.png | 0 .../icons_mici/settings/keyboard/enter_disabled.png | 0 .../settings/keyboard/keyboard_background.png | 0 .../assets/icons_mici/settings/keyboard/space.png | 0 .../settings/network/cell_strength_full.png | 0 .../settings/network/cell_strength_high.png | 0 .../settings/network/cell_strength_low.png | 0 .../settings/network/cell_strength_medium.png | 0 .../settings/network/cell_strength_none.png | 0 .../settings/network/new/forget_button.png | 0 .../settings/network/new/forget_button_pressed.png | 0 .../assets/icons_mici/settings/network/new/lock.png | 0 .../icons_mici/settings/network/new/trash.png | 0 .../icons_mici/settings/network/tethering.png | 0 .../settings/network/wifi_strength_full.png | 0 .../settings/network/wifi_strength_low.png | 0 .../settings/network/wifi_strength_medium.png | 0 .../settings/network/wifi_strength_none.png | 0 .../settings/network/wifi_strength_slash.png | 0 .../assets/icons_mici/settings/software.png | 0 .../selfdrive}/assets/icons_mici/setup/cancel.png | 0 .../selfdrive}/assets/icons_mici/setup/continue.png | 0 .../assets/icons_mici/setup/continue_disabled.png | 0 .../assets/icons_mici/setup/continue_pressed.png | 0 .../icons_mici/setup/driver_monitoring/dm_check.png | 0 .../setup/driver_monitoring/dm_question.png | 0 .../assets/icons_mici/setup/factory_reset.png | 0 .../selfdrive}/assets/icons_mici/setup/green_dm.png | 0 .../assets/icons_mici/setup/green_info.png | 0 .../assets/icons_mici/setup/orange_dm.png | 0 .../assets/icons_mici/setup/red_warning.png | 0 .../assets/icons_mici/setup/reset_failed.png | 0 .../selfdrive}/assets/icons_mici/setup/restore.png | 0 .../assets/icons_mici/setup/small_button.png | 0 .../icons_mici/setup/small_button_disabled.png | 0 .../icons_mici/setup/small_button_pressed.png | 0 .../icons_mici/setup/small_slider/slider_arrow.png | 0 .../setup/small_slider/slider_bg_larger.png | 0 .../small_slider/slider_black_rounded_rectangle.png | 0 .../slider_black_rounded_rectangle_pressed.png | 0 .../small_slider/slider_green_rounded_rectangle.png | 0 .../slider_green_rounded_rectangle_pressed.png | 0 .../assets/icons_mici/setup/start_button.png | 0 .../icons_mici/setup/start_button_pressed.png | 0 .../selfdrive}/assets/icons_mici/setup/warning.png | 0 .../selfdrive}/assets/icons_mici/ssh_short.png | 0 .../assets/icons_mici/turn_intent_left.png | 0 .../selfdrive}/assets/icons_mici/wheel.png | 0 .../selfdrive}/assets/icons_mici/wheel_critical.png | 0 .../assets/images/button_continue_triangle.png | 0 .../assets/images/button_continue_triangle.svg | 0 .../selfdrive}/assets/images/button_flag.png | 0 .../selfdrive}/assets/images/button_home.png | 0 .../selfdrive}/assets/images/button_settings.png | 0 .../selfdrive}/assets/images/spinner_comma.png | 0 .../selfdrive}/assets/images/spinner_track.png | 0 .../selfdrive}/assets/offroad/fcc.html | 0 .../selfdrive}/assets/offroad/mici_fcc.html | 0 .../selfdrive}/assets/prep-svg.sh | 0 .../selfdrive}/assets/sounds/disengage.wav | 0 .../selfdrive}/assets/sounds/disengage_tizi.wav | 0 .../selfdrive}/assets/sounds/engage.wav | 0 .../selfdrive}/assets/sounds/engage_tizi.wav | 0 .../selfdrive}/assets/sounds/make_beeps.py | 0 .../selfdrive}/assets/sounds/prompt.wav | 0 .../selfdrive}/assets/sounds/prompt_distracted.wav | 0 .../selfdrive}/assets/sounds/refuse.wav | 0 .../selfdrive}/assets/sounds/warning_immediate.wav | 0 .../selfdrive}/assets/sounds/warning_soft.wav | 0 .../selfdrive}/assets/training/step0.png | 0 .../selfdrive}/assets/training/step1.png | 0 .../selfdrive}/assets/training/step10.png | 0 .../selfdrive}/assets/training/step11.png | 0 .../selfdrive}/assets/training/step12.png | 0 .../selfdrive}/assets/training/step13.png | 0 .../selfdrive}/assets/training/step14.png | 0 .../selfdrive}/assets/training/step15.png | 0 .../selfdrive}/assets/training/step16.png | 0 .../selfdrive}/assets/training/step17.png | 0 .../selfdrive}/assets/training/step18.png | 0 .../selfdrive}/assets/training/step2.png | 0 .../selfdrive}/assets/training/step3.png | 0 .../selfdrive}/assets/training/step4.png | 0 .../selfdrive}/assets/training/step5.png | 0 .../selfdrive}/assets/training/step6.png | 0 .../selfdrive}/assets/training/step7.png | 0 .../selfdrive}/assets/training/step8.png | 0 .../selfdrive}/assets/training/step9.png | 0 .../selfdrive}/car/CARS_template.md | 0 {selfdrive => openpilot/selfdrive}/car/__init__.py | 0 .../selfdrive}/car/car_specific.py | 0 {selfdrive => openpilot/selfdrive}/car/card.py | 0 {selfdrive => openpilot/selfdrive}/car/cruise.py | 0 {selfdrive => openpilot/selfdrive}/car/docs.py | 0 .../selfdrive}/car/tests/__init__.py | 0 .../selfdrive}/car/tests/big_cars_test.sh | 2 +- .../selfdrive}/car/tests/test_car_interfaces.py | 0 .../selfdrive}/car/tests/test_cruise_speed.py | 0 .../selfdrive}/car/tests/test_docs.py | 0 .../selfdrive}/car/tests/test_models.py | 0 .../selfdrive}/car/tests/test_models_segs.txt | 0 .../selfdrive}/controls/__init__.py | 0 .../selfdrive}/controls/controlsd.py | 0 .../selfdrive}/controls/lib/__init__.py | 0 .../selfdrive}/controls/lib/desire_helper.py | 0 .../selfdrive}/controls/lib/drive_helpers.py | 0 .../selfdrive}/controls/lib/latcontrol.py | 0 .../selfdrive}/controls/lib/latcontrol_angle.py | 0 .../selfdrive}/controls/lib/latcontrol_curvature.py | 0 .../selfdrive}/controls/lib/latcontrol_pid.py | 0 .../selfdrive}/controls/lib/latcontrol_torque.py | 0 .../controls/lib/lateral_mpc_lib/.gitignore | 0 .../controls/lib/lateral_mpc_lib/SConscript | 0 .../controls/lib/lateral_mpc_lib/__init__.py | 0 .../controls/lib/lateral_mpc_lib/lat_mpc.py | 0 .../selfdrive}/controls/lib/ldw.py | 0 .../selfdrive}/controls/lib/longcontrol.py | 0 .../controls/lib/longitudinal_mpc_lib/.gitignore | 0 .../controls/lib/longitudinal_mpc_lib/SConscript | 0 .../controls/lib/longitudinal_mpc_lib/__init__.py | 0 .../controls/lib/longitudinal_mpc_lib/long_mpc.py | 0 .../selfdrive}/controls/lib/longitudinal_planner.py | 0 .../selfdrive}/controls/plannerd.py | 0 .../selfdrive}/controls/radard.py | 0 .../selfdrive}/controls/tests/__init__.py | 0 .../controls/tests/test_following_distance.py | 0 .../selfdrive}/controls/tests/test_latcontrol.py | 0 .../controls/tests/test_latcontrol_torque_buffer.py | 0 .../selfdrive}/controls/tests/test_lateral_mpc.py | 0 .../selfdrive}/controls/tests/test_leads.py | 0 .../selfdrive}/controls/tests/test_longcontrol.py | 0 .../controls/tests/test_torqued_lat_accel_offset.py | 0 .../selfdrive}/locationd/SConscript | 0 .../selfdrive}/locationd/__init__.py | 0 .../selfdrive}/locationd/calibrationd.py | 0 .../selfdrive}/locationd/helpers.py | 0 .../selfdrive}/locationd/lagd.py | 0 .../selfdrive}/locationd/locationd.py | 0 .../selfdrive}/locationd/models/.gitignore | 0 .../selfdrive}/locationd/models/__init__.py | 0 .../selfdrive}/locationd/models/car_kf.py | 0 .../selfdrive}/locationd/models/constants.py | 0 .../selfdrive}/locationd/models/pose_kf.py | 0 .../selfdrive}/locationd/paramsd.py | 0 .../selfdrive}/locationd/test/__init__.py | 0 .../selfdrive}/locationd/test/test_calibrationd.py | 0 .../selfdrive}/locationd/test/test_lagd.py | 0 .../locationd/test/test_locationd_scenarios.py | 0 .../selfdrive}/locationd/test/test_paramsd.py | 0 .../selfdrive}/locationd/test/test_torqued.py | 0 .../selfdrive}/locationd/torqued.py | 0 .../selfdrive}/modeld/SConscript | 0 .../selfdrive}/modeld/__init__.py | 0 .../selfdrive}/modeld/compile_dm_warp.py | 0 .../selfdrive}/modeld/compile_modeld.py | 0 .../selfdrive}/modeld/constants.py | 0 .../selfdrive}/modeld/dmonitoringmodeld.py | 0 .../selfdrive}/modeld/fill_model_msg.py | 0 .../selfdrive}/modeld/get_model_metadata.py | 0 .../selfdrive}/modeld/helpers.py | 0 {selfdrive => openpilot/selfdrive}/modeld/modeld.py | 0 .../selfdrive}/modeld/models/README.md | 0 .../selfdrive}/modeld/models/__init__.py | 0 .../modeld/models/big_driving_supercombo.onnx | 0 .../selfdrive}/modeld/models/dmonitoring_model.onnx | 0 .../modeld/models/driving_supercombo.onnx | 0 .../selfdrive}/modeld/parse_model_outputs.py | 0 .../selfdrive}/monitoring/dmonitoringd.py | 0 .../selfdrive}/monitoring/policy.py | 0 .../selfdrive}/monitoring/test_monitoring.py | 0 .../selfdrive}/pandad/.gitignore | 0 .../selfdrive}/pandad/SConscript | 0 .../selfdrive}/pandad/__init__.py | 0 {selfdrive => openpilot/selfdrive}/pandad/main.cc | 0 {selfdrive => openpilot/selfdrive}/pandad/panda.cc | 2 +- {selfdrive => openpilot/selfdrive}/pandad/panda.h | 0 .../selfdrive}/pandad/panda_comms.h | 0 .../selfdrive}/pandad/panda_safety.cc | 0 {selfdrive => openpilot/selfdrive}/pandad/pandad.cc | 0 {selfdrive => openpilot/selfdrive}/pandad/pandad.h | 0 {selfdrive => openpilot/selfdrive}/pandad/pandad.py | 0 .../selfdrive}/pandad/pandad_api_impl.py | 0 {selfdrive => openpilot/selfdrive}/pandad/spi.cc | 0 .../selfdrive}/pandad/tests/__init__.py | 0 .../selfdrive}/pandad/tests/bootstub.panda_h7.bin | Bin .../selfdrive}/pandad/tests/test_pandad.py | 0 .../pandad/tests/test_pandad_canprotocol.cc | 0 .../selfdrive}/pandad/tests/test_pandad_loopback.py | 0 .../selfdrive}/pandad/tests/test_pandad_spi.py | 0 .../selfdrive}/selfdrived/alertmanager.py | 0 .../selfdrive}/selfdrived/alerts_offroad.json | 0 .../selfdrive}/selfdrived/events.py | 0 .../selfdrive}/selfdrived/helpers.py | 0 .../selfdrive}/selfdrived/selfdrived.py | 0 .../selfdrive}/selfdrived/state.py | 0 .../selfdrived/tests/test_alertmanager.py | 0 .../selfdrive}/selfdrived/tests/test_alerts.py | 0 .../selfdrived/tests/test_state_machine.py | 0 {selfdrive => openpilot/selfdrive}/test/.gitignore | 0 {selfdrive => openpilot/selfdrive}/test/__init__.py | 0 .../selfdrive}/test/cpp_harness.py | 0 .../selfdrive}/test/fuzzy_generation.py | 0 {selfdrive => openpilot/selfdrive}/test/helpers.py | 0 .../test/longitudinal_maneuvers/.gitignore | 0 .../test/longitudinal_maneuvers/__init__.py | 0 .../test/longitudinal_maneuvers/maneuver.py | 0 .../selfdrive}/test/longitudinal_maneuvers/plant.py | 0 .../longitudinal_maneuvers/test_longitudinal.py | 0 .../selfdrive}/test/process_replay/README.md | 0 .../selfdrive}/test/process_replay/__init__.py | 0 .../selfdrive}/test/process_replay/capture.py | 0 .../selfdrive}/test/process_replay/compare_logs.py | 0 .../selfdrive}/test/process_replay/diff_report.py | 0 .../selfdrive}/test/process_replay/migration.py | 0 .../selfdrive}/test/process_replay/model_replay.py | 0 .../test/process_replay/process_replay.py | 0 .../selfdrive}/test/process_replay/regen.py | 0 .../selfdrive}/test/process_replay/regen_all.py | 0 .../selfdrive}/test/process_replay/test_fuzzy.py | 0 .../test/process_replay/test_processes.py | 0 .../selfdrive}/test/process_replay/test_regen.py | 0 .../selfdrive}/test/process_replay/vision_meta.py | 0 .../selfdrive}/test/scons_build_test.sh | 2 +- .../selfdrive}/test/setup_device_ci.sh | 0 .../selfdrive}/test/setup_xvfb.sh | 0 .../selfdrive}/test/test_onroad.py | 0 .../selfdrive}/test/test_power_draw.py | 0 .../selfdrive}/test/update_ci_routes.py | 0 {selfdrive => openpilot/selfdrive}/ui/.gitignore | 0 {selfdrive => openpilot/selfdrive}/ui/SConscript | 0 {selfdrive => openpilot/selfdrive}/ui/__init__.py | 0 .../selfdrive}/ui/body/__init__.py | 0 .../selfdrive}/ui/body/animations.py | 0 .../selfdrive}/ui/body/layouts/__init__.py | 0 .../selfdrive}/ui/body/layouts/onroad.py | 0 .../selfdrive}/ui/feedback/feedbackd.py | 0 .../selfdrive}/ui/installer/continue_openpilot.sh | 0 .../selfdrive}/ui/installer/installer.cc | 0 .../selfdrive}/ui/installer/inter-ascii.ttf | 0 .../selfdrive}/ui/layouts/__init__.py | 0 .../selfdrive}/ui/layouts/home.py | 0 .../selfdrive}/ui/layouts/main.py | 0 .../selfdrive}/ui/layouts/onboarding.py | 0 .../selfdrive}/ui/layouts/settings/common.py | 0 .../selfdrive}/ui/layouts/settings/developer.py | 0 .../selfdrive}/ui/layouts/settings/device.py | 0 .../selfdrive}/ui/layouts/settings/firehose.py | 0 .../selfdrive}/ui/layouts/settings/settings.py | 0 .../selfdrive}/ui/layouts/settings/software.py | 0 .../selfdrive}/ui/layouts/settings/toggles.py | 0 .../selfdrive}/ui/layouts/sidebar.py | 0 .../selfdrive}/ui/lib/api_helpers.py | 0 .../selfdrive}/ui/lib/prime_state.py | 0 .../selfdrive}/ui/mici/layouts/__init__.py | 0 .../selfdrive}/ui/mici/layouts/home.py | 0 .../selfdrive}/ui/mici/layouts/main.py | 0 .../selfdrive}/ui/mici/layouts/offroad_alerts.py | 0 .../selfdrive}/ui/mici/layouts/onboarding.py | 0 .../ui/mici/layouts/settings/developer.py | 0 .../selfdrive}/ui/mici/layouts/settings/device.py | 0 .../selfdrive}/ui/mici/layouts/settings/firehose.py | 0 .../ui/mici/layouts/settings/network/__init__.py | 0 .../mici/layouts/settings/network/network_layout.py | 0 .../ui/mici/layouts/settings/network/wifi_ui.py | 0 .../selfdrive}/ui/mici/layouts/settings/settings.py | 0 .../selfdrive}/ui/mici/layouts/settings/software.py | 0 .../selfdrive}/ui/mici/layouts/settings/toggles.py | 0 .../selfdrive}/ui/mici/onroad/__init__.py | 0 .../selfdrive}/ui/mici/onroad/alert_renderer.py | 0 .../ui/mici/onroad/augmented_road_view.py | 0 .../selfdrive}/ui/mici/onroad/cameraview.py | 0 .../selfdrive}/ui/mici/onroad/confidence_ball.py | 0 .../ui/mici/onroad/driver_camera_dialog.py | 0 .../selfdrive}/ui/mici/onroad/driver_state.py | 0 .../selfdrive}/ui/mici/onroad/hud_renderer.py | 0 .../selfdrive}/ui/mici/onroad/model_renderer.py | 0 .../selfdrive}/ui/mici/onroad/torque_bar.py | 0 .../selfdrive}/ui/mici/tests/test_widget_leaks.py | 0 .../selfdrive}/ui/mici/widgets/button.py | 0 .../selfdrive}/ui/mici/widgets/dialog.py | 0 .../selfdrive}/ui/mici/widgets/pairing_dialog.py | 0 .../selfdrive}/ui/onroad/__init__.py | 0 .../selfdrive}/ui/onroad/alert_renderer.py | 0 .../selfdrive}/ui/onroad/augmented_road_view.py | 0 .../selfdrive}/ui/onroad/cameraview.py | 0 .../selfdrive}/ui/onroad/driver_camera_dialog.py | 0 .../selfdrive}/ui/onroad/driver_state.py | 0 .../selfdrive}/ui/onroad/exp_button.py | 0 .../selfdrive}/ui/onroad/hud_renderer.py | 0 .../selfdrive}/ui/onroad/model_renderer.py | 0 {selfdrive => openpilot/selfdrive}/ui/soundd.py | 0 .../selfdrive}/ui/tests/__init__.py | 0 {selfdrive => openpilot/selfdrive}/ui/tests/body.py | 0 .../selfdrive}/ui/tests/cycle_offroad_alerts.py | 0 .../selfdrive}/ui/tests/diff/diff.py | 0 .../selfdrive}/ui/tests/diff/diff_template.html | 0 .../selfdrive}/ui/tests/diff/replay.py | 0 .../selfdrive}/ui/tests/diff/replay_script.py | 0 .../selfdrive}/ui/tests/profile_onroad.py | 0 .../selfdrive}/ui/tests/test_feedbackd.py | 0 .../selfdrive}/ui/tests/test_raylib_ui.py | 0 .../selfdrive}/ui/tests/test_soundd.py | 0 .../selfdrive}/ui/tests/test_translations.py | 0 .../selfdrive}/ui/translations/app.pot | 0 .../selfdrive}/ui/translations/app_de.po | 0 .../selfdrive}/ui/translations/app_en.po | 0 .../selfdrive}/ui/translations/app_es.po | 0 .../selfdrive}/ui/translations/app_fr.po | 0 .../selfdrive}/ui/translations/app_ja.po | 0 .../selfdrive}/ui/translations/app_ko.po | 0 .../selfdrive}/ui/translations/app_pt-BR.po | 0 .../selfdrive}/ui/translations/app_th.po | 0 .../selfdrive}/ui/translations/app_tr.po | 0 .../selfdrive}/ui/translations/app_uk.po | 0 .../selfdrive}/ui/translations/app_zh-CHS.po | 0 .../selfdrive}/ui/translations/app_zh-CHT.po | 0 .../selfdrive}/ui/translations/auto_translate.sh | 0 .../selfdrive}/ui/translations/languages.json | 0 .../selfdrive}/ui/translations/potools.py | 0 .../ui/translations/update_translations.py | 0 {selfdrive => openpilot/selfdrive}/ui/ui.py | 0 {selfdrive => openpilot/selfdrive}/ui/ui_state.py | 0 {selfdrive => openpilot/selfdrive}/ui/watch3.py | 0 .../selfdrive}/ui/widgets/__init__.py | 0 .../selfdrive}/ui/widgets/exp_mode_button.py | 0 .../selfdrive}/ui/widgets/offroad_alerts.py | 0 .../selfdrive}/ui/widgets/pairing_dialog.py | 0 .../selfdrive}/ui/widgets/prime.py | 0 .../selfdrive}/ui/widgets/setup.py | 0 .../selfdrive}/ui/widgets/ssh_key.py | 0 openpilot/system | 1 - {system => openpilot/system}/__init__.py | 0 {system => openpilot/system}/athena/__init__.py | 0 {system => openpilot/system}/athena/athenad.py | 0 .../system}/athena/manage_athenad.py | 0 {system => openpilot/system}/athena/registration.py | 0 .../system}/athena/tests/__init__.py | 0 .../system}/athena/tests/helpers.py | 0 .../system}/athena/tests/test_athenad.py | 0 .../system}/athena/tests/test_athenad_ping.py | 0 .../system}/athena/tests/test_registration.py | 0 {system => openpilot/system}/camerad/SConscript | 0 {system => openpilot/system}/camerad/__init__.py | 0 .../system}/camerad/cameras/bps_blobs.h | 0 .../system}/camerad/cameras/camera_common.cc | 0 .../system}/camerad/cameras/camera_common.h | 0 .../system}/camerad/cameras/camera_qcom2.cc | 0 {system => openpilot/system}/camerad/cameras/cdm.cc | 0 {system => openpilot/system}/camerad/cameras/cdm.h | 0 {system => openpilot/system}/camerad/cameras/hw.h | 0 {system => openpilot/system}/camerad/cameras/ife.h | 0 .../system}/camerad/cameras/nv12_info.h | 0 .../system}/camerad/cameras/nv12_info.py | 0 .../system}/camerad/cameras/spectra.cc | 0 .../system}/camerad/cameras/spectra.h | 0 {system => openpilot/system}/camerad/main.cc | 0 .../system}/camerad/sensors/os04c10.cc | 0 .../system}/camerad/sensors/os04c10_registers.h | 0 .../system}/camerad/sensors/ox03c10.cc | 0 .../system}/camerad/sensors/ox03c10_registers.h | 0 .../system}/camerad/sensors/sensor.h | 0 {system => openpilot/system}/camerad/snapshot.py | 0 .../system}/camerad/test/.gitignore | 0 {system => openpilot/system}/camerad/test/debug.sh | 0 .../system}/camerad/test/icp_debug.sh | 0 .../system}/camerad/test/intercept.sh | 0 .../system}/camerad/test/stress_restart.sh | 0 .../system}/camerad/test/test_ae_gray.cc | 0 .../system}/camerad/test/test_camerad.py | 0 .../system}/camerad/webcam/README.md | 0 .../system}/camerad/webcam/camera.py | 0 .../system}/camerad/webcam/camerad.py | 0 .../system}/hardware/fan_controller.py | 0 {system => openpilot/system}/hardware/hardwared.py | 0 .../system}/hardware/power_monitoring.py | 0 .../system}/hardware/tests/__init__.py | 0 .../system}/hardware/tests/test_fan_controller.py | 0 .../system}/hardware/tests/test_power_monitoring.py | 0 .../system}/hardware/tici/agnos.json | 0 {system => openpilot/system}/journald.py | 0 {system => openpilot/system}/loggerd/.gitignore | 0 {system => openpilot/system}/loggerd/SConscript | 0 {system => openpilot/system}/loggerd/__init__.py | 0 {system => openpilot/system}/loggerd/bootlog.cc | 0 {system => openpilot/system}/loggerd/config.py | 0 {system => openpilot/system}/loggerd/deleter.py | 0 .../system}/loggerd/encoder/encoder.cc | 0 .../system}/loggerd/encoder/encoder.h | 0 .../system}/loggerd/encoder/ffmpeg_encoder.cc | 0 .../system}/loggerd/encoder/ffmpeg_encoder.h | 0 .../system}/loggerd/encoder/jpeg_encoder.cc | 0 .../system}/loggerd/encoder/jpeg_encoder.h | 0 .../system}/loggerd/encoder/v4l_encoder.cc | 0 .../system}/loggerd/encoder/v4l_encoder.h | 0 {system => openpilot/system}/loggerd/encoderd.cc | 0 {system => openpilot/system}/loggerd/logger.cc | 0 {system => openpilot/system}/loggerd/logger.h | 0 {system => openpilot/system}/loggerd/loggerd.cc | 0 {system => openpilot/system}/loggerd/loggerd.h | 0 .../system}/loggerd/tests/__init__.py | 0 .../system}/loggerd/tests/loggerd_tests_common.py | 0 .../system}/loggerd/tests/test_deleter.py | 0 .../system}/loggerd/tests/test_encoder.py | 0 .../system}/loggerd/tests/test_logger.cc | 0 .../system}/loggerd/tests/test_loggerd.py | 0 .../system}/loggerd/tests/test_runner.cc | 0 .../system}/loggerd/tests/test_uploader.py | 0 .../system}/loggerd/tests/test_zstd_writer.cc | 0 .../system}/loggerd/tests/vidc_debug.sh | 0 {system => openpilot/system}/loggerd/uploader.py | 0 .../system}/loggerd/video_writer.cc | 0 {system => openpilot/system}/loggerd/video_writer.h | 0 {system => openpilot/system}/loggerd/xattr_cache.py | 0 {system => openpilot/system}/loggerd/zstd_writer.cc | 0 {system => openpilot/system}/loggerd/zstd_writer.h | 0 {system => openpilot/system}/logmessaged.py | 0 {system => openpilot/system}/manager/__init__.py | 0 {system => openpilot/system}/manager/build.py | 0 {system => openpilot/system}/manager/helpers.py | 0 {system => openpilot/system}/manager/manager.py | 0 {system => openpilot/system}/manager/process.py | 0 .../system}/manager/process_config.py | 0 .../system}/manager/test/__init__.py | 0 .../system}/manager/test/test_manager.py | 0 {system => openpilot/system}/micd.py | 0 {system => openpilot/system}/proclogd.py | 0 {system => openpilot/system}/qcomgpsd/modemdiag.py | 0 {system => openpilot/system}/qcomgpsd/nmeaport.py | 0 {system => openpilot/system}/qcomgpsd/qcomgpsd.py | 0 {system => openpilot/system}/qcomgpsd/structs.py | 0 {system => openpilot/system}/sensord/__init__.py | 0 {system => openpilot/system}/sensord/sensord.py | 0 .../system}/sensord/sensors/__init__.py | 0 .../system}/sensord/sensors/i2c_sensor.py | 0 .../system}/sensord/sensors/lsm6ds3_accel.py | 0 .../system}/sensord/sensors/lsm6ds3_gyro.py | 0 .../system}/sensord/sensors/lsm6ds3_temp.py | 0 .../system}/sensord/tests/__init__.py | 0 .../system}/sensord/tests/test_sensord.py | 0 {system => openpilot/system}/sentry.py | 0 {system => openpilot/system}/tests/__init__.py | 0 .../system}/tests/test_logmessaged.py | 0 {system => openpilot/system}/timed.py | 0 {system => openpilot/system}/tombstoned.py | 0 .../system}/ubloxd/binary_struct.py | 0 {system => openpilot/system}/ubloxd/glonass.py | 0 {system => openpilot/system}/ubloxd/gps.py | 0 {system => openpilot/system}/ubloxd/pigeond.py | 0 .../system}/ubloxd/tests/test_pigeond.py | 0 {system => openpilot/system}/ubloxd/ubloxd.py | 0 {system => openpilot/system}/ubloxd/ubx.py | 0 {system => openpilot/system}/ui/README.md | 0 {system => openpilot/system}/ui/lib/__init__.py | 0 {system => openpilot/system}/ui/lib/application.py | 0 {system => openpilot/system}/ui/lib/egl.py | 0 {system => openpilot/system}/ui/lib/emoji.py | 0 {system => openpilot/system}/ui/lib/multilang.py | 0 .../system}/ui/lib/networkmanager.py | 0 {system => openpilot/system}/ui/lib/scroll_panel.py | 0 .../system}/ui/lib/scroll_panel2.py | 0 .../system}/ui/lib/shader_polygon.py | 0 .../ui/lib/tests/test_handle_state_change.py | 0 {system => openpilot/system}/ui/lib/text_measure.py | 0 {system => openpilot/system}/ui/lib/utils.py | 0 {system => openpilot/system}/ui/lib/wifi_manager.py | 0 {system => openpilot/system}/ui/lib/wrap_text.py | 0 {system => openpilot/system}/ui/mici_reset.py | 0 {system => openpilot/system}/ui/mici_setup.py | 0 {system => openpilot/system}/ui/mici_updater.py | 0 {system => openpilot/system}/ui/reset.py | 0 {system => openpilot/system}/ui/setup.py | 0 {system => openpilot/system}/ui/spinner.py | 0 {system => openpilot/system}/ui/text.py | 0 {system => openpilot/system}/ui/tici_reset.py | 0 {system => openpilot/system}/ui/tici_setup.py | 0 {system => openpilot/system}/ui/tici_updater.py | 0 {system => openpilot/system}/ui/updater.py | 0 {system => openpilot/system}/ui/widgets/__init__.py | 0 {system => openpilot/system}/ui/widgets/button.py | 0 .../system}/ui/widgets/confirm_dialog.py | 0 .../system}/ui/widgets/html_render.py | 0 .../system}/ui/widgets/icon_widget.py | 0 {system => openpilot/system}/ui/widgets/inputbox.py | 0 {system => openpilot/system}/ui/widgets/keyboard.py | 0 {system => openpilot/system}/ui/widgets/label.py | 0 {system => openpilot/system}/ui/widgets/layouts.py | 0 .../system}/ui/widgets/list_view.py | 0 .../system}/ui/widgets/mici_keyboard.py | 0 .../system}/ui/widgets/nav_widget.py | 0 {system => openpilot/system}/ui/widgets/network.py | 0 .../system}/ui/widgets/option_dialog.py | 0 {system => openpilot/system}/ui/widgets/scroller.py | 0 .../system}/ui/widgets/scroller_tici.py | 0 {system => openpilot/system}/ui/widgets/slider.py | 0 {system => openpilot/system}/ui/widgets/toggle.py | 0 {system => openpilot/system}/updated/common.py | 0 {system => openpilot/system}/updated/updated.py | 0 {system => openpilot/system}/webrtc/__init__.py | 0 {system => openpilot/system}/webrtc/device/video.py | 0 {system => openpilot/system}/webrtc/helpers.py | 0 {system => openpilot/system}/webrtc/schema.py | 0 .../system}/webrtc/tests/test_stream_session.py | 0 {system => openpilot/system}/webrtc/webrtcd.py | 0 openpilot/tools | 1 - {tools => openpilot/tools}/CTF.md | 0 {tools => openpilot/tools}/README.md | 0 {tools => openpilot/tools}/__init__.py | 0 {tools => openpilot/tools}/auto_source.py | 0 {tools => openpilot/tools}/cabana/.gitignore | 0 {tools => openpilot/tools}/cabana/README.md | 0 {tools => openpilot/tools}/cabana/SConscript | 0 {tools => openpilot/tools}/cabana/assets/assets.qrc | 0 .../tools}/cabana/assets/cabana-icon.png | 0 {tools => openpilot/tools}/cabana/binaryview.cc | 0 {tools => openpilot/tools}/cabana/binaryview.h | 0 {tools => openpilot/tools}/cabana/cabana | 0 {tools => openpilot/tools}/cabana/cabana.cc | 0 {tools => openpilot/tools}/cabana/cameraview.cc | 0 {tools => openpilot/tools}/cabana/cameraview.h | 0 {tools => openpilot/tools}/cabana/chart/chart.cc | 0 {tools => openpilot/tools}/cabana/chart/chart.h | 0 .../tools}/cabana/chart/chartswidget.cc | 0 .../tools}/cabana/chart/chartswidget.h | 0 .../tools}/cabana/chart/signalselector.cc | 0 .../tools}/cabana/chart/signalselector.h | 0 .../tools}/cabana/chart/sparkline.cc | 0 {tools => openpilot/tools}/cabana/chart/sparkline.h | 0 {tools => openpilot/tools}/cabana/chart/tiplabel.cc | 0 {tools => openpilot/tools}/cabana/chart/tiplabel.h | 0 {tools => openpilot/tools}/cabana/commands.cc | 0 {tools => openpilot/tools}/cabana/commands.h | 0 {tools => openpilot/tools}/cabana/dbc/dbc.cc | 0 {tools => openpilot/tools}/cabana/dbc/dbc.h | 0 {tools => openpilot/tools}/cabana/dbc/dbcfile.cc | 0 {tools => openpilot/tools}/cabana/dbc/dbcfile.h | 0 {tools => openpilot/tools}/cabana/dbc/dbcmanager.cc | 0 {tools => openpilot/tools}/cabana/dbc/dbcmanager.h | 0 .../tools}/cabana/dbc/generate_dbc_json.py | 0 {tools => openpilot/tools}/cabana/detailwidget.cc | 0 {tools => openpilot/tools}/cabana/detailwidget.h | 0 {tools => openpilot/tools}/cabana/historylog.cc | 0 {tools => openpilot/tools}/cabana/historylog.h | 0 {tools => openpilot/tools}/cabana/mainwin.cc | 0 {tools => openpilot/tools}/cabana/mainwin.h | 0 {tools => openpilot/tools}/cabana/messageswidget.cc | 0 {tools => openpilot/tools}/cabana/messageswidget.h | 0 {tools => openpilot/tools}/cabana/panda.cc | 0 {tools => openpilot/tools}/cabana/panda.h | 0 {tools => openpilot/tools}/cabana/settings.cc | 0 {tools => openpilot/tools}/cabana/settings.h | 0 {tools => openpilot/tools}/cabana/signalview.cc | 0 {tools => openpilot/tools}/cabana/signalview.h | 0 .../tools}/cabana/streams/abstractstream.cc | 0 .../tools}/cabana/streams/abstractstream.h | 0 .../tools}/cabana/streams/devicestream.cc | 0 .../tools}/cabana/streams/devicestream.h | 0 .../tools}/cabana/streams/livestream.cc | 0 .../tools}/cabana/streams/livestream.h | 0 .../tools}/cabana/streams/pandastream.cc | 0 .../tools}/cabana/streams/pandastream.h | 0 .../tools}/cabana/streams/replaystream.cc | 0 .../tools}/cabana/streams/replaystream.h | 0 {tools => openpilot/tools}/cabana/streams/routes.cc | 0 {tools => openpilot/tools}/cabana/streams/routes.h | 0 .../tools}/cabana/streams/socketcanstream.cc | 0 .../tools}/cabana/streams/socketcanstream.h | 0 {tools => openpilot/tools}/cabana/streamselector.cc | 0 {tools => openpilot/tools}/cabana/streamselector.h | 0 .../tools}/cabana/tests/test_cabana.cc | 0 .../tools}/cabana/tests/test_runner.cc | 0 .../tools}/cabana/tools/findsignal.cc | 0 .../tools}/cabana/tools/findsignal.h | 0 .../tools}/cabana/tools/findsimilarbits.cc | 0 .../tools}/cabana/tools/findsimilarbits.h | 0 .../tools}/cabana/tools/routeinfo.cc | 0 {tools => openpilot/tools}/cabana/tools/routeinfo.h | 0 .../tools}/cabana/utils/elidedlabel.cc | 0 .../tools}/cabana/utils/elidedlabel.h | 0 {tools => openpilot/tools}/cabana/utils/export.cc | 0 {tools => openpilot/tools}/cabana/utils/export.h | 0 {tools => openpilot/tools}/cabana/utils/util.cc | 0 {tools => openpilot/tools}/cabana/utils/util.h | 0 {tools => openpilot/tools}/cabana/videowidget.cc | 0 {tools => openpilot/tools}/cabana/videowidget.h | 0 {tools => openpilot/tools}/camerastream/README.md | 0 .../tools}/camerastream/compressed_vipc.py | 0 {tools => openpilot/tools}/car_porting/README.md | 0 .../tools}/car_porting/auto_fingerprint.py | 0 .../examples/find_segments_with_message.ipynb | 0 .../car_porting/examples/ford_vin_fingerprint.ipynb | 0 .../examples/hkg_canfd_gear_message.ipynb | 0 .../examples/subaru_fuzzy_fingerprint.ipynb | 0 .../car_porting/examples/subaru_long_accel.ipynb | 0 .../examples/subaru_steer_temp_fault.ipynb | 0 .../tools}/car_porting/measure_steering_accuracy.py | 0 .../tools}/car_porting/test_car_model.py | 0 {tools => openpilot/tools}/clip/run.py | 0 {tools => openpilot/tools}/jotpluggler/.gitignore | 0 {tools => openpilot/tools}/jotpluggler/SConscript | 0 {tools => openpilot/tools}/jotpluggler/app.cc | 0 {tools => openpilot/tools}/jotpluggler/app.h | 0 {tools => openpilot/tools}/jotpluggler/browser.cc | 0 {tools => openpilot/tools}/jotpluggler/camera.cc | 0 {tools => openpilot/tools}/jotpluggler/camera.h | 0 {tools => openpilot/tools}/jotpluggler/common.cc | 0 {tools => openpilot/tools}/jotpluggler/common.h | 0 .../tools}/jotpluggler/custom_series.cc | 0 {tools => openpilot/tools}/jotpluggler/dbc.h | 0 .../tools}/jotpluggler/generate_event_extractors.py | 0 .../tools}/jotpluggler/generated_dbcs/.gitignore | 0 {tools => openpilot/tools}/jotpluggler/icons.cc | 0 {tools => openpilot/tools}/jotpluggler/internal.h | 0 {tools => openpilot/tools}/jotpluggler/layout.cc | 0 {tools => openpilot/tools}/jotpluggler/layout_io.cc | 0 .../tools}/jotpluggler/layouts/.gitignore | 0 .../tools}/jotpluggler/layouts/CAN-bus-debug.json | 0 .../tools}/jotpluggler/layouts/camera-timings.json | 0 .../tools}/jotpluggler/layouts/cameras-and-map.json | 0 .../tools}/jotpluggler/layouts/can-states.json | 0 .../layouts/controls_mismatch_debug.json | 0 .../layouts/driver-monitoring-debug.json | 0 .../tools}/jotpluggler/layouts/gps.json | 0 .../tools}/jotpluggler/layouts/gps_vs_llk.json | 0 .../tools}/jotpluggler/layouts/locationd_debug.json | 0 .../tools}/jotpluggler/layouts/longitudinal.json | 0 .../jotpluggler/layouts/max-torque-debug.json | 0 .../tools}/jotpluggler/layouts/new-layout.json | 0 .../jotpluggler/layouts/system_lag_debug.json | 0 .../tools}/jotpluggler/layouts/thermal_debug.json | 0 .../jotpluggler/layouts/torque-controller.json | 0 .../tools}/jotpluggler/layouts/tuning.json | 0 .../tools}/jotpluggler/layouts/ublox-debug.json | 0 {tools => openpilot/tools}/jotpluggler/logs.cc | 0 {tools => openpilot/tools}/jotpluggler/main.cc | 0 {tools => openpilot/tools}/jotpluggler/map.cc | 0 {tools => openpilot/tools}/jotpluggler/map.h | 0 {tools => openpilot/tools}/jotpluggler/math_eval.py | 0 {tools => openpilot/tools}/jotpluggler/plot.cc | 0 {tools => openpilot/tools}/jotpluggler/render.cc | 0 {tools => openpilot/tools}/jotpluggler/runtime.cc | 0 {tools => openpilot/tools}/jotpluggler/session.cc | 0 {tools => openpilot/tools}/jotpluggler/sidebar.cc | 0 .../tools}/jotpluggler/sketch_layout.cc | 0 {tools => openpilot/tools}/jotpluggler/stream.cc | 0 {tools => openpilot/tools}/jotpluggler/util.cc | 0 {tools => openpilot/tools}/jotpluggler/util.h | 0 {tools => openpilot/tools}/joystick/README.md | 0 .../tools}/joystick/joystick_control.py | 0 {tools => openpilot/tools}/joystick/joystickd.py | 0 .../tools}/lateral_maneuvers/.gitignore | 0 .../tools}/lateral_maneuvers/README.md | 0 .../tools}/lateral_maneuvers/generate_report.py | 0 .../tools}/lateral_maneuvers/lateral_maneuversd.py | 0 {tools => openpilot/tools}/lib/README.md | 0 {tools => openpilot/tools}/lib/__init__.py | 0 {tools => openpilot/tools}/lib/api.py | 0 {tools => openpilot/tools}/lib/auth.py | 0 {tools => openpilot/tools}/lib/auth_config.py | 0 {tools => openpilot/tools}/lib/azure_container.py | 0 {tools => openpilot/tools}/lib/bootlog.py | 0 {tools => openpilot/tools}/lib/cache.py | 0 .../tools}/lib/comma_car_segments.py | 0 {tools => openpilot/tools}/lib/exceptions.py | 0 {tools => openpilot/tools}/lib/file_downloader.py | 0 {tools => openpilot/tools}/lib/file_sources.py | 0 {tools => openpilot/tools}/lib/filereader.py | 0 {tools => openpilot/tools}/lib/framereader.py | 0 {tools => openpilot/tools}/lib/github_utils.py | 0 {tools => openpilot/tools}/lib/helpers.py | 0 {tools => openpilot/tools}/lib/kbhit.py | 0 {tools => openpilot/tools}/lib/live_logreader.py | 0 {tools => openpilot/tools}/lib/log_time_series.py | 0 {tools => openpilot/tools}/lib/logreader.py | 0 {tools => openpilot/tools}/lib/openpilotci.py | 0 .../tools}/lib/openpilotcontainers.py | 0 {tools => openpilot/tools}/lib/route.py | 0 {tools => openpilot/tools}/lib/sanitizer.py | 0 {tools => openpilot/tools}/lib/tests/__init__.py | 0 .../tools}/lib/tests/test_caching.py | 0 .../tools}/lib/tests/test_comma_car_segments.py | 0 .../tools}/lib/tests/test_logreader.py | 0 .../tools}/lib/tests/test_route_library.py | 0 {tools => openpilot/tools}/lib/url_file.py | 0 {tools => openpilot/tools}/lib/vidindex.py | 0 .../tools}/longitudinal_maneuvers/.gitignore | 0 .../tools}/longitudinal_maneuvers/README.md | 0 .../longitudinal_maneuvers/generate_report.py | 0 .../longitudinal_maneuvers/maneuver_helpers.py | 0 .../tools}/longitudinal_maneuvers/maneuversd.py | 0 .../mpc_longitudinal_tuning_report.py | 0 {tools => openpilot/tools}/op.sh | 2 +- {tools => openpilot/tools}/plotjuggler/README.md | 0 {tools => openpilot/tools}/plotjuggler/juggle.py | 0 .../tools}/plotjuggler/layouts/CAN-bus-debug.xml | 0 .../tools}/plotjuggler/layouts/camera-timings.xml | 0 .../tools}/plotjuggler/layouts/can-states.xml | 0 .../plotjuggler/layouts/controls_mismatch_debug.xml | 0 .../tools}/plotjuggler/layouts/gps.xml | 0 .../tools}/plotjuggler/layouts/gps_vs_llk.xml | 0 .../tools}/plotjuggler/layouts/locationd_debug.xml | 0 .../tools}/plotjuggler/layouts/longitudinal.xml | 0 .../tools}/plotjuggler/layouts/max-torque-debug.xml | 0 .../tools}/plotjuggler/layouts/system_lag_debug.xml | 0 .../tools}/plotjuggler/layouts/thermal_debug.xml | 0 .../plotjuggler/layouts/torque-controller.xml | 0 .../tools}/plotjuggler/layouts/tuning.xml | 0 .../tools}/plotjuggler/layouts/ublox-debug.xml | 0 .../tools}/plotjuggler/test_plotjuggler.py | 0 {tools => openpilot/tools}/replay/.gitignore | 0 {tools => openpilot/tools}/replay/README.md | 0 {tools => openpilot/tools}/replay/SConscript | 0 {tools => openpilot/tools}/replay/__init__.py | 0 {tools => openpilot/tools}/replay/camera.cc | 0 {tools => openpilot/tools}/replay/camera.h | 0 {tools => openpilot/tools}/replay/can_replay.py | 0 {tools => openpilot/tools}/replay/consoleui.cc | 0 {tools => openpilot/tools}/replay/consoleui.h | 0 {tools => openpilot/tools}/replay/filereader.cc | 0 {tools => openpilot/tools}/replay/filereader.h | 0 {tools => openpilot/tools}/replay/framereader.cc | 0 {tools => openpilot/tools}/replay/framereader.h | 0 {tools => openpilot/tools}/replay/lib/__init__.py | 0 {tools => openpilot/tools}/replay/lib/ui_helpers.py | 0 {tools => openpilot/tools}/replay/logreader.cc | 0 {tools => openpilot/tools}/replay/logreader.h | 0 {tools => openpilot/tools}/replay/main.cc | 0 {tools => openpilot/tools}/replay/py_downloader.cc | 0 {tools => openpilot/tools}/replay/py_downloader.h | 0 {tools => openpilot/tools}/replay/qcom_decoder.cc | 0 {tools => openpilot/tools}/replay/qcom_decoder.h | 0 {tools => openpilot/tools}/replay/replay.cc | 0 {tools => openpilot/tools}/replay/replay.h | 0 {tools => openpilot/tools}/replay/route.cc | 0 {tools => openpilot/tools}/replay/route.h | 0 {tools => openpilot/tools}/replay/seg_mgr.cc | 0 {tools => openpilot/tools}/replay/seg_mgr.h | 0 .../tools}/replay/tests/test_replay.cc | 0 {tools => openpilot/tools}/replay/timeline.cc | 0 {tools => openpilot/tools}/replay/timeline.h | 0 {tools => openpilot/tools}/replay/ui.py | 0 {tools => openpilot/tools}/replay/util.cc | 0 {tools => openpilot/tools}/replay/util.h | 0 {tools => openpilot/tools}/scripts/__init__.py | 0 {tools => openpilot/tools}/scripts/adb_ssh.sh | 0 .../tools}/scripts/car/can_print_changes.py | 0 .../tools}/scripts/car/can_printer.py | 0 {tools => openpilot/tools}/scripts/car/can_table.py | 0 {tools => openpilot/tools}/scripts/car/clear_dtc.py | 0 .../tools}/scripts/car/disable_ecu.py | 0 {tools => openpilot/tools}/scripts/car/ecu_addrs.py | 0 .../tools}/scripts/car/fw_versions.py | 0 .../scripts/car/hyundai_enable_radar_points.py | 0 .../tools}/scripts/car/max_lat_accel.py | 0 .../scripts/car/measure_torque_time_to_max.py | 0 .../tools}/scripts/car/read_dtc_status.py | 0 .../tools}/scripts/car/toyota_eps_factor.py | 0 {tools => openpilot/tools}/scripts/car/vin.py | 0 .../tools}/scripts/car/vw_mqb_config.py | 0 {tools => openpilot/tools}/scripts/count_events.py | 0 .../tools}/scripts/cpu_usage_stat.py | 0 {tools => openpilot/tools}/scripts/cycle_alerts.py | 0 .../scripts/debug_fw_fingerprinting_offline.py | 0 {tools => openpilot/tools}/scripts/devsync.py | 0 {tools => openpilot/tools}/scripts/dump.py | 0 {tools => openpilot/tools}/scripts/extract_audio.py | 0 .../tools}/scripts/filter_log_message.py | 0 .../tools}/scripts/fingerprint_from_route.py | 0 .../tools}/scripts/fuzz_fw_fingerprint.py | 0 .../tools}/scripts/get_fingerprint.py | 0 .../tools}/scripts/live_cpu_and_temp.py | 0 {tools => openpilot/tools}/scripts/mem_usage.py | 0 {tools => openpilot/tools}/scripts/print_flags.py | 0 .../tools}/scripts/profiling/clpeak/.gitignore | 0 .../tools}/scripts/profiling/clpeak/build.sh | 0 .../tools}/scripts/profiling/clpeak/no_print.patch | 0 .../scripts/profiling/clpeak/run_continuously.patch | 0 .../tools}/scripts/profiling/ftrace.sh | 0 .../tools}/scripts/profiling/palanteer/.gitignore | 0 .../tools}/scripts/profiling/palanteer/setup.sh | 0 .../tools}/scripts/profiling/perfetto/.gitignore | 0 .../tools}/scripts/profiling/perfetto/build.sh | 0 .../tools}/scripts/profiling/perfetto/copy.sh | 0 .../tools}/scripts/profiling/perfetto/record.sh | 0 .../tools}/scripts/profiling/perfetto/server.sh | 0 .../tools}/scripts/profiling/perfetto/traces.sh | 0 .../tools}/scripts/profiling/py-spy/profile.sh | 0 .../tools}/scripts/profiling/snapdragon/.gitignore | 0 .../tools}/scripts/profiling/snapdragon/README.md | 0 .../scripts/profiling/snapdragon/setup-agnos.sh | 0 .../scripts/profiling/snapdragon/setup-profiler.sh | 0 .../tools}/scripts/profiling/watch-irqs.sh | 0 {tools => openpilot/tools}/scripts/qlog_size.py | 0 .../tools}/scripts/run_process_on_route.py | 0 {tools => openpilot/tools}/scripts/serial.sh | 0 .../tools}/scripts/set_car_params.py | 0 .../tools}/scripts/setup_ssh_keys.py | 0 {tools => openpilot/tools}/scripts/ssh.py | 0 .../tools}/scripts/test_fw_query_on_routes.py | 0 {tools => openpilot/tools}/scripts/uiview.py | 0 {tools => openpilot/tools}/scripts/watch_timings.py | 0 {tools => openpilot/tools}/setup.sh | 0 {tools => openpilot/tools}/setup_dependencies.sh | 0 {tools => openpilot/tools}/sim/README.md | 0 {tools => openpilot/tools}/sim/__init__.py | 0 {tools => openpilot/tools}/sim/bridge/__init__.py | 0 {tools => openpilot/tools}/sim/bridge/common.py | 0 .../tools}/sim/bridge/metadrive/metadrive_bridge.py | 0 .../tools}/sim/bridge/metadrive/metadrive_common.py | 0 .../sim/bridge/metadrive/metadrive_process.py | 0 .../tools}/sim/bridge/metadrive/metadrive_world.py | 0 {tools => openpilot/tools}/sim/launch_openpilot.sh | 0 {tools => openpilot/tools}/sim/lib/__init__.py | 0 {tools => openpilot/tools}/sim/lib/camerad.py | 0 {tools => openpilot/tools}/sim/lib/common.py | 0 {tools => openpilot/tools}/sim/lib/keyboard_ctrl.py | 0 {tools => openpilot/tools}/sim/lib/manual_ctrl.py | 0 {tools => openpilot/tools}/sim/lib/simulated_car.py | 0 .../tools}/sim/lib/simulated_sensors.py | 0 {tools => openpilot/tools}/sim/run_bridge.py | 0 {tools => openpilot/tools}/sim/tests/__init__.py | 0 {tools => openpilot/tools}/sim/tests/conftest.py | 0 .../tools}/sim/tests/test_metadrive_bridge.py | 0 .../tools}/sim/tests/test_sim_bridge.py | 0 pyproject.toml | 2 +- scripts/lint/lint.sh | 2 +- 1062 files changed, 15 insertions(+), 19 deletions(-) delete mode 120000 openpilot/common rename {common => openpilot/common}/SConscript (100%) rename {common => openpilot/common}/__init__.py (100%) rename {common => openpilot/common}/api.py (100%) rename {common => openpilot/common}/basedir.py (71%) rename {common => openpilot/common}/constants.py (100%) rename {common => openpilot/common}/esim/__init__.py (100%) rename {common => openpilot/common}/esim/base.py (100%) rename {common => openpilot/common}/esim/esim.py (100%) rename {common => openpilot/common}/esim/gsma_ci_bundle.pem (100%) rename {common => openpilot/common}/esim/lpa.py (100%) rename {common => openpilot/common}/file_chunker.py (100%) rename {common => openpilot/common}/filter_simple.py (100%) rename {common => openpilot/common}/git.py (100%) rename {common => openpilot/common}/gpio.py (100%) rename {common => openpilot/common}/gps.py (100%) rename {common => openpilot/common}/hardware/__init__.py (100%) rename {common => openpilot/common}/hardware/base.h (100%) rename {common => openpilot/common}/hardware/base.py (100%) rename {common => openpilot/common}/hardware/hw.h (100%) rename {common => openpilot/common}/hardware/hw.py (100%) rename {common => openpilot/common}/hardware/pc/__init__.py (100%) rename {common => openpilot/common}/hardware/pc/hardware.h (100%) rename {common => openpilot/common}/hardware/pc/hardware.py (100%) rename {common => openpilot/common}/hardware/tici/__init__.py (100%) rename {common => openpilot/common}/hardware/tici/agnos.json (100%) rename {common => openpilot/common}/hardware/tici/agnos.py (100%) rename {common => openpilot/common}/hardware/tici/all-partitions.json (100%) rename {common => openpilot/common}/hardware/tici/amplifier.py (100%) rename {common => openpilot/common}/hardware/tici/hardware.h (100%) rename {common => openpilot/common}/hardware/tici/hardware.py (100%) rename {common => openpilot/common}/hardware/tici/id_rsa (100%) rename {common => openpilot/common}/hardware/tici/modem.py (100%) rename {common => openpilot/common}/hardware/tici/pins.py (100%) rename {common => openpilot/common}/hardware/tici/power_monitor.py (100%) rename {common => openpilot/common}/hardware/tici/tests/__init__.py (100%) rename {common => openpilot/common}/hardware/tici/tests/test_agnos_updater.py (100%) rename {common => openpilot/common}/hardware/tici/tests/test_amplifier.py (100%) rename {common => openpilot/common}/hardware/tici/updater (100%) rename {common => openpilot/common}/i2c.py (100%) rename {common => openpilot/common}/logging_extra.py (100%) rename {common => openpilot/common}/markdown.py (100%) rename {common => openpilot/common}/mock/__init__.py (100%) rename {common => openpilot/common}/mock/generators.py (100%) rename {common => openpilot/common}/parameterized.py (100%) rename {common => openpilot/common}/params.cc (100%) rename {common => openpilot/common}/params.h (100%) rename {common => openpilot/common}/params.py (100%) rename {common => openpilot/common}/params_keys.h (100%) rename {common => openpilot/common}/params_pyx.pyx (100%) rename {common => openpilot/common}/pid.py (100%) rename {common => openpilot/common}/prefix.h (100%) rename {common => openpilot/common}/prefix.py (100%) rename {common => openpilot/common}/queue.h (100%) rename {common => openpilot/common}/ratekeeper.cc (100%) rename {common => openpilot/common}/ratekeeper.h (100%) rename {common => openpilot/common}/realtime.py (100%) rename {common => openpilot/common}/simple_kalman.py (100%) rename {common => openpilot/common}/spinner.py (100%) rename {common => openpilot/common}/stat_live.py (100%) rename {common => openpilot/common}/swaglog.cc (100%) rename {common => openpilot/common}/swaglog.h (100%) rename {common => openpilot/common}/swaglog.py (100%) rename {common => openpilot/common}/tests/.gitignore (100%) rename {common => openpilot/common}/tests/__init__.py (100%) rename {common => openpilot/common}/tests/test_file_helpers.py (100%) rename {common => openpilot/common}/tests/test_markdown.py (100%) rename {common => openpilot/common}/tests/test_params.cc (100%) rename {common => openpilot/common}/tests/test_params.py (100%) rename {common => openpilot/common}/tests/test_runner.cc (100%) rename {common => openpilot/common}/tests/test_simple_kalman.py (100%) rename {common => openpilot/common}/tests/test_swaglog.cc (100%) rename {common => openpilot/common}/tests/test_util.cc (100%) rename {common => openpilot/common}/text_window.py (100%) rename {common => openpilot/common}/time_helpers.py (100%) rename {common => openpilot/common}/timeout.py (100%) rename {common => openpilot/common}/timing.h (100%) rename {common => openpilot/common}/transformations/README.md (100%) rename {common => openpilot/common}/transformations/__init__.py (100%) rename {common => openpilot/common}/transformations/camera.py (100%) rename {common => openpilot/common}/transformations/coordinates.py (100%) rename {common => openpilot/common}/transformations/model.py (100%) rename {common => openpilot/common}/transformations/orientation.py (100%) rename {common => openpilot/common}/transformations/tests/__init__.py (100%) rename {common => openpilot/common}/transformations/tests/test_coordinates.py (100%) rename {common => openpilot/common}/transformations/tests/test_orientation.py (100%) rename {common => openpilot/common}/transformations/transformations.py (100%) rename {common => openpilot/common}/util.cc (100%) rename {common => openpilot/common}/util.h (100%) rename {common => openpilot/common}/utils.py (100%) rename {common => openpilot/common}/version.h (100%) rename {common => openpilot/common}/version.py (100%) delete mode 120000 openpilot/selfdrive rename {selfdrive => openpilot/selfdrive}/__init__.py (100%) rename {selfdrive => openpilot/selfdrive}/assets/.gitignore (100%) rename {selfdrive => openpilot/selfdrive}/assets/assets.qrc (100%) rename {selfdrive => openpilot/selfdrive}/assets/body/awake.gif (100%) rename {selfdrive => openpilot/selfdrive}/assets/body/sleep.gif (100%) rename {selfdrive => openpilot/selfdrive}/assets/compress-images.sh (100%) rename {selfdrive => openpilot/selfdrive}/assets/fonts/Inter-Black.ttf (100%) rename {selfdrive => openpilot/selfdrive}/assets/fonts/Inter-Bold.ttf (100%) rename {selfdrive => openpilot/selfdrive}/assets/fonts/Inter-ExtraBold.ttf (100%) rename {selfdrive => openpilot/selfdrive}/assets/fonts/Inter-ExtraLight.ttf (100%) rename {selfdrive => openpilot/selfdrive}/assets/fonts/Inter-Light.ttf (100%) rename {selfdrive => openpilot/selfdrive}/assets/fonts/Inter-Medium.ttf (100%) rename {selfdrive => openpilot/selfdrive}/assets/fonts/Inter-Regular.ttf (100%) rename {selfdrive => openpilot/selfdrive}/assets/fonts/Inter-SemiBold.ttf (100%) rename {selfdrive => openpilot/selfdrive}/assets/fonts/Inter-Thin.ttf (100%) rename {selfdrive => openpilot/selfdrive}/assets/fonts/JetBrainsMono-Medium.ttf (100%) rename {selfdrive => openpilot/selfdrive}/assets/fonts/NotoColorEmoji.ttf (100%) rename {selfdrive => openpilot/selfdrive}/assets/fonts/process.py (100%) rename {selfdrive => openpilot/selfdrive}/assets/fonts/unifont.otf (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons/arrow-right.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons/backspace.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons/calibration.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons/capslock-fill.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons/checkmark.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons/checkmark.svg (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons/chevron_right.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons/chffr_wheel.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons/circled_check.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons/circled_check.svg (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons/circled_slash.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons/circled_slash.svg (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons/close.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons/close.svg (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons/close2.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons/close2.svg (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons/couch.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons/couch.svg (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons/disengage_on_accelerator.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons/disengage_on_accelerator.svg (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons/driver_face.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons/experimental.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons/experimental.svg (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons/experimental_grey.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons/experimental_grey.svg (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons/experimental_white.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons/experimental_white.svg (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons/eye_closed.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons/eye_closed.svg (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons/eye_open.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons/eye_open.svg (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons/eyes_crossed.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons/eyes_open.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons/link.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons/lock_closed.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons/lock_closed.svg (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons/menu.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons/metric.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons/microphone.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons/minus.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons/monitoring.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons/network.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons/road.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons/settings.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons/shell.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons/shift-fill.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons/shift.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons/speed_limit.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons/triangle.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons/triangle.svg (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons/warning.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons/wifi_strength_full.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons/wifi_strength_full.svg (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons/wifi_strength_high.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons/wifi_strength_high.svg (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons/wifi_strength_low.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons/wifi_strength_low.svg (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons/wifi_strength_medium.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons/wifi_strength_medium.svg (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons/wifi_uploading.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons/wifi_uploading.svg (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/adb_short.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/alerts_bell.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/alerts_pill.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/body.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/buttons/button_circle.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/buttons/button_circle_disabled.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/buttons/button_circle_pressed.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/buttons/button_circle_red.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/buttons/button_circle_red_pressed.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/buttons/button_rectangle.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/buttons/button_rectangle_disabled.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/buttons/button_rectangle_pressed.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/buttons/slider_bg.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/buttons/toggle_dot_disabled.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/buttons/toggle_dot_enabled.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/buttons/toggle_pill_disabled.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/buttons/toggle_pill_enabled.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/egpu.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/egpu_gray.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/exclamation_point.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/experimental_mode.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/microphone.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/offroad_alerts/big_alert.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/offroad_alerts/big_alert_pressed.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/offroad_alerts/green_wheel.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/offroad_alerts/medium_alert.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/offroad_alerts/medium_alert_pressed.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/offroad_alerts/orange_warning.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/offroad_alerts/red_warning.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/offroad_alerts/small_alert.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/offroad_alerts/small_alert_pressed.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/onroad/blind_spot_left.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/onroad/bookmark.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/onroad/driver_monitoring/dm_background.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/onroad/driver_monitoring/dm_cone.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/onroad/driver_monitoring/dm_person.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/onroad/eye_fill.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/onroad/eye_orange.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/onroad/glasses.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/onroad/onroad_fade.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/onroad/turn_signal_left.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/settings.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/settings/comma_icon.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/settings/developer/ssh.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/settings/developer_icon.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/settings/device/cameras.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/settings/device/fcc_logo.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/settings/device/info.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/settings/device/lkas.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/settings/device/pair.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/settings/device/power.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/settings/device/reboot.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/settings/device/uninstall.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/settings/device/up_to_date.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/settings/device/update.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/settings/device_icon.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/settings/firehose.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/settings/horizontal_scroll_indicator.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/settings/keyboard/backspace.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/settings/keyboard/caps_lock.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/settings/keyboard/caps_lower.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/settings/keyboard/caps_upper.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/settings/keyboard/enter.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/settings/keyboard/enter_disabled.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/settings/keyboard/keyboard_background.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/settings/keyboard/space.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/settings/network/cell_strength_full.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/settings/network/cell_strength_high.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/settings/network/cell_strength_low.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/settings/network/cell_strength_medium.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/settings/network/cell_strength_none.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/settings/network/new/forget_button.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/settings/network/new/forget_button_pressed.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/settings/network/new/lock.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/settings/network/new/trash.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/settings/network/tethering.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/settings/network/wifi_strength_full.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/settings/network/wifi_strength_low.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/settings/network/wifi_strength_medium.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/settings/network/wifi_strength_none.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/settings/network/wifi_strength_slash.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/settings/software.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/setup/cancel.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/setup/continue.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/setup/continue_disabled.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/setup/continue_pressed.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/setup/driver_monitoring/dm_check.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/setup/driver_monitoring/dm_question.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/setup/factory_reset.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/setup/green_dm.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/setup/green_info.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/setup/orange_dm.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/setup/red_warning.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/setup/reset_failed.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/setup/restore.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/setup/small_button.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/setup/small_button_disabled.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/setup/small_button_pressed.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/setup/small_slider/slider_arrow.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/setup/small_slider/slider_bg_larger.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/setup/small_slider/slider_black_rounded_rectangle.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/setup/small_slider/slider_black_rounded_rectangle_pressed.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/setup/small_slider/slider_green_rounded_rectangle.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/setup/small_slider/slider_green_rounded_rectangle_pressed.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/setup/start_button.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/setup/start_button_pressed.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/setup/warning.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/ssh_short.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/turn_intent_left.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/wheel.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/icons_mici/wheel_critical.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/images/button_continue_triangle.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/images/button_continue_triangle.svg (100%) rename {selfdrive => openpilot/selfdrive}/assets/images/button_flag.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/images/button_home.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/images/button_settings.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/images/spinner_comma.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/images/spinner_track.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/offroad/fcc.html (100%) rename {selfdrive => openpilot/selfdrive}/assets/offroad/mici_fcc.html (100%) rename {selfdrive => openpilot/selfdrive}/assets/prep-svg.sh (100%) rename {selfdrive => openpilot/selfdrive}/assets/sounds/disengage.wav (100%) rename {selfdrive => openpilot/selfdrive}/assets/sounds/disengage_tizi.wav (100%) rename {selfdrive => openpilot/selfdrive}/assets/sounds/engage.wav (100%) rename {selfdrive => openpilot/selfdrive}/assets/sounds/engage_tizi.wav (100%) rename {selfdrive => openpilot/selfdrive}/assets/sounds/make_beeps.py (100%) rename {selfdrive => openpilot/selfdrive}/assets/sounds/prompt.wav (100%) rename {selfdrive => openpilot/selfdrive}/assets/sounds/prompt_distracted.wav (100%) rename {selfdrive => openpilot/selfdrive}/assets/sounds/refuse.wav (100%) rename {selfdrive => openpilot/selfdrive}/assets/sounds/warning_immediate.wav (100%) rename {selfdrive => openpilot/selfdrive}/assets/sounds/warning_soft.wav (100%) rename {selfdrive => openpilot/selfdrive}/assets/training/step0.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/training/step1.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/training/step10.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/training/step11.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/training/step12.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/training/step13.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/training/step14.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/training/step15.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/training/step16.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/training/step17.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/training/step18.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/training/step2.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/training/step3.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/training/step4.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/training/step5.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/training/step6.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/training/step7.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/training/step8.png (100%) rename {selfdrive => openpilot/selfdrive}/assets/training/step9.png (100%) rename {selfdrive => openpilot/selfdrive}/car/CARS_template.md (100%) rename {selfdrive => openpilot/selfdrive}/car/__init__.py (100%) rename {selfdrive => openpilot/selfdrive}/car/car_specific.py (100%) rename {selfdrive => openpilot/selfdrive}/car/card.py (100%) rename {selfdrive => openpilot/selfdrive}/car/cruise.py (100%) rename {selfdrive => openpilot/selfdrive}/car/docs.py (100%) rename {selfdrive => openpilot/selfdrive}/car/tests/__init__.py (100%) rename {selfdrive => openpilot/selfdrive}/car/tests/big_cars_test.sh (85%) rename {selfdrive => openpilot/selfdrive}/car/tests/test_car_interfaces.py (100%) rename {selfdrive => openpilot/selfdrive}/car/tests/test_cruise_speed.py (100%) rename {selfdrive => openpilot/selfdrive}/car/tests/test_docs.py (100%) rename {selfdrive => openpilot/selfdrive}/car/tests/test_models.py (100%) rename {selfdrive => openpilot/selfdrive}/car/tests/test_models_segs.txt (100%) rename {selfdrive => openpilot/selfdrive}/controls/__init__.py (100%) rename {selfdrive => openpilot/selfdrive}/controls/controlsd.py (100%) rename {selfdrive => openpilot/selfdrive}/controls/lib/__init__.py (100%) rename {selfdrive => openpilot/selfdrive}/controls/lib/desire_helper.py (100%) rename {selfdrive => openpilot/selfdrive}/controls/lib/drive_helpers.py (100%) rename {selfdrive => openpilot/selfdrive}/controls/lib/latcontrol.py (100%) rename {selfdrive => openpilot/selfdrive}/controls/lib/latcontrol_angle.py (100%) rename {selfdrive => openpilot/selfdrive}/controls/lib/latcontrol_curvature.py (100%) rename {selfdrive => openpilot/selfdrive}/controls/lib/latcontrol_pid.py (100%) rename {selfdrive => openpilot/selfdrive}/controls/lib/latcontrol_torque.py (100%) rename {selfdrive => openpilot/selfdrive}/controls/lib/lateral_mpc_lib/.gitignore (100%) rename {selfdrive => openpilot/selfdrive}/controls/lib/lateral_mpc_lib/SConscript (100%) rename {selfdrive => openpilot/selfdrive}/controls/lib/lateral_mpc_lib/__init__.py (100%) rename {selfdrive => openpilot/selfdrive}/controls/lib/lateral_mpc_lib/lat_mpc.py (100%) rename {selfdrive => openpilot/selfdrive}/controls/lib/ldw.py (100%) rename {selfdrive => openpilot/selfdrive}/controls/lib/longcontrol.py (100%) rename {selfdrive => openpilot/selfdrive}/controls/lib/longitudinal_mpc_lib/.gitignore (100%) rename {selfdrive => openpilot/selfdrive}/controls/lib/longitudinal_mpc_lib/SConscript (100%) rename {selfdrive => openpilot/selfdrive}/controls/lib/longitudinal_mpc_lib/__init__.py (100%) rename {selfdrive => openpilot/selfdrive}/controls/lib/longitudinal_mpc_lib/long_mpc.py (100%) rename {selfdrive => openpilot/selfdrive}/controls/lib/longitudinal_planner.py (100%) rename {selfdrive => openpilot/selfdrive}/controls/plannerd.py (100%) rename {selfdrive => openpilot/selfdrive}/controls/radard.py (100%) rename {selfdrive => openpilot/selfdrive}/controls/tests/__init__.py (100%) rename {selfdrive => openpilot/selfdrive}/controls/tests/test_following_distance.py (100%) rename {selfdrive => openpilot/selfdrive}/controls/tests/test_latcontrol.py (100%) rename {selfdrive => openpilot/selfdrive}/controls/tests/test_latcontrol_torque_buffer.py (100%) rename {selfdrive => openpilot/selfdrive}/controls/tests/test_lateral_mpc.py (100%) rename {selfdrive => openpilot/selfdrive}/controls/tests/test_leads.py (100%) rename {selfdrive => openpilot/selfdrive}/controls/tests/test_longcontrol.py (100%) rename {selfdrive => openpilot/selfdrive}/controls/tests/test_torqued_lat_accel_offset.py (100%) rename {selfdrive => openpilot/selfdrive}/locationd/SConscript (100%) rename {selfdrive => openpilot/selfdrive}/locationd/__init__.py (100%) rename {selfdrive => openpilot/selfdrive}/locationd/calibrationd.py (100%) rename {selfdrive => openpilot/selfdrive}/locationd/helpers.py (100%) rename {selfdrive => openpilot/selfdrive}/locationd/lagd.py (100%) rename {selfdrive => openpilot/selfdrive}/locationd/locationd.py (100%) rename {selfdrive => openpilot/selfdrive}/locationd/models/.gitignore (100%) rename {selfdrive => openpilot/selfdrive}/locationd/models/__init__.py (100%) rename {selfdrive => openpilot/selfdrive}/locationd/models/car_kf.py (100%) rename {selfdrive => openpilot/selfdrive}/locationd/models/constants.py (100%) rename {selfdrive => openpilot/selfdrive}/locationd/models/pose_kf.py (100%) rename {selfdrive => openpilot/selfdrive}/locationd/paramsd.py (100%) rename {selfdrive => openpilot/selfdrive}/locationd/test/__init__.py (100%) rename {selfdrive => openpilot/selfdrive}/locationd/test/test_calibrationd.py (100%) rename {selfdrive => openpilot/selfdrive}/locationd/test/test_lagd.py (100%) rename {selfdrive => openpilot/selfdrive}/locationd/test/test_locationd_scenarios.py (100%) rename {selfdrive => openpilot/selfdrive}/locationd/test/test_paramsd.py (100%) rename {selfdrive => openpilot/selfdrive}/locationd/test/test_torqued.py (100%) rename {selfdrive => openpilot/selfdrive}/locationd/torqued.py (100%) rename {selfdrive => openpilot/selfdrive}/modeld/SConscript (100%) rename {selfdrive => openpilot/selfdrive}/modeld/__init__.py (100%) rename {selfdrive => openpilot/selfdrive}/modeld/compile_dm_warp.py (100%) rename {selfdrive => openpilot/selfdrive}/modeld/compile_modeld.py (100%) rename {selfdrive => openpilot/selfdrive}/modeld/constants.py (100%) rename {selfdrive => openpilot/selfdrive}/modeld/dmonitoringmodeld.py (100%) rename {selfdrive => openpilot/selfdrive}/modeld/fill_model_msg.py (100%) rename {selfdrive => openpilot/selfdrive}/modeld/get_model_metadata.py (100%) rename {selfdrive => openpilot/selfdrive}/modeld/helpers.py (100%) rename {selfdrive => openpilot/selfdrive}/modeld/modeld.py (100%) rename {selfdrive => openpilot/selfdrive}/modeld/models/README.md (100%) rename {selfdrive => openpilot/selfdrive}/modeld/models/__init__.py (100%) rename {selfdrive => openpilot/selfdrive}/modeld/models/big_driving_supercombo.onnx (100%) rename {selfdrive => openpilot/selfdrive}/modeld/models/dmonitoring_model.onnx (100%) rename {selfdrive => openpilot/selfdrive}/modeld/models/driving_supercombo.onnx (100%) rename {selfdrive => openpilot/selfdrive}/modeld/parse_model_outputs.py (100%) rename {selfdrive => openpilot/selfdrive}/monitoring/dmonitoringd.py (100%) rename {selfdrive => openpilot/selfdrive}/monitoring/policy.py (100%) rename {selfdrive => openpilot/selfdrive}/monitoring/test_monitoring.py (100%) rename {selfdrive => openpilot/selfdrive}/pandad/.gitignore (100%) rename {selfdrive => openpilot/selfdrive}/pandad/SConscript (100%) rename {selfdrive => openpilot/selfdrive}/pandad/__init__.py (100%) rename {selfdrive => openpilot/selfdrive}/pandad/main.cc (100%) rename {selfdrive => openpilot/selfdrive}/pandad/panda.cc (98%) rename {selfdrive => openpilot/selfdrive}/pandad/panda.h (100%) rename {selfdrive => openpilot/selfdrive}/pandad/panda_comms.h (100%) rename {selfdrive => openpilot/selfdrive}/pandad/panda_safety.cc (100%) rename {selfdrive => openpilot/selfdrive}/pandad/pandad.cc (100%) rename {selfdrive => openpilot/selfdrive}/pandad/pandad.h (100%) rename {selfdrive => openpilot/selfdrive}/pandad/pandad.py (100%) rename {selfdrive => openpilot/selfdrive}/pandad/pandad_api_impl.py (100%) rename {selfdrive => openpilot/selfdrive}/pandad/spi.cc (100%) rename {selfdrive => openpilot/selfdrive}/pandad/tests/__init__.py (100%) rename {selfdrive => openpilot/selfdrive}/pandad/tests/bootstub.panda_h7.bin (100%) rename {selfdrive => openpilot/selfdrive}/pandad/tests/test_pandad.py (100%) rename {selfdrive => openpilot/selfdrive}/pandad/tests/test_pandad_canprotocol.cc (100%) rename {selfdrive => openpilot/selfdrive}/pandad/tests/test_pandad_loopback.py (100%) rename {selfdrive => openpilot/selfdrive}/pandad/tests/test_pandad_spi.py (100%) rename {selfdrive => openpilot/selfdrive}/selfdrived/alertmanager.py (100%) rename {selfdrive => openpilot/selfdrive}/selfdrived/alerts_offroad.json (100%) rename {selfdrive => openpilot/selfdrive}/selfdrived/events.py (100%) rename {selfdrive => openpilot/selfdrive}/selfdrived/helpers.py (100%) rename {selfdrive => openpilot/selfdrive}/selfdrived/selfdrived.py (100%) rename {selfdrive => openpilot/selfdrive}/selfdrived/state.py (100%) rename {selfdrive => openpilot/selfdrive}/selfdrived/tests/test_alertmanager.py (100%) rename {selfdrive => openpilot/selfdrive}/selfdrived/tests/test_alerts.py (100%) rename {selfdrive => openpilot/selfdrive}/selfdrived/tests/test_state_machine.py (100%) rename {selfdrive => openpilot/selfdrive}/test/.gitignore (100%) rename {selfdrive => openpilot/selfdrive}/test/__init__.py (100%) rename {selfdrive => openpilot/selfdrive}/test/cpp_harness.py (100%) rename {selfdrive => openpilot/selfdrive}/test/fuzzy_generation.py (100%) rename {selfdrive => openpilot/selfdrive}/test/helpers.py (100%) rename {selfdrive => openpilot/selfdrive}/test/longitudinal_maneuvers/.gitignore (100%) rename {selfdrive => openpilot/selfdrive}/test/longitudinal_maneuvers/__init__.py (100%) rename {selfdrive => openpilot/selfdrive}/test/longitudinal_maneuvers/maneuver.py (100%) rename {selfdrive => openpilot/selfdrive}/test/longitudinal_maneuvers/plant.py (100%) rename {selfdrive => openpilot/selfdrive}/test/longitudinal_maneuvers/test_longitudinal.py (100%) rename {selfdrive => openpilot/selfdrive}/test/process_replay/README.md (100%) rename {selfdrive => openpilot/selfdrive}/test/process_replay/__init__.py (100%) rename {selfdrive => openpilot/selfdrive}/test/process_replay/capture.py (100%) rename {selfdrive => openpilot/selfdrive}/test/process_replay/compare_logs.py (100%) rename {selfdrive => openpilot/selfdrive}/test/process_replay/diff_report.py (100%) rename {selfdrive => openpilot/selfdrive}/test/process_replay/migration.py (100%) rename {selfdrive => openpilot/selfdrive}/test/process_replay/model_replay.py (100%) rename {selfdrive => openpilot/selfdrive}/test/process_replay/process_replay.py (100%) rename {selfdrive => openpilot/selfdrive}/test/process_replay/regen.py (100%) rename {selfdrive => openpilot/selfdrive}/test/process_replay/regen_all.py (100%) rename {selfdrive => openpilot/selfdrive}/test/process_replay/test_fuzzy.py (100%) rename {selfdrive => openpilot/selfdrive}/test/process_replay/test_processes.py (100%) rename {selfdrive => openpilot/selfdrive}/test/process_replay/test_regen.py (100%) rename {selfdrive => openpilot/selfdrive}/test/process_replay/vision_meta.py (100%) rename {selfdrive => openpilot/selfdrive}/test/scons_build_test.sh (89%) rename {selfdrive => openpilot/selfdrive}/test/setup_device_ci.sh (100%) rename {selfdrive => openpilot/selfdrive}/test/setup_xvfb.sh (100%) rename {selfdrive => openpilot/selfdrive}/test/test_onroad.py (100%) rename {selfdrive => openpilot/selfdrive}/test/test_power_draw.py (100%) rename {selfdrive => openpilot/selfdrive}/test/update_ci_routes.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/.gitignore (100%) rename {selfdrive => openpilot/selfdrive}/ui/SConscript (100%) rename {selfdrive => openpilot/selfdrive}/ui/__init__.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/body/__init__.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/body/animations.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/body/layouts/__init__.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/body/layouts/onroad.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/feedback/feedbackd.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/installer/continue_openpilot.sh (100%) rename {selfdrive => openpilot/selfdrive}/ui/installer/installer.cc (100%) rename {selfdrive => openpilot/selfdrive}/ui/installer/inter-ascii.ttf (100%) rename {selfdrive => openpilot/selfdrive}/ui/layouts/__init__.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/layouts/home.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/layouts/main.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/layouts/onboarding.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/layouts/settings/common.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/layouts/settings/developer.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/layouts/settings/device.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/layouts/settings/firehose.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/layouts/settings/settings.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/layouts/settings/software.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/layouts/settings/toggles.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/layouts/sidebar.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/lib/api_helpers.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/lib/prime_state.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/mici/layouts/__init__.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/mici/layouts/home.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/mici/layouts/main.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/mici/layouts/offroad_alerts.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/mici/layouts/onboarding.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/mici/layouts/settings/developer.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/mici/layouts/settings/device.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/mici/layouts/settings/firehose.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/mici/layouts/settings/network/__init__.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/mici/layouts/settings/network/network_layout.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/mici/layouts/settings/network/wifi_ui.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/mici/layouts/settings/settings.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/mici/layouts/settings/software.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/mici/layouts/settings/toggles.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/mici/onroad/__init__.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/mici/onroad/alert_renderer.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/mici/onroad/augmented_road_view.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/mici/onroad/cameraview.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/mici/onroad/confidence_ball.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/mici/onroad/driver_camera_dialog.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/mici/onroad/driver_state.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/mici/onroad/hud_renderer.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/mici/onroad/model_renderer.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/mici/onroad/torque_bar.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/mici/tests/test_widget_leaks.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/mici/widgets/button.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/mici/widgets/dialog.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/mici/widgets/pairing_dialog.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/onroad/__init__.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/onroad/alert_renderer.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/onroad/augmented_road_view.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/onroad/cameraview.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/onroad/driver_camera_dialog.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/onroad/driver_state.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/onroad/exp_button.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/onroad/hud_renderer.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/onroad/model_renderer.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/soundd.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/tests/__init__.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/tests/body.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/tests/cycle_offroad_alerts.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/tests/diff/diff.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/tests/diff/diff_template.html (100%) rename {selfdrive => openpilot/selfdrive}/ui/tests/diff/replay.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/tests/diff/replay_script.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/tests/profile_onroad.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/tests/test_feedbackd.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/tests/test_raylib_ui.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/tests/test_soundd.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/tests/test_translations.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/translations/app.pot (100%) rename {selfdrive => openpilot/selfdrive}/ui/translations/app_de.po (100%) rename {selfdrive => openpilot/selfdrive}/ui/translations/app_en.po (100%) rename {selfdrive => openpilot/selfdrive}/ui/translations/app_es.po (100%) rename {selfdrive => openpilot/selfdrive}/ui/translations/app_fr.po (100%) rename {selfdrive => openpilot/selfdrive}/ui/translations/app_ja.po (100%) rename {selfdrive => openpilot/selfdrive}/ui/translations/app_ko.po (100%) rename {selfdrive => openpilot/selfdrive}/ui/translations/app_pt-BR.po (100%) rename {selfdrive => openpilot/selfdrive}/ui/translations/app_th.po (100%) rename {selfdrive => openpilot/selfdrive}/ui/translations/app_tr.po (100%) rename {selfdrive => openpilot/selfdrive}/ui/translations/app_uk.po (100%) rename {selfdrive => openpilot/selfdrive}/ui/translations/app_zh-CHS.po (100%) rename {selfdrive => openpilot/selfdrive}/ui/translations/app_zh-CHT.po (100%) rename {selfdrive => openpilot/selfdrive}/ui/translations/auto_translate.sh (100%) rename {selfdrive => openpilot/selfdrive}/ui/translations/languages.json (100%) rename {selfdrive => openpilot/selfdrive}/ui/translations/potools.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/translations/update_translations.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/ui.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/ui_state.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/watch3.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/widgets/__init__.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/widgets/exp_mode_button.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/widgets/offroad_alerts.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/widgets/pairing_dialog.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/widgets/prime.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/widgets/setup.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/widgets/ssh_key.py (100%) delete mode 120000 openpilot/system rename {system => openpilot/system}/__init__.py (100%) rename {system => openpilot/system}/athena/__init__.py (100%) rename {system => openpilot/system}/athena/athenad.py (100%) rename {system => openpilot/system}/athena/manage_athenad.py (100%) rename {system => openpilot/system}/athena/registration.py (100%) rename {system => openpilot/system}/athena/tests/__init__.py (100%) rename {system => openpilot/system}/athena/tests/helpers.py (100%) rename {system => openpilot/system}/athena/tests/test_athenad.py (100%) rename {system => openpilot/system}/athena/tests/test_athenad_ping.py (100%) rename {system => openpilot/system}/athena/tests/test_registration.py (100%) rename {system => openpilot/system}/camerad/SConscript (100%) rename {system => openpilot/system}/camerad/__init__.py (100%) rename {system => openpilot/system}/camerad/cameras/bps_blobs.h (100%) rename {system => openpilot/system}/camerad/cameras/camera_common.cc (100%) rename {system => openpilot/system}/camerad/cameras/camera_common.h (100%) rename {system => openpilot/system}/camerad/cameras/camera_qcom2.cc (100%) rename {system => openpilot/system}/camerad/cameras/cdm.cc (100%) rename {system => openpilot/system}/camerad/cameras/cdm.h (100%) rename {system => openpilot/system}/camerad/cameras/hw.h (100%) rename {system => openpilot/system}/camerad/cameras/ife.h (100%) rename {system => openpilot/system}/camerad/cameras/nv12_info.h (100%) rename {system => openpilot/system}/camerad/cameras/nv12_info.py (100%) rename {system => openpilot/system}/camerad/cameras/spectra.cc (100%) rename {system => openpilot/system}/camerad/cameras/spectra.h (100%) rename {system => openpilot/system}/camerad/main.cc (100%) rename {system => openpilot/system}/camerad/sensors/os04c10.cc (100%) rename {system => openpilot/system}/camerad/sensors/os04c10_registers.h (100%) rename {system => openpilot/system}/camerad/sensors/ox03c10.cc (100%) rename {system => openpilot/system}/camerad/sensors/ox03c10_registers.h (100%) rename {system => openpilot/system}/camerad/sensors/sensor.h (100%) rename {system => openpilot/system}/camerad/snapshot.py (100%) rename {system => openpilot/system}/camerad/test/.gitignore (100%) rename {system => openpilot/system}/camerad/test/debug.sh (100%) rename {system => openpilot/system}/camerad/test/icp_debug.sh (100%) rename {system => openpilot/system}/camerad/test/intercept.sh (100%) rename {system => openpilot/system}/camerad/test/stress_restart.sh (100%) rename {system => openpilot/system}/camerad/test/test_ae_gray.cc (100%) rename {system => openpilot/system}/camerad/test/test_camerad.py (100%) rename {system => openpilot/system}/camerad/webcam/README.md (100%) rename {system => openpilot/system}/camerad/webcam/camera.py (100%) rename {system => openpilot/system}/camerad/webcam/camerad.py (100%) rename {system => openpilot/system}/hardware/fan_controller.py (100%) rename {system => openpilot/system}/hardware/hardwared.py (100%) rename {system => openpilot/system}/hardware/power_monitoring.py (100%) rename {system => openpilot/system}/hardware/tests/__init__.py (100%) rename {system => openpilot/system}/hardware/tests/test_fan_controller.py (100%) rename {system => openpilot/system}/hardware/tests/test_power_monitoring.py (100%) rename {system => openpilot/system}/hardware/tici/agnos.json (100%) rename {system => openpilot/system}/journald.py (100%) rename {system => openpilot/system}/loggerd/.gitignore (100%) rename {system => openpilot/system}/loggerd/SConscript (100%) rename {system => openpilot/system}/loggerd/__init__.py (100%) rename {system => openpilot/system}/loggerd/bootlog.cc (100%) rename {system => openpilot/system}/loggerd/config.py (100%) rename {system => openpilot/system}/loggerd/deleter.py (100%) rename {system => openpilot/system}/loggerd/encoder/encoder.cc (100%) rename {system => openpilot/system}/loggerd/encoder/encoder.h (100%) rename {system => openpilot/system}/loggerd/encoder/ffmpeg_encoder.cc (100%) rename {system => openpilot/system}/loggerd/encoder/ffmpeg_encoder.h (100%) rename {system => openpilot/system}/loggerd/encoder/jpeg_encoder.cc (100%) rename {system => openpilot/system}/loggerd/encoder/jpeg_encoder.h (100%) rename {system => openpilot/system}/loggerd/encoder/v4l_encoder.cc (100%) rename {system => openpilot/system}/loggerd/encoder/v4l_encoder.h (100%) rename {system => openpilot/system}/loggerd/encoderd.cc (100%) rename {system => openpilot/system}/loggerd/logger.cc (100%) rename {system => openpilot/system}/loggerd/logger.h (100%) rename {system => openpilot/system}/loggerd/loggerd.cc (100%) rename {system => openpilot/system}/loggerd/loggerd.h (100%) rename {system => openpilot/system}/loggerd/tests/__init__.py (100%) rename {system => openpilot/system}/loggerd/tests/loggerd_tests_common.py (100%) rename {system => openpilot/system}/loggerd/tests/test_deleter.py (100%) rename {system => openpilot/system}/loggerd/tests/test_encoder.py (100%) rename {system => openpilot/system}/loggerd/tests/test_logger.cc (100%) rename {system => openpilot/system}/loggerd/tests/test_loggerd.py (100%) rename {system => openpilot/system}/loggerd/tests/test_runner.cc (100%) rename {system => openpilot/system}/loggerd/tests/test_uploader.py (100%) rename {system => openpilot/system}/loggerd/tests/test_zstd_writer.cc (100%) rename {system => openpilot/system}/loggerd/tests/vidc_debug.sh (100%) rename {system => openpilot/system}/loggerd/uploader.py (100%) rename {system => openpilot/system}/loggerd/video_writer.cc (100%) rename {system => openpilot/system}/loggerd/video_writer.h (100%) rename {system => openpilot/system}/loggerd/xattr_cache.py (100%) rename {system => openpilot/system}/loggerd/zstd_writer.cc (100%) rename {system => openpilot/system}/loggerd/zstd_writer.h (100%) rename {system => openpilot/system}/logmessaged.py (100%) rename {system => openpilot/system}/manager/__init__.py (100%) rename {system => openpilot/system}/manager/build.py (100%) rename {system => openpilot/system}/manager/helpers.py (100%) rename {system => openpilot/system}/manager/manager.py (100%) rename {system => openpilot/system}/manager/process.py (100%) rename {system => openpilot/system}/manager/process_config.py (100%) rename {system => openpilot/system}/manager/test/__init__.py (100%) rename {system => openpilot/system}/manager/test/test_manager.py (100%) rename {system => openpilot/system}/micd.py (100%) rename {system => openpilot/system}/proclogd.py (100%) rename {system => openpilot/system}/qcomgpsd/modemdiag.py (100%) rename {system => openpilot/system}/qcomgpsd/nmeaport.py (100%) rename {system => openpilot/system}/qcomgpsd/qcomgpsd.py (100%) rename {system => openpilot/system}/qcomgpsd/structs.py (100%) rename {system => openpilot/system}/sensord/__init__.py (100%) rename {system => openpilot/system}/sensord/sensord.py (100%) rename {system => openpilot/system}/sensord/sensors/__init__.py (100%) rename {system => openpilot/system}/sensord/sensors/i2c_sensor.py (100%) rename {system => openpilot/system}/sensord/sensors/lsm6ds3_accel.py (100%) rename {system => openpilot/system}/sensord/sensors/lsm6ds3_gyro.py (100%) rename {system => openpilot/system}/sensord/sensors/lsm6ds3_temp.py (100%) rename {system => openpilot/system}/sensord/tests/__init__.py (100%) rename {system => openpilot/system}/sensord/tests/test_sensord.py (100%) rename {system => openpilot/system}/sentry.py (100%) rename {system => openpilot/system}/tests/__init__.py (100%) rename {system => openpilot/system}/tests/test_logmessaged.py (100%) rename {system => openpilot/system}/timed.py (100%) rename {system => openpilot/system}/tombstoned.py (100%) rename {system => openpilot/system}/ubloxd/binary_struct.py (100%) rename {system => openpilot/system}/ubloxd/glonass.py (100%) rename {system => openpilot/system}/ubloxd/gps.py (100%) rename {system => openpilot/system}/ubloxd/pigeond.py (100%) rename {system => openpilot/system}/ubloxd/tests/test_pigeond.py (100%) rename {system => openpilot/system}/ubloxd/ubloxd.py (100%) rename {system => openpilot/system}/ubloxd/ubx.py (100%) rename {system => openpilot/system}/ui/README.md (100%) rename {system => openpilot/system}/ui/lib/__init__.py (100%) rename {system => openpilot/system}/ui/lib/application.py (100%) rename {system => openpilot/system}/ui/lib/egl.py (100%) rename {system => openpilot/system}/ui/lib/emoji.py (100%) rename {system => openpilot/system}/ui/lib/multilang.py (100%) rename {system => openpilot/system}/ui/lib/networkmanager.py (100%) rename {system => openpilot/system}/ui/lib/scroll_panel.py (100%) rename {system => openpilot/system}/ui/lib/scroll_panel2.py (100%) rename {system => openpilot/system}/ui/lib/shader_polygon.py (100%) rename {system => openpilot/system}/ui/lib/tests/test_handle_state_change.py (100%) rename {system => openpilot/system}/ui/lib/text_measure.py (100%) rename {system => openpilot/system}/ui/lib/utils.py (100%) rename {system => openpilot/system}/ui/lib/wifi_manager.py (100%) rename {system => openpilot/system}/ui/lib/wrap_text.py (100%) rename {system => openpilot/system}/ui/mici_reset.py (100%) rename {system => openpilot/system}/ui/mici_setup.py (100%) rename {system => openpilot/system}/ui/mici_updater.py (100%) rename {system => openpilot/system}/ui/reset.py (100%) rename {system => openpilot/system}/ui/setup.py (100%) rename {system => openpilot/system}/ui/spinner.py (100%) rename {system => openpilot/system}/ui/text.py (100%) rename {system => openpilot/system}/ui/tici_reset.py (100%) rename {system => openpilot/system}/ui/tici_setup.py (100%) rename {system => openpilot/system}/ui/tici_updater.py (100%) rename {system => openpilot/system}/ui/updater.py (100%) rename {system => openpilot/system}/ui/widgets/__init__.py (100%) rename {system => openpilot/system}/ui/widgets/button.py (100%) rename {system => openpilot/system}/ui/widgets/confirm_dialog.py (100%) rename {system => openpilot/system}/ui/widgets/html_render.py (100%) rename {system => openpilot/system}/ui/widgets/icon_widget.py (100%) rename {system => openpilot/system}/ui/widgets/inputbox.py (100%) rename {system => openpilot/system}/ui/widgets/keyboard.py (100%) rename {system => openpilot/system}/ui/widgets/label.py (100%) rename {system => openpilot/system}/ui/widgets/layouts.py (100%) rename {system => openpilot/system}/ui/widgets/list_view.py (100%) rename {system => openpilot/system}/ui/widgets/mici_keyboard.py (100%) rename {system => openpilot/system}/ui/widgets/nav_widget.py (100%) rename {system => openpilot/system}/ui/widgets/network.py (100%) rename {system => openpilot/system}/ui/widgets/option_dialog.py (100%) rename {system => openpilot/system}/ui/widgets/scroller.py (100%) rename {system => openpilot/system}/ui/widgets/scroller_tici.py (100%) rename {system => openpilot/system}/ui/widgets/slider.py (100%) rename {system => openpilot/system}/ui/widgets/toggle.py (100%) rename {system => openpilot/system}/updated/common.py (100%) rename {system => openpilot/system}/updated/updated.py (100%) rename {system => openpilot/system}/webrtc/__init__.py (100%) rename {system => openpilot/system}/webrtc/device/video.py (100%) rename {system => openpilot/system}/webrtc/helpers.py (100%) rename {system => openpilot/system}/webrtc/schema.py (100%) rename {system => openpilot/system}/webrtc/tests/test_stream_session.py (100%) rename {system => openpilot/system}/webrtc/webrtcd.py (100%) delete mode 120000 openpilot/tools rename {tools => openpilot/tools}/CTF.md (100%) rename {tools => openpilot/tools}/README.md (100%) rename {tools => openpilot/tools}/__init__.py (100%) rename {tools => openpilot/tools}/auto_source.py (100%) rename {tools => openpilot/tools}/cabana/.gitignore (100%) rename {tools => openpilot/tools}/cabana/README.md (100%) rename {tools => openpilot/tools}/cabana/SConscript (100%) rename {tools => openpilot/tools}/cabana/assets/assets.qrc (100%) rename {tools => openpilot/tools}/cabana/assets/cabana-icon.png (100%) rename {tools => openpilot/tools}/cabana/binaryview.cc (100%) rename {tools => openpilot/tools}/cabana/binaryview.h (100%) rename {tools => openpilot/tools}/cabana/cabana (100%) rename {tools => openpilot/tools}/cabana/cabana.cc (100%) rename {tools => openpilot/tools}/cabana/cameraview.cc (100%) rename {tools => openpilot/tools}/cabana/cameraview.h (100%) rename {tools => openpilot/tools}/cabana/chart/chart.cc (100%) rename {tools => openpilot/tools}/cabana/chart/chart.h (100%) rename {tools => openpilot/tools}/cabana/chart/chartswidget.cc (100%) rename {tools => openpilot/tools}/cabana/chart/chartswidget.h (100%) rename {tools => openpilot/tools}/cabana/chart/signalselector.cc (100%) rename {tools => openpilot/tools}/cabana/chart/signalselector.h (100%) rename {tools => openpilot/tools}/cabana/chart/sparkline.cc (100%) rename {tools => openpilot/tools}/cabana/chart/sparkline.h (100%) rename {tools => openpilot/tools}/cabana/chart/tiplabel.cc (100%) rename {tools => openpilot/tools}/cabana/chart/tiplabel.h (100%) rename {tools => openpilot/tools}/cabana/commands.cc (100%) rename {tools => openpilot/tools}/cabana/commands.h (100%) rename {tools => openpilot/tools}/cabana/dbc/dbc.cc (100%) rename {tools => openpilot/tools}/cabana/dbc/dbc.h (100%) rename {tools => openpilot/tools}/cabana/dbc/dbcfile.cc (100%) rename {tools => openpilot/tools}/cabana/dbc/dbcfile.h (100%) rename {tools => openpilot/tools}/cabana/dbc/dbcmanager.cc (100%) rename {tools => openpilot/tools}/cabana/dbc/dbcmanager.h (100%) rename {tools => openpilot/tools}/cabana/dbc/generate_dbc_json.py (100%) rename {tools => openpilot/tools}/cabana/detailwidget.cc (100%) rename {tools => openpilot/tools}/cabana/detailwidget.h (100%) rename {tools => openpilot/tools}/cabana/historylog.cc (100%) rename {tools => openpilot/tools}/cabana/historylog.h (100%) rename {tools => openpilot/tools}/cabana/mainwin.cc (100%) rename {tools => openpilot/tools}/cabana/mainwin.h (100%) rename {tools => openpilot/tools}/cabana/messageswidget.cc (100%) rename {tools => openpilot/tools}/cabana/messageswidget.h (100%) rename {tools => openpilot/tools}/cabana/panda.cc (100%) rename {tools => openpilot/tools}/cabana/panda.h (100%) rename {tools => openpilot/tools}/cabana/settings.cc (100%) rename {tools => openpilot/tools}/cabana/settings.h (100%) rename {tools => openpilot/tools}/cabana/signalview.cc (100%) rename {tools => openpilot/tools}/cabana/signalview.h (100%) rename {tools => openpilot/tools}/cabana/streams/abstractstream.cc (100%) rename {tools => openpilot/tools}/cabana/streams/abstractstream.h (100%) rename {tools => openpilot/tools}/cabana/streams/devicestream.cc (100%) rename {tools => openpilot/tools}/cabana/streams/devicestream.h (100%) rename {tools => openpilot/tools}/cabana/streams/livestream.cc (100%) rename {tools => openpilot/tools}/cabana/streams/livestream.h (100%) rename {tools => openpilot/tools}/cabana/streams/pandastream.cc (100%) rename {tools => openpilot/tools}/cabana/streams/pandastream.h (100%) rename {tools => openpilot/tools}/cabana/streams/replaystream.cc (100%) rename {tools => openpilot/tools}/cabana/streams/replaystream.h (100%) rename {tools => openpilot/tools}/cabana/streams/routes.cc (100%) rename {tools => openpilot/tools}/cabana/streams/routes.h (100%) rename {tools => openpilot/tools}/cabana/streams/socketcanstream.cc (100%) rename {tools => openpilot/tools}/cabana/streams/socketcanstream.h (100%) rename {tools => openpilot/tools}/cabana/streamselector.cc (100%) rename {tools => openpilot/tools}/cabana/streamselector.h (100%) rename {tools => openpilot/tools}/cabana/tests/test_cabana.cc (100%) rename {tools => openpilot/tools}/cabana/tests/test_runner.cc (100%) rename {tools => openpilot/tools}/cabana/tools/findsignal.cc (100%) rename {tools => openpilot/tools}/cabana/tools/findsignal.h (100%) rename {tools => openpilot/tools}/cabana/tools/findsimilarbits.cc (100%) rename {tools => openpilot/tools}/cabana/tools/findsimilarbits.h (100%) rename {tools => openpilot/tools}/cabana/tools/routeinfo.cc (100%) rename {tools => openpilot/tools}/cabana/tools/routeinfo.h (100%) rename {tools => openpilot/tools}/cabana/utils/elidedlabel.cc (100%) rename {tools => openpilot/tools}/cabana/utils/elidedlabel.h (100%) rename {tools => openpilot/tools}/cabana/utils/export.cc (100%) rename {tools => openpilot/tools}/cabana/utils/export.h (100%) rename {tools => openpilot/tools}/cabana/utils/util.cc (100%) rename {tools => openpilot/tools}/cabana/utils/util.h (100%) rename {tools => openpilot/tools}/cabana/videowidget.cc (100%) rename {tools => openpilot/tools}/cabana/videowidget.h (100%) rename {tools => openpilot/tools}/camerastream/README.md (100%) rename {tools => openpilot/tools}/camerastream/compressed_vipc.py (100%) rename {tools => openpilot/tools}/car_porting/README.md (100%) rename {tools => openpilot/tools}/car_porting/auto_fingerprint.py (100%) rename {tools => openpilot/tools}/car_porting/examples/find_segments_with_message.ipynb (100%) rename {tools => openpilot/tools}/car_porting/examples/ford_vin_fingerprint.ipynb (100%) rename {tools => openpilot/tools}/car_porting/examples/hkg_canfd_gear_message.ipynb (100%) rename {tools => openpilot/tools}/car_porting/examples/subaru_fuzzy_fingerprint.ipynb (100%) rename {tools => openpilot/tools}/car_porting/examples/subaru_long_accel.ipynb (100%) rename {tools => openpilot/tools}/car_porting/examples/subaru_steer_temp_fault.ipynb (100%) rename {tools => openpilot/tools}/car_porting/measure_steering_accuracy.py (100%) rename {tools => openpilot/tools}/car_porting/test_car_model.py (100%) rename {tools => openpilot/tools}/clip/run.py (100%) rename {tools => openpilot/tools}/jotpluggler/.gitignore (100%) rename {tools => openpilot/tools}/jotpluggler/SConscript (100%) rename {tools => openpilot/tools}/jotpluggler/app.cc (100%) rename {tools => openpilot/tools}/jotpluggler/app.h (100%) rename {tools => openpilot/tools}/jotpluggler/browser.cc (100%) rename {tools => openpilot/tools}/jotpluggler/camera.cc (100%) rename {tools => openpilot/tools}/jotpluggler/camera.h (100%) rename {tools => openpilot/tools}/jotpluggler/common.cc (100%) rename {tools => openpilot/tools}/jotpluggler/common.h (100%) rename {tools => openpilot/tools}/jotpluggler/custom_series.cc (100%) rename {tools => openpilot/tools}/jotpluggler/dbc.h (100%) rename {tools => openpilot/tools}/jotpluggler/generate_event_extractors.py (100%) rename {tools => openpilot/tools}/jotpluggler/generated_dbcs/.gitignore (100%) rename {tools => openpilot/tools}/jotpluggler/icons.cc (100%) rename {tools => openpilot/tools}/jotpluggler/internal.h (100%) rename {tools => openpilot/tools}/jotpluggler/layout.cc (100%) rename {tools => openpilot/tools}/jotpluggler/layout_io.cc (100%) rename {tools => openpilot/tools}/jotpluggler/layouts/.gitignore (100%) rename {tools => openpilot/tools}/jotpluggler/layouts/CAN-bus-debug.json (100%) rename {tools => openpilot/tools}/jotpluggler/layouts/camera-timings.json (100%) rename {tools => openpilot/tools}/jotpluggler/layouts/cameras-and-map.json (100%) rename {tools => openpilot/tools}/jotpluggler/layouts/can-states.json (100%) rename {tools => openpilot/tools}/jotpluggler/layouts/controls_mismatch_debug.json (100%) rename {tools => openpilot/tools}/jotpluggler/layouts/driver-monitoring-debug.json (100%) rename {tools => openpilot/tools}/jotpluggler/layouts/gps.json (100%) rename {tools => openpilot/tools}/jotpluggler/layouts/gps_vs_llk.json (100%) rename {tools => openpilot/tools}/jotpluggler/layouts/locationd_debug.json (100%) rename {tools => openpilot/tools}/jotpluggler/layouts/longitudinal.json (100%) rename {tools => openpilot/tools}/jotpluggler/layouts/max-torque-debug.json (100%) rename {tools => openpilot/tools}/jotpluggler/layouts/new-layout.json (100%) rename {tools => openpilot/tools}/jotpluggler/layouts/system_lag_debug.json (100%) rename {tools => openpilot/tools}/jotpluggler/layouts/thermal_debug.json (100%) rename {tools => openpilot/tools}/jotpluggler/layouts/torque-controller.json (100%) rename {tools => openpilot/tools}/jotpluggler/layouts/tuning.json (100%) rename {tools => openpilot/tools}/jotpluggler/layouts/ublox-debug.json (100%) rename {tools => openpilot/tools}/jotpluggler/logs.cc (100%) rename {tools => openpilot/tools}/jotpluggler/main.cc (100%) rename {tools => openpilot/tools}/jotpluggler/map.cc (100%) rename {tools => openpilot/tools}/jotpluggler/map.h (100%) rename {tools => openpilot/tools}/jotpluggler/math_eval.py (100%) rename {tools => openpilot/tools}/jotpluggler/plot.cc (100%) rename {tools => openpilot/tools}/jotpluggler/render.cc (100%) rename {tools => openpilot/tools}/jotpluggler/runtime.cc (100%) rename {tools => openpilot/tools}/jotpluggler/session.cc (100%) rename {tools => openpilot/tools}/jotpluggler/sidebar.cc (100%) rename {tools => openpilot/tools}/jotpluggler/sketch_layout.cc (100%) rename {tools => openpilot/tools}/jotpluggler/stream.cc (100%) rename {tools => openpilot/tools}/jotpluggler/util.cc (100%) rename {tools => openpilot/tools}/jotpluggler/util.h (100%) rename {tools => openpilot/tools}/joystick/README.md (100%) rename {tools => openpilot/tools}/joystick/joystick_control.py (100%) rename {tools => openpilot/tools}/joystick/joystickd.py (100%) rename {tools => openpilot/tools}/lateral_maneuvers/.gitignore (100%) rename {tools => openpilot/tools}/lateral_maneuvers/README.md (100%) rename {tools => openpilot/tools}/lateral_maneuvers/generate_report.py (100%) rename {tools => openpilot/tools}/lateral_maneuvers/lateral_maneuversd.py (100%) rename {tools => openpilot/tools}/lib/README.md (100%) rename {tools => openpilot/tools}/lib/__init__.py (100%) rename {tools => openpilot/tools}/lib/api.py (100%) rename {tools => openpilot/tools}/lib/auth.py (100%) rename {tools => openpilot/tools}/lib/auth_config.py (100%) rename {tools => openpilot/tools}/lib/azure_container.py (100%) rename {tools => openpilot/tools}/lib/bootlog.py (100%) rename {tools => openpilot/tools}/lib/cache.py (100%) rename {tools => openpilot/tools}/lib/comma_car_segments.py (100%) rename {tools => openpilot/tools}/lib/exceptions.py (100%) rename {tools => openpilot/tools}/lib/file_downloader.py (100%) rename {tools => openpilot/tools}/lib/file_sources.py (100%) rename {tools => openpilot/tools}/lib/filereader.py (100%) rename {tools => openpilot/tools}/lib/framereader.py (100%) rename {tools => openpilot/tools}/lib/github_utils.py (100%) rename {tools => openpilot/tools}/lib/helpers.py (100%) rename {tools => openpilot/tools}/lib/kbhit.py (100%) rename {tools => openpilot/tools}/lib/live_logreader.py (100%) rename {tools => openpilot/tools}/lib/log_time_series.py (100%) rename {tools => openpilot/tools}/lib/logreader.py (100%) rename {tools => openpilot/tools}/lib/openpilotci.py (100%) rename {tools => openpilot/tools}/lib/openpilotcontainers.py (100%) rename {tools => openpilot/tools}/lib/route.py (100%) rename {tools => openpilot/tools}/lib/sanitizer.py (100%) rename {tools => openpilot/tools}/lib/tests/__init__.py (100%) rename {tools => openpilot/tools}/lib/tests/test_caching.py (100%) rename {tools => openpilot/tools}/lib/tests/test_comma_car_segments.py (100%) rename {tools => openpilot/tools}/lib/tests/test_logreader.py (100%) rename {tools => openpilot/tools}/lib/tests/test_route_library.py (100%) rename {tools => openpilot/tools}/lib/url_file.py (100%) rename {tools => openpilot/tools}/lib/vidindex.py (100%) rename {tools => openpilot/tools}/longitudinal_maneuvers/.gitignore (100%) rename {tools => openpilot/tools}/longitudinal_maneuvers/README.md (100%) rename {tools => openpilot/tools}/longitudinal_maneuvers/generate_report.py (100%) rename {tools => openpilot/tools}/longitudinal_maneuvers/maneuver_helpers.py (100%) rename {tools => openpilot/tools}/longitudinal_maneuvers/maneuversd.py (100%) rename {tools => openpilot/tools}/longitudinal_maneuvers/mpc_longitudinal_tuning_report.py (100%) rename {tools => openpilot/tools}/op.sh (99%) rename {tools => openpilot/tools}/plotjuggler/README.md (100%) rename {tools => openpilot/tools}/plotjuggler/juggle.py (100%) rename {tools => openpilot/tools}/plotjuggler/layouts/CAN-bus-debug.xml (100%) rename {tools => openpilot/tools}/plotjuggler/layouts/camera-timings.xml (100%) rename {tools => openpilot/tools}/plotjuggler/layouts/can-states.xml (100%) rename {tools => openpilot/tools}/plotjuggler/layouts/controls_mismatch_debug.xml (100%) rename {tools => openpilot/tools}/plotjuggler/layouts/gps.xml (100%) rename {tools => openpilot/tools}/plotjuggler/layouts/gps_vs_llk.xml (100%) rename {tools => openpilot/tools}/plotjuggler/layouts/locationd_debug.xml (100%) rename {tools => openpilot/tools}/plotjuggler/layouts/longitudinal.xml (100%) rename {tools => openpilot/tools}/plotjuggler/layouts/max-torque-debug.xml (100%) rename {tools => openpilot/tools}/plotjuggler/layouts/system_lag_debug.xml (100%) rename {tools => openpilot/tools}/plotjuggler/layouts/thermal_debug.xml (100%) rename {tools => openpilot/tools}/plotjuggler/layouts/torque-controller.xml (100%) rename {tools => openpilot/tools}/plotjuggler/layouts/tuning.xml (100%) rename {tools => openpilot/tools}/plotjuggler/layouts/ublox-debug.xml (100%) rename {tools => openpilot/tools}/plotjuggler/test_plotjuggler.py (100%) rename {tools => openpilot/tools}/replay/.gitignore (100%) rename {tools => openpilot/tools}/replay/README.md (100%) rename {tools => openpilot/tools}/replay/SConscript (100%) rename {tools => openpilot/tools}/replay/__init__.py (100%) rename {tools => openpilot/tools}/replay/camera.cc (100%) rename {tools => openpilot/tools}/replay/camera.h (100%) rename {tools => openpilot/tools}/replay/can_replay.py (100%) rename {tools => openpilot/tools}/replay/consoleui.cc (100%) rename {tools => openpilot/tools}/replay/consoleui.h (100%) rename {tools => openpilot/tools}/replay/filereader.cc (100%) rename {tools => openpilot/tools}/replay/filereader.h (100%) rename {tools => openpilot/tools}/replay/framereader.cc (100%) rename {tools => openpilot/tools}/replay/framereader.h (100%) rename {tools => openpilot/tools}/replay/lib/__init__.py (100%) rename {tools => openpilot/tools}/replay/lib/ui_helpers.py (100%) rename {tools => openpilot/tools}/replay/logreader.cc (100%) rename {tools => openpilot/tools}/replay/logreader.h (100%) rename {tools => openpilot/tools}/replay/main.cc (100%) rename {tools => openpilot/tools}/replay/py_downloader.cc (100%) rename {tools => openpilot/tools}/replay/py_downloader.h (100%) rename {tools => openpilot/tools}/replay/qcom_decoder.cc (100%) rename {tools => openpilot/tools}/replay/qcom_decoder.h (100%) rename {tools => openpilot/tools}/replay/replay.cc (100%) rename {tools => openpilot/tools}/replay/replay.h (100%) rename {tools => openpilot/tools}/replay/route.cc (100%) rename {tools => openpilot/tools}/replay/route.h (100%) rename {tools => openpilot/tools}/replay/seg_mgr.cc (100%) rename {tools => openpilot/tools}/replay/seg_mgr.h (100%) rename {tools => openpilot/tools}/replay/tests/test_replay.cc (100%) rename {tools => openpilot/tools}/replay/timeline.cc (100%) rename {tools => openpilot/tools}/replay/timeline.h (100%) rename {tools => openpilot/tools}/replay/ui.py (100%) rename {tools => openpilot/tools}/replay/util.cc (100%) rename {tools => openpilot/tools}/replay/util.h (100%) rename {tools => openpilot/tools}/scripts/__init__.py (100%) rename {tools => openpilot/tools}/scripts/adb_ssh.sh (100%) rename {tools => openpilot/tools}/scripts/car/can_print_changes.py (100%) rename {tools => openpilot/tools}/scripts/car/can_printer.py (100%) rename {tools => openpilot/tools}/scripts/car/can_table.py (100%) rename {tools => openpilot/tools}/scripts/car/clear_dtc.py (100%) rename {tools => openpilot/tools}/scripts/car/disable_ecu.py (100%) rename {tools => openpilot/tools}/scripts/car/ecu_addrs.py (100%) rename {tools => openpilot/tools}/scripts/car/fw_versions.py (100%) rename {tools => openpilot/tools}/scripts/car/hyundai_enable_radar_points.py (100%) rename {tools => openpilot/tools}/scripts/car/max_lat_accel.py (100%) rename {tools => openpilot/tools}/scripts/car/measure_torque_time_to_max.py (100%) rename {tools => openpilot/tools}/scripts/car/read_dtc_status.py (100%) rename {tools => openpilot/tools}/scripts/car/toyota_eps_factor.py (100%) rename {tools => openpilot/tools}/scripts/car/vin.py (100%) rename {tools => openpilot/tools}/scripts/car/vw_mqb_config.py (100%) rename {tools => openpilot/tools}/scripts/count_events.py (100%) rename {tools => openpilot/tools}/scripts/cpu_usage_stat.py (100%) rename {tools => openpilot/tools}/scripts/cycle_alerts.py (100%) rename {tools => openpilot/tools}/scripts/debug_fw_fingerprinting_offline.py (100%) rename {tools => openpilot/tools}/scripts/devsync.py (100%) rename {tools => openpilot/tools}/scripts/dump.py (100%) rename {tools => openpilot/tools}/scripts/extract_audio.py (100%) rename {tools => openpilot/tools}/scripts/filter_log_message.py (100%) rename {tools => openpilot/tools}/scripts/fingerprint_from_route.py (100%) rename {tools => openpilot/tools}/scripts/fuzz_fw_fingerprint.py (100%) rename {tools => openpilot/tools}/scripts/get_fingerprint.py (100%) rename {tools => openpilot/tools}/scripts/live_cpu_and_temp.py (100%) rename {tools => openpilot/tools}/scripts/mem_usage.py (100%) rename {tools => openpilot/tools}/scripts/print_flags.py (100%) rename {tools => openpilot/tools}/scripts/profiling/clpeak/.gitignore (100%) rename {tools => openpilot/tools}/scripts/profiling/clpeak/build.sh (100%) rename {tools => openpilot/tools}/scripts/profiling/clpeak/no_print.patch (100%) rename {tools => openpilot/tools}/scripts/profiling/clpeak/run_continuously.patch (100%) rename {tools => openpilot/tools}/scripts/profiling/ftrace.sh (100%) rename {tools => openpilot/tools}/scripts/profiling/palanteer/.gitignore (100%) rename {tools => openpilot/tools}/scripts/profiling/palanteer/setup.sh (100%) rename {tools => openpilot/tools}/scripts/profiling/perfetto/.gitignore (100%) rename {tools => openpilot/tools}/scripts/profiling/perfetto/build.sh (100%) rename {tools => openpilot/tools}/scripts/profiling/perfetto/copy.sh (100%) rename {tools => openpilot/tools}/scripts/profiling/perfetto/record.sh (100%) rename {tools => openpilot/tools}/scripts/profiling/perfetto/server.sh (100%) rename {tools => openpilot/tools}/scripts/profiling/perfetto/traces.sh (100%) rename {tools => openpilot/tools}/scripts/profiling/py-spy/profile.sh (100%) rename {tools => openpilot/tools}/scripts/profiling/snapdragon/.gitignore (100%) rename {tools => openpilot/tools}/scripts/profiling/snapdragon/README.md (100%) rename {tools => openpilot/tools}/scripts/profiling/snapdragon/setup-agnos.sh (100%) rename {tools => openpilot/tools}/scripts/profiling/snapdragon/setup-profiler.sh (100%) rename {tools => openpilot/tools}/scripts/profiling/watch-irqs.sh (100%) rename {tools => openpilot/tools}/scripts/qlog_size.py (100%) rename {tools => openpilot/tools}/scripts/run_process_on_route.py (100%) rename {tools => openpilot/tools}/scripts/serial.sh (100%) rename {tools => openpilot/tools}/scripts/set_car_params.py (100%) rename {tools => openpilot/tools}/scripts/setup_ssh_keys.py (100%) rename {tools => openpilot/tools}/scripts/ssh.py (100%) rename {tools => openpilot/tools}/scripts/test_fw_query_on_routes.py (100%) rename {tools => openpilot/tools}/scripts/uiview.py (100%) rename {tools => openpilot/tools}/scripts/watch_timings.py (100%) rename {tools => openpilot/tools}/setup.sh (100%) rename {tools => openpilot/tools}/setup_dependencies.sh (100%) rename {tools => openpilot/tools}/sim/README.md (100%) rename {tools => openpilot/tools}/sim/__init__.py (100%) rename {tools => openpilot/tools}/sim/bridge/__init__.py (100%) rename {tools => openpilot/tools}/sim/bridge/common.py (100%) rename {tools => openpilot/tools}/sim/bridge/metadrive/metadrive_bridge.py (100%) rename {tools => openpilot/tools}/sim/bridge/metadrive/metadrive_common.py (100%) rename {tools => openpilot/tools}/sim/bridge/metadrive/metadrive_process.py (100%) rename {tools => openpilot/tools}/sim/bridge/metadrive/metadrive_world.py (100%) rename {tools => openpilot/tools}/sim/launch_openpilot.sh (100%) rename {tools => openpilot/tools}/sim/lib/__init__.py (100%) rename {tools => openpilot/tools}/sim/lib/camerad.py (100%) rename {tools => openpilot/tools}/sim/lib/common.py (100%) rename {tools => openpilot/tools}/sim/lib/keyboard_ctrl.py (100%) rename {tools => openpilot/tools}/sim/lib/manual_ctrl.py (100%) rename {tools => openpilot/tools}/sim/lib/simulated_car.py (100%) rename {tools => openpilot/tools}/sim/lib/simulated_sensors.py (100%) rename {tools => openpilot/tools}/sim/run_bridge.py (100%) rename {tools => openpilot/tools}/sim/tests/__init__.py (100%) rename {tools => openpilot/tools}/sim/tests/conftest.py (100%) rename {tools => openpilot/tools}/sim/tests/test_metadrive_bridge.py (100%) rename {tools => openpilot/tools}/sim/tests/test_sim_bridge.py (100%) diff --git a/.gitattributes b/.gitattributes index 507eb73c13..1cf541aa3a 100644 --- a/.gitattributes +++ b/.gitattributes @@ -10,5 +10,5 @@ *.otf filter=lfs diff=lfs merge=lfs -text *.wav filter=lfs diff=lfs merge=lfs -text -selfdrive/car/tests/test_models_segs.txt filter=lfs diff=lfs merge=lfs -text -common/hardware/tici/updater filter=lfs diff=lfs merge=lfs -text +openpilot/selfdrive/car/tests/test_models_segs.txt filter=lfs diff=lfs merge=lfs -text +openpilot/common/hardware/tici/updater filter=lfs diff=lfs merge=lfs -text diff --git a/.gitignore b/.gitignore index 35a2fe8c5e..6581b90e7c 100644 --- a/.gitignore +++ b/.gitignore @@ -44,18 +44,18 @@ bin/ config.json compile_commands.json compare_runtime*.html -selfdrive/modeld/models/tg_input_devices.json +openpilot/selfdrive/modeld/models/tg_input_devices.json # build artifacts docs_site/ -selfdrive/pandad/pandad +openpilot/selfdrive/pandad/pandad openpilot/cereal/services.h openpilot/cereal/gen openpilot/cereal/messaging/bridge -selfdrive/ui/translations/tmp -selfdrive/car/tests/cars_dump -system/camerad/camerad -system/camerad/test/ae_gray_test +openpilot/selfdrive/ui/translations/tmp +openpilot/selfdrive/car/tests/cars_dump +openpilot/system/camerad/camerad +openpilot/system/camerad/test/ae_gray_test .coverage* coverage.xml diff --git a/openpilot/common b/openpilot/common deleted file mode 120000 index 60d3b0a6a8..0000000000 --- a/openpilot/common +++ /dev/null @@ -1 +0,0 @@ -../common \ No newline at end of file diff --git a/common/SConscript b/openpilot/common/SConscript similarity index 100% rename from common/SConscript rename to openpilot/common/SConscript diff --git a/common/__init__.py b/openpilot/common/__init__.py similarity index 100% rename from common/__init__.py rename to openpilot/common/__init__.py diff --git a/common/api.py b/openpilot/common/api.py similarity index 100% rename from common/api.py rename to openpilot/common/api.py diff --git a/common/basedir.py b/openpilot/common/basedir.py similarity index 71% rename from common/basedir.py rename to openpilot/common/basedir.py index 6b4811e53c..49b092d930 100644 --- a/common/basedir.py +++ b/openpilot/common/basedir.py @@ -1,4 +1,4 @@ import os -BASEDIR = os.path.abspath(os.path.join(os.path.dirname(os.path.realpath(__file__)), "../")) +BASEDIR = os.path.abspath(os.path.join(os.path.dirname(os.path.realpath(__file__)), "../..")) diff --git a/common/constants.py b/openpilot/common/constants.py similarity index 100% rename from common/constants.py rename to openpilot/common/constants.py diff --git a/common/esim/__init__.py b/openpilot/common/esim/__init__.py similarity index 100% rename from common/esim/__init__.py rename to openpilot/common/esim/__init__.py diff --git a/common/esim/base.py b/openpilot/common/esim/base.py similarity index 100% rename from common/esim/base.py rename to openpilot/common/esim/base.py diff --git a/common/esim/esim.py b/openpilot/common/esim/esim.py similarity index 100% rename from common/esim/esim.py rename to openpilot/common/esim/esim.py diff --git a/common/esim/gsma_ci_bundle.pem b/openpilot/common/esim/gsma_ci_bundle.pem similarity index 100% rename from common/esim/gsma_ci_bundle.pem rename to openpilot/common/esim/gsma_ci_bundle.pem diff --git a/common/esim/lpa.py b/openpilot/common/esim/lpa.py similarity index 100% rename from common/esim/lpa.py rename to openpilot/common/esim/lpa.py diff --git a/common/file_chunker.py b/openpilot/common/file_chunker.py similarity index 100% rename from common/file_chunker.py rename to openpilot/common/file_chunker.py diff --git a/common/filter_simple.py b/openpilot/common/filter_simple.py similarity index 100% rename from common/filter_simple.py rename to openpilot/common/filter_simple.py diff --git a/common/git.py b/openpilot/common/git.py similarity index 100% rename from common/git.py rename to openpilot/common/git.py diff --git a/common/gpio.py b/openpilot/common/gpio.py similarity index 100% rename from common/gpio.py rename to openpilot/common/gpio.py diff --git a/common/gps.py b/openpilot/common/gps.py similarity index 100% rename from common/gps.py rename to openpilot/common/gps.py diff --git a/common/hardware/__init__.py b/openpilot/common/hardware/__init__.py similarity index 100% rename from common/hardware/__init__.py rename to openpilot/common/hardware/__init__.py diff --git a/common/hardware/base.h b/openpilot/common/hardware/base.h similarity index 100% rename from common/hardware/base.h rename to openpilot/common/hardware/base.h diff --git a/common/hardware/base.py b/openpilot/common/hardware/base.py similarity index 100% rename from common/hardware/base.py rename to openpilot/common/hardware/base.py diff --git a/common/hardware/hw.h b/openpilot/common/hardware/hw.h similarity index 100% rename from common/hardware/hw.h rename to openpilot/common/hardware/hw.h diff --git a/common/hardware/hw.py b/openpilot/common/hardware/hw.py similarity index 100% rename from common/hardware/hw.py rename to openpilot/common/hardware/hw.py diff --git a/common/hardware/pc/__init__.py b/openpilot/common/hardware/pc/__init__.py similarity index 100% rename from common/hardware/pc/__init__.py rename to openpilot/common/hardware/pc/__init__.py diff --git a/common/hardware/pc/hardware.h b/openpilot/common/hardware/pc/hardware.h similarity index 100% rename from common/hardware/pc/hardware.h rename to openpilot/common/hardware/pc/hardware.h diff --git a/common/hardware/pc/hardware.py b/openpilot/common/hardware/pc/hardware.py similarity index 100% rename from common/hardware/pc/hardware.py rename to openpilot/common/hardware/pc/hardware.py diff --git a/common/hardware/tici/__init__.py b/openpilot/common/hardware/tici/__init__.py similarity index 100% rename from common/hardware/tici/__init__.py rename to openpilot/common/hardware/tici/__init__.py diff --git a/common/hardware/tici/agnos.json b/openpilot/common/hardware/tici/agnos.json similarity index 100% rename from common/hardware/tici/agnos.json rename to openpilot/common/hardware/tici/agnos.json diff --git a/common/hardware/tici/agnos.py b/openpilot/common/hardware/tici/agnos.py similarity index 100% rename from common/hardware/tici/agnos.py rename to openpilot/common/hardware/tici/agnos.py diff --git a/common/hardware/tici/all-partitions.json b/openpilot/common/hardware/tici/all-partitions.json similarity index 100% rename from common/hardware/tici/all-partitions.json rename to openpilot/common/hardware/tici/all-partitions.json diff --git a/common/hardware/tici/amplifier.py b/openpilot/common/hardware/tici/amplifier.py similarity index 100% rename from common/hardware/tici/amplifier.py rename to openpilot/common/hardware/tici/amplifier.py diff --git a/common/hardware/tici/hardware.h b/openpilot/common/hardware/tici/hardware.h similarity index 100% rename from common/hardware/tici/hardware.h rename to openpilot/common/hardware/tici/hardware.h diff --git a/common/hardware/tici/hardware.py b/openpilot/common/hardware/tici/hardware.py similarity index 100% rename from common/hardware/tici/hardware.py rename to openpilot/common/hardware/tici/hardware.py diff --git a/common/hardware/tici/id_rsa b/openpilot/common/hardware/tici/id_rsa similarity index 100% rename from common/hardware/tici/id_rsa rename to openpilot/common/hardware/tici/id_rsa diff --git a/common/hardware/tici/modem.py b/openpilot/common/hardware/tici/modem.py similarity index 100% rename from common/hardware/tici/modem.py rename to openpilot/common/hardware/tici/modem.py diff --git a/common/hardware/tici/pins.py b/openpilot/common/hardware/tici/pins.py similarity index 100% rename from common/hardware/tici/pins.py rename to openpilot/common/hardware/tici/pins.py diff --git a/common/hardware/tici/power_monitor.py b/openpilot/common/hardware/tici/power_monitor.py similarity index 100% rename from common/hardware/tici/power_monitor.py rename to openpilot/common/hardware/tici/power_monitor.py diff --git a/common/hardware/tici/tests/__init__.py b/openpilot/common/hardware/tici/tests/__init__.py similarity index 100% rename from common/hardware/tici/tests/__init__.py rename to openpilot/common/hardware/tici/tests/__init__.py diff --git a/common/hardware/tici/tests/test_agnos_updater.py b/openpilot/common/hardware/tici/tests/test_agnos_updater.py similarity index 100% rename from common/hardware/tici/tests/test_agnos_updater.py rename to openpilot/common/hardware/tici/tests/test_agnos_updater.py diff --git a/common/hardware/tici/tests/test_amplifier.py b/openpilot/common/hardware/tici/tests/test_amplifier.py similarity index 100% rename from common/hardware/tici/tests/test_amplifier.py rename to openpilot/common/hardware/tici/tests/test_amplifier.py diff --git a/common/hardware/tici/updater b/openpilot/common/hardware/tici/updater similarity index 100% rename from common/hardware/tici/updater rename to openpilot/common/hardware/tici/updater diff --git a/common/i2c.py b/openpilot/common/i2c.py similarity index 100% rename from common/i2c.py rename to openpilot/common/i2c.py diff --git a/common/logging_extra.py b/openpilot/common/logging_extra.py similarity index 100% rename from common/logging_extra.py rename to openpilot/common/logging_extra.py diff --git a/common/markdown.py b/openpilot/common/markdown.py similarity index 100% rename from common/markdown.py rename to openpilot/common/markdown.py diff --git a/common/mock/__init__.py b/openpilot/common/mock/__init__.py similarity index 100% rename from common/mock/__init__.py rename to openpilot/common/mock/__init__.py diff --git a/common/mock/generators.py b/openpilot/common/mock/generators.py similarity index 100% rename from common/mock/generators.py rename to openpilot/common/mock/generators.py diff --git a/common/parameterized.py b/openpilot/common/parameterized.py similarity index 100% rename from common/parameterized.py rename to openpilot/common/parameterized.py diff --git a/common/params.cc b/openpilot/common/params.cc similarity index 100% rename from common/params.cc rename to openpilot/common/params.cc diff --git a/common/params.h b/openpilot/common/params.h similarity index 100% rename from common/params.h rename to openpilot/common/params.h diff --git a/common/params.py b/openpilot/common/params.py similarity index 100% rename from common/params.py rename to openpilot/common/params.py diff --git a/common/params_keys.h b/openpilot/common/params_keys.h similarity index 100% rename from common/params_keys.h rename to openpilot/common/params_keys.h diff --git a/common/params_pyx.pyx b/openpilot/common/params_pyx.pyx similarity index 100% rename from common/params_pyx.pyx rename to openpilot/common/params_pyx.pyx diff --git a/common/pid.py b/openpilot/common/pid.py similarity index 100% rename from common/pid.py rename to openpilot/common/pid.py diff --git a/common/prefix.h b/openpilot/common/prefix.h similarity index 100% rename from common/prefix.h rename to openpilot/common/prefix.h diff --git a/common/prefix.py b/openpilot/common/prefix.py similarity index 100% rename from common/prefix.py rename to openpilot/common/prefix.py diff --git a/common/queue.h b/openpilot/common/queue.h similarity index 100% rename from common/queue.h rename to openpilot/common/queue.h diff --git a/common/ratekeeper.cc b/openpilot/common/ratekeeper.cc similarity index 100% rename from common/ratekeeper.cc rename to openpilot/common/ratekeeper.cc diff --git a/common/ratekeeper.h b/openpilot/common/ratekeeper.h similarity index 100% rename from common/ratekeeper.h rename to openpilot/common/ratekeeper.h diff --git a/common/realtime.py b/openpilot/common/realtime.py similarity index 100% rename from common/realtime.py rename to openpilot/common/realtime.py diff --git a/common/simple_kalman.py b/openpilot/common/simple_kalman.py similarity index 100% rename from common/simple_kalman.py rename to openpilot/common/simple_kalman.py diff --git a/common/spinner.py b/openpilot/common/spinner.py similarity index 100% rename from common/spinner.py rename to openpilot/common/spinner.py diff --git a/common/stat_live.py b/openpilot/common/stat_live.py similarity index 100% rename from common/stat_live.py rename to openpilot/common/stat_live.py diff --git a/common/swaglog.cc b/openpilot/common/swaglog.cc similarity index 100% rename from common/swaglog.cc rename to openpilot/common/swaglog.cc diff --git a/common/swaglog.h b/openpilot/common/swaglog.h similarity index 100% rename from common/swaglog.h rename to openpilot/common/swaglog.h diff --git a/common/swaglog.py b/openpilot/common/swaglog.py similarity index 100% rename from common/swaglog.py rename to openpilot/common/swaglog.py diff --git a/common/tests/.gitignore b/openpilot/common/tests/.gitignore similarity index 100% rename from common/tests/.gitignore rename to openpilot/common/tests/.gitignore diff --git a/common/tests/__init__.py b/openpilot/common/tests/__init__.py similarity index 100% rename from common/tests/__init__.py rename to openpilot/common/tests/__init__.py diff --git a/common/tests/test_file_helpers.py b/openpilot/common/tests/test_file_helpers.py similarity index 100% rename from common/tests/test_file_helpers.py rename to openpilot/common/tests/test_file_helpers.py diff --git a/common/tests/test_markdown.py b/openpilot/common/tests/test_markdown.py similarity index 100% rename from common/tests/test_markdown.py rename to openpilot/common/tests/test_markdown.py diff --git a/common/tests/test_params.cc b/openpilot/common/tests/test_params.cc similarity index 100% rename from common/tests/test_params.cc rename to openpilot/common/tests/test_params.cc diff --git a/common/tests/test_params.py b/openpilot/common/tests/test_params.py similarity index 100% rename from common/tests/test_params.py rename to openpilot/common/tests/test_params.py diff --git a/common/tests/test_runner.cc b/openpilot/common/tests/test_runner.cc similarity index 100% rename from common/tests/test_runner.cc rename to openpilot/common/tests/test_runner.cc diff --git a/common/tests/test_simple_kalman.py b/openpilot/common/tests/test_simple_kalman.py similarity index 100% rename from common/tests/test_simple_kalman.py rename to openpilot/common/tests/test_simple_kalman.py diff --git a/common/tests/test_swaglog.cc b/openpilot/common/tests/test_swaglog.cc similarity index 100% rename from common/tests/test_swaglog.cc rename to openpilot/common/tests/test_swaglog.cc diff --git a/common/tests/test_util.cc b/openpilot/common/tests/test_util.cc similarity index 100% rename from common/tests/test_util.cc rename to openpilot/common/tests/test_util.cc diff --git a/common/text_window.py b/openpilot/common/text_window.py similarity index 100% rename from common/text_window.py rename to openpilot/common/text_window.py diff --git a/common/time_helpers.py b/openpilot/common/time_helpers.py similarity index 100% rename from common/time_helpers.py rename to openpilot/common/time_helpers.py diff --git a/common/timeout.py b/openpilot/common/timeout.py similarity index 100% rename from common/timeout.py rename to openpilot/common/timeout.py diff --git a/common/timing.h b/openpilot/common/timing.h similarity index 100% rename from common/timing.h rename to openpilot/common/timing.h diff --git a/common/transformations/README.md b/openpilot/common/transformations/README.md similarity index 100% rename from common/transformations/README.md rename to openpilot/common/transformations/README.md diff --git a/common/transformations/__init__.py b/openpilot/common/transformations/__init__.py similarity index 100% rename from common/transformations/__init__.py rename to openpilot/common/transformations/__init__.py diff --git a/common/transformations/camera.py b/openpilot/common/transformations/camera.py similarity index 100% rename from common/transformations/camera.py rename to openpilot/common/transformations/camera.py diff --git a/common/transformations/coordinates.py b/openpilot/common/transformations/coordinates.py similarity index 100% rename from common/transformations/coordinates.py rename to openpilot/common/transformations/coordinates.py diff --git a/common/transformations/model.py b/openpilot/common/transformations/model.py similarity index 100% rename from common/transformations/model.py rename to openpilot/common/transformations/model.py diff --git a/common/transformations/orientation.py b/openpilot/common/transformations/orientation.py similarity index 100% rename from common/transformations/orientation.py rename to openpilot/common/transformations/orientation.py diff --git a/common/transformations/tests/__init__.py b/openpilot/common/transformations/tests/__init__.py similarity index 100% rename from common/transformations/tests/__init__.py rename to openpilot/common/transformations/tests/__init__.py diff --git a/common/transformations/tests/test_coordinates.py b/openpilot/common/transformations/tests/test_coordinates.py similarity index 100% rename from common/transformations/tests/test_coordinates.py rename to openpilot/common/transformations/tests/test_coordinates.py diff --git a/common/transformations/tests/test_orientation.py b/openpilot/common/transformations/tests/test_orientation.py similarity index 100% rename from common/transformations/tests/test_orientation.py rename to openpilot/common/transformations/tests/test_orientation.py diff --git a/common/transformations/transformations.py b/openpilot/common/transformations/transformations.py similarity index 100% rename from common/transformations/transformations.py rename to openpilot/common/transformations/transformations.py diff --git a/common/util.cc b/openpilot/common/util.cc similarity index 100% rename from common/util.cc rename to openpilot/common/util.cc diff --git a/common/util.h b/openpilot/common/util.h similarity index 100% rename from common/util.h rename to openpilot/common/util.h diff --git a/common/utils.py b/openpilot/common/utils.py similarity index 100% rename from common/utils.py rename to openpilot/common/utils.py diff --git a/common/version.h b/openpilot/common/version.h similarity index 100% rename from common/version.h rename to openpilot/common/version.h diff --git a/common/version.py b/openpilot/common/version.py similarity index 100% rename from common/version.py rename to openpilot/common/version.py diff --git a/openpilot/selfdrive b/openpilot/selfdrive deleted file mode 120000 index e005fd0d04..0000000000 --- a/openpilot/selfdrive +++ /dev/null @@ -1 +0,0 @@ -../selfdrive/ \ No newline at end of file diff --git a/selfdrive/__init__.py b/openpilot/selfdrive/__init__.py similarity index 100% rename from selfdrive/__init__.py rename to openpilot/selfdrive/__init__.py diff --git a/selfdrive/assets/.gitignore b/openpilot/selfdrive/assets/.gitignore similarity index 100% rename from selfdrive/assets/.gitignore rename to openpilot/selfdrive/assets/.gitignore diff --git a/selfdrive/assets/assets.qrc b/openpilot/selfdrive/assets/assets.qrc similarity index 100% rename from selfdrive/assets/assets.qrc rename to openpilot/selfdrive/assets/assets.qrc diff --git a/selfdrive/assets/body/awake.gif b/openpilot/selfdrive/assets/body/awake.gif similarity index 100% rename from selfdrive/assets/body/awake.gif rename to openpilot/selfdrive/assets/body/awake.gif diff --git a/selfdrive/assets/body/sleep.gif b/openpilot/selfdrive/assets/body/sleep.gif similarity index 100% rename from selfdrive/assets/body/sleep.gif rename to openpilot/selfdrive/assets/body/sleep.gif diff --git a/selfdrive/assets/compress-images.sh b/openpilot/selfdrive/assets/compress-images.sh similarity index 100% rename from selfdrive/assets/compress-images.sh rename to openpilot/selfdrive/assets/compress-images.sh diff --git a/selfdrive/assets/fonts/Inter-Black.ttf b/openpilot/selfdrive/assets/fonts/Inter-Black.ttf similarity index 100% rename from selfdrive/assets/fonts/Inter-Black.ttf rename to openpilot/selfdrive/assets/fonts/Inter-Black.ttf diff --git a/selfdrive/assets/fonts/Inter-Bold.ttf b/openpilot/selfdrive/assets/fonts/Inter-Bold.ttf similarity index 100% rename from selfdrive/assets/fonts/Inter-Bold.ttf rename to openpilot/selfdrive/assets/fonts/Inter-Bold.ttf diff --git a/selfdrive/assets/fonts/Inter-ExtraBold.ttf b/openpilot/selfdrive/assets/fonts/Inter-ExtraBold.ttf similarity index 100% rename from selfdrive/assets/fonts/Inter-ExtraBold.ttf rename to openpilot/selfdrive/assets/fonts/Inter-ExtraBold.ttf diff --git a/selfdrive/assets/fonts/Inter-ExtraLight.ttf b/openpilot/selfdrive/assets/fonts/Inter-ExtraLight.ttf similarity index 100% rename from selfdrive/assets/fonts/Inter-ExtraLight.ttf rename to openpilot/selfdrive/assets/fonts/Inter-ExtraLight.ttf diff --git a/selfdrive/assets/fonts/Inter-Light.ttf b/openpilot/selfdrive/assets/fonts/Inter-Light.ttf similarity index 100% rename from selfdrive/assets/fonts/Inter-Light.ttf rename to openpilot/selfdrive/assets/fonts/Inter-Light.ttf diff --git a/selfdrive/assets/fonts/Inter-Medium.ttf b/openpilot/selfdrive/assets/fonts/Inter-Medium.ttf similarity index 100% rename from selfdrive/assets/fonts/Inter-Medium.ttf rename to openpilot/selfdrive/assets/fonts/Inter-Medium.ttf diff --git a/selfdrive/assets/fonts/Inter-Regular.ttf b/openpilot/selfdrive/assets/fonts/Inter-Regular.ttf similarity index 100% rename from selfdrive/assets/fonts/Inter-Regular.ttf rename to openpilot/selfdrive/assets/fonts/Inter-Regular.ttf diff --git a/selfdrive/assets/fonts/Inter-SemiBold.ttf b/openpilot/selfdrive/assets/fonts/Inter-SemiBold.ttf similarity index 100% rename from selfdrive/assets/fonts/Inter-SemiBold.ttf rename to openpilot/selfdrive/assets/fonts/Inter-SemiBold.ttf diff --git a/selfdrive/assets/fonts/Inter-Thin.ttf b/openpilot/selfdrive/assets/fonts/Inter-Thin.ttf similarity index 100% rename from selfdrive/assets/fonts/Inter-Thin.ttf rename to openpilot/selfdrive/assets/fonts/Inter-Thin.ttf diff --git a/selfdrive/assets/fonts/JetBrainsMono-Medium.ttf b/openpilot/selfdrive/assets/fonts/JetBrainsMono-Medium.ttf similarity index 100% rename from selfdrive/assets/fonts/JetBrainsMono-Medium.ttf rename to openpilot/selfdrive/assets/fonts/JetBrainsMono-Medium.ttf diff --git a/selfdrive/assets/fonts/NotoColorEmoji.ttf b/openpilot/selfdrive/assets/fonts/NotoColorEmoji.ttf similarity index 100% rename from selfdrive/assets/fonts/NotoColorEmoji.ttf rename to openpilot/selfdrive/assets/fonts/NotoColorEmoji.ttf diff --git a/selfdrive/assets/fonts/process.py b/openpilot/selfdrive/assets/fonts/process.py similarity index 100% rename from selfdrive/assets/fonts/process.py rename to openpilot/selfdrive/assets/fonts/process.py diff --git a/selfdrive/assets/fonts/unifont.otf b/openpilot/selfdrive/assets/fonts/unifont.otf similarity index 100% rename from selfdrive/assets/fonts/unifont.otf rename to openpilot/selfdrive/assets/fonts/unifont.otf diff --git a/selfdrive/assets/icons/arrow-right.png b/openpilot/selfdrive/assets/icons/arrow-right.png similarity index 100% rename from selfdrive/assets/icons/arrow-right.png rename to openpilot/selfdrive/assets/icons/arrow-right.png diff --git a/selfdrive/assets/icons/backspace.png b/openpilot/selfdrive/assets/icons/backspace.png similarity index 100% rename from selfdrive/assets/icons/backspace.png rename to openpilot/selfdrive/assets/icons/backspace.png diff --git a/selfdrive/assets/icons/calibration.png b/openpilot/selfdrive/assets/icons/calibration.png similarity index 100% rename from selfdrive/assets/icons/calibration.png rename to openpilot/selfdrive/assets/icons/calibration.png diff --git a/selfdrive/assets/icons/capslock-fill.png b/openpilot/selfdrive/assets/icons/capslock-fill.png similarity index 100% rename from selfdrive/assets/icons/capslock-fill.png rename to openpilot/selfdrive/assets/icons/capslock-fill.png diff --git a/selfdrive/assets/icons/checkmark.png b/openpilot/selfdrive/assets/icons/checkmark.png similarity index 100% rename from selfdrive/assets/icons/checkmark.png rename to openpilot/selfdrive/assets/icons/checkmark.png diff --git a/selfdrive/assets/icons/checkmark.svg b/openpilot/selfdrive/assets/icons/checkmark.svg similarity index 100% rename from selfdrive/assets/icons/checkmark.svg rename to openpilot/selfdrive/assets/icons/checkmark.svg diff --git a/selfdrive/assets/icons/chevron_right.png b/openpilot/selfdrive/assets/icons/chevron_right.png similarity index 100% rename from selfdrive/assets/icons/chevron_right.png rename to openpilot/selfdrive/assets/icons/chevron_right.png diff --git a/selfdrive/assets/icons/chffr_wheel.png b/openpilot/selfdrive/assets/icons/chffr_wheel.png similarity index 100% rename from selfdrive/assets/icons/chffr_wheel.png rename to openpilot/selfdrive/assets/icons/chffr_wheel.png diff --git a/selfdrive/assets/icons/circled_check.png b/openpilot/selfdrive/assets/icons/circled_check.png similarity index 100% rename from selfdrive/assets/icons/circled_check.png rename to openpilot/selfdrive/assets/icons/circled_check.png diff --git a/selfdrive/assets/icons/circled_check.svg b/openpilot/selfdrive/assets/icons/circled_check.svg similarity index 100% rename from selfdrive/assets/icons/circled_check.svg rename to openpilot/selfdrive/assets/icons/circled_check.svg diff --git a/selfdrive/assets/icons/circled_slash.png b/openpilot/selfdrive/assets/icons/circled_slash.png similarity index 100% rename from selfdrive/assets/icons/circled_slash.png rename to openpilot/selfdrive/assets/icons/circled_slash.png diff --git a/selfdrive/assets/icons/circled_slash.svg b/openpilot/selfdrive/assets/icons/circled_slash.svg similarity index 100% rename from selfdrive/assets/icons/circled_slash.svg rename to openpilot/selfdrive/assets/icons/circled_slash.svg diff --git a/selfdrive/assets/icons/close.png b/openpilot/selfdrive/assets/icons/close.png similarity index 100% rename from selfdrive/assets/icons/close.png rename to openpilot/selfdrive/assets/icons/close.png diff --git a/selfdrive/assets/icons/close.svg b/openpilot/selfdrive/assets/icons/close.svg similarity index 100% rename from selfdrive/assets/icons/close.svg rename to openpilot/selfdrive/assets/icons/close.svg diff --git a/selfdrive/assets/icons/close2.png b/openpilot/selfdrive/assets/icons/close2.png similarity index 100% rename from selfdrive/assets/icons/close2.png rename to openpilot/selfdrive/assets/icons/close2.png diff --git a/selfdrive/assets/icons/close2.svg b/openpilot/selfdrive/assets/icons/close2.svg similarity index 100% rename from selfdrive/assets/icons/close2.svg rename to openpilot/selfdrive/assets/icons/close2.svg diff --git a/selfdrive/assets/icons/couch.png b/openpilot/selfdrive/assets/icons/couch.png similarity index 100% rename from selfdrive/assets/icons/couch.png rename to openpilot/selfdrive/assets/icons/couch.png diff --git a/selfdrive/assets/icons/couch.svg b/openpilot/selfdrive/assets/icons/couch.svg similarity index 100% rename from selfdrive/assets/icons/couch.svg rename to openpilot/selfdrive/assets/icons/couch.svg diff --git a/selfdrive/assets/icons/disengage_on_accelerator.png b/openpilot/selfdrive/assets/icons/disengage_on_accelerator.png similarity index 100% rename from selfdrive/assets/icons/disengage_on_accelerator.png rename to openpilot/selfdrive/assets/icons/disengage_on_accelerator.png diff --git a/selfdrive/assets/icons/disengage_on_accelerator.svg b/openpilot/selfdrive/assets/icons/disengage_on_accelerator.svg similarity index 100% rename from selfdrive/assets/icons/disengage_on_accelerator.svg rename to openpilot/selfdrive/assets/icons/disengage_on_accelerator.svg diff --git a/selfdrive/assets/icons/driver_face.png b/openpilot/selfdrive/assets/icons/driver_face.png similarity index 100% rename from selfdrive/assets/icons/driver_face.png rename to openpilot/selfdrive/assets/icons/driver_face.png diff --git a/selfdrive/assets/icons/experimental.png b/openpilot/selfdrive/assets/icons/experimental.png similarity index 100% rename from selfdrive/assets/icons/experimental.png rename to openpilot/selfdrive/assets/icons/experimental.png diff --git a/selfdrive/assets/icons/experimental.svg b/openpilot/selfdrive/assets/icons/experimental.svg similarity index 100% rename from selfdrive/assets/icons/experimental.svg rename to openpilot/selfdrive/assets/icons/experimental.svg diff --git a/selfdrive/assets/icons/experimental_grey.png b/openpilot/selfdrive/assets/icons/experimental_grey.png similarity index 100% rename from selfdrive/assets/icons/experimental_grey.png rename to openpilot/selfdrive/assets/icons/experimental_grey.png diff --git a/selfdrive/assets/icons/experimental_grey.svg b/openpilot/selfdrive/assets/icons/experimental_grey.svg similarity index 100% rename from selfdrive/assets/icons/experimental_grey.svg rename to openpilot/selfdrive/assets/icons/experimental_grey.svg diff --git a/selfdrive/assets/icons/experimental_white.png b/openpilot/selfdrive/assets/icons/experimental_white.png similarity index 100% rename from selfdrive/assets/icons/experimental_white.png rename to openpilot/selfdrive/assets/icons/experimental_white.png diff --git a/selfdrive/assets/icons/experimental_white.svg b/openpilot/selfdrive/assets/icons/experimental_white.svg similarity index 100% rename from selfdrive/assets/icons/experimental_white.svg rename to openpilot/selfdrive/assets/icons/experimental_white.svg diff --git a/selfdrive/assets/icons/eye_closed.png b/openpilot/selfdrive/assets/icons/eye_closed.png similarity index 100% rename from selfdrive/assets/icons/eye_closed.png rename to openpilot/selfdrive/assets/icons/eye_closed.png diff --git a/selfdrive/assets/icons/eye_closed.svg b/openpilot/selfdrive/assets/icons/eye_closed.svg similarity index 100% rename from selfdrive/assets/icons/eye_closed.svg rename to openpilot/selfdrive/assets/icons/eye_closed.svg diff --git a/selfdrive/assets/icons/eye_open.png b/openpilot/selfdrive/assets/icons/eye_open.png similarity index 100% rename from selfdrive/assets/icons/eye_open.png rename to openpilot/selfdrive/assets/icons/eye_open.png diff --git a/selfdrive/assets/icons/eye_open.svg b/openpilot/selfdrive/assets/icons/eye_open.svg similarity index 100% rename from selfdrive/assets/icons/eye_open.svg rename to openpilot/selfdrive/assets/icons/eye_open.svg diff --git a/selfdrive/assets/icons/eyes_crossed.png b/openpilot/selfdrive/assets/icons/eyes_crossed.png similarity index 100% rename from selfdrive/assets/icons/eyes_crossed.png rename to openpilot/selfdrive/assets/icons/eyes_crossed.png diff --git a/selfdrive/assets/icons/eyes_open.png b/openpilot/selfdrive/assets/icons/eyes_open.png similarity index 100% rename from selfdrive/assets/icons/eyes_open.png rename to openpilot/selfdrive/assets/icons/eyes_open.png diff --git a/selfdrive/assets/icons/link.png b/openpilot/selfdrive/assets/icons/link.png similarity index 100% rename from selfdrive/assets/icons/link.png rename to openpilot/selfdrive/assets/icons/link.png diff --git a/selfdrive/assets/icons/lock_closed.png b/openpilot/selfdrive/assets/icons/lock_closed.png similarity index 100% rename from selfdrive/assets/icons/lock_closed.png rename to openpilot/selfdrive/assets/icons/lock_closed.png diff --git a/selfdrive/assets/icons/lock_closed.svg b/openpilot/selfdrive/assets/icons/lock_closed.svg similarity index 100% rename from selfdrive/assets/icons/lock_closed.svg rename to openpilot/selfdrive/assets/icons/lock_closed.svg diff --git a/selfdrive/assets/icons/menu.png b/openpilot/selfdrive/assets/icons/menu.png similarity index 100% rename from selfdrive/assets/icons/menu.png rename to openpilot/selfdrive/assets/icons/menu.png diff --git a/selfdrive/assets/icons/metric.png b/openpilot/selfdrive/assets/icons/metric.png similarity index 100% rename from selfdrive/assets/icons/metric.png rename to openpilot/selfdrive/assets/icons/metric.png diff --git a/selfdrive/assets/icons/microphone.png b/openpilot/selfdrive/assets/icons/microphone.png similarity index 100% rename from selfdrive/assets/icons/microphone.png rename to openpilot/selfdrive/assets/icons/microphone.png diff --git a/selfdrive/assets/icons/minus.png b/openpilot/selfdrive/assets/icons/minus.png similarity index 100% rename from selfdrive/assets/icons/minus.png rename to openpilot/selfdrive/assets/icons/minus.png diff --git a/selfdrive/assets/icons/monitoring.png b/openpilot/selfdrive/assets/icons/monitoring.png similarity index 100% rename from selfdrive/assets/icons/monitoring.png rename to openpilot/selfdrive/assets/icons/monitoring.png diff --git a/selfdrive/assets/icons/network.png b/openpilot/selfdrive/assets/icons/network.png similarity index 100% rename from selfdrive/assets/icons/network.png rename to openpilot/selfdrive/assets/icons/network.png diff --git a/selfdrive/assets/icons/road.png b/openpilot/selfdrive/assets/icons/road.png similarity index 100% rename from selfdrive/assets/icons/road.png rename to openpilot/selfdrive/assets/icons/road.png diff --git a/selfdrive/assets/icons/settings.png b/openpilot/selfdrive/assets/icons/settings.png similarity index 100% rename from selfdrive/assets/icons/settings.png rename to openpilot/selfdrive/assets/icons/settings.png diff --git a/selfdrive/assets/icons/shell.png b/openpilot/selfdrive/assets/icons/shell.png similarity index 100% rename from selfdrive/assets/icons/shell.png rename to openpilot/selfdrive/assets/icons/shell.png diff --git a/selfdrive/assets/icons/shift-fill.png b/openpilot/selfdrive/assets/icons/shift-fill.png similarity index 100% rename from selfdrive/assets/icons/shift-fill.png rename to openpilot/selfdrive/assets/icons/shift-fill.png diff --git a/selfdrive/assets/icons/shift.png b/openpilot/selfdrive/assets/icons/shift.png similarity index 100% rename from selfdrive/assets/icons/shift.png rename to openpilot/selfdrive/assets/icons/shift.png diff --git a/selfdrive/assets/icons/speed_limit.png b/openpilot/selfdrive/assets/icons/speed_limit.png similarity index 100% rename from selfdrive/assets/icons/speed_limit.png rename to openpilot/selfdrive/assets/icons/speed_limit.png diff --git a/selfdrive/assets/icons/triangle.png b/openpilot/selfdrive/assets/icons/triangle.png similarity index 100% rename from selfdrive/assets/icons/triangle.png rename to openpilot/selfdrive/assets/icons/triangle.png diff --git a/selfdrive/assets/icons/triangle.svg b/openpilot/selfdrive/assets/icons/triangle.svg similarity index 100% rename from selfdrive/assets/icons/triangle.svg rename to openpilot/selfdrive/assets/icons/triangle.svg diff --git a/selfdrive/assets/icons/warning.png b/openpilot/selfdrive/assets/icons/warning.png similarity index 100% rename from selfdrive/assets/icons/warning.png rename to openpilot/selfdrive/assets/icons/warning.png diff --git a/selfdrive/assets/icons/wifi_strength_full.png b/openpilot/selfdrive/assets/icons/wifi_strength_full.png similarity index 100% rename from selfdrive/assets/icons/wifi_strength_full.png rename to openpilot/selfdrive/assets/icons/wifi_strength_full.png diff --git a/selfdrive/assets/icons/wifi_strength_full.svg b/openpilot/selfdrive/assets/icons/wifi_strength_full.svg similarity index 100% rename from selfdrive/assets/icons/wifi_strength_full.svg rename to openpilot/selfdrive/assets/icons/wifi_strength_full.svg diff --git a/selfdrive/assets/icons/wifi_strength_high.png b/openpilot/selfdrive/assets/icons/wifi_strength_high.png similarity index 100% rename from selfdrive/assets/icons/wifi_strength_high.png rename to openpilot/selfdrive/assets/icons/wifi_strength_high.png diff --git a/selfdrive/assets/icons/wifi_strength_high.svg b/openpilot/selfdrive/assets/icons/wifi_strength_high.svg similarity index 100% rename from selfdrive/assets/icons/wifi_strength_high.svg rename to openpilot/selfdrive/assets/icons/wifi_strength_high.svg diff --git a/selfdrive/assets/icons/wifi_strength_low.png b/openpilot/selfdrive/assets/icons/wifi_strength_low.png similarity index 100% rename from selfdrive/assets/icons/wifi_strength_low.png rename to openpilot/selfdrive/assets/icons/wifi_strength_low.png diff --git a/selfdrive/assets/icons/wifi_strength_low.svg b/openpilot/selfdrive/assets/icons/wifi_strength_low.svg similarity index 100% rename from selfdrive/assets/icons/wifi_strength_low.svg rename to openpilot/selfdrive/assets/icons/wifi_strength_low.svg diff --git a/selfdrive/assets/icons/wifi_strength_medium.png b/openpilot/selfdrive/assets/icons/wifi_strength_medium.png similarity index 100% rename from selfdrive/assets/icons/wifi_strength_medium.png rename to openpilot/selfdrive/assets/icons/wifi_strength_medium.png diff --git a/selfdrive/assets/icons/wifi_strength_medium.svg b/openpilot/selfdrive/assets/icons/wifi_strength_medium.svg similarity index 100% rename from selfdrive/assets/icons/wifi_strength_medium.svg rename to openpilot/selfdrive/assets/icons/wifi_strength_medium.svg diff --git a/selfdrive/assets/icons/wifi_uploading.png b/openpilot/selfdrive/assets/icons/wifi_uploading.png similarity index 100% rename from selfdrive/assets/icons/wifi_uploading.png rename to openpilot/selfdrive/assets/icons/wifi_uploading.png diff --git a/selfdrive/assets/icons/wifi_uploading.svg b/openpilot/selfdrive/assets/icons/wifi_uploading.svg similarity index 100% rename from selfdrive/assets/icons/wifi_uploading.svg rename to openpilot/selfdrive/assets/icons/wifi_uploading.svg diff --git a/selfdrive/assets/icons_mici/adb_short.png b/openpilot/selfdrive/assets/icons_mici/adb_short.png similarity index 100% rename from selfdrive/assets/icons_mici/adb_short.png rename to openpilot/selfdrive/assets/icons_mici/adb_short.png diff --git a/selfdrive/assets/icons_mici/alerts_bell.png b/openpilot/selfdrive/assets/icons_mici/alerts_bell.png similarity index 100% rename from selfdrive/assets/icons_mici/alerts_bell.png rename to openpilot/selfdrive/assets/icons_mici/alerts_bell.png diff --git a/selfdrive/assets/icons_mici/alerts_pill.png b/openpilot/selfdrive/assets/icons_mici/alerts_pill.png similarity index 100% rename from selfdrive/assets/icons_mici/alerts_pill.png rename to openpilot/selfdrive/assets/icons_mici/alerts_pill.png diff --git a/selfdrive/assets/icons_mici/body.png b/openpilot/selfdrive/assets/icons_mici/body.png similarity index 100% rename from selfdrive/assets/icons_mici/body.png rename to openpilot/selfdrive/assets/icons_mici/body.png diff --git a/selfdrive/assets/icons_mici/buttons/button_circle.png b/openpilot/selfdrive/assets/icons_mici/buttons/button_circle.png similarity index 100% rename from selfdrive/assets/icons_mici/buttons/button_circle.png rename to openpilot/selfdrive/assets/icons_mici/buttons/button_circle.png diff --git a/selfdrive/assets/icons_mici/buttons/button_circle_disabled.png b/openpilot/selfdrive/assets/icons_mici/buttons/button_circle_disabled.png similarity index 100% rename from selfdrive/assets/icons_mici/buttons/button_circle_disabled.png rename to openpilot/selfdrive/assets/icons_mici/buttons/button_circle_disabled.png diff --git a/selfdrive/assets/icons_mici/buttons/button_circle_pressed.png b/openpilot/selfdrive/assets/icons_mici/buttons/button_circle_pressed.png similarity index 100% rename from selfdrive/assets/icons_mici/buttons/button_circle_pressed.png rename to openpilot/selfdrive/assets/icons_mici/buttons/button_circle_pressed.png diff --git a/selfdrive/assets/icons_mici/buttons/button_circle_red.png b/openpilot/selfdrive/assets/icons_mici/buttons/button_circle_red.png similarity index 100% rename from selfdrive/assets/icons_mici/buttons/button_circle_red.png rename to openpilot/selfdrive/assets/icons_mici/buttons/button_circle_red.png diff --git a/selfdrive/assets/icons_mici/buttons/button_circle_red_pressed.png b/openpilot/selfdrive/assets/icons_mici/buttons/button_circle_red_pressed.png similarity index 100% rename from selfdrive/assets/icons_mici/buttons/button_circle_red_pressed.png rename to openpilot/selfdrive/assets/icons_mici/buttons/button_circle_red_pressed.png diff --git a/selfdrive/assets/icons_mici/buttons/button_rectangle.png b/openpilot/selfdrive/assets/icons_mici/buttons/button_rectangle.png similarity index 100% rename from selfdrive/assets/icons_mici/buttons/button_rectangle.png rename to openpilot/selfdrive/assets/icons_mici/buttons/button_rectangle.png diff --git a/selfdrive/assets/icons_mici/buttons/button_rectangle_disabled.png b/openpilot/selfdrive/assets/icons_mici/buttons/button_rectangle_disabled.png similarity index 100% rename from selfdrive/assets/icons_mici/buttons/button_rectangle_disabled.png rename to openpilot/selfdrive/assets/icons_mici/buttons/button_rectangle_disabled.png diff --git a/selfdrive/assets/icons_mici/buttons/button_rectangle_pressed.png b/openpilot/selfdrive/assets/icons_mici/buttons/button_rectangle_pressed.png similarity index 100% rename from selfdrive/assets/icons_mici/buttons/button_rectangle_pressed.png rename to openpilot/selfdrive/assets/icons_mici/buttons/button_rectangle_pressed.png diff --git a/selfdrive/assets/icons_mici/buttons/slider_bg.png b/openpilot/selfdrive/assets/icons_mici/buttons/slider_bg.png similarity index 100% rename from selfdrive/assets/icons_mici/buttons/slider_bg.png rename to openpilot/selfdrive/assets/icons_mici/buttons/slider_bg.png diff --git a/selfdrive/assets/icons_mici/buttons/toggle_dot_disabled.png b/openpilot/selfdrive/assets/icons_mici/buttons/toggle_dot_disabled.png similarity index 100% rename from selfdrive/assets/icons_mici/buttons/toggle_dot_disabled.png rename to openpilot/selfdrive/assets/icons_mici/buttons/toggle_dot_disabled.png diff --git a/selfdrive/assets/icons_mici/buttons/toggle_dot_enabled.png b/openpilot/selfdrive/assets/icons_mici/buttons/toggle_dot_enabled.png similarity index 100% rename from selfdrive/assets/icons_mici/buttons/toggle_dot_enabled.png rename to openpilot/selfdrive/assets/icons_mici/buttons/toggle_dot_enabled.png diff --git a/selfdrive/assets/icons_mici/buttons/toggle_pill_disabled.png b/openpilot/selfdrive/assets/icons_mici/buttons/toggle_pill_disabled.png similarity index 100% rename from selfdrive/assets/icons_mici/buttons/toggle_pill_disabled.png rename to openpilot/selfdrive/assets/icons_mici/buttons/toggle_pill_disabled.png diff --git a/selfdrive/assets/icons_mici/buttons/toggle_pill_enabled.png b/openpilot/selfdrive/assets/icons_mici/buttons/toggle_pill_enabled.png similarity index 100% rename from selfdrive/assets/icons_mici/buttons/toggle_pill_enabled.png rename to openpilot/selfdrive/assets/icons_mici/buttons/toggle_pill_enabled.png diff --git a/selfdrive/assets/icons_mici/egpu.png b/openpilot/selfdrive/assets/icons_mici/egpu.png similarity index 100% rename from selfdrive/assets/icons_mici/egpu.png rename to openpilot/selfdrive/assets/icons_mici/egpu.png diff --git a/selfdrive/assets/icons_mici/egpu_gray.png b/openpilot/selfdrive/assets/icons_mici/egpu_gray.png similarity index 100% rename from selfdrive/assets/icons_mici/egpu_gray.png rename to openpilot/selfdrive/assets/icons_mici/egpu_gray.png diff --git a/selfdrive/assets/icons_mici/exclamation_point.png b/openpilot/selfdrive/assets/icons_mici/exclamation_point.png similarity index 100% rename from selfdrive/assets/icons_mici/exclamation_point.png rename to openpilot/selfdrive/assets/icons_mici/exclamation_point.png diff --git a/selfdrive/assets/icons_mici/experimental_mode.png b/openpilot/selfdrive/assets/icons_mici/experimental_mode.png similarity index 100% rename from selfdrive/assets/icons_mici/experimental_mode.png rename to openpilot/selfdrive/assets/icons_mici/experimental_mode.png diff --git a/selfdrive/assets/icons_mici/microphone.png b/openpilot/selfdrive/assets/icons_mici/microphone.png similarity index 100% rename from selfdrive/assets/icons_mici/microphone.png rename to openpilot/selfdrive/assets/icons_mici/microphone.png diff --git a/selfdrive/assets/icons_mici/offroad_alerts/big_alert.png b/openpilot/selfdrive/assets/icons_mici/offroad_alerts/big_alert.png similarity index 100% rename from selfdrive/assets/icons_mici/offroad_alerts/big_alert.png rename to openpilot/selfdrive/assets/icons_mici/offroad_alerts/big_alert.png diff --git a/selfdrive/assets/icons_mici/offroad_alerts/big_alert_pressed.png b/openpilot/selfdrive/assets/icons_mici/offroad_alerts/big_alert_pressed.png similarity index 100% rename from selfdrive/assets/icons_mici/offroad_alerts/big_alert_pressed.png rename to openpilot/selfdrive/assets/icons_mici/offroad_alerts/big_alert_pressed.png diff --git a/selfdrive/assets/icons_mici/offroad_alerts/green_wheel.png b/openpilot/selfdrive/assets/icons_mici/offroad_alerts/green_wheel.png similarity index 100% rename from selfdrive/assets/icons_mici/offroad_alerts/green_wheel.png rename to openpilot/selfdrive/assets/icons_mici/offroad_alerts/green_wheel.png diff --git a/selfdrive/assets/icons_mici/offroad_alerts/medium_alert.png b/openpilot/selfdrive/assets/icons_mici/offroad_alerts/medium_alert.png similarity index 100% rename from selfdrive/assets/icons_mici/offroad_alerts/medium_alert.png rename to openpilot/selfdrive/assets/icons_mici/offroad_alerts/medium_alert.png diff --git a/selfdrive/assets/icons_mici/offroad_alerts/medium_alert_pressed.png b/openpilot/selfdrive/assets/icons_mici/offroad_alerts/medium_alert_pressed.png similarity index 100% rename from selfdrive/assets/icons_mici/offroad_alerts/medium_alert_pressed.png rename to openpilot/selfdrive/assets/icons_mici/offroad_alerts/medium_alert_pressed.png diff --git a/selfdrive/assets/icons_mici/offroad_alerts/orange_warning.png b/openpilot/selfdrive/assets/icons_mici/offroad_alerts/orange_warning.png similarity index 100% rename from selfdrive/assets/icons_mici/offroad_alerts/orange_warning.png rename to openpilot/selfdrive/assets/icons_mici/offroad_alerts/orange_warning.png diff --git a/selfdrive/assets/icons_mici/offroad_alerts/red_warning.png b/openpilot/selfdrive/assets/icons_mici/offroad_alerts/red_warning.png similarity index 100% rename from selfdrive/assets/icons_mici/offroad_alerts/red_warning.png rename to openpilot/selfdrive/assets/icons_mici/offroad_alerts/red_warning.png diff --git a/selfdrive/assets/icons_mici/offroad_alerts/small_alert.png b/openpilot/selfdrive/assets/icons_mici/offroad_alerts/small_alert.png similarity index 100% rename from selfdrive/assets/icons_mici/offroad_alerts/small_alert.png rename to openpilot/selfdrive/assets/icons_mici/offroad_alerts/small_alert.png diff --git a/selfdrive/assets/icons_mici/offroad_alerts/small_alert_pressed.png b/openpilot/selfdrive/assets/icons_mici/offroad_alerts/small_alert_pressed.png similarity index 100% rename from selfdrive/assets/icons_mici/offroad_alerts/small_alert_pressed.png rename to openpilot/selfdrive/assets/icons_mici/offroad_alerts/small_alert_pressed.png diff --git a/selfdrive/assets/icons_mici/onroad/blind_spot_left.png b/openpilot/selfdrive/assets/icons_mici/onroad/blind_spot_left.png similarity index 100% rename from selfdrive/assets/icons_mici/onroad/blind_spot_left.png rename to openpilot/selfdrive/assets/icons_mici/onroad/blind_spot_left.png diff --git a/selfdrive/assets/icons_mici/onroad/bookmark.png b/openpilot/selfdrive/assets/icons_mici/onroad/bookmark.png similarity index 100% rename from selfdrive/assets/icons_mici/onroad/bookmark.png rename to openpilot/selfdrive/assets/icons_mici/onroad/bookmark.png diff --git a/selfdrive/assets/icons_mici/onroad/driver_monitoring/dm_background.png b/openpilot/selfdrive/assets/icons_mici/onroad/driver_monitoring/dm_background.png similarity index 100% rename from selfdrive/assets/icons_mici/onroad/driver_monitoring/dm_background.png rename to openpilot/selfdrive/assets/icons_mici/onroad/driver_monitoring/dm_background.png diff --git a/selfdrive/assets/icons_mici/onroad/driver_monitoring/dm_cone.png b/openpilot/selfdrive/assets/icons_mici/onroad/driver_monitoring/dm_cone.png similarity index 100% rename from selfdrive/assets/icons_mici/onroad/driver_monitoring/dm_cone.png rename to openpilot/selfdrive/assets/icons_mici/onroad/driver_monitoring/dm_cone.png diff --git a/selfdrive/assets/icons_mici/onroad/driver_monitoring/dm_person.png b/openpilot/selfdrive/assets/icons_mici/onroad/driver_monitoring/dm_person.png similarity index 100% rename from selfdrive/assets/icons_mici/onroad/driver_monitoring/dm_person.png rename to openpilot/selfdrive/assets/icons_mici/onroad/driver_monitoring/dm_person.png diff --git a/selfdrive/assets/icons_mici/onroad/eye_fill.png b/openpilot/selfdrive/assets/icons_mici/onroad/eye_fill.png similarity index 100% rename from selfdrive/assets/icons_mici/onroad/eye_fill.png rename to openpilot/selfdrive/assets/icons_mici/onroad/eye_fill.png diff --git a/selfdrive/assets/icons_mici/onroad/eye_orange.png b/openpilot/selfdrive/assets/icons_mici/onroad/eye_orange.png similarity index 100% rename from selfdrive/assets/icons_mici/onroad/eye_orange.png rename to openpilot/selfdrive/assets/icons_mici/onroad/eye_orange.png diff --git a/selfdrive/assets/icons_mici/onroad/glasses.png b/openpilot/selfdrive/assets/icons_mici/onroad/glasses.png similarity index 100% rename from selfdrive/assets/icons_mici/onroad/glasses.png rename to openpilot/selfdrive/assets/icons_mici/onroad/glasses.png diff --git a/selfdrive/assets/icons_mici/onroad/onroad_fade.png b/openpilot/selfdrive/assets/icons_mici/onroad/onroad_fade.png similarity index 100% rename from selfdrive/assets/icons_mici/onroad/onroad_fade.png rename to openpilot/selfdrive/assets/icons_mici/onroad/onroad_fade.png diff --git a/selfdrive/assets/icons_mici/onroad/turn_signal_left.png b/openpilot/selfdrive/assets/icons_mici/onroad/turn_signal_left.png similarity index 100% rename from selfdrive/assets/icons_mici/onroad/turn_signal_left.png rename to openpilot/selfdrive/assets/icons_mici/onroad/turn_signal_left.png diff --git a/selfdrive/assets/icons_mici/settings.png b/openpilot/selfdrive/assets/icons_mici/settings.png similarity index 100% rename from selfdrive/assets/icons_mici/settings.png rename to openpilot/selfdrive/assets/icons_mici/settings.png diff --git a/selfdrive/assets/icons_mici/settings/comma_icon.png b/openpilot/selfdrive/assets/icons_mici/settings/comma_icon.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/comma_icon.png rename to openpilot/selfdrive/assets/icons_mici/settings/comma_icon.png diff --git a/selfdrive/assets/icons_mici/settings/developer/ssh.png b/openpilot/selfdrive/assets/icons_mici/settings/developer/ssh.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/developer/ssh.png rename to openpilot/selfdrive/assets/icons_mici/settings/developer/ssh.png diff --git a/selfdrive/assets/icons_mici/settings/developer_icon.png b/openpilot/selfdrive/assets/icons_mici/settings/developer_icon.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/developer_icon.png rename to openpilot/selfdrive/assets/icons_mici/settings/developer_icon.png diff --git a/selfdrive/assets/icons_mici/settings/device/cameras.png b/openpilot/selfdrive/assets/icons_mici/settings/device/cameras.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/device/cameras.png rename to openpilot/selfdrive/assets/icons_mici/settings/device/cameras.png diff --git a/selfdrive/assets/icons_mici/settings/device/fcc_logo.png b/openpilot/selfdrive/assets/icons_mici/settings/device/fcc_logo.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/device/fcc_logo.png rename to openpilot/selfdrive/assets/icons_mici/settings/device/fcc_logo.png diff --git a/selfdrive/assets/icons_mici/settings/device/info.png b/openpilot/selfdrive/assets/icons_mici/settings/device/info.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/device/info.png rename to openpilot/selfdrive/assets/icons_mici/settings/device/info.png diff --git a/selfdrive/assets/icons_mici/settings/device/lkas.png b/openpilot/selfdrive/assets/icons_mici/settings/device/lkas.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/device/lkas.png rename to openpilot/selfdrive/assets/icons_mici/settings/device/lkas.png diff --git a/selfdrive/assets/icons_mici/settings/device/pair.png b/openpilot/selfdrive/assets/icons_mici/settings/device/pair.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/device/pair.png rename to openpilot/selfdrive/assets/icons_mici/settings/device/pair.png diff --git a/selfdrive/assets/icons_mici/settings/device/power.png b/openpilot/selfdrive/assets/icons_mici/settings/device/power.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/device/power.png rename to openpilot/selfdrive/assets/icons_mici/settings/device/power.png diff --git a/selfdrive/assets/icons_mici/settings/device/reboot.png b/openpilot/selfdrive/assets/icons_mici/settings/device/reboot.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/device/reboot.png rename to openpilot/selfdrive/assets/icons_mici/settings/device/reboot.png diff --git a/selfdrive/assets/icons_mici/settings/device/uninstall.png b/openpilot/selfdrive/assets/icons_mici/settings/device/uninstall.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/device/uninstall.png rename to openpilot/selfdrive/assets/icons_mici/settings/device/uninstall.png diff --git a/selfdrive/assets/icons_mici/settings/device/up_to_date.png b/openpilot/selfdrive/assets/icons_mici/settings/device/up_to_date.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/device/up_to_date.png rename to openpilot/selfdrive/assets/icons_mici/settings/device/up_to_date.png diff --git a/selfdrive/assets/icons_mici/settings/device/update.png b/openpilot/selfdrive/assets/icons_mici/settings/device/update.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/device/update.png rename to openpilot/selfdrive/assets/icons_mici/settings/device/update.png diff --git a/selfdrive/assets/icons_mici/settings/device_icon.png b/openpilot/selfdrive/assets/icons_mici/settings/device_icon.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/device_icon.png rename to openpilot/selfdrive/assets/icons_mici/settings/device_icon.png diff --git a/selfdrive/assets/icons_mici/settings/firehose.png b/openpilot/selfdrive/assets/icons_mici/settings/firehose.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/firehose.png rename to openpilot/selfdrive/assets/icons_mici/settings/firehose.png diff --git a/selfdrive/assets/icons_mici/settings/horizontal_scroll_indicator.png b/openpilot/selfdrive/assets/icons_mici/settings/horizontal_scroll_indicator.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/horizontal_scroll_indicator.png rename to openpilot/selfdrive/assets/icons_mici/settings/horizontal_scroll_indicator.png diff --git a/selfdrive/assets/icons_mici/settings/keyboard/backspace.png b/openpilot/selfdrive/assets/icons_mici/settings/keyboard/backspace.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/keyboard/backspace.png rename to openpilot/selfdrive/assets/icons_mici/settings/keyboard/backspace.png diff --git a/selfdrive/assets/icons_mici/settings/keyboard/caps_lock.png b/openpilot/selfdrive/assets/icons_mici/settings/keyboard/caps_lock.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/keyboard/caps_lock.png rename to openpilot/selfdrive/assets/icons_mici/settings/keyboard/caps_lock.png diff --git a/selfdrive/assets/icons_mici/settings/keyboard/caps_lower.png b/openpilot/selfdrive/assets/icons_mici/settings/keyboard/caps_lower.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/keyboard/caps_lower.png rename to openpilot/selfdrive/assets/icons_mici/settings/keyboard/caps_lower.png diff --git a/selfdrive/assets/icons_mici/settings/keyboard/caps_upper.png b/openpilot/selfdrive/assets/icons_mici/settings/keyboard/caps_upper.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/keyboard/caps_upper.png rename to openpilot/selfdrive/assets/icons_mici/settings/keyboard/caps_upper.png diff --git a/selfdrive/assets/icons_mici/settings/keyboard/enter.png b/openpilot/selfdrive/assets/icons_mici/settings/keyboard/enter.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/keyboard/enter.png rename to openpilot/selfdrive/assets/icons_mici/settings/keyboard/enter.png diff --git a/selfdrive/assets/icons_mici/settings/keyboard/enter_disabled.png b/openpilot/selfdrive/assets/icons_mici/settings/keyboard/enter_disabled.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/keyboard/enter_disabled.png rename to openpilot/selfdrive/assets/icons_mici/settings/keyboard/enter_disabled.png diff --git a/selfdrive/assets/icons_mici/settings/keyboard/keyboard_background.png b/openpilot/selfdrive/assets/icons_mici/settings/keyboard/keyboard_background.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/keyboard/keyboard_background.png rename to openpilot/selfdrive/assets/icons_mici/settings/keyboard/keyboard_background.png diff --git a/selfdrive/assets/icons_mici/settings/keyboard/space.png b/openpilot/selfdrive/assets/icons_mici/settings/keyboard/space.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/keyboard/space.png rename to openpilot/selfdrive/assets/icons_mici/settings/keyboard/space.png diff --git a/selfdrive/assets/icons_mici/settings/network/cell_strength_full.png b/openpilot/selfdrive/assets/icons_mici/settings/network/cell_strength_full.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/network/cell_strength_full.png rename to openpilot/selfdrive/assets/icons_mici/settings/network/cell_strength_full.png diff --git a/selfdrive/assets/icons_mici/settings/network/cell_strength_high.png b/openpilot/selfdrive/assets/icons_mici/settings/network/cell_strength_high.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/network/cell_strength_high.png rename to openpilot/selfdrive/assets/icons_mici/settings/network/cell_strength_high.png diff --git a/selfdrive/assets/icons_mici/settings/network/cell_strength_low.png b/openpilot/selfdrive/assets/icons_mici/settings/network/cell_strength_low.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/network/cell_strength_low.png rename to openpilot/selfdrive/assets/icons_mici/settings/network/cell_strength_low.png diff --git a/selfdrive/assets/icons_mici/settings/network/cell_strength_medium.png b/openpilot/selfdrive/assets/icons_mici/settings/network/cell_strength_medium.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/network/cell_strength_medium.png rename to openpilot/selfdrive/assets/icons_mici/settings/network/cell_strength_medium.png diff --git a/selfdrive/assets/icons_mici/settings/network/cell_strength_none.png b/openpilot/selfdrive/assets/icons_mici/settings/network/cell_strength_none.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/network/cell_strength_none.png rename to openpilot/selfdrive/assets/icons_mici/settings/network/cell_strength_none.png diff --git a/selfdrive/assets/icons_mici/settings/network/new/forget_button.png b/openpilot/selfdrive/assets/icons_mici/settings/network/new/forget_button.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/network/new/forget_button.png rename to openpilot/selfdrive/assets/icons_mici/settings/network/new/forget_button.png diff --git a/selfdrive/assets/icons_mici/settings/network/new/forget_button_pressed.png b/openpilot/selfdrive/assets/icons_mici/settings/network/new/forget_button_pressed.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/network/new/forget_button_pressed.png rename to openpilot/selfdrive/assets/icons_mici/settings/network/new/forget_button_pressed.png diff --git a/selfdrive/assets/icons_mici/settings/network/new/lock.png b/openpilot/selfdrive/assets/icons_mici/settings/network/new/lock.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/network/new/lock.png rename to openpilot/selfdrive/assets/icons_mici/settings/network/new/lock.png diff --git a/selfdrive/assets/icons_mici/settings/network/new/trash.png b/openpilot/selfdrive/assets/icons_mici/settings/network/new/trash.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/network/new/trash.png rename to openpilot/selfdrive/assets/icons_mici/settings/network/new/trash.png diff --git a/selfdrive/assets/icons_mici/settings/network/tethering.png b/openpilot/selfdrive/assets/icons_mici/settings/network/tethering.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/network/tethering.png rename to openpilot/selfdrive/assets/icons_mici/settings/network/tethering.png diff --git a/selfdrive/assets/icons_mici/settings/network/wifi_strength_full.png b/openpilot/selfdrive/assets/icons_mici/settings/network/wifi_strength_full.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/network/wifi_strength_full.png rename to openpilot/selfdrive/assets/icons_mici/settings/network/wifi_strength_full.png diff --git a/selfdrive/assets/icons_mici/settings/network/wifi_strength_low.png b/openpilot/selfdrive/assets/icons_mici/settings/network/wifi_strength_low.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/network/wifi_strength_low.png rename to openpilot/selfdrive/assets/icons_mici/settings/network/wifi_strength_low.png diff --git a/selfdrive/assets/icons_mici/settings/network/wifi_strength_medium.png b/openpilot/selfdrive/assets/icons_mici/settings/network/wifi_strength_medium.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/network/wifi_strength_medium.png rename to openpilot/selfdrive/assets/icons_mici/settings/network/wifi_strength_medium.png diff --git a/selfdrive/assets/icons_mici/settings/network/wifi_strength_none.png b/openpilot/selfdrive/assets/icons_mici/settings/network/wifi_strength_none.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/network/wifi_strength_none.png rename to openpilot/selfdrive/assets/icons_mici/settings/network/wifi_strength_none.png diff --git a/selfdrive/assets/icons_mici/settings/network/wifi_strength_slash.png b/openpilot/selfdrive/assets/icons_mici/settings/network/wifi_strength_slash.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/network/wifi_strength_slash.png rename to openpilot/selfdrive/assets/icons_mici/settings/network/wifi_strength_slash.png diff --git a/selfdrive/assets/icons_mici/settings/software.png b/openpilot/selfdrive/assets/icons_mici/settings/software.png similarity index 100% rename from selfdrive/assets/icons_mici/settings/software.png rename to openpilot/selfdrive/assets/icons_mici/settings/software.png diff --git a/selfdrive/assets/icons_mici/setup/cancel.png b/openpilot/selfdrive/assets/icons_mici/setup/cancel.png similarity index 100% rename from selfdrive/assets/icons_mici/setup/cancel.png rename to openpilot/selfdrive/assets/icons_mici/setup/cancel.png diff --git a/selfdrive/assets/icons_mici/setup/continue.png b/openpilot/selfdrive/assets/icons_mici/setup/continue.png similarity index 100% rename from selfdrive/assets/icons_mici/setup/continue.png rename to openpilot/selfdrive/assets/icons_mici/setup/continue.png diff --git a/selfdrive/assets/icons_mici/setup/continue_disabled.png b/openpilot/selfdrive/assets/icons_mici/setup/continue_disabled.png similarity index 100% rename from selfdrive/assets/icons_mici/setup/continue_disabled.png rename to openpilot/selfdrive/assets/icons_mici/setup/continue_disabled.png diff --git a/selfdrive/assets/icons_mici/setup/continue_pressed.png b/openpilot/selfdrive/assets/icons_mici/setup/continue_pressed.png similarity index 100% rename from selfdrive/assets/icons_mici/setup/continue_pressed.png rename to openpilot/selfdrive/assets/icons_mici/setup/continue_pressed.png diff --git a/selfdrive/assets/icons_mici/setup/driver_monitoring/dm_check.png b/openpilot/selfdrive/assets/icons_mici/setup/driver_monitoring/dm_check.png similarity index 100% rename from selfdrive/assets/icons_mici/setup/driver_monitoring/dm_check.png rename to openpilot/selfdrive/assets/icons_mici/setup/driver_monitoring/dm_check.png diff --git a/selfdrive/assets/icons_mici/setup/driver_monitoring/dm_question.png b/openpilot/selfdrive/assets/icons_mici/setup/driver_monitoring/dm_question.png similarity index 100% rename from selfdrive/assets/icons_mici/setup/driver_monitoring/dm_question.png rename to openpilot/selfdrive/assets/icons_mici/setup/driver_monitoring/dm_question.png diff --git a/selfdrive/assets/icons_mici/setup/factory_reset.png b/openpilot/selfdrive/assets/icons_mici/setup/factory_reset.png similarity index 100% rename from selfdrive/assets/icons_mici/setup/factory_reset.png rename to openpilot/selfdrive/assets/icons_mici/setup/factory_reset.png diff --git a/selfdrive/assets/icons_mici/setup/green_dm.png b/openpilot/selfdrive/assets/icons_mici/setup/green_dm.png similarity index 100% rename from selfdrive/assets/icons_mici/setup/green_dm.png rename to openpilot/selfdrive/assets/icons_mici/setup/green_dm.png diff --git a/selfdrive/assets/icons_mici/setup/green_info.png b/openpilot/selfdrive/assets/icons_mici/setup/green_info.png similarity index 100% rename from selfdrive/assets/icons_mici/setup/green_info.png rename to openpilot/selfdrive/assets/icons_mici/setup/green_info.png diff --git a/selfdrive/assets/icons_mici/setup/orange_dm.png b/openpilot/selfdrive/assets/icons_mici/setup/orange_dm.png similarity index 100% rename from selfdrive/assets/icons_mici/setup/orange_dm.png rename to openpilot/selfdrive/assets/icons_mici/setup/orange_dm.png diff --git a/selfdrive/assets/icons_mici/setup/red_warning.png b/openpilot/selfdrive/assets/icons_mici/setup/red_warning.png similarity index 100% rename from selfdrive/assets/icons_mici/setup/red_warning.png rename to openpilot/selfdrive/assets/icons_mici/setup/red_warning.png diff --git a/selfdrive/assets/icons_mici/setup/reset_failed.png b/openpilot/selfdrive/assets/icons_mici/setup/reset_failed.png similarity index 100% rename from selfdrive/assets/icons_mici/setup/reset_failed.png rename to openpilot/selfdrive/assets/icons_mici/setup/reset_failed.png diff --git a/selfdrive/assets/icons_mici/setup/restore.png b/openpilot/selfdrive/assets/icons_mici/setup/restore.png similarity index 100% rename from selfdrive/assets/icons_mici/setup/restore.png rename to openpilot/selfdrive/assets/icons_mici/setup/restore.png diff --git a/selfdrive/assets/icons_mici/setup/small_button.png b/openpilot/selfdrive/assets/icons_mici/setup/small_button.png similarity index 100% rename from selfdrive/assets/icons_mici/setup/small_button.png rename to openpilot/selfdrive/assets/icons_mici/setup/small_button.png diff --git a/selfdrive/assets/icons_mici/setup/small_button_disabled.png b/openpilot/selfdrive/assets/icons_mici/setup/small_button_disabled.png similarity index 100% rename from selfdrive/assets/icons_mici/setup/small_button_disabled.png rename to openpilot/selfdrive/assets/icons_mici/setup/small_button_disabled.png diff --git a/selfdrive/assets/icons_mici/setup/small_button_pressed.png b/openpilot/selfdrive/assets/icons_mici/setup/small_button_pressed.png similarity index 100% rename from selfdrive/assets/icons_mici/setup/small_button_pressed.png rename to openpilot/selfdrive/assets/icons_mici/setup/small_button_pressed.png diff --git a/selfdrive/assets/icons_mici/setup/small_slider/slider_arrow.png b/openpilot/selfdrive/assets/icons_mici/setup/small_slider/slider_arrow.png similarity index 100% rename from selfdrive/assets/icons_mici/setup/small_slider/slider_arrow.png rename to openpilot/selfdrive/assets/icons_mici/setup/small_slider/slider_arrow.png diff --git a/selfdrive/assets/icons_mici/setup/small_slider/slider_bg_larger.png b/openpilot/selfdrive/assets/icons_mici/setup/small_slider/slider_bg_larger.png similarity index 100% rename from selfdrive/assets/icons_mici/setup/small_slider/slider_bg_larger.png rename to openpilot/selfdrive/assets/icons_mici/setup/small_slider/slider_bg_larger.png diff --git a/selfdrive/assets/icons_mici/setup/small_slider/slider_black_rounded_rectangle.png b/openpilot/selfdrive/assets/icons_mici/setup/small_slider/slider_black_rounded_rectangle.png similarity index 100% rename from selfdrive/assets/icons_mici/setup/small_slider/slider_black_rounded_rectangle.png rename to openpilot/selfdrive/assets/icons_mici/setup/small_slider/slider_black_rounded_rectangle.png diff --git a/selfdrive/assets/icons_mici/setup/small_slider/slider_black_rounded_rectangle_pressed.png b/openpilot/selfdrive/assets/icons_mici/setup/small_slider/slider_black_rounded_rectangle_pressed.png similarity index 100% rename from selfdrive/assets/icons_mici/setup/small_slider/slider_black_rounded_rectangle_pressed.png rename to openpilot/selfdrive/assets/icons_mici/setup/small_slider/slider_black_rounded_rectangle_pressed.png diff --git a/selfdrive/assets/icons_mici/setup/small_slider/slider_green_rounded_rectangle.png b/openpilot/selfdrive/assets/icons_mici/setup/small_slider/slider_green_rounded_rectangle.png similarity index 100% rename from selfdrive/assets/icons_mici/setup/small_slider/slider_green_rounded_rectangle.png rename to openpilot/selfdrive/assets/icons_mici/setup/small_slider/slider_green_rounded_rectangle.png diff --git a/selfdrive/assets/icons_mici/setup/small_slider/slider_green_rounded_rectangle_pressed.png b/openpilot/selfdrive/assets/icons_mici/setup/small_slider/slider_green_rounded_rectangle_pressed.png similarity index 100% rename from selfdrive/assets/icons_mici/setup/small_slider/slider_green_rounded_rectangle_pressed.png rename to openpilot/selfdrive/assets/icons_mici/setup/small_slider/slider_green_rounded_rectangle_pressed.png diff --git a/selfdrive/assets/icons_mici/setup/start_button.png b/openpilot/selfdrive/assets/icons_mici/setup/start_button.png similarity index 100% rename from selfdrive/assets/icons_mici/setup/start_button.png rename to openpilot/selfdrive/assets/icons_mici/setup/start_button.png diff --git a/selfdrive/assets/icons_mici/setup/start_button_pressed.png b/openpilot/selfdrive/assets/icons_mici/setup/start_button_pressed.png similarity index 100% rename from selfdrive/assets/icons_mici/setup/start_button_pressed.png rename to openpilot/selfdrive/assets/icons_mici/setup/start_button_pressed.png diff --git a/selfdrive/assets/icons_mici/setup/warning.png b/openpilot/selfdrive/assets/icons_mici/setup/warning.png similarity index 100% rename from selfdrive/assets/icons_mici/setup/warning.png rename to openpilot/selfdrive/assets/icons_mici/setup/warning.png diff --git a/selfdrive/assets/icons_mici/ssh_short.png b/openpilot/selfdrive/assets/icons_mici/ssh_short.png similarity index 100% rename from selfdrive/assets/icons_mici/ssh_short.png rename to openpilot/selfdrive/assets/icons_mici/ssh_short.png diff --git a/selfdrive/assets/icons_mici/turn_intent_left.png b/openpilot/selfdrive/assets/icons_mici/turn_intent_left.png similarity index 100% rename from selfdrive/assets/icons_mici/turn_intent_left.png rename to openpilot/selfdrive/assets/icons_mici/turn_intent_left.png diff --git a/selfdrive/assets/icons_mici/wheel.png b/openpilot/selfdrive/assets/icons_mici/wheel.png similarity index 100% rename from selfdrive/assets/icons_mici/wheel.png rename to openpilot/selfdrive/assets/icons_mici/wheel.png diff --git a/selfdrive/assets/icons_mici/wheel_critical.png b/openpilot/selfdrive/assets/icons_mici/wheel_critical.png similarity index 100% rename from selfdrive/assets/icons_mici/wheel_critical.png rename to openpilot/selfdrive/assets/icons_mici/wheel_critical.png diff --git a/selfdrive/assets/images/button_continue_triangle.png b/openpilot/selfdrive/assets/images/button_continue_triangle.png similarity index 100% rename from selfdrive/assets/images/button_continue_triangle.png rename to openpilot/selfdrive/assets/images/button_continue_triangle.png diff --git a/selfdrive/assets/images/button_continue_triangle.svg b/openpilot/selfdrive/assets/images/button_continue_triangle.svg similarity index 100% rename from selfdrive/assets/images/button_continue_triangle.svg rename to openpilot/selfdrive/assets/images/button_continue_triangle.svg diff --git a/selfdrive/assets/images/button_flag.png b/openpilot/selfdrive/assets/images/button_flag.png similarity index 100% rename from selfdrive/assets/images/button_flag.png rename to openpilot/selfdrive/assets/images/button_flag.png diff --git a/selfdrive/assets/images/button_home.png b/openpilot/selfdrive/assets/images/button_home.png similarity index 100% rename from selfdrive/assets/images/button_home.png rename to openpilot/selfdrive/assets/images/button_home.png diff --git a/selfdrive/assets/images/button_settings.png b/openpilot/selfdrive/assets/images/button_settings.png similarity index 100% rename from selfdrive/assets/images/button_settings.png rename to openpilot/selfdrive/assets/images/button_settings.png diff --git a/selfdrive/assets/images/spinner_comma.png b/openpilot/selfdrive/assets/images/spinner_comma.png similarity index 100% rename from selfdrive/assets/images/spinner_comma.png rename to openpilot/selfdrive/assets/images/spinner_comma.png diff --git a/selfdrive/assets/images/spinner_track.png b/openpilot/selfdrive/assets/images/spinner_track.png similarity index 100% rename from selfdrive/assets/images/spinner_track.png rename to openpilot/selfdrive/assets/images/spinner_track.png diff --git a/selfdrive/assets/offroad/fcc.html b/openpilot/selfdrive/assets/offroad/fcc.html similarity index 100% rename from selfdrive/assets/offroad/fcc.html rename to openpilot/selfdrive/assets/offroad/fcc.html diff --git a/selfdrive/assets/offroad/mici_fcc.html b/openpilot/selfdrive/assets/offroad/mici_fcc.html similarity index 100% rename from selfdrive/assets/offroad/mici_fcc.html rename to openpilot/selfdrive/assets/offroad/mici_fcc.html diff --git a/selfdrive/assets/prep-svg.sh b/openpilot/selfdrive/assets/prep-svg.sh similarity index 100% rename from selfdrive/assets/prep-svg.sh rename to openpilot/selfdrive/assets/prep-svg.sh diff --git a/selfdrive/assets/sounds/disengage.wav b/openpilot/selfdrive/assets/sounds/disengage.wav similarity index 100% rename from selfdrive/assets/sounds/disengage.wav rename to openpilot/selfdrive/assets/sounds/disengage.wav diff --git a/selfdrive/assets/sounds/disengage_tizi.wav b/openpilot/selfdrive/assets/sounds/disengage_tizi.wav similarity index 100% rename from selfdrive/assets/sounds/disengage_tizi.wav rename to openpilot/selfdrive/assets/sounds/disengage_tizi.wav diff --git a/selfdrive/assets/sounds/engage.wav b/openpilot/selfdrive/assets/sounds/engage.wav similarity index 100% rename from selfdrive/assets/sounds/engage.wav rename to openpilot/selfdrive/assets/sounds/engage.wav diff --git a/selfdrive/assets/sounds/engage_tizi.wav b/openpilot/selfdrive/assets/sounds/engage_tizi.wav similarity index 100% rename from selfdrive/assets/sounds/engage_tizi.wav rename to openpilot/selfdrive/assets/sounds/engage_tizi.wav diff --git a/selfdrive/assets/sounds/make_beeps.py b/openpilot/selfdrive/assets/sounds/make_beeps.py similarity index 100% rename from selfdrive/assets/sounds/make_beeps.py rename to openpilot/selfdrive/assets/sounds/make_beeps.py diff --git a/selfdrive/assets/sounds/prompt.wav b/openpilot/selfdrive/assets/sounds/prompt.wav similarity index 100% rename from selfdrive/assets/sounds/prompt.wav rename to openpilot/selfdrive/assets/sounds/prompt.wav diff --git a/selfdrive/assets/sounds/prompt_distracted.wav b/openpilot/selfdrive/assets/sounds/prompt_distracted.wav similarity index 100% rename from selfdrive/assets/sounds/prompt_distracted.wav rename to openpilot/selfdrive/assets/sounds/prompt_distracted.wav diff --git a/selfdrive/assets/sounds/refuse.wav b/openpilot/selfdrive/assets/sounds/refuse.wav similarity index 100% rename from selfdrive/assets/sounds/refuse.wav rename to openpilot/selfdrive/assets/sounds/refuse.wav diff --git a/selfdrive/assets/sounds/warning_immediate.wav b/openpilot/selfdrive/assets/sounds/warning_immediate.wav similarity index 100% rename from selfdrive/assets/sounds/warning_immediate.wav rename to openpilot/selfdrive/assets/sounds/warning_immediate.wav diff --git a/selfdrive/assets/sounds/warning_soft.wav b/openpilot/selfdrive/assets/sounds/warning_soft.wav similarity index 100% rename from selfdrive/assets/sounds/warning_soft.wav rename to openpilot/selfdrive/assets/sounds/warning_soft.wav diff --git a/selfdrive/assets/training/step0.png b/openpilot/selfdrive/assets/training/step0.png similarity index 100% rename from selfdrive/assets/training/step0.png rename to openpilot/selfdrive/assets/training/step0.png diff --git a/selfdrive/assets/training/step1.png b/openpilot/selfdrive/assets/training/step1.png similarity index 100% rename from selfdrive/assets/training/step1.png rename to openpilot/selfdrive/assets/training/step1.png diff --git a/selfdrive/assets/training/step10.png b/openpilot/selfdrive/assets/training/step10.png similarity index 100% rename from selfdrive/assets/training/step10.png rename to openpilot/selfdrive/assets/training/step10.png diff --git a/selfdrive/assets/training/step11.png b/openpilot/selfdrive/assets/training/step11.png similarity index 100% rename from selfdrive/assets/training/step11.png rename to openpilot/selfdrive/assets/training/step11.png diff --git a/selfdrive/assets/training/step12.png b/openpilot/selfdrive/assets/training/step12.png similarity index 100% rename from selfdrive/assets/training/step12.png rename to openpilot/selfdrive/assets/training/step12.png diff --git a/selfdrive/assets/training/step13.png b/openpilot/selfdrive/assets/training/step13.png similarity index 100% rename from selfdrive/assets/training/step13.png rename to openpilot/selfdrive/assets/training/step13.png diff --git a/selfdrive/assets/training/step14.png b/openpilot/selfdrive/assets/training/step14.png similarity index 100% rename from selfdrive/assets/training/step14.png rename to openpilot/selfdrive/assets/training/step14.png diff --git a/selfdrive/assets/training/step15.png b/openpilot/selfdrive/assets/training/step15.png similarity index 100% rename from selfdrive/assets/training/step15.png rename to openpilot/selfdrive/assets/training/step15.png diff --git a/selfdrive/assets/training/step16.png b/openpilot/selfdrive/assets/training/step16.png similarity index 100% rename from selfdrive/assets/training/step16.png rename to openpilot/selfdrive/assets/training/step16.png diff --git a/selfdrive/assets/training/step17.png b/openpilot/selfdrive/assets/training/step17.png similarity index 100% rename from selfdrive/assets/training/step17.png rename to openpilot/selfdrive/assets/training/step17.png diff --git a/selfdrive/assets/training/step18.png b/openpilot/selfdrive/assets/training/step18.png similarity index 100% rename from selfdrive/assets/training/step18.png rename to openpilot/selfdrive/assets/training/step18.png diff --git a/selfdrive/assets/training/step2.png b/openpilot/selfdrive/assets/training/step2.png similarity index 100% rename from selfdrive/assets/training/step2.png rename to openpilot/selfdrive/assets/training/step2.png diff --git a/selfdrive/assets/training/step3.png b/openpilot/selfdrive/assets/training/step3.png similarity index 100% rename from selfdrive/assets/training/step3.png rename to openpilot/selfdrive/assets/training/step3.png diff --git a/selfdrive/assets/training/step4.png b/openpilot/selfdrive/assets/training/step4.png similarity index 100% rename from selfdrive/assets/training/step4.png rename to openpilot/selfdrive/assets/training/step4.png diff --git a/selfdrive/assets/training/step5.png b/openpilot/selfdrive/assets/training/step5.png similarity index 100% rename from selfdrive/assets/training/step5.png rename to openpilot/selfdrive/assets/training/step5.png diff --git a/selfdrive/assets/training/step6.png b/openpilot/selfdrive/assets/training/step6.png similarity index 100% rename from selfdrive/assets/training/step6.png rename to openpilot/selfdrive/assets/training/step6.png diff --git a/selfdrive/assets/training/step7.png b/openpilot/selfdrive/assets/training/step7.png similarity index 100% rename from selfdrive/assets/training/step7.png rename to openpilot/selfdrive/assets/training/step7.png diff --git a/selfdrive/assets/training/step8.png b/openpilot/selfdrive/assets/training/step8.png similarity index 100% rename from selfdrive/assets/training/step8.png rename to openpilot/selfdrive/assets/training/step8.png diff --git a/selfdrive/assets/training/step9.png b/openpilot/selfdrive/assets/training/step9.png similarity index 100% rename from selfdrive/assets/training/step9.png rename to openpilot/selfdrive/assets/training/step9.png diff --git a/selfdrive/car/CARS_template.md b/openpilot/selfdrive/car/CARS_template.md similarity index 100% rename from selfdrive/car/CARS_template.md rename to openpilot/selfdrive/car/CARS_template.md diff --git a/selfdrive/car/__init__.py b/openpilot/selfdrive/car/__init__.py similarity index 100% rename from selfdrive/car/__init__.py rename to openpilot/selfdrive/car/__init__.py diff --git a/selfdrive/car/car_specific.py b/openpilot/selfdrive/car/car_specific.py similarity index 100% rename from selfdrive/car/car_specific.py rename to openpilot/selfdrive/car/car_specific.py diff --git a/selfdrive/car/card.py b/openpilot/selfdrive/car/card.py similarity index 100% rename from selfdrive/car/card.py rename to openpilot/selfdrive/car/card.py diff --git a/selfdrive/car/cruise.py b/openpilot/selfdrive/car/cruise.py similarity index 100% rename from selfdrive/car/cruise.py rename to openpilot/selfdrive/car/cruise.py diff --git a/selfdrive/car/docs.py b/openpilot/selfdrive/car/docs.py similarity index 100% rename from selfdrive/car/docs.py rename to openpilot/selfdrive/car/docs.py diff --git a/selfdrive/car/tests/__init__.py b/openpilot/selfdrive/car/tests/__init__.py similarity index 100% rename from selfdrive/car/tests/__init__.py rename to openpilot/selfdrive/car/tests/__init__.py diff --git a/selfdrive/car/tests/big_cars_test.sh b/openpilot/selfdrive/car/tests/big_cars_test.sh similarity index 85% rename from selfdrive/car/tests/big_cars_test.sh rename to openpilot/selfdrive/car/tests/big_cars_test.sh index 1c3da2e9e7..456fc698c5 100755 --- a/selfdrive/car/tests/big_cars_test.sh +++ b/openpilot/selfdrive/car/tests/big_cars_test.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash SCRIPT_DIR=$(dirname "$0") -BASEDIR=$(realpath "$SCRIPT_DIR/../../../") +BASEDIR=$(realpath "$SCRIPT_DIR/../../../../") cd $BASEDIR export MAX_EXAMPLES=300 diff --git a/selfdrive/car/tests/test_car_interfaces.py b/openpilot/selfdrive/car/tests/test_car_interfaces.py similarity index 100% rename from selfdrive/car/tests/test_car_interfaces.py rename to openpilot/selfdrive/car/tests/test_car_interfaces.py diff --git a/selfdrive/car/tests/test_cruise_speed.py b/openpilot/selfdrive/car/tests/test_cruise_speed.py similarity index 100% rename from selfdrive/car/tests/test_cruise_speed.py rename to openpilot/selfdrive/car/tests/test_cruise_speed.py diff --git a/selfdrive/car/tests/test_docs.py b/openpilot/selfdrive/car/tests/test_docs.py similarity index 100% rename from selfdrive/car/tests/test_docs.py rename to openpilot/selfdrive/car/tests/test_docs.py diff --git a/selfdrive/car/tests/test_models.py b/openpilot/selfdrive/car/tests/test_models.py similarity index 100% rename from selfdrive/car/tests/test_models.py rename to openpilot/selfdrive/car/tests/test_models.py diff --git a/selfdrive/car/tests/test_models_segs.txt b/openpilot/selfdrive/car/tests/test_models_segs.txt similarity index 100% rename from selfdrive/car/tests/test_models_segs.txt rename to openpilot/selfdrive/car/tests/test_models_segs.txt diff --git a/selfdrive/controls/__init__.py b/openpilot/selfdrive/controls/__init__.py similarity index 100% rename from selfdrive/controls/__init__.py rename to openpilot/selfdrive/controls/__init__.py diff --git a/selfdrive/controls/controlsd.py b/openpilot/selfdrive/controls/controlsd.py similarity index 100% rename from selfdrive/controls/controlsd.py rename to openpilot/selfdrive/controls/controlsd.py diff --git a/selfdrive/controls/lib/__init__.py b/openpilot/selfdrive/controls/lib/__init__.py similarity index 100% rename from selfdrive/controls/lib/__init__.py rename to openpilot/selfdrive/controls/lib/__init__.py diff --git a/selfdrive/controls/lib/desire_helper.py b/openpilot/selfdrive/controls/lib/desire_helper.py similarity index 100% rename from selfdrive/controls/lib/desire_helper.py rename to openpilot/selfdrive/controls/lib/desire_helper.py diff --git a/selfdrive/controls/lib/drive_helpers.py b/openpilot/selfdrive/controls/lib/drive_helpers.py similarity index 100% rename from selfdrive/controls/lib/drive_helpers.py rename to openpilot/selfdrive/controls/lib/drive_helpers.py diff --git a/selfdrive/controls/lib/latcontrol.py b/openpilot/selfdrive/controls/lib/latcontrol.py similarity index 100% rename from selfdrive/controls/lib/latcontrol.py rename to openpilot/selfdrive/controls/lib/latcontrol.py diff --git a/selfdrive/controls/lib/latcontrol_angle.py b/openpilot/selfdrive/controls/lib/latcontrol_angle.py similarity index 100% rename from selfdrive/controls/lib/latcontrol_angle.py rename to openpilot/selfdrive/controls/lib/latcontrol_angle.py diff --git a/selfdrive/controls/lib/latcontrol_curvature.py b/openpilot/selfdrive/controls/lib/latcontrol_curvature.py similarity index 100% rename from selfdrive/controls/lib/latcontrol_curvature.py rename to openpilot/selfdrive/controls/lib/latcontrol_curvature.py diff --git a/selfdrive/controls/lib/latcontrol_pid.py b/openpilot/selfdrive/controls/lib/latcontrol_pid.py similarity index 100% rename from selfdrive/controls/lib/latcontrol_pid.py rename to openpilot/selfdrive/controls/lib/latcontrol_pid.py diff --git a/selfdrive/controls/lib/latcontrol_torque.py b/openpilot/selfdrive/controls/lib/latcontrol_torque.py similarity index 100% rename from selfdrive/controls/lib/latcontrol_torque.py rename to openpilot/selfdrive/controls/lib/latcontrol_torque.py diff --git a/selfdrive/controls/lib/lateral_mpc_lib/.gitignore b/openpilot/selfdrive/controls/lib/lateral_mpc_lib/.gitignore similarity index 100% rename from selfdrive/controls/lib/lateral_mpc_lib/.gitignore rename to openpilot/selfdrive/controls/lib/lateral_mpc_lib/.gitignore diff --git a/selfdrive/controls/lib/lateral_mpc_lib/SConscript b/openpilot/selfdrive/controls/lib/lateral_mpc_lib/SConscript similarity index 100% rename from selfdrive/controls/lib/lateral_mpc_lib/SConscript rename to openpilot/selfdrive/controls/lib/lateral_mpc_lib/SConscript diff --git a/selfdrive/controls/lib/lateral_mpc_lib/__init__.py b/openpilot/selfdrive/controls/lib/lateral_mpc_lib/__init__.py similarity index 100% rename from selfdrive/controls/lib/lateral_mpc_lib/__init__.py rename to openpilot/selfdrive/controls/lib/lateral_mpc_lib/__init__.py diff --git a/selfdrive/controls/lib/lateral_mpc_lib/lat_mpc.py b/openpilot/selfdrive/controls/lib/lateral_mpc_lib/lat_mpc.py similarity index 100% rename from selfdrive/controls/lib/lateral_mpc_lib/lat_mpc.py rename to openpilot/selfdrive/controls/lib/lateral_mpc_lib/lat_mpc.py diff --git a/selfdrive/controls/lib/ldw.py b/openpilot/selfdrive/controls/lib/ldw.py similarity index 100% rename from selfdrive/controls/lib/ldw.py rename to openpilot/selfdrive/controls/lib/ldw.py diff --git a/selfdrive/controls/lib/longcontrol.py b/openpilot/selfdrive/controls/lib/longcontrol.py similarity index 100% rename from selfdrive/controls/lib/longcontrol.py rename to openpilot/selfdrive/controls/lib/longcontrol.py diff --git a/selfdrive/controls/lib/longitudinal_mpc_lib/.gitignore b/openpilot/selfdrive/controls/lib/longitudinal_mpc_lib/.gitignore similarity index 100% rename from selfdrive/controls/lib/longitudinal_mpc_lib/.gitignore rename to openpilot/selfdrive/controls/lib/longitudinal_mpc_lib/.gitignore diff --git a/selfdrive/controls/lib/longitudinal_mpc_lib/SConscript b/openpilot/selfdrive/controls/lib/longitudinal_mpc_lib/SConscript similarity index 100% rename from selfdrive/controls/lib/longitudinal_mpc_lib/SConscript rename to openpilot/selfdrive/controls/lib/longitudinal_mpc_lib/SConscript diff --git a/selfdrive/controls/lib/longitudinal_mpc_lib/__init__.py b/openpilot/selfdrive/controls/lib/longitudinal_mpc_lib/__init__.py similarity index 100% rename from selfdrive/controls/lib/longitudinal_mpc_lib/__init__.py rename to openpilot/selfdrive/controls/lib/longitudinal_mpc_lib/__init__.py diff --git a/selfdrive/controls/lib/longitudinal_mpc_lib/long_mpc.py b/openpilot/selfdrive/controls/lib/longitudinal_mpc_lib/long_mpc.py similarity index 100% rename from selfdrive/controls/lib/longitudinal_mpc_lib/long_mpc.py rename to openpilot/selfdrive/controls/lib/longitudinal_mpc_lib/long_mpc.py diff --git a/selfdrive/controls/lib/longitudinal_planner.py b/openpilot/selfdrive/controls/lib/longitudinal_planner.py similarity index 100% rename from selfdrive/controls/lib/longitudinal_planner.py rename to openpilot/selfdrive/controls/lib/longitudinal_planner.py diff --git a/selfdrive/controls/plannerd.py b/openpilot/selfdrive/controls/plannerd.py similarity index 100% rename from selfdrive/controls/plannerd.py rename to openpilot/selfdrive/controls/plannerd.py diff --git a/selfdrive/controls/radard.py b/openpilot/selfdrive/controls/radard.py similarity index 100% rename from selfdrive/controls/radard.py rename to openpilot/selfdrive/controls/radard.py diff --git a/selfdrive/controls/tests/__init__.py b/openpilot/selfdrive/controls/tests/__init__.py similarity index 100% rename from selfdrive/controls/tests/__init__.py rename to openpilot/selfdrive/controls/tests/__init__.py diff --git a/selfdrive/controls/tests/test_following_distance.py b/openpilot/selfdrive/controls/tests/test_following_distance.py similarity index 100% rename from selfdrive/controls/tests/test_following_distance.py rename to openpilot/selfdrive/controls/tests/test_following_distance.py diff --git a/selfdrive/controls/tests/test_latcontrol.py b/openpilot/selfdrive/controls/tests/test_latcontrol.py similarity index 100% rename from selfdrive/controls/tests/test_latcontrol.py rename to openpilot/selfdrive/controls/tests/test_latcontrol.py diff --git a/selfdrive/controls/tests/test_latcontrol_torque_buffer.py b/openpilot/selfdrive/controls/tests/test_latcontrol_torque_buffer.py similarity index 100% rename from selfdrive/controls/tests/test_latcontrol_torque_buffer.py rename to openpilot/selfdrive/controls/tests/test_latcontrol_torque_buffer.py diff --git a/selfdrive/controls/tests/test_lateral_mpc.py b/openpilot/selfdrive/controls/tests/test_lateral_mpc.py similarity index 100% rename from selfdrive/controls/tests/test_lateral_mpc.py rename to openpilot/selfdrive/controls/tests/test_lateral_mpc.py diff --git a/selfdrive/controls/tests/test_leads.py b/openpilot/selfdrive/controls/tests/test_leads.py similarity index 100% rename from selfdrive/controls/tests/test_leads.py rename to openpilot/selfdrive/controls/tests/test_leads.py diff --git a/selfdrive/controls/tests/test_longcontrol.py b/openpilot/selfdrive/controls/tests/test_longcontrol.py similarity index 100% rename from selfdrive/controls/tests/test_longcontrol.py rename to openpilot/selfdrive/controls/tests/test_longcontrol.py diff --git a/selfdrive/controls/tests/test_torqued_lat_accel_offset.py b/openpilot/selfdrive/controls/tests/test_torqued_lat_accel_offset.py similarity index 100% rename from selfdrive/controls/tests/test_torqued_lat_accel_offset.py rename to openpilot/selfdrive/controls/tests/test_torqued_lat_accel_offset.py diff --git a/selfdrive/locationd/SConscript b/openpilot/selfdrive/locationd/SConscript similarity index 100% rename from selfdrive/locationd/SConscript rename to openpilot/selfdrive/locationd/SConscript diff --git a/selfdrive/locationd/__init__.py b/openpilot/selfdrive/locationd/__init__.py similarity index 100% rename from selfdrive/locationd/__init__.py rename to openpilot/selfdrive/locationd/__init__.py diff --git a/selfdrive/locationd/calibrationd.py b/openpilot/selfdrive/locationd/calibrationd.py similarity index 100% rename from selfdrive/locationd/calibrationd.py rename to openpilot/selfdrive/locationd/calibrationd.py diff --git a/selfdrive/locationd/helpers.py b/openpilot/selfdrive/locationd/helpers.py similarity index 100% rename from selfdrive/locationd/helpers.py rename to openpilot/selfdrive/locationd/helpers.py diff --git a/selfdrive/locationd/lagd.py b/openpilot/selfdrive/locationd/lagd.py similarity index 100% rename from selfdrive/locationd/lagd.py rename to openpilot/selfdrive/locationd/lagd.py diff --git a/selfdrive/locationd/locationd.py b/openpilot/selfdrive/locationd/locationd.py similarity index 100% rename from selfdrive/locationd/locationd.py rename to openpilot/selfdrive/locationd/locationd.py diff --git a/selfdrive/locationd/models/.gitignore b/openpilot/selfdrive/locationd/models/.gitignore similarity index 100% rename from selfdrive/locationd/models/.gitignore rename to openpilot/selfdrive/locationd/models/.gitignore diff --git a/selfdrive/locationd/models/__init__.py b/openpilot/selfdrive/locationd/models/__init__.py similarity index 100% rename from selfdrive/locationd/models/__init__.py rename to openpilot/selfdrive/locationd/models/__init__.py diff --git a/selfdrive/locationd/models/car_kf.py b/openpilot/selfdrive/locationd/models/car_kf.py similarity index 100% rename from selfdrive/locationd/models/car_kf.py rename to openpilot/selfdrive/locationd/models/car_kf.py diff --git a/selfdrive/locationd/models/constants.py b/openpilot/selfdrive/locationd/models/constants.py similarity index 100% rename from selfdrive/locationd/models/constants.py rename to openpilot/selfdrive/locationd/models/constants.py diff --git a/selfdrive/locationd/models/pose_kf.py b/openpilot/selfdrive/locationd/models/pose_kf.py similarity index 100% rename from selfdrive/locationd/models/pose_kf.py rename to openpilot/selfdrive/locationd/models/pose_kf.py diff --git a/selfdrive/locationd/paramsd.py b/openpilot/selfdrive/locationd/paramsd.py similarity index 100% rename from selfdrive/locationd/paramsd.py rename to openpilot/selfdrive/locationd/paramsd.py diff --git a/selfdrive/locationd/test/__init__.py b/openpilot/selfdrive/locationd/test/__init__.py similarity index 100% rename from selfdrive/locationd/test/__init__.py rename to openpilot/selfdrive/locationd/test/__init__.py diff --git a/selfdrive/locationd/test/test_calibrationd.py b/openpilot/selfdrive/locationd/test/test_calibrationd.py similarity index 100% rename from selfdrive/locationd/test/test_calibrationd.py rename to openpilot/selfdrive/locationd/test/test_calibrationd.py diff --git a/selfdrive/locationd/test/test_lagd.py b/openpilot/selfdrive/locationd/test/test_lagd.py similarity index 100% rename from selfdrive/locationd/test/test_lagd.py rename to openpilot/selfdrive/locationd/test/test_lagd.py diff --git a/selfdrive/locationd/test/test_locationd_scenarios.py b/openpilot/selfdrive/locationd/test/test_locationd_scenarios.py similarity index 100% rename from selfdrive/locationd/test/test_locationd_scenarios.py rename to openpilot/selfdrive/locationd/test/test_locationd_scenarios.py diff --git a/selfdrive/locationd/test/test_paramsd.py b/openpilot/selfdrive/locationd/test/test_paramsd.py similarity index 100% rename from selfdrive/locationd/test/test_paramsd.py rename to openpilot/selfdrive/locationd/test/test_paramsd.py diff --git a/selfdrive/locationd/test/test_torqued.py b/openpilot/selfdrive/locationd/test/test_torqued.py similarity index 100% rename from selfdrive/locationd/test/test_torqued.py rename to openpilot/selfdrive/locationd/test/test_torqued.py diff --git a/selfdrive/locationd/torqued.py b/openpilot/selfdrive/locationd/torqued.py similarity index 100% rename from selfdrive/locationd/torqued.py rename to openpilot/selfdrive/locationd/torqued.py diff --git a/selfdrive/modeld/SConscript b/openpilot/selfdrive/modeld/SConscript similarity index 100% rename from selfdrive/modeld/SConscript rename to openpilot/selfdrive/modeld/SConscript diff --git a/selfdrive/modeld/__init__.py b/openpilot/selfdrive/modeld/__init__.py similarity index 100% rename from selfdrive/modeld/__init__.py rename to openpilot/selfdrive/modeld/__init__.py diff --git a/selfdrive/modeld/compile_dm_warp.py b/openpilot/selfdrive/modeld/compile_dm_warp.py similarity index 100% rename from selfdrive/modeld/compile_dm_warp.py rename to openpilot/selfdrive/modeld/compile_dm_warp.py diff --git a/selfdrive/modeld/compile_modeld.py b/openpilot/selfdrive/modeld/compile_modeld.py similarity index 100% rename from selfdrive/modeld/compile_modeld.py rename to openpilot/selfdrive/modeld/compile_modeld.py diff --git a/selfdrive/modeld/constants.py b/openpilot/selfdrive/modeld/constants.py similarity index 100% rename from selfdrive/modeld/constants.py rename to openpilot/selfdrive/modeld/constants.py diff --git a/selfdrive/modeld/dmonitoringmodeld.py b/openpilot/selfdrive/modeld/dmonitoringmodeld.py similarity index 100% rename from selfdrive/modeld/dmonitoringmodeld.py rename to openpilot/selfdrive/modeld/dmonitoringmodeld.py diff --git a/selfdrive/modeld/fill_model_msg.py b/openpilot/selfdrive/modeld/fill_model_msg.py similarity index 100% rename from selfdrive/modeld/fill_model_msg.py rename to openpilot/selfdrive/modeld/fill_model_msg.py diff --git a/selfdrive/modeld/get_model_metadata.py b/openpilot/selfdrive/modeld/get_model_metadata.py similarity index 100% rename from selfdrive/modeld/get_model_metadata.py rename to openpilot/selfdrive/modeld/get_model_metadata.py diff --git a/selfdrive/modeld/helpers.py b/openpilot/selfdrive/modeld/helpers.py similarity index 100% rename from selfdrive/modeld/helpers.py rename to openpilot/selfdrive/modeld/helpers.py diff --git a/selfdrive/modeld/modeld.py b/openpilot/selfdrive/modeld/modeld.py similarity index 100% rename from selfdrive/modeld/modeld.py rename to openpilot/selfdrive/modeld/modeld.py diff --git a/selfdrive/modeld/models/README.md b/openpilot/selfdrive/modeld/models/README.md similarity index 100% rename from selfdrive/modeld/models/README.md rename to openpilot/selfdrive/modeld/models/README.md diff --git a/selfdrive/modeld/models/__init__.py b/openpilot/selfdrive/modeld/models/__init__.py similarity index 100% rename from selfdrive/modeld/models/__init__.py rename to openpilot/selfdrive/modeld/models/__init__.py diff --git a/selfdrive/modeld/models/big_driving_supercombo.onnx b/openpilot/selfdrive/modeld/models/big_driving_supercombo.onnx similarity index 100% rename from selfdrive/modeld/models/big_driving_supercombo.onnx rename to openpilot/selfdrive/modeld/models/big_driving_supercombo.onnx diff --git a/selfdrive/modeld/models/dmonitoring_model.onnx b/openpilot/selfdrive/modeld/models/dmonitoring_model.onnx similarity index 100% rename from selfdrive/modeld/models/dmonitoring_model.onnx rename to openpilot/selfdrive/modeld/models/dmonitoring_model.onnx diff --git a/selfdrive/modeld/models/driving_supercombo.onnx b/openpilot/selfdrive/modeld/models/driving_supercombo.onnx similarity index 100% rename from selfdrive/modeld/models/driving_supercombo.onnx rename to openpilot/selfdrive/modeld/models/driving_supercombo.onnx diff --git a/selfdrive/modeld/parse_model_outputs.py b/openpilot/selfdrive/modeld/parse_model_outputs.py similarity index 100% rename from selfdrive/modeld/parse_model_outputs.py rename to openpilot/selfdrive/modeld/parse_model_outputs.py diff --git a/selfdrive/monitoring/dmonitoringd.py b/openpilot/selfdrive/monitoring/dmonitoringd.py similarity index 100% rename from selfdrive/monitoring/dmonitoringd.py rename to openpilot/selfdrive/monitoring/dmonitoringd.py diff --git a/selfdrive/monitoring/policy.py b/openpilot/selfdrive/monitoring/policy.py similarity index 100% rename from selfdrive/monitoring/policy.py rename to openpilot/selfdrive/monitoring/policy.py diff --git a/selfdrive/monitoring/test_monitoring.py b/openpilot/selfdrive/monitoring/test_monitoring.py similarity index 100% rename from selfdrive/monitoring/test_monitoring.py rename to openpilot/selfdrive/monitoring/test_monitoring.py diff --git a/selfdrive/pandad/.gitignore b/openpilot/selfdrive/pandad/.gitignore similarity index 100% rename from selfdrive/pandad/.gitignore rename to openpilot/selfdrive/pandad/.gitignore diff --git a/selfdrive/pandad/SConscript b/openpilot/selfdrive/pandad/SConscript similarity index 100% rename from selfdrive/pandad/SConscript rename to openpilot/selfdrive/pandad/SConscript diff --git a/selfdrive/pandad/__init__.py b/openpilot/selfdrive/pandad/__init__.py similarity index 100% rename from selfdrive/pandad/__init__.py rename to openpilot/selfdrive/pandad/__init__.py diff --git a/selfdrive/pandad/main.cc b/openpilot/selfdrive/pandad/main.cc similarity index 100% rename from selfdrive/pandad/main.cc rename to openpilot/selfdrive/pandad/main.cc diff --git a/selfdrive/pandad/panda.cc b/openpilot/selfdrive/pandad/panda.cc similarity index 98% rename from selfdrive/pandad/panda.cc rename to openpilot/selfdrive/pandad/panda.cc index 730ce59b6e..d067a73107 100644 --- a/selfdrive/pandad/panda.cc +++ b/openpilot/selfdrive/pandad/panda.cc @@ -116,7 +116,7 @@ std::optional Panda::get_serial() { bool Panda::up_to_date() { if (auto fw_sig = get_firmware_version()) { for (auto fn : { "panda.bin.signed", "panda_h7.bin.signed" }) { - auto content = util::read_file(std::string("../../panda/board/obj/") + fn); + auto content = util::read_file(std::string("../../../panda/board/obj/") + fn); if (content.size() >= fw_sig->size() && memcmp(content.data() + content.size() - fw_sig->size(), fw_sig->data(), fw_sig->size()) == 0) { return true; diff --git a/selfdrive/pandad/panda.h b/openpilot/selfdrive/pandad/panda.h similarity index 100% rename from selfdrive/pandad/panda.h rename to openpilot/selfdrive/pandad/panda.h diff --git a/selfdrive/pandad/panda_comms.h b/openpilot/selfdrive/pandad/panda_comms.h similarity index 100% rename from selfdrive/pandad/panda_comms.h rename to openpilot/selfdrive/pandad/panda_comms.h diff --git a/selfdrive/pandad/panda_safety.cc b/openpilot/selfdrive/pandad/panda_safety.cc similarity index 100% rename from selfdrive/pandad/panda_safety.cc rename to openpilot/selfdrive/pandad/panda_safety.cc diff --git a/selfdrive/pandad/pandad.cc b/openpilot/selfdrive/pandad/pandad.cc similarity index 100% rename from selfdrive/pandad/pandad.cc rename to openpilot/selfdrive/pandad/pandad.cc diff --git a/selfdrive/pandad/pandad.h b/openpilot/selfdrive/pandad/pandad.h similarity index 100% rename from selfdrive/pandad/pandad.h rename to openpilot/selfdrive/pandad/pandad.h diff --git a/selfdrive/pandad/pandad.py b/openpilot/selfdrive/pandad/pandad.py similarity index 100% rename from selfdrive/pandad/pandad.py rename to openpilot/selfdrive/pandad/pandad.py diff --git a/selfdrive/pandad/pandad_api_impl.py b/openpilot/selfdrive/pandad/pandad_api_impl.py similarity index 100% rename from selfdrive/pandad/pandad_api_impl.py rename to openpilot/selfdrive/pandad/pandad_api_impl.py diff --git a/selfdrive/pandad/spi.cc b/openpilot/selfdrive/pandad/spi.cc similarity index 100% rename from selfdrive/pandad/spi.cc rename to openpilot/selfdrive/pandad/spi.cc diff --git a/selfdrive/pandad/tests/__init__.py b/openpilot/selfdrive/pandad/tests/__init__.py similarity index 100% rename from selfdrive/pandad/tests/__init__.py rename to openpilot/selfdrive/pandad/tests/__init__.py diff --git a/selfdrive/pandad/tests/bootstub.panda_h7.bin b/openpilot/selfdrive/pandad/tests/bootstub.panda_h7.bin similarity index 100% rename from selfdrive/pandad/tests/bootstub.panda_h7.bin rename to openpilot/selfdrive/pandad/tests/bootstub.panda_h7.bin diff --git a/selfdrive/pandad/tests/test_pandad.py b/openpilot/selfdrive/pandad/tests/test_pandad.py similarity index 100% rename from selfdrive/pandad/tests/test_pandad.py rename to openpilot/selfdrive/pandad/tests/test_pandad.py diff --git a/selfdrive/pandad/tests/test_pandad_canprotocol.cc b/openpilot/selfdrive/pandad/tests/test_pandad_canprotocol.cc similarity index 100% rename from selfdrive/pandad/tests/test_pandad_canprotocol.cc rename to openpilot/selfdrive/pandad/tests/test_pandad_canprotocol.cc diff --git a/selfdrive/pandad/tests/test_pandad_loopback.py b/openpilot/selfdrive/pandad/tests/test_pandad_loopback.py similarity index 100% rename from selfdrive/pandad/tests/test_pandad_loopback.py rename to openpilot/selfdrive/pandad/tests/test_pandad_loopback.py diff --git a/selfdrive/pandad/tests/test_pandad_spi.py b/openpilot/selfdrive/pandad/tests/test_pandad_spi.py similarity index 100% rename from selfdrive/pandad/tests/test_pandad_spi.py rename to openpilot/selfdrive/pandad/tests/test_pandad_spi.py diff --git a/selfdrive/selfdrived/alertmanager.py b/openpilot/selfdrive/selfdrived/alertmanager.py similarity index 100% rename from selfdrive/selfdrived/alertmanager.py rename to openpilot/selfdrive/selfdrived/alertmanager.py diff --git a/selfdrive/selfdrived/alerts_offroad.json b/openpilot/selfdrive/selfdrived/alerts_offroad.json similarity index 100% rename from selfdrive/selfdrived/alerts_offroad.json rename to openpilot/selfdrive/selfdrived/alerts_offroad.json diff --git a/selfdrive/selfdrived/events.py b/openpilot/selfdrive/selfdrived/events.py similarity index 100% rename from selfdrive/selfdrived/events.py rename to openpilot/selfdrive/selfdrived/events.py diff --git a/selfdrive/selfdrived/helpers.py b/openpilot/selfdrive/selfdrived/helpers.py similarity index 100% rename from selfdrive/selfdrived/helpers.py rename to openpilot/selfdrive/selfdrived/helpers.py diff --git a/selfdrive/selfdrived/selfdrived.py b/openpilot/selfdrive/selfdrived/selfdrived.py similarity index 100% rename from selfdrive/selfdrived/selfdrived.py rename to openpilot/selfdrive/selfdrived/selfdrived.py diff --git a/selfdrive/selfdrived/state.py b/openpilot/selfdrive/selfdrived/state.py similarity index 100% rename from selfdrive/selfdrived/state.py rename to openpilot/selfdrive/selfdrived/state.py diff --git a/selfdrive/selfdrived/tests/test_alertmanager.py b/openpilot/selfdrive/selfdrived/tests/test_alertmanager.py similarity index 100% rename from selfdrive/selfdrived/tests/test_alertmanager.py rename to openpilot/selfdrive/selfdrived/tests/test_alertmanager.py diff --git a/selfdrive/selfdrived/tests/test_alerts.py b/openpilot/selfdrive/selfdrived/tests/test_alerts.py similarity index 100% rename from selfdrive/selfdrived/tests/test_alerts.py rename to openpilot/selfdrive/selfdrived/tests/test_alerts.py diff --git a/selfdrive/selfdrived/tests/test_state_machine.py b/openpilot/selfdrive/selfdrived/tests/test_state_machine.py similarity index 100% rename from selfdrive/selfdrived/tests/test_state_machine.py rename to openpilot/selfdrive/selfdrived/tests/test_state_machine.py diff --git a/selfdrive/test/.gitignore b/openpilot/selfdrive/test/.gitignore similarity index 100% rename from selfdrive/test/.gitignore rename to openpilot/selfdrive/test/.gitignore diff --git a/selfdrive/test/__init__.py b/openpilot/selfdrive/test/__init__.py similarity index 100% rename from selfdrive/test/__init__.py rename to openpilot/selfdrive/test/__init__.py diff --git a/selfdrive/test/cpp_harness.py b/openpilot/selfdrive/test/cpp_harness.py similarity index 100% rename from selfdrive/test/cpp_harness.py rename to openpilot/selfdrive/test/cpp_harness.py diff --git a/selfdrive/test/fuzzy_generation.py b/openpilot/selfdrive/test/fuzzy_generation.py similarity index 100% rename from selfdrive/test/fuzzy_generation.py rename to openpilot/selfdrive/test/fuzzy_generation.py diff --git a/selfdrive/test/helpers.py b/openpilot/selfdrive/test/helpers.py similarity index 100% rename from selfdrive/test/helpers.py rename to openpilot/selfdrive/test/helpers.py diff --git a/selfdrive/test/longitudinal_maneuvers/.gitignore b/openpilot/selfdrive/test/longitudinal_maneuvers/.gitignore similarity index 100% rename from selfdrive/test/longitudinal_maneuvers/.gitignore rename to openpilot/selfdrive/test/longitudinal_maneuvers/.gitignore diff --git a/selfdrive/test/longitudinal_maneuvers/__init__.py b/openpilot/selfdrive/test/longitudinal_maneuvers/__init__.py similarity index 100% rename from selfdrive/test/longitudinal_maneuvers/__init__.py rename to openpilot/selfdrive/test/longitudinal_maneuvers/__init__.py diff --git a/selfdrive/test/longitudinal_maneuvers/maneuver.py b/openpilot/selfdrive/test/longitudinal_maneuvers/maneuver.py similarity index 100% rename from selfdrive/test/longitudinal_maneuvers/maneuver.py rename to openpilot/selfdrive/test/longitudinal_maneuvers/maneuver.py diff --git a/selfdrive/test/longitudinal_maneuvers/plant.py b/openpilot/selfdrive/test/longitudinal_maneuvers/plant.py similarity index 100% rename from selfdrive/test/longitudinal_maneuvers/plant.py rename to openpilot/selfdrive/test/longitudinal_maneuvers/plant.py diff --git a/selfdrive/test/longitudinal_maneuvers/test_longitudinal.py b/openpilot/selfdrive/test/longitudinal_maneuvers/test_longitudinal.py similarity index 100% rename from selfdrive/test/longitudinal_maneuvers/test_longitudinal.py rename to openpilot/selfdrive/test/longitudinal_maneuvers/test_longitudinal.py diff --git a/selfdrive/test/process_replay/README.md b/openpilot/selfdrive/test/process_replay/README.md similarity index 100% rename from selfdrive/test/process_replay/README.md rename to openpilot/selfdrive/test/process_replay/README.md diff --git a/selfdrive/test/process_replay/__init__.py b/openpilot/selfdrive/test/process_replay/__init__.py similarity index 100% rename from selfdrive/test/process_replay/__init__.py rename to openpilot/selfdrive/test/process_replay/__init__.py diff --git a/selfdrive/test/process_replay/capture.py b/openpilot/selfdrive/test/process_replay/capture.py similarity index 100% rename from selfdrive/test/process_replay/capture.py rename to openpilot/selfdrive/test/process_replay/capture.py diff --git a/selfdrive/test/process_replay/compare_logs.py b/openpilot/selfdrive/test/process_replay/compare_logs.py similarity index 100% rename from selfdrive/test/process_replay/compare_logs.py rename to openpilot/selfdrive/test/process_replay/compare_logs.py diff --git a/selfdrive/test/process_replay/diff_report.py b/openpilot/selfdrive/test/process_replay/diff_report.py similarity index 100% rename from selfdrive/test/process_replay/diff_report.py rename to openpilot/selfdrive/test/process_replay/diff_report.py diff --git a/selfdrive/test/process_replay/migration.py b/openpilot/selfdrive/test/process_replay/migration.py similarity index 100% rename from selfdrive/test/process_replay/migration.py rename to openpilot/selfdrive/test/process_replay/migration.py diff --git a/selfdrive/test/process_replay/model_replay.py b/openpilot/selfdrive/test/process_replay/model_replay.py similarity index 100% rename from selfdrive/test/process_replay/model_replay.py rename to openpilot/selfdrive/test/process_replay/model_replay.py diff --git a/selfdrive/test/process_replay/process_replay.py b/openpilot/selfdrive/test/process_replay/process_replay.py similarity index 100% rename from selfdrive/test/process_replay/process_replay.py rename to openpilot/selfdrive/test/process_replay/process_replay.py diff --git a/selfdrive/test/process_replay/regen.py b/openpilot/selfdrive/test/process_replay/regen.py similarity index 100% rename from selfdrive/test/process_replay/regen.py rename to openpilot/selfdrive/test/process_replay/regen.py diff --git a/selfdrive/test/process_replay/regen_all.py b/openpilot/selfdrive/test/process_replay/regen_all.py similarity index 100% rename from selfdrive/test/process_replay/regen_all.py rename to openpilot/selfdrive/test/process_replay/regen_all.py diff --git a/selfdrive/test/process_replay/test_fuzzy.py b/openpilot/selfdrive/test/process_replay/test_fuzzy.py similarity index 100% rename from selfdrive/test/process_replay/test_fuzzy.py rename to openpilot/selfdrive/test/process_replay/test_fuzzy.py diff --git a/selfdrive/test/process_replay/test_processes.py b/openpilot/selfdrive/test/process_replay/test_processes.py similarity index 100% rename from selfdrive/test/process_replay/test_processes.py rename to openpilot/selfdrive/test/process_replay/test_processes.py diff --git a/selfdrive/test/process_replay/test_regen.py b/openpilot/selfdrive/test/process_replay/test_regen.py similarity index 100% rename from selfdrive/test/process_replay/test_regen.py rename to openpilot/selfdrive/test/process_replay/test_regen.py diff --git a/selfdrive/test/process_replay/vision_meta.py b/openpilot/selfdrive/test/process_replay/vision_meta.py similarity index 100% rename from selfdrive/test/process_replay/vision_meta.py rename to openpilot/selfdrive/test/process_replay/vision_meta.py diff --git a/selfdrive/test/scons_build_test.sh b/openpilot/selfdrive/test/scons_build_test.sh similarity index 89% rename from selfdrive/test/scons_build_test.sh rename to openpilot/selfdrive/test/scons_build_test.sh index d4a0733569..6f6eafcad1 100755 --- a/selfdrive/test/scons_build_test.sh +++ b/openpilot/selfdrive/test/scons_build_test.sh @@ -2,7 +2,7 @@ set -e SCRIPT_DIR=$(dirname "$0") -BASEDIR=$(realpath "$SCRIPT_DIR/../../") +BASEDIR=$(realpath "$SCRIPT_DIR/../../../") cd $BASEDIR # tests that our build system's dependencies are configured properly, diff --git a/selfdrive/test/setup_device_ci.sh b/openpilot/selfdrive/test/setup_device_ci.sh similarity index 100% rename from selfdrive/test/setup_device_ci.sh rename to openpilot/selfdrive/test/setup_device_ci.sh diff --git a/selfdrive/test/setup_xvfb.sh b/openpilot/selfdrive/test/setup_xvfb.sh similarity index 100% rename from selfdrive/test/setup_xvfb.sh rename to openpilot/selfdrive/test/setup_xvfb.sh diff --git a/selfdrive/test/test_onroad.py b/openpilot/selfdrive/test/test_onroad.py similarity index 100% rename from selfdrive/test/test_onroad.py rename to openpilot/selfdrive/test/test_onroad.py diff --git a/selfdrive/test/test_power_draw.py b/openpilot/selfdrive/test/test_power_draw.py similarity index 100% rename from selfdrive/test/test_power_draw.py rename to openpilot/selfdrive/test/test_power_draw.py diff --git a/selfdrive/test/update_ci_routes.py b/openpilot/selfdrive/test/update_ci_routes.py similarity index 100% rename from selfdrive/test/update_ci_routes.py rename to openpilot/selfdrive/test/update_ci_routes.py diff --git a/selfdrive/ui/.gitignore b/openpilot/selfdrive/ui/.gitignore similarity index 100% rename from selfdrive/ui/.gitignore rename to openpilot/selfdrive/ui/.gitignore diff --git a/selfdrive/ui/SConscript b/openpilot/selfdrive/ui/SConscript similarity index 100% rename from selfdrive/ui/SConscript rename to openpilot/selfdrive/ui/SConscript diff --git a/selfdrive/ui/__init__.py b/openpilot/selfdrive/ui/__init__.py similarity index 100% rename from selfdrive/ui/__init__.py rename to openpilot/selfdrive/ui/__init__.py diff --git a/selfdrive/ui/body/__init__.py b/openpilot/selfdrive/ui/body/__init__.py similarity index 100% rename from selfdrive/ui/body/__init__.py rename to openpilot/selfdrive/ui/body/__init__.py diff --git a/selfdrive/ui/body/animations.py b/openpilot/selfdrive/ui/body/animations.py similarity index 100% rename from selfdrive/ui/body/animations.py rename to openpilot/selfdrive/ui/body/animations.py diff --git a/selfdrive/ui/body/layouts/__init__.py b/openpilot/selfdrive/ui/body/layouts/__init__.py similarity index 100% rename from selfdrive/ui/body/layouts/__init__.py rename to openpilot/selfdrive/ui/body/layouts/__init__.py diff --git a/selfdrive/ui/body/layouts/onroad.py b/openpilot/selfdrive/ui/body/layouts/onroad.py similarity index 100% rename from selfdrive/ui/body/layouts/onroad.py rename to openpilot/selfdrive/ui/body/layouts/onroad.py diff --git a/selfdrive/ui/feedback/feedbackd.py b/openpilot/selfdrive/ui/feedback/feedbackd.py similarity index 100% rename from selfdrive/ui/feedback/feedbackd.py rename to openpilot/selfdrive/ui/feedback/feedbackd.py diff --git a/selfdrive/ui/installer/continue_openpilot.sh b/openpilot/selfdrive/ui/installer/continue_openpilot.sh similarity index 100% rename from selfdrive/ui/installer/continue_openpilot.sh rename to openpilot/selfdrive/ui/installer/continue_openpilot.sh diff --git a/selfdrive/ui/installer/installer.cc b/openpilot/selfdrive/ui/installer/installer.cc similarity index 100% rename from selfdrive/ui/installer/installer.cc rename to openpilot/selfdrive/ui/installer/installer.cc diff --git a/selfdrive/ui/installer/inter-ascii.ttf b/openpilot/selfdrive/ui/installer/inter-ascii.ttf similarity index 100% rename from selfdrive/ui/installer/inter-ascii.ttf rename to openpilot/selfdrive/ui/installer/inter-ascii.ttf diff --git a/selfdrive/ui/layouts/__init__.py b/openpilot/selfdrive/ui/layouts/__init__.py similarity index 100% rename from selfdrive/ui/layouts/__init__.py rename to openpilot/selfdrive/ui/layouts/__init__.py diff --git a/selfdrive/ui/layouts/home.py b/openpilot/selfdrive/ui/layouts/home.py similarity index 100% rename from selfdrive/ui/layouts/home.py rename to openpilot/selfdrive/ui/layouts/home.py diff --git a/selfdrive/ui/layouts/main.py b/openpilot/selfdrive/ui/layouts/main.py similarity index 100% rename from selfdrive/ui/layouts/main.py rename to openpilot/selfdrive/ui/layouts/main.py diff --git a/selfdrive/ui/layouts/onboarding.py b/openpilot/selfdrive/ui/layouts/onboarding.py similarity index 100% rename from selfdrive/ui/layouts/onboarding.py rename to openpilot/selfdrive/ui/layouts/onboarding.py diff --git a/selfdrive/ui/layouts/settings/common.py b/openpilot/selfdrive/ui/layouts/settings/common.py similarity index 100% rename from selfdrive/ui/layouts/settings/common.py rename to openpilot/selfdrive/ui/layouts/settings/common.py diff --git a/selfdrive/ui/layouts/settings/developer.py b/openpilot/selfdrive/ui/layouts/settings/developer.py similarity index 100% rename from selfdrive/ui/layouts/settings/developer.py rename to openpilot/selfdrive/ui/layouts/settings/developer.py diff --git a/selfdrive/ui/layouts/settings/device.py b/openpilot/selfdrive/ui/layouts/settings/device.py similarity index 100% rename from selfdrive/ui/layouts/settings/device.py rename to openpilot/selfdrive/ui/layouts/settings/device.py diff --git a/selfdrive/ui/layouts/settings/firehose.py b/openpilot/selfdrive/ui/layouts/settings/firehose.py similarity index 100% rename from selfdrive/ui/layouts/settings/firehose.py rename to openpilot/selfdrive/ui/layouts/settings/firehose.py diff --git a/selfdrive/ui/layouts/settings/settings.py b/openpilot/selfdrive/ui/layouts/settings/settings.py similarity index 100% rename from selfdrive/ui/layouts/settings/settings.py rename to openpilot/selfdrive/ui/layouts/settings/settings.py diff --git a/selfdrive/ui/layouts/settings/software.py b/openpilot/selfdrive/ui/layouts/settings/software.py similarity index 100% rename from selfdrive/ui/layouts/settings/software.py rename to openpilot/selfdrive/ui/layouts/settings/software.py diff --git a/selfdrive/ui/layouts/settings/toggles.py b/openpilot/selfdrive/ui/layouts/settings/toggles.py similarity index 100% rename from selfdrive/ui/layouts/settings/toggles.py rename to openpilot/selfdrive/ui/layouts/settings/toggles.py diff --git a/selfdrive/ui/layouts/sidebar.py b/openpilot/selfdrive/ui/layouts/sidebar.py similarity index 100% rename from selfdrive/ui/layouts/sidebar.py rename to openpilot/selfdrive/ui/layouts/sidebar.py diff --git a/selfdrive/ui/lib/api_helpers.py b/openpilot/selfdrive/ui/lib/api_helpers.py similarity index 100% rename from selfdrive/ui/lib/api_helpers.py rename to openpilot/selfdrive/ui/lib/api_helpers.py diff --git a/selfdrive/ui/lib/prime_state.py b/openpilot/selfdrive/ui/lib/prime_state.py similarity index 100% rename from selfdrive/ui/lib/prime_state.py rename to openpilot/selfdrive/ui/lib/prime_state.py diff --git a/selfdrive/ui/mici/layouts/__init__.py b/openpilot/selfdrive/ui/mici/layouts/__init__.py similarity index 100% rename from selfdrive/ui/mici/layouts/__init__.py rename to openpilot/selfdrive/ui/mici/layouts/__init__.py diff --git a/selfdrive/ui/mici/layouts/home.py b/openpilot/selfdrive/ui/mici/layouts/home.py similarity index 100% rename from selfdrive/ui/mici/layouts/home.py rename to openpilot/selfdrive/ui/mici/layouts/home.py diff --git a/selfdrive/ui/mici/layouts/main.py b/openpilot/selfdrive/ui/mici/layouts/main.py similarity index 100% rename from selfdrive/ui/mici/layouts/main.py rename to openpilot/selfdrive/ui/mici/layouts/main.py diff --git a/selfdrive/ui/mici/layouts/offroad_alerts.py b/openpilot/selfdrive/ui/mici/layouts/offroad_alerts.py similarity index 100% rename from selfdrive/ui/mici/layouts/offroad_alerts.py rename to openpilot/selfdrive/ui/mici/layouts/offroad_alerts.py diff --git a/selfdrive/ui/mici/layouts/onboarding.py b/openpilot/selfdrive/ui/mici/layouts/onboarding.py similarity index 100% rename from selfdrive/ui/mici/layouts/onboarding.py rename to openpilot/selfdrive/ui/mici/layouts/onboarding.py diff --git a/selfdrive/ui/mici/layouts/settings/developer.py b/openpilot/selfdrive/ui/mici/layouts/settings/developer.py similarity index 100% rename from selfdrive/ui/mici/layouts/settings/developer.py rename to openpilot/selfdrive/ui/mici/layouts/settings/developer.py diff --git a/selfdrive/ui/mici/layouts/settings/device.py b/openpilot/selfdrive/ui/mici/layouts/settings/device.py similarity index 100% rename from selfdrive/ui/mici/layouts/settings/device.py rename to openpilot/selfdrive/ui/mici/layouts/settings/device.py diff --git a/selfdrive/ui/mici/layouts/settings/firehose.py b/openpilot/selfdrive/ui/mici/layouts/settings/firehose.py similarity index 100% rename from selfdrive/ui/mici/layouts/settings/firehose.py rename to openpilot/selfdrive/ui/mici/layouts/settings/firehose.py diff --git a/selfdrive/ui/mici/layouts/settings/network/__init__.py b/openpilot/selfdrive/ui/mici/layouts/settings/network/__init__.py similarity index 100% rename from selfdrive/ui/mici/layouts/settings/network/__init__.py rename to openpilot/selfdrive/ui/mici/layouts/settings/network/__init__.py diff --git a/selfdrive/ui/mici/layouts/settings/network/network_layout.py b/openpilot/selfdrive/ui/mici/layouts/settings/network/network_layout.py similarity index 100% rename from selfdrive/ui/mici/layouts/settings/network/network_layout.py rename to openpilot/selfdrive/ui/mici/layouts/settings/network/network_layout.py diff --git a/selfdrive/ui/mici/layouts/settings/network/wifi_ui.py b/openpilot/selfdrive/ui/mici/layouts/settings/network/wifi_ui.py similarity index 100% rename from selfdrive/ui/mici/layouts/settings/network/wifi_ui.py rename to openpilot/selfdrive/ui/mici/layouts/settings/network/wifi_ui.py diff --git a/selfdrive/ui/mici/layouts/settings/settings.py b/openpilot/selfdrive/ui/mici/layouts/settings/settings.py similarity index 100% rename from selfdrive/ui/mici/layouts/settings/settings.py rename to openpilot/selfdrive/ui/mici/layouts/settings/settings.py diff --git a/selfdrive/ui/mici/layouts/settings/software.py b/openpilot/selfdrive/ui/mici/layouts/settings/software.py similarity index 100% rename from selfdrive/ui/mici/layouts/settings/software.py rename to openpilot/selfdrive/ui/mici/layouts/settings/software.py diff --git a/selfdrive/ui/mici/layouts/settings/toggles.py b/openpilot/selfdrive/ui/mici/layouts/settings/toggles.py similarity index 100% rename from selfdrive/ui/mici/layouts/settings/toggles.py rename to openpilot/selfdrive/ui/mici/layouts/settings/toggles.py diff --git a/selfdrive/ui/mici/onroad/__init__.py b/openpilot/selfdrive/ui/mici/onroad/__init__.py similarity index 100% rename from selfdrive/ui/mici/onroad/__init__.py rename to openpilot/selfdrive/ui/mici/onroad/__init__.py diff --git a/selfdrive/ui/mici/onroad/alert_renderer.py b/openpilot/selfdrive/ui/mici/onroad/alert_renderer.py similarity index 100% rename from selfdrive/ui/mici/onroad/alert_renderer.py rename to openpilot/selfdrive/ui/mici/onroad/alert_renderer.py diff --git a/selfdrive/ui/mici/onroad/augmented_road_view.py b/openpilot/selfdrive/ui/mici/onroad/augmented_road_view.py similarity index 100% rename from selfdrive/ui/mici/onroad/augmented_road_view.py rename to openpilot/selfdrive/ui/mici/onroad/augmented_road_view.py diff --git a/selfdrive/ui/mici/onroad/cameraview.py b/openpilot/selfdrive/ui/mici/onroad/cameraview.py similarity index 100% rename from selfdrive/ui/mici/onroad/cameraview.py rename to openpilot/selfdrive/ui/mici/onroad/cameraview.py diff --git a/selfdrive/ui/mici/onroad/confidence_ball.py b/openpilot/selfdrive/ui/mici/onroad/confidence_ball.py similarity index 100% rename from selfdrive/ui/mici/onroad/confidence_ball.py rename to openpilot/selfdrive/ui/mici/onroad/confidence_ball.py diff --git a/selfdrive/ui/mici/onroad/driver_camera_dialog.py b/openpilot/selfdrive/ui/mici/onroad/driver_camera_dialog.py similarity index 100% rename from selfdrive/ui/mici/onroad/driver_camera_dialog.py rename to openpilot/selfdrive/ui/mici/onroad/driver_camera_dialog.py diff --git a/selfdrive/ui/mici/onroad/driver_state.py b/openpilot/selfdrive/ui/mici/onroad/driver_state.py similarity index 100% rename from selfdrive/ui/mici/onroad/driver_state.py rename to openpilot/selfdrive/ui/mici/onroad/driver_state.py diff --git a/selfdrive/ui/mici/onroad/hud_renderer.py b/openpilot/selfdrive/ui/mici/onroad/hud_renderer.py similarity index 100% rename from selfdrive/ui/mici/onroad/hud_renderer.py rename to openpilot/selfdrive/ui/mici/onroad/hud_renderer.py diff --git a/selfdrive/ui/mici/onroad/model_renderer.py b/openpilot/selfdrive/ui/mici/onroad/model_renderer.py similarity index 100% rename from selfdrive/ui/mici/onroad/model_renderer.py rename to openpilot/selfdrive/ui/mici/onroad/model_renderer.py diff --git a/selfdrive/ui/mici/onroad/torque_bar.py b/openpilot/selfdrive/ui/mici/onroad/torque_bar.py similarity index 100% rename from selfdrive/ui/mici/onroad/torque_bar.py rename to openpilot/selfdrive/ui/mici/onroad/torque_bar.py diff --git a/selfdrive/ui/mici/tests/test_widget_leaks.py b/openpilot/selfdrive/ui/mici/tests/test_widget_leaks.py similarity index 100% rename from selfdrive/ui/mici/tests/test_widget_leaks.py rename to openpilot/selfdrive/ui/mici/tests/test_widget_leaks.py diff --git a/selfdrive/ui/mici/widgets/button.py b/openpilot/selfdrive/ui/mici/widgets/button.py similarity index 100% rename from selfdrive/ui/mici/widgets/button.py rename to openpilot/selfdrive/ui/mici/widgets/button.py diff --git a/selfdrive/ui/mici/widgets/dialog.py b/openpilot/selfdrive/ui/mici/widgets/dialog.py similarity index 100% rename from selfdrive/ui/mici/widgets/dialog.py rename to openpilot/selfdrive/ui/mici/widgets/dialog.py diff --git a/selfdrive/ui/mici/widgets/pairing_dialog.py b/openpilot/selfdrive/ui/mici/widgets/pairing_dialog.py similarity index 100% rename from selfdrive/ui/mici/widgets/pairing_dialog.py rename to openpilot/selfdrive/ui/mici/widgets/pairing_dialog.py diff --git a/selfdrive/ui/onroad/__init__.py b/openpilot/selfdrive/ui/onroad/__init__.py similarity index 100% rename from selfdrive/ui/onroad/__init__.py rename to openpilot/selfdrive/ui/onroad/__init__.py diff --git a/selfdrive/ui/onroad/alert_renderer.py b/openpilot/selfdrive/ui/onroad/alert_renderer.py similarity index 100% rename from selfdrive/ui/onroad/alert_renderer.py rename to openpilot/selfdrive/ui/onroad/alert_renderer.py diff --git a/selfdrive/ui/onroad/augmented_road_view.py b/openpilot/selfdrive/ui/onroad/augmented_road_view.py similarity index 100% rename from selfdrive/ui/onroad/augmented_road_view.py rename to openpilot/selfdrive/ui/onroad/augmented_road_view.py diff --git a/selfdrive/ui/onroad/cameraview.py b/openpilot/selfdrive/ui/onroad/cameraview.py similarity index 100% rename from selfdrive/ui/onroad/cameraview.py rename to openpilot/selfdrive/ui/onroad/cameraview.py diff --git a/selfdrive/ui/onroad/driver_camera_dialog.py b/openpilot/selfdrive/ui/onroad/driver_camera_dialog.py similarity index 100% rename from selfdrive/ui/onroad/driver_camera_dialog.py rename to openpilot/selfdrive/ui/onroad/driver_camera_dialog.py diff --git a/selfdrive/ui/onroad/driver_state.py b/openpilot/selfdrive/ui/onroad/driver_state.py similarity index 100% rename from selfdrive/ui/onroad/driver_state.py rename to openpilot/selfdrive/ui/onroad/driver_state.py diff --git a/selfdrive/ui/onroad/exp_button.py b/openpilot/selfdrive/ui/onroad/exp_button.py similarity index 100% rename from selfdrive/ui/onroad/exp_button.py rename to openpilot/selfdrive/ui/onroad/exp_button.py diff --git a/selfdrive/ui/onroad/hud_renderer.py b/openpilot/selfdrive/ui/onroad/hud_renderer.py similarity index 100% rename from selfdrive/ui/onroad/hud_renderer.py rename to openpilot/selfdrive/ui/onroad/hud_renderer.py diff --git a/selfdrive/ui/onroad/model_renderer.py b/openpilot/selfdrive/ui/onroad/model_renderer.py similarity index 100% rename from selfdrive/ui/onroad/model_renderer.py rename to openpilot/selfdrive/ui/onroad/model_renderer.py diff --git a/selfdrive/ui/soundd.py b/openpilot/selfdrive/ui/soundd.py similarity index 100% rename from selfdrive/ui/soundd.py rename to openpilot/selfdrive/ui/soundd.py diff --git a/selfdrive/ui/tests/__init__.py b/openpilot/selfdrive/ui/tests/__init__.py similarity index 100% rename from selfdrive/ui/tests/__init__.py rename to openpilot/selfdrive/ui/tests/__init__.py diff --git a/selfdrive/ui/tests/body.py b/openpilot/selfdrive/ui/tests/body.py similarity index 100% rename from selfdrive/ui/tests/body.py rename to openpilot/selfdrive/ui/tests/body.py diff --git a/selfdrive/ui/tests/cycle_offroad_alerts.py b/openpilot/selfdrive/ui/tests/cycle_offroad_alerts.py similarity index 100% rename from selfdrive/ui/tests/cycle_offroad_alerts.py rename to openpilot/selfdrive/ui/tests/cycle_offroad_alerts.py diff --git a/selfdrive/ui/tests/diff/diff.py b/openpilot/selfdrive/ui/tests/diff/diff.py similarity index 100% rename from selfdrive/ui/tests/diff/diff.py rename to openpilot/selfdrive/ui/tests/diff/diff.py diff --git a/selfdrive/ui/tests/diff/diff_template.html b/openpilot/selfdrive/ui/tests/diff/diff_template.html similarity index 100% rename from selfdrive/ui/tests/diff/diff_template.html rename to openpilot/selfdrive/ui/tests/diff/diff_template.html diff --git a/selfdrive/ui/tests/diff/replay.py b/openpilot/selfdrive/ui/tests/diff/replay.py similarity index 100% rename from selfdrive/ui/tests/diff/replay.py rename to openpilot/selfdrive/ui/tests/diff/replay.py diff --git a/selfdrive/ui/tests/diff/replay_script.py b/openpilot/selfdrive/ui/tests/diff/replay_script.py similarity index 100% rename from selfdrive/ui/tests/diff/replay_script.py rename to openpilot/selfdrive/ui/tests/diff/replay_script.py diff --git a/selfdrive/ui/tests/profile_onroad.py b/openpilot/selfdrive/ui/tests/profile_onroad.py similarity index 100% rename from selfdrive/ui/tests/profile_onroad.py rename to openpilot/selfdrive/ui/tests/profile_onroad.py diff --git a/selfdrive/ui/tests/test_feedbackd.py b/openpilot/selfdrive/ui/tests/test_feedbackd.py similarity index 100% rename from selfdrive/ui/tests/test_feedbackd.py rename to openpilot/selfdrive/ui/tests/test_feedbackd.py diff --git a/selfdrive/ui/tests/test_raylib_ui.py b/openpilot/selfdrive/ui/tests/test_raylib_ui.py similarity index 100% rename from selfdrive/ui/tests/test_raylib_ui.py rename to openpilot/selfdrive/ui/tests/test_raylib_ui.py diff --git a/selfdrive/ui/tests/test_soundd.py b/openpilot/selfdrive/ui/tests/test_soundd.py similarity index 100% rename from selfdrive/ui/tests/test_soundd.py rename to openpilot/selfdrive/ui/tests/test_soundd.py diff --git a/selfdrive/ui/tests/test_translations.py b/openpilot/selfdrive/ui/tests/test_translations.py similarity index 100% rename from selfdrive/ui/tests/test_translations.py rename to openpilot/selfdrive/ui/tests/test_translations.py diff --git a/selfdrive/ui/translations/app.pot b/openpilot/selfdrive/ui/translations/app.pot similarity index 100% rename from selfdrive/ui/translations/app.pot rename to openpilot/selfdrive/ui/translations/app.pot diff --git a/selfdrive/ui/translations/app_de.po b/openpilot/selfdrive/ui/translations/app_de.po similarity index 100% rename from selfdrive/ui/translations/app_de.po rename to openpilot/selfdrive/ui/translations/app_de.po diff --git a/selfdrive/ui/translations/app_en.po b/openpilot/selfdrive/ui/translations/app_en.po similarity index 100% rename from selfdrive/ui/translations/app_en.po rename to openpilot/selfdrive/ui/translations/app_en.po diff --git a/selfdrive/ui/translations/app_es.po b/openpilot/selfdrive/ui/translations/app_es.po similarity index 100% rename from selfdrive/ui/translations/app_es.po rename to openpilot/selfdrive/ui/translations/app_es.po diff --git a/selfdrive/ui/translations/app_fr.po b/openpilot/selfdrive/ui/translations/app_fr.po similarity index 100% rename from selfdrive/ui/translations/app_fr.po rename to openpilot/selfdrive/ui/translations/app_fr.po diff --git a/selfdrive/ui/translations/app_ja.po b/openpilot/selfdrive/ui/translations/app_ja.po similarity index 100% rename from selfdrive/ui/translations/app_ja.po rename to openpilot/selfdrive/ui/translations/app_ja.po diff --git a/selfdrive/ui/translations/app_ko.po b/openpilot/selfdrive/ui/translations/app_ko.po similarity index 100% rename from selfdrive/ui/translations/app_ko.po rename to openpilot/selfdrive/ui/translations/app_ko.po diff --git a/selfdrive/ui/translations/app_pt-BR.po b/openpilot/selfdrive/ui/translations/app_pt-BR.po similarity index 100% rename from selfdrive/ui/translations/app_pt-BR.po rename to openpilot/selfdrive/ui/translations/app_pt-BR.po diff --git a/selfdrive/ui/translations/app_th.po b/openpilot/selfdrive/ui/translations/app_th.po similarity index 100% rename from selfdrive/ui/translations/app_th.po rename to openpilot/selfdrive/ui/translations/app_th.po diff --git a/selfdrive/ui/translations/app_tr.po b/openpilot/selfdrive/ui/translations/app_tr.po similarity index 100% rename from selfdrive/ui/translations/app_tr.po rename to openpilot/selfdrive/ui/translations/app_tr.po diff --git a/selfdrive/ui/translations/app_uk.po b/openpilot/selfdrive/ui/translations/app_uk.po similarity index 100% rename from selfdrive/ui/translations/app_uk.po rename to openpilot/selfdrive/ui/translations/app_uk.po diff --git a/selfdrive/ui/translations/app_zh-CHS.po b/openpilot/selfdrive/ui/translations/app_zh-CHS.po similarity index 100% rename from selfdrive/ui/translations/app_zh-CHS.po rename to openpilot/selfdrive/ui/translations/app_zh-CHS.po diff --git a/selfdrive/ui/translations/app_zh-CHT.po b/openpilot/selfdrive/ui/translations/app_zh-CHT.po similarity index 100% rename from selfdrive/ui/translations/app_zh-CHT.po rename to openpilot/selfdrive/ui/translations/app_zh-CHT.po diff --git a/selfdrive/ui/translations/auto_translate.sh b/openpilot/selfdrive/ui/translations/auto_translate.sh similarity index 100% rename from selfdrive/ui/translations/auto_translate.sh rename to openpilot/selfdrive/ui/translations/auto_translate.sh diff --git a/selfdrive/ui/translations/languages.json b/openpilot/selfdrive/ui/translations/languages.json similarity index 100% rename from selfdrive/ui/translations/languages.json rename to openpilot/selfdrive/ui/translations/languages.json diff --git a/selfdrive/ui/translations/potools.py b/openpilot/selfdrive/ui/translations/potools.py similarity index 100% rename from selfdrive/ui/translations/potools.py rename to openpilot/selfdrive/ui/translations/potools.py diff --git a/selfdrive/ui/translations/update_translations.py b/openpilot/selfdrive/ui/translations/update_translations.py similarity index 100% rename from selfdrive/ui/translations/update_translations.py rename to openpilot/selfdrive/ui/translations/update_translations.py diff --git a/selfdrive/ui/ui.py b/openpilot/selfdrive/ui/ui.py similarity index 100% rename from selfdrive/ui/ui.py rename to openpilot/selfdrive/ui/ui.py diff --git a/selfdrive/ui/ui_state.py b/openpilot/selfdrive/ui/ui_state.py similarity index 100% rename from selfdrive/ui/ui_state.py rename to openpilot/selfdrive/ui/ui_state.py diff --git a/selfdrive/ui/watch3.py b/openpilot/selfdrive/ui/watch3.py similarity index 100% rename from selfdrive/ui/watch3.py rename to openpilot/selfdrive/ui/watch3.py diff --git a/selfdrive/ui/widgets/__init__.py b/openpilot/selfdrive/ui/widgets/__init__.py similarity index 100% rename from selfdrive/ui/widgets/__init__.py rename to openpilot/selfdrive/ui/widgets/__init__.py diff --git a/selfdrive/ui/widgets/exp_mode_button.py b/openpilot/selfdrive/ui/widgets/exp_mode_button.py similarity index 100% rename from selfdrive/ui/widgets/exp_mode_button.py rename to openpilot/selfdrive/ui/widgets/exp_mode_button.py diff --git a/selfdrive/ui/widgets/offroad_alerts.py b/openpilot/selfdrive/ui/widgets/offroad_alerts.py similarity index 100% rename from selfdrive/ui/widgets/offroad_alerts.py rename to openpilot/selfdrive/ui/widgets/offroad_alerts.py diff --git a/selfdrive/ui/widgets/pairing_dialog.py b/openpilot/selfdrive/ui/widgets/pairing_dialog.py similarity index 100% rename from selfdrive/ui/widgets/pairing_dialog.py rename to openpilot/selfdrive/ui/widgets/pairing_dialog.py diff --git a/selfdrive/ui/widgets/prime.py b/openpilot/selfdrive/ui/widgets/prime.py similarity index 100% rename from selfdrive/ui/widgets/prime.py rename to openpilot/selfdrive/ui/widgets/prime.py diff --git a/selfdrive/ui/widgets/setup.py b/openpilot/selfdrive/ui/widgets/setup.py similarity index 100% rename from selfdrive/ui/widgets/setup.py rename to openpilot/selfdrive/ui/widgets/setup.py diff --git a/selfdrive/ui/widgets/ssh_key.py b/openpilot/selfdrive/ui/widgets/ssh_key.py similarity index 100% rename from selfdrive/ui/widgets/ssh_key.py rename to openpilot/selfdrive/ui/widgets/ssh_key.py diff --git a/openpilot/system b/openpilot/system deleted file mode 120000 index 16f8cc2b23..0000000000 --- a/openpilot/system +++ /dev/null @@ -1 +0,0 @@ -../system/ \ No newline at end of file diff --git a/system/__init__.py b/openpilot/system/__init__.py similarity index 100% rename from system/__init__.py rename to openpilot/system/__init__.py diff --git a/system/athena/__init__.py b/openpilot/system/athena/__init__.py similarity index 100% rename from system/athena/__init__.py rename to openpilot/system/athena/__init__.py diff --git a/system/athena/athenad.py b/openpilot/system/athena/athenad.py similarity index 100% rename from system/athena/athenad.py rename to openpilot/system/athena/athenad.py diff --git a/system/athena/manage_athenad.py b/openpilot/system/athena/manage_athenad.py similarity index 100% rename from system/athena/manage_athenad.py rename to openpilot/system/athena/manage_athenad.py diff --git a/system/athena/registration.py b/openpilot/system/athena/registration.py similarity index 100% rename from system/athena/registration.py rename to openpilot/system/athena/registration.py diff --git a/system/athena/tests/__init__.py b/openpilot/system/athena/tests/__init__.py similarity index 100% rename from system/athena/tests/__init__.py rename to openpilot/system/athena/tests/__init__.py diff --git a/system/athena/tests/helpers.py b/openpilot/system/athena/tests/helpers.py similarity index 100% rename from system/athena/tests/helpers.py rename to openpilot/system/athena/tests/helpers.py diff --git a/system/athena/tests/test_athenad.py b/openpilot/system/athena/tests/test_athenad.py similarity index 100% rename from system/athena/tests/test_athenad.py rename to openpilot/system/athena/tests/test_athenad.py diff --git a/system/athena/tests/test_athenad_ping.py b/openpilot/system/athena/tests/test_athenad_ping.py similarity index 100% rename from system/athena/tests/test_athenad_ping.py rename to openpilot/system/athena/tests/test_athenad_ping.py diff --git a/system/athena/tests/test_registration.py b/openpilot/system/athena/tests/test_registration.py similarity index 100% rename from system/athena/tests/test_registration.py rename to openpilot/system/athena/tests/test_registration.py diff --git a/system/camerad/SConscript b/openpilot/system/camerad/SConscript similarity index 100% rename from system/camerad/SConscript rename to openpilot/system/camerad/SConscript diff --git a/system/camerad/__init__.py b/openpilot/system/camerad/__init__.py similarity index 100% rename from system/camerad/__init__.py rename to openpilot/system/camerad/__init__.py diff --git a/system/camerad/cameras/bps_blobs.h b/openpilot/system/camerad/cameras/bps_blobs.h similarity index 100% rename from system/camerad/cameras/bps_blobs.h rename to openpilot/system/camerad/cameras/bps_blobs.h diff --git a/system/camerad/cameras/camera_common.cc b/openpilot/system/camerad/cameras/camera_common.cc similarity index 100% rename from system/camerad/cameras/camera_common.cc rename to openpilot/system/camerad/cameras/camera_common.cc diff --git a/system/camerad/cameras/camera_common.h b/openpilot/system/camerad/cameras/camera_common.h similarity index 100% rename from system/camerad/cameras/camera_common.h rename to openpilot/system/camerad/cameras/camera_common.h diff --git a/system/camerad/cameras/camera_qcom2.cc b/openpilot/system/camerad/cameras/camera_qcom2.cc similarity index 100% rename from system/camerad/cameras/camera_qcom2.cc rename to openpilot/system/camerad/cameras/camera_qcom2.cc diff --git a/system/camerad/cameras/cdm.cc b/openpilot/system/camerad/cameras/cdm.cc similarity index 100% rename from system/camerad/cameras/cdm.cc rename to openpilot/system/camerad/cameras/cdm.cc diff --git a/system/camerad/cameras/cdm.h b/openpilot/system/camerad/cameras/cdm.h similarity index 100% rename from system/camerad/cameras/cdm.h rename to openpilot/system/camerad/cameras/cdm.h diff --git a/system/camerad/cameras/hw.h b/openpilot/system/camerad/cameras/hw.h similarity index 100% rename from system/camerad/cameras/hw.h rename to openpilot/system/camerad/cameras/hw.h diff --git a/system/camerad/cameras/ife.h b/openpilot/system/camerad/cameras/ife.h similarity index 100% rename from system/camerad/cameras/ife.h rename to openpilot/system/camerad/cameras/ife.h diff --git a/system/camerad/cameras/nv12_info.h b/openpilot/system/camerad/cameras/nv12_info.h similarity index 100% rename from system/camerad/cameras/nv12_info.h rename to openpilot/system/camerad/cameras/nv12_info.h diff --git a/system/camerad/cameras/nv12_info.py b/openpilot/system/camerad/cameras/nv12_info.py similarity index 100% rename from system/camerad/cameras/nv12_info.py rename to openpilot/system/camerad/cameras/nv12_info.py diff --git a/system/camerad/cameras/spectra.cc b/openpilot/system/camerad/cameras/spectra.cc similarity index 100% rename from system/camerad/cameras/spectra.cc rename to openpilot/system/camerad/cameras/spectra.cc diff --git a/system/camerad/cameras/spectra.h b/openpilot/system/camerad/cameras/spectra.h similarity index 100% rename from system/camerad/cameras/spectra.h rename to openpilot/system/camerad/cameras/spectra.h diff --git a/system/camerad/main.cc b/openpilot/system/camerad/main.cc similarity index 100% rename from system/camerad/main.cc rename to openpilot/system/camerad/main.cc diff --git a/system/camerad/sensors/os04c10.cc b/openpilot/system/camerad/sensors/os04c10.cc similarity index 100% rename from system/camerad/sensors/os04c10.cc rename to openpilot/system/camerad/sensors/os04c10.cc diff --git a/system/camerad/sensors/os04c10_registers.h b/openpilot/system/camerad/sensors/os04c10_registers.h similarity index 100% rename from system/camerad/sensors/os04c10_registers.h rename to openpilot/system/camerad/sensors/os04c10_registers.h diff --git a/system/camerad/sensors/ox03c10.cc b/openpilot/system/camerad/sensors/ox03c10.cc similarity index 100% rename from system/camerad/sensors/ox03c10.cc rename to openpilot/system/camerad/sensors/ox03c10.cc diff --git a/system/camerad/sensors/ox03c10_registers.h b/openpilot/system/camerad/sensors/ox03c10_registers.h similarity index 100% rename from system/camerad/sensors/ox03c10_registers.h rename to openpilot/system/camerad/sensors/ox03c10_registers.h diff --git a/system/camerad/sensors/sensor.h b/openpilot/system/camerad/sensors/sensor.h similarity index 100% rename from system/camerad/sensors/sensor.h rename to openpilot/system/camerad/sensors/sensor.h diff --git a/system/camerad/snapshot.py b/openpilot/system/camerad/snapshot.py similarity index 100% rename from system/camerad/snapshot.py rename to openpilot/system/camerad/snapshot.py diff --git a/system/camerad/test/.gitignore b/openpilot/system/camerad/test/.gitignore similarity index 100% rename from system/camerad/test/.gitignore rename to openpilot/system/camerad/test/.gitignore diff --git a/system/camerad/test/debug.sh b/openpilot/system/camerad/test/debug.sh similarity index 100% rename from system/camerad/test/debug.sh rename to openpilot/system/camerad/test/debug.sh diff --git a/system/camerad/test/icp_debug.sh b/openpilot/system/camerad/test/icp_debug.sh similarity index 100% rename from system/camerad/test/icp_debug.sh rename to openpilot/system/camerad/test/icp_debug.sh diff --git a/system/camerad/test/intercept.sh b/openpilot/system/camerad/test/intercept.sh similarity index 100% rename from system/camerad/test/intercept.sh rename to openpilot/system/camerad/test/intercept.sh diff --git a/system/camerad/test/stress_restart.sh b/openpilot/system/camerad/test/stress_restart.sh similarity index 100% rename from system/camerad/test/stress_restart.sh rename to openpilot/system/camerad/test/stress_restart.sh diff --git a/system/camerad/test/test_ae_gray.cc b/openpilot/system/camerad/test/test_ae_gray.cc similarity index 100% rename from system/camerad/test/test_ae_gray.cc rename to openpilot/system/camerad/test/test_ae_gray.cc diff --git a/system/camerad/test/test_camerad.py b/openpilot/system/camerad/test/test_camerad.py similarity index 100% rename from system/camerad/test/test_camerad.py rename to openpilot/system/camerad/test/test_camerad.py diff --git a/system/camerad/webcam/README.md b/openpilot/system/camerad/webcam/README.md similarity index 100% rename from system/camerad/webcam/README.md rename to openpilot/system/camerad/webcam/README.md diff --git a/system/camerad/webcam/camera.py b/openpilot/system/camerad/webcam/camera.py similarity index 100% rename from system/camerad/webcam/camera.py rename to openpilot/system/camerad/webcam/camera.py diff --git a/system/camerad/webcam/camerad.py b/openpilot/system/camerad/webcam/camerad.py similarity index 100% rename from system/camerad/webcam/camerad.py rename to openpilot/system/camerad/webcam/camerad.py diff --git a/system/hardware/fan_controller.py b/openpilot/system/hardware/fan_controller.py similarity index 100% rename from system/hardware/fan_controller.py rename to openpilot/system/hardware/fan_controller.py diff --git a/system/hardware/hardwared.py b/openpilot/system/hardware/hardwared.py similarity index 100% rename from system/hardware/hardwared.py rename to openpilot/system/hardware/hardwared.py diff --git a/system/hardware/power_monitoring.py b/openpilot/system/hardware/power_monitoring.py similarity index 100% rename from system/hardware/power_monitoring.py rename to openpilot/system/hardware/power_monitoring.py diff --git a/system/hardware/tests/__init__.py b/openpilot/system/hardware/tests/__init__.py similarity index 100% rename from system/hardware/tests/__init__.py rename to openpilot/system/hardware/tests/__init__.py diff --git a/system/hardware/tests/test_fan_controller.py b/openpilot/system/hardware/tests/test_fan_controller.py similarity index 100% rename from system/hardware/tests/test_fan_controller.py rename to openpilot/system/hardware/tests/test_fan_controller.py diff --git a/system/hardware/tests/test_power_monitoring.py b/openpilot/system/hardware/tests/test_power_monitoring.py similarity index 100% rename from system/hardware/tests/test_power_monitoring.py rename to openpilot/system/hardware/tests/test_power_monitoring.py diff --git a/system/hardware/tici/agnos.json b/openpilot/system/hardware/tici/agnos.json similarity index 100% rename from system/hardware/tici/agnos.json rename to openpilot/system/hardware/tici/agnos.json diff --git a/system/journald.py b/openpilot/system/journald.py similarity index 100% rename from system/journald.py rename to openpilot/system/journald.py diff --git a/system/loggerd/.gitignore b/openpilot/system/loggerd/.gitignore similarity index 100% rename from system/loggerd/.gitignore rename to openpilot/system/loggerd/.gitignore diff --git a/system/loggerd/SConscript b/openpilot/system/loggerd/SConscript similarity index 100% rename from system/loggerd/SConscript rename to openpilot/system/loggerd/SConscript diff --git a/system/loggerd/__init__.py b/openpilot/system/loggerd/__init__.py similarity index 100% rename from system/loggerd/__init__.py rename to openpilot/system/loggerd/__init__.py diff --git a/system/loggerd/bootlog.cc b/openpilot/system/loggerd/bootlog.cc similarity index 100% rename from system/loggerd/bootlog.cc rename to openpilot/system/loggerd/bootlog.cc diff --git a/system/loggerd/config.py b/openpilot/system/loggerd/config.py similarity index 100% rename from system/loggerd/config.py rename to openpilot/system/loggerd/config.py diff --git a/system/loggerd/deleter.py b/openpilot/system/loggerd/deleter.py similarity index 100% rename from system/loggerd/deleter.py rename to openpilot/system/loggerd/deleter.py diff --git a/system/loggerd/encoder/encoder.cc b/openpilot/system/loggerd/encoder/encoder.cc similarity index 100% rename from system/loggerd/encoder/encoder.cc rename to openpilot/system/loggerd/encoder/encoder.cc diff --git a/system/loggerd/encoder/encoder.h b/openpilot/system/loggerd/encoder/encoder.h similarity index 100% rename from system/loggerd/encoder/encoder.h rename to openpilot/system/loggerd/encoder/encoder.h diff --git a/system/loggerd/encoder/ffmpeg_encoder.cc b/openpilot/system/loggerd/encoder/ffmpeg_encoder.cc similarity index 100% rename from system/loggerd/encoder/ffmpeg_encoder.cc rename to openpilot/system/loggerd/encoder/ffmpeg_encoder.cc diff --git a/system/loggerd/encoder/ffmpeg_encoder.h b/openpilot/system/loggerd/encoder/ffmpeg_encoder.h similarity index 100% rename from system/loggerd/encoder/ffmpeg_encoder.h rename to openpilot/system/loggerd/encoder/ffmpeg_encoder.h diff --git a/system/loggerd/encoder/jpeg_encoder.cc b/openpilot/system/loggerd/encoder/jpeg_encoder.cc similarity index 100% rename from system/loggerd/encoder/jpeg_encoder.cc rename to openpilot/system/loggerd/encoder/jpeg_encoder.cc diff --git a/system/loggerd/encoder/jpeg_encoder.h b/openpilot/system/loggerd/encoder/jpeg_encoder.h similarity index 100% rename from system/loggerd/encoder/jpeg_encoder.h rename to openpilot/system/loggerd/encoder/jpeg_encoder.h diff --git a/system/loggerd/encoder/v4l_encoder.cc b/openpilot/system/loggerd/encoder/v4l_encoder.cc similarity index 100% rename from system/loggerd/encoder/v4l_encoder.cc rename to openpilot/system/loggerd/encoder/v4l_encoder.cc diff --git a/system/loggerd/encoder/v4l_encoder.h b/openpilot/system/loggerd/encoder/v4l_encoder.h similarity index 100% rename from system/loggerd/encoder/v4l_encoder.h rename to openpilot/system/loggerd/encoder/v4l_encoder.h diff --git a/system/loggerd/encoderd.cc b/openpilot/system/loggerd/encoderd.cc similarity index 100% rename from system/loggerd/encoderd.cc rename to openpilot/system/loggerd/encoderd.cc diff --git a/system/loggerd/logger.cc b/openpilot/system/loggerd/logger.cc similarity index 100% rename from system/loggerd/logger.cc rename to openpilot/system/loggerd/logger.cc diff --git a/system/loggerd/logger.h b/openpilot/system/loggerd/logger.h similarity index 100% rename from system/loggerd/logger.h rename to openpilot/system/loggerd/logger.h diff --git a/system/loggerd/loggerd.cc b/openpilot/system/loggerd/loggerd.cc similarity index 100% rename from system/loggerd/loggerd.cc rename to openpilot/system/loggerd/loggerd.cc diff --git a/system/loggerd/loggerd.h b/openpilot/system/loggerd/loggerd.h similarity index 100% rename from system/loggerd/loggerd.h rename to openpilot/system/loggerd/loggerd.h diff --git a/system/loggerd/tests/__init__.py b/openpilot/system/loggerd/tests/__init__.py similarity index 100% rename from system/loggerd/tests/__init__.py rename to openpilot/system/loggerd/tests/__init__.py diff --git a/system/loggerd/tests/loggerd_tests_common.py b/openpilot/system/loggerd/tests/loggerd_tests_common.py similarity index 100% rename from system/loggerd/tests/loggerd_tests_common.py rename to openpilot/system/loggerd/tests/loggerd_tests_common.py diff --git a/system/loggerd/tests/test_deleter.py b/openpilot/system/loggerd/tests/test_deleter.py similarity index 100% rename from system/loggerd/tests/test_deleter.py rename to openpilot/system/loggerd/tests/test_deleter.py diff --git a/system/loggerd/tests/test_encoder.py b/openpilot/system/loggerd/tests/test_encoder.py similarity index 100% rename from system/loggerd/tests/test_encoder.py rename to openpilot/system/loggerd/tests/test_encoder.py diff --git a/system/loggerd/tests/test_logger.cc b/openpilot/system/loggerd/tests/test_logger.cc similarity index 100% rename from system/loggerd/tests/test_logger.cc rename to openpilot/system/loggerd/tests/test_logger.cc diff --git a/system/loggerd/tests/test_loggerd.py b/openpilot/system/loggerd/tests/test_loggerd.py similarity index 100% rename from system/loggerd/tests/test_loggerd.py rename to openpilot/system/loggerd/tests/test_loggerd.py diff --git a/system/loggerd/tests/test_runner.cc b/openpilot/system/loggerd/tests/test_runner.cc similarity index 100% rename from system/loggerd/tests/test_runner.cc rename to openpilot/system/loggerd/tests/test_runner.cc diff --git a/system/loggerd/tests/test_uploader.py b/openpilot/system/loggerd/tests/test_uploader.py similarity index 100% rename from system/loggerd/tests/test_uploader.py rename to openpilot/system/loggerd/tests/test_uploader.py diff --git a/system/loggerd/tests/test_zstd_writer.cc b/openpilot/system/loggerd/tests/test_zstd_writer.cc similarity index 100% rename from system/loggerd/tests/test_zstd_writer.cc rename to openpilot/system/loggerd/tests/test_zstd_writer.cc diff --git a/system/loggerd/tests/vidc_debug.sh b/openpilot/system/loggerd/tests/vidc_debug.sh similarity index 100% rename from system/loggerd/tests/vidc_debug.sh rename to openpilot/system/loggerd/tests/vidc_debug.sh diff --git a/system/loggerd/uploader.py b/openpilot/system/loggerd/uploader.py similarity index 100% rename from system/loggerd/uploader.py rename to openpilot/system/loggerd/uploader.py diff --git a/system/loggerd/video_writer.cc b/openpilot/system/loggerd/video_writer.cc similarity index 100% rename from system/loggerd/video_writer.cc rename to openpilot/system/loggerd/video_writer.cc diff --git a/system/loggerd/video_writer.h b/openpilot/system/loggerd/video_writer.h similarity index 100% rename from system/loggerd/video_writer.h rename to openpilot/system/loggerd/video_writer.h diff --git a/system/loggerd/xattr_cache.py b/openpilot/system/loggerd/xattr_cache.py similarity index 100% rename from system/loggerd/xattr_cache.py rename to openpilot/system/loggerd/xattr_cache.py diff --git a/system/loggerd/zstd_writer.cc b/openpilot/system/loggerd/zstd_writer.cc similarity index 100% rename from system/loggerd/zstd_writer.cc rename to openpilot/system/loggerd/zstd_writer.cc diff --git a/system/loggerd/zstd_writer.h b/openpilot/system/loggerd/zstd_writer.h similarity index 100% rename from system/loggerd/zstd_writer.h rename to openpilot/system/loggerd/zstd_writer.h diff --git a/system/logmessaged.py b/openpilot/system/logmessaged.py similarity index 100% rename from system/logmessaged.py rename to openpilot/system/logmessaged.py diff --git a/system/manager/__init__.py b/openpilot/system/manager/__init__.py similarity index 100% rename from system/manager/__init__.py rename to openpilot/system/manager/__init__.py diff --git a/system/manager/build.py b/openpilot/system/manager/build.py similarity index 100% rename from system/manager/build.py rename to openpilot/system/manager/build.py diff --git a/system/manager/helpers.py b/openpilot/system/manager/helpers.py similarity index 100% rename from system/manager/helpers.py rename to openpilot/system/manager/helpers.py diff --git a/system/manager/manager.py b/openpilot/system/manager/manager.py similarity index 100% rename from system/manager/manager.py rename to openpilot/system/manager/manager.py diff --git a/system/manager/process.py b/openpilot/system/manager/process.py similarity index 100% rename from system/manager/process.py rename to openpilot/system/manager/process.py diff --git a/system/manager/process_config.py b/openpilot/system/manager/process_config.py similarity index 100% rename from system/manager/process_config.py rename to openpilot/system/manager/process_config.py diff --git a/system/manager/test/__init__.py b/openpilot/system/manager/test/__init__.py similarity index 100% rename from system/manager/test/__init__.py rename to openpilot/system/manager/test/__init__.py diff --git a/system/manager/test/test_manager.py b/openpilot/system/manager/test/test_manager.py similarity index 100% rename from system/manager/test/test_manager.py rename to openpilot/system/manager/test/test_manager.py diff --git a/system/micd.py b/openpilot/system/micd.py similarity index 100% rename from system/micd.py rename to openpilot/system/micd.py diff --git a/system/proclogd.py b/openpilot/system/proclogd.py similarity index 100% rename from system/proclogd.py rename to openpilot/system/proclogd.py diff --git a/system/qcomgpsd/modemdiag.py b/openpilot/system/qcomgpsd/modemdiag.py similarity index 100% rename from system/qcomgpsd/modemdiag.py rename to openpilot/system/qcomgpsd/modemdiag.py diff --git a/system/qcomgpsd/nmeaport.py b/openpilot/system/qcomgpsd/nmeaport.py similarity index 100% rename from system/qcomgpsd/nmeaport.py rename to openpilot/system/qcomgpsd/nmeaport.py diff --git a/system/qcomgpsd/qcomgpsd.py b/openpilot/system/qcomgpsd/qcomgpsd.py similarity index 100% rename from system/qcomgpsd/qcomgpsd.py rename to openpilot/system/qcomgpsd/qcomgpsd.py diff --git a/system/qcomgpsd/structs.py b/openpilot/system/qcomgpsd/structs.py similarity index 100% rename from system/qcomgpsd/structs.py rename to openpilot/system/qcomgpsd/structs.py diff --git a/system/sensord/__init__.py b/openpilot/system/sensord/__init__.py similarity index 100% rename from system/sensord/__init__.py rename to openpilot/system/sensord/__init__.py diff --git a/system/sensord/sensord.py b/openpilot/system/sensord/sensord.py similarity index 100% rename from system/sensord/sensord.py rename to openpilot/system/sensord/sensord.py diff --git a/system/sensord/sensors/__init__.py b/openpilot/system/sensord/sensors/__init__.py similarity index 100% rename from system/sensord/sensors/__init__.py rename to openpilot/system/sensord/sensors/__init__.py diff --git a/system/sensord/sensors/i2c_sensor.py b/openpilot/system/sensord/sensors/i2c_sensor.py similarity index 100% rename from system/sensord/sensors/i2c_sensor.py rename to openpilot/system/sensord/sensors/i2c_sensor.py diff --git a/system/sensord/sensors/lsm6ds3_accel.py b/openpilot/system/sensord/sensors/lsm6ds3_accel.py similarity index 100% rename from system/sensord/sensors/lsm6ds3_accel.py rename to openpilot/system/sensord/sensors/lsm6ds3_accel.py diff --git a/system/sensord/sensors/lsm6ds3_gyro.py b/openpilot/system/sensord/sensors/lsm6ds3_gyro.py similarity index 100% rename from system/sensord/sensors/lsm6ds3_gyro.py rename to openpilot/system/sensord/sensors/lsm6ds3_gyro.py diff --git a/system/sensord/sensors/lsm6ds3_temp.py b/openpilot/system/sensord/sensors/lsm6ds3_temp.py similarity index 100% rename from system/sensord/sensors/lsm6ds3_temp.py rename to openpilot/system/sensord/sensors/lsm6ds3_temp.py diff --git a/system/sensord/tests/__init__.py b/openpilot/system/sensord/tests/__init__.py similarity index 100% rename from system/sensord/tests/__init__.py rename to openpilot/system/sensord/tests/__init__.py diff --git a/system/sensord/tests/test_sensord.py b/openpilot/system/sensord/tests/test_sensord.py similarity index 100% rename from system/sensord/tests/test_sensord.py rename to openpilot/system/sensord/tests/test_sensord.py diff --git a/system/sentry.py b/openpilot/system/sentry.py similarity index 100% rename from system/sentry.py rename to openpilot/system/sentry.py diff --git a/system/tests/__init__.py b/openpilot/system/tests/__init__.py similarity index 100% rename from system/tests/__init__.py rename to openpilot/system/tests/__init__.py diff --git a/system/tests/test_logmessaged.py b/openpilot/system/tests/test_logmessaged.py similarity index 100% rename from system/tests/test_logmessaged.py rename to openpilot/system/tests/test_logmessaged.py diff --git a/system/timed.py b/openpilot/system/timed.py similarity index 100% rename from system/timed.py rename to openpilot/system/timed.py diff --git a/system/tombstoned.py b/openpilot/system/tombstoned.py similarity index 100% rename from system/tombstoned.py rename to openpilot/system/tombstoned.py diff --git a/system/ubloxd/binary_struct.py b/openpilot/system/ubloxd/binary_struct.py similarity index 100% rename from system/ubloxd/binary_struct.py rename to openpilot/system/ubloxd/binary_struct.py diff --git a/system/ubloxd/glonass.py b/openpilot/system/ubloxd/glonass.py similarity index 100% rename from system/ubloxd/glonass.py rename to openpilot/system/ubloxd/glonass.py diff --git a/system/ubloxd/gps.py b/openpilot/system/ubloxd/gps.py similarity index 100% rename from system/ubloxd/gps.py rename to openpilot/system/ubloxd/gps.py diff --git a/system/ubloxd/pigeond.py b/openpilot/system/ubloxd/pigeond.py similarity index 100% rename from system/ubloxd/pigeond.py rename to openpilot/system/ubloxd/pigeond.py diff --git a/system/ubloxd/tests/test_pigeond.py b/openpilot/system/ubloxd/tests/test_pigeond.py similarity index 100% rename from system/ubloxd/tests/test_pigeond.py rename to openpilot/system/ubloxd/tests/test_pigeond.py diff --git a/system/ubloxd/ubloxd.py b/openpilot/system/ubloxd/ubloxd.py similarity index 100% rename from system/ubloxd/ubloxd.py rename to openpilot/system/ubloxd/ubloxd.py diff --git a/system/ubloxd/ubx.py b/openpilot/system/ubloxd/ubx.py similarity index 100% rename from system/ubloxd/ubx.py rename to openpilot/system/ubloxd/ubx.py diff --git a/system/ui/README.md b/openpilot/system/ui/README.md similarity index 100% rename from system/ui/README.md rename to openpilot/system/ui/README.md diff --git a/system/ui/lib/__init__.py b/openpilot/system/ui/lib/__init__.py similarity index 100% rename from system/ui/lib/__init__.py rename to openpilot/system/ui/lib/__init__.py diff --git a/system/ui/lib/application.py b/openpilot/system/ui/lib/application.py similarity index 100% rename from system/ui/lib/application.py rename to openpilot/system/ui/lib/application.py diff --git a/system/ui/lib/egl.py b/openpilot/system/ui/lib/egl.py similarity index 100% rename from system/ui/lib/egl.py rename to openpilot/system/ui/lib/egl.py diff --git a/system/ui/lib/emoji.py b/openpilot/system/ui/lib/emoji.py similarity index 100% rename from system/ui/lib/emoji.py rename to openpilot/system/ui/lib/emoji.py diff --git a/system/ui/lib/multilang.py b/openpilot/system/ui/lib/multilang.py similarity index 100% rename from system/ui/lib/multilang.py rename to openpilot/system/ui/lib/multilang.py diff --git a/system/ui/lib/networkmanager.py b/openpilot/system/ui/lib/networkmanager.py similarity index 100% rename from system/ui/lib/networkmanager.py rename to openpilot/system/ui/lib/networkmanager.py diff --git a/system/ui/lib/scroll_panel.py b/openpilot/system/ui/lib/scroll_panel.py similarity index 100% rename from system/ui/lib/scroll_panel.py rename to openpilot/system/ui/lib/scroll_panel.py diff --git a/system/ui/lib/scroll_panel2.py b/openpilot/system/ui/lib/scroll_panel2.py similarity index 100% rename from system/ui/lib/scroll_panel2.py rename to openpilot/system/ui/lib/scroll_panel2.py diff --git a/system/ui/lib/shader_polygon.py b/openpilot/system/ui/lib/shader_polygon.py similarity index 100% rename from system/ui/lib/shader_polygon.py rename to openpilot/system/ui/lib/shader_polygon.py diff --git a/system/ui/lib/tests/test_handle_state_change.py b/openpilot/system/ui/lib/tests/test_handle_state_change.py similarity index 100% rename from system/ui/lib/tests/test_handle_state_change.py rename to openpilot/system/ui/lib/tests/test_handle_state_change.py diff --git a/system/ui/lib/text_measure.py b/openpilot/system/ui/lib/text_measure.py similarity index 100% rename from system/ui/lib/text_measure.py rename to openpilot/system/ui/lib/text_measure.py diff --git a/system/ui/lib/utils.py b/openpilot/system/ui/lib/utils.py similarity index 100% rename from system/ui/lib/utils.py rename to openpilot/system/ui/lib/utils.py diff --git a/system/ui/lib/wifi_manager.py b/openpilot/system/ui/lib/wifi_manager.py similarity index 100% rename from system/ui/lib/wifi_manager.py rename to openpilot/system/ui/lib/wifi_manager.py diff --git a/system/ui/lib/wrap_text.py b/openpilot/system/ui/lib/wrap_text.py similarity index 100% rename from system/ui/lib/wrap_text.py rename to openpilot/system/ui/lib/wrap_text.py diff --git a/system/ui/mici_reset.py b/openpilot/system/ui/mici_reset.py similarity index 100% rename from system/ui/mici_reset.py rename to openpilot/system/ui/mici_reset.py diff --git a/system/ui/mici_setup.py b/openpilot/system/ui/mici_setup.py similarity index 100% rename from system/ui/mici_setup.py rename to openpilot/system/ui/mici_setup.py diff --git a/system/ui/mici_updater.py b/openpilot/system/ui/mici_updater.py similarity index 100% rename from system/ui/mici_updater.py rename to openpilot/system/ui/mici_updater.py diff --git a/system/ui/reset.py b/openpilot/system/ui/reset.py similarity index 100% rename from system/ui/reset.py rename to openpilot/system/ui/reset.py diff --git a/system/ui/setup.py b/openpilot/system/ui/setup.py similarity index 100% rename from system/ui/setup.py rename to openpilot/system/ui/setup.py diff --git a/system/ui/spinner.py b/openpilot/system/ui/spinner.py similarity index 100% rename from system/ui/spinner.py rename to openpilot/system/ui/spinner.py diff --git a/system/ui/text.py b/openpilot/system/ui/text.py similarity index 100% rename from system/ui/text.py rename to openpilot/system/ui/text.py diff --git a/system/ui/tici_reset.py b/openpilot/system/ui/tici_reset.py similarity index 100% rename from system/ui/tici_reset.py rename to openpilot/system/ui/tici_reset.py diff --git a/system/ui/tici_setup.py b/openpilot/system/ui/tici_setup.py similarity index 100% rename from system/ui/tici_setup.py rename to openpilot/system/ui/tici_setup.py diff --git a/system/ui/tici_updater.py b/openpilot/system/ui/tici_updater.py similarity index 100% rename from system/ui/tici_updater.py rename to openpilot/system/ui/tici_updater.py diff --git a/system/ui/updater.py b/openpilot/system/ui/updater.py similarity index 100% rename from system/ui/updater.py rename to openpilot/system/ui/updater.py diff --git a/system/ui/widgets/__init__.py b/openpilot/system/ui/widgets/__init__.py similarity index 100% rename from system/ui/widgets/__init__.py rename to openpilot/system/ui/widgets/__init__.py diff --git a/system/ui/widgets/button.py b/openpilot/system/ui/widgets/button.py similarity index 100% rename from system/ui/widgets/button.py rename to openpilot/system/ui/widgets/button.py diff --git a/system/ui/widgets/confirm_dialog.py b/openpilot/system/ui/widgets/confirm_dialog.py similarity index 100% rename from system/ui/widgets/confirm_dialog.py rename to openpilot/system/ui/widgets/confirm_dialog.py diff --git a/system/ui/widgets/html_render.py b/openpilot/system/ui/widgets/html_render.py similarity index 100% rename from system/ui/widgets/html_render.py rename to openpilot/system/ui/widgets/html_render.py diff --git a/system/ui/widgets/icon_widget.py b/openpilot/system/ui/widgets/icon_widget.py similarity index 100% rename from system/ui/widgets/icon_widget.py rename to openpilot/system/ui/widgets/icon_widget.py diff --git a/system/ui/widgets/inputbox.py b/openpilot/system/ui/widgets/inputbox.py similarity index 100% rename from system/ui/widgets/inputbox.py rename to openpilot/system/ui/widgets/inputbox.py diff --git a/system/ui/widgets/keyboard.py b/openpilot/system/ui/widgets/keyboard.py similarity index 100% rename from system/ui/widgets/keyboard.py rename to openpilot/system/ui/widgets/keyboard.py diff --git a/system/ui/widgets/label.py b/openpilot/system/ui/widgets/label.py similarity index 100% rename from system/ui/widgets/label.py rename to openpilot/system/ui/widgets/label.py diff --git a/system/ui/widgets/layouts.py b/openpilot/system/ui/widgets/layouts.py similarity index 100% rename from system/ui/widgets/layouts.py rename to openpilot/system/ui/widgets/layouts.py diff --git a/system/ui/widgets/list_view.py b/openpilot/system/ui/widgets/list_view.py similarity index 100% rename from system/ui/widgets/list_view.py rename to openpilot/system/ui/widgets/list_view.py diff --git a/system/ui/widgets/mici_keyboard.py b/openpilot/system/ui/widgets/mici_keyboard.py similarity index 100% rename from system/ui/widgets/mici_keyboard.py rename to openpilot/system/ui/widgets/mici_keyboard.py diff --git a/system/ui/widgets/nav_widget.py b/openpilot/system/ui/widgets/nav_widget.py similarity index 100% rename from system/ui/widgets/nav_widget.py rename to openpilot/system/ui/widgets/nav_widget.py diff --git a/system/ui/widgets/network.py b/openpilot/system/ui/widgets/network.py similarity index 100% rename from system/ui/widgets/network.py rename to openpilot/system/ui/widgets/network.py diff --git a/system/ui/widgets/option_dialog.py b/openpilot/system/ui/widgets/option_dialog.py similarity index 100% rename from system/ui/widgets/option_dialog.py rename to openpilot/system/ui/widgets/option_dialog.py diff --git a/system/ui/widgets/scroller.py b/openpilot/system/ui/widgets/scroller.py similarity index 100% rename from system/ui/widgets/scroller.py rename to openpilot/system/ui/widgets/scroller.py diff --git a/system/ui/widgets/scroller_tici.py b/openpilot/system/ui/widgets/scroller_tici.py similarity index 100% rename from system/ui/widgets/scroller_tici.py rename to openpilot/system/ui/widgets/scroller_tici.py diff --git a/system/ui/widgets/slider.py b/openpilot/system/ui/widgets/slider.py similarity index 100% rename from system/ui/widgets/slider.py rename to openpilot/system/ui/widgets/slider.py diff --git a/system/ui/widgets/toggle.py b/openpilot/system/ui/widgets/toggle.py similarity index 100% rename from system/ui/widgets/toggle.py rename to openpilot/system/ui/widgets/toggle.py diff --git a/system/updated/common.py b/openpilot/system/updated/common.py similarity index 100% rename from system/updated/common.py rename to openpilot/system/updated/common.py diff --git a/system/updated/updated.py b/openpilot/system/updated/updated.py similarity index 100% rename from system/updated/updated.py rename to openpilot/system/updated/updated.py diff --git a/system/webrtc/__init__.py b/openpilot/system/webrtc/__init__.py similarity index 100% rename from system/webrtc/__init__.py rename to openpilot/system/webrtc/__init__.py diff --git a/system/webrtc/device/video.py b/openpilot/system/webrtc/device/video.py similarity index 100% rename from system/webrtc/device/video.py rename to openpilot/system/webrtc/device/video.py diff --git a/system/webrtc/helpers.py b/openpilot/system/webrtc/helpers.py similarity index 100% rename from system/webrtc/helpers.py rename to openpilot/system/webrtc/helpers.py diff --git a/system/webrtc/schema.py b/openpilot/system/webrtc/schema.py similarity index 100% rename from system/webrtc/schema.py rename to openpilot/system/webrtc/schema.py diff --git a/system/webrtc/tests/test_stream_session.py b/openpilot/system/webrtc/tests/test_stream_session.py similarity index 100% rename from system/webrtc/tests/test_stream_session.py rename to openpilot/system/webrtc/tests/test_stream_session.py diff --git a/system/webrtc/webrtcd.py b/openpilot/system/webrtc/webrtcd.py similarity index 100% rename from system/webrtc/webrtcd.py rename to openpilot/system/webrtc/webrtcd.py diff --git a/openpilot/tools b/openpilot/tools deleted file mode 120000 index 4887d6e0c9..0000000000 --- a/openpilot/tools +++ /dev/null @@ -1 +0,0 @@ -../tools \ No newline at end of file diff --git a/tools/CTF.md b/openpilot/tools/CTF.md similarity index 100% rename from tools/CTF.md rename to openpilot/tools/CTF.md diff --git a/tools/README.md b/openpilot/tools/README.md similarity index 100% rename from tools/README.md rename to openpilot/tools/README.md diff --git a/tools/__init__.py b/openpilot/tools/__init__.py similarity index 100% rename from tools/__init__.py rename to openpilot/tools/__init__.py diff --git a/tools/auto_source.py b/openpilot/tools/auto_source.py similarity index 100% rename from tools/auto_source.py rename to openpilot/tools/auto_source.py diff --git a/tools/cabana/.gitignore b/openpilot/tools/cabana/.gitignore similarity index 100% rename from tools/cabana/.gitignore rename to openpilot/tools/cabana/.gitignore diff --git a/tools/cabana/README.md b/openpilot/tools/cabana/README.md similarity index 100% rename from tools/cabana/README.md rename to openpilot/tools/cabana/README.md diff --git a/tools/cabana/SConscript b/openpilot/tools/cabana/SConscript similarity index 100% rename from tools/cabana/SConscript rename to openpilot/tools/cabana/SConscript diff --git a/tools/cabana/assets/assets.qrc b/openpilot/tools/cabana/assets/assets.qrc similarity index 100% rename from tools/cabana/assets/assets.qrc rename to openpilot/tools/cabana/assets/assets.qrc diff --git a/tools/cabana/assets/cabana-icon.png b/openpilot/tools/cabana/assets/cabana-icon.png similarity index 100% rename from tools/cabana/assets/cabana-icon.png rename to openpilot/tools/cabana/assets/cabana-icon.png diff --git a/tools/cabana/binaryview.cc b/openpilot/tools/cabana/binaryview.cc similarity index 100% rename from tools/cabana/binaryview.cc rename to openpilot/tools/cabana/binaryview.cc diff --git a/tools/cabana/binaryview.h b/openpilot/tools/cabana/binaryview.h similarity index 100% rename from tools/cabana/binaryview.h rename to openpilot/tools/cabana/binaryview.h diff --git a/tools/cabana/cabana b/openpilot/tools/cabana/cabana similarity index 100% rename from tools/cabana/cabana rename to openpilot/tools/cabana/cabana diff --git a/tools/cabana/cabana.cc b/openpilot/tools/cabana/cabana.cc similarity index 100% rename from tools/cabana/cabana.cc rename to openpilot/tools/cabana/cabana.cc diff --git a/tools/cabana/cameraview.cc b/openpilot/tools/cabana/cameraview.cc similarity index 100% rename from tools/cabana/cameraview.cc rename to openpilot/tools/cabana/cameraview.cc diff --git a/tools/cabana/cameraview.h b/openpilot/tools/cabana/cameraview.h similarity index 100% rename from tools/cabana/cameraview.h rename to openpilot/tools/cabana/cameraview.h diff --git a/tools/cabana/chart/chart.cc b/openpilot/tools/cabana/chart/chart.cc similarity index 100% rename from tools/cabana/chart/chart.cc rename to openpilot/tools/cabana/chart/chart.cc diff --git a/tools/cabana/chart/chart.h b/openpilot/tools/cabana/chart/chart.h similarity index 100% rename from tools/cabana/chart/chart.h rename to openpilot/tools/cabana/chart/chart.h diff --git a/tools/cabana/chart/chartswidget.cc b/openpilot/tools/cabana/chart/chartswidget.cc similarity index 100% rename from tools/cabana/chart/chartswidget.cc rename to openpilot/tools/cabana/chart/chartswidget.cc diff --git a/tools/cabana/chart/chartswidget.h b/openpilot/tools/cabana/chart/chartswidget.h similarity index 100% rename from tools/cabana/chart/chartswidget.h rename to openpilot/tools/cabana/chart/chartswidget.h diff --git a/tools/cabana/chart/signalselector.cc b/openpilot/tools/cabana/chart/signalselector.cc similarity index 100% rename from tools/cabana/chart/signalselector.cc rename to openpilot/tools/cabana/chart/signalselector.cc diff --git a/tools/cabana/chart/signalselector.h b/openpilot/tools/cabana/chart/signalselector.h similarity index 100% rename from tools/cabana/chart/signalselector.h rename to openpilot/tools/cabana/chart/signalselector.h diff --git a/tools/cabana/chart/sparkline.cc b/openpilot/tools/cabana/chart/sparkline.cc similarity index 100% rename from tools/cabana/chart/sparkline.cc rename to openpilot/tools/cabana/chart/sparkline.cc diff --git a/tools/cabana/chart/sparkline.h b/openpilot/tools/cabana/chart/sparkline.h similarity index 100% rename from tools/cabana/chart/sparkline.h rename to openpilot/tools/cabana/chart/sparkline.h diff --git a/tools/cabana/chart/tiplabel.cc b/openpilot/tools/cabana/chart/tiplabel.cc similarity index 100% rename from tools/cabana/chart/tiplabel.cc rename to openpilot/tools/cabana/chart/tiplabel.cc diff --git a/tools/cabana/chart/tiplabel.h b/openpilot/tools/cabana/chart/tiplabel.h similarity index 100% rename from tools/cabana/chart/tiplabel.h rename to openpilot/tools/cabana/chart/tiplabel.h diff --git a/tools/cabana/commands.cc b/openpilot/tools/cabana/commands.cc similarity index 100% rename from tools/cabana/commands.cc rename to openpilot/tools/cabana/commands.cc diff --git a/tools/cabana/commands.h b/openpilot/tools/cabana/commands.h similarity index 100% rename from tools/cabana/commands.h rename to openpilot/tools/cabana/commands.h diff --git a/tools/cabana/dbc/dbc.cc b/openpilot/tools/cabana/dbc/dbc.cc similarity index 100% rename from tools/cabana/dbc/dbc.cc rename to openpilot/tools/cabana/dbc/dbc.cc diff --git a/tools/cabana/dbc/dbc.h b/openpilot/tools/cabana/dbc/dbc.h similarity index 100% rename from tools/cabana/dbc/dbc.h rename to openpilot/tools/cabana/dbc/dbc.h diff --git a/tools/cabana/dbc/dbcfile.cc b/openpilot/tools/cabana/dbc/dbcfile.cc similarity index 100% rename from tools/cabana/dbc/dbcfile.cc rename to openpilot/tools/cabana/dbc/dbcfile.cc diff --git a/tools/cabana/dbc/dbcfile.h b/openpilot/tools/cabana/dbc/dbcfile.h similarity index 100% rename from tools/cabana/dbc/dbcfile.h rename to openpilot/tools/cabana/dbc/dbcfile.h diff --git a/tools/cabana/dbc/dbcmanager.cc b/openpilot/tools/cabana/dbc/dbcmanager.cc similarity index 100% rename from tools/cabana/dbc/dbcmanager.cc rename to openpilot/tools/cabana/dbc/dbcmanager.cc diff --git a/tools/cabana/dbc/dbcmanager.h b/openpilot/tools/cabana/dbc/dbcmanager.h similarity index 100% rename from tools/cabana/dbc/dbcmanager.h rename to openpilot/tools/cabana/dbc/dbcmanager.h diff --git a/tools/cabana/dbc/generate_dbc_json.py b/openpilot/tools/cabana/dbc/generate_dbc_json.py similarity index 100% rename from tools/cabana/dbc/generate_dbc_json.py rename to openpilot/tools/cabana/dbc/generate_dbc_json.py diff --git a/tools/cabana/detailwidget.cc b/openpilot/tools/cabana/detailwidget.cc similarity index 100% rename from tools/cabana/detailwidget.cc rename to openpilot/tools/cabana/detailwidget.cc diff --git a/tools/cabana/detailwidget.h b/openpilot/tools/cabana/detailwidget.h similarity index 100% rename from tools/cabana/detailwidget.h rename to openpilot/tools/cabana/detailwidget.h diff --git a/tools/cabana/historylog.cc b/openpilot/tools/cabana/historylog.cc similarity index 100% rename from tools/cabana/historylog.cc rename to openpilot/tools/cabana/historylog.cc diff --git a/tools/cabana/historylog.h b/openpilot/tools/cabana/historylog.h similarity index 100% rename from tools/cabana/historylog.h rename to openpilot/tools/cabana/historylog.h diff --git a/tools/cabana/mainwin.cc b/openpilot/tools/cabana/mainwin.cc similarity index 100% rename from tools/cabana/mainwin.cc rename to openpilot/tools/cabana/mainwin.cc diff --git a/tools/cabana/mainwin.h b/openpilot/tools/cabana/mainwin.h similarity index 100% rename from tools/cabana/mainwin.h rename to openpilot/tools/cabana/mainwin.h diff --git a/tools/cabana/messageswidget.cc b/openpilot/tools/cabana/messageswidget.cc similarity index 100% rename from tools/cabana/messageswidget.cc rename to openpilot/tools/cabana/messageswidget.cc diff --git a/tools/cabana/messageswidget.h b/openpilot/tools/cabana/messageswidget.h similarity index 100% rename from tools/cabana/messageswidget.h rename to openpilot/tools/cabana/messageswidget.h diff --git a/tools/cabana/panda.cc b/openpilot/tools/cabana/panda.cc similarity index 100% rename from tools/cabana/panda.cc rename to openpilot/tools/cabana/panda.cc diff --git a/tools/cabana/panda.h b/openpilot/tools/cabana/panda.h similarity index 100% rename from tools/cabana/panda.h rename to openpilot/tools/cabana/panda.h diff --git a/tools/cabana/settings.cc b/openpilot/tools/cabana/settings.cc similarity index 100% rename from tools/cabana/settings.cc rename to openpilot/tools/cabana/settings.cc diff --git a/tools/cabana/settings.h b/openpilot/tools/cabana/settings.h similarity index 100% rename from tools/cabana/settings.h rename to openpilot/tools/cabana/settings.h diff --git a/tools/cabana/signalview.cc b/openpilot/tools/cabana/signalview.cc similarity index 100% rename from tools/cabana/signalview.cc rename to openpilot/tools/cabana/signalview.cc diff --git a/tools/cabana/signalview.h b/openpilot/tools/cabana/signalview.h similarity index 100% rename from tools/cabana/signalview.h rename to openpilot/tools/cabana/signalview.h diff --git a/tools/cabana/streams/abstractstream.cc b/openpilot/tools/cabana/streams/abstractstream.cc similarity index 100% rename from tools/cabana/streams/abstractstream.cc rename to openpilot/tools/cabana/streams/abstractstream.cc diff --git a/tools/cabana/streams/abstractstream.h b/openpilot/tools/cabana/streams/abstractstream.h similarity index 100% rename from tools/cabana/streams/abstractstream.h rename to openpilot/tools/cabana/streams/abstractstream.h diff --git a/tools/cabana/streams/devicestream.cc b/openpilot/tools/cabana/streams/devicestream.cc similarity index 100% rename from tools/cabana/streams/devicestream.cc rename to openpilot/tools/cabana/streams/devicestream.cc diff --git a/tools/cabana/streams/devicestream.h b/openpilot/tools/cabana/streams/devicestream.h similarity index 100% rename from tools/cabana/streams/devicestream.h rename to openpilot/tools/cabana/streams/devicestream.h diff --git a/tools/cabana/streams/livestream.cc b/openpilot/tools/cabana/streams/livestream.cc similarity index 100% rename from tools/cabana/streams/livestream.cc rename to openpilot/tools/cabana/streams/livestream.cc diff --git a/tools/cabana/streams/livestream.h b/openpilot/tools/cabana/streams/livestream.h similarity index 100% rename from tools/cabana/streams/livestream.h rename to openpilot/tools/cabana/streams/livestream.h diff --git a/tools/cabana/streams/pandastream.cc b/openpilot/tools/cabana/streams/pandastream.cc similarity index 100% rename from tools/cabana/streams/pandastream.cc rename to openpilot/tools/cabana/streams/pandastream.cc diff --git a/tools/cabana/streams/pandastream.h b/openpilot/tools/cabana/streams/pandastream.h similarity index 100% rename from tools/cabana/streams/pandastream.h rename to openpilot/tools/cabana/streams/pandastream.h diff --git a/tools/cabana/streams/replaystream.cc b/openpilot/tools/cabana/streams/replaystream.cc similarity index 100% rename from tools/cabana/streams/replaystream.cc rename to openpilot/tools/cabana/streams/replaystream.cc diff --git a/tools/cabana/streams/replaystream.h b/openpilot/tools/cabana/streams/replaystream.h similarity index 100% rename from tools/cabana/streams/replaystream.h rename to openpilot/tools/cabana/streams/replaystream.h diff --git a/tools/cabana/streams/routes.cc b/openpilot/tools/cabana/streams/routes.cc similarity index 100% rename from tools/cabana/streams/routes.cc rename to openpilot/tools/cabana/streams/routes.cc diff --git a/tools/cabana/streams/routes.h b/openpilot/tools/cabana/streams/routes.h similarity index 100% rename from tools/cabana/streams/routes.h rename to openpilot/tools/cabana/streams/routes.h diff --git a/tools/cabana/streams/socketcanstream.cc b/openpilot/tools/cabana/streams/socketcanstream.cc similarity index 100% rename from tools/cabana/streams/socketcanstream.cc rename to openpilot/tools/cabana/streams/socketcanstream.cc diff --git a/tools/cabana/streams/socketcanstream.h b/openpilot/tools/cabana/streams/socketcanstream.h similarity index 100% rename from tools/cabana/streams/socketcanstream.h rename to openpilot/tools/cabana/streams/socketcanstream.h diff --git a/tools/cabana/streamselector.cc b/openpilot/tools/cabana/streamselector.cc similarity index 100% rename from tools/cabana/streamselector.cc rename to openpilot/tools/cabana/streamselector.cc diff --git a/tools/cabana/streamselector.h b/openpilot/tools/cabana/streamselector.h similarity index 100% rename from tools/cabana/streamselector.h rename to openpilot/tools/cabana/streamselector.h diff --git a/tools/cabana/tests/test_cabana.cc b/openpilot/tools/cabana/tests/test_cabana.cc similarity index 100% rename from tools/cabana/tests/test_cabana.cc rename to openpilot/tools/cabana/tests/test_cabana.cc diff --git a/tools/cabana/tests/test_runner.cc b/openpilot/tools/cabana/tests/test_runner.cc similarity index 100% rename from tools/cabana/tests/test_runner.cc rename to openpilot/tools/cabana/tests/test_runner.cc diff --git a/tools/cabana/tools/findsignal.cc b/openpilot/tools/cabana/tools/findsignal.cc similarity index 100% rename from tools/cabana/tools/findsignal.cc rename to openpilot/tools/cabana/tools/findsignal.cc diff --git a/tools/cabana/tools/findsignal.h b/openpilot/tools/cabana/tools/findsignal.h similarity index 100% rename from tools/cabana/tools/findsignal.h rename to openpilot/tools/cabana/tools/findsignal.h diff --git a/tools/cabana/tools/findsimilarbits.cc b/openpilot/tools/cabana/tools/findsimilarbits.cc similarity index 100% rename from tools/cabana/tools/findsimilarbits.cc rename to openpilot/tools/cabana/tools/findsimilarbits.cc diff --git a/tools/cabana/tools/findsimilarbits.h b/openpilot/tools/cabana/tools/findsimilarbits.h similarity index 100% rename from tools/cabana/tools/findsimilarbits.h rename to openpilot/tools/cabana/tools/findsimilarbits.h diff --git a/tools/cabana/tools/routeinfo.cc b/openpilot/tools/cabana/tools/routeinfo.cc similarity index 100% rename from tools/cabana/tools/routeinfo.cc rename to openpilot/tools/cabana/tools/routeinfo.cc diff --git a/tools/cabana/tools/routeinfo.h b/openpilot/tools/cabana/tools/routeinfo.h similarity index 100% rename from tools/cabana/tools/routeinfo.h rename to openpilot/tools/cabana/tools/routeinfo.h diff --git a/tools/cabana/utils/elidedlabel.cc b/openpilot/tools/cabana/utils/elidedlabel.cc similarity index 100% rename from tools/cabana/utils/elidedlabel.cc rename to openpilot/tools/cabana/utils/elidedlabel.cc diff --git a/tools/cabana/utils/elidedlabel.h b/openpilot/tools/cabana/utils/elidedlabel.h similarity index 100% rename from tools/cabana/utils/elidedlabel.h rename to openpilot/tools/cabana/utils/elidedlabel.h diff --git a/tools/cabana/utils/export.cc b/openpilot/tools/cabana/utils/export.cc similarity index 100% rename from tools/cabana/utils/export.cc rename to openpilot/tools/cabana/utils/export.cc diff --git a/tools/cabana/utils/export.h b/openpilot/tools/cabana/utils/export.h similarity index 100% rename from tools/cabana/utils/export.h rename to openpilot/tools/cabana/utils/export.h diff --git a/tools/cabana/utils/util.cc b/openpilot/tools/cabana/utils/util.cc similarity index 100% rename from tools/cabana/utils/util.cc rename to openpilot/tools/cabana/utils/util.cc diff --git a/tools/cabana/utils/util.h b/openpilot/tools/cabana/utils/util.h similarity index 100% rename from tools/cabana/utils/util.h rename to openpilot/tools/cabana/utils/util.h diff --git a/tools/cabana/videowidget.cc b/openpilot/tools/cabana/videowidget.cc similarity index 100% rename from tools/cabana/videowidget.cc rename to openpilot/tools/cabana/videowidget.cc diff --git a/tools/cabana/videowidget.h b/openpilot/tools/cabana/videowidget.h similarity index 100% rename from tools/cabana/videowidget.h rename to openpilot/tools/cabana/videowidget.h diff --git a/tools/camerastream/README.md b/openpilot/tools/camerastream/README.md similarity index 100% rename from tools/camerastream/README.md rename to openpilot/tools/camerastream/README.md diff --git a/tools/camerastream/compressed_vipc.py b/openpilot/tools/camerastream/compressed_vipc.py similarity index 100% rename from tools/camerastream/compressed_vipc.py rename to openpilot/tools/camerastream/compressed_vipc.py diff --git a/tools/car_porting/README.md b/openpilot/tools/car_porting/README.md similarity index 100% rename from tools/car_porting/README.md rename to openpilot/tools/car_porting/README.md diff --git a/tools/car_porting/auto_fingerprint.py b/openpilot/tools/car_porting/auto_fingerprint.py similarity index 100% rename from tools/car_porting/auto_fingerprint.py rename to openpilot/tools/car_porting/auto_fingerprint.py diff --git a/tools/car_porting/examples/find_segments_with_message.ipynb b/openpilot/tools/car_porting/examples/find_segments_with_message.ipynb similarity index 100% rename from tools/car_porting/examples/find_segments_with_message.ipynb rename to openpilot/tools/car_porting/examples/find_segments_with_message.ipynb diff --git a/tools/car_porting/examples/ford_vin_fingerprint.ipynb b/openpilot/tools/car_porting/examples/ford_vin_fingerprint.ipynb similarity index 100% rename from tools/car_porting/examples/ford_vin_fingerprint.ipynb rename to openpilot/tools/car_porting/examples/ford_vin_fingerprint.ipynb diff --git a/tools/car_porting/examples/hkg_canfd_gear_message.ipynb b/openpilot/tools/car_porting/examples/hkg_canfd_gear_message.ipynb similarity index 100% rename from tools/car_porting/examples/hkg_canfd_gear_message.ipynb rename to openpilot/tools/car_porting/examples/hkg_canfd_gear_message.ipynb diff --git a/tools/car_porting/examples/subaru_fuzzy_fingerprint.ipynb b/openpilot/tools/car_porting/examples/subaru_fuzzy_fingerprint.ipynb similarity index 100% rename from tools/car_porting/examples/subaru_fuzzy_fingerprint.ipynb rename to openpilot/tools/car_porting/examples/subaru_fuzzy_fingerprint.ipynb diff --git a/tools/car_porting/examples/subaru_long_accel.ipynb b/openpilot/tools/car_porting/examples/subaru_long_accel.ipynb similarity index 100% rename from tools/car_porting/examples/subaru_long_accel.ipynb rename to openpilot/tools/car_porting/examples/subaru_long_accel.ipynb diff --git a/tools/car_porting/examples/subaru_steer_temp_fault.ipynb b/openpilot/tools/car_porting/examples/subaru_steer_temp_fault.ipynb similarity index 100% rename from tools/car_porting/examples/subaru_steer_temp_fault.ipynb rename to openpilot/tools/car_porting/examples/subaru_steer_temp_fault.ipynb diff --git a/tools/car_porting/measure_steering_accuracy.py b/openpilot/tools/car_porting/measure_steering_accuracy.py similarity index 100% rename from tools/car_porting/measure_steering_accuracy.py rename to openpilot/tools/car_porting/measure_steering_accuracy.py diff --git a/tools/car_porting/test_car_model.py b/openpilot/tools/car_porting/test_car_model.py similarity index 100% rename from tools/car_porting/test_car_model.py rename to openpilot/tools/car_porting/test_car_model.py diff --git a/tools/clip/run.py b/openpilot/tools/clip/run.py similarity index 100% rename from tools/clip/run.py rename to openpilot/tools/clip/run.py diff --git a/tools/jotpluggler/.gitignore b/openpilot/tools/jotpluggler/.gitignore similarity index 100% rename from tools/jotpluggler/.gitignore rename to openpilot/tools/jotpluggler/.gitignore diff --git a/tools/jotpluggler/SConscript b/openpilot/tools/jotpluggler/SConscript similarity index 100% rename from tools/jotpluggler/SConscript rename to openpilot/tools/jotpluggler/SConscript diff --git a/tools/jotpluggler/app.cc b/openpilot/tools/jotpluggler/app.cc similarity index 100% rename from tools/jotpluggler/app.cc rename to openpilot/tools/jotpluggler/app.cc diff --git a/tools/jotpluggler/app.h b/openpilot/tools/jotpluggler/app.h similarity index 100% rename from tools/jotpluggler/app.h rename to openpilot/tools/jotpluggler/app.h diff --git a/tools/jotpluggler/browser.cc b/openpilot/tools/jotpluggler/browser.cc similarity index 100% rename from tools/jotpluggler/browser.cc rename to openpilot/tools/jotpluggler/browser.cc diff --git a/tools/jotpluggler/camera.cc b/openpilot/tools/jotpluggler/camera.cc similarity index 100% rename from tools/jotpluggler/camera.cc rename to openpilot/tools/jotpluggler/camera.cc diff --git a/tools/jotpluggler/camera.h b/openpilot/tools/jotpluggler/camera.h similarity index 100% rename from tools/jotpluggler/camera.h rename to openpilot/tools/jotpluggler/camera.h diff --git a/tools/jotpluggler/common.cc b/openpilot/tools/jotpluggler/common.cc similarity index 100% rename from tools/jotpluggler/common.cc rename to openpilot/tools/jotpluggler/common.cc diff --git a/tools/jotpluggler/common.h b/openpilot/tools/jotpluggler/common.h similarity index 100% rename from tools/jotpluggler/common.h rename to openpilot/tools/jotpluggler/common.h diff --git a/tools/jotpluggler/custom_series.cc b/openpilot/tools/jotpluggler/custom_series.cc similarity index 100% rename from tools/jotpluggler/custom_series.cc rename to openpilot/tools/jotpluggler/custom_series.cc diff --git a/tools/jotpluggler/dbc.h b/openpilot/tools/jotpluggler/dbc.h similarity index 100% rename from tools/jotpluggler/dbc.h rename to openpilot/tools/jotpluggler/dbc.h diff --git a/tools/jotpluggler/generate_event_extractors.py b/openpilot/tools/jotpluggler/generate_event_extractors.py similarity index 100% rename from tools/jotpluggler/generate_event_extractors.py rename to openpilot/tools/jotpluggler/generate_event_extractors.py diff --git a/tools/jotpluggler/generated_dbcs/.gitignore b/openpilot/tools/jotpluggler/generated_dbcs/.gitignore similarity index 100% rename from tools/jotpluggler/generated_dbcs/.gitignore rename to openpilot/tools/jotpluggler/generated_dbcs/.gitignore diff --git a/tools/jotpluggler/icons.cc b/openpilot/tools/jotpluggler/icons.cc similarity index 100% rename from tools/jotpluggler/icons.cc rename to openpilot/tools/jotpluggler/icons.cc diff --git a/tools/jotpluggler/internal.h b/openpilot/tools/jotpluggler/internal.h similarity index 100% rename from tools/jotpluggler/internal.h rename to openpilot/tools/jotpluggler/internal.h diff --git a/tools/jotpluggler/layout.cc b/openpilot/tools/jotpluggler/layout.cc similarity index 100% rename from tools/jotpluggler/layout.cc rename to openpilot/tools/jotpluggler/layout.cc diff --git a/tools/jotpluggler/layout_io.cc b/openpilot/tools/jotpluggler/layout_io.cc similarity index 100% rename from tools/jotpluggler/layout_io.cc rename to openpilot/tools/jotpluggler/layout_io.cc diff --git a/tools/jotpluggler/layouts/.gitignore b/openpilot/tools/jotpluggler/layouts/.gitignore similarity index 100% rename from tools/jotpluggler/layouts/.gitignore rename to openpilot/tools/jotpluggler/layouts/.gitignore diff --git a/tools/jotpluggler/layouts/CAN-bus-debug.json b/openpilot/tools/jotpluggler/layouts/CAN-bus-debug.json similarity index 100% rename from tools/jotpluggler/layouts/CAN-bus-debug.json rename to openpilot/tools/jotpluggler/layouts/CAN-bus-debug.json diff --git a/tools/jotpluggler/layouts/camera-timings.json b/openpilot/tools/jotpluggler/layouts/camera-timings.json similarity index 100% rename from tools/jotpluggler/layouts/camera-timings.json rename to openpilot/tools/jotpluggler/layouts/camera-timings.json diff --git a/tools/jotpluggler/layouts/cameras-and-map.json b/openpilot/tools/jotpluggler/layouts/cameras-and-map.json similarity index 100% rename from tools/jotpluggler/layouts/cameras-and-map.json rename to openpilot/tools/jotpluggler/layouts/cameras-and-map.json diff --git a/tools/jotpluggler/layouts/can-states.json b/openpilot/tools/jotpluggler/layouts/can-states.json similarity index 100% rename from tools/jotpluggler/layouts/can-states.json rename to openpilot/tools/jotpluggler/layouts/can-states.json diff --git a/tools/jotpluggler/layouts/controls_mismatch_debug.json b/openpilot/tools/jotpluggler/layouts/controls_mismatch_debug.json similarity index 100% rename from tools/jotpluggler/layouts/controls_mismatch_debug.json rename to openpilot/tools/jotpluggler/layouts/controls_mismatch_debug.json diff --git a/tools/jotpluggler/layouts/driver-monitoring-debug.json b/openpilot/tools/jotpluggler/layouts/driver-monitoring-debug.json similarity index 100% rename from tools/jotpluggler/layouts/driver-monitoring-debug.json rename to openpilot/tools/jotpluggler/layouts/driver-monitoring-debug.json diff --git a/tools/jotpluggler/layouts/gps.json b/openpilot/tools/jotpluggler/layouts/gps.json similarity index 100% rename from tools/jotpluggler/layouts/gps.json rename to openpilot/tools/jotpluggler/layouts/gps.json diff --git a/tools/jotpluggler/layouts/gps_vs_llk.json b/openpilot/tools/jotpluggler/layouts/gps_vs_llk.json similarity index 100% rename from tools/jotpluggler/layouts/gps_vs_llk.json rename to openpilot/tools/jotpluggler/layouts/gps_vs_llk.json diff --git a/tools/jotpluggler/layouts/locationd_debug.json b/openpilot/tools/jotpluggler/layouts/locationd_debug.json similarity index 100% rename from tools/jotpluggler/layouts/locationd_debug.json rename to openpilot/tools/jotpluggler/layouts/locationd_debug.json diff --git a/tools/jotpluggler/layouts/longitudinal.json b/openpilot/tools/jotpluggler/layouts/longitudinal.json similarity index 100% rename from tools/jotpluggler/layouts/longitudinal.json rename to openpilot/tools/jotpluggler/layouts/longitudinal.json diff --git a/tools/jotpluggler/layouts/max-torque-debug.json b/openpilot/tools/jotpluggler/layouts/max-torque-debug.json similarity index 100% rename from tools/jotpluggler/layouts/max-torque-debug.json rename to openpilot/tools/jotpluggler/layouts/max-torque-debug.json diff --git a/tools/jotpluggler/layouts/new-layout.json b/openpilot/tools/jotpluggler/layouts/new-layout.json similarity index 100% rename from tools/jotpluggler/layouts/new-layout.json rename to openpilot/tools/jotpluggler/layouts/new-layout.json diff --git a/tools/jotpluggler/layouts/system_lag_debug.json b/openpilot/tools/jotpluggler/layouts/system_lag_debug.json similarity index 100% rename from tools/jotpluggler/layouts/system_lag_debug.json rename to openpilot/tools/jotpluggler/layouts/system_lag_debug.json diff --git a/tools/jotpluggler/layouts/thermal_debug.json b/openpilot/tools/jotpluggler/layouts/thermal_debug.json similarity index 100% rename from tools/jotpluggler/layouts/thermal_debug.json rename to openpilot/tools/jotpluggler/layouts/thermal_debug.json diff --git a/tools/jotpluggler/layouts/torque-controller.json b/openpilot/tools/jotpluggler/layouts/torque-controller.json similarity index 100% rename from tools/jotpluggler/layouts/torque-controller.json rename to openpilot/tools/jotpluggler/layouts/torque-controller.json diff --git a/tools/jotpluggler/layouts/tuning.json b/openpilot/tools/jotpluggler/layouts/tuning.json similarity index 100% rename from tools/jotpluggler/layouts/tuning.json rename to openpilot/tools/jotpluggler/layouts/tuning.json diff --git a/tools/jotpluggler/layouts/ublox-debug.json b/openpilot/tools/jotpluggler/layouts/ublox-debug.json similarity index 100% rename from tools/jotpluggler/layouts/ublox-debug.json rename to openpilot/tools/jotpluggler/layouts/ublox-debug.json diff --git a/tools/jotpluggler/logs.cc b/openpilot/tools/jotpluggler/logs.cc similarity index 100% rename from tools/jotpluggler/logs.cc rename to openpilot/tools/jotpluggler/logs.cc diff --git a/tools/jotpluggler/main.cc b/openpilot/tools/jotpluggler/main.cc similarity index 100% rename from tools/jotpluggler/main.cc rename to openpilot/tools/jotpluggler/main.cc diff --git a/tools/jotpluggler/map.cc b/openpilot/tools/jotpluggler/map.cc similarity index 100% rename from tools/jotpluggler/map.cc rename to openpilot/tools/jotpluggler/map.cc diff --git a/tools/jotpluggler/map.h b/openpilot/tools/jotpluggler/map.h similarity index 100% rename from tools/jotpluggler/map.h rename to openpilot/tools/jotpluggler/map.h diff --git a/tools/jotpluggler/math_eval.py b/openpilot/tools/jotpluggler/math_eval.py similarity index 100% rename from tools/jotpluggler/math_eval.py rename to openpilot/tools/jotpluggler/math_eval.py diff --git a/tools/jotpluggler/plot.cc b/openpilot/tools/jotpluggler/plot.cc similarity index 100% rename from tools/jotpluggler/plot.cc rename to openpilot/tools/jotpluggler/plot.cc diff --git a/tools/jotpluggler/render.cc b/openpilot/tools/jotpluggler/render.cc similarity index 100% rename from tools/jotpluggler/render.cc rename to openpilot/tools/jotpluggler/render.cc diff --git a/tools/jotpluggler/runtime.cc b/openpilot/tools/jotpluggler/runtime.cc similarity index 100% rename from tools/jotpluggler/runtime.cc rename to openpilot/tools/jotpluggler/runtime.cc diff --git a/tools/jotpluggler/session.cc b/openpilot/tools/jotpluggler/session.cc similarity index 100% rename from tools/jotpluggler/session.cc rename to openpilot/tools/jotpluggler/session.cc diff --git a/tools/jotpluggler/sidebar.cc b/openpilot/tools/jotpluggler/sidebar.cc similarity index 100% rename from tools/jotpluggler/sidebar.cc rename to openpilot/tools/jotpluggler/sidebar.cc diff --git a/tools/jotpluggler/sketch_layout.cc b/openpilot/tools/jotpluggler/sketch_layout.cc similarity index 100% rename from tools/jotpluggler/sketch_layout.cc rename to openpilot/tools/jotpluggler/sketch_layout.cc diff --git a/tools/jotpluggler/stream.cc b/openpilot/tools/jotpluggler/stream.cc similarity index 100% rename from tools/jotpluggler/stream.cc rename to openpilot/tools/jotpluggler/stream.cc diff --git a/tools/jotpluggler/util.cc b/openpilot/tools/jotpluggler/util.cc similarity index 100% rename from tools/jotpluggler/util.cc rename to openpilot/tools/jotpluggler/util.cc diff --git a/tools/jotpluggler/util.h b/openpilot/tools/jotpluggler/util.h similarity index 100% rename from tools/jotpluggler/util.h rename to openpilot/tools/jotpluggler/util.h diff --git a/tools/joystick/README.md b/openpilot/tools/joystick/README.md similarity index 100% rename from tools/joystick/README.md rename to openpilot/tools/joystick/README.md diff --git a/tools/joystick/joystick_control.py b/openpilot/tools/joystick/joystick_control.py similarity index 100% rename from tools/joystick/joystick_control.py rename to openpilot/tools/joystick/joystick_control.py diff --git a/tools/joystick/joystickd.py b/openpilot/tools/joystick/joystickd.py similarity index 100% rename from tools/joystick/joystickd.py rename to openpilot/tools/joystick/joystickd.py diff --git a/tools/lateral_maneuvers/.gitignore b/openpilot/tools/lateral_maneuvers/.gitignore similarity index 100% rename from tools/lateral_maneuvers/.gitignore rename to openpilot/tools/lateral_maneuvers/.gitignore diff --git a/tools/lateral_maneuvers/README.md b/openpilot/tools/lateral_maneuvers/README.md similarity index 100% rename from tools/lateral_maneuvers/README.md rename to openpilot/tools/lateral_maneuvers/README.md diff --git a/tools/lateral_maneuvers/generate_report.py b/openpilot/tools/lateral_maneuvers/generate_report.py similarity index 100% rename from tools/lateral_maneuvers/generate_report.py rename to openpilot/tools/lateral_maneuvers/generate_report.py diff --git a/tools/lateral_maneuvers/lateral_maneuversd.py b/openpilot/tools/lateral_maneuvers/lateral_maneuversd.py similarity index 100% rename from tools/lateral_maneuvers/lateral_maneuversd.py rename to openpilot/tools/lateral_maneuvers/lateral_maneuversd.py diff --git a/tools/lib/README.md b/openpilot/tools/lib/README.md similarity index 100% rename from tools/lib/README.md rename to openpilot/tools/lib/README.md diff --git a/tools/lib/__init__.py b/openpilot/tools/lib/__init__.py similarity index 100% rename from tools/lib/__init__.py rename to openpilot/tools/lib/__init__.py diff --git a/tools/lib/api.py b/openpilot/tools/lib/api.py similarity index 100% rename from tools/lib/api.py rename to openpilot/tools/lib/api.py diff --git a/tools/lib/auth.py b/openpilot/tools/lib/auth.py similarity index 100% rename from tools/lib/auth.py rename to openpilot/tools/lib/auth.py diff --git a/tools/lib/auth_config.py b/openpilot/tools/lib/auth_config.py similarity index 100% rename from tools/lib/auth_config.py rename to openpilot/tools/lib/auth_config.py diff --git a/tools/lib/azure_container.py b/openpilot/tools/lib/azure_container.py similarity index 100% rename from tools/lib/azure_container.py rename to openpilot/tools/lib/azure_container.py diff --git a/tools/lib/bootlog.py b/openpilot/tools/lib/bootlog.py similarity index 100% rename from tools/lib/bootlog.py rename to openpilot/tools/lib/bootlog.py diff --git a/tools/lib/cache.py b/openpilot/tools/lib/cache.py similarity index 100% rename from tools/lib/cache.py rename to openpilot/tools/lib/cache.py diff --git a/tools/lib/comma_car_segments.py b/openpilot/tools/lib/comma_car_segments.py similarity index 100% rename from tools/lib/comma_car_segments.py rename to openpilot/tools/lib/comma_car_segments.py diff --git a/tools/lib/exceptions.py b/openpilot/tools/lib/exceptions.py similarity index 100% rename from tools/lib/exceptions.py rename to openpilot/tools/lib/exceptions.py diff --git a/tools/lib/file_downloader.py b/openpilot/tools/lib/file_downloader.py similarity index 100% rename from tools/lib/file_downloader.py rename to openpilot/tools/lib/file_downloader.py diff --git a/tools/lib/file_sources.py b/openpilot/tools/lib/file_sources.py similarity index 100% rename from tools/lib/file_sources.py rename to openpilot/tools/lib/file_sources.py diff --git a/tools/lib/filereader.py b/openpilot/tools/lib/filereader.py similarity index 100% rename from tools/lib/filereader.py rename to openpilot/tools/lib/filereader.py diff --git a/tools/lib/framereader.py b/openpilot/tools/lib/framereader.py similarity index 100% rename from tools/lib/framereader.py rename to openpilot/tools/lib/framereader.py diff --git a/tools/lib/github_utils.py b/openpilot/tools/lib/github_utils.py similarity index 100% rename from tools/lib/github_utils.py rename to openpilot/tools/lib/github_utils.py diff --git a/tools/lib/helpers.py b/openpilot/tools/lib/helpers.py similarity index 100% rename from tools/lib/helpers.py rename to openpilot/tools/lib/helpers.py diff --git a/tools/lib/kbhit.py b/openpilot/tools/lib/kbhit.py similarity index 100% rename from tools/lib/kbhit.py rename to openpilot/tools/lib/kbhit.py diff --git a/tools/lib/live_logreader.py b/openpilot/tools/lib/live_logreader.py similarity index 100% rename from tools/lib/live_logreader.py rename to openpilot/tools/lib/live_logreader.py diff --git a/tools/lib/log_time_series.py b/openpilot/tools/lib/log_time_series.py similarity index 100% rename from tools/lib/log_time_series.py rename to openpilot/tools/lib/log_time_series.py diff --git a/tools/lib/logreader.py b/openpilot/tools/lib/logreader.py similarity index 100% rename from tools/lib/logreader.py rename to openpilot/tools/lib/logreader.py diff --git a/tools/lib/openpilotci.py b/openpilot/tools/lib/openpilotci.py similarity index 100% rename from tools/lib/openpilotci.py rename to openpilot/tools/lib/openpilotci.py diff --git a/tools/lib/openpilotcontainers.py b/openpilot/tools/lib/openpilotcontainers.py similarity index 100% rename from tools/lib/openpilotcontainers.py rename to openpilot/tools/lib/openpilotcontainers.py diff --git a/tools/lib/route.py b/openpilot/tools/lib/route.py similarity index 100% rename from tools/lib/route.py rename to openpilot/tools/lib/route.py diff --git a/tools/lib/sanitizer.py b/openpilot/tools/lib/sanitizer.py similarity index 100% rename from tools/lib/sanitizer.py rename to openpilot/tools/lib/sanitizer.py diff --git a/tools/lib/tests/__init__.py b/openpilot/tools/lib/tests/__init__.py similarity index 100% rename from tools/lib/tests/__init__.py rename to openpilot/tools/lib/tests/__init__.py diff --git a/tools/lib/tests/test_caching.py b/openpilot/tools/lib/tests/test_caching.py similarity index 100% rename from tools/lib/tests/test_caching.py rename to openpilot/tools/lib/tests/test_caching.py diff --git a/tools/lib/tests/test_comma_car_segments.py b/openpilot/tools/lib/tests/test_comma_car_segments.py similarity index 100% rename from tools/lib/tests/test_comma_car_segments.py rename to openpilot/tools/lib/tests/test_comma_car_segments.py diff --git a/tools/lib/tests/test_logreader.py b/openpilot/tools/lib/tests/test_logreader.py similarity index 100% rename from tools/lib/tests/test_logreader.py rename to openpilot/tools/lib/tests/test_logreader.py diff --git a/tools/lib/tests/test_route_library.py b/openpilot/tools/lib/tests/test_route_library.py similarity index 100% rename from tools/lib/tests/test_route_library.py rename to openpilot/tools/lib/tests/test_route_library.py diff --git a/tools/lib/url_file.py b/openpilot/tools/lib/url_file.py similarity index 100% rename from tools/lib/url_file.py rename to openpilot/tools/lib/url_file.py diff --git a/tools/lib/vidindex.py b/openpilot/tools/lib/vidindex.py similarity index 100% rename from tools/lib/vidindex.py rename to openpilot/tools/lib/vidindex.py diff --git a/tools/longitudinal_maneuvers/.gitignore b/openpilot/tools/longitudinal_maneuvers/.gitignore similarity index 100% rename from tools/longitudinal_maneuvers/.gitignore rename to openpilot/tools/longitudinal_maneuvers/.gitignore diff --git a/tools/longitudinal_maneuvers/README.md b/openpilot/tools/longitudinal_maneuvers/README.md similarity index 100% rename from tools/longitudinal_maneuvers/README.md rename to openpilot/tools/longitudinal_maneuvers/README.md diff --git a/tools/longitudinal_maneuvers/generate_report.py b/openpilot/tools/longitudinal_maneuvers/generate_report.py similarity index 100% rename from tools/longitudinal_maneuvers/generate_report.py rename to openpilot/tools/longitudinal_maneuvers/generate_report.py diff --git a/tools/longitudinal_maneuvers/maneuver_helpers.py b/openpilot/tools/longitudinal_maneuvers/maneuver_helpers.py similarity index 100% rename from tools/longitudinal_maneuvers/maneuver_helpers.py rename to openpilot/tools/longitudinal_maneuvers/maneuver_helpers.py diff --git a/tools/longitudinal_maneuvers/maneuversd.py b/openpilot/tools/longitudinal_maneuvers/maneuversd.py similarity index 100% rename from tools/longitudinal_maneuvers/maneuversd.py rename to openpilot/tools/longitudinal_maneuvers/maneuversd.py diff --git a/tools/longitudinal_maneuvers/mpc_longitudinal_tuning_report.py b/openpilot/tools/longitudinal_maneuvers/mpc_longitudinal_tuning_report.py similarity index 100% rename from tools/longitudinal_maneuvers/mpc_longitudinal_tuning_report.py rename to openpilot/tools/longitudinal_maneuvers/mpc_longitudinal_tuning_report.py diff --git a/tools/op.sh b/openpilot/tools/op.sh similarity index 99% rename from tools/op.sh rename to openpilot/tools/op.sh index 3b766b61ee..3d0af526ba 100755 --- a/tools/op.sh +++ b/openpilot/tools/op.sh @@ -75,7 +75,7 @@ function op_get_openpilot_dir() { # Fallback to hardcoded directories if not found SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)" - for dir in "${SCRIPT_DIR%/tools}" "$HOME/openpilot" "/data/openpilot"; do + for dir in "$(readlink -f "$SCRIPT_DIR/../..")" "$HOME/openpilot" "/data/openpilot"; do if [[ -f "$dir/launch_openpilot.sh" ]]; then OPENPILOT_ROOT="$dir" return 0 diff --git a/tools/plotjuggler/README.md b/openpilot/tools/plotjuggler/README.md similarity index 100% rename from tools/plotjuggler/README.md rename to openpilot/tools/plotjuggler/README.md diff --git a/tools/plotjuggler/juggle.py b/openpilot/tools/plotjuggler/juggle.py similarity index 100% rename from tools/plotjuggler/juggle.py rename to openpilot/tools/plotjuggler/juggle.py diff --git a/tools/plotjuggler/layouts/CAN-bus-debug.xml b/openpilot/tools/plotjuggler/layouts/CAN-bus-debug.xml similarity index 100% rename from tools/plotjuggler/layouts/CAN-bus-debug.xml rename to openpilot/tools/plotjuggler/layouts/CAN-bus-debug.xml diff --git a/tools/plotjuggler/layouts/camera-timings.xml b/openpilot/tools/plotjuggler/layouts/camera-timings.xml similarity index 100% rename from tools/plotjuggler/layouts/camera-timings.xml rename to openpilot/tools/plotjuggler/layouts/camera-timings.xml diff --git a/tools/plotjuggler/layouts/can-states.xml b/openpilot/tools/plotjuggler/layouts/can-states.xml similarity index 100% rename from tools/plotjuggler/layouts/can-states.xml rename to openpilot/tools/plotjuggler/layouts/can-states.xml diff --git a/tools/plotjuggler/layouts/controls_mismatch_debug.xml b/openpilot/tools/plotjuggler/layouts/controls_mismatch_debug.xml similarity index 100% rename from tools/plotjuggler/layouts/controls_mismatch_debug.xml rename to openpilot/tools/plotjuggler/layouts/controls_mismatch_debug.xml diff --git a/tools/plotjuggler/layouts/gps.xml b/openpilot/tools/plotjuggler/layouts/gps.xml similarity index 100% rename from tools/plotjuggler/layouts/gps.xml rename to openpilot/tools/plotjuggler/layouts/gps.xml diff --git a/tools/plotjuggler/layouts/gps_vs_llk.xml b/openpilot/tools/plotjuggler/layouts/gps_vs_llk.xml similarity index 100% rename from tools/plotjuggler/layouts/gps_vs_llk.xml rename to openpilot/tools/plotjuggler/layouts/gps_vs_llk.xml diff --git a/tools/plotjuggler/layouts/locationd_debug.xml b/openpilot/tools/plotjuggler/layouts/locationd_debug.xml similarity index 100% rename from tools/plotjuggler/layouts/locationd_debug.xml rename to openpilot/tools/plotjuggler/layouts/locationd_debug.xml diff --git a/tools/plotjuggler/layouts/longitudinal.xml b/openpilot/tools/plotjuggler/layouts/longitudinal.xml similarity index 100% rename from tools/plotjuggler/layouts/longitudinal.xml rename to openpilot/tools/plotjuggler/layouts/longitudinal.xml diff --git a/tools/plotjuggler/layouts/max-torque-debug.xml b/openpilot/tools/plotjuggler/layouts/max-torque-debug.xml similarity index 100% rename from tools/plotjuggler/layouts/max-torque-debug.xml rename to openpilot/tools/plotjuggler/layouts/max-torque-debug.xml diff --git a/tools/plotjuggler/layouts/system_lag_debug.xml b/openpilot/tools/plotjuggler/layouts/system_lag_debug.xml similarity index 100% rename from tools/plotjuggler/layouts/system_lag_debug.xml rename to openpilot/tools/plotjuggler/layouts/system_lag_debug.xml diff --git a/tools/plotjuggler/layouts/thermal_debug.xml b/openpilot/tools/plotjuggler/layouts/thermal_debug.xml similarity index 100% rename from tools/plotjuggler/layouts/thermal_debug.xml rename to openpilot/tools/plotjuggler/layouts/thermal_debug.xml diff --git a/tools/plotjuggler/layouts/torque-controller.xml b/openpilot/tools/plotjuggler/layouts/torque-controller.xml similarity index 100% rename from tools/plotjuggler/layouts/torque-controller.xml rename to openpilot/tools/plotjuggler/layouts/torque-controller.xml diff --git a/tools/plotjuggler/layouts/tuning.xml b/openpilot/tools/plotjuggler/layouts/tuning.xml similarity index 100% rename from tools/plotjuggler/layouts/tuning.xml rename to openpilot/tools/plotjuggler/layouts/tuning.xml diff --git a/tools/plotjuggler/layouts/ublox-debug.xml b/openpilot/tools/plotjuggler/layouts/ublox-debug.xml similarity index 100% rename from tools/plotjuggler/layouts/ublox-debug.xml rename to openpilot/tools/plotjuggler/layouts/ublox-debug.xml diff --git a/tools/plotjuggler/test_plotjuggler.py b/openpilot/tools/plotjuggler/test_plotjuggler.py similarity index 100% rename from tools/plotjuggler/test_plotjuggler.py rename to openpilot/tools/plotjuggler/test_plotjuggler.py diff --git a/tools/replay/.gitignore b/openpilot/tools/replay/.gitignore similarity index 100% rename from tools/replay/.gitignore rename to openpilot/tools/replay/.gitignore diff --git a/tools/replay/README.md b/openpilot/tools/replay/README.md similarity index 100% rename from tools/replay/README.md rename to openpilot/tools/replay/README.md diff --git a/tools/replay/SConscript b/openpilot/tools/replay/SConscript similarity index 100% rename from tools/replay/SConscript rename to openpilot/tools/replay/SConscript diff --git a/tools/replay/__init__.py b/openpilot/tools/replay/__init__.py similarity index 100% rename from tools/replay/__init__.py rename to openpilot/tools/replay/__init__.py diff --git a/tools/replay/camera.cc b/openpilot/tools/replay/camera.cc similarity index 100% rename from tools/replay/camera.cc rename to openpilot/tools/replay/camera.cc diff --git a/tools/replay/camera.h b/openpilot/tools/replay/camera.h similarity index 100% rename from tools/replay/camera.h rename to openpilot/tools/replay/camera.h diff --git a/tools/replay/can_replay.py b/openpilot/tools/replay/can_replay.py similarity index 100% rename from tools/replay/can_replay.py rename to openpilot/tools/replay/can_replay.py diff --git a/tools/replay/consoleui.cc b/openpilot/tools/replay/consoleui.cc similarity index 100% rename from tools/replay/consoleui.cc rename to openpilot/tools/replay/consoleui.cc diff --git a/tools/replay/consoleui.h b/openpilot/tools/replay/consoleui.h similarity index 100% rename from tools/replay/consoleui.h rename to openpilot/tools/replay/consoleui.h diff --git a/tools/replay/filereader.cc b/openpilot/tools/replay/filereader.cc similarity index 100% rename from tools/replay/filereader.cc rename to openpilot/tools/replay/filereader.cc diff --git a/tools/replay/filereader.h b/openpilot/tools/replay/filereader.h similarity index 100% rename from tools/replay/filereader.h rename to openpilot/tools/replay/filereader.h diff --git a/tools/replay/framereader.cc b/openpilot/tools/replay/framereader.cc similarity index 100% rename from tools/replay/framereader.cc rename to openpilot/tools/replay/framereader.cc diff --git a/tools/replay/framereader.h b/openpilot/tools/replay/framereader.h similarity index 100% rename from tools/replay/framereader.h rename to openpilot/tools/replay/framereader.h diff --git a/tools/replay/lib/__init__.py b/openpilot/tools/replay/lib/__init__.py similarity index 100% rename from tools/replay/lib/__init__.py rename to openpilot/tools/replay/lib/__init__.py diff --git a/tools/replay/lib/ui_helpers.py b/openpilot/tools/replay/lib/ui_helpers.py similarity index 100% rename from tools/replay/lib/ui_helpers.py rename to openpilot/tools/replay/lib/ui_helpers.py diff --git a/tools/replay/logreader.cc b/openpilot/tools/replay/logreader.cc similarity index 100% rename from tools/replay/logreader.cc rename to openpilot/tools/replay/logreader.cc diff --git a/tools/replay/logreader.h b/openpilot/tools/replay/logreader.h similarity index 100% rename from tools/replay/logreader.h rename to openpilot/tools/replay/logreader.h diff --git a/tools/replay/main.cc b/openpilot/tools/replay/main.cc similarity index 100% rename from tools/replay/main.cc rename to openpilot/tools/replay/main.cc diff --git a/tools/replay/py_downloader.cc b/openpilot/tools/replay/py_downloader.cc similarity index 100% rename from tools/replay/py_downloader.cc rename to openpilot/tools/replay/py_downloader.cc diff --git a/tools/replay/py_downloader.h b/openpilot/tools/replay/py_downloader.h similarity index 100% rename from tools/replay/py_downloader.h rename to openpilot/tools/replay/py_downloader.h diff --git a/tools/replay/qcom_decoder.cc b/openpilot/tools/replay/qcom_decoder.cc similarity index 100% rename from tools/replay/qcom_decoder.cc rename to openpilot/tools/replay/qcom_decoder.cc diff --git a/tools/replay/qcom_decoder.h b/openpilot/tools/replay/qcom_decoder.h similarity index 100% rename from tools/replay/qcom_decoder.h rename to openpilot/tools/replay/qcom_decoder.h diff --git a/tools/replay/replay.cc b/openpilot/tools/replay/replay.cc similarity index 100% rename from tools/replay/replay.cc rename to openpilot/tools/replay/replay.cc diff --git a/tools/replay/replay.h b/openpilot/tools/replay/replay.h similarity index 100% rename from tools/replay/replay.h rename to openpilot/tools/replay/replay.h diff --git a/tools/replay/route.cc b/openpilot/tools/replay/route.cc similarity index 100% rename from tools/replay/route.cc rename to openpilot/tools/replay/route.cc diff --git a/tools/replay/route.h b/openpilot/tools/replay/route.h similarity index 100% rename from tools/replay/route.h rename to openpilot/tools/replay/route.h diff --git a/tools/replay/seg_mgr.cc b/openpilot/tools/replay/seg_mgr.cc similarity index 100% rename from tools/replay/seg_mgr.cc rename to openpilot/tools/replay/seg_mgr.cc diff --git a/tools/replay/seg_mgr.h b/openpilot/tools/replay/seg_mgr.h similarity index 100% rename from tools/replay/seg_mgr.h rename to openpilot/tools/replay/seg_mgr.h diff --git a/tools/replay/tests/test_replay.cc b/openpilot/tools/replay/tests/test_replay.cc similarity index 100% rename from tools/replay/tests/test_replay.cc rename to openpilot/tools/replay/tests/test_replay.cc diff --git a/tools/replay/timeline.cc b/openpilot/tools/replay/timeline.cc similarity index 100% rename from tools/replay/timeline.cc rename to openpilot/tools/replay/timeline.cc diff --git a/tools/replay/timeline.h b/openpilot/tools/replay/timeline.h similarity index 100% rename from tools/replay/timeline.h rename to openpilot/tools/replay/timeline.h diff --git a/tools/replay/ui.py b/openpilot/tools/replay/ui.py similarity index 100% rename from tools/replay/ui.py rename to openpilot/tools/replay/ui.py diff --git a/tools/replay/util.cc b/openpilot/tools/replay/util.cc similarity index 100% rename from tools/replay/util.cc rename to openpilot/tools/replay/util.cc diff --git a/tools/replay/util.h b/openpilot/tools/replay/util.h similarity index 100% rename from tools/replay/util.h rename to openpilot/tools/replay/util.h diff --git a/tools/scripts/__init__.py b/openpilot/tools/scripts/__init__.py similarity index 100% rename from tools/scripts/__init__.py rename to openpilot/tools/scripts/__init__.py diff --git a/tools/scripts/adb_ssh.sh b/openpilot/tools/scripts/adb_ssh.sh similarity index 100% rename from tools/scripts/adb_ssh.sh rename to openpilot/tools/scripts/adb_ssh.sh diff --git a/tools/scripts/car/can_print_changes.py b/openpilot/tools/scripts/car/can_print_changes.py similarity index 100% rename from tools/scripts/car/can_print_changes.py rename to openpilot/tools/scripts/car/can_print_changes.py diff --git a/tools/scripts/car/can_printer.py b/openpilot/tools/scripts/car/can_printer.py similarity index 100% rename from tools/scripts/car/can_printer.py rename to openpilot/tools/scripts/car/can_printer.py diff --git a/tools/scripts/car/can_table.py b/openpilot/tools/scripts/car/can_table.py similarity index 100% rename from tools/scripts/car/can_table.py rename to openpilot/tools/scripts/car/can_table.py diff --git a/tools/scripts/car/clear_dtc.py b/openpilot/tools/scripts/car/clear_dtc.py similarity index 100% rename from tools/scripts/car/clear_dtc.py rename to openpilot/tools/scripts/car/clear_dtc.py diff --git a/tools/scripts/car/disable_ecu.py b/openpilot/tools/scripts/car/disable_ecu.py similarity index 100% rename from tools/scripts/car/disable_ecu.py rename to openpilot/tools/scripts/car/disable_ecu.py diff --git a/tools/scripts/car/ecu_addrs.py b/openpilot/tools/scripts/car/ecu_addrs.py similarity index 100% rename from tools/scripts/car/ecu_addrs.py rename to openpilot/tools/scripts/car/ecu_addrs.py diff --git a/tools/scripts/car/fw_versions.py b/openpilot/tools/scripts/car/fw_versions.py similarity index 100% rename from tools/scripts/car/fw_versions.py rename to openpilot/tools/scripts/car/fw_versions.py diff --git a/tools/scripts/car/hyundai_enable_radar_points.py b/openpilot/tools/scripts/car/hyundai_enable_radar_points.py similarity index 100% rename from tools/scripts/car/hyundai_enable_radar_points.py rename to openpilot/tools/scripts/car/hyundai_enable_radar_points.py diff --git a/tools/scripts/car/max_lat_accel.py b/openpilot/tools/scripts/car/max_lat_accel.py similarity index 100% rename from tools/scripts/car/max_lat_accel.py rename to openpilot/tools/scripts/car/max_lat_accel.py diff --git a/tools/scripts/car/measure_torque_time_to_max.py b/openpilot/tools/scripts/car/measure_torque_time_to_max.py similarity index 100% rename from tools/scripts/car/measure_torque_time_to_max.py rename to openpilot/tools/scripts/car/measure_torque_time_to_max.py diff --git a/tools/scripts/car/read_dtc_status.py b/openpilot/tools/scripts/car/read_dtc_status.py similarity index 100% rename from tools/scripts/car/read_dtc_status.py rename to openpilot/tools/scripts/car/read_dtc_status.py diff --git a/tools/scripts/car/toyota_eps_factor.py b/openpilot/tools/scripts/car/toyota_eps_factor.py similarity index 100% rename from tools/scripts/car/toyota_eps_factor.py rename to openpilot/tools/scripts/car/toyota_eps_factor.py diff --git a/tools/scripts/car/vin.py b/openpilot/tools/scripts/car/vin.py similarity index 100% rename from tools/scripts/car/vin.py rename to openpilot/tools/scripts/car/vin.py diff --git a/tools/scripts/car/vw_mqb_config.py b/openpilot/tools/scripts/car/vw_mqb_config.py similarity index 100% rename from tools/scripts/car/vw_mqb_config.py rename to openpilot/tools/scripts/car/vw_mqb_config.py diff --git a/tools/scripts/count_events.py b/openpilot/tools/scripts/count_events.py similarity index 100% rename from tools/scripts/count_events.py rename to openpilot/tools/scripts/count_events.py diff --git a/tools/scripts/cpu_usage_stat.py b/openpilot/tools/scripts/cpu_usage_stat.py similarity index 100% rename from tools/scripts/cpu_usage_stat.py rename to openpilot/tools/scripts/cpu_usage_stat.py diff --git a/tools/scripts/cycle_alerts.py b/openpilot/tools/scripts/cycle_alerts.py similarity index 100% rename from tools/scripts/cycle_alerts.py rename to openpilot/tools/scripts/cycle_alerts.py diff --git a/tools/scripts/debug_fw_fingerprinting_offline.py b/openpilot/tools/scripts/debug_fw_fingerprinting_offline.py similarity index 100% rename from tools/scripts/debug_fw_fingerprinting_offline.py rename to openpilot/tools/scripts/debug_fw_fingerprinting_offline.py diff --git a/tools/scripts/devsync.py b/openpilot/tools/scripts/devsync.py similarity index 100% rename from tools/scripts/devsync.py rename to openpilot/tools/scripts/devsync.py diff --git a/tools/scripts/dump.py b/openpilot/tools/scripts/dump.py similarity index 100% rename from tools/scripts/dump.py rename to openpilot/tools/scripts/dump.py diff --git a/tools/scripts/extract_audio.py b/openpilot/tools/scripts/extract_audio.py similarity index 100% rename from tools/scripts/extract_audio.py rename to openpilot/tools/scripts/extract_audio.py diff --git a/tools/scripts/filter_log_message.py b/openpilot/tools/scripts/filter_log_message.py similarity index 100% rename from tools/scripts/filter_log_message.py rename to openpilot/tools/scripts/filter_log_message.py diff --git a/tools/scripts/fingerprint_from_route.py b/openpilot/tools/scripts/fingerprint_from_route.py similarity index 100% rename from tools/scripts/fingerprint_from_route.py rename to openpilot/tools/scripts/fingerprint_from_route.py diff --git a/tools/scripts/fuzz_fw_fingerprint.py b/openpilot/tools/scripts/fuzz_fw_fingerprint.py similarity index 100% rename from tools/scripts/fuzz_fw_fingerprint.py rename to openpilot/tools/scripts/fuzz_fw_fingerprint.py diff --git a/tools/scripts/get_fingerprint.py b/openpilot/tools/scripts/get_fingerprint.py similarity index 100% rename from tools/scripts/get_fingerprint.py rename to openpilot/tools/scripts/get_fingerprint.py diff --git a/tools/scripts/live_cpu_and_temp.py b/openpilot/tools/scripts/live_cpu_and_temp.py similarity index 100% rename from tools/scripts/live_cpu_and_temp.py rename to openpilot/tools/scripts/live_cpu_and_temp.py diff --git a/tools/scripts/mem_usage.py b/openpilot/tools/scripts/mem_usage.py similarity index 100% rename from tools/scripts/mem_usage.py rename to openpilot/tools/scripts/mem_usage.py diff --git a/tools/scripts/print_flags.py b/openpilot/tools/scripts/print_flags.py similarity index 100% rename from tools/scripts/print_flags.py rename to openpilot/tools/scripts/print_flags.py diff --git a/tools/scripts/profiling/clpeak/.gitignore b/openpilot/tools/scripts/profiling/clpeak/.gitignore similarity index 100% rename from tools/scripts/profiling/clpeak/.gitignore rename to openpilot/tools/scripts/profiling/clpeak/.gitignore diff --git a/tools/scripts/profiling/clpeak/build.sh b/openpilot/tools/scripts/profiling/clpeak/build.sh similarity index 100% rename from tools/scripts/profiling/clpeak/build.sh rename to openpilot/tools/scripts/profiling/clpeak/build.sh diff --git a/tools/scripts/profiling/clpeak/no_print.patch b/openpilot/tools/scripts/profiling/clpeak/no_print.patch similarity index 100% rename from tools/scripts/profiling/clpeak/no_print.patch rename to openpilot/tools/scripts/profiling/clpeak/no_print.patch diff --git a/tools/scripts/profiling/clpeak/run_continuously.patch b/openpilot/tools/scripts/profiling/clpeak/run_continuously.patch similarity index 100% rename from tools/scripts/profiling/clpeak/run_continuously.patch rename to openpilot/tools/scripts/profiling/clpeak/run_continuously.patch diff --git a/tools/scripts/profiling/ftrace.sh b/openpilot/tools/scripts/profiling/ftrace.sh similarity index 100% rename from tools/scripts/profiling/ftrace.sh rename to openpilot/tools/scripts/profiling/ftrace.sh diff --git a/tools/scripts/profiling/palanteer/.gitignore b/openpilot/tools/scripts/profiling/palanteer/.gitignore similarity index 100% rename from tools/scripts/profiling/palanteer/.gitignore rename to openpilot/tools/scripts/profiling/palanteer/.gitignore diff --git a/tools/scripts/profiling/palanteer/setup.sh b/openpilot/tools/scripts/profiling/palanteer/setup.sh similarity index 100% rename from tools/scripts/profiling/palanteer/setup.sh rename to openpilot/tools/scripts/profiling/palanteer/setup.sh diff --git a/tools/scripts/profiling/perfetto/.gitignore b/openpilot/tools/scripts/profiling/perfetto/.gitignore similarity index 100% rename from tools/scripts/profiling/perfetto/.gitignore rename to openpilot/tools/scripts/profiling/perfetto/.gitignore diff --git a/tools/scripts/profiling/perfetto/build.sh b/openpilot/tools/scripts/profiling/perfetto/build.sh similarity index 100% rename from tools/scripts/profiling/perfetto/build.sh rename to openpilot/tools/scripts/profiling/perfetto/build.sh diff --git a/tools/scripts/profiling/perfetto/copy.sh b/openpilot/tools/scripts/profiling/perfetto/copy.sh similarity index 100% rename from tools/scripts/profiling/perfetto/copy.sh rename to openpilot/tools/scripts/profiling/perfetto/copy.sh diff --git a/tools/scripts/profiling/perfetto/record.sh b/openpilot/tools/scripts/profiling/perfetto/record.sh similarity index 100% rename from tools/scripts/profiling/perfetto/record.sh rename to openpilot/tools/scripts/profiling/perfetto/record.sh diff --git a/tools/scripts/profiling/perfetto/server.sh b/openpilot/tools/scripts/profiling/perfetto/server.sh similarity index 100% rename from tools/scripts/profiling/perfetto/server.sh rename to openpilot/tools/scripts/profiling/perfetto/server.sh diff --git a/tools/scripts/profiling/perfetto/traces.sh b/openpilot/tools/scripts/profiling/perfetto/traces.sh similarity index 100% rename from tools/scripts/profiling/perfetto/traces.sh rename to openpilot/tools/scripts/profiling/perfetto/traces.sh diff --git a/tools/scripts/profiling/py-spy/profile.sh b/openpilot/tools/scripts/profiling/py-spy/profile.sh similarity index 100% rename from tools/scripts/profiling/py-spy/profile.sh rename to openpilot/tools/scripts/profiling/py-spy/profile.sh diff --git a/tools/scripts/profiling/snapdragon/.gitignore b/openpilot/tools/scripts/profiling/snapdragon/.gitignore similarity index 100% rename from tools/scripts/profiling/snapdragon/.gitignore rename to openpilot/tools/scripts/profiling/snapdragon/.gitignore diff --git a/tools/scripts/profiling/snapdragon/README.md b/openpilot/tools/scripts/profiling/snapdragon/README.md similarity index 100% rename from tools/scripts/profiling/snapdragon/README.md rename to openpilot/tools/scripts/profiling/snapdragon/README.md diff --git a/tools/scripts/profiling/snapdragon/setup-agnos.sh b/openpilot/tools/scripts/profiling/snapdragon/setup-agnos.sh similarity index 100% rename from tools/scripts/profiling/snapdragon/setup-agnos.sh rename to openpilot/tools/scripts/profiling/snapdragon/setup-agnos.sh diff --git a/tools/scripts/profiling/snapdragon/setup-profiler.sh b/openpilot/tools/scripts/profiling/snapdragon/setup-profiler.sh similarity index 100% rename from tools/scripts/profiling/snapdragon/setup-profiler.sh rename to openpilot/tools/scripts/profiling/snapdragon/setup-profiler.sh diff --git a/tools/scripts/profiling/watch-irqs.sh b/openpilot/tools/scripts/profiling/watch-irqs.sh similarity index 100% rename from tools/scripts/profiling/watch-irqs.sh rename to openpilot/tools/scripts/profiling/watch-irqs.sh diff --git a/tools/scripts/qlog_size.py b/openpilot/tools/scripts/qlog_size.py similarity index 100% rename from tools/scripts/qlog_size.py rename to openpilot/tools/scripts/qlog_size.py diff --git a/tools/scripts/run_process_on_route.py b/openpilot/tools/scripts/run_process_on_route.py similarity index 100% rename from tools/scripts/run_process_on_route.py rename to openpilot/tools/scripts/run_process_on_route.py diff --git a/tools/scripts/serial.sh b/openpilot/tools/scripts/serial.sh similarity index 100% rename from tools/scripts/serial.sh rename to openpilot/tools/scripts/serial.sh diff --git a/tools/scripts/set_car_params.py b/openpilot/tools/scripts/set_car_params.py similarity index 100% rename from tools/scripts/set_car_params.py rename to openpilot/tools/scripts/set_car_params.py diff --git a/tools/scripts/setup_ssh_keys.py b/openpilot/tools/scripts/setup_ssh_keys.py similarity index 100% rename from tools/scripts/setup_ssh_keys.py rename to openpilot/tools/scripts/setup_ssh_keys.py diff --git a/tools/scripts/ssh.py b/openpilot/tools/scripts/ssh.py similarity index 100% rename from tools/scripts/ssh.py rename to openpilot/tools/scripts/ssh.py diff --git a/tools/scripts/test_fw_query_on_routes.py b/openpilot/tools/scripts/test_fw_query_on_routes.py similarity index 100% rename from tools/scripts/test_fw_query_on_routes.py rename to openpilot/tools/scripts/test_fw_query_on_routes.py diff --git a/tools/scripts/uiview.py b/openpilot/tools/scripts/uiview.py similarity index 100% rename from tools/scripts/uiview.py rename to openpilot/tools/scripts/uiview.py diff --git a/tools/scripts/watch_timings.py b/openpilot/tools/scripts/watch_timings.py similarity index 100% rename from tools/scripts/watch_timings.py rename to openpilot/tools/scripts/watch_timings.py diff --git a/tools/setup.sh b/openpilot/tools/setup.sh similarity index 100% rename from tools/setup.sh rename to openpilot/tools/setup.sh diff --git a/tools/setup_dependencies.sh b/openpilot/tools/setup_dependencies.sh similarity index 100% rename from tools/setup_dependencies.sh rename to openpilot/tools/setup_dependencies.sh diff --git a/tools/sim/README.md b/openpilot/tools/sim/README.md similarity index 100% rename from tools/sim/README.md rename to openpilot/tools/sim/README.md diff --git a/tools/sim/__init__.py b/openpilot/tools/sim/__init__.py similarity index 100% rename from tools/sim/__init__.py rename to openpilot/tools/sim/__init__.py diff --git a/tools/sim/bridge/__init__.py b/openpilot/tools/sim/bridge/__init__.py similarity index 100% rename from tools/sim/bridge/__init__.py rename to openpilot/tools/sim/bridge/__init__.py diff --git a/tools/sim/bridge/common.py b/openpilot/tools/sim/bridge/common.py similarity index 100% rename from tools/sim/bridge/common.py rename to openpilot/tools/sim/bridge/common.py diff --git a/tools/sim/bridge/metadrive/metadrive_bridge.py b/openpilot/tools/sim/bridge/metadrive/metadrive_bridge.py similarity index 100% rename from tools/sim/bridge/metadrive/metadrive_bridge.py rename to openpilot/tools/sim/bridge/metadrive/metadrive_bridge.py diff --git a/tools/sim/bridge/metadrive/metadrive_common.py b/openpilot/tools/sim/bridge/metadrive/metadrive_common.py similarity index 100% rename from tools/sim/bridge/metadrive/metadrive_common.py rename to openpilot/tools/sim/bridge/metadrive/metadrive_common.py diff --git a/tools/sim/bridge/metadrive/metadrive_process.py b/openpilot/tools/sim/bridge/metadrive/metadrive_process.py similarity index 100% rename from tools/sim/bridge/metadrive/metadrive_process.py rename to openpilot/tools/sim/bridge/metadrive/metadrive_process.py diff --git a/tools/sim/bridge/metadrive/metadrive_world.py b/openpilot/tools/sim/bridge/metadrive/metadrive_world.py similarity index 100% rename from tools/sim/bridge/metadrive/metadrive_world.py rename to openpilot/tools/sim/bridge/metadrive/metadrive_world.py diff --git a/tools/sim/launch_openpilot.sh b/openpilot/tools/sim/launch_openpilot.sh similarity index 100% rename from tools/sim/launch_openpilot.sh rename to openpilot/tools/sim/launch_openpilot.sh diff --git a/tools/sim/lib/__init__.py b/openpilot/tools/sim/lib/__init__.py similarity index 100% rename from tools/sim/lib/__init__.py rename to openpilot/tools/sim/lib/__init__.py diff --git a/tools/sim/lib/camerad.py b/openpilot/tools/sim/lib/camerad.py similarity index 100% rename from tools/sim/lib/camerad.py rename to openpilot/tools/sim/lib/camerad.py diff --git a/tools/sim/lib/common.py b/openpilot/tools/sim/lib/common.py similarity index 100% rename from tools/sim/lib/common.py rename to openpilot/tools/sim/lib/common.py diff --git a/tools/sim/lib/keyboard_ctrl.py b/openpilot/tools/sim/lib/keyboard_ctrl.py similarity index 100% rename from tools/sim/lib/keyboard_ctrl.py rename to openpilot/tools/sim/lib/keyboard_ctrl.py diff --git a/tools/sim/lib/manual_ctrl.py b/openpilot/tools/sim/lib/manual_ctrl.py similarity index 100% rename from tools/sim/lib/manual_ctrl.py rename to openpilot/tools/sim/lib/manual_ctrl.py diff --git a/tools/sim/lib/simulated_car.py b/openpilot/tools/sim/lib/simulated_car.py similarity index 100% rename from tools/sim/lib/simulated_car.py rename to openpilot/tools/sim/lib/simulated_car.py diff --git a/tools/sim/lib/simulated_sensors.py b/openpilot/tools/sim/lib/simulated_sensors.py similarity index 100% rename from tools/sim/lib/simulated_sensors.py rename to openpilot/tools/sim/lib/simulated_sensors.py diff --git a/tools/sim/run_bridge.py b/openpilot/tools/sim/run_bridge.py similarity index 100% rename from tools/sim/run_bridge.py rename to openpilot/tools/sim/run_bridge.py diff --git a/tools/sim/tests/__init__.py b/openpilot/tools/sim/tests/__init__.py similarity index 100% rename from tools/sim/tests/__init__.py rename to openpilot/tools/sim/tests/__init__.py diff --git a/tools/sim/tests/conftest.py b/openpilot/tools/sim/tests/conftest.py similarity index 100% rename from tools/sim/tests/conftest.py rename to openpilot/tools/sim/tests/conftest.py diff --git a/tools/sim/tests/test_metadrive_bridge.py b/openpilot/tools/sim/tests/test_metadrive_bridge.py similarity index 100% rename from tools/sim/tests/test_metadrive_bridge.py rename to openpilot/tools/sim/tests/test_metadrive_bridge.py diff --git a/tools/sim/tests/test_sim_bridge.py b/openpilot/tools/sim/tests/test_sim_bridge.py similarity index 100% rename from tools/sim/tests/test_sim_bridge.py rename to openpilot/tools/sim/tests/test_sim_bridge.py diff --git a/pyproject.toml b/pyproject.toml index 8cff68a176..b844145a4a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -149,7 +149,7 @@ quiet-level = 3 # if you've got a short variable name that's getting flagged, add it here ignore-words-list = "bu,ro,te,ue,alo,hda,ois,nam,nams,ned,som,parm,setts,inout,warmup,bumb,nd,sie,preints,whit,indexIn,ws,uint,grey,deque,stdio,amin,BA,LITE,atEnd,UIs,errorString,arange,FocusIn,od,tim,relA,hist,copyable,jupyter,thead,TGE,abl,lite,ser" builtin = "clear,rare,informal,code,names,en-GB_to_en-US" -skip = "*.po, uv.lock, *.onnx, *.pem, */c_generated_code/*, docs/assets/*, tools/plotjuggler/layouts/*, openpilot/tools/plotjuggler/layouts/*, selfdrive/assets/offroad/mici_fcc.html, openpilot/selfdrive/assets/offroad/mici_fcc.html" +skip = "*.po, uv.lock, *.onnx, *.pem, */c_generated_code/*, docs/assets/*, openpilot/tools/plotjuggler/layouts/*, openpilot/selfdrive/assets/offroad/mici_fcc.html" # https://docs.astral.sh/ruff/configuration/#using-pyprojecttoml [tool.ruff] diff --git a/scripts/lint/lint.sh b/scripts/lint/lint.sh index 77d29e7092..e01e7b37c2 100755 --- a/scripts/lint/lint.sh +++ b/scripts/lint/lint.sh @@ -102,7 +102,7 @@ done RUN=$([ -z "$RUN" ] && echo "" || echo "!($(echo $RUN | sed 's/ /|/g'))") SKIP="@($(echo $SKIP | sed 's/ /|/g'))" -GIT_FILES="$(git ls-files openpilot common selfdrive system tools)" +GIT_FILES="$(git ls-files openpilot)" ALL_FILES="" for f in $GIT_FILES; do if [[ -f $f ]]; then From 8a9ca15464d9c2e51e6700e55d1d2755ccd9a0be Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Sun, 21 Jun 2026 19:17:01 -0700 Subject: [PATCH 077/151] cleanup leftovers from the shuffling (#38224) * cleanup leftovers * rm * one more --- .vscode/launch.json | 8 ++++---- .vscode/settings.json | 5 ----- docs/concepts/logs.md | 2 +- openpilot/tools/CTF.md | 2 +- openpilot/tools/jotpluggler/app.cc | 4 ++-- openpilot/tools/jotpluggler/custom_series.cc | 2 +- openpilot/tools/jotpluggler/layout.cc | 4 ++-- openpilot/tools/jotpluggler/sketch_layout.cc | 4 ++-- pyproject.toml | 4 ---- 9 files changed, 13 insertions(+), 22 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 151b757dab..5a052a112a 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -6,9 +6,9 @@ "type": "pickString", "description": "Select the process to debug", "options": [ - "selfdrive/controls/controlsd.py", - "system/timed/timed.py", - "tools/sim/run_bridge.py" + "openpilot/selfdrive/controls/controlsd.py", + "openpilot/system/timed/timed.py", + "openpilot/tools/sim/run_bridge.py" ] }, { @@ -16,7 +16,7 @@ "type": "pickString", "description": "Select the process to debug", "options": [ - "selfdrive/ui/ui" + "openpilot/selfdrive/ui/ui" ] }, { diff --git a/.vscode/settings.json b/.vscode/settings.json index 811306f399..68f6b90371 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -17,10 +17,5 @@ "**/.git", "**/.venv", "**/__pycache__", - // exclude directories that should be using the symlinked version - "common/**", - "selfdrive/**", - "system/**", - "tools/**", ] } diff --git a/docs/concepts/logs.md b/docs/concepts/logs.md index 8ba2486ab5..dd954d4c76 100644 --- a/docs/concepts/logs.md +++ b/docs/concepts/logs.md @@ -2,7 +2,7 @@ openpilot records routes in one minute chunks called segments. A route starts on the rising edge of ignition and ends on the falling edge. -Check out our [Python library](https://github.com/commaai/openpilot/blob/master/openpilot/tools/lib/logreader.py) for reading openpilot logs. Also checkout our [tools](https://github.com/commaai/openpilot/tree/master/tools) to replay and view your data. These are the same tools we use to debug and develop openpilot. +Check out our [Python library](https://github.com/commaai/openpilot/blob/master/openpilot/tools/lib/logreader.py) for reading openpilot logs. Also checkout our [tools](https://github.com/commaai/openpilot/tree/master/openpilot/tools) to replay and view your data. These are the same tools we use to debug and develop openpilot. For each segment, openpilot records the following log types: diff --git a/openpilot/tools/CTF.md b/openpilot/tools/CTF.md index b8acc46fef..2b877a0e25 100644 --- a/openpilot/tools/CTF.md +++ b/openpilot/tools/CTF.md @@ -5,7 +5,7 @@ Welcome to the first part of the comma CTF! * there's 2 flags in each segment, with roughly increasing difficulty * everything you'll need to find the flags is in the openpilot repo * grep is also your friend - * first, [setup](https://github.com/commaai/openpilot/tree/master/tools#setup-your-pc) your PC + * first, [setup](https://github.com/commaai/openpilot/tree/master/openpilot/tools#setup-your-pc) your PC * read the docs & checkout out the tools in openpilot/tools/ * tip: once you get the replay and UI up, start by familiarizing yourself with seeking in replay diff --git a/openpilot/tools/jotpluggler/app.cc b/openpilot/tools/jotpluggler/app.cc index f80443e569..01eec15367 100644 --- a/openpilot/tools/jotpluggler/app.cc +++ b/openpilot/tools/jotpluggler/app.cc @@ -49,7 +49,7 @@ std::string layout_name_from_arg(const std::string &layout_arg) { } fs::path layouts_dir() { - return repo_root() / "tools" / "jotpluggler" / "layouts"; + return repo_root() / "openpilot" / "tools" / "jotpluggler" / "layouts"; } std::string sanitize_layout_stem(std::string_view name) { @@ -249,7 +249,7 @@ void configure_style() { g_ui_font = nullptr; g_ui_bold_font = nullptr; g_mono_font = nullptr; - const fs::path fonts_dir = repo_root() / "selfdrive" / "assets" / "fonts"; + const fs::path fonts_dir = repo_root() / "openpilot" / "selfdrive" / "assets" / "fonts"; ImFontConfig font_cfg; font_cfg.OversampleH = 2; font_cfg.OversampleV = 2; diff --git a/openpilot/tools/jotpluggler/custom_series.cc b/openpilot/tools/jotpluggler/custom_series.cc index aabf78a0db..70b3e8c3cb 100644 --- a/openpilot/tools/jotpluggler/custom_series.cc +++ b/openpilot/tools/jotpluggler/custom_series.cc @@ -189,7 +189,7 @@ PythonEvalResult evaluate_custom_python_series(const AppSession &session, const CommandResult process = run_process_capture_output({ "python3", - (repo_root() / "tools" / "jotpluggler" / "math_eval.py").string(), + (repo_root() / "openpilot" / "tools" / "jotpluggler" / "math_eval.py").string(), manifest_path.string(), globals_path.string(), code_path.string(), diff --git a/openpilot/tools/jotpluggler/layout.cc b/openpilot/tools/jotpluggler/layout.cc index bf2a3f208c..dc7109808a 100644 --- a/openpilot/tools/jotpluggler/layout.cc +++ b/openpilot/tools/jotpluggler/layout.cc @@ -274,7 +274,7 @@ std::string default_dbc_template() { } DbcEditorSource resolve_dbc_editor_source(const std::string &dbc_name) { - const fs::path generated_dbc_dir = repo_root() / "tools" / "jotpluggler" / "generated_dbcs"; + const fs::path generated_dbc_dir = repo_root() / "openpilot" / "tools" / "jotpluggler" / "generated_dbcs"; const std::array candidates = {{ {.path = repo_root() / "opendbc" / "dbc" / (dbc_name + ".dbc"), .kind = DbcEditorState::SourceKind::Opendbc}, {.path = generated_dbc_dir / (dbc_name + ".dbc"), .kind = DbcEditorState::SourceKind::Generated}, @@ -334,7 +334,7 @@ bool save_dbc_editor_contents(AppSession *session, UiState *state) { } try { dbc::Database::fromContent(editor.text, editor.save_name + ".dbc"); - const fs::path generated_dbc_dir = repo_root() / "tools" / "jotpluggler" / "generated_dbcs"; + const fs::path generated_dbc_dir = repo_root() / "openpilot" / "tools" / "jotpluggler" / "generated_dbcs"; fs::create_directories(generated_dbc_dir); const fs::path output = generated_dbc_dir / (editor.save_name + ".dbc"); write_file_or_throw(output, editor.text); diff --git a/openpilot/tools/jotpluggler/sketch_layout.cc b/openpilot/tools/jotpluggler/sketch_layout.cc index 143a6f5a1d..fcc4b183d0 100644 --- a/openpilot/tools/jotpluggler/sketch_layout.cc +++ b/openpilot/tools/jotpluggler/sketch_layout.cc @@ -386,7 +386,7 @@ std::vector available_dbc_names_impl() { std::set names; for (const fs::path &dbc_dir : { repo_root() / "opendbc" / "dbc", - repo_root() / "tools" / "jotpluggler" / "generated_dbcs", + repo_root() / "openpilot" / "tools" / "jotpluggler" / "generated_dbcs", }) { if (fs::exists(dbc_dir) && fs::is_directory(dbc_dir)) { for (const auto &entry : fs::directory_iterator(dbc_dir)) { @@ -408,7 +408,7 @@ std::vector available_dbc_names_impl() { fs::path resolve_dbc_path(const std::string &dbc_name) { for (const fs::path &candidate : { repo_root() / "opendbc" / "dbc" / (dbc_name + ".dbc"), - repo_root() / "tools" / "jotpluggler" / "generated_dbcs" / (dbc_name + ".dbc"), + repo_root() / "openpilot" / "tools" / "jotpluggler" / "generated_dbcs" / (dbc_name + ".dbc"), }) { if (fs::exists(candidate)) return candidate; } diff --git a/pyproject.toml b/pyproject.toml index b844145a4a..54f67d6299 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -182,10 +182,6 @@ exclude = [ lint.flake8-implicit-str-concat.allow-multiline = false [tool.ruff.lint.flake8-tidy-imports.banned-api] -"selfdrive".msg = "Use openpilot.selfdrive" -"common".msg = "Use openpilot.common" -"system".msg = "Use openpilot.system" -"tools".msg = "Use openpilot.tools" "pytest.main".msg = "pytest.main requires special handling that is easy to mess up!" "unittest".msg = "Use pytest" "time.time".msg = "Use time.monotonic" From 2e9fa514bb77df3a2a06012a6fe7bef99d07f66e Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Sun, 21 Jun 2026 19:39:21 -0700 Subject: [PATCH 078/151] simple pip install test (#38218) * fails * lil more * try that --- pyproject.toml | 10 +++++++++- scripts/test_pip_install.sh | 22 ++++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) create mode 100755 scripts/test_pip_install.sh diff --git a/pyproject.toml b/pyproject.toml index 54f67d6299..15efc934fe 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -121,7 +121,15 @@ requires = ["hatchling"] build-backend = "hatchling.build" [tool.hatch.build.targets.wheel] -packages = [ "." ] +packages = [ + "openpilot", + "msgq", + "opendbc", + "panda", + "rednose", + "teleoprtc", + "tinygrad", +] [tool.hatch.metadata] allow-direct-references = true diff --git a/scripts/test_pip_install.sh b/scripts/test_pip_install.sh new file mode 100755 index 0000000000..d2dbedff0a --- /dev/null +++ b/scripts/test_pip_install.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env bash +set -euxo pipefail + +SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)" +REPO_ROOT="$(git -C "$SCRIPT_DIR/.." rev-parse --show-toplevel)" +PYTHON_VERSION="$(cat "$REPO_ROOT/.python-version")" +PACKAGE="${1:-$REPO_ROOT}" + +TMPDIR="$(mktemp -d)" +trap 'rm -rf "$TMPDIR"' EXIT + +cd "$TMPDIR" + +uv venv --python "$PYTHON_VERSION" +source .venv/bin/activate +uv pip install "$PACKAGE" +python3 - <<'PY' +from openpilot.tools.lib.logreader import LogReader + +assert LogReader.__name__ == "LogReader" +print("ok: imported LogReader") +PY From 1474d5474dcee0d7300aa521b5e75491729cfcd3 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Mon, 22 Jun 2026 09:45:00 -0700 Subject: [PATCH 079/151] move root include to the end to prevent using stale build products --- SConstruct | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SConstruct b/SConstruct index 2e4002f1f2..031984bf4c 100644 --- a/SConstruct +++ b/SConstruct @@ -112,12 +112,12 @@ env = Environment( CFLAGS=["-std=gnu11"], CXXFLAGS=["-std=c++1z"], CPPPATH=[ - "#", "#openpilot", "#msgq", "#openpilot/cereal/gen/cpp", acados_include_dirs, [x.INCLUDE_DIR for x in pkgs], + "#", ], LIBPATH=[ "#openpilot/common", From cddb6103eb9ea741df1ec8c3c1a38b447ad0be82 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Mon, 22 Jun 2026 14:25:19 -0700 Subject: [PATCH 080/151] webrtc: replace aiohttp with stdlib http server (#38226) * webrtc: replace aiohttp with stdlib http server * lil more * simplify * remove aiohttp error response helper --------- Co-authored-by: stefpi <19478336+stefpi@users.noreply.github.com> --- openpilot/system/webrtc/webrtcd.py | 211 ++++++++++++++++++++++------- pyproject.toml | 1 - uv.lock | 167 ----------------------- 3 files changed, 164 insertions(+), 215 deletions(-) diff --git a/openpilot/system/webrtc/webrtcd.py b/openpilot/system/webrtc/webrtcd.py index 72d949f551..bf96cd04ba 100755 --- a/openpilot/system/webrtc/webrtcd.py +++ b/openpilot/system/webrtc/webrtcd.py @@ -10,6 +10,10 @@ import contextlib import json import uuid import logging +import signal +import threading +from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer +from urllib.parse import urlparse, parse_qs from typing import Any, TYPE_CHECKING # aiortc and its dependencies have lots of internal warnings :( @@ -18,7 +22,6 @@ warnings.filterwarnings("ignore", category=DeprecationWarning) warnings.filterwarnings("ignore", category=RuntimeWarning) # TODO: remove this when google-crc32c publish a python3.12 wheel import capnp -from aiohttp import web if TYPE_CHECKING: from aiortc.rtcdatachannel import RTCDataChannel import aioice.ice @@ -363,27 +366,43 @@ class StreamSession: await self.stream.stop() -def schedule_teardown(app): - # if nothing connects for 5 seconds, tear down livestreaming processes - h = app.get('teardown') - if h: - h.cancel() +class ServerState: + def __init__(self, debug: bool): + self.streams: dict[str, StreamSession] = {} + self.stream_lock = asyncio.Lock() + self.debug = debug + self.teardown: asyncio.TimerHandle | None = None + + +# if nothing connects for 5 seconds, tear down livestreaming processes +def schedule_teardown(state: ServerState): + if state.teardown is not None: + state.teardown.cancel() + def clear(): - if not app['streams']: - Params().put_bool("IsLiveStreaming", False) - app['teardown'] = asyncio.get_running_loop().call_later(5.0, clear) + if not state.streams: + Params().put_bool("IsLiveStreaming", False) + + state.teardown = asyncio.get_running_loop().call_later(5.0, clear) -async def get_stream(request: 'web.Request'): - stream_dict, debug_mode = request.app['streams'], request.app['debug'] - raw_body = await request.json() - body = StreamRequestBody(**raw_body) +def _json_response(obj: Any, status: int = 200) -> tuple[int, bytes, str]: + return (status, json.dumps(obj).encode(), "application/json; charset=utf-8") - async with request.app['stream_lock']: + +def _text_response(text: str, status: int = 200) -> tuple[int, bytes, str]: + return (status, text.encode(), "text/plain; charset=utf-8") + + +async def handle_get_stream(state: ServerState, raw_body: bytes) -> tuple[int, bytes, str]: + stream_dict, debug_mode = state.streams, state.debug + body = StreamRequestBody(**json.loads(raw_body)) + + async with state.stream_lock: # don't remove existing connection on prewarm request enabled = any(s.run_task and not s.run_task.done() and s.enabled for s in stream_dict.values()) if enabled and not body.enabled: - return web.json_response({"error": "busy", "message": "someone else is connected."}) + return _json_response({"error": "busy", "message": "someone else is connected."}) for sid, s in list(stream_dict.items()): if s.run_task and not s.run_task.done(): @@ -408,54 +427,134 @@ async def get_stream(request: 'web.Request'): def remove_finished_session(_: asyncio.Task) -> None: stream_dict.pop(session.identifier, None) - schedule_teardown(request.app) + schedule_teardown(state) + session.run_task.add_done_callback(remove_finished_session) - return web.json_response({"sdp": answer.sdp, "type": answer.type}) + return _json_response({"sdp": answer.sdp, "type": answer.type}) -async def get_schema(request: 'web.Request'): - services = request.query.get("services", "").split(",") +async def handle_get_schema(state: ServerState, services_param: str) -> tuple[int, bytes, str]: + services = services_param.split(",") services = [s for s in services if s] assert all(s in log.Event.schema.fields and not s.endswith("DEPRECATED") for s in services), "Invalid service name" schema_dict = {s: generate_field(log.Event.schema.fields[s]) for s in services} - return web.json_response(schema_dict) + return _json_response(schema_dict) -async def post_notify(request: 'web.Request'): - try: - payload = await request.json() - except Exception as e: - raise web.HTTPBadRequest(text="Invalid JSON") from e - - for session in list(request.app.get('streams', {}).values()): +async def handle_post_notify(state: ServerState, payload: Any) -> tuple[int, bytes, str]: + for session in list(state.streams.values()): try: ch = session.stream.get_messaging_channel() ch.send(json.dumps(payload)) except Exception: continue - return web.Response(status=200, text="OK") + return _text_response("OK") -async def on_shutdown(app: 'web.Application'): - for session in list(app['streams'].values()): +async def on_shutdown(state: ServerState): + for session in list(state.streams.values()): try: ch = session.stream.get_messaging_channel() ch.send(json.dumps({"type": "disconnect", "data": "device streaming has been stopped."})) except Exception: pass await session.stop() - del app['streams'] + state.streams.clear() -@web.middleware -async def error_middleware(request: 'web.Request', handler): - try: - return await handler(request) - except Exception as e: - logging.getLogger("webrtcd").exception("Unhandled error handling %s", request.path) - return web.json_response({"error": "exception", "message": f"{type(e).__name__}: {e}"}, status=500) +class WebrtcdHandler(BaseHTTPRequestHandler): + protocol_version = "HTTP/1.1" + + # path -> allowed methods (aiohttp registered POST /stream, POST /notify, GET /schema + its auto HEAD) + _routes = { + "/schema": ("GET", "HEAD"), + "/stream": ("POST",), + "/notify": ("POST",), + } + + def _send(self, status: int, body: bytes, content_type: str) -> None: + self.send_response(status) + self.send_header("Content-Type", content_type) + self.send_header("Content-Length", str(len(body))) + self.end_headers() + if self.command != "HEAD": + self.wfile.write(body) + + def _read_body(self) -> bytes: + length = int(self.headers.get("Content-Length", 0)) + return self.rfile.read(length) if length else b"" + + def _run(self, coro) -> tuple[int, bytes, str]: + return asyncio.run_coroutine_threadsafe(coro, self.server.loop).result() + + def _dispatch_request(self) -> None: + parsed = urlparse(self.path) + allowed = self._routes.get(parsed.path) + + try: + if allowed is None: + result = _json_response({"error": "not found"}, status=404) + elif self.command not in allowed: + result = _json_response({"error": "method not allowed"}, status=405) + elif parsed.path == "/schema": + services = parse_qs(parsed.query).get("services", [""])[0] + result = self._run(handle_get_schema(self.server.state, services)) + elif parsed.path == "/stream": + result = self._run(handle_get_stream(self.server.state, self._read_body())) + else: # /notify + try: + payload = json.loads(self._read_body()) + except Exception: + result = _json_response({"error": "bad request"}, status=400) + else: + result = self._run(handle_post_notify(self.server.state, payload)) + except Exception as e: + logging.getLogger("webrtcd").exception("Unhandled error handling %s", self.path) + result = _json_response({"error": "exception", "message": f"{type(e).__name__}: {e}"}, status=500) + + self._send(*result) + + def do_GET(self) -> None: + self._dispatch_request() + + def do_HEAD(self) -> None: + self._dispatch_request() + + def do_POST(self) -> None: + self._dispatch_request() + + def do_PUT(self) -> None: + self._dispatch_request() + + def do_DELETE(self) -> None: + self._dispatch_request() + + def do_PATCH(self) -> None: + self._dispatch_request() + + def do_OPTIONS(self) -> None: + self._dispatch_request() + + def log_message(self, fmt, *args) -> None: + # silence default access logging; errors are logged explicitly in _dispatch_request + pass + + +class WebrtcdHTTPServer(ThreadingHTTPServer): + daemon_threads = True + allow_reuse_address = True + state: ServerState + loop: asyncio.AbstractEventLoop + + +async def _shutdown(server: WebrtcdHTTPServer, state: ServerState, loop: asyncio.AbstractEventLoop) -> None: + # stop accepting new HTTP connections (blocks until serve_forever returns, so + # run it off the loop) then tear down active stream sessions. + await loop.run_in_executor(None, server.shutdown) + await on_shutdown(state) + loop.stop() def prewarm_stream_session_imports(debug_mode: bool = False) -> None: @@ -475,17 +574,35 @@ def webrtcd_thread(host: str, port: int, debug: bool): prewarm_end = time.monotonic() logging.getLogger("webrtcd").info(f"webrtc prewarm finished in {(prewarm_end - prewarm_start) * 1000} ms") - app = web.Application(middlewares=[error_middleware]) + loop = asyncio.new_event_loop() + asyncio.set_event_loop(loop) + state = ServerState(debug) - app['streams'] = dict() - app['stream_lock'] = asyncio.Lock() - app['debug'] = debug - app.on_shutdown.append(on_shutdown) - app.router.add_post("/stream", get_stream) - app.router.add_post("/notify", post_notify) - app.router.add_get("/schema", get_schema) + server = WebrtcdHTTPServer((host, port), WebrtcdHandler) + server.state = state + server.loop = loop - web.run_app(app, host=host, port=port) + # serve HTTP on a daemon thread so the asyncio loop can own the main thread + http_thread = threading.Thread(target=server.serve_forever, name="webrtcd-http", daemon=True) + http_thread.start() + + shutting_down = False + + def request_shutdown() -> None: + nonlocal shutting_down + if shutting_down: + return + shutting_down = True + loop.create_task(_shutdown(server, state, loop)) + + for sig in (signal.SIGINT, signal.SIGTERM): + loop.add_signal_handler(sig, request_shutdown) + + try: + loop.run_forever() + finally: + server.server_close() + loop.close() def main(): diff --git a/pyproject.toml b/pyproject.toml index 15efc934fe..df57623b8a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -46,7 +46,6 @@ dependencies = [ # body / webrtcd "av", - "aiohttp", "aiortc", # panda diff --git a/uv.lock b/uv.lock index e95c49f497..303a99f3bf 100644 --- a/uv.lock +++ b/uv.lock @@ -10,49 +10,6 @@ dependencies = [ { name = "numpy" }, ] -[[package]] -name = "aiohappyeyeballs" -version = "2.6.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/33/c6/61a2d7b7572279226bb2e7f61d7a19ca7c90da0329c93fa0d560cbf288d8/aiohappyeyeballs-2.6.2.tar.gz", hash = "sha256:e202810ee718bd01fc6ef49e8ea53d023d5cb6b581076d7925aa499fa55dbe64", size = 22591, upload-time = "2026-05-20T15:12:24.631Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/5f/fc/a7bf5b6e4e617b45f90f2d9d2a68519c249c81dd4fc2658c7a2a61c4f4b7/aiohappyeyeballs-2.6.2-py3-none-any.whl", hash = "sha256:4708045e2d7a6c6bdf8aafa8ed39649eaf926a4543b54560659129e3365953c4", size = 15062, upload-time = "2026-05-20T15:12:23.328Z" }, -] - -[[package]] -name = "aiohttp" -version = "3.13.5" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "aiohappyeyeballs" }, - { name = "aiosignal" }, - { name = "attrs" }, - { name = "frozenlist" }, - { name = "multidict" }, - { name = "propcache" }, - { name = "yarl" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/77/9a/152096d4808df8e4268befa55fba462f440f14beab85e8ad9bf990516918/aiohttp-3.13.5.tar.gz", hash = "sha256:9d98cc980ecc96be6eb4c1994ce35d28d8b1f5e5208a23b421187d1209dbb7d1", size = 7858271, upload-time = "2026-03-31T22:01:03.343Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/be/6f/353954c29e7dcce7cf00280a02c75f30e133c00793c7a2ed3776d7b2f426/aiohttp-3.13.5-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:023ecba036ddd840b0b19bf195bfae970083fd7024ce1ac22e9bba90464620e9", size = 748876, upload-time = "2026-03-31T21:57:36.319Z" }, - { url = "https://files.pythonhosted.org/packages/f5/1b/428a7c64687b3b2e9cd293186695affc0e1e54a445d0361743b231f11066/aiohttp-3.13.5-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:15c933ad7920b7d9a20de151efcd05a6e38302cbf0e10c9b2acb9a42210a2416", size = 499557, upload-time = "2026-03-31T21:57:38.236Z" }, - { url = "https://files.pythonhosted.org/packages/29/47/7be41556bfbb6917069d6a6634bb7dd5e163ba445b783a90d40f5ac7e3a7/aiohttp-3.13.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ab2899f9fa2f9f741896ebb6fa07c4c883bfa5c7f2ddd8cf2aafa86fa981b2d2", size = 500258, upload-time = "2026-03-31T21:57:39.923Z" }, - { url = "https://files.pythonhosted.org/packages/67/84/c9ecc5828cb0b3695856c07c0a6817a99d51e2473400f705275a2b3d9239/aiohttp-3.13.5-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a60eaa2d440cd4707696b52e40ed3e2b0f73f65be07fd0ef23b6b539c9c0b0b4", size = 1749199, upload-time = "2026-03-31T21:57:41.938Z" }, - { url = "https://files.pythonhosted.org/packages/f0/d3/3c6d610e66b495657622edb6ae7c7fd31b2e9086b4ec50b47897ad6042a9/aiohttp-3.13.5-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:55b3bdd3292283295774ab585160c4004f4f2f203946997f49aac032c84649e9", size = 1721013, upload-time = "2026-03-31T21:57:43.904Z" }, - { url = "https://files.pythonhosted.org/packages/49/a0/24409c12217456df0bae7babe3b014e460b0b38a8e60753d6cb339f6556d/aiohttp-3.13.5-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c2b2355dc094e5f7d45a7bb262fe7207aa0460b37a0d87027dcf21b5d890e7d5", size = 1781501, upload-time = "2026-03-31T21:57:46.285Z" }, - { url = "https://files.pythonhosted.org/packages/98/9d/b65ec649adc5bccc008b0957a9a9c691070aeac4e41cea18559fef49958b/aiohttp-3.13.5-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b38765950832f7d728297689ad78f5f2cf79ff82487131c4d26fe6ceecdc5f8e", size = 1878981, upload-time = "2026-03-31T21:57:48.734Z" }, - { url = "https://files.pythonhosted.org/packages/57/d8/8d44036d7eb7b6a8ec4c5494ea0c8c8b94fbc0ed3991c1a7adf230df03bf/aiohttp-3.13.5-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b18f31b80d5a33661e08c89e202edabf1986e9b49c42b4504371daeaa11b47c1", size = 1767934, upload-time = "2026-03-31T21:57:51.171Z" }, - { url = "https://files.pythonhosted.org/packages/31/04/d3f8211f273356f158e3464e9e45484d3fb8c4ce5eb2f6fe9405c3273983/aiohttp-3.13.5-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:33add2463dde55c4f2d9635c6ab33ce154e5ecf322bd26d09af95c5f81cfa286", size = 1566671, upload-time = "2026-03-31T21:57:53.326Z" }, - { url = "https://files.pythonhosted.org/packages/41/db/073e4ebe00b78e2dfcacff734291651729a62953b48933d765dc513bf798/aiohttp-3.13.5-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:327cc432fdf1356fb4fbc6fe833ad4e9f6aacb71a8acaa5f1855e4b25910e4a9", size = 1705219, upload-time = "2026-03-31T21:57:55.385Z" }, - { url = "https://files.pythonhosted.org/packages/48/45/7dfba71a2f9fd97b15c95c06819de7eb38113d2cdb6319669195a7d64270/aiohttp-3.13.5-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:7c35b0bf0b48a70b4cb4fc5d7bed9b932532728e124874355de1a0af8ec4bc88", size = 1743049, upload-time = "2026-03-31T21:57:57.341Z" }, - { url = "https://files.pythonhosted.org/packages/18/71/901db0061e0f717d226386a7f471bb59b19566f2cae5f0d93874b017271f/aiohttp-3.13.5-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:df23d57718f24badef8656c49743e11a89fd6f5358fa8a7b96e728fda2abf7d3", size = 1749557, upload-time = "2026-03-31T21:57:59.626Z" }, - { url = "https://files.pythonhosted.org/packages/08/d5/41eebd16066e59cd43728fe74bce953d7402f2b4ddfdfef2c0e9f17ca274/aiohttp-3.13.5-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:02e048037a6501a5ec1f6fc9736135aec6eb8a004ce48838cb951c515f32c80b", size = 1558931, upload-time = "2026-03-31T21:58:01.972Z" }, - { url = "https://files.pythonhosted.org/packages/30/e6/4a799798bf05740e66c3a1161079bda7a3dd8e22ca392481d7a7f9af82a6/aiohttp-3.13.5-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:31cebae8b26f8a615d2b546fee45d5ffb76852ae6450e2a03f42c9102260d6fe", size = 1774125, upload-time = "2026-03-31T21:58:04.007Z" }, - { url = "https://files.pythonhosted.org/packages/84/63/7749337c90f92bc2cb18f9560d67aa6258c7060d1397d21529b8004fcf6f/aiohttp-3.13.5-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:888e78eb5ca55a615d285c3c09a7a91b42e9dd6fc699b166ebd5dee87c9ccf14", size = 1732427, upload-time = "2026-03-31T21:58:06.337Z" }, - { url = "https://files.pythonhosted.org/packages/98/de/cf2f44ff98d307e72fb97d5f5bbae3bfcb442f0ea9790c0bf5c5c2331404/aiohttp-3.13.5-cp312-cp312-win32.whl", hash = "sha256:8bd3ec6376e68a41f9f95f5ed170e2fcf22d4eb27a1f8cb361d0508f6e0557f3", size = 433534, upload-time = "2026-03-31T21:58:08.712Z" }, - { url = "https://files.pythonhosted.org/packages/aa/ca/eadf6f9c8fa5e31d40993e3db153fb5ed0b11008ad5d9de98a95045bed84/aiohttp-3.13.5-cp312-cp312-win_amd64.whl", hash = "sha256:110e448e02c729bcebb18c60b9214a87ba33bac4a9fa5e9a5f139938b56c6cb1", size = 460446, upload-time = "2026-03-31T21:58:10.945Z" }, -] - [[package]] name = "aioice" version = "0.10.2" @@ -84,19 +41,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/57/ab/31646a49209568cde3b97eeade0d28bb78b400e6645c56422c101df68932/aiortc-1.14.0-py3-none-any.whl", hash = "sha256:4b244d7e482f4e1f67e685b3468269628eca1ec91fa5b329ab517738cfca086e", size = 93183, upload-time = "2025-10-13T21:40:36.59Z" }, ] -[[package]] -name = "aiosignal" -version = "1.4.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "frozenlist" }, - { name = "typing-extensions" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/61/62/06741b579156360248d1ec624842ad0edf697050bbaf7c3e46394e106ad1/aiosignal-1.4.0.tar.gz", hash = "sha256:f47eecd9468083c2029cc99945502cb7708b082c232f9aca65da147157b251c7", size = 25007, upload-time = "2025-07-03T22:54:43.528Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl", hash = "sha256:053243f8b92b990551949e63930a839ff0cf0b0ebbe0597b0f3fb19e1a0fe82e", size = 7490, upload-time = "2025-07-03T22:54:42.156Z" }, -] - [[package]] name = "attrs" version = "26.1.0" @@ -414,31 +358,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/2c/47/c99d5268f354002ce80f8d029cd9d7d872969da1de8b93d32de4dc56d6f4/fonttools-4.63.0-py3-none-any.whl", hash = "sha256:445af2eab030a16b9171ea8bdda7ebf7d96bda2df88ee182a464252f6e05e20d", size = 1164562, upload-time = "2026-05-14T12:04:29.092Z" }, ] -[[package]] -name = "frozenlist" -version = "1.8.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/2d/f5/c831fac6cc817d26fd54c7eaccd04ef7e0288806943f7cc5bbf69f3ac1f0/frozenlist-1.8.0.tar.gz", hash = "sha256:3ede829ed8d842f6cd48fc7081d7a41001a56f1f38603f9d49bf3020d59a31ad", size = 45875, upload-time = "2025-10-06T05:38:17.865Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/69/29/948b9aa87e75820a38650af445d2ef2b6b8a6fab1a23b6bb9e4ef0be2d59/frozenlist-1.8.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:78f7b9e5d6f2fdb88cdde9440dc147259b62b9d3b019924def9f6478be254ac1", size = 87782, upload-time = "2025-10-06T05:36:06.649Z" }, - { url = "https://files.pythonhosted.org/packages/64/80/4f6e318ee2a7c0750ed724fa33a4bdf1eacdc5a39a7a24e818a773cd91af/frozenlist-1.8.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:229bf37d2e4acdaf808fd3f06e854a4a7a3661e871b10dc1f8f1896a3b05f18b", size = 50594, upload-time = "2025-10-06T05:36:07.69Z" }, - { url = "https://files.pythonhosted.org/packages/2b/94/5c8a2b50a496b11dd519f4a24cb5496cf125681dd99e94c604ccdea9419a/frozenlist-1.8.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f833670942247a14eafbb675458b4e61c82e002a148f49e68257b79296e865c4", size = 50448, upload-time = "2025-10-06T05:36:08.78Z" }, - { url = "https://files.pythonhosted.org/packages/6a/bd/d91c5e39f490a49df14320f4e8c80161cfcce09f1e2cde1edd16a551abb3/frozenlist-1.8.0-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:494a5952b1c597ba44e0e78113a7266e656b9794eec897b19ead706bd7074383", size = 242411, upload-time = "2025-10-06T05:36:09.801Z" }, - { url = "https://files.pythonhosted.org/packages/8f/83/f61505a05109ef3293dfb1ff594d13d64a2324ac3482be2cedc2be818256/frozenlist-1.8.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:96f423a119f4777a4a056b66ce11527366a8bb92f54e541ade21f2374433f6d4", size = 243014, upload-time = "2025-10-06T05:36:11.394Z" }, - { url = "https://files.pythonhosted.org/packages/d8/cb/cb6c7b0f7d4023ddda30cf56b8b17494eb3a79e3fda666bf735f63118b35/frozenlist-1.8.0-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3462dd9475af2025c31cc61be6652dfa25cbfb56cbbf52f4ccfe029f38decaf8", size = 234909, upload-time = "2025-10-06T05:36:12.598Z" }, - { url = "https://files.pythonhosted.org/packages/31/c5/cd7a1f3b8b34af009fb17d4123c5a778b44ae2804e3ad6b86204255f9ec5/frozenlist-1.8.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c4c800524c9cd9bac5166cd6f55285957fcfc907db323e193f2afcd4d9abd69b", size = 250049, upload-time = "2025-10-06T05:36:14.065Z" }, - { url = "https://files.pythonhosted.org/packages/c0/01/2f95d3b416c584a1e7f0e1d6d31998c4a795f7544069ee2e0962a4b60740/frozenlist-1.8.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d6a5df73acd3399d893dafc71663ad22534b5aa4f94e8a2fabfe856c3c1b6a52", size = 256485, upload-time = "2025-10-06T05:36:15.39Z" }, - { url = "https://files.pythonhosted.org/packages/ce/03/024bf7720b3abaebcff6d0793d73c154237b85bdf67b7ed55e5e9596dc9a/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:405e8fe955c2280ce66428b3ca55e12b3c4e9c336fb2103a4937e891c69a4a29", size = 237619, upload-time = "2025-10-06T05:36:16.558Z" }, - { url = "https://files.pythonhosted.org/packages/69/fa/f8abdfe7d76b731f5d8bd217827cf6764d4f1d9763407e42717b4bed50a0/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:908bd3f6439f2fef9e85031b59fd4f1297af54415fb60e4254a95f75b3cab3f3", size = 250320, upload-time = "2025-10-06T05:36:17.821Z" }, - { url = "https://files.pythonhosted.org/packages/f5/3c/b051329f718b463b22613e269ad72138cc256c540f78a6de89452803a47d/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:294e487f9ec720bd8ffcebc99d575f7eff3568a08a253d1ee1a0378754b74143", size = 246820, upload-time = "2025-10-06T05:36:19.046Z" }, - { url = "https://files.pythonhosted.org/packages/0f/ae/58282e8f98e444b3f4dd42448ff36fa38bef29e40d40f330b22e7108f565/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:74c51543498289c0c43656701be6b077f4b265868fa7f8a8859c197006efb608", size = 250518, upload-time = "2025-10-06T05:36:20.763Z" }, - { url = "https://files.pythonhosted.org/packages/8f/96/007e5944694d66123183845a106547a15944fbbb7154788cbf7272789536/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:776f352e8329135506a1d6bf16ac3f87bc25b28e765949282dcc627af36123aa", size = 239096, upload-time = "2025-10-06T05:36:22.129Z" }, - { url = "https://files.pythonhosted.org/packages/66/bb/852b9d6db2fa40be96f29c0d1205c306288f0684df8fd26ca1951d461a56/frozenlist-1.8.0-cp312-cp312-win32.whl", hash = "sha256:433403ae80709741ce34038da08511d4a77062aa924baf411ef73d1146e74faf", size = 39985, upload-time = "2025-10-06T05:36:23.661Z" }, - { url = "https://files.pythonhosted.org/packages/b8/af/38e51a553dd66eb064cdf193841f16f077585d4d28394c2fa6235cb41765/frozenlist-1.8.0-cp312-cp312-win_amd64.whl", hash = "sha256:34187385b08f866104f0c0617404c8eb08165ab1272e884abc89c112e9c00746", size = 44591, upload-time = "2025-10-06T05:36:24.958Z" }, - { url = "https://files.pythonhosted.org/packages/a7/06/1dc65480ab147339fecc70797e9c2f69d9cea9cf38934ce08df070fdb9cb/frozenlist-1.8.0-cp312-cp312-win_arm64.whl", hash = "sha256:fe3c58d2f5db5fbd18c2987cba06d51b0529f52bc3a6cdc33d3f4eab725104bd", size = 40102, upload-time = "2025-10-06T05:36:26.333Z" }, - { url = "https://files.pythonhosted.org/packages/9a/9a/e35b4a917281c0b8419d4207f4334c8e8c5dbf4f3f5f9ada73958d937dcc/frozenlist-1.8.0-py3-none-any.whl", hash = "sha256:0c18a16eab41e82c295618a77502e17b195883241c563b00f0aa5106fc4eaa0d", size = 13409, upload-time = "2025-10-06T05:38:16.721Z" }, -] - [[package]] name = "gcc-arm-none-eabi" version = "13.2.1" @@ -667,33 +586,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/43/e3/7d92a15f894aa0c9c4b49b8ee9ac9850d6e63b03c9c32c0367a13ae62209/mpmath-1.3.0-py3-none-any.whl", hash = "sha256:a0b2b9fe80bbcd81a6647ff13108738cfb482d481d826cc0e02f5b35e5c88d2c", size = 536198, upload-time = "2023-03-07T16:47:09.197Z" }, ] -[[package]] -name = "multidict" -version = "6.7.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/1a/c2/c2d94cbe6ac1753f3fc980da97b3d930efe1da3af3c9f5125354436c073d/multidict-6.7.1.tar.gz", hash = "sha256:ec6652a1bee61c53a3e5776b6049172c53b6aaba34f18c9ad04f82712bac623d", size = 102010, upload-time = "2026-01-26T02:46:45.979Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/8d/9c/f20e0e2cf80e4b2e4b1c365bf5fe104ee633c751a724246262db8f1a0b13/multidict-6.7.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:a90f75c956e32891a4eda3639ce6dd86e87105271f43d43442a3aedf3cddf172", size = 76893, upload-time = "2026-01-26T02:43:52.754Z" }, - { url = "https://files.pythonhosted.org/packages/fe/cf/18ef143a81610136d3da8193da9d80bfe1cb548a1e2d1c775f26b23d024a/multidict-6.7.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:3fccb473e87eaa1382689053e4a4618e7ba7b9b9b8d6adf2027ee474597128cd", size = 45456, upload-time = "2026-01-26T02:43:53.893Z" }, - { url = "https://files.pythonhosted.org/packages/a9/65/1caac9d4cd32e8433908683446eebc953e82d22b03d10d41a5f0fefe991b/multidict-6.7.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b0fa96985700739c4c7853a43c0b3e169360d6855780021bfc6d0f1ce7c123e7", size = 43872, upload-time = "2026-01-26T02:43:55.041Z" }, - { url = "https://files.pythonhosted.org/packages/cf/3b/d6bd75dc4f3ff7c73766e04e705b00ed6dbbaccf670d9e05a12b006f5a21/multidict-6.7.1-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:cb2a55f408c3043e42b40cc8eecd575afa27b7e0b956dfb190de0f8499a57a53", size = 251018, upload-time = "2026-01-26T02:43:56.198Z" }, - { url = "https://files.pythonhosted.org/packages/fd/80/c959c5933adedb9ac15152e4067c702a808ea183a8b64cf8f31af8ad3155/multidict-6.7.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:eb0ce7b2a32d09892b3dd6cc44877a0d02a33241fafca5f25c8b6b62374f8b75", size = 258883, upload-time = "2026-01-26T02:43:57.499Z" }, - { url = "https://files.pythonhosted.org/packages/86/85/7ed40adafea3d4f1c8b916e3b5cc3a8e07dfcdcb9cd72800f4ed3ca1b387/multidict-6.7.1-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:c3a32d23520ee37bf327d1e1a656fec76a2edd5c038bf43eddfa0572ec49c60b", size = 242413, upload-time = "2026-01-26T02:43:58.755Z" }, - { url = "https://files.pythonhosted.org/packages/d2/57/b8565ff533e48595503c785f8361ff9a4fde4d67de25c207cd0ba3befd03/multidict-6.7.1-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:9c90fed18bffc0189ba814749fdcc102b536e83a9f738a9003e569acd540a733", size = 268404, upload-time = "2026-01-26T02:44:00.216Z" }, - { url = "https://files.pythonhosted.org/packages/e0/50/9810c5c29350f7258180dfdcb2e52783a0632862eb334c4896ac717cebcb/multidict-6.7.1-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:da62917e6076f512daccfbbde27f46fed1c98fee202f0559adec8ee0de67f71a", size = 269456, upload-time = "2026-01-26T02:44:02.202Z" }, - { url = "https://files.pythonhosted.org/packages/f3/8d/5e5be3ced1d12966fefb5c4ea3b2a5b480afcea36406559442c6e31d4a48/multidict-6.7.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bfde23ef6ed9db7eaee6c37dcec08524cb43903c60b285b172b6c094711b3961", size = 256322, upload-time = "2026-01-26T02:44:03.56Z" }, - { url = "https://files.pythonhosted.org/packages/31/6e/d8a26d81ac166a5592782d208dd90dfdc0a7a218adaa52b45a672b46c122/multidict-6.7.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3758692429e4e32f1ba0df23219cd0b4fc0a52f476726fff9337d1a57676a582", size = 253955, upload-time = "2026-01-26T02:44:04.845Z" }, - { url = "https://files.pythonhosted.org/packages/59/4c/7c672c8aad41534ba619bcd4ade7a0dc87ed6b8b5c06149b85d3dd03f0cd/multidict-6.7.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:398c1478926eca669f2fd6a5856b6de9c0acf23a2cb59a14c0ba5844fa38077e", size = 251254, upload-time = "2026-01-26T02:44:06.133Z" }, - { url = "https://files.pythonhosted.org/packages/7b/bd/84c24de512cbafbdbc39439f74e967f19570ce7924e3007174a29c348916/multidict-6.7.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:c102791b1c4f3ab36ce4101154549105a53dc828f016356b3e3bcae2e3a039d3", size = 252059, upload-time = "2026-01-26T02:44:07.518Z" }, - { url = "https://files.pythonhosted.org/packages/fa/ba/f5449385510825b73d01c2d4087bf6d2fccc20a2d42ac34df93191d3dd03/multidict-6.7.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:a088b62bd733e2ad12c50dad01b7d0166c30287c166e137433d3b410add807a6", size = 263588, upload-time = "2026-01-26T02:44:09.382Z" }, - { url = "https://files.pythonhosted.org/packages/d7/11/afc7c677f68f75c84a69fe37184f0f82fce13ce4b92f49f3db280b7e92b3/multidict-6.7.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:3d51ff4785d58d3f6c91bdbffcb5e1f7ddfda557727043aa20d20ec4f65e324a", size = 259642, upload-time = "2026-01-26T02:44:10.73Z" }, - { url = "https://files.pythonhosted.org/packages/2b/17/ebb9644da78c4ab36403739e0e6e0e30ebb135b9caf3440825001a0bddcb/multidict-6.7.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fc5907494fccf3e7d3f94f95c91d6336b092b5fc83811720fae5e2765890dfba", size = 251377, upload-time = "2026-01-26T02:44:12.042Z" }, - { url = "https://files.pythonhosted.org/packages/ca/a4/840f5b97339e27846c46307f2530a2805d9d537d8b8bd416af031cad7fa0/multidict-6.7.1-cp312-cp312-win32.whl", hash = "sha256:28ca5ce2fd9716631133d0e9a9b9a745ad7f60bac2bccafb56aa380fc0b6c511", size = 41887, upload-time = "2026-01-26T02:44:14.245Z" }, - { url = "https://files.pythonhosted.org/packages/80/31/0b2517913687895f5904325c2069d6a3b78f66cc641a86a2baf75a05dcbb/multidict-6.7.1-cp312-cp312-win_amd64.whl", hash = "sha256:fcee94dfbd638784645b066074b338bc9cc155d4b4bffa4adce1615c5a426c19", size = 46053, upload-time = "2026-01-26T02:44:15.371Z" }, - { url = "https://files.pythonhosted.org/packages/0c/5b/aba28e4ee4006ae4c7df8d327d31025d760ffa992ea23812a601d226e682/multidict-6.7.1-cp312-cp312-win_arm64.whl", hash = "sha256:ba0a9fb644d0c1a2194cf7ffb043bd852cea63a57f66fbd33959f7dae18517bf", size = 43307, upload-time = "2026-01-26T02:44:16.852Z" }, - { url = "https://files.pythonhosted.org/packages/81/08/7036c080d7117f28a4af526d794aab6a84463126db031b007717c1a6676e/multidict-6.7.1-py3-none-any.whl", hash = "sha256:55d97cc6dae627efa6a6e548885712d4864b81110ac76fa4e534c03819fa4a56", size = 12319, upload-time = "2026-01-26T02:46:44.004Z" }, -] - [[package]] name = "ncurses" version = "6.5" @@ -724,7 +616,6 @@ version = "0.1.0" source = { editable = "." } dependencies = [ { name = "acados" }, - { name = "aiohttp" }, { name = "aiortc" }, { name = "av" }, { name = "bootstrap-icons" }, @@ -802,7 +693,6 @@ tools = [ [package.metadata] requires-dist = [ { name = "acados", git = "https://github.com/commaai/dependencies.git?subdirectory=acados&rev=release-acados" }, - { name = "aiohttp" }, { name = "aiortc" }, { name = "av" }, { name = "bootstrap-icons", git = "https://github.com/commaai/dependencies.git?subdirectory=bootstrap-icons&rev=release-bootstrap-icons" }, @@ -917,32 +807,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/12/46/eba9be9daa403fa94854ce16a458c29df9a01c6c047931c3d8be6016cd9a/pre_commit_hooks-6.0.0-py2.py3-none-any.whl", hash = "sha256:76161b76d321d2f8ee2a8e0b84c30ee8443e01376121fd1c90851e33e3bd7ee2", size = 41338, upload-time = "2025-08-09T19:25:03.513Z" }, ] -[[package]] -name = "propcache" -version = "0.5.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ec/44/c87281c333769159c50594f22610f77398a47ccbfbbf23074e744e86f87c/propcache-0.5.2.tar.gz", hash = "sha256:01c4fc7480cd0598bb4b57022df55b9ca296da7fc5a8760bd8451a7e63a7d427", size = 50208, upload-time = "2026-05-08T21:02:12.199Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/4a/cb/e27bc2b2737a0bb49962b275efa051e8f1c35a936df7d5139b6b658b7dc9/propcache-0.5.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:806719138ecd720339a12410fb9614ac9b2b2d3a5fdf8235d56981c36f4039ba", size = 95887, upload-time = "2026-05-08T21:00:11.277Z" }, - { url = "https://files.pythonhosted.org/packages/e6/13/b8ae04c59392f8d11c6cd9fb4011d1dc7c86b81225c770280300e259ffe1/propcache-0.5.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:db2b80ea58eab4f86b2beec3cc8b39e8ff9276ac20e96b7cce43c8ae84cd6b5a", size = 54654, upload-time = "2026-05-08T21:00:12.604Z" }, - { url = "https://files.pythonhosted.org/packages/2c/7d/49777a3e20b55863d4794384a38acd460c04157b0a00f8602b0d508b8431/propcache-0.5.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:e5cbfac9f61484f7e9f3597775500cd3ebe8274e9b050c38f9525c77c97520bf", size = 55190, upload-time = "2026-05-08T21:00:13.935Z" }, - { url = "https://files.pythonhosted.org/packages/44/c7/085d0cd63062e84044e3f05797749c3f8e3938ff3aeb0eb2f69d43fafc91/propcache-0.5.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5dbc581d2814337da56222fab8dc5f161cd798a434e49bac27930aaef798e144", size = 59995, upload-time = "2026-05-08T21:00:15.526Z" }, - { url = "https://files.pythonhosted.org/packages/9c/42/32cf8e3009e92b2645cf1e944f701e8ea4e924dffde1ee26db860bcbf7e4/propcache-0.5.2-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:857187f381f88c8e2fa2fe56ab94879d011b883d5a2ee5a1b60a8cd2a06846d9", size = 63422, upload-time = "2026-05-08T21:00:16.824Z" }, - { url = "https://files.pythonhosted.org/packages/9e/1b/f112433f99fc979431b87a39ef169e3f8df070d99a72792c56d6937ac48b/propcache-0.5.2-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:178b4a2cdaac1818e2bf1c5a99b94383fa73ea5382e032a48dec07dc5668dc42", size = 64342, upload-time = "2026-05-08T21:00:18.362Z" }, - { url = "https://files.pythonhosted.org/packages/14/15/5574111ae50dd6e879456888c0eadd4c5a869959775854e18e18a6b345f3/propcache-0.5.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6f328175a2cde1f0ff2c4ed8ce968b9dcfb55f3a7153f39e2957ed994da13476", size = 61639, upload-time = "2026-05-08T21:00:19.692Z" }, - { url = "https://files.pythonhosted.org/packages/cc/da/4d775080b1490c0ae604acda868bd71aabe3a89ed16f2aa4339eb8a283e7/propcache-0.5.2-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:5671d09a36b06d0fd4a3da0fccbcae360e9b1570924171a15e9e0997f0249fba", size = 61588, upload-time = "2026-05-08T21:00:21.155Z" }, - { url = "https://files.pythonhosted.org/packages/04/ac/f076982cbe2195ee9cf32de5a1e46951d9fb399fc207f390562dd0fd8fb2/propcache-0.5.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:80168e2ebe4d3ec6599d10ad8f520304ae1cad9b6c5a95372aef1b66b7bfb53a", size = 60029, upload-time = "2026-05-08T21:00:22.713Z" }, - { url = "https://files.pythonhosted.org/packages/70/60/189be62e0dd898dce3b331e1b8c7a543cd3a405ac0c81fe8ee8a9d5d77e1/propcache-0.5.2-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:45f11346f884bc47444f6e6647131055844134c3175b629f84952e2b5cd62b64", size = 56774, upload-time = "2026-05-08T21:00:24.001Z" }, - { url = "https://files.pythonhosted.org/packages/ea/9e/93377b9c7939c1ffae98f878dee955efadfd638078bc86dbc21f9d52f651/propcache-0.5.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:8e778ebd44ef4f66ed60a0416b06b489687db264a9c0b3620362f26489492913", size = 63532, upload-time = "2026-05-08T21:00:25.545Z" }, - { url = "https://files.pythonhosted.org/packages/14/f9/590ef6cfb9b8028d516d287812ece32bb0bc5f11fbb9c8bf6b2e6313fec8/propcache-0.5.2-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:c0cb9ed24c8964e172768d455a38254c2dd8a552905729ce006cad3d3dda59b1", size = 61592, upload-time = "2026-05-08T21:00:27.186Z" }, - { url = "https://files.pythonhosted.org/packages/b4/5e/70958b3034c297a630bba2f17ca7abc2d5f39a803ad7e370ab79d1ecd022/propcache-0.5.2-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:1d1ad32d9d4355e2be65574fd0bfd3677e7066b009cd5b9b2dee8aa6a6393b33", size = 64788, upload-time = "2026-05-08T21:00:28.8Z" }, - { url = "https://files.pythonhosted.org/packages/12/fd/77fe5936d8c3086ca9048f7f415f122ed82e53884a9ec193646b42deef06/propcache-0.5.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c80f4ba3e8f00189165999a742ee526ebeccedf6c3f7beb0c7df821e9772435a", size = 62514, upload-time = "2026-05-08T21:00:30.098Z" }, - { url = "https://files.pythonhosted.org/packages/cf/74/66bd798b5b3be70aa1b391f5cc9d6a0a5532d7fd3b19ec0b213e72e6ad9d/propcache-0.5.2-cp312-cp312-win32.whl", hash = "sha256:8c7972d8f193740d9175f0998ab38717e6cd322d5935c5b0fef8c0d323fd9031", size = 39018, upload-time = "2026-05-08T21:00:31.622Z" }, - { url = "https://files.pythonhosted.org/packages/61/7c/5c0d34aa3024694d6dcb9271cdbdd08c4e47c1c0ad95ec7e7bc74cdea145/propcache-0.5.2-cp312-cp312-win_amd64.whl", hash = "sha256:d9ee8826a7d47863a08ac44e1a5f611a462eefc3a194b492da242128bec75b42", size = 42322, upload-time = "2026-05-08T21:00:32.918Z" }, - { url = "https://files.pythonhosted.org/packages/4d/91/875812f1a3feb20ceba818ef39fbe4d92f1081e04ac815c822496d0d038b/propcache-0.5.2-cp312-cp312-win_arm64.whl", hash = "sha256:2800a4a8ead6b28cccd1ec54b59346f0def7922ee1c7598e8499c733cfbb7c84", size = 38172, upload-time = "2026-05-08T21:00:35.124Z" }, - { url = "https://files.pythonhosted.org/packages/3a/ed/1cdcab6ba3d6ab7feca11fc14f0eeea80755bb53ef4e892079f31b10a25f/propcache-0.5.2-py3-none-any.whl", hash = "sha256:be1ddfcbb376e3de5d2e2db1d58d6d67463e6b4f9f040c000de8e300295465fe", size = 14036, upload-time = "2026-05-08T21:02:10.673Z" }, -] - [[package]] name = "psutil" version = "7.2.2" @@ -1491,37 +1355,6 @@ name = "xvfb" version = "1.20.11.post1" source = { git = "https://github.com/commaai/dependencies.git?subdirectory=xvfb&rev=release-xvfb#f0bb0b0d9154ea7858f3c0333b607ba7d356b571" } -[[package]] -name = "yarl" -version = "1.24.2" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "idna" }, - { name = "multidict" }, - { name = "propcache" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/79/12/1e8f37460ea0f7eb59c221fdaf0ed75e7ac43e97f8093b9c6f411df50a78/yarl-1.24.2.tar.gz", hash = "sha256:9ac374123c6fd7abf64d1fec93962b0bd4ee2c19751755a762a72dd96c0378f8", size = 210798, upload-time = "2026-05-19T21:31:05.599Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/f0/da/866bcb01076ba49d2b42b309867bed3826421f1c479655eb7a607b44f20b/yarl-1.24.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:b975866c184564c827e0877380f0dae57dcca7e52782128381b72feff6dfceb8", size = 129957, upload-time = "2026-05-19T21:28:51.695Z" }, - { url = "https://files.pythonhosted.org/packages/bf/1d/fcefb70922ea2268a8971d8e5874d9a8218644200fb8465f1dcad55e6851/yarl-1.24.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:3b075301a2836a0e297b1b658cb6d6135df535d62efefdd60366bd589c2c82f2", size = 92164, upload-time = "2026-05-19T21:28:53.242Z" }, - { url = "https://files.pythonhosted.org/packages/29/b6/170e2b8d4e3bc30e6bfdcca53556537f5bf595e938632dfcb059311f3ff6/yarl-1.24.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8ae44649b00947634ab0dab2a374a638f52923a6e67083f2c156cd5cbd1a881d", size = 91688, upload-time = "2026-05-19T21:28:54.865Z" }, - { url = "https://files.pythonhosted.org/packages/fe/a5/c9f655d5553ea0b99fdac9d6a99ad3f9b3e73b8e5758bb46f58c9831f74c/yarl-1.24.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:507cc19f0b45454e2d6dcd62ff7d062b9f77a2812404e62dbdaec05b50faa035", size = 102902, upload-time = "2026-05-19T21:28:56.963Z" }, - { url = "https://files.pythonhosted.org/packages/5d/bc/6b9664d815d79af4ee553337f9d606c56bbf269186ada9172de45f1b5f60/yarl-1.24.2-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:c4c17bad5a530912d2111825d3f05e89bab2dd376aaa8cbc77e449e6db63e576", size = 97931, upload-time = "2026-05-19T21:28:58.56Z" }, - { url = "https://files.pythonhosted.org/packages/98/ec/32ba48acae30fecd60928f5791188b80a9d6ee3840507ffda29fecd37b71/yarl-1.24.2-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f5f0cbb112838a4a293985b6ed73948a547dadcc1ba6d2089938e7abdedceef8", size = 111030, upload-time = "2026-05-19T21:29:00.148Z" }, - { url = "https://files.pythonhosted.org/packages/82/5a/6f4cd081e5f4934d2ae3a8ef4abe3afacc010d26f0035ee91b35cd7d7c37/yarl-1.24.2-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5ec8356b8a6afcf81fc7aeeef13b1ff7a49dec00f313394bbb9e83830d32ccd7", size = 110392, upload-time = "2026-05-19T21:29:02.155Z" }, - { url = "https://files.pythonhosted.org/packages/7a/da/323a01c349bd5fb01bb6652e314d9bb218cee630a736bdb810ad50e4013f/yarl-1.24.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7e7ebcdef69dec6c6451e616f32b622a6d4a2e92b445c992f7c8e5274a6bbc4c", size = 105612, upload-time = "2026-05-19T21:29:04.247Z" }, - { url = "https://files.pythonhosted.org/packages/7c/80/264ab684f181e1a876389374519ff05d10248725535ae2ac4e8ac4e563d6/yarl-1.24.2-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:47a55d6cf6db2f401017a9e96e5288844e5051911fb4e0c8311a3980f5e59a7d", size = 104487, upload-time = "2026-05-19T21:29:06.491Z" }, - { url = "https://files.pythonhosted.org/packages/41/07/efabe5df87e96d7ad5959760b888344be48cd6884db127b407c6b5503adc/yarl-1.24.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3065657c80a2321225e804048597ad55658a7e76b32d6f5ee4074d04c50401db", size = 102333, upload-time = "2026-05-19T21:29:08.267Z" }, - { url = "https://files.pythonhosted.org/packages/44/0c/bcf7c42603e1009295f586d8890f2ba032c8b53310e815adf0a202c73d9f/yarl-1.24.2-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:cb84b80d88e19ede158619b80813968713d8d008b0e2497a576e6a0557d50712", size = 99025, upload-time = "2026-05-19T21:29:10.682Z" }, - { url = "https://files.pythonhosted.org/packages/4f/82/84482ab1a57a0f21a08afe6a7004c61d741f8f2ecc3b05c321577c612164/yarl-1.24.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:990de4f680b1c217e77ff0d6aa0029f9eb79889c11fb3e9a3942c7eba29c1996", size = 110507, upload-time = "2026-05-19T21:29:12.954Z" }, - { url = "https://files.pythonhosted.org/packages/c4/8d/a546ba1dfe1b0f290e05fef145cd07614c0f15df1a707195e512d1e39d1d/yarl-1.24.2-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:abb8ec0323b80161e3802da3150ef660b41d0e9be2048b76a363d93eee992c2b", size = 103719, upload-time = "2026-05-19T21:29:14.893Z" }, - { url = "https://files.pythonhosted.org/packages/1a/b6/267f2a09213138473adfce6b8a6e17791d7fee70bd4d9003218e4dec58b0/yarl-1.24.2-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:e7977781f83638a4c73e0f88425563d70173e0dfd90ac006a45c65036293ee3c", size = 110438, upload-time = "2026-05-19T21:29:16.485Z" }, - { url = "https://files.pythonhosted.org/packages/48/2d/1c8d89c7c5f9cad9fb2902445d94e2ab1d7aa35de029afbb8ae95c42d00f/yarl-1.24.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e30dd55825dc554ec5b66a94953b8eda8745926514c5089dfcacecb9c99b5bd1", size = 105719, upload-time = "2026-05-19T21:29:18.367Z" }, - { url = "https://files.pythonhosted.org/packages/a7/25/722e3b93bd687009afb2d59a35e13d30ddd8f80571445bb0c4e4ce26ec66/yarl-1.24.2-cp312-cp312-win_amd64.whl", hash = "sha256:7dafe10c12ddd4d120d528c4b5599c953bd7b12845347d507b95451195bb6cad", size = 92901, upload-time = "2026-05-19T21:29:20.014Z" }, - { url = "https://files.pythonhosted.org/packages/39/47/4486ccfb674c04854a1ef8aa77868b6a6f765feaf69633409d7ca4f02cb8/yarl-1.24.2-cp312-cp312-win_arm64.whl", hash = "sha256:044a09d8401fcf8681977faef6d286b8ade1e2d2e9dceda175d1cfa5ca496f30", size = 87229, upload-time = "2026-05-19T21:29:22.1Z" }, - { url = "https://files.pythonhosted.org/packages/fd/4d/4b880086bd0d3e034d25647be1d830afc3e3f610e98c4ab3490af6b1b6d5/yarl-1.24.2-py3-none-any.whl", hash = "sha256:2783d9226db8797636cd6896e4de81feed252d1db72265686c9558d97a4d94b9", size = 53576, upload-time = "2026-05-19T21:31:03.909Z" }, -] - [[package]] name = "zensical" version = "0.0.43" From 288aa60bf4a16e763aace01276d50a956f6fca1e Mon Sep 17 00:00:00 2001 From: commaci-public <60409688+commaci-public@users.noreply.github.com> Date: Mon, 22 Jun 2026 15:28:11 -0700 Subject: [PATCH 081/151] [bot] Update Python packages (#38227) * Update Python packages * fix numpy reshape warning * relock --------- Co-authored-by: Vehicle Researcher Co-authored-by: Adeeb Shihadeh --- docs/CARS.md | 6 +- opendbc_repo | 2 +- .../common/transformations/orientation.py | 5 +- panda | 2 +- tinygrad_repo | 2 +- uv.lock | 322 +++++++++--------- 6 files changed, 167 insertions(+), 172 deletions(-) diff --git a/docs/CARS.md b/docs/CARS.md index b0891b8366..31abdf433c 100644 --- a/docs/CARS.md +++ b/docs/CARS.md @@ -4,7 +4,7 @@ A supported vehicle is one that just works when you install a comma device. All supported cars provide a better experience than any stock system. Supported vehicles reference the US market unless otherwise specified. -# 334 Supported Cars +# 332 Supported Cars |Make|Model|Supported Package|ACC|No ACC accel below|No ALC below|Steering Torque|Resume from stop|Hardware Needed
 |Video|Setup Video| |---|---|---|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:| @@ -78,7 +78,7 @@ A supported vehicle is one that just works when you install a comma device. All |Honda|Accord 2018-22|All|openpilot available[1,5](#footnotes)|0 mph|3 mph|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Honda Bosch A connector
- 1 OBD-C cable (2 ft)
- 1 comma four
- 1 comma power v3
- 1 harness box
- 1 mount
Buy Here
||| |Honda|Accord 2023-25|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Honda Bosch C connector
- 1 OBD-C cable (2 ft)
- 1 comma four
- 1 comma power v3
- 1 harness box
- 1 mount
Buy Here
||| |Honda|Accord Hybrid 2018-22|All|openpilot available[1,5](#footnotes)|0 mph|3 mph|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Honda Bosch A connector
- 1 OBD-C cable (2 ft)
- 1 comma four
- 1 comma power v3
- 1 harness box
- 1 mount
Buy Here
||| -|Honda|Accord Hybrid 2023-25|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Honda Bosch C connector
- 1 OBD-C cable (2 ft)
- 1 comma four
- 1 comma power v3
- 1 harness box
- 1 mount
Buy Here
||| +|Honda|Accord Hybrid 2023-26|All|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Honda Bosch C connector
- 1 OBD-C cable (2 ft)
- 1 comma four
- 1 comma power v3
- 1 harness box
- 1 mount
Buy Here
||| |Honda|City (Brazil only) 2023|All|openpilot available[1,5](#footnotes)|0 mph|14 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Honda Bosch B connector
- 1 OBD-C cable (2 ft)
- 1 comma four
- 1 comma power v3
- 1 harness box
- 1 mount
Buy Here
||| |Honda|Civic 2016-18|Honda Sensing|openpilot|0 mph|12 mph|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Honda Nidec connector
- 1 OBD-C cable (2 ft)
- 1 comma four
- 1 comma power v3
- 1 harness box
- 1 mount
Buy Here
||| |Honda|Civic 2019-21|All|openpilot available[1,5](#footnotes)|0 mph|2 mph[4](#footnotes)|[![star](assets/icon-star-empty.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 Honda Bosch A connector
- 1 OBD-C cable (2 ft)
- 1 comma four
- 1 comma power v3
- 1 harness box
- 1 mount
Buy Here
||| @@ -233,9 +233,7 @@ A supported vehicle is one that just works when you install a comma device. All |Nissan[6](#footnotes)|X-Trail 2017|ProPILOT Assist|Stock|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|
Parts- 1 Nissan A connector
- 1 OBD-C cable (2 ft)
- 1 comma four
- 1 comma power v3
- 1 harness box
- 1 long OBD-C cable (9.5 ft)
- 1 mount
Buy Here
||| |Ram|1500 2019-24|Adaptive Cruise Control (ACC)|Stock|0 mph|32 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 OBD-C cable (2 ft)
- 1 Ram connector
- 1 comma four
- 1 comma power v3
- 1 harness box
- 1 mount
Buy Here
||| |Rivian|R1S 2022-24|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 OBD-C cable (2 ft)
- 1 Rivian A connector
- 1 comma four
- 1 comma power v3
- 1 harness box
- 1 long OBD-C cable (9.5 ft)
- 1 mount
Buy Here
||| -|Rivian|R1S 2025|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 OBD-C cable (2 ft)
- 1 Rivian B connector
- 1 comma four
- 1 comma power v3
- 1 harness box
- 1 long OBD-C cable (9.5 ft)
- 1 mount
Buy Here
||| |Rivian|R1T 2022-24|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 OBD-C cable (2 ft)
- 1 Rivian A connector
- 1 comma four
- 1 comma power v3
- 1 harness box
- 1 long OBD-C cable (9.5 ft)
- 1 mount
Buy Here
||| -|Rivian|R1T 2025|All|openpilot|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 OBD-C cable (2 ft)
- 1 Rivian B connector
- 1 comma four
- 1 comma power v3
- 1 harness box
- 1 long OBD-C cable (9.5 ft)
- 1 mount
Buy Here
||| |SEAT[12](#footnotes)|Ateca 2016-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,16](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 OBD-C cable (2 ft)
- 1 VW J533 connector
- 1 comma four
- 1 harness box
- 1 long OBD-C cable (9.5 ft)
- 1 mount
Buy Here
||| |SEAT[12](#footnotes)|Leon 2014-20|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[1,16](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-full.svg)](##)|
Parts- 1 OBD-C cable (2 ft)
- 1 VW J533 connector
- 1 comma four
- 1 harness box
- 1 long OBD-C cable (9.5 ft)
- 1 mount
Buy Here
||| |Subaru|Ascent 2019-21|All[7](#footnotes)|openpilot available[1,8](#footnotes)|0 mph|0 mph|[![star](assets/icon-star-full.svg)](##)|[![star](assets/icon-star-empty.svg)](##)|
Parts- 1 OBD-C cable (2 ft)
- 1 Subaru A connector
- 1 comma four
- 1 comma power v3
- 1 harness box
- 1 mount
Buy Here
Tools- 1 Pry Tool
- 1 Socket Wrench 8mm or 5/16" (deep)
||| diff --git a/opendbc_repo b/opendbc_repo index 7e3a0703b9..58b89559ed 160000 --- a/opendbc_repo +++ b/opendbc_repo @@ -1 +1 @@ -Subproject commit 7e3a0703b9d254812151f3660b6f8549432c954e +Subproject commit 58b89559ede390a9a4b389f2276ab3863a3ecc52 diff --git a/openpilot/common/transformations/orientation.py b/openpilot/common/transformations/orientation.py index 86e6a6c347..d2ccda13a5 100644 --- a/openpilot/common/transformations/orientation.py +++ b/openpilot/common/transformations/orientation.py @@ -25,11 +25,10 @@ def numpy_wrap(function, input_shape, output_shape) -> Callable[..., np.ndarray] # Add empty dimension if inputs is not a list if len(shape) == len(input_shape): - inp.shape = (1, ) + inp.shape + inp = inp.reshape((1, ) + inp.shape) result = np.asarray([function(*args, i) for i in inp]) - result.shape = out_shape - return result + return result.reshape(out_shape) return f diff --git a/panda b/panda index 7ffc916578..1a40b79413 160000 --- a/panda +++ b/panda @@ -1 +1 @@ -Subproject commit 7ffc916578af9373a165cf9df5974720d9a258a5 +Subproject commit 1a40b79413d36222f029f46a4d5adf95766d0193 diff --git a/tinygrad_repo b/tinygrad_repo index 443f976305..f9c8c697d6 160000 --- a/tinygrad_repo +++ b/tinygrad_repo @@ -1 +1 @@ -Subproject commit 443f976305038c113cc7836799967da738c5b77e +Subproject commit f9c8c697d6bfb76ba0bd79e15704ed376f0c45ec diff --git a/uv.lock b/uv.lock index 303a99f3bf..0804481dcd 100644 --- a/uv.lock +++ b/uv.lock @@ -5,7 +5,7 @@ requires-python = ">=3.12.3, <3.13" [[package]] name = "acados" version = "0.2.2" -source = { git = "https://github.com/commaai/dependencies.git?subdirectory=acados&rev=release-acados#25933c81c7db5573afe38f012f52befc15cdb804" } +source = { git = "https://github.com/commaai/dependencies.git?subdirectory=acados&rev=release-acados#acfa1f7978b450d30fd346d61ae10e18bb4434c7" } dependencies = [ { name = "numpy" }, ] @@ -68,30 +68,30 @@ wheels = [ [[package]] name = "bootstrap-icons" version = "1.10.5.0" -source = { git = "https://github.com/commaai/dependencies.git?subdirectory=bootstrap-icons&rev=release-bootstrap-icons#d7e41838af9320328dd7102f9288a94f0cf0fa9f" } +source = { git = "https://github.com/commaai/dependencies.git?subdirectory=bootstrap-icons&rev=release-bootstrap-icons#8baa670f1b5c588e92ee8b9aa0ac821002b2e0f0" } [[package]] name = "bzip2" version = "1.0.8" -source = { git = "https://github.com/commaai/dependencies.git?subdirectory=bzip2&rev=release-bzip2#12916f9f84848239e5a69a8c5a282f3dcb0d86a3" } +source = { git = "https://github.com/commaai/dependencies.git?subdirectory=bzip2&rev=release-bzip2#c998c0bbd86966dfaf6508a10454d58bc9941549" } [[package]] name = "capnproto" version = "1.0.1" -source = { git = "https://github.com/commaai/dependencies.git?subdirectory=capnproto&rev=release-capnproto#a75eb83bd98440e890261f82aa8dcfbda0b0a206" } +source = { git = "https://github.com/commaai/dependencies.git?subdirectory=capnproto&rev=release-capnproto#e85b11061487aa5e2015b96f44b25a5bde8ed7d9" } [[package]] name = "catch2" version = "2.13.10" -source = { git = "https://github.com/commaai/dependencies.git?subdirectory=catch2&rev=release-catch2#7287b4c99d23fdd87e66f9941b0e35ece6b4d91b" } +source = { git = "https://github.com/commaai/dependencies.git?subdirectory=catch2&rev=release-catch2#802399c0b7e28325066bf3e880bf12010b771257" } [[package]] name = "certifi" -version = "2026.5.20" +version = "2026.6.17" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f3/ce/ee2ecad540810a79593028e88299baeae54d346cc7a0d94b6199988b89b1/certifi-2026.5.20.tar.gz", hash = "sha256:69dea482ab64caa7b9f6aba1c6bf48bb6a5448d1c0f1b17ab42ad8c763a5344d", size = 135422, upload-time = "2026-05-20T11:46:50.073Z" } +sdist = { url = "https://files.pythonhosted.org/packages/c9/c7/424b75da314c1045981bd9777432fad05a9e0c69daa4ed7e308bbaffe405/certifi-2026.6.17.tar.gz", hash = "sha256:024c88eeec92ca068db80f02b8b07c9cef7b9fe261d1d535abfd5abd6f6af432", size = 134594, upload-time = "2026-06-17T10:31:07.894Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/59/8c/57e832b7af6d7c5abe66eb3fbe3a3a32f4d11ea23a1aa7131371035be991/certifi-2026.5.20-py3-none-any.whl", hash = "sha256:3c52e209ba0a4ad7aebe60436a4ab349c39e1e602e8c134221e546902ad25897", size = 134134, upload-time = "2026-05-20T11:46:48.578Z" }, + { url = "https://files.pythonhosted.org/packages/ef/2f/c5464532e965badff2f4c4c1a3a83f5697f0d7c407ed0cda44aaa99bb451/certifi-2026.6.17-py3-none-any.whl", hash = "sha256:2227dcbaafe0d2f59279d1762ddddc37783ed4354594f194ffc31d20f41fc3db", size = 133289, upload-time = "2026-06-17T10:31:06.348Z" }, ] [[package]] @@ -196,26 +196,26 @@ wheels = [ [[package]] name = "coverage" -version = "7.14.1" +version = "7.14.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/54/fd/0ab2772530e946e1be1abd0bc09e647ec9b02e88f0867857601fefca8953/coverage-7.14.1.tar.gz", hash = "sha256:30c08f7d90415aa98b3c990385dea2939b0da55f38515e5b369b83655f8523be", size = 920132, upload-time = "2026-05-26T20:41:36.783Z" } +sdist = { url = "https://files.pythonhosted.org/packages/9c/a3/3834a5564fe8f32154cd7032400d3c2f9c565b2a373fa671f2bbdad6f634/coverage-7.14.2.tar.gz", hash = "sha256:7a2da3d81cfe17c18038c6d98e6592aa9147d596d056119b0ee612c3c8bd5230", size = 923982, upload-time = "2026-06-20T14:49:30.885Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/3d/b7/bdbb725ba02c5b42825b200c940f38b7a54fcad24627b7192f78f8110d76/coverage-7.14.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:a06c76364a9360e33d6d23769aefdf7f66f38e2ffb60ceb1baaa4989d83b695c", size = 220022, upload-time = "2026-05-26T20:39:03.702Z" }, - { url = "https://files.pythonhosted.org/packages/72/81/fdc0898a55c6219223291ec1a1fe89966ef212ce82276aa0899df84b5de0/coverage-7.14.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fad54e871165f6ec2f536063ac74c3104508a12963e64072ba44bd822de52b0c", size = 220379, upload-time = "2026-05-26T20:39:05.381Z" }, - { url = "https://files.pythonhosted.org/packages/de/72/de048c4a25e13bce59ac6a339351c10bdf2515e07459afcdaf04dc3143a2/coverage-7.14.1-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:84b535f00655ecafe1d929d1fb00ed5d6fa3051ea643ab2c161a3887b86f294b", size = 251888, upload-time = "2026-05-26T20:39:07.367Z" }, - { url = "https://files.pythonhosted.org/packages/28/30/300c343f68beb9d4cbb64ec81e58c5b6b80b56927f72d2b38654ac26e013/coverage-7.14.1-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:6b6b0853b895fe0e98cbfc580d1ec3393d9302b4b1e96a77b3f5c91fdab899e6", size = 254624, upload-time = "2026-05-26T20:39:09.037Z" }, - { url = "https://files.pythonhosted.org/packages/b1/ed/7b25642496e8170b6bac14adce00537c6e5fa2d586159401a4de3e8b49e6/coverage-7.14.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:442cc9c952b2df400cda54bb04ab87330cf2cd08a8692cbbea36773531eb6f37", size = 255739, upload-time = "2026-05-26T20:39:10.889Z" }, - { url = "https://files.pythonhosted.org/packages/7f/a2/abd210b8c4e29c24e4624916db97bb519097a91034aaeb767f937e7da794/coverage-7.14.1-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:8270544c361ed405a27a060dbc9ed2c124b084d96dfdc2d9a2510482aef981ad", size = 257998, upload-time = "2026-05-26T20:39:12.722Z" }, - { url = "https://files.pythonhosted.org/packages/7f/24/7c50beed3792fe62f6ce0545c6686ce83379719e2c0276179333d97eae92/coverage-7.14.1-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:48b283b1dd6372e8de2a7a9a4c4d5dc06f4d4fd209b876f3c88a7a205a0c8f84", size = 252296, upload-time = "2026-05-26T20:39:14.259Z" }, - { url = "https://files.pythonhosted.org/packages/15/05/0f874628ebcbfc77ead559ff210281ef06a97db08481832e7dd39274a135/coverage-7.14.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5b0c99ba93a07d56f6df340bb79be53202a082b2fdb81bfe6190b741a3470d54", size = 253658, upload-time = "2026-05-26T20:39:15.923Z" }, - { url = "https://files.pythonhosted.org/packages/99/6f/ca6ad067364b337ef997802115e7ecad2abd2248b05471464b0dea02b4d4/coverage-7.14.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:e471bc5769ff073b058cfadb0d736b56ce067c8560eabeb0da88462df98c23e7", size = 251803, upload-time = "2026-05-26T20:39:17.537Z" }, - { url = "https://files.pythonhosted.org/packages/c0/30/b9b4d377cd9f40baf228068f5a81faf8450c6228503011bd499708483a50/coverage-7.14.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:f497a1ea81d4cd7c10ddcaa685135b9aabd291af3d55775a9ddf3cb7a364cdd9", size = 255873, upload-time = "2026-05-26T20:39:19.414Z" }, - { url = "https://files.pythonhosted.org/packages/3c/21/7c721a9e5e6bb88547d30a787aefb97512d3f54c1324c7488d9b3743f7f9/coverage-7.14.1-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:2222be86d0b54f5dd5a38f45f17f315f737245e857bf0bdedc70734f84a13c02", size = 251372, upload-time = "2026-05-26T20:39:21.169Z" }, - { url = "https://files.pythonhosted.org/packages/9d/8c/f8ae5a2200130e1503cd7661a6cd3b2b7bacef98277fbf3571fb13f8b766/coverage-7.14.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:85e85586565842f6932abebd4c18bcb1074223dc0b3576e7d173ca710622813a", size = 253245, upload-time = "2026-05-26T20:39:23.097Z" }, - { url = "https://files.pythonhosted.org/packages/34/62/70a9024672a5f6910517d9628c52c9afbdd3cf8f46426af52bb148a56fff/coverage-7.14.1-cp312-cp312-win32.whl", hash = "sha256:4a28fd227808366b196a75476dced2eb35b351d6766ba9c858dc93319e87f4f1", size = 222567, upload-time = "2026-05-26T20:39:24.868Z" }, - { url = "https://files.pythonhosted.org/packages/f6/81/8b7cd386839b039ebe1855733b9f9449a8dec5d79564018234f185a7fa70/coverage-7.14.1-cp312-cp312-win_amd64.whl", hash = "sha256:54acdb6674a4661768d7bf7db32dfb9f46ab1d764f8aba6df75ce1a6a088724e", size = 223372, upload-time = "2026-05-26T20:39:26.603Z" }, - { url = "https://files.pythonhosted.org/packages/ae/ba/b44d472022f620d289d95fa830143235c0c36461c6f2437ea8d51e5481ed/coverage-7.14.1-cp312-cp312-win_arm64.whl", hash = "sha256:99cd41ff91afd94896fea3bc002706b6ae4ce95727d06e4a0f39c0a8d8bd8b1a", size = 221989, upload-time = "2026-05-26T20:39:28.242Z" }, - { url = "https://files.pythonhosted.org/packages/8a/3c/1a983b9a745d7f83d53f057bcc5bf79ba6a2bbc08266b3f0c7d6fe630c9b/coverage-7.14.1-py3-none-any.whl", hash = "sha256:a252f21c27e38347e60111a3266b03827422a7d5525951aceee313aa68bab1d2", size = 211815, upload-time = "2026-05-26T20:41:34.078Z" }, + { url = "https://files.pythonhosted.org/packages/d0/d9/bdd141aa2c605096a8ef63b8435fd4f5fec78946a3cb7b9145840ec78291/coverage-7.14.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:37c94712e533ea06f0b1e4d934811c520b1914ce0e4da3916220717aa7a86bc6", size = 220528, upload-time = "2026-06-20T14:47:49.652Z" }, + { url = "https://files.pythonhosted.org/packages/02/97/d24ae7d2afc62c54a36313d4dedb655c9afbba3003f0f7f1ae81e97af31f/coverage-7.14.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c050bbc7bba94c77e4ed7438f4fda1babe98ab145691d80aa6f60df934a1468b", size = 220883, upload-time = "2026-06-20T14:47:51.036Z" }, + { url = "https://files.pythonhosted.org/packages/f8/0e/d8f00efd3df0d63e6843ebcbade9e4119d60f5376753c9705d84b014c775/coverage-7.14.2-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:a7af571767a2ee342a171c16fc1b1a07a0bf511606d381703fb7cf397fe49d46", size = 252395, upload-time = "2026-06-20T14:47:52.627Z" }, + { url = "https://files.pythonhosted.org/packages/1c/1c/ab9510dfe1a16a35a10f90efad0d9a9cf61b9876973752968f2ba882f73f/coverage-7.14.2-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:8b4910cce599cd2438f8da65f5ef199a70a1cdb6ab314926df78271ca5954240", size = 255131, upload-time = "2026-06-20T14:47:54.235Z" }, + { url = "https://files.pythonhosted.org/packages/ba/dd/70171e9371003b33dc6b20f527ac216ff91bbe5c1088e754eb8950d79193/coverage-7.14.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c33e9e4878972f430b0cc06de3bf2a28d054a9efb4f8426d27de0d9cb81396ff", size = 256246, upload-time = "2026-06-20T14:47:55.61Z" }, + { url = "https://files.pythonhosted.org/packages/0f/80/a68b1dd81d5c011e17fd6ab0d707d33297df1d0c618114b9b750a2219c80/coverage-7.14.2-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e7967ea55c6dea6becba4d5870e2fa0aa4915a8be7ebff1bb79e6207aa75ce8d", size = 258504, upload-time = "2026-06-20T14:47:56.979Z" }, + { url = "https://files.pythonhosted.org/packages/8e/7b/40baaa946189f5317cd77d484e39b9b0727d02ebada0a12162374f2faee2/coverage-7.14.2-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:d1322f237c2979b84096f4239c17828ff17fea6b3bbe96c44381c5f587c44c26", size = 252808, upload-time = "2026-06-20T14:47:58.418Z" }, + { url = "https://files.pythonhosted.org/packages/d5/05/b19517b09c43d1e8591de6c13178b0c03166c31e1adbebda378e64c66b9a/coverage-7.14.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:77849525340c99f516d793dddbcee16b18d50af892ac43c8de1a6f343d41e3b5", size = 254166, upload-time = "2026-06-20T14:48:00.004Z" }, + { url = "https://files.pythonhosted.org/packages/ae/f5/6e65da5957e041d2094a9b97736628dd80160f1cc007a50790bbb2668c1a/coverage-7.14.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:ef11695493ec3f06f7b2678ca274bcabb4ca04057317df268ddbfd8b05f661a8", size = 252310, upload-time = "2026-06-20T14:48:01.458Z" }, + { url = "https://files.pythonhosted.org/packages/2d/de/01b5274f0db63175b04d9354eff68d2d268b8b57a1b2db7d3dcb1f2c9dbb/coverage-7.14.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:8134f0e0723e080d1c27bbe8fc149f0162e429fa1852482150015d0fce83eaf1", size = 256379, upload-time = "2026-06-20T14:48:02.981Z" }, + { url = "https://files.pythonhosted.org/packages/71/d6/9a2ffbca41e2f8f86f61e8b78b86afa433ec8cdeac4908ace93a28fe3ff0/coverage-7.14.2-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:914eead2b843fc357f733b3fe39cc94f1b53d466e8cfe03080b1ed9d24ccfc73", size = 251880, upload-time = "2026-06-20T14:48:04.463Z" }, + { url = "https://files.pythonhosted.org/packages/e3/ff/20bd54a43c88c08f474e6cb355a97e024e38412873ef0a581629abe1e26f/coverage-7.14.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e4b2d5e847fb7958583b74910cc19e5ec4ece514487385677b26433b2546116e", size = 253753, upload-time = "2026-06-20T14:48:05.99Z" }, + { url = "https://files.pythonhosted.org/packages/35/2a/2b3482c30d8344f301d8df6ff232a321f2ab87d5ac97ba21891a68638131/coverage-7.14.2-cp312-cp312-win32.whl", hash = "sha256:e753db9e40dda7302e0ac3e1e6e1325fb7f7b4694f87a7314ab15dd5d57911a7", size = 222584, upload-time = "2026-06-20T14:48:07.361Z" }, + { url = "https://files.pythonhosted.org/packages/f6/5e/83934ffff147edd313fe925db426e8f7ccad9e4663262eb5c4db4e345658/coverage-7.14.2-cp312-cp312-win_amd64.whl", hash = "sha256:d32e5ca5f16dafb269ee50b60d32b00c704b3f6f78e238105f1d94a3a5f24bf5", size = 223118, upload-time = "2026-06-20T14:48:08.837Z" }, + { url = "https://files.pythonhosted.org/packages/bb/ee/616b4f38a34f076f3045d3eedfa764d34d82e6a6cc6b300acb0f1ff22a98/coverage-7.14.2-cp312-cp312-win_arm64.whl", hash = "sha256:dc366f158e2fb2add9d4e57338ca48f12611024278688ee657eb0b853fcb5de5", size = 222504, upload-time = "2026-06-20T14:48:10.436Z" }, + { url = "https://files.pythonhosted.org/packages/a3/5e/a8ba14ceb014f39bd5e3f7077150718c7de61c01ce326bfe7e8eae9b19b2/coverage-7.14.2-py3-none-any.whl", hash = "sha256:04d92589e481a8b68a005a5a1e0646a91c76f322c397c4635298c57cf63699b5", size = 212325, upload-time = "2026-06-20T14:49:28.991Z" }, ] [[package]] @@ -236,41 +236,39 @@ wheels = [ [[package]] name = "cryptography" -version = "48.0.0" +version = "49.0.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "cffi", marker = "platform_python_implementation != 'PyPy'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/9f/a9/db8f313fdcd85d767d4973515e1db101f9c71f95fced83233de224673757/cryptography-48.0.0.tar.gz", hash = "sha256:5c3932f4436d1cccb036cb0eaef46e6e2db91035166f1ad6505c3c9d5a635920", size = 832984, upload-time = "2026-05-04T22:59:38.133Z" } +sdist = { url = "https://files.pythonhosted.org/packages/1f/99/d1c90d6041656cc6ee229dc99cd67fd0cd5aec3c5f7d72fffc27cc750054/cryptography-49.0.0.tar.gz", hash = "sha256:f89660a348f4f78a92366240a61404e337586ef7f5909a2fef59ca88ef505493", size = 854345, upload-time = "2026-06-12T20:02:30.512Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/df/3d/01f6dd9190170a5a241e0e98c2d04be3664a9e6f5b9b872cde63aff1c3dd/cryptography-48.0.0-cp311-abi3-macosx_10_9_universal2.whl", hash = "sha256:0c558d2cdffd8f4bbb30fc7134c74d2ca9a476f830bb053074498fbc86f41ed6", size = 8001587, upload-time = "2026-05-04T22:57:36.803Z" }, - { url = "https://files.pythonhosted.org/packages/b2/6e/e90527eef33f309beb811cf7c982c3aeffcce8e3edb178baa4ca3ae4a6fa/cryptography-48.0.0-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:f5333311663ea94f75dd408665686aaf426563556bb5283554a3539177e03b8c", size = 4690433, upload-time = "2026-05-04T22:57:40.373Z" }, - { url = "https://files.pythonhosted.org/packages/90/04/673510ed51ddff56575f306cf1617d80411ee76831ccd3097599140efdfe/cryptography-48.0.0-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7995ef305d7165c3f11ae07f2517e5a4f1d5c18da1376a0a9ed496336b69e5f3", size = 4710620, upload-time = "2026-05-04T22:57:42.935Z" }, - { url = "https://files.pythonhosted.org/packages/14/d5/e9c4ef932c8d800490c34d8bd589d64a31d5890e27ec9e9ad532be893294/cryptography-48.0.0-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:40ba1f85eaa6959837b1d51c9767e230e14612eea4ef110ee8854ada22da1bf5", size = 4696283, upload-time = "2026-05-04T22:57:45.294Z" }, - { url = "https://files.pythonhosted.org/packages/0c/29/174b9dfb60b12d59ecfc6cfa04bc88c21b42a54f01b8aae09bb6e51e4c7f/cryptography-48.0.0-cp311-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:369a6348999f94bbd53435c894377b20ab95f25a9065c283570e70150d8abc3c", size = 5296573, upload-time = "2026-05-04T22:57:47.933Z" }, - { url = "https://files.pythonhosted.org/packages/95/38/0d29a6fd7d0d1373f0c0c88a04ba20e359b257753ac497564cd660fc1d55/cryptography-48.0.0-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:a0e692c683f4df67815a2d258b324e66f4738bd7a96a218c826dce4f4bd05d8f", size = 4743677, upload-time = "2026-05-04T22:57:50.067Z" }, - { url = "https://files.pythonhosted.org/packages/30/be/eef653013d5c63b6a490529e0316f9ac14a37602965d4903efed1399f32b/cryptography-48.0.0-cp311-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:18349bbc56f4743c8b12dc32e2bccb2cf83ee8b69a3bba74ef8ae857e26b3d25", size = 4330808, upload-time = "2026-05-04T22:57:52.301Z" }, - { url = "https://files.pythonhosted.org/packages/84/9e/500463e87abb7a0a0f9f256ec21123ecde0a7b5541a15e840ea54551fd81/cryptography-48.0.0-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:7e8eac43dfca5c4cccc6dad9a80504436fca53bb9bc3100a2386d730fbe6b602", size = 4695941, upload-time = "2026-05-04T22:57:54.603Z" }, - { url = "https://files.pythonhosted.org/packages/e3/dc/7303087450c2ec9e7fbb750e17c2abfbc658f23cbd0e54009509b7cc4091/cryptography-48.0.0-cp311-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:9ccdac7d40688ecb5a3b4a604b8a88c8002e3442d6c60aead1db2a89a041560c", size = 5252579, upload-time = "2026-05-04T22:57:57.207Z" }, - { url = "https://files.pythonhosted.org/packages/d0/c0/7101d3b7215edcdc90c45da544961fd8ed2d6448f77577460fa75a8443f7/cryptography-48.0.0-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:bd72e68b06bb1e96913f97dd4901119bc17f39d4586a5adf2d3e47bc2b9d58b5", size = 4743326, upload-time = "2026-05-04T22:57:59.535Z" }, - { url = "https://files.pythonhosted.org/packages/ac/d8/5b833bad13016f562ab9d063d68199a4bd121d18458e439515601d3357ec/cryptography-48.0.0-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:59baa2cb386c4f0b9905bd6eb4c2a79a69a128408fd31d32ca4d7102d4156321", size = 4826672, upload-time = "2026-05-04T22:58:01.996Z" }, - { url = "https://files.pythonhosted.org/packages/98/e1/7074eb8bf3c135558c73fc2bcf0f5633f912e6fb87e868a55c454080ef09/cryptography-48.0.0-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:9249e3cd978541d665967ac2cb2787fd6a62bddf1e75b3e347a594d7dacf4f74", size = 4972574, upload-time = "2026-05-04T22:58:03.968Z" }, - { url = "https://files.pythonhosted.org/packages/04/70/e5a1b41d325f797f39427aa44ef8baf0be500065ab6d8e10369d850d4a4f/cryptography-48.0.0-cp311-abi3-win32.whl", hash = "sha256:9c459db21422be75e2809370b829a87eb37f74cd785fc4aa9ea1e5f43b47cda4", size = 3294868, upload-time = "2026-05-04T22:58:06.467Z" }, - { url = "https://files.pythonhosted.org/packages/f4/ac/8ac51b4a5fc5932eb7ee5c517ba7dc8cd834f0048962b6b352f00f41ebf9/cryptography-48.0.0-cp311-abi3-win_amd64.whl", hash = "sha256:5b012212e08b8dd5edc78ef54da83dd9892fd9105323b3993eff6bea65dc21d7", size = 3817107, upload-time = "2026-05-04T22:58:08.845Z" }, - { url = "https://files.pythonhosted.org/packages/f2/63/61d4a4e1c6b6bab6ce1e213cd36a24c415d90e76d78c5eb8577c5541d2e8/cryptography-48.0.0-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:58d00498e8933e4a194f3076aee1b4a97dfec1a6da444535755822fe5d8b0b86", size = 7983482, upload-time = "2026-05-04T22:58:43.769Z" }, - { url = "https://files.pythonhosted.org/packages/d5/ac/f5b5995b87770c693e2596559ffafe195b4033a57f14a82268a2842953f3/cryptography-48.0.0-cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:614d0949f4790582d2cc25553abd09dd723025f0c0e7c67376a1d77196743d6e", size = 4683266, upload-time = "2026-05-04T22:58:46.064Z" }, - { url = "https://files.pythonhosted.org/packages/ec/c6/8b14f67e18338fbc4adb76f66c001f5c3610b3e2d1837f268f47a347dbbb/cryptography-48.0.0-cp39-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7ce4bfae76319a532a2dc68f82cc32f5676ee792a983187dac07183690e5c66f", size = 4696228, upload-time = "2026-05-04T22:58:48.22Z" }, - { url = "https://files.pythonhosted.org/packages/ea/73/f808fbae9514bd91b47875b003f13e284c8c6bdfd904b7944e803937eec1/cryptography-48.0.0-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:2eb992bbd4661238c5a397594c83f5b4dc2bc5b848c365c8f991b6780efcc5c7", size = 4689097, upload-time = "2026-05-04T22:58:50.9Z" }, - { url = "https://files.pythonhosted.org/packages/93/01/d86632d7d28db8ae83221995752eeb6639ffb374c2d22955648cf8d52797/cryptography-48.0.0-cp39-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:22a5cb272895dce158b2cacdfdc3debd299019659f42947dbdac6f32d68fe832", size = 5283582, upload-time = "2026-05-04T22:58:53.017Z" }, - { url = "https://files.pythonhosted.org/packages/02/e1/50edc7a50334807cc4791fc4a0ce7468b4a1416d9138eab358bfc9a3d70b/cryptography-48.0.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:2b4d59804e8408e2fea7d1fbaf218e5ec984325221db76e6a241a9abd6cdd95c", size = 4730479, upload-time = "2026-05-04T22:58:55.611Z" }, - { url = "https://files.pythonhosted.org/packages/6f/af/99a582b1b1641ff5911ac559beb45097cf79efd4ead4657f578ef1af2d47/cryptography-48.0.0-cp39-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:984a20b0f62a26f48a3396c72e4bc34c66e356d356bf370053066b3b6d54634a", size = 4326481, upload-time = "2026-05-04T22:58:57.607Z" }, - { url = "https://files.pythonhosted.org/packages/90/ee/89aa26a06ef0a7d7611788ffd571a7c50e368cc6a4d5eef8b4884e866edb/cryptography-48.0.0-cp39-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:5a5ed8fde7a1d09376ca0b40e68cd59c69fe23b1f9768bd5824f54681626032a", size = 4688713, upload-time = "2026-05-04T22:59:00.077Z" }, - { url = "https://files.pythonhosted.org/packages/70/ba/bcb1b0bb7a33d4c7c0c4d4c7874b4a62ae4f56113a5f4baefa362dfb1f0f/cryptography-48.0.0-cp39-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:8cd666227ef7af430aa5914a9910e0ddd703e75f039cef0825cd0da71b6b711a", size = 5238165, upload-time = "2026-05-04T22:59:02.317Z" }, - { url = "https://files.pythonhosted.org/packages/c9/70/ca4003b1ce5ca3dc3186ada51908c8a9b9ff7d5cab83cc0d43ee14ec144f/cryptography-48.0.0-cp39-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:9071196d81abc88b3516ac8cdfad32e2b66dd4a5393a8e68a961e9161ddc6239", size = 4729947, upload-time = "2026-05-04T22:59:05.255Z" }, - { url = "https://files.pythonhosted.org/packages/44/a0/4ec7cf774207905aef1a8d11c3750d5a1db805eb380ee4e16df317870128/cryptography-48.0.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:1e2d54c8be6152856a36f0882ab231e70f8ec7f14e93cf87db8a2ed056bf160c", size = 4822059, upload-time = "2026-05-04T22:59:07.802Z" }, - { url = "https://files.pythonhosted.org/packages/1e/75/a2e55f99c16fcac7b5d6c1eb19ad8e00799854d6be5ca845f9259eae1681/cryptography-48.0.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:a5da777e32ffed6f85a7b2b3f7c5cbc88c146bfcd0a1d7baf5fcc6c52ee35dd4", size = 4960575, upload-time = "2026-05-04T22:59:09.851Z" }, - { url = "https://files.pythonhosted.org/packages/b8/23/6e6f32143ab5d8b36ca848a502c4bcd477ae75b9e1677e3530d669062578/cryptography-48.0.0-cp39-abi3-win32.whl", hash = "sha256:77a2ccbbe917f6710e05ba9adaa25fb5075620bf3ea6fb751997875aff4ae4bd", size = 3279117, upload-time = "2026-05-04T22:59:12.019Z" }, - { url = "https://files.pythonhosted.org/packages/9d/9a/0fea98a70cf1749d41d738836f6349d97945f7c89433a259a6c2642eefeb/cryptography-48.0.0-cp39-abi3-win_amd64.whl", hash = "sha256:16cd65b9330583e4619939b3a3843eec1e6e789744bb01e7c7e2e62e33c239c8", size = 3792100, upload-time = "2026-05-04T22:59:14.884Z" }, + { url = "https://files.pythonhosted.org/packages/9b/22/adf66990e63584a68dfb50c24f48a125c07b1699899381c8151e63ed458c/cryptography-49.0.0-cp311-abi3-macosx_11_0_arm64.whl", hash = "sha256:966fe0e9c67490071f14c0d2b1cb2dfb3023c5ce39457343931415f08382f2db", size = 4032100, upload-time = "2026-06-12T20:02:32.143Z" }, + { url = "https://files.pythonhosted.org/packages/09/41/3797cfaf69cae04a13ee78ebd83f0678d9c02b4779d21ce24445326f1a69/cryptography-49.0.0-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:36d1709f992593689b45bda411498d62c6e365f2ca00b84657d4dadd24de16db", size = 4692978, upload-time = "2026-06-12T20:01:21.305Z" }, + { url = "https://files.pythonhosted.org/packages/e6/8b/43011f7ebe515a8aa20d61f290a326cd890c2e738e16e59eaff8d9c3a412/cryptography-49.0.0-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:0e959b578856a3924bc0cbb710fc12c387b9412a951389f3ca61704a9e25f325", size = 4716422, upload-time = "2026-06-12T20:01:48.566Z" }, + { url = "https://files.pythonhosted.org/packages/4a/91/01ce7303a4579e6d3a6abef01bd322848e9ea7a219adcabc5048b9033571/cryptography-49.0.0-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:53ecee2e23f7169b6117e99fc8a944e5e50f79e69758a83b52a00cb98ab2b2d2", size = 4700503, upload-time = "2026-06-12T20:02:47.091Z" }, + { url = "https://files.pythonhosted.org/packages/62/99/a2c95cf8293f07491e9e27c20cc4dcd18176d944e674679adeb1d0173fd6/cryptography-49.0.0-cp311-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:2eda353d8a27bcbcaa4cbed18994a74ab4d19a2ca897db188ea269ab9b71419b", size = 5309779, upload-time = "2026-06-12T20:02:08.987Z" }, + { url = "https://files.pythonhosted.org/packages/20/2c/0622f20ff02b2ef32558733443805dc82fd4c275be01b2d19d14676f3a1b/cryptography-49.0.0-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:2afe9051da7ae7bd5905da5a949280c7d2bb75682e188f650a9d0f2756b834c6", size = 4749683, upload-time = "2026-06-12T20:02:03.335Z" }, + { url = "https://files.pythonhosted.org/packages/a3/5b/c5246635d5fd3b64e0d45ae10e99fd32fe9676a79915ccfe5a61ba9af1a5/cryptography-49.0.0-cp311-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:0b82e28ee398a386f0807bba7884d30f25218855690f45115831bcce5d90822c", size = 4337874, upload-time = "2026-06-12T20:02:54.323Z" }, + { url = "https://files.pythonhosted.org/packages/6d/88/05563c7fe2e914e87d1a536d06fe83e66b4e1d95cb593e05aea375531da8/cryptography-49.0.0-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:ccac2bfebc306b862133e3bb71f3f6ee8bb525240089b2d952e4144b3a6d5da7", size = 4700283, upload-time = "2026-06-12T20:01:34.822Z" }, + { url = "https://files.pythonhosted.org/packages/c4/b6/d7696e4e890d6ae1469935164c9e5215c557671cb78d6e3f458ccceaa632/cryptography-49.0.0-cp311-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:d0527ce944105f257f605a827d6ebead966c752038b6e8656abb9c5edee6fc68", size = 5265844, upload-time = "2026-06-12T20:01:24.09Z" }, + { url = "https://files.pythonhosted.org/packages/a9/3c/f3ad17eecc1a57b0ba236dc01f90e783c51f4a2f35f64777cc4f47a184b2/cryptography-49.0.0-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:cbc77da8c523d5abd028635ba850a6966fcee2c82e2bf65a41d1d8afe0f98be9", size = 4749290, upload-time = "2026-06-12T20:01:30.848Z" }, + { url = "https://files.pythonhosted.org/packages/4f/01/339573cf1023163a400b0b5d16f6d507de413b9f60be6fd1b77feeaf6737/cryptography-49.0.0-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:b87e65d263b3e5d3bb92a57e2a6638e2f31110fa7aa890c7b2dbba42248d0a3f", size = 4834612, upload-time = "2026-06-12T20:01:29.246Z" }, + { url = "https://files.pythonhosted.org/packages/71/fd/577302e213a1be9468f92d1afef66fcf1ef83d516819d9992ca547f592bd/cryptography-49.0.0-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:66ec79c3904820572d7e987abdf304281f141d37ad9a489b8e97066e7b9b6459", size = 4980804, upload-time = "2026-06-12T20:01:42.853Z" }, + { url = "https://files.pythonhosted.org/packages/1f/09/f42b1d190c5ba75f72062a387f8030d1d75f6ab035788f1d9c4b01de6525/cryptography-49.0.0-cp311-abi3-win_amd64.whl", hash = "sha256:e5dfc1e64de5677cec922ffa8da89c546d0415bf6efdf081842e5d44c84e1f0e", size = 3810026, upload-time = "2026-06-12T20:02:39.262Z" }, + { url = "https://files.pythonhosted.org/packages/19/2a/5bb823f5bedcf80718cea7fbc95ec5515cca3769633c4b01a32be7f30e7c/cryptography-49.0.0-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:ec5e529fb80935c94fe7b729f9972b50e351a0e6b50aa294fd5cabb109fcc29a", size = 4025947, upload-time = "2026-06-12T20:01:25.745Z" }, + { url = "https://files.pythonhosted.org/packages/3d/df/40577043ca124e17012f408ddddaeb213b856336ac82ddb3bc915f39e29f/cryptography-49.0.0-cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:f78ff2c9ed8dc2d036b0f4d640e22522213d047c1b14e61205a7e55c80a494d4", size = 4692429, upload-time = "2026-06-12T20:01:53.628Z" }, + { url = "https://files.pythonhosted.org/packages/2c/99/2d13299eb3dd27b02dcfaafcc91d6b5cb3329f7cbd6d8f51921acd566c1a/cryptography-49.0.0-cp39-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:35b151772baff2c74cba7fa290ceaff4c3b11c0c881eb93eb5dbc05a7cfbba18", size = 4700968, upload-time = "2026-06-12T20:02:45.383Z" }, + { url = "https://files.pythonhosted.org/packages/a5/4d/9c0cd02f95e2602dd5e563da149ee0830abef3537be8b34dc56281ebe27a/cryptography-49.0.0-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:0f21641cf4b30fca7aee061ced0ec7ad7b073518088b7c9969a297c0ae796c69", size = 4697758, upload-time = "2026-06-12T20:01:41.13Z" }, + { url = "https://files.pythonhosted.org/packages/24/01/186c825898477d77e2324d5360fefe622ff1d8d1963ec0554e2cada8ec77/cryptography-49.0.0-cp39-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:9e82dcc8e56052715fb18b2429e3bca4823b1629136a2084fc45a9a5cecb9b64", size = 5298863, upload-time = "2026-06-12T20:02:24.579Z" }, + { url = "https://files.pythonhosted.org/packages/b8/7b/62cbbab75d0659865bf0273790031544a0b16c8072d258f9428dcd8190dc/cryptography-49.0.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:6f2debedf9ca60cf1d5bd466475638af5130f89965605cd818484d19987d3a21", size = 4735983, upload-time = "2026-06-12T20:01:50.14Z" }, + { url = "https://files.pythonhosted.org/packages/6c/72/3e798c064bc39e471008075d0f9bc9daf77a80879c092e4a8e170c585ed4/cryptography-49.0.0-cp39-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:8c25ceb16df5b9435f3f6a9829204985b0e0cbee3b48aacd432c7d2c850b44d9", size = 4334173, upload-time = "2026-06-12T20:01:44.743Z" }, + { url = "https://files.pythonhosted.org/packages/f0/ee/6fca21d1ac73e06f8bef71940abfd4d2f6472b4bca284d770f32bd4086f6/cryptography-49.0.0-cp39-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:28d8b15e6275f12c8a207dc309dfa957903c927d08d0cc937ee3f63f200693cc", size = 4697298, upload-time = "2026-06-12T20:02:20.918Z" }, + { url = "https://files.pythonhosted.org/packages/67/d0/a5fcd3515f0bae49a7b6d0413cc1bdccdcc1fc0047037a0d480642cdc5d6/cryptography-49.0.0-cp39-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:6fc361c34fb6aac015ce19435876635e5c6d21db31998b0920f675f131e043b8", size = 5254338, upload-time = "2026-06-12T20:02:22.737Z" }, + { url = "https://files.pythonhosted.org/packages/a0/84/84fe36f19caf857d61cb7fc9c63035a47ffabd84ea12d1d393148efa3615/cryptography-49.0.0-cp39-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:2400ef9c9e2299a25614eb1dea3db54a69b1349efd043bfac9c67630d136df36", size = 4735650, upload-time = "2026-06-12T20:02:41.389Z" }, + { url = "https://files.pythonhosted.org/packages/6c/a0/db537264e234f7273a73ec020873d6d6b39dfd8a53db78b550ca8320440e/cryptography-49.0.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:67e1d20ad9ef3a563c59ef22e7a8a0b8210bd26604369ea4a30a7c66aefe504e", size = 4834820, upload-time = "2026-06-12T20:01:51.847Z" }, + { url = "https://files.pythonhosted.org/packages/93/77/8df9eb486495979bccecd1062e2eaf435250e84437040295b57d09048b0b/cryptography-49.0.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:42b0684e0e40cf26122427802486f6d93aea593612603a94fbf260c7eb1e9c1b", size = 4967968, upload-time = "2026-06-12T20:02:12.524Z" }, + { url = "https://files.pythonhosted.org/packages/c2/e6/f60198ea8d9dfa15fff9ed4ca02ce362f6eadd9ba757dcc50634c4257b63/cryptography-49.0.0-cp39-abi3-win_amd64.whl", hash = "sha256:026ac7423e6fa66872d3bf889be5974507da3944f866f704fa200eadacd00001", size = 3785547, upload-time = "2026-06-12T20:02:26.847Z" }, ] [[package]] @@ -306,11 +304,11 @@ wheels = [ [[package]] name = "deepmerge" -version = "2.0" +version = "2.1.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a8/3a/b0ba594708f1ad0bc735884b3ad854d3ca3bdc1d741e56e40bbda6263499/deepmerge-2.0.tar.gz", hash = "sha256:5c3d86081fbebd04dd5de03626a0607b809a98fb6ccba5770b62466fe940ff20", size = 19890, upload-time = "2024-08-30T05:31:50.308Z" } +sdist = { url = "https://files.pythonhosted.org/packages/2a/78/6e9e20106224083cfb817d2d3c26e80e72258d617b616721a169b87081e0/deepmerge-2.1.0.tar.gz", hash = "sha256:07ca7a7b8935df596c512fa8161877c0487ac61f691c07766e7d71d2b23bdd2f", size = 21449, upload-time = "2026-06-22T05:46:07.669Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/2d/82/e5d2c1c67d19841e9edc74954c827444ae826978499bde3dfc1d007c8c11/deepmerge-2.0-py3-none-any.whl", hash = "sha256:6de9ce507115cff0bed95ff0ce9ecc31088ef50cbdf09bc90a09349a318b3d00", size = 13475, upload-time = "2024-08-30T05:31:48.659Z" }, + { url = "https://files.pythonhosted.org/packages/51/25/2a75b47cb057b1e164c604fb81ab690a6cdb5e2260ce651194eae90f64a3/deepmerge-2.1.0-py3-none-any.whl", hash = "sha256:8f148339a91d680a75ecb74ade235d9e759a93df373a0b04e9d31c8666cfeb75", size = 14345, upload-time = "2026-06-22T05:46:06.742Z" }, ] [[package]] @@ -325,7 +323,7 @@ wheels = [ [[package]] name = "eigen" version = "3.4.0" -source = { git = "https://github.com/commaai/dependencies.git?subdirectory=eigen&rev=release-eigen#f855b17636a376d8399f3df03629ff3e535f6b22" } +source = { git = "https://github.com/commaai/dependencies.git?subdirectory=eigen&rev=release-eigen#9d2dba116fa763abf9bfaea17037ab7ed15c20a7" } [[package]] name = "execnet" @@ -339,7 +337,7 @@ wheels = [ [[package]] name = "ffmpeg" version = "7.1.0" -source = { git = "https://github.com/commaai/dependencies.git?subdirectory=ffmpeg&rev=release-ffmpeg#f5153626027621f8ac0cdec056d254d3a1ef6acd" } +source = { git = "https://github.com/commaai/dependencies.git?subdirectory=ffmpeg&rev=release-ffmpeg#fefb542cea16c9e151a05684591cf956c3ebfe0c" } [[package]] name = "fonttools" @@ -361,12 +359,12 @@ wheels = [ [[package]] name = "gcc-arm-none-eabi" version = "13.2.1" -source = { git = "https://github.com/commaai/dependencies.git?subdirectory=gcc-arm-none-eabi&rev=release-gcc-arm-none-eabi#15791161bd7a752ef821ad6d999a364b13d6e9ca" } +source = { git = "https://github.com/commaai/dependencies.git?subdirectory=gcc-arm-none-eabi&rev=release-gcc-arm-none-eabi#89a0ae5aa2f36057351e8ae392a82dd0b9506174" } [[package]] name = "git-lfs" version = "3.6.1" -source = { git = "https://github.com/commaai/dependencies.git?subdirectory=git-lfs&rev=release-git-lfs#035fb711541a6d8609bb57b26c2f31813c743eb3" } +source = { git = "https://github.com/commaai/dependencies.git?subdirectory=git-lfs&rev=release-git-lfs#866e78eb06963c78721e01f8cd4a0dadcf187a14" } [[package]] name = "google-crc32c" @@ -396,11 +394,11 @@ wheels = [ [[package]] name = "idna" -version = "3.17" +version = "3.18" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b9/28/99c51f664567218d824af024c0251650fb27e4ca066df188dab0769c5b91/idna-3.17.tar.gz", hash = "sha256:5eb0cb53bc467c12eadcf6de83163ad8527cec9416f44b9b61b19caedad2b87f", size = 196048, upload-time = "2026-05-28T14:32:38.55Z" } +sdist = { url = "https://files.pythonhosted.org/packages/cd/63/9496c57188a2ee585e0f1db071d75089a11e98aa86eb99d9d7618fc1edce/idna-3.18.tar.gz", hash = "sha256:ffb385a7e039654cef1ab9ef32c6fafe283c0c0467bba1d9029738ce4a14a848", size = 196711, upload-time = "2026-06-02T14:34:07.794Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/de/a7/f76514cc40ad6234098ecdebda08732d75964776c51a42845b7da10649e2/idna-3.17-py3-none-any.whl", hash = "sha256:466e48829084efe2548012b855df21540b96f2e20e51bd124c851536556a592c", size = 65316, upload-time = "2026-05-28T14:32:37.035Z" }, + { url = "https://files.pythonhosted.org/packages/1e/5e/d4e9f1a599fb8e573b7b87160658329fbf28d19eac2718f51fc3def3aa5a/idna-3.18-py3-none-any.whl", hash = "sha256:7f952cbe720b688055e3f87de14f5c3e5fdaa8bc3928985c4077ca689de849a2", size = 65455, upload-time = "2026-06-02T14:34:06.319Z" }, ] [[package]] @@ -415,7 +413,7 @@ wheels = [ [[package]] name = "imgui" version = "1.92.7" -source = { git = "https://github.com/commaai/dependencies.git?subdirectory=imgui&rev=release-imgui#af4a30c3930c5e19cf8cea128e342686ba283624" } +source = { git = "https://github.com/commaai/dependencies.git?subdirectory=imgui&rev=release-imgui#6e183051fcfedebc1d765571f10c4f1e27e6c8e6" } [[package]] name = "iniconfig" @@ -468,7 +466,7 @@ wheels = [ [[package]] name = "json11" version = "20170411.0" -source = { git = "https://github.com/commaai/dependencies.git?subdirectory=json11&rev=release-json11#0443a506c32eadfec2071a7c163c38c6c7b81d66" } +source = { git = "https://github.com/commaai/dependencies.git?subdirectory=json11&rev=release-json11#39d9a6fcb2b85f1d30486861da761a9d5b8b523b" } [[package]] name = "kiwisolver" @@ -500,12 +498,12 @@ wheels = [ [[package]] name = "libjpeg" version = "3.1.0" -source = { git = "https://github.com/commaai/dependencies.git?subdirectory=libjpeg&rev=release-libjpeg#a615ec26d971cc4cca9a1a426e2c996760fe3c7f" } +source = { git = "https://github.com/commaai/dependencies.git?subdirectory=libjpeg&rev=release-libjpeg#f39de7bd84f043d280e843ec89a8b3185ff7db6e" } [[package]] name = "libusb" version = "1.0.29" -source = { git = "https://github.com/commaai/dependencies.git?subdirectory=libusb&rev=release-libusb#23132cff0d629bf69590e23b6a682950433aaec8" } +source = { git = "https://github.com/commaai/dependencies.git?subdirectory=libusb&rev=release-libusb#d35ca758bf9d77a757a56c7f3e4a8ecead82d3e4" } [[package]] name = "libusb1" @@ -521,7 +519,7 @@ wheels = [ [[package]] name = "libyuv" version = "1922.0" -source = { git = "https://github.com/commaai/dependencies.git?subdirectory=libyuv&rev=release-libyuv#70295e7a22d89f9c5bdb61dd93c30f0cbb55d815" } +source = { git = "https://github.com/commaai/dependencies.git?subdirectory=libyuv&rev=release-libyuv#c6d2856b35c3965308ef1a6eff4b474ea6fd1d28" } [[package]] name = "markdown" @@ -553,7 +551,7 @@ wheels = [ [[package]] name = "matplotlib" -version = "3.10.9" +version = "3.11.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "contourpy" }, @@ -566,15 +564,15 @@ dependencies = [ { name = "pyparsing" }, { name = "python-dateutil" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/63/1b/4be5be87d43d327a0cf4de1a56e86f7f84c89312452406cf122efe2839e6/matplotlib-3.10.9.tar.gz", hash = "sha256:fd66508e8c6877d98e586654b608a0456db8d7e8a546eb1e2600efd957302358", size = 34811233, upload-time = "2026-04-24T00:14:13.539Z" } +sdist = { url = "https://files.pythonhosted.org/packages/1f/24/080c99d223d158d3a8902769269ab6da5b50f7a0e6e072513907e02b7a6c/matplotlib-3.11.0.tar.gz", hash = "sha256:68c0c7be01b30dcca3638934f7f591df73401235cbdbf0d1ab1c71e7db7f8b57", size = 33251176, upload-time = "2026-06-12T02:29:15.508Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/35/c6/5581e26c72233ebb2a2a6fed2d24fb7c66b4700120b813f51b0555acf0b6/matplotlib-3.10.9-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f0c3c28d9fbcc1fe7a03be236d73430cf6409c41fb2383a7ac52fe932b072cb1", size = 8319908, upload-time = "2026-04-24T00:12:21.323Z" }, - { url = "https://files.pythonhosted.org/packages/b7/18/4880dd762e40cd360c1bf06e890c5a97b997e91cb324602b1a19950ad5ce/matplotlib-3.10.9-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:41cb28c2bd769aa3e98322c6ab09854cbcc52ab69d2759d681bba3e327b2b320", size = 8216016, upload-time = "2026-04-24T00:12:23.4Z" }, - { url = "https://files.pythonhosted.org/packages/32/91/d024616abdba99e83120e07a20658976f6a343646710760c4a51df126029/matplotlib-3.10.9-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ae20801130378b82d647ff5047c07316295b68dc054ca6b3c13519d0ea624285", size = 8789336, upload-time = "2026-04-24T00:12:26.096Z" }, - { url = "https://files.pythonhosted.org/packages/5c/04/030a2f61ef2158f5e4c259487a92ac877732499fb33d871585d89e03c42d/matplotlib-3.10.9-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6c63ebcd8b4b169eb2f5c200552ae6b8be8999a005b6b507ed76fb8d7d674fe2", size = 9604602, upload-time = "2026-04-24T00:12:29.052Z" }, - { url = "https://files.pythonhosted.org/packages/fc/c2/541e4d09d87bb6b5830fc28b4c887a9a8cf4e1c6cee698a8c05552ae2003/matplotlib-3.10.9-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d75d11c949914165976c621b2324f9ef162af7ebf4b057ddf95dd1dba7e5edcf", size = 9670966, upload-time = "2026-04-24T00:12:32.131Z" }, - { url = "https://files.pythonhosted.org/packages/04/a1/4571fc46e7702de8d0c2dc54ad1b2f8e29328dea3ee90831181f7353d93c/matplotlib-3.10.9-cp312-cp312-win_amd64.whl", hash = "sha256:d091f9d758b34aaaaa6331d13574bf01891d903b3dec59bfff458ef7551de5d6", size = 8217462, upload-time = "2026-04-24T00:12:35.226Z" }, - { url = "https://files.pythonhosted.org/packages/4b/d0/2269edb12aa30c13c8bcc9382892e39943ce1d28aab4ec296e0381798e81/matplotlib-3.10.9-cp312-cp312-win_arm64.whl", hash = "sha256:10cc5ce06d10231c36f40e875f3c7e8050362a4ee8f0ee5d29a6b3277d57bb42", size = 8136688, upload-time = "2026-04-24T00:12:37.442Z" }, + { url = "https://files.pythonhosted.org/packages/da/17/f5276b496c61477a6c4fc5e7401f4bfe1c2e5ef7c6cd67896f2ade3809cb/matplotlib-3.11.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:06b5872e9cf11adc8f589ded3ce11bc3e1061ad498259664fabc1f6615beb918", size = 9449976, upload-time = "2026-06-12T02:27:50.989Z" }, + { url = "https://files.pythonhosted.org/packages/82/34/bdd77418adb2178a1d59f044bd67bfebb115896e91b840b8a197eb3f4f4e/matplotlib-3.11.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0515d495124be3124340e59f164d901ed4484e2246a5b74cfa483cac3b80bd97", size = 9279307, upload-time = "2026-06-12T02:27:53.247Z" }, + { url = "https://files.pythonhosted.org/packages/94/95/7f522393c88313336b20d70fc849555757b2e5febc22b83b3a3f0fd4bce9/matplotlib-3.11.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:be5f93a1d21981bfb802ded0d77a0caa92d4342a47d45754fac77e314a506344", size = 10031353, upload-time = "2026-06-12T02:27:55.215Z" }, + { url = "https://files.pythonhosted.org/packages/87/ce/8f25a0e3186aefd61913e7467d1b999465bcd0d0c03ac695c1b26ca559b7/matplotlib-3.11.0-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:41635d7909d19e52e924a521dde6d8f670b0f53ab1d0e8c331fa831554f681d1", size = 10839232, upload-time = "2026-06-12T02:27:57.746Z" }, + { url = "https://files.pythonhosted.org/packages/85/c2/db15da2bbdf9e3ca66df7db8e2c33a1dfed67be24a24d2c878efaaff01d6/matplotlib-3.11.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:94f5000f67ca9faa300863ea17f8bce9175cb67b88bec4bc7780502d53dd7c9e", size = 10923899, upload-time = "2026-06-12T02:28:00.223Z" }, + { url = "https://files.pythonhosted.org/packages/e5/2f/a58a4443a4d052a4ea77557478336aefc26c7981f6408d37adba763aa758/matplotlib-3.11.0-cp312-cp312-win_amd64.whl", hash = "sha256:ac6f1ef39f3d0f9e2463303013094992cdbe0f85f43bc54155bc472b2042768e", size = 9329528, upload-time = "2026-06-12T02:28:02.27Z" }, + { url = "https://files.pythonhosted.org/packages/61/0f/4b669589d47733b97ab9df4b58d6fc1e68acb5ea42a928dc7cbdd6bf5871/matplotlib-3.11.0-cp312-cp312-win_arm64.whl", hash = "sha256:9dd11fb612ce7bc60b1de5b4fc87ff959d22317b5de42aabf392f66f97af22eb", size = 9003413, upload-time = "2026-06-12T02:28:04.49Z" }, ] [[package]] @@ -589,25 +587,25 @@ wheels = [ [[package]] name = "ncurses" version = "6.5" -source = { git = "https://github.com/commaai/dependencies.git?subdirectory=ncurses&rev=release-ncurses#eae89aae0266b3fbae7b808a3c0c19a97a82a81c" } +source = { git = "https://github.com/commaai/dependencies.git?subdirectory=ncurses&rev=release-ncurses#c46bad849b29b29bb041805a4c895c7e1d5c0b7e" } [[package]] name = "numpy" -version = "2.4.6" +version = "2.5.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d0/ad/fed0499ce6a338d2a03ebae59cd15093910c8875328855781952abf6c2fe/numpy-2.4.6.tar.gz", hash = "sha256:f3a3570c4a2a16746ac2c31a7c7c7b0c186b95ce902e33db6f28094ed7387dda", size = 20735807, upload-time = "2026-05-18T23:37:14.07Z" } +sdist = { url = "https://files.pythonhosted.org/packages/e7/05/3d27272d30698dc0ecb7fdfaa41ad70303b444f81722bb99bce1d818638a/numpy-2.5.0.tar.gz", hash = "sha256:5a129578019311b6e56bdd714250f19b518f7dceeeb8d1af5490f4942d3f891c", size = 20652461, upload-time = "2026-06-21T20:57:51.95Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/95/2a/3d7b5ac8aac24feaf9ad7ed58f45b0bbc06d37e4338ae84c9f2298b570f9/numpy-2.4.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:001fbb8e08d942dd57599e781f2472269ee7f2755fae407b4f67b2f0b17da3f1", size = 16689119, upload-time = "2026-05-18T23:33:54.065Z" }, - { url = "https://files.pythonhosted.org/packages/ea/12/92c4c131527599e8288d6918e888d88726f84d805d784b771f32408aeaef/numpy-2.4.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ebfb099f8dcf083deef3ac1ca4c1503f387cf76296fcb3816b66f5ecb5f54fdb", size = 14699246, upload-time = "2026-05-18T23:33:57.621Z" }, - { url = "https://files.pythonhosted.org/packages/ad/fe/c0a6b7b2ca128a8fb228575147073b660656734b8ebe4d76c8fd748dcc79/numpy-2.4.6-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:3213d622a0283a39a93d188f3cf72b26862df52fbb4ca3697f51705016523d41", size = 5204410, upload-time = "2026-05-18T23:34:00.302Z" }, - { url = "https://files.pythonhosted.org/packages/f3/d4/9770d14ba719432bb90a421bfd443872ed0f70f7264b64bec12ea363d5fd/numpy-2.4.6-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:357cc07a6d7b0b182ff02249616a03742827ebb1277546b5c7cd7f7620a45698", size = 6551240, upload-time = "2026-05-18T23:34:02.852Z" }, - { url = "https://files.pythonhosted.org/packages/c9/c6/50a46a6205feba2343f1d6d17438107c5dc491ed1c736e6ea68689fd906b/numpy-2.4.6-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5f9fb9157b4ce2971008323afe46053787b526ef624fea915b261468a8421a0f", size = 15671012, upload-time = "2026-05-18T23:34:05.485Z" }, - { url = "https://files.pythonhosted.org/packages/99/60/14115e6364fa676c5397c2ad3004e527e9aa487abf5d0706ec81bbd08529/numpy-2.4.6-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:90f9849678c75fe7afa2d348ac842c168b0a4d3d61919687216dfc547976d853", size = 16645538, upload-time = "2026-05-18T23:34:09.265Z" }, - { url = "https://files.pythonhosted.org/packages/ae/c5/693cbe59e57db94d2231fa519ca3978dc9e19da5a8f088588f5c6e947ff2/numpy-2.4.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:c1a2af6c6ef86344a6b0db6b97834208bf598db514f2b155042439b62605601a", size = 17020706, upload-time = "2026-05-18T23:34:13.053Z" }, - { url = "https://files.pythonhosted.org/packages/ef/fc/85b7c4eff9b4966ade25c2273cf7e7012e92366c032058653934b37de044/numpy-2.4.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e5805d5a22fd19c8ccff10a9561f9df94436b0545619ea579db2d3c35294bce2", size = 18368541, upload-time = "2026-05-18T23:34:17.024Z" }, - { url = "https://files.pythonhosted.org/packages/f6/81/e1b27545deedce7f4a0b348618c6b62d74e36a4dc9ccd42f3eb2f85eee32/numpy-2.4.6-cp312-cp312-win32.whl", hash = "sha256:e3eeb0aabd6bd5ce64faae67e9935203a6991b4bc2a485a767fbafb2c5125f45", size = 5962825, upload-time = "2026-05-18T23:34:20.3Z" }, - { url = "https://files.pythonhosted.org/packages/ab/ca/feab00bd44aa5fe1ad2c18f08b4d3bb92e26484b0b1d1443897809ed528c/numpy-2.4.6-cp312-cp312-win_amd64.whl", hash = "sha256:d8e8286dd7cea7895157318d1b91cdacac64c479f3cbc8dce548331728484751", size = 12321687, upload-time = "2026-05-18T23:34:23.095Z" }, - { url = "https://files.pythonhosted.org/packages/63/cf/5a6d34850a39d1093558564f77ee8e8e0bee5061151b8f05a55711001ec7/numpy-2.4.6-cp312-cp312-win_arm64.whl", hash = "sha256:4081eb135ac24158bd51cdfbef16f1c64df7063b1143f24731387137c092bec8", size = 10221482, upload-time = "2026-05-18T23:34:25.876Z" }, + { url = "https://files.pythonhosted.org/packages/fa/0a/11486d02add7b1384dff7374d124b1cfbb0ee864dcc9f6a2c0380638cf84/numpy-2.5.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:489780423903667933b4ed6197b6ec3b75ea5dd17d1d8f0f38d798feb6921561", size = 16789987, upload-time = "2026-06-21T20:56:16.657Z" }, + { url = "https://files.pythonhosted.org/packages/55/b2/285f48640a181947b4587a3766d21ec1eaa7fea833d4b49957e09da467a2/numpy-2.5.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ece55976ced6bca95a03ae2839e2e5ccffe8eb6a3e7022415645eb154a81e4e6", size = 11760322, upload-time = "2026-06-21T20:56:19.813Z" }, + { url = "https://files.pythonhosted.org/packages/dd/67/b032db1eb03ca30d16eda3b0c22aaa615338b9263c2fd559d0f29451aca4/numpy-2.5.0-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:c83b664b0e6eee9594fa920cf0639d8af796606d3fad6cc70180c87e4b97c7be", size = 5319605, upload-time = "2026-06-21T20:56:22.173Z" }, + { url = "https://files.pythonhosted.org/packages/b9/83/03fc7300c7c6b6c84c487b1dc80d322817b95fbd1f4dd57a85e23b7198de/numpy-2.5.0-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:bf80333980bf37f523341ddd72c783f39d6829ec7736b9eb99086388a2d52cc2", size = 6653628, upload-time = "2026-06-21T20:56:23.914Z" }, + { url = "https://files.pythonhosted.org/packages/82/49/2ec21730bc63ccfda829323f7040a8ed4715b3852ce658689cf74ee96a8c/numpy-2.5.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a1a4874217b36d5ac8fc876f52e39df56f8182c88463e9e2dceabf7ca8b7efb8", size = 15153691, upload-time = "2026-06-21T20:56:25.631Z" }, + { url = "https://files.pythonhosted.org/packages/bb/6b/f4a3d0637692c49da8ef99d72d52526f92e0a8d6ac4f0ca9f31441b9d9ea/numpy-2.5.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:aaa760137137e8d3c920d27927748215b56014f92667dc9b6c27dfc61249255a", size = 16660066, upload-time = "2026-06-21T20:56:28.009Z" }, + { url = "https://files.pythonhosted.org/packages/3a/2f/c354ec86d1f3f5c19649463b0d39652e160736e5b0a4cd18dff0576715c4/numpy-2.5.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7174ce8265fc7f7417d171c9ea8fe905220748893ea67a2a7abe726ec331c4b0", size = 16514638, upload-time = "2026-06-21T20:56:30.26Z" }, + { url = "https://files.pythonhosted.org/packages/06/34/43efdcb319988648580f93c11f1ae82cf7e2faa74925e98e454ae3aa95f8/numpy-2.5.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b8c3daaf99de52415d20b42f8e8155c78642cb04207d02f9d317a0dcf1b3fb54", size = 18419647, upload-time = "2026-06-21T20:56:32.41Z" }, + { url = "https://files.pythonhosted.org/packages/71/e2/f5d1676b1d7fb682eb5e9a1641e7ebd2414b3216c370661d1029778908b4/numpy-2.5.0-cp312-cp312-win32.whl", hash = "sha256:6206db0af545d73d068add6d992279145f158428d1da6cc49adc4b630c5d6ee5", size = 6056688, upload-time = "2026-06-21T20:56:34.657Z" }, + { url = "https://files.pythonhosted.org/packages/8f/7c/48f115d1c58a34032facebcd51fdf2d02df2c51d4a46a81dd1197bb2ea6b/numpy-2.5.0-cp312-cp312-win_amd64.whl", hash = "sha256:6f2d6873e2940c860a309d21e25b1e69af6aaffdd80aa056b04c16380db1c4f2", size = 12419237, upload-time = "2026-06-21T20:56:36.24Z" }, + { url = "https://files.pythonhosted.org/packages/86/26/2e0882f4044d1b1a1b63e875151fb2393389032022a8b7f5657a7996d3b2/numpy-2.5.0-cp312-cp312-win_arm64.whl", hash = "sha256:a55e1eb2bca2cfd17a16b213c99dfc8502d47b0d494224d2122277d0400935ca", size = 10339912, upload-time = "2026-06-21T20:56:38.733Z" }, ] [[package]] @@ -938,15 +936,15 @@ wheels = [ [[package]] name = "pyopenssl" -version = "26.2.0" +version = "26.3.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "cryptography" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/1a/51/27a5ad5f939d08f690a326ef9582cda7140555180db71695f6fb747d6a36/pyopenssl-26.2.0.tar.gz", hash = "sha256:8c6fcecd1183a7fc897548dfe388b0cdb7f37e018200d8409cf33959dbe35387", size = 182195, upload-time = "2026-05-04T23:06:09.72Z" } +sdist = { url = "https://files.pythonhosted.org/packages/74/b7/da07bae88f5a9506b4def6f2f4903cf4c3b8831e560dba8fa18ca08f758f/pyopenssl-26.3.0.tar.gz", hash = "sha256:589de7fae1c9ea670d18422ed00fc04da787bbde8e1454aea872aa57b49ad341", size = 182024, upload-time = "2026-06-12T20:28:07.458Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/73/b8/a0e2790ae249d6f38c9f66de7a211621a7ab2650217bcd04e1262f578a56/pyopenssl-26.2.0-py3-none-any.whl", hash = "sha256:4f9d971bc5298b8bc1fab282803da04bf000c755d4ad9d99b52de2569ca19a70", size = 55823, upload-time = "2026-05-04T23:06:08.395Z" }, + { url = "https://files.pythonhosted.org/packages/54/18/1dd71c9b43192ab83f1d531ad6002dc81108ac36c475f79fb7a295abe2f4/pyopenssl-26.3.0-py3-none-any.whl", hash = "sha256:46367f8f66b92271e6d218da9c87607e1ef5a0bc5c8dea5bb3db82f395c385a3", size = 56008, upload-time = "2026-06-12T20:28:05.999Z" }, ] [[package]] @@ -969,7 +967,7 @@ wheels = [ [[package]] name = "pytest" -version = "9.0.3" +version = "9.1.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, @@ -978,9 +976,9 @@ dependencies = [ { name = "pluggy" }, { name = "pygments" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/7d/0d/549bd94f1a0a402dc8cf64563a117c0f3765662e2e668477624baeec44d5/pytest-9.0.3.tar.gz", hash = "sha256:b86ada508af81d19edeb213c681b1d48246c1a91d304c6c81a427674c17eb91c", size = 1572165, upload-time = "2026-04-07T17:16:18.027Z" } +sdist = { url = "https://files.pythonhosted.org/packages/e4/47/b9efed96c114afcfa3c9d3fe98a76a1d14c74a9e266d397cf6eb64be5e01/pytest-9.1.1.tar.gz", hash = "sha256:1088fbde8f2b49d95a549a195707afa7a76a3ce9bcadc26b6d71f0ffda5fe313", size = 1636369, upload-time = "2026-06-19T10:58:32.857Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d4/24/a372aaf5c9b7208e7112038812994107bc65a84cd00e0354a88c2c77a617/pytest-9.0.3-py3-none-any.whl", hash = "sha256:2c5efc453d45394fdd706ade797c0a81091eccd1d6e4bccfcd476e2b8e0ab5d9", size = 375249, upload-time = "2026-04-07T17:16:16.13Z" }, + { url = "https://files.pythonhosted.org/packages/24/25/1de2678b631f5a49215c6c96fff41ba892b0a34df68d6d80292b1b48aa7f/pytest-9.1.1-py3-none-any.whl", hash = "sha256:37a86b45efb9a47a61a36449063e8e18d0cab3161329fc099eb21783169c4f0c", size = 386536, upload-time = "2026-06-19T10:58:31.347Z" }, ] [[package]] @@ -1095,7 +1093,7 @@ wheels = [ [[package]] name = "raylib" version = "6.0.0.0" -source = { git = "https://github.com/commaai/dependencies.git?subdirectory=raylib&rev=release-raylib#dbf05cd774c2f74a70a0ee9ebb80015ed70ce718" } +source = { git = "https://github.com/commaai/dependencies.git?subdirectory=raylib&rev=release-raylib#ed1a3f64532efe2f3761a681fd9133a88e5da664" } dependencies = [ { name = "cffi" }, ] @@ -1126,27 +1124,27 @@ wheels = [ [[package]] name = "ruff" -version = "0.15.15" +version = "0.15.18" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/84/6f/a76f7d96e5c962f5b69cee865e49c15c1116897c01990faa8a57edb62e7f/ruff-0.15.15.tar.gz", hash = "sha256:b8dff018130b46d8e5bf0f926ef6b60cf871d6d5ae45fc9334e09632daa741d6", size = 4706985, upload-time = "2026-05-28T14:16:57.784Z" } +sdist = { url = "https://files.pythonhosted.org/packages/74/98/1295ad5a5aa9bc85bdcdfa5d82fe7b49c61af5657df4f227637ff9de0da6/ruff-0.15.18.tar.gz", hash = "sha256:2698a964c70e8bf402dcb99c8810472d270d141e7aa8c4e13599fd52033a2f33", size = 4761437, upload-time = "2026-06-18T18:25:39.224Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/fa/9d/3a45c05b8ab04b4705989de70a79008e27c8003296a0feaee9edc18dd7e9/ruff-0.15.15-py3-none-linux_armv6l.whl", hash = "sha256:cf93e5388f412e1b108b1f8b34a6e036b70fe8aff89393befad96fe48670311b", size = 10710652, upload-time = "2026-05-28T14:16:06.701Z" }, - { url = "https://files.pythonhosted.org/packages/05/66/da974431624bf3b49f6ee1f9543c02d929ff1cba78b0d5a79c38cf21f744/ruff-0.15.15-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:ac5a646d1f6a7dadd5d50842dae2c1f9862ac887ef5d1b1375e02def791fde6e", size = 11096615, upload-time = "2026-05-28T14:16:23.313Z" }, - { url = "https://files.pythonhosted.org/packages/8c/09/7443452e5d290230a712103f2fdceeef7184f3ec99a2bd01c8be78aaceb5/ruff-0.15.15-py3-none-macosx_11_0_arm64.whl", hash = "sha256:77d955a431430c66f72dd94e379ad38a16daea3d25094872ac4edf9e797be530", size = 10436683, upload-time = "2026-05-28T14:16:40.974Z" }, - { url = "https://files.pythonhosted.org/packages/53/01/d330c26a57fa4f3943a14424904027428315b700fe4d14a84bb123a649e5/ruff-0.15.15-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7614ee79c69788cf6cedd568069ade9cecc22a1ad20494efe8d0c9ebb4b622d4", size = 10769064, upload-time = "2026-05-28T14:16:28.905Z" }, - { url = "https://files.pythonhosted.org/packages/1d/85/cc8770f8bdff541b1da8392d1634141fe4a0e3f4ee596605959b7906c27f/ruff-0.15.15-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3cdb1679e06a1f6b47bc384714ae96f6e2fb65ca441eb78c43d2ca554176ce1f", size = 10511987, upload-time = "2026-05-28T14:16:43.732Z" }, - { url = "https://files.pythonhosted.org/packages/7c/29/8c190c1472b63013583ba391f3342036e02010544c1270455ed8e519bdf3/ruff-0.15.15-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2728b93d7b23a603ea2c0ac6eb73d760bd38ec9de35f35fb41e18f7a3fee7622", size = 11275100, upload-time = "2026-05-28T14:16:55.244Z" }, - { url = "https://files.pythonhosted.org/packages/9f/6b/7e145ce2cc8e63d6834eca03d83a0e18d121def5c69f91b4cf4011ed4879/ruff-0.15.15-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:be582fcc0db438902c7792b08d6ddf6c9b9e21addaa10092c2c741cfb09e5a45", size = 12176903, upload-time = "2026-05-28T14:16:14.368Z" }, - { url = "https://files.pythonhosted.org/packages/80/a3/d5974637f68e451f7fadf015cf3101d1cd7d8ba5027cffe0b9e3826ebe6b/ruff-0.15.15-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7aa77465b8ecaf1a27bea098d696f7fed5e1eccbd10b321b682d6de586ae5627", size = 11404550, upload-time = "2026-05-28T14:16:20.138Z" }, - { url = "https://files.pythonhosted.org/packages/fe/1c/e6e5e568f22be4fb05d6244234aba384c06b451252453b821e1a529263cf/ruff-0.15.15-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:48decfa11d740de4889de623be1463308346312f2409a56e24aa280c86162dc4", size = 11382027, upload-time = "2026-05-28T14:16:46.615Z" }, - { url = "https://files.pythonhosted.org/packages/1d/01/170921b49fcd2e8858825593f91cf7146c3e40a5c3e6df763e4bb0484dde/ruff-0.15.15-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:a5015088452ca0081387063649ec67f06d3d1d6b8b936a1f836b5e9657ecd48c", size = 11366041, upload-time = "2026-05-28T14:16:26.247Z" }, - { url = "https://files.pythonhosted.org/packages/87/54/a7bad711d7de93254e15e06a4c375b89a03d18de45d3e5dcc86a4472fb1a/ruff-0.15.15-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:f5294aab6356c81600fcdea3a62bb1b924dfd5e91767c12318d3f68f86af57cd", size = 10741795, upload-time = "2026-05-28T14:16:17.11Z" }, - { url = "https://files.pythonhosted.org/packages/c9/31/38c075963668f8b41c6914ee0f6f318727fbe30ab9145cb29e6df464c5fa/ruff-0.15.15-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:db5bd4d802415cca656dc1616070b725952d6ae95eb5d4831e49fbd94a38f75f", size = 10511117, upload-time = "2026-05-28T14:16:31.767Z" }, - { url = "https://files.pythonhosted.org/packages/9d/96/6ff689e1f7e375d1d97075eca022f74c2bab59554a432fe4d2e6f091986a/ruff-0.15.15-py3-none-musllinux_1_2_i686.whl", hash = "sha256:587a6278ed42059191c1a466e490bd7930fb50bd2e255398bc29616c895a61cb", size = 10994867, upload-time = "2026-05-28T14:16:35.149Z" }, - { url = "https://files.pythonhosted.org/packages/c3/c2/5dce0ab9f92a8d534fa62b9bf9caca3eddb8c1a81b616f5e195ada4f0d6e/ruff-0.15.15-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:df0c1c084f5f4be9812f61518a45c440d3c30d69ce4bf6c5270e66d38338f02a", size = 11482101, upload-time = "2026-05-28T14:16:49.598Z" }, - { url = "https://files.pythonhosted.org/packages/b1/c0/1003b60edd697c649faf61f1a34094b1abb38fb3d1181e3f895781250a08/ruff-0.15.15-py3-none-win32.whl", hash = "sha256:29428ea79694afbe756d45fd59b36f22b6b020dc0443cf7de0173046236964b9", size = 10716774, upload-time = "2026-05-28T14:16:52.337Z" }, - { url = "https://files.pythonhosted.org/packages/02/a8/1269eddd6945a06c23f055ef7848886e37cf9d6a8bebb386a3115f01470c/ruff-0.15.15-py3-none-win_amd64.whl", hash = "sha256:8df0323902e15e24bc4bf246da830573d3cf3352bd0b9a164eab335d111ff4a4", size = 11868463, upload-time = "2026-05-28T14:16:11.333Z" }, - { url = "https://files.pythonhosted.org/packages/4e/b2/920464c907b191e37469d477a1aa8bc048b8f36c4c1610dfa4ab87b39e18/ruff-0.15.15-py3-none-win_arm64.whl", hash = "sha256:3c8ceca6792f38196b8f589bc92eccd03eef286602da92e5dc05cc42ef6441b7", size = 11138498, upload-time = "2026-05-28T14:16:38.425Z" }, + { url = "https://files.pythonhosted.org/packages/b9/d0/686e984941269621e2be72612d5c1e461f8f7b38415a2a7d7a81c8ae6715/ruff-0.15.18-py3-none-linux_armv6l.whl", hash = "sha256:8b6850172348c8381b8b3084c5915a4393c2373b9b54cd5b5e1ea15812bc10df", size = 10887308, upload-time = "2026-06-18T18:25:03.062Z" }, + { url = "https://files.pythonhosted.org/packages/ed/21/bc4123e3f5515ee99f8ce1eb93a14a0628fe4d1678663cd08f933ac16931/ruff-0.15.18-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:3fccc153a85417dcd976883160cacce486997b0a0058dd18f54b8aaaac7d1ce2", size = 11281305, upload-time = "2026-06-18T18:25:30.026Z" }, + { url = "https://files.pythonhosted.org/packages/51/93/4769464c25cf7ab2acb3c7dda9cad3d867eb41c59565b3e2a9d17249c90c/ruff-0.15.18-py3-none-macosx_11_0_arm64.whl", hash = "sha256:08d4c86a68f2c3ec2c9d56380a71fb4a4f65373055cbb8caabd645e9102f38d4", size = 10641215, upload-time = "2026-06-18T18:25:15.802Z" }, + { url = "https://files.pythonhosted.org/packages/6c/42/56926d17120db2c208d76bf60a1a019644dd9e91dc27f0f95c9caddb1366/ruff-0.15.18-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:37e5108745c2c0705da916d7d4de533ddf547051ef45f62888c31bae73f66318", size = 10957224, upload-time = "2026-06-18T18:25:36.955Z" }, + { url = "https://files.pythonhosted.org/packages/22/4f/d43fab8d8189afde803103022d000a8ef9f230616d436d52a8b2b8d63b50/ruff-0.15.18-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:56949a6ce8b3abde54c0bcb22cebfe57e8771cadc84b407ae8b8eaf67ebdcd43", size = 10699024, upload-time = "2026-06-18T18:25:05.707Z" }, + { url = "https://files.pythonhosted.org/packages/63/42/1e3e4c68bd408b9768cf3e439acbe2c78245225faef253f7028a0cdb63e0/ruff-0.15.18-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01a754cd6a1b630d3f97e33eb452cf7a98040482318e870f8bc52a5a30e62657", size = 11491458, upload-time = "2026-06-18T18:25:20.275Z" }, + { url = "https://files.pythonhosted.org/packages/20/77/47a3484bea8521e14a203d98c389c5c97846675e4f02734672da4a69b52a/ruff-0.15.18-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6ba7a07e03a44dbf10bb086ee06705b173625014ec99f73a7e6836a5e5590a0c", size = 12383752, upload-time = "2026-06-18T18:25:22.535Z" }, + { url = "https://files.pythonhosted.org/packages/0a/ca/054159590787023d83b658a1a1819c4c8910114e7015069340b71c0961cb/ruff-0.15.18-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5a2c40a41a4cadbcf5897b548ab29dfe248b20c540961c0247d98a3973c70403", size = 11577923, upload-time = "2026-06-18T18:25:10.702Z" }, + { url = "https://files.pythonhosted.org/packages/6d/ff/d353d6b7bbd73cc0ec37f4463d7540e45e894338abdd9964eee0de332708/ruff-0.15.18-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f0480ce690cbb6c4db6e5d08f19fce98e10ba131a8b60c1bcdac42771e3ae2d", size = 11583925, upload-time = "2026-06-18T18:25:32.391Z" }, + { url = "https://files.pythonhosted.org/packages/c1/4a/891f89b9c296ed3e5f3ece1a5629badc989d9a8fdaa30431aaf4774bc1c2/ruff-0.15.18-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:2330215f1f393fa8733f55edce04fcf94c36a2c460fcde31f78cc84e4951e9b1", size = 11582834, upload-time = "2026-06-18T18:25:27.309Z" }, + { url = "https://files.pythonhosted.org/packages/32/a3/ed9e370154bf85de360b93c03026157f02d4943b2d01ff4945f4429f8e8a/ruff-0.15.18-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:a6aa6a3d979e48ae617578183674bf264fbe7d0114a796a26bd678d67963c7ff", size = 10927328, upload-time = "2026-06-18T18:25:34.676Z" }, + { url = "https://files.pythonhosted.org/packages/f5/d1/5cf5909329fedb5d39d555ee818ba5cf4638e1a301b89785d34f2905bfcb/ruff-0.15.18-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:a81beadbbff2c9c245561ae3f77b16709d87f35eec650d0501679239d3449b22", size = 10693187, upload-time = "2026-06-18T18:25:08.245Z" }, + { url = "https://files.pythonhosted.org/packages/fd/44/ff6c635cf2c4f4e7b618b6640da057376baa36014695487d88aed4794268/ruff-0.15.18-py3-none-musllinux_1_2_i686.whl", hash = "sha256:2186d9e940ae332ab293623a75b5f4fe49565f449954d50a72a046683aa6b809", size = 11208721, upload-time = "2026-06-18T18:25:41.327Z" }, + { url = "https://files.pythonhosted.org/packages/88/d9/5baa2a30861adfb7022cf33c1e35b2fc18085b08c16f83eff4c7b99a5f48/ruff-0.15.18-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:5c2abf140438032bc77b2284a6c9944ecd8a19e5f1c7b52b1b8e4a0a80d19a7a", size = 11678599, upload-time = "2026-06-18T18:25:13.607Z" }, + { url = "https://files.pythonhosted.org/packages/c3/1a/0725a7cfdc32ff769efb96ee782bec882e16448c5d9e3be947ec4c04ce27/ruff-0.15.18-py3-none-win32.whl", hash = "sha256:02299e6e9fa5b297a3f6d5d10d7bcd655c925b028bb8b9d4588214549c6b9ec4", size = 10901903, upload-time = "2026-06-18T18:25:24.755Z" }, + { url = "https://files.pythonhosted.org/packages/f3/51/805d9f6fb7970505c3504794a5ec350f605361b807fef4dcf214ebd35e72/ruff-0.15.18-py3-none-win_amd64.whl", hash = "sha256:dac80dc8d26b2257dbefabed62f5d255c3937b4ccb122da1fc634794fa3578b3", size = 12041189, upload-time = "2026-06-18T18:25:17.915Z" }, + { url = "https://files.pythonhosted.org/packages/29/4c/67bb45e41609eb4726f1bfeb59e083cf91d14c696d4bd14c234a980be93d/ruff-0.15.18-py3-none-win_arm64.whl", hash = "sha256:b2c9257fcbd4a3e5b977a1904e6facca016bafe2edc17df24db67cfaee03b4e4", size = 11329958, upload-time = "2026-06-18T18:25:43.686Z" }, ] [[package]] @@ -1160,15 +1158,15 @@ wheels = [ [[package]] name = "sentry-sdk" -version = "2.61.1" +version = "2.63.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "certifi" }, { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/63/3b/4bc6b348bbd331daa14d4babe9f2b99bc854f4da41560eefb9488d78481d/sentry_sdk-2.61.1.tar.gz", hash = "sha256:9c6adccb3feefa9ba032c8d295ca477575c2f11896046a2b0ad686c47c4af555", size = 459429, upload-time = "2026-06-01T07:24:18.875Z" } +sdist = { url = "https://files.pythonhosted.org/packages/ba/c8/b3c970a5b186722d276cd40a05b3254e03bccc0208560aff20f612e018e8/sentry_sdk-2.63.0.tar.gz", hash = "sha256:2a1502bf864769275dbc8c2c9fc7a0f7f5e18358180b615d262d13a31ffba216", size = 912449, upload-time = "2026-06-16T12:45:57.553Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/df/54/c9218db183846e08efaf68534889ef42e499dde432778881104a42f7071b/sentry_sdk-2.61.1-py3-none-any.whl", hash = "sha256:fa36eaf4b8ad708f718500d4bdcc1532637526a22beb874d88cbc0a46458b5ae", size = 483735, upload-time = "2026-06-01T07:24:17.027Z" }, + { url = "https://files.pythonhosted.org/packages/7b/57/cb205f7d93373120f666b9c5736dc0815524d96a9b278e7a728f018dc22a/sentry_sdk-2.63.0-py3-none-any.whl", hash = "sha256:3a9b5ddd403f79eb73bd670f75f04485819db53d28f76ced7bc09041cb0dfd6a", size = 495950, upload-time = "2026-06-16T12:45:55.819Z" }, ] [[package]] @@ -1270,39 +1268,39 @@ wheels = [ [[package]] name = "tqdm" -version = "4.67.3" +version = "4.68.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/09/a9/6ba95a270c6f1fbcd8dac228323f2777d886cb206987444e4bce66338dd4/tqdm-4.67.3.tar.gz", hash = "sha256:7d825f03f89244ef73f1d4ce193cb1774a8179fd96f31d7e1dcde62092b960bb", size = 169598, upload-time = "2026-02-03T17:35:53.048Z" } +sdist = { url = "https://files.pythonhosted.org/packages/87/d7/0535a28b1f5f24f6612fb3ff1e89fb1a8d160fee0f976e0aa6803862134b/tqdm-4.68.3.tar.gz", hash = "sha256:00dfa48452b6b6cfae3dd9885636c23d3422d1ec97c66d96818cbd5e0821d482", size = 170596, upload-time = "2026-06-17T07:36:52.105Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/16/e1/3079a9ff9b8e11b846c6ac5c8b5bfb7ff225eee721825310c91b3b50304f/tqdm-4.67.3-py3-none-any.whl", hash = "sha256:ee1e4c0e59148062281c49d80b25b67771a127c85fc9676d3be5f243206826bf", size = 78374, upload-time = "2026-02-03T17:35:50.982Z" }, + { url = "https://files.pythonhosted.org/packages/d8/8e/bb97bb0c71802080bfc8952937d174e49cfc50de5c951dd47b2496f0dcdb/tqdm-4.68.3-py3-none-any.whl", hash = "sha256:39832cc2def2789a6f29df83f172db7416cea70052c0907a57801c5f2fdccb03", size = 78337, upload-time = "2026-06-17T07:36:50.132Z" }, ] [[package]] name = "ty" -version = "0.0.41" +version = "0.0.51" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/eb/8b/a64ba465cbc5d1b83c561a498ee5e7729b810606220277cafa93983e6ce1/ty-0.0.41.tar.gz", hash = "sha256:1e8b55bf4729634b2db64a7d9541cd880087cd681e87efc36e6a056cf05fb648", size = 5765398, upload-time = "2026-06-01T11:49:36.815Z" } +sdist = { url = "https://files.pythonhosted.org/packages/7e/ce/352fcdba5c72ea20e5d2e46e28809cdb617575b71209d971eff2ace8e6c4/ty-0.0.51.tar.gz", hash = "sha256:b90172d46365bb9d51a7011cbb5c60cc4f514f42c86635df6c092b717f85e1ac", size = 5953151, upload-time = "2026-06-19T01:48:58.015Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/8f/22/b032e4d0f35a436f60eabaa19c70dbed6f5095eb7e30c53ddff918aafcff/ty-0.0.41-py3-none-linux_armv6l.whl", hash = "sha256:5f61c5c06616129ce31dd74141e18be69f5e4204a9a0f4505688213353475b30", size = 11541803, upload-time = "2026-06-01T11:49:33.837Z" }, - { url = "https://files.pythonhosted.org/packages/46/f8/78f073febd728f19f0fcbe2e320855ed337b871ed775e0abe5c7b25bbc6a/ty-0.0.41-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:25d6b4fbf198ae7523b8e4845ec3c7e1b1cd5efa1712febcad3856e70e66632b", size = 11275600, upload-time = "2026-06-01T11:49:59.384Z" }, - { url = "https://files.pythonhosted.org/packages/62/c6/b1b46684514e7372960348c723657f56db56799c36542571b49c77c18c87/ty-0.0.41-py3-none-macosx_11_0_arm64.whl", hash = "sha256:3509788ed3753669cdd28d289f281b834ceee91b4de648fcf0ef60677a75b030", size = 10695726, upload-time = "2026-06-01T11:50:05.232Z" }, - { url = "https://files.pythonhosted.org/packages/36/73/badf085590648a14bfe06571799becefaa2b409c5838c39b198b790c8f58/ty-0.0.41-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b8c04f1424c872f1d8d28efbd69fb52728fcc6c37aa2d11675bf16f76d33ae14", size = 11196461, upload-time = "2026-06-01T11:50:07.174Z" }, - { url = "https://files.pythonhosted.org/packages/ff/8f/399ee615282f80fd912b5ce4b3fe31206a6d40283e0700046aebbbb893f2/ty-0.0.41-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:53e52bfce12f3723c376d690625f5c462fe318c46dbe53b16d36c266388ee04c", size = 11310318, upload-time = "2026-06-01T11:49:50.663Z" }, - { url = "https://files.pythonhosted.org/packages/e8/43/204e8fe9f4f8932dd8e42a23e3aa8a365a93ecc601f67172da1c4cea50c0/ty-0.0.41-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c4f1d606602dc0eb895a0943af737d638311c7afd48b414897fd42a05e876a76", size = 11785266, upload-time = "2026-06-01T11:49:48.733Z" }, - { url = "https://files.pythonhosted.org/packages/e3/85/9098e96e40324ebd3797c3cad20ea0d855b56219806605e10b6455cf71b3/ty-0.0.41-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e8f3c41f0b6b0525bcc8d76a9a5921cccda11886ae11f73e2d51e20e185bafb3", size = 12328093, upload-time = "2026-06-01T11:49:52.945Z" }, - { url = "https://files.pythonhosted.org/packages/0e/41/b6a4d29591e86a27ab1364ddc70d6cee9a78cff1ede5466f6862f0384a68/ty-0.0.41-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bff8c4468933961e656664c3ef190800e3d50582c248aed41bb8a1578d64864a", size = 11979937, upload-time = "2026-06-01T11:49:29.633Z" }, - { url = "https://files.pythonhosted.org/packages/94/b2/6772c2c24fe412ebd0d57166d36afc176948857f7e90f368d321c561a12e/ty-0.0.41-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c83077a5c56770b1dab5b086a908a4e77740fb8f29d862ed05bd4c854549603d", size = 11859185, upload-time = "2026-06-01T11:49:46.474Z" }, - { url = "https://files.pythonhosted.org/packages/75/59/e4a1e0feef9d74308621c3a8b1558db97fa1c022948341d0eed1bdfc59a1/ty-0.0.41-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:8067fae5532ad3c48295c7ddbd1657ea3ee7392810c57810c9c98fe83d43d57f", size = 12036836, upload-time = "2026-06-01T11:49:39.182Z" }, - { url = "https://files.pythonhosted.org/packages/31/67/38f5312c74d51a510fb46c55b49880af6ca186cb87618938c67e808a45a5/ty-0.0.41-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:73a245242380bac3fbf3005d085c153923a45de8918001fad475af54c6fd50e4", size = 11179559, upload-time = "2026-06-01T11:50:01.355Z" }, - { url = "https://files.pythonhosted.org/packages/8c/55/f8cb36874dc1b8b26c6ae066f8ebec392197caa22becdc55bc7e53d251a5/ty-0.0.41-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:4eb25f5dc398aa0a5fbd90de62d6a0fd3713354e566ba93cc53670fe84067ee1", size = 11347231, upload-time = "2026-06-01T11:49:55.093Z" }, - { url = "https://files.pythonhosted.org/packages/8d/96/2d4369d7e8240b2dea1d7a7985709c38c6ccc57bbc8dbbdae3db5ee8d71a/ty-0.0.41-py3-none-musllinux_1_2_i686.whl", hash = "sha256:092c3a1ef9e3a189f71428092e736080ef42bf5c14412aa61bee8d644261797d", size = 11446240, upload-time = "2026-06-01T11:49:31.822Z" }, - { url = "https://files.pythonhosted.org/packages/8b/b0/36f09bfb568bc14f8496f2ace503c63c9152b4b65da4518cd3be0aa85312/ty-0.0.41-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:53edeb6e2ac430fe789454471f0e22a2a71581100818271150bd8f89fa468cc7", size = 11947795, upload-time = "2026-06-01T11:49:41.654Z" }, - { url = "https://files.pythonhosted.org/packages/92/33/ffd38f5e3ecb25e1b7aac314d902ceaa93be16f4874dc236f9da79509468/ty-0.0.41-py3-none-win32.whl", hash = "sha256:f66bdf3afb71f11d412a4c704fa9691e0209cbc8268a19489c8960c7b74eac8b", size = 10776684, upload-time = "2026-06-01T11:50:03.309Z" }, - { url = "https://files.pythonhosted.org/packages/ce/35/4c3e821906cfb05a88c232f5c1202be7ed336e05f4cc796213c809ab6177/ty-0.0.41-py3-none-win_amd64.whl", hash = "sha256:c18386e5c3a0c3d118ce58ee0d8a35f8d18d6b1020ca8ec690f6064e6230a79b", size = 11860965, upload-time = "2026-06-01T11:49:57.07Z" }, - { url = "https://files.pythonhosted.org/packages/5e/20/7c587e4c3c6da1757555831cac308c4add7a958f8b1c7f76cb1dd55ceabf/ty-0.0.41-py3-none-win_arm64.whl", hash = "sha256:289eb66ee5c3554d59b0ea69885ddc5fc8051f3228dd9fee2501799db4a07117", size = 11206414, upload-time = "2026-06-01T11:49:44.395Z" }, + { url = "https://files.pythonhosted.org/packages/2b/8f/8fe7cab79a45320b2cdcd602f16d44c8108d2f418ff7ec316c6212f1f0cc/ty-0.0.51-py3-none-linux_armv6l.whl", hash = "sha256:947986bd82d324b3a5c58ce03f1dad160cdf36443d3e8f64b3484b861ba9bc64", size = 11884805, upload-time = "2026-06-19T01:48:20.184Z" }, + { url = "https://files.pythonhosted.org/packages/fa/b4/56fdc39a3f44c0564fd157e1e59e1f9c3fc5ba57ae4472ded85c67c63d74/ty-0.0.51-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:25a5b31e6f23fd5dc63ad29087ded09932409e4154e2fe07bbaed015035990bb", size = 11633593, upload-time = "2026-06-19T01:48:22.998Z" }, + { url = "https://files.pythonhosted.org/packages/33/57/136e83f24fc04f5afdcabff42f40fa27eae5ac3f0e3f12627d072a55f679/ty-0.0.51-py3-none-macosx_11_0_arm64.whl", hash = "sha256:2faed19a8f1505370de071c008df52a994fc03a204f3267c3a33a32ca26f854f", size = 11063076, upload-time = "2026-06-19T01:48:25.223Z" }, + { url = "https://files.pythonhosted.org/packages/32/f8/5d32f0df5692446440ab781b9b119aa3e0c0dbfa78c583fe9be8417d54fa/ty-0.0.51-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:08adbe53fb8bc9e7f00e89bf1d3c875a02cda76d83f109d2e6ab1ff35a7bfa8c", size = 11579542, upload-time = "2026-06-19T01:48:27.302Z" }, + { url = "https://files.pythonhosted.org/packages/7f/0c/4f54ef338e9623886809ecd508931b0cd5b3aba1e591586a2f6aeaa8bd11/ty-0.0.51-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dc5e93695ab5dcbf1eef663aee60ec23a413547cc9cb06adcb0d842e9166bd0f", size = 11676189, upload-time = "2026-06-19T01:48:29.518Z" }, + { url = "https://files.pythonhosted.org/packages/56/27/31729066f9b9d3596941edaf267894eefc0b30df4518f003dba5f7276258/ty-0.0.51-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:abd92913bc90d1705ef9391ff8c6822b61e2e827fa295eb30bf0dfabcf815645", size = 12188154, upload-time = "2026-06-19T01:48:31.68Z" }, + { url = "https://files.pythonhosted.org/packages/2f/38/d4301aa12d2283c7130908baf1417a37dfe3e10f5669cb4ce2853c2540b4/ty-0.0.51-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:429a997394dac73870d71b87cc90efc54da3efaf319e72ca18aeef35a78aef90", size = 12780597, upload-time = "2026-06-19T01:48:33.839Z" }, + { url = "https://files.pythonhosted.org/packages/c1/52/4b2e67e53f126d39abe201bd2299e467e27463a284e965ad195cbc217fa0/ty-0.0.51-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:62d94f06e8c317e89b6884f2bde443040e596b88c7c79bd944c84c105b06257a", size = 12491115, upload-time = "2026-06-19T01:48:36.169Z" }, + { url = "https://files.pythonhosted.org/packages/74/50/aabfe55c132ebe72b4d639cbf772d931e11b0990d29c1f691922b6ccabc1/ty-0.0.51-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8f52952cff665bc52a36147e610c10f5699d30007d7a14ab7f345cff93476ff", size = 12230135, upload-time = "2026-06-19T01:48:38.445Z" }, + { url = "https://files.pythonhosted.org/packages/0d/1b/9aa428052dbed91c50919cd080426a313cf20ce14c6bfe2b71345e548671/ty-0.0.51-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:c1bd1355aee86af01e4e21b0bc16fc460fb05905761f0d8b8d70841de0feade8", size = 12468123, upload-time = "2026-06-19T01:48:40.47Z" }, + { url = "https://files.pythonhosted.org/packages/0b/5a/f6ce69f2575259386c950c40e02578d0902760cb61f95045e9971182c24e/ty-0.0.51-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:79d1877e93460f936bc10ed1a31525702b7ce51075763ccba993be17f0b9e905", size = 11541672, upload-time = "2026-06-19T01:48:42.635Z" }, + { url = "https://files.pythonhosted.org/packages/35/3a/2af48924a683e959e95e5cc4dc88e5a8595206a0812b869032b95196f2b0/ty-0.0.51-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:cc233a6235fb23e2a44b14731a10043e37ba2f30f2c361cf49ad3633c5b9da9c", size = 11694015, upload-time = "2026-06-19T01:48:44.819Z" }, + { url = "https://files.pythonhosted.org/packages/a4/12/899875d8a60b198c8121cb92ce18e18cc072d23ca2130fcdaa176383ef72/ty-0.0.51-py3-none-musllinux_1_2_i686.whl", hash = "sha256:bc7459348a253247bbfb2669a021e614281b86bbea24c36112b8a6e1a2499a16", size = 11832856, upload-time = "2026-06-19T01:48:47.028Z" }, + { url = "https://files.pythonhosted.org/packages/e6/a2/88f681d826d97cc96ef9f6cadd4935f775758944cee07340aa46113bce28/ty-0.0.51-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:49a21237f6fd1de56beaff0a3e85fe022a09a3401e67e3abec41ce838a5d4d2e", size = 12333449, upload-time = "2026-06-19T01:48:49.091Z" }, + { url = "https://files.pythonhosted.org/packages/f8/61/535a4163b4452c6978c31fedfd7b5803cf3a2253e9455cde350f86638d6a/ty-0.0.51-py3-none-win32.whl", hash = "sha256:61b4b6a003c3ebe53a63a1125c9b6542aa01bc1b6c9a235d01ee328d000d61a9", size = 11177338, upload-time = "2026-06-19T01:48:51.433Z" }, + { url = "https://files.pythonhosted.org/packages/aa/4d/2334fbb74291a20129fa7aaa8f789619ec9b6883b27f997b8baa27e4674f/ty-0.0.51-py3-none-win_amd64.whl", hash = "sha256:608d417cd1eaf79bcbd713d9830d5e3db9d57ec225c3af3e4ac9a9ff66b45d70", size = 12325675, upload-time = "2026-06-19T01:48:53.774Z" }, + { url = "https://files.pythonhosted.org/packages/50/b5/d49096cd5f3694becb86a5a6ccd0f229ead695fc7430d6bc4dd0a104c6fe/ty-0.0.51-py3-none-win_arm64.whl", hash = "sha256:62ced5e380284f12b2dc4802a3e4ed3dac39913fc6719afde7978814a4c7f169", size = 11657350, upload-time = "2026-06-19T01:48:55.904Z" }, ] [[package]] @@ -1353,11 +1351,11 @@ wheels = [ [[package]] name = "xvfb" version = "1.20.11.post1" -source = { git = "https://github.com/commaai/dependencies.git?subdirectory=xvfb&rev=release-xvfb#f0bb0b0d9154ea7858f3c0333b607ba7d356b571" } +source = { git = "https://github.com/commaai/dependencies.git?subdirectory=xvfb&rev=release-xvfb#94b5f8acfb7d8f3b3034f2b85851512ffc7bee65" } [[package]] name = "zensical" -version = "0.0.43" +version = "0.0.46" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "click" }, @@ -1369,26 +1367,26 @@ dependencies = [ { name = "pyyaml" }, { name = "tomli" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/d4/85/ec45162e7824a8f879d887ef0774ee65926bf7d1064e2eebccc7eaee3378/zensical-0.0.43.tar.gz", hash = "sha256:dc2d3804ff562795c1024130e0c3ce79736467930729dda314f096d0e35b98c8", size = 3932396, upload-time = "2026-05-19T09:44:07.418Z" } +sdist = { url = "https://files.pythonhosted.org/packages/aa/57/c7bbb71f943e1e0ba5ce460f4930ec836ead7286969e7fd742f7a6c049ab/zensical-0.0.46.tar.gz", hash = "sha256:3ec21f4fb1e78cd7c0d6b07ae336b04770e27ba020dabc457b2790e5d34f1978", size = 3973968, upload-time = "2026-06-21T18:52:40.368Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/55/c2/55e0709607ae41c266987c3b91a1a9702b37fbbef0d07eddfe5e25c2d823/zensical-0.0.43-cp310-abi3-macosx_10_12_x86_64.whl", hash = "sha256:17c335362b6bac3a50178181694a964f6d9f0c516fc532129ba5a0a5c4103fb6", size = 12706531, upload-time = "2026-05-19T09:43:32.729Z" }, - { url = "https://files.pythonhosted.org/packages/2c/64/ce8627bc5ea30556162b29b041fe97d6a6aef2a87b51f12def628e4fa608/zensical-0.0.43-cp310-abi3-macosx_11_0_arm64.whl", hash = "sha256:b8fe97f185194215f6193af45a17d2b30ebd72c8113e3650f2d7d6767b9c2206", size = 12563012, upload-time = "2026-05-19T09:43:35.962Z" }, - { url = "https://files.pythonhosted.org/packages/66/d1/533bc9454f0e06b3d9d8bd2e7ac405308c3d4dee6572acab98f0ed6d1c07/zensical-0.0.43-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4c4c85978c765b3e7f347e8102dfe1373d4bbe4229d7008b6bdbf352f1fbcd7f", size = 12947599, upload-time = "2026-05-19T09:43:38.754Z" }, - { url = "https://files.pythonhosted.org/packages/75/a0/94f47d6fb592997be7ab9526938c929f0199adf2637c3c2b2b9b2101b28e/zensical-0.0.43-cp310-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:90d7c06ffd07b2bdf78bef041d541baba8a3ea51fd2dd84dbdbc5b0229076524", size = 12904911, upload-time = "2026-05-19T09:43:42.434Z" }, - { url = "https://files.pythonhosted.org/packages/96/fb/1db3ad9a86ff772f74a8bc60ad5b447aa02a158e70f94adacf50bdd5c40f/zensical-0.0.43-cp310-abi3-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:60022f4a6b95e46ec0023f51052fcd491743b3ebd08c0066b22a5cf1e741fecd", size = 13269386, upload-time = "2026-05-19T09:43:45.387Z" }, - { url = "https://files.pythonhosted.org/packages/31/ee/b24fd0f94885519d851c35615b086d069a1077b0198021a56755395a4633/zensical-0.0.43-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e278eb948a0b7545d50609d713c7c27e366dade4523ff73a311a5d5f136518a", size = 12999364, upload-time = "2026-05-19T09:43:48.549Z" }, - { url = "https://files.pythonhosted.org/packages/28/78/401ccd7afd9d2690f81b5319b7f1eed05108154ce20e4207053914518c1c/zensical-0.0.43-cp310-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:b85e5ab99fbda13823e67c43a4be6e5ebda6600602969c6575e143f20ac203fd", size = 13124392, upload-time = "2026-05-19T09:43:50.965Z" }, - { url = "https://files.pythonhosted.org/packages/98/b3/9af6eba5826b0ef143fc8308bd1e219e221441e307a958e39f824ba9ab53/zensical-0.0.43-cp310-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:751385accc92cccfd4560dabed7c423870686ef6ede244a67e5c96286af25e8f", size = 13177538, upload-time = "2026-05-19T09:43:53.964Z" }, - { url = "https://files.pythonhosted.org/packages/be/6b/cd090bd6659d32692487206469988ee84d41aa6de4cdf9e380f847da90e2/zensical-0.0.43-cp310-abi3-musllinux_1_2_i686.whl", hash = "sha256:dd3ff5bfa6e65cf3d2550dc639c3da2a3bfa11087b83d57e06623c4c1607d583", size = 13327086, upload-time = "2026-05-19T09:43:56.8Z" }, - { url = "https://files.pythonhosted.org/packages/79/5b/ac2555354b5a53cb9c2c942811905c47be0b9f5603d3c1328ee8564333eb/zensical-0.0.43-cp310-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:85055a115b12f49c6ab194dcf04f966fc06b690ed6a8ddddd819929fc5f340e6", size = 13284645, upload-time = "2026-05-19T09:43:59.329Z" }, - { url = "https://files.pythonhosted.org/packages/d0/c6/1688ec6e5be15e3ab367d7804753291bfbdff3109b06e20c19ce30a7129c/zensical-0.0.43-cp310-abi3-win32.whl", hash = "sha256:8a75ddd4bb3cd3c4a8e71d2ebae44c5611fd636c1d355c6124dd96e2f9c52838", size = 12256740, upload-time = "2026-05-19T09:44:02.102Z" }, - { url = "https://files.pythonhosted.org/packages/ca/a8/d967e70eac810a7e9eb8c5150d6d02848a1f42260f42977c71debed3cb02/zensical-0.0.43-cp310-abi3-win_amd64.whl", hash = "sha256:03a9d1744a6394ad66c355d6f1de04cfd92efa525b0b94bf6dbf6971c5cd2c6b", size = 12496166, upload-time = "2026-05-19T09:44:04.915Z" }, + { url = "https://files.pythonhosted.org/packages/4c/bd/bbc499ee35ac9ec5459dbfec7bb7231556689e97eaa13a5eddbe1f0443b5/zensical-0.0.46-cp310-abi3-macosx_10_12_x86_64.whl", hash = "sha256:d91af81ab058c8693dfd75f2f77b4c73bcba4125681d1d276f38624291820bd2", size = 12796482, upload-time = "2026-06-21T18:52:07.369Z" }, + { url = "https://files.pythonhosted.org/packages/88/1b/7acc273184d59b8e894d15ebe3cf1c5e81b3a822fde1792ea3e33be37a2e/zensical-0.0.46-cp310-abi3-macosx_11_0_arm64.whl", hash = "sha256:d9221264a9a87409900a47e29985607b0c9245dacb89077e87c8e16e31edc167", size = 12660030, upload-time = "2026-06-21T18:52:10.186Z" }, + { url = "https://files.pythonhosted.org/packages/80/df/bd0a68de98a19fc6050c58be11f36d05ea72a213b6a7ff7395d33c793747/zensical-0.0.46-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec43018d5343ca2e1d71aa352eeddd560fef504effd03025840a5a783abefa4f", size = 13057130, upload-time = "2026-06-21T18:52:12.911Z" }, + { url = "https://files.pythonhosted.org/packages/f4/db/e27635f5787a42245f900e658340698a6654e165d466f9a3b640efced2cd/zensical-0.0.46-cp310-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:26e98fb8ab7ab50cdd20a73e2c7d4d9aae0b46cf2d8691e6bb22f9c261b8a60a", size = 13022345, upload-time = "2026-06-21T18:52:15.84Z" }, + { url = "https://files.pythonhosted.org/packages/e7/9d/6ce2ba11c97154870b458a8dae4637ade93b7097912f0102f5ea7fe8cf5b/zensical-0.0.46-cp310-abi3-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:46fe578f26963f8ee89567983e62737b6fadc9197d4742e1020b522e092d7baa", size = 13377445, upload-time = "2026-06-21T18:52:18.538Z" }, + { url = "https://files.pythonhosted.org/packages/68/06/9930d43cd9d2f899b648d63491007c1b4f9716cf118b0c98e867b933069c/zensical-0.0.46-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aef03fa186a5589148e10b62610500989c6b075a2c08e1554233adbf91b2a3dc", size = 13086749, upload-time = "2026-06-21T18:52:21.452Z" }, + { url = "https://files.pythonhosted.org/packages/c4/ed/2342cf860fbb02314938b0d1f1b02344935801b04d185ff3151ef1812898/zensical-0.0.46-cp310-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:bc7446cdf97a8dea390f20ed2bd6b030cddc1bd36a8ce113ea3efef6fa61c573", size = 13231120, upload-time = "2026-06-21T18:52:24.171Z" }, + { url = "https://files.pythonhosted.org/packages/de/b0/d2ece02f63cd767fcf10fd7608dc8e0a995f87dc5261209b1dbc296fd57b/zensical-0.0.46-cp310-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:bbee37801f1ed500f158dc0992c569282950f780ae353c37fe6969f99983d701", size = 13295035, upload-time = "2026-06-21T18:52:26.942Z" }, + { url = "https://files.pythonhosted.org/packages/4b/b2/cb0048a612e63e615399fc507472a557d1c5b7c2f74065c5bf11998fd597/zensical-0.0.46-cp310-abi3-musllinux_1_2_i686.whl", hash = "sha256:9487c147c9cceb50c04d0ad70b024821a6eab1629dafd70ab6d1e86ec841e623", size = 13437191, upload-time = "2026-06-21T18:52:29.69Z" }, + { url = "https://files.pythonhosted.org/packages/91/16/515f81db8055b109a510063be481e60a657c4fad1a883680b2ee4aa9a424/zensical-0.0.46-cp310-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:f42a4683c762f026878d19ede4bcf7bfbb84dbecb5ad923949abb77806ed88a5", size = 13369382, upload-time = "2026-06-21T18:52:32.521Z" }, + { url = "https://files.pythonhosted.org/packages/b9/5c/da54ee65b642eb7d88dd4a3db35845d0765915638e05d5d434a10b42f1c3/zensical-0.0.46-cp310-abi3-win32.whl", hash = "sha256:85f018f2a7ee76a83915c87ddb12b58cf343fd6154081d33ac95b6751b011dd7", size = 12354298, upload-time = "2026-06-21T18:52:34.976Z" }, + { url = "https://files.pythonhosted.org/packages/73/26/fc7ef081acbdada8436825221cb728ee84a81d4d78a7bb79aa58bd150d31/zensical-0.0.46-cp310-abi3-win_amd64.whl", hash = "sha256:1543a693a160de60e86ca589592401b584670e7e12c5ae30e3c2ba76786f7ec3", size = 12599687, upload-time = "2026-06-21T18:52:37.913Z" }, ] [[package]] name = "zeromq" version = "4.3.5" -source = { git = "https://github.com/commaai/dependencies.git?subdirectory=zeromq&rev=release-zeromq#40b29e8e88a69802e8afc4f71f5c955bc2d5c74c" } +source = { git = "https://github.com/commaai/dependencies.git?subdirectory=zeromq&rev=release-zeromq#28563a27b2f333688399a03c3bebea41b0cead32" } [[package]] name = "zstandard" @@ -1418,4 +1416,4 @@ wheels = [ [[package]] name = "zstd" version = "1.5.6" -source = { git = "https://github.com/commaai/dependencies.git?subdirectory=zstd&rev=release-zstd#13015596466eb68825f109ad0d5aefa6330cc495" } +source = { git = "https://github.com/commaai/dependencies.git?subdirectory=zstd&rev=release-zstd#96e569f08cf4a7b4a0f8181859fc791f45d0bc4e" } From 7d325d6650206d9d78e63179ba9b4a2e1d84e4fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Harald=20Sch=C3=A4fer?= Date: Tue, 23 Jun 2026 11:34:05 -0700 Subject: [PATCH 082/151] Simplify lane change logic (#38229) * desire cleanups * remove the finalize timeout --------- Co-authored-by: Robbe Derks --- .../selfdrive/controls/lib/desire_helper.py | 62 +++++-------------- 1 file changed, 16 insertions(+), 46 deletions(-) diff --git a/openpilot/selfdrive/controls/lib/desire_helper.py b/openpilot/selfdrive/controls/lib/desire_helper.py index 68ddc3861e..cbf4d95d38 100644 --- a/openpilot/selfdrive/controls/lib/desire_helper.py +++ b/openpilot/selfdrive/controls/lib/desire_helper.py @@ -7,35 +7,13 @@ LaneChangeDirection = log.LaneChangeDirection LANE_CHANGE_SPEED_MIN = 20 * CV.MPH_TO_MS LANE_CHANGE_TIME_MAX = 10. - -DESIRES = { - LaneChangeDirection.none: { - LaneChangeState.off: log.Desire.none, - LaneChangeState.preLaneChange: log.Desire.none, - LaneChangeState.laneChangeStarting: log.Desire.none, - LaneChangeState.laneChangeFinishing: log.Desire.none, - }, - LaneChangeDirection.left: { - LaneChangeState.off: log.Desire.none, - LaneChangeState.preLaneChange: log.Desire.none, - LaneChangeState.laneChangeStarting: log.Desire.laneChangeLeft, - LaneChangeState.laneChangeFinishing: log.Desire.laneChangeLeft, - }, - LaneChangeDirection.right: { - LaneChangeState.off: log.Desire.none, - LaneChangeState.preLaneChange: log.Desire.none, - LaneChangeState.laneChangeStarting: log.Desire.laneChangeRight, - LaneChangeState.laneChangeFinishing: log.Desire.laneChangeRight, - }, -} - +LANE_CHANGE_START_TIME = 0.5 class DesireHelper: def __init__(self): self.lane_change_state = LaneChangeState.off self.lane_change_direction = LaneChangeDirection.none self.lane_change_timer = 0.0 - self.lane_change_ll_prob = 1.0 self.prev_one_blinker = False self.desire = log.Desire.none @@ -51,15 +29,14 @@ class DesireHelper: if not lateral_active or self.lane_change_timer > LANE_CHANGE_TIME_MAX: self.lane_change_state = LaneChangeState.off self.lane_change_direction = LaneChangeDirection.none + self.lane_change_timer = 0.0 else: - # LaneChangeState.off if self.lane_change_state == LaneChangeState.off and one_blinker and not self.prev_one_blinker and not below_lane_change_speed: self.lane_change_state = LaneChangeState.preLaneChange - self.lane_change_ll_prob = 1.0 + self.lane_change_timer = 0.0 # Initialize lane change direction to prevent UI alert flicker self.lane_change_direction = self.get_lane_change_direction(carstate) - # LaneChangeState.preLaneChange elif self.lane_change_state == LaneChangeState.preLaneChange: # Update lane change direction self.lane_change_direction = self.get_lane_change_direction(carstate) @@ -74,35 +51,28 @@ class DesireHelper: if not one_blinker or below_lane_change_speed: self.lane_change_state = LaneChangeState.off self.lane_change_direction = LaneChangeDirection.none + self.lane_change_timer = 0.0 elif torque_applied and not blindspot_detected: self.lane_change_state = LaneChangeState.laneChangeStarting + self.lane_change_timer = 0.0 - # LaneChangeState.laneChangeStarting elif self.lane_change_state == LaneChangeState.laneChangeStarting: - # fade out over .5s - self.lane_change_ll_prob = max(self.lane_change_ll_prob - 2 * DT_MDL, 0.0) + self.lane_change_timer += DT_MDL - # 98% certainty - if lane_change_prob < 0.02 and self.lane_change_ll_prob < 0.01: - self.lane_change_state = LaneChangeState.laneChangeFinishing - - # LaneChangeState.laneChangeFinishing - elif self.lane_change_state == LaneChangeState.laneChangeFinishing: - # fade in laneline over 1s - self.lane_change_ll_prob = min(self.lane_change_ll_prob + DT_MDL, 1.0) - - if self.lane_change_ll_prob > 0.99: - self.lane_change_direction = LaneChangeDirection.none + if lane_change_prob < 0.02 and self.lane_change_timer >= LANE_CHANGE_START_TIME: + self.lane_change_timer = 0.0 if one_blinker: self.lane_change_state = LaneChangeState.preLaneChange + self.lane_change_direction = self.get_lane_change_direction(carstate) else: self.lane_change_state = LaneChangeState.off - - if self.lane_change_state in (LaneChangeState.off, LaneChangeState.preLaneChange): - self.lane_change_timer = 0.0 - else: - self.lane_change_timer += DT_MDL + self.lane_change_direction = LaneChangeDirection.none self.prev_one_blinker = one_blinker - self.desire = DESIRES[self.lane_change_direction][self.lane_change_state] + self.desire = log.Desire.none + if self.lane_change_state == LaneChangeState.laneChangeStarting: + if self.lane_change_direction == LaneChangeDirection.left: + self.desire = log.Desire.laneChangeLeft + elif self.lane_change_direction == LaneChangeDirection.right: + self.desire = log.Desire.laneChangeRight From addca46f68790820c5c831de13cc810b69a8ec7a Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Wed, 24 Jun 2026 19:21:19 -0700 Subject: [PATCH 083/151] move some tools back to root (#38235) --- .github/workflows/docs.yaml | 2 +- .github/workflows/release.yaml | 4 +-- .github/workflows/repo-maintenance.yaml | 2 +- .github/workflows/tests.yaml | 20 +++++------ Jenkinsfile | 12 ++++--- .../scripts => selfdrive/test}/mem_usage.py | 29 --------------- openpilot/selfdrive/test/test_onroad.py | 2 +- scripts/post-commit | 2 +- {openpilot/tools => tools}/CTF.md | 0 {openpilot/tools => tools}/README.md | 4 +-- .../tools => tools}/car_porting/README.md | 20 +++++------ .../car_porting/auto_fingerprint.py | 0 .../examples/find_segments_with_message.ipynb | 0 .../examples/ford_vin_fingerprint.ipynb | 0 .../examples/hkg_canfd_gear_message.ipynb | 0 .../examples/subaru_fuzzy_fingerprint.ipynb | 0 .../examples/subaru_long_accel.ipynb | 0 .../examples/subaru_steer_temp_fault.ipynb | 0 .../car_porting/measure_steering_accuracy.py | 0 .../car_porting/test_car_model.py | 0 {openpilot/tools => tools}/op.sh | 6 ++-- {release => tools/release}/README.md | 2 +- {release => tools/release}/build_release.sh | 4 +-- {release => tools/release}/build_stripped.sh | 2 +- {release => tools/release}/check-dirty.sh | 0 .../release}/check-submodules.sh | 0 {release => tools/release}/identity.sh | 0 {release => tools/release}/pack.py | 0 {release => tools/release}/release_files.py | 2 +- .../tools => tools}/scripts/__init__.py | 0 {openpilot/tools => tools}/scripts/adb_ssh.sh | 0 .../scripts/car/can_print_changes.py | 2 +- .../scripts/car/can_printer.py | 0 .../tools => tools}/scripts/car/can_table.py | 0 .../tools => tools}/scripts/car/clear_dtc.py | 0 .../scripts/car/disable_ecu.py | 0 .../tools => tools}/scripts/car/ecu_addrs.py | 0 .../scripts/car/fw_versions.py | 0 .../car/hyundai_enable_radar_points.py | 0 .../scripts/car/max_lat_accel.py | 0 .../scripts/car/measure_torque_time_to_max.py | 0 .../scripts/car/read_dtc_status.py | 0 .../scripts/car/toyota_eps_factor.py | 0 {openpilot/tools => tools}/scripts/car/vin.py | 0 .../scripts/car/vw_mqb_config.py | 0 .../tools => tools}/scripts/count_events.py | 0 .../tools => tools}/scripts/cpu_usage_stat.py | 0 .../tools => tools}/scripts/cycle_alerts.py | 0 .../debug_fw_fingerprinting_offline.py | 0 {openpilot/tools => tools}/scripts/devsync.py | 0 {openpilot/tools => tools}/scripts/dump.py | 0 .../tools => tools}/scripts/extract_audio.py | 0 .../scripts/filter_log_message.py | 0 .../scripts/fingerprint_from_route.py | 0 .../scripts/fuzz_fw_fingerprint.py | 0 .../scripts/get_fingerprint.py | 0 .../scripts/live_cpu_and_temp.py | 0 tools/scripts/mem_usage.py | 35 +++++++++++++++++++ .../tools => tools}/scripts/print_flags.py | 0 .../scripts/profiling/clpeak/.gitignore | 0 .../scripts/profiling/clpeak/build.sh | 0 .../scripts/profiling/clpeak/no_print.patch | 0 .../profiling/clpeak/run_continuously.patch | 0 .../scripts/profiling/ftrace.sh | 0 .../scripts/profiling/palanteer/.gitignore | 0 .../scripts/profiling/palanteer/setup.sh | 0 .../scripts/profiling/perfetto/.gitignore | 0 .../scripts/profiling/perfetto/build.sh | 0 .../scripts/profiling/perfetto/copy.sh | 0 .../scripts/profiling/perfetto/record.sh | 0 .../scripts/profiling/perfetto/server.sh | 0 .../scripts/profiling/perfetto/traces.sh | 0 .../scripts/profiling/py-spy/profile.sh | 0 .../scripts/profiling/snapdragon/.gitignore | 0 .../scripts/profiling/snapdragon/README.md | 0 .../profiling/snapdragon/setup-agnos.sh | 0 .../profiling/snapdragon/setup-profiler.sh | 0 .../scripts/profiling/watch-irqs.sh | 0 .../tools => tools}/scripts/qlog_size.py | 0 .../scripts/run_process_on_route.py | 0 {openpilot/tools => tools}/scripts/serial.sh | 0 .../tools => tools}/scripts/set_car_params.py | 0 .../tools => tools}/scripts/setup_ssh_keys.py | 0 {openpilot/tools => tools}/scripts/ssh.py | 0 .../scripts/test_fw_query_on_routes.py | 0 {openpilot/tools => tools}/scripts/uiview.py | 0 .../tools => tools}/scripts/watch_timings.py | 0 {openpilot/tools => tools}/setup.sh | 6 ++-- .../tools => tools}/setup_dependencies.sh | 0 89 files changed, 82 insertions(+), 74 deletions(-) rename openpilot/{tools/scripts => selfdrive/test}/mem_usage.py (90%) mode change 100755 => 100644 rename {openpilot/tools => tools}/CTF.md (100%) rename {openpilot/tools => tools}/README.md (97%) rename {openpilot/tools => tools}/car_porting/README.md (87%) rename {openpilot/tools => tools}/car_porting/auto_fingerprint.py (100%) rename {openpilot/tools => tools}/car_porting/examples/find_segments_with_message.ipynb (100%) rename {openpilot/tools => tools}/car_porting/examples/ford_vin_fingerprint.ipynb (100%) rename {openpilot/tools => tools}/car_porting/examples/hkg_canfd_gear_message.ipynb (100%) rename {openpilot/tools => tools}/car_porting/examples/subaru_fuzzy_fingerprint.ipynb (100%) rename {openpilot/tools => tools}/car_porting/examples/subaru_long_accel.ipynb (100%) rename {openpilot/tools => tools}/car_porting/examples/subaru_steer_temp_fault.ipynb (100%) rename {openpilot/tools => tools}/car_porting/measure_steering_accuracy.py (100%) rename {openpilot/tools => tools}/car_porting/test_car_model.py (100%) rename {openpilot/tools => tools}/op.sh (98%) rename {release => tools/release}/README.md (88%) rename {release => tools/release}/build_release.sh (94%) rename {release => tools/release}/build_stripped.sh (97%) rename {release => tools/release}/check-dirty.sh (100%) rename {release => tools/release}/check-submodules.sh (100%) rename {release => tools/release}/identity.sh (100%) rename {release => tools/release}/pack.py (100%) rename {release => tools/release}/release_files.py (93%) rename {openpilot/tools => tools}/scripts/__init__.py (100%) rename {openpilot/tools => tools}/scripts/adb_ssh.sh (100%) rename {openpilot/tools => tools}/scripts/car/can_print_changes.py (98%) rename {openpilot/tools => tools}/scripts/car/can_printer.py (100%) rename {openpilot/tools => tools}/scripts/car/can_table.py (100%) rename {openpilot/tools => tools}/scripts/car/clear_dtc.py (100%) rename {openpilot/tools => tools}/scripts/car/disable_ecu.py (100%) rename {openpilot/tools => tools}/scripts/car/ecu_addrs.py (100%) rename {openpilot/tools => tools}/scripts/car/fw_versions.py (100%) rename {openpilot/tools => tools}/scripts/car/hyundai_enable_radar_points.py (100%) rename {openpilot/tools => tools}/scripts/car/max_lat_accel.py (100%) rename {openpilot/tools => tools}/scripts/car/measure_torque_time_to_max.py (100%) rename {openpilot/tools => tools}/scripts/car/read_dtc_status.py (100%) rename {openpilot/tools => tools}/scripts/car/toyota_eps_factor.py (100%) rename {openpilot/tools => tools}/scripts/car/vin.py (100%) rename {openpilot/tools => tools}/scripts/car/vw_mqb_config.py (100%) rename {openpilot/tools => tools}/scripts/count_events.py (100%) rename {openpilot/tools => tools}/scripts/cpu_usage_stat.py (100%) rename {openpilot/tools => tools}/scripts/cycle_alerts.py (100%) rename {openpilot/tools => tools}/scripts/debug_fw_fingerprinting_offline.py (100%) rename {openpilot/tools => tools}/scripts/devsync.py (100%) rename {openpilot/tools => tools}/scripts/dump.py (100%) rename {openpilot/tools => tools}/scripts/extract_audio.py (100%) rename {openpilot/tools => tools}/scripts/filter_log_message.py (100%) rename {openpilot/tools => tools}/scripts/fingerprint_from_route.py (100%) rename {openpilot/tools => tools}/scripts/fuzz_fw_fingerprint.py (100%) rename {openpilot/tools => tools}/scripts/get_fingerprint.py (100%) rename {openpilot/tools => tools}/scripts/live_cpu_and_temp.py (100%) create mode 100755 tools/scripts/mem_usage.py rename {openpilot/tools => tools}/scripts/print_flags.py (100%) rename {openpilot/tools => tools}/scripts/profiling/clpeak/.gitignore (100%) rename {openpilot/tools => tools}/scripts/profiling/clpeak/build.sh (100%) rename {openpilot/tools => tools}/scripts/profiling/clpeak/no_print.patch (100%) rename {openpilot/tools => tools}/scripts/profiling/clpeak/run_continuously.patch (100%) rename {openpilot/tools => tools}/scripts/profiling/ftrace.sh (100%) rename {openpilot/tools => tools}/scripts/profiling/palanteer/.gitignore (100%) rename {openpilot/tools => tools}/scripts/profiling/palanteer/setup.sh (100%) rename {openpilot/tools => tools}/scripts/profiling/perfetto/.gitignore (100%) rename {openpilot/tools => tools}/scripts/profiling/perfetto/build.sh (100%) rename {openpilot/tools => tools}/scripts/profiling/perfetto/copy.sh (100%) rename {openpilot/tools => tools}/scripts/profiling/perfetto/record.sh (100%) rename {openpilot/tools => tools}/scripts/profiling/perfetto/server.sh (100%) rename {openpilot/tools => tools}/scripts/profiling/perfetto/traces.sh (100%) rename {openpilot/tools => tools}/scripts/profiling/py-spy/profile.sh (100%) rename {openpilot/tools => tools}/scripts/profiling/snapdragon/.gitignore (100%) rename {openpilot/tools => tools}/scripts/profiling/snapdragon/README.md (100%) rename {openpilot/tools => tools}/scripts/profiling/snapdragon/setup-agnos.sh (100%) rename {openpilot/tools => tools}/scripts/profiling/snapdragon/setup-profiler.sh (100%) rename {openpilot/tools => tools}/scripts/profiling/watch-irqs.sh (100%) rename {openpilot/tools => tools}/scripts/qlog_size.py (100%) rename {openpilot/tools => tools}/scripts/run_process_on_route.py (100%) rename {openpilot/tools => tools}/scripts/serial.sh (100%) rename {openpilot/tools => tools}/scripts/set_car_params.py (100%) rename {openpilot/tools => tools}/scripts/setup_ssh_keys.py (100%) rename {openpilot/tools => tools}/scripts/ssh.py (100%) rename {openpilot/tools => tools}/scripts/test_fw_query_on_routes.py (100%) rename {openpilot/tools => tools}/scripts/uiview.py (100%) rename {openpilot/tools => tools}/scripts/watch_timings.py (100%) rename {openpilot/tools => tools}/setup.sh (96%) rename {openpilot/tools => tools}/setup_dependencies.sh (100%) diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index f618c1bdf8..d072cd71d1 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -45,7 +45,7 @@ jobs: run: | set -x - source release/identity.sh + source tools/release/identity.sh cd openpilot-docs git checkout --orphan tmp diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index ae6a2655a4..27faccae6e 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -26,6 +26,6 @@ jobs: with: submodules: true fetch-depth: 0 - - run: ./openpilot/tools/op.sh setup + - run: ./tools/op.sh setup - name: Push master-ci - run: BRANCH=__nightly release/build_stripped.sh + run: BRANCH=__nightly tools/release/build_stripped.sh diff --git a/.github/workflows/repo-maintenance.yaml b/.github/workflows/repo-maintenance.yaml index 14c613fbe4..1a99852be1 100644 --- a/.github/workflows/repo-maintenance.yaml +++ b/.github/workflows/repo-maintenance.yaml @@ -17,7 +17,7 @@ jobs: - uses: actions/checkout@v6 with: submodules: true - - run: ./openpilot/tools/op.sh setup + - run: ./tools/op.sh setup - name: uv lock run: uv lock --upgrade - name: uv pip tree diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 3ed0829a26..4fa3af3d5e 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -46,8 +46,8 @@ jobs: command: git lfs pull - name: Build devel timeout-minutes: 1 - run: TARGET_DIR=$STRIPPED_DIR release/build_stripped.sh - - run: ./openpilot/tools/op.sh setup + run: TARGET_DIR=$STRIPPED_DIR tools/release/build_stripped.sh + - run: ./tools/op.sh setup - name: Build openpilot and run checks timeout-minutes: 30 working-directory: ${{ env.STRIPPED_DIR }} @@ -55,11 +55,11 @@ jobs: - name: Run tests timeout-minutes: 1 working-directory: ${{ env.STRIPPED_DIR }} - run: release/check-dirty.sh + run: tools/release/check-dirty.sh - name: Check submodules if: github.repository == 'commaai/openpilot' timeout-minutes: 3 - run: release/check-submodules.sh + run: tools/release/check-submodules.sh build_mac: name: build macOS @@ -72,7 +72,7 @@ jobs: run: | FILTERED=$(echo "$PATH" | tr ':' '\n' | grep -v '/opt/homebrew' | tr '\n' ':') echo "PATH=${FILTERED}/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin" >> $GITHUB_ENV - - run: ./openpilot/tools/op.sh setup + - run: ./tools/op.sh setup - name: Building openpilot run: scons @@ -88,7 +88,7 @@ jobs: - uses: actions/checkout@v6 with: submodules: true - - run: ./openpilot/tools/op.sh setup + - run: ./tools/op.sh setup - name: Static analysis timeout-minutes: 1 run: scripts/lint/lint.sh @@ -105,7 +105,7 @@ jobs: - uses: actions/checkout@v6 with: submodules: true - - run: ./openpilot/tools/op.sh setup + - run: ./tools/op.sh setup - name: Build openpilot run: scons - name: Run unit tests @@ -128,7 +128,7 @@ jobs: - uses: actions/checkout@v6 with: submodules: true - - run: ./openpilot/tools/op.sh setup + - run: ./tools/op.sh setup - name: Build openpilot run: scons - name: Run replay @@ -201,7 +201,7 @@ jobs: - uses: actions/checkout@v6 with: submodules: true - - run: ./openpilot/tools/op.sh setup + - run: ./tools/op.sh setup - name: Build openpilot run: scons - name: Driving test @@ -222,7 +222,7 @@ jobs: - uses: actions/checkout@v6 with: submodules: true - - run: ./openpilot/tools/op.sh setup + - run: ./tools/op.sh setup - name: Build openpilot run: scons - name: Create UI Report diff --git a/Jenkinsfile b/Jenkinsfile index c06674a5c5..d57e9502aa 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -63,6 +63,8 @@ if [ -f /data/openpilot/launch_env.sh ]; then source /data/openpilot/launch_env.sh fi +export LD_LIBRARY_PATH="\$(python -c 'import ffmpeg; print(ffmpeg.LIB_DIR)'):/usr/local/lib:\${LD_LIBRARY_PATH:-}" + ln -snf ${env.TEST_DIR} /data/pythonpath cd ${env.TEST_DIR} || true @@ -179,7 +181,7 @@ node { try { if (env.BRANCH_NAME == 'devel-staging') { deviceStage("build release-tizi-staging", "tizi-needs-can", [], [ - step("build release-tizi-staging", "RELEASE_BRANCH=release-tizi-staging,release-mici-staging $SOURCE_DIR/release/build_release.sh"), + step("build release-tizi-staging", "RELEASE_BRANCH=release-tizi-staging,release-mici-staging $SOURCE_DIR/tools/release/build_release.sh"), ]) } @@ -187,12 +189,12 @@ node { parallel ( 'nightly': { deviceStage("build nightly", "tizi-needs-can", [], [ - step("build nightly", "RELEASE_BRANCH=nightly $SOURCE_DIR/release/build_release.sh"), + step("build nightly", "RELEASE_BRANCH=nightly $SOURCE_DIR/tools/release/build_release.sh"), ]) }, 'nightly-dev': { deviceStage("build nightly-dev", "tizi-needs-can", [], [ - step("build nightly-dev", "PANDA_DEBUG_BUILD=1 RELEASE_BRANCH=nightly-dev $SOURCE_DIR/release/build_release.sh"), + step("build nightly-dev", "PANDA_DEBUG_BUILD=1 RELEASE_BRANCH=nightly-dev $SOURCE_DIR/tools/release/build_release.sh"), ]) }, ) @@ -203,7 +205,7 @@ node { 'onroad tests': { deviceStage("onroad", "tizi-needs-can", ["UNSAFE=1"], [ step("build openpilot", "cd openpilot/system/manager && ./build.py"), - step("check dirty", "release/check-dirty.sh"), + step("check dirty", "tools/release/check-dirty.sh"), step("onroad tests", "pytest openpilot/selfdrive/test/test_onroad.py -s", [timeout: 60]), ]) }, @@ -211,7 +213,7 @@ node { deviceStage("tizi-hardware", "tizi-common", ["UNSAFE=1"], [ step("build", "cd openpilot/system/manager && ./build.py"), step("test power draw", "pytest -s openpilot/selfdrive/test//test_power_draw.py"), - step("test encoder", "LD_LIBRARY_PATH=/usr/local/lib pytest openpilot/system/loggerd/tests/test_encoder.py", [diffPaths: ["openpilot/system/loggerd/"]]), + step("test encoder", "pytest openpilot/system/loggerd/tests/test_encoder.py", [diffPaths: ["openpilot/system/loggerd/"]]), step("test manager", "pytest openpilot/system/manager/test/test_manager.py"), ]) }, diff --git a/openpilot/tools/scripts/mem_usage.py b/openpilot/selfdrive/test/mem_usage.py old mode 100755 new mode 100644 similarity index 90% rename from openpilot/tools/scripts/mem_usage.py rename to openpilot/selfdrive/test/mem_usage.py index bc0e97e7ca..1446d0b4dc --- a/openpilot/tools/scripts/mem_usage.py +++ b/openpilot/selfdrive/test/mem_usage.py @@ -1,12 +1,9 @@ -#!/usr/bin/env python3 -import argparse import os from collections import defaultdict import numpy as np from openpilot.common.utils import tabulate -from openpilot.tools.lib.logreader import LogReader DEMO_ROUTE = "5beb9b58bd12b691/0000010a--a51155e496" MB = 1024 * 1024 @@ -210,29 +207,3 @@ def print_report(proc_logs, device_states=None): print_process_tables(op_procs, other_procs, total_mb, use_pss) print_memory_accounting(proc_logs, op_procs, other_procs, total_mb, use_pss) - - -if __name__ == "__main__": - parser = argparse.ArgumentParser(description="Analyze memory usage from route logs") - parser.add_argument("route", nargs="?", default=None, help="route ID or local rlog path") - parser.add_argument("--demo", action="store_true", help=f"use demo route ({DEMO_ROUTE})") - args = parser.parse_args() - - if args.demo: - route = DEMO_ROUTE - elif args.route: - route = args.route - else: - parser.error("provide a route or use --demo") - - print(f"Reading logs from: {route}") - - proc_logs = [] - device_states = [] - for msg in LogReader(route): - if msg.which() == 'procLog': - proc_logs.append(msg) - elif msg.which() == 'deviceState': - device_states.append(msg) - - print_report(proc_logs, device_states) diff --git a/openpilot/selfdrive/test/test_onroad.py b/openpilot/selfdrive/test/test_onroad.py index 56ea9dbd06..b2192b0d5a 100644 --- a/openpilot/selfdrive/test/test_onroad.py +++ b/openpilot/selfdrive/test/test_onroad.py @@ -283,7 +283,7 @@ class TestOnroad: print("--------------- Memory Usage -------------------") print("------------------------------------------------") - from openpilot.tools.scripts.mem_usage import print_report + from openpilot.selfdrive.test.mem_usage import print_report print_report(self.msgs['procLog'], self.msgs['deviceState']) offset = int(SERVICE_LIST['deviceState'].frequency * LOG_OFFSET) diff --git a/scripts/post-commit b/scripts/post-commit index 399b73c523..f9964639de 100755 --- a/scripts/post-commit +++ b/scripts/post-commit @@ -3,5 +3,5 @@ set -e if [[ -f .git/hooks/post-commit.d/post-commit ]]; then .git/hooks/post-commit.d/post-commit fi -openpilot/tools/op.sh lint --fast +tools/op.sh lint --fast echo "" diff --git a/openpilot/tools/CTF.md b/tools/CTF.md similarity index 100% rename from openpilot/tools/CTF.md rename to tools/CTF.md diff --git a/openpilot/tools/README.md b/tools/README.md similarity index 97% rename from openpilot/tools/README.md rename to tools/README.md index 522bb38868..1ea42bbe1d 100644 --- a/openpilot/tools/README.md +++ b/tools/README.md @@ -18,7 +18,7 @@ git clone https://github.com/commaai/openpilot.git **2. Run the setup script** ``` bash cd openpilot -openpilot/tools/op.sh setup +tools/op.sh setup ``` **3. Activate a Python shell** @@ -41,7 +41,7 @@ Follow [these instructions](https://docs.microsoft.com/en-us/windows/wsl/install **NOTE**: If you are running WSL 2 and experiencing performance issues with the UI or simulator, you may need to explicitly enable hardware acceleration by setting `GALLIUM_DRIVER=d3d12` before commands. Add `export GALLIUM_DRIVER=d3d12` to your `~/.bashrc` file to make it automatic for future sessions. ## CTF -Learn about the openpilot ecosystem and tools by playing our [CTF](/openpilot/tools/CTF.md). +Learn about the openpilot ecosystem and tools by playing our [CTF](/tools/CTF.md). ## Directory Structure diff --git a/openpilot/tools/car_porting/README.md b/tools/car_porting/README.md similarity index 87% rename from openpilot/tools/car_porting/README.md rename to tools/car_porting/README.md index 3766978e97..07ca2d0eba 100644 --- a/openpilot/tools/car_porting/README.md +++ b/tools/car_porting/README.md @@ -1,4 +1,4 @@ -# openpilot/tools/car_porting +# tools/car_porting Check out [this blog post](https://blog.comma.ai/how-to-write-a-car-port-for-openpilot/) for a high-level overview of porting a car. @@ -15,13 +15,13 @@ Example: > openpilot/tools/cabana/cabana '1bbe6bf2d62f58a8|2022-07-14--17-11-43' ``` -### [openpilot/tools/car_porting/auto_fingerprint.py](/openpilot/tools/car_porting/auto_fingerprint.py) +### [tools/car_porting/auto_fingerprint.py](/tools/car_porting/auto_fingerprint.py) Given a route and platform, automatically inserts FW fingerprints from the platform into the correct place in fingerprints.py Example: ```bash -> python3 openpilot/tools/car_porting/auto_fingerprint.py '1bbe6bf2d62f58a8|2022-07-14--17-11-43' 'OUTBACK' +> python3 tools/car_porting/auto_fingerprint.py '1bbe6bf2d62f58a8|2022-07-14--17-11-43' 'OUTBACK' Attempting to add fw version for: OUTBACK ``` @@ -39,13 +39,13 @@ FAILED openpilot/selfdrive/car/tests/test_car_interfaces.py::TestCarInterfaces:: ``` -### [openpilot/tools/car_porting/test_car_model.py](/openpilot/tools/car_porting/test_car_model.py) +### [tools/car_porting/test_car_model.py](/tools/car_porting/test_car_model.py) Given a route, runs most of the car interface to check for common errors like missing signals, blocked panda messages, and safety mismatches. #### Example: panda safety mismatch for gasPressed ```bash -> python3 openpilot/tools/car_porting/test_car_model.py '4822a427b188122a|2023-08-14--16-22-21' +> python3 tools/car_porting/test_car_model.py '4822a427b188122a|2023-08-14--16-22-21' ===================================================================== FAIL: test_panda_safety_carstate (__main__.CarModelTestCase.test_panda_safety_carstate) @@ -59,7 +59,7 @@ AssertionError: 1 is not false : panda safety doesn't agree with openpilot: {'ga ## Jupyter notebooks -To use these notebooks, install Jupyter within your [openpilot virtual environment](/openpilot/tools/README.md). +To use these notebooks, install Jupyter within your [openpilot virtual environment](/tools/README.md). ```bash uv pip install jupyter ipykernel @@ -71,7 +71,7 @@ Launching: jupyter notebook ``` -### [examples/subaru_steer_temp_fault.ipynb](/openpilot/tools/car_porting/examples/subaru_steer_temp_fault.ipynb) +### [examples/subaru_steer_temp_fault.ipynb](/tools/car_porting/examples/subaru_steer_temp_fault.ipynb) An example of searching through a database of segments for a specific condition, and plotting the results. @@ -79,7 +79,7 @@ An example of searching through a database of segments for a specific condition, *a plot of the steer_warning vs steering angle, where we can see it is clearly caused by a large steering angle change* -### [examples/subaru_long_accel.ipynb](/openpilot/tools/car_porting/examples/subaru_long_accel.ipynb) +### [examples/subaru_long_accel.ipynb](/tools/car_porting/examples/subaru_long_accel.ipynb) An example of plotting the response of an actuator when it is active. @@ -87,7 +87,7 @@ An example of plotting the response of an actuator when it is active. *a plot of the brake_pressure vs acceleration, where we can see it is a fairly linear response.* -### [examples/ford_vin_fingerprint.ipynb](/openpilot/tools/car_porting/examples/ford_vin_fingerprint.ipynb) +### [examples/ford_vin_fingerprint.ipynb](/tools/car_porting/examples/ford_vin_fingerprint.ipynb) In this example, we use the public comma car segments database to check if vin fingerprinting is feasible for ford. @@ -109,7 +109,7 @@ vin: 3FTTW8E31PRXXXXXX real platform: FORD MAVERICK 1ST GEN determi vin: 3FTTW8E99NRXXXXXX real platform: FORD MAVERICK 1ST GEN determined platform: mock correct: False ``` -### [examples/find_segments_with_message.ipynb](/openpilot/tools/car_porting/examples/find_segments_with_message.ipynb) +### [examples/find_segments_with_message.ipynb](/tools/car_porting/examples/find_segments_with_message.ipynb) Searches for segments where a set of given CAN message IDs are present. In the example, we search for all messages used for CAN-based ignition detection. diff --git a/openpilot/tools/car_porting/auto_fingerprint.py b/tools/car_porting/auto_fingerprint.py similarity index 100% rename from openpilot/tools/car_porting/auto_fingerprint.py rename to tools/car_porting/auto_fingerprint.py diff --git a/openpilot/tools/car_porting/examples/find_segments_with_message.ipynb b/tools/car_porting/examples/find_segments_with_message.ipynb similarity index 100% rename from openpilot/tools/car_porting/examples/find_segments_with_message.ipynb rename to tools/car_porting/examples/find_segments_with_message.ipynb diff --git a/openpilot/tools/car_porting/examples/ford_vin_fingerprint.ipynb b/tools/car_porting/examples/ford_vin_fingerprint.ipynb similarity index 100% rename from openpilot/tools/car_porting/examples/ford_vin_fingerprint.ipynb rename to tools/car_porting/examples/ford_vin_fingerprint.ipynb diff --git a/openpilot/tools/car_porting/examples/hkg_canfd_gear_message.ipynb b/tools/car_porting/examples/hkg_canfd_gear_message.ipynb similarity index 100% rename from openpilot/tools/car_porting/examples/hkg_canfd_gear_message.ipynb rename to tools/car_porting/examples/hkg_canfd_gear_message.ipynb diff --git a/openpilot/tools/car_porting/examples/subaru_fuzzy_fingerprint.ipynb b/tools/car_porting/examples/subaru_fuzzy_fingerprint.ipynb similarity index 100% rename from openpilot/tools/car_porting/examples/subaru_fuzzy_fingerprint.ipynb rename to tools/car_porting/examples/subaru_fuzzy_fingerprint.ipynb diff --git a/openpilot/tools/car_porting/examples/subaru_long_accel.ipynb b/tools/car_porting/examples/subaru_long_accel.ipynb similarity index 100% rename from openpilot/tools/car_porting/examples/subaru_long_accel.ipynb rename to tools/car_porting/examples/subaru_long_accel.ipynb diff --git a/openpilot/tools/car_porting/examples/subaru_steer_temp_fault.ipynb b/tools/car_porting/examples/subaru_steer_temp_fault.ipynb similarity index 100% rename from openpilot/tools/car_porting/examples/subaru_steer_temp_fault.ipynb rename to tools/car_porting/examples/subaru_steer_temp_fault.ipynb diff --git a/openpilot/tools/car_porting/measure_steering_accuracy.py b/tools/car_porting/measure_steering_accuracy.py similarity index 100% rename from openpilot/tools/car_porting/measure_steering_accuracy.py rename to tools/car_porting/measure_steering_accuracy.py diff --git a/openpilot/tools/car_porting/test_car_model.py b/tools/car_porting/test_car_model.py similarity index 100% rename from openpilot/tools/car_porting/test_car_model.py rename to tools/car_porting/test_car_model.py diff --git a/openpilot/tools/op.sh b/tools/op.sh similarity index 98% rename from openpilot/tools/op.sh rename to tools/op.sh index 3d0af526ba..d8de248c24 100755 --- a/openpilot/tools/op.sh +++ b/tools/op.sh @@ -201,7 +201,7 @@ function op_setup() { echo "Installing dependencies..." st="$(date +%s)" - SETUP_SCRIPT="openpilot/tools/setup_dependencies.sh" + SETUP_SCRIPT="tools/setup_dependencies.sh" if ! $OPENPILOT_ROOT/$SETUP_SCRIPT; then echo -e " ↳ [${RED}✗${NC}] Dependencies installation failed!" return 1 @@ -269,12 +269,12 @@ function op_venv() { function op_adb() { op_before_cmd - op_run_command openpilot/tools/scripts/adb_ssh.sh "$@" + op_run_command tools/scripts/adb_ssh.sh "$@" } function op_ssh() { op_before_cmd - op_run_command openpilot/tools/scripts/ssh.py "$@" + op_run_command tools/scripts/ssh.py "$@" } function op_script() { diff --git a/release/README.md b/tools/release/README.md similarity index 88% rename from release/README.md rename to tools/release/README.md index f3dcefd587..862836bf90 100644 --- a/release/README.md +++ b/tools/release/README.md @@ -11,7 +11,7 @@ - [ ] push the new branch - [ ] push to staging: - [ ] make sure you are on the newly created release master branch (`zerotentwo`) - - [ ] run `BRANCH=devel-staging release/build_stripped.sh`. Jenkins will then automatically build staging on device, run `test_onroad` and update the staging branch + - [ ] run `BRANCH=devel-staging tools/release/build_stripped.sh`. Jenkins will then automatically build staging on device, run `test_onroad` and update the staging branch - [ ] bump version on master: `openpilot/common/version.h` and `RELEASES.md` - [ ] post on Discord, tag `@release crew` diff --git a/release/build_release.sh b/tools/release/build_release.sh similarity index 94% rename from release/build_release.sh rename to tools/release/build_release.sh index 4f609aea3f..cf03c8b393 100755 --- a/release/build_release.sh +++ b/tools/release/build_release.sh @@ -33,7 +33,7 @@ git checkout --orphan $BUILD_BRANCH # do the files copy echo "[-] copying files T=$SECONDS" cd $SOURCE_DIR -cp -pR --parents $(./release/release_files.py) $BUILD_DIR/ +cp -pR --parents $(./tools/release/release_files.py) $BUILD_DIR/ # in the directory cd $BUILD_DIR @@ -73,7 +73,7 @@ find . -name '*.os' -delete find . -name '*.pyc' -delete find . -name 'moc_*' -delete find . -name '__pycache__' -delete -rm -rf .sconsign.dblite Jenkinsfile release/ +rm -rf .sconsign.dblite Jenkinsfile tools/release/ rm -f openpilot/selfdrive/modeld/models/*.onnx* # Mark as prebuilt release diff --git a/release/build_stripped.sh b/tools/release/build_stripped.sh similarity index 97% rename from release/build_stripped.sh rename to tools/release/build_stripped.sh index ea74aac859..1892360f6d 100755 --- a/release/build_stripped.sh +++ b/tools/release/build_stripped.sh @@ -38,7 +38,7 @@ git submodule foreach --recursive git clean -xdff # do the files copy echo "[-] copying files T=$SECONDS" cd $SOURCE_DIR -cp -pR --parents $(./release/release_files.py) $TARGET_DIR/ +cp -pR --parents $(./tools/release/release_files.py) $TARGET_DIR/ # in the directory cd $TARGET_DIR diff --git a/release/check-dirty.sh b/tools/release/check-dirty.sh similarity index 100% rename from release/check-dirty.sh rename to tools/release/check-dirty.sh diff --git a/release/check-submodules.sh b/tools/release/check-submodules.sh similarity index 100% rename from release/check-submodules.sh rename to tools/release/check-submodules.sh diff --git a/release/identity.sh b/tools/release/identity.sh similarity index 100% rename from release/identity.sh rename to tools/release/identity.sh diff --git a/release/pack.py b/tools/release/pack.py similarity index 100% rename from release/pack.py rename to tools/release/pack.py diff --git a/release/release_files.py b/tools/release/release_files.py similarity index 93% rename from release/release_files.py rename to tools/release/release_files.py index 36910293a4..dd6b16253c 100755 --- a/release/release_files.py +++ b/tools/release/release_files.py @@ -4,7 +4,7 @@ import re from pathlib import Path HERE = os.path.abspath(os.path.dirname(__file__)) -ROOT = HERE + "/.." +ROOT = os.path.abspath(os.path.join(HERE, "../..")) blacklist = [ ".git/", diff --git a/openpilot/tools/scripts/__init__.py b/tools/scripts/__init__.py similarity index 100% rename from openpilot/tools/scripts/__init__.py rename to tools/scripts/__init__.py diff --git a/openpilot/tools/scripts/adb_ssh.sh b/tools/scripts/adb_ssh.sh similarity index 100% rename from openpilot/tools/scripts/adb_ssh.sh rename to tools/scripts/adb_ssh.sh diff --git a/openpilot/tools/scripts/car/can_print_changes.py b/tools/scripts/car/can_print_changes.py similarity index 98% rename from openpilot/tools/scripts/car/can_print_changes.py rename to tools/scripts/car/can_print_changes.py index 1db29c3d37..e466cd2968 100755 --- a/openpilot/tools/scripts/car/can_print_changes.py +++ b/tools/scripts/car/can_print_changes.py @@ -5,7 +5,7 @@ import time from collections import defaultdict import openpilot.cereal.messaging as messaging -from openpilot.tools.scripts.can_table import can_table +from tools.scripts.car.can_table import can_table from openpilot.tools.lib.logreader import LogIterable, LogReader RED = '\033[91m' diff --git a/openpilot/tools/scripts/car/can_printer.py b/tools/scripts/car/can_printer.py similarity index 100% rename from openpilot/tools/scripts/car/can_printer.py rename to tools/scripts/car/can_printer.py diff --git a/openpilot/tools/scripts/car/can_table.py b/tools/scripts/car/can_table.py similarity index 100% rename from openpilot/tools/scripts/car/can_table.py rename to tools/scripts/car/can_table.py diff --git a/openpilot/tools/scripts/car/clear_dtc.py b/tools/scripts/car/clear_dtc.py similarity index 100% rename from openpilot/tools/scripts/car/clear_dtc.py rename to tools/scripts/car/clear_dtc.py diff --git a/openpilot/tools/scripts/car/disable_ecu.py b/tools/scripts/car/disable_ecu.py similarity index 100% rename from openpilot/tools/scripts/car/disable_ecu.py rename to tools/scripts/car/disable_ecu.py diff --git a/openpilot/tools/scripts/car/ecu_addrs.py b/tools/scripts/car/ecu_addrs.py similarity index 100% rename from openpilot/tools/scripts/car/ecu_addrs.py rename to tools/scripts/car/ecu_addrs.py diff --git a/openpilot/tools/scripts/car/fw_versions.py b/tools/scripts/car/fw_versions.py similarity index 100% rename from openpilot/tools/scripts/car/fw_versions.py rename to tools/scripts/car/fw_versions.py diff --git a/openpilot/tools/scripts/car/hyundai_enable_radar_points.py b/tools/scripts/car/hyundai_enable_radar_points.py similarity index 100% rename from openpilot/tools/scripts/car/hyundai_enable_radar_points.py rename to tools/scripts/car/hyundai_enable_radar_points.py diff --git a/openpilot/tools/scripts/car/max_lat_accel.py b/tools/scripts/car/max_lat_accel.py similarity index 100% rename from openpilot/tools/scripts/car/max_lat_accel.py rename to tools/scripts/car/max_lat_accel.py diff --git a/openpilot/tools/scripts/car/measure_torque_time_to_max.py b/tools/scripts/car/measure_torque_time_to_max.py similarity index 100% rename from openpilot/tools/scripts/car/measure_torque_time_to_max.py rename to tools/scripts/car/measure_torque_time_to_max.py diff --git a/openpilot/tools/scripts/car/read_dtc_status.py b/tools/scripts/car/read_dtc_status.py similarity index 100% rename from openpilot/tools/scripts/car/read_dtc_status.py rename to tools/scripts/car/read_dtc_status.py diff --git a/openpilot/tools/scripts/car/toyota_eps_factor.py b/tools/scripts/car/toyota_eps_factor.py similarity index 100% rename from openpilot/tools/scripts/car/toyota_eps_factor.py rename to tools/scripts/car/toyota_eps_factor.py diff --git a/openpilot/tools/scripts/car/vin.py b/tools/scripts/car/vin.py similarity index 100% rename from openpilot/tools/scripts/car/vin.py rename to tools/scripts/car/vin.py diff --git a/openpilot/tools/scripts/car/vw_mqb_config.py b/tools/scripts/car/vw_mqb_config.py similarity index 100% rename from openpilot/tools/scripts/car/vw_mqb_config.py rename to tools/scripts/car/vw_mqb_config.py diff --git a/openpilot/tools/scripts/count_events.py b/tools/scripts/count_events.py similarity index 100% rename from openpilot/tools/scripts/count_events.py rename to tools/scripts/count_events.py diff --git a/openpilot/tools/scripts/cpu_usage_stat.py b/tools/scripts/cpu_usage_stat.py similarity index 100% rename from openpilot/tools/scripts/cpu_usage_stat.py rename to tools/scripts/cpu_usage_stat.py diff --git a/openpilot/tools/scripts/cycle_alerts.py b/tools/scripts/cycle_alerts.py similarity index 100% rename from openpilot/tools/scripts/cycle_alerts.py rename to tools/scripts/cycle_alerts.py diff --git a/openpilot/tools/scripts/debug_fw_fingerprinting_offline.py b/tools/scripts/debug_fw_fingerprinting_offline.py similarity index 100% rename from openpilot/tools/scripts/debug_fw_fingerprinting_offline.py rename to tools/scripts/debug_fw_fingerprinting_offline.py diff --git a/openpilot/tools/scripts/devsync.py b/tools/scripts/devsync.py similarity index 100% rename from openpilot/tools/scripts/devsync.py rename to tools/scripts/devsync.py diff --git a/openpilot/tools/scripts/dump.py b/tools/scripts/dump.py similarity index 100% rename from openpilot/tools/scripts/dump.py rename to tools/scripts/dump.py diff --git a/openpilot/tools/scripts/extract_audio.py b/tools/scripts/extract_audio.py similarity index 100% rename from openpilot/tools/scripts/extract_audio.py rename to tools/scripts/extract_audio.py diff --git a/openpilot/tools/scripts/filter_log_message.py b/tools/scripts/filter_log_message.py similarity index 100% rename from openpilot/tools/scripts/filter_log_message.py rename to tools/scripts/filter_log_message.py diff --git a/openpilot/tools/scripts/fingerprint_from_route.py b/tools/scripts/fingerprint_from_route.py similarity index 100% rename from openpilot/tools/scripts/fingerprint_from_route.py rename to tools/scripts/fingerprint_from_route.py diff --git a/openpilot/tools/scripts/fuzz_fw_fingerprint.py b/tools/scripts/fuzz_fw_fingerprint.py similarity index 100% rename from openpilot/tools/scripts/fuzz_fw_fingerprint.py rename to tools/scripts/fuzz_fw_fingerprint.py diff --git a/openpilot/tools/scripts/get_fingerprint.py b/tools/scripts/get_fingerprint.py similarity index 100% rename from openpilot/tools/scripts/get_fingerprint.py rename to tools/scripts/get_fingerprint.py diff --git a/openpilot/tools/scripts/live_cpu_and_temp.py b/tools/scripts/live_cpu_and_temp.py similarity index 100% rename from openpilot/tools/scripts/live_cpu_and_temp.py rename to tools/scripts/live_cpu_and_temp.py diff --git a/tools/scripts/mem_usage.py b/tools/scripts/mem_usage.py new file mode 100755 index 0000000000..9b13a56ce2 --- /dev/null +++ b/tools/scripts/mem_usage.py @@ -0,0 +1,35 @@ +#!/usr/bin/env python3 +import argparse +import os +import sys + +sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))) + +from openpilot.selfdrive.test.mem_usage import DEMO_ROUTE, print_report +from openpilot.tools.lib.logreader import LogReader + + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description="Analyze memory usage from route logs") + parser.add_argument("route", nargs="?", default=None, help="route ID or local rlog path") + parser.add_argument("--demo", action="store_true", help=f"use demo route ({DEMO_ROUTE})") + args = parser.parse_args() + + if args.demo: + route = DEMO_ROUTE + elif args.route: + route = args.route + else: + parser.error("provide a route or use --demo") + + print(f"Reading logs from: {route}") + + proc_logs = [] + device_states = [] + for msg in LogReader(route): + if msg.which() == 'procLog': + proc_logs.append(msg) + elif msg.which() == 'deviceState': + device_states.append(msg) + + print_report(proc_logs, device_states) diff --git a/openpilot/tools/scripts/print_flags.py b/tools/scripts/print_flags.py similarity index 100% rename from openpilot/tools/scripts/print_flags.py rename to tools/scripts/print_flags.py diff --git a/openpilot/tools/scripts/profiling/clpeak/.gitignore b/tools/scripts/profiling/clpeak/.gitignore similarity index 100% rename from openpilot/tools/scripts/profiling/clpeak/.gitignore rename to tools/scripts/profiling/clpeak/.gitignore diff --git a/openpilot/tools/scripts/profiling/clpeak/build.sh b/tools/scripts/profiling/clpeak/build.sh similarity index 100% rename from openpilot/tools/scripts/profiling/clpeak/build.sh rename to tools/scripts/profiling/clpeak/build.sh diff --git a/openpilot/tools/scripts/profiling/clpeak/no_print.patch b/tools/scripts/profiling/clpeak/no_print.patch similarity index 100% rename from openpilot/tools/scripts/profiling/clpeak/no_print.patch rename to tools/scripts/profiling/clpeak/no_print.patch diff --git a/openpilot/tools/scripts/profiling/clpeak/run_continuously.patch b/tools/scripts/profiling/clpeak/run_continuously.patch similarity index 100% rename from openpilot/tools/scripts/profiling/clpeak/run_continuously.patch rename to tools/scripts/profiling/clpeak/run_continuously.patch diff --git a/openpilot/tools/scripts/profiling/ftrace.sh b/tools/scripts/profiling/ftrace.sh similarity index 100% rename from openpilot/tools/scripts/profiling/ftrace.sh rename to tools/scripts/profiling/ftrace.sh diff --git a/openpilot/tools/scripts/profiling/palanteer/.gitignore b/tools/scripts/profiling/palanteer/.gitignore similarity index 100% rename from openpilot/tools/scripts/profiling/palanteer/.gitignore rename to tools/scripts/profiling/palanteer/.gitignore diff --git a/openpilot/tools/scripts/profiling/palanteer/setup.sh b/tools/scripts/profiling/palanteer/setup.sh similarity index 100% rename from openpilot/tools/scripts/profiling/palanteer/setup.sh rename to tools/scripts/profiling/palanteer/setup.sh diff --git a/openpilot/tools/scripts/profiling/perfetto/.gitignore b/tools/scripts/profiling/perfetto/.gitignore similarity index 100% rename from openpilot/tools/scripts/profiling/perfetto/.gitignore rename to tools/scripts/profiling/perfetto/.gitignore diff --git a/openpilot/tools/scripts/profiling/perfetto/build.sh b/tools/scripts/profiling/perfetto/build.sh similarity index 100% rename from openpilot/tools/scripts/profiling/perfetto/build.sh rename to tools/scripts/profiling/perfetto/build.sh diff --git a/openpilot/tools/scripts/profiling/perfetto/copy.sh b/tools/scripts/profiling/perfetto/copy.sh similarity index 100% rename from openpilot/tools/scripts/profiling/perfetto/copy.sh rename to tools/scripts/profiling/perfetto/copy.sh diff --git a/openpilot/tools/scripts/profiling/perfetto/record.sh b/tools/scripts/profiling/perfetto/record.sh similarity index 100% rename from openpilot/tools/scripts/profiling/perfetto/record.sh rename to tools/scripts/profiling/perfetto/record.sh diff --git a/openpilot/tools/scripts/profiling/perfetto/server.sh b/tools/scripts/profiling/perfetto/server.sh similarity index 100% rename from openpilot/tools/scripts/profiling/perfetto/server.sh rename to tools/scripts/profiling/perfetto/server.sh diff --git a/openpilot/tools/scripts/profiling/perfetto/traces.sh b/tools/scripts/profiling/perfetto/traces.sh similarity index 100% rename from openpilot/tools/scripts/profiling/perfetto/traces.sh rename to tools/scripts/profiling/perfetto/traces.sh diff --git a/openpilot/tools/scripts/profiling/py-spy/profile.sh b/tools/scripts/profiling/py-spy/profile.sh similarity index 100% rename from openpilot/tools/scripts/profiling/py-spy/profile.sh rename to tools/scripts/profiling/py-spy/profile.sh diff --git a/openpilot/tools/scripts/profiling/snapdragon/.gitignore b/tools/scripts/profiling/snapdragon/.gitignore similarity index 100% rename from openpilot/tools/scripts/profiling/snapdragon/.gitignore rename to tools/scripts/profiling/snapdragon/.gitignore diff --git a/openpilot/tools/scripts/profiling/snapdragon/README.md b/tools/scripts/profiling/snapdragon/README.md similarity index 100% rename from openpilot/tools/scripts/profiling/snapdragon/README.md rename to tools/scripts/profiling/snapdragon/README.md diff --git a/openpilot/tools/scripts/profiling/snapdragon/setup-agnos.sh b/tools/scripts/profiling/snapdragon/setup-agnos.sh similarity index 100% rename from openpilot/tools/scripts/profiling/snapdragon/setup-agnos.sh rename to tools/scripts/profiling/snapdragon/setup-agnos.sh diff --git a/openpilot/tools/scripts/profiling/snapdragon/setup-profiler.sh b/tools/scripts/profiling/snapdragon/setup-profiler.sh similarity index 100% rename from openpilot/tools/scripts/profiling/snapdragon/setup-profiler.sh rename to tools/scripts/profiling/snapdragon/setup-profiler.sh diff --git a/openpilot/tools/scripts/profiling/watch-irqs.sh b/tools/scripts/profiling/watch-irqs.sh similarity index 100% rename from openpilot/tools/scripts/profiling/watch-irqs.sh rename to tools/scripts/profiling/watch-irqs.sh diff --git a/openpilot/tools/scripts/qlog_size.py b/tools/scripts/qlog_size.py similarity index 100% rename from openpilot/tools/scripts/qlog_size.py rename to tools/scripts/qlog_size.py diff --git a/openpilot/tools/scripts/run_process_on_route.py b/tools/scripts/run_process_on_route.py similarity index 100% rename from openpilot/tools/scripts/run_process_on_route.py rename to tools/scripts/run_process_on_route.py diff --git a/openpilot/tools/scripts/serial.sh b/tools/scripts/serial.sh similarity index 100% rename from openpilot/tools/scripts/serial.sh rename to tools/scripts/serial.sh diff --git a/openpilot/tools/scripts/set_car_params.py b/tools/scripts/set_car_params.py similarity index 100% rename from openpilot/tools/scripts/set_car_params.py rename to tools/scripts/set_car_params.py diff --git a/openpilot/tools/scripts/setup_ssh_keys.py b/tools/scripts/setup_ssh_keys.py similarity index 100% rename from openpilot/tools/scripts/setup_ssh_keys.py rename to tools/scripts/setup_ssh_keys.py diff --git a/openpilot/tools/scripts/ssh.py b/tools/scripts/ssh.py similarity index 100% rename from openpilot/tools/scripts/ssh.py rename to tools/scripts/ssh.py diff --git a/openpilot/tools/scripts/test_fw_query_on_routes.py b/tools/scripts/test_fw_query_on_routes.py similarity index 100% rename from openpilot/tools/scripts/test_fw_query_on_routes.py rename to tools/scripts/test_fw_query_on_routes.py diff --git a/openpilot/tools/scripts/uiview.py b/tools/scripts/uiview.py similarity index 100% rename from openpilot/tools/scripts/uiview.py rename to tools/scripts/uiview.py diff --git a/openpilot/tools/scripts/watch_timings.py b/tools/scripts/watch_timings.py similarity index 100% rename from openpilot/tools/scripts/watch_timings.py rename to tools/scripts/watch_timings.py diff --git a/openpilot/tools/setup.sh b/tools/setup.sh similarity index 96% rename from openpilot/tools/setup.sh rename to tools/setup.sh index 1437a1d686..dafd466ef9 100755 --- a/openpilot/tools/setup.sh +++ b/tools/setup.sh @@ -121,10 +121,10 @@ function git_clone() { function install_with_op() { cd $OPENPILOT_ROOT - $OPENPILOT_ROOT/openpilot/tools/op.sh install - $OPENPILOT_ROOT/openpilot/tools/op.sh post-commit + $OPENPILOT_ROOT/tools/op.sh install + $OPENPILOT_ROOT/tools/op.sh post-commit - if ! $OPENPILOT_ROOT/openpilot/tools/op.sh setup; then + if ! $OPENPILOT_ROOT/tools/op.sh setup; then echo -e "\n[${RED}✗${NC}] failed to install openpilot!" return 1 fi diff --git a/openpilot/tools/setup_dependencies.sh b/tools/setup_dependencies.sh similarity index 100% rename from openpilot/tools/setup_dependencies.sh rename to tools/setup_dependencies.sh From 5629b5a83d003027344a451712fb0e37b43e7da4 Mon Sep 17 00:00:00 2001 From: probablyanasian <43358667+probablyanasian@users.noreply.github.com> Date: Thu, 25 Jun 2026 18:06:42 -0700 Subject: [PATCH 084/151] bump sensors test limits (#38245) * bump sensors test limits * loosen back to 60 c max due to device density * 10 dps in 3d is 0.3 rad max --- openpilot/system/sensord/tests/test_sensord.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openpilot/system/sensord/tests/test_sensord.py b/openpilot/system/sensord/tests/test_sensord.py index 27c2365602..23811189f6 100644 --- a/openpilot/system/sensord/tests/test_sensord.py +++ b/openpilot/system/sensord/tests/test_sensord.py @@ -14,8 +14,8 @@ SensorConfig = namedtuple('SensorConfig', ['service', 'measurement', 'sanity_min SENSOR_CONFIGS = ( SensorConfig("accelerometer", "acceleration", 5, 15, 5), - SensorConfig("gyroscope", "gyroUncalibrated", 0, .15, 0.5), - SensorConfig("temperatureSensor", "temperature", 10, 40, 0.5), # set for max range of our office + SensorConfig("gyroscope", "gyroUncalibrated", 0, .3, 0.5), + SensorConfig("temperatureSensor", "temperature", 10, 60, 0.5), # looser for device density ) SENSOR_CONFIGS_BY_MEASUREMENT = {config.measurement: config for config in SENSOR_CONFIGS} From 069506aa36d43c3fc967cee5a301a95df0924517 Mon Sep 17 00:00:00 2001 From: ZwX1616 Date: Fri, 26 Jun 2026 13:55:30 -0700 Subject: [PATCH 085/151] sound: use log enum (#38246) --- openpilot/cereal/log.capnp | 23 +++++++++++++++++-- openpilot/selfdrive/selfdrived/events.py | 6 ++--- .../ui/mici/onroad/driver_camera_dialog.py | 3 +-- openpilot/selfdrive/ui/soundd.py | 5 ++-- openpilot/selfdrive/ui/tests/test_soundd.py | 4 ++-- 5 files changed, 29 insertions(+), 12 deletions(-) diff --git a/openpilot/cereal/log.capnp b/openpilot/cereal/log.capnp index beb71c8da8..2c4ff026e6 100644 --- a/openpilot/cereal/log.capnp +++ b/openpilot/cereal/log.capnp @@ -771,13 +771,28 @@ struct SelfdriveState { alertStatus @5 :AlertStatus; alertSize @6 :AlertSize; alertType @7 :Text; - alertSound @8 :Car.CarControl.HUDControl.AudibleAlert; + alertSound @13 :AudibleAlert; alertHudVisual @12 :Car.CarControl.HUDControl.VisualAlert; # configurable driving settings experimentalMode @10 :Bool; personality @11 :LongitudinalPersonality; + enum AudibleAlert { + none @0; + + engage @1; + disengage @2; + refuse @3; + + warningSoft @4; + warningImmediate @5; + + prompt @6; + promptRepeat @7; + promptDistracted @8; + } + enum OpenpilotState @0xdbe58b96d2d1ac61 { disabled @0; preEnabled @1; @@ -798,6 +813,10 @@ struct SelfdriveState { mid @2; full @3; } + + deprecated :group { + alertSound @8 :Car.CarControl.HUDControl.AudibleAlert; + } } struct ControlsState @0x97ff69c53601abf1 { @@ -918,7 +937,7 @@ struct ControlsState @0x97ff69c53601abf1 { alertStatus @38 :SelfdriveState.AlertStatus; alertSize @39 :SelfdriveState.AlertSize; alertType @44 :Text; - alertSound2 @56 :Car.CarControl.HUDControl.AudibleAlert; + alertSound2 @56 :SelfdriveState.AudibleAlert; engageable @41 :Bool; # can OP be engaged? state @31 :SelfdriveState.OpenpilotState; enabled @19 :Bool; diff --git a/openpilot/selfdrive/selfdrived/events.py b/openpilot/selfdrive/selfdrived/events.py index cc841accaf..44814c2908 100755 --- a/openpilot/selfdrive/selfdrived/events.py +++ b/openpilot/selfdrive/selfdrived/events.py @@ -19,7 +19,7 @@ from openpilot.common.hardware import HARDWARE AlertSize = log.SelfdriveState.AlertSize AlertStatus = log.SelfdriveState.AlertStatus VisualAlert = car.CarControl.HUDControl.VisualAlert -AudibleAlert = car.CarControl.HUDControl.AudibleAlert +AudibleAlert = log.SelfdriveState.AudibleAlert EventName = log.OnroadEvent.EventName @@ -118,7 +118,7 @@ class Alert: alert_size: log.SelfdriveState.AlertSize, priority: Priority, visual_alert: car.CarControl.HUDControl.VisualAlert, - audible_alert: car.CarControl.HUDControl.AudibleAlert, + audible_alert: log.SelfdriveState.AudibleAlert, duration: float, creation_delay: float = 0.): @@ -183,7 +183,7 @@ class ImmediateDisableAlert(Alert): class EngagementAlert(Alert): - def __init__(self, audible_alert: car.CarControl.HUDControl.AudibleAlert): + def __init__(self, audible_alert: log.SelfdriveState.AudibleAlert): super().__init__("", "", AlertStatus.normal, AlertSize.none, Priority.MID, VisualAlert.none, diff --git a/openpilot/selfdrive/ui/mici/onroad/driver_camera_dialog.py b/openpilot/selfdrive/ui/mici/onroad/driver_camera_dialog.py index d880189412..35ebc34955 100644 --- a/openpilot/selfdrive/ui/mici/onroad/driver_camera_dialog.py +++ b/openpilot/selfdrive/ui/mici/onroad/driver_camera_dialog.py @@ -1,6 +1,5 @@ import pyray as rl from openpilot.cereal import log, messaging -from opendbc.car.structs import car from msgq.visionipc import VisionStreamType from openpilot.selfdrive.ui.mici.onroad.cameraview import CameraView from openpilot.selfdrive.ui.mici.onroad.driver_state import DriverStateRenderer @@ -105,7 +104,7 @@ class BaseDriverCameraDialog(Widget): if self._pm is None: return - AudibleAlert = car.CarControl.HUDControl.AudibleAlert + AudibleAlert = log.SelfdriveState.AudibleAlert ALERT_SOUNDS = { 'two': AudibleAlert.promptDistracted, 'three': AudibleAlert.warningImmediate, diff --git a/openpilot/selfdrive/ui/soundd.py b/openpilot/selfdrive/ui/soundd.py index 901e2b56cb..2eb731e9e1 100644 --- a/openpilot/selfdrive/ui/soundd.py +++ b/openpilot/selfdrive/ui/soundd.py @@ -4,8 +4,7 @@ import time import wave -from openpilot.cereal import messaging -from opendbc.car.structs import car +from openpilot.cereal import log, messaging from openpilot.common.basedir import BASEDIR from openpilot.common.filter_simple import FirstOrderFilter from openpilot.common.realtime import Ratekeeper @@ -31,7 +30,7 @@ if HARDWARE.get_device_type() == "tizi": AMBIENT_DB = 30 VOLUME_BASE = 10 -AudibleAlert = car.CarControl.HUDControl.AudibleAlert +AudibleAlert = log.SelfdriveState.AudibleAlert sound_list: dict[int, tuple[str, int | None, float]] = { diff --git a/openpilot/selfdrive/ui/tests/test_soundd.py b/openpilot/selfdrive/ui/tests/test_soundd.py index 2890d4ae78..f878839c23 100644 --- a/openpilot/selfdrive/ui/tests/test_soundd.py +++ b/openpilot/selfdrive/ui/tests/test_soundd.py @@ -1,11 +1,11 @@ -from opendbc.car.structs import car +from openpilot.cereal import log from openpilot.cereal import messaging from openpilot.cereal.messaging import SubMaster, PubMaster from openpilot.selfdrive.ui.soundd import SELFDRIVE_STATE_TIMEOUT, check_selfdrive_timeout_alert import time -AudibleAlert = car.CarControl.HUDControl.AudibleAlert +AudibleAlert = log.SelfdriveState.AudibleAlert class TestSoundd: From f9c555a3fefffdecaf930e398e486aa3a5d2ae30 Mon Sep 17 00:00:00 2001 From: ZwX1616 Date: Fri, 26 Jun 2026 14:57:19 -0700 Subject: [PATCH 086/151] DM: update escalation/lockout specs; softer sounds (#38244) --- openpilot/cereal/log.capnp | 13 ++- .../selfdrive/assets/sounds/pre_alert.wav | 3 + .../assets/sounds/prompt_distracted.wav | 4 +- openpilot/selfdrive/controls/controlsd.py | 2 +- openpilot/selfdrive/monitoring/policy.py | 92 ++++++++++++------- .../selfdrive/monitoring/test_monitoring.py | 75 +++++++++------ openpilot/selfdrive/selfdrived/events.py | 17 +++- openpilot/selfdrive/selfdrived/selfdrived.py | 5 +- .../ui/mici/onroad/driver_camera_dialog.py | 1 + openpilot/selfdrive/ui/soundd.py | 2 + openpilot/selfdrive/ui/tests/test_soundd.py | 3 +- 11 files changed, 142 insertions(+), 75 deletions(-) create mode 100644 openpilot/selfdrive/assets/sounds/pre_alert.wav diff --git a/openpilot/cereal/log.capnp b/openpilot/cereal/log.capnp index 2c4ff026e6..8d4d801161 100644 --- a/openpilot/cereal/log.capnp +++ b/openpilot/cereal/log.capnp @@ -791,6 +791,8 @@ struct SelfdriveState { prompt @6; promptRepeat @7; promptDistracted @8; + + preAlert @9; } enum OpenpilotState @0xdbe58b96d2d1ac61 { @@ -2139,8 +2141,10 @@ struct DriverMonitoringStateDEPRECATED @0xb83cda094a1da284 { struct DriverMonitoringState { lockout @0 :Bool; - alertCountLockoutPercent @1 :Int8; - alertTimeLockoutPercent @2 :Int8; + lockoutRecoveryPercent @11 :Int8; + alert3Count @12 :Int8; + noResponseCount @13 :Int8; + noResponseForceDecel @14 :Bool; alwaysOn @3 :Bool; alwaysOnLockout @4 :Bool; @@ -2204,6 +2208,11 @@ struct DriverMonitoringState { calibratedPercent @0 :Int8; offset @1 :Float32; } + + deprecated :group { + alertCountLockoutPercent @1 :Int8; + alertTimeLockoutPercent @2 :Int8; + } } struct Boot { diff --git a/openpilot/selfdrive/assets/sounds/pre_alert.wav b/openpilot/selfdrive/assets/sounds/pre_alert.wav new file mode 100644 index 0000000000..4443bf7d23 --- /dev/null +++ b/openpilot/selfdrive/assets/sounds/pre_alert.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2c0af7f5fe57bb36ab96fae868e20feca763541c97a61b3a3a84a0e7fcb81163 +size 83350 diff --git a/openpilot/selfdrive/assets/sounds/prompt_distracted.wav b/openpilot/selfdrive/assets/sounds/prompt_distracted.wav index 750d580f04..c11993f20c 100644 --- a/openpilot/selfdrive/assets/sounds/prompt_distracted.wav +++ b/openpilot/selfdrive/assets/sounds/prompt_distracted.wav @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1810ad0418ac234f02dec005883c8f0e1c3e0e5ece7a3157803c5a66cb8e5adc -size 85662 +oid sha256:412ef25d2fb103c1ebd55c667313a5921493305fb4e1f4e1dafc08d3b95d86ab +size 73026 diff --git a/openpilot/selfdrive/controls/controlsd.py b/openpilot/selfdrive/controls/controlsd.py index fe3b0f66c0..9afcdf1d27 100755 --- a/openpilot/selfdrive/controls/controlsd.py +++ b/openpilot/selfdrive/controls/controlsd.py @@ -200,7 +200,7 @@ class Controls: cs.upAccelCmd = float(self.LoC.pid.p) cs.uiAccelCmd = float(self.LoC.pid.i) cs.ufAccelCmd = float(self.LoC.pid.f) - cs.forceDecel = bool((self.sm['driverMonitoringState'].alertLevel == log.DriverMonitoringState.AlertLevel.three) or + cs.forceDecel = bool(self.sm['driverMonitoringState'].noResponseForceDecel or (self.sm['selfdriveState'].state == State.softDisabling)) # trigger the car's stock driver monitoring escalation diff --git a/openpilot/selfdrive/monitoring/policy.py b/openpilot/selfdrive/monitoring/policy.py index adb61b0a38..03db1dc02e 100644 --- a/openpilot/selfdrive/monitoring/policy.py +++ b/openpilot/selfdrive/monitoring/policy.py @@ -25,21 +25,27 @@ def to_percent(v): class DRIVER_MONITOR_SETTINGS: def __init__(self): - # https://eur-lex.europa.eu/legal-content/EN/TXT/PDF/?uri=CELEX:42018X1947&rid=2 - self._WHEELTOUCH_POLICY_ALERT_1_TIMEOUT = 15. - self._WHEELTOUCH_POLICY_ALERT_2_TIMEOUT = 24. - self._WHEELTOUCH_POLICY_ALERT_3_TIMEOUT = 30. - # https://cdn.euroncap.com/cars/assets/euro_ncap_protocol_safe_driving_driver_engagement_v11_a30e874152.pdf - self._VISION_POLICY_ALERT_1_TIMEOUT = 3. - self._VISION_POLICY_ALERT_2_TIMEOUT = 5. - self._VISION_POLICY_ALERT_3_TIMEOUT = 11. + # https://eur-lex.europa.eu/legal-content/EN/TXT/PDF/?uri=OJ:L_202501899 + self._ALERT_MIN_SPEED = 2.8 # 10 km/h + + self._WHEELTOUCH_POLICY_ALERT_1_TIMEOUT = 5. + self._WHEELTOUCH_POLICY_ALERT_2_TIMEOUT = 15. + self._WHEELTOUCH_POLICY_ALERT_3_TIMEOUT = 25. + self._VISION_POLICY_ALERT_1_TIMEOUT = 5. + self._VISION_POLICY_ALERT_2_TIMEOUT = 8. + self._VISION_POLICY_ALERT_3_TIMEOUT = 13. + + # no response = alert_3 sustained for certain amount of time + self._NO_RESPONSE_TIMEOUT = 5. + + # lockout specs + self._MAX_ALERT_3 = 2 + self._MAX_NO_RESPONSE = 1 + self._LOCKOUT_TIME = int(1800 / DT_DMON) self._TIMEOUT_RECOVERY_FACTOR_MAX = 5. self._TIMEOUT_RECOVERY_FACTOR_MIN = 1.25 - self._MAX_TERMINAL_ALERTS = 3 # not allowed to engage after 3 terminal alerts - self._MAX_TERMINAL_DURATION = int(30 / DT_DMON) # not allowed to engage after 30s of terminal alerts - self._FACE_THRESHOLD = 0.7 self._EYE_THRESHOLD = 0.65 self._SG_THRESHOLD = 0.9 @@ -142,8 +148,11 @@ class DriverMonitoring: self.wheel_on_right_last = None self.wheel_on_right_default = rhd_saved self.face_detected = False - self.terminal_alert_cnt = 0 - self.terminal_time = 0 + self.alert_3_cnt = 0 + self.cnt_since_alert_3 = 0 + self.no_response_timeout = int(self.settings._NO_RESPONSE_TIMEOUT / DT_DMON) + self.no_response_cnt = 0 + self.lockout_time = 0 self.step_change = 0. self.active_policy = MonitoringPolicy.vision self.driver_interacting = False @@ -230,7 +239,7 @@ class DriverMonitoring: self.distracted_types['eye'] = bool((self.blink.left + self.blink.right)*0.5 > self.settings._BLINK_THRESHOLD) self.distracted_types['phone'] = bool(self.phone_prob > self.settings._PHONE_THRESH) - def _update_states(self, driver_state, cal_rpy, car_speed, op_engaged, standstill, demo_mode=False, steering_angle_deg=0.): + def _update_states(self, driver_state, cal_rpy, car_speed, op_engaged, lowspeed, demo_mode=False, steering_angle_deg=0.): rhd_pred = driver_state.wheelOnRightProb # calibrates only when there's movement and either face detected if car_speed > self.settings._WHEELPOS_CALIB_MIN_SPEED and (driver_state.leftDriverData.faceProb > self.settings._FACE_THRESHOLD or @@ -281,7 +290,7 @@ class DriverMonitoring: if self.face_detected and not self.driver_distracted: dcam_uncertain = self.model_std_max > self.settings._DCAM_UNCERTAIN_ALERT_THRESHOLD - if dcam_uncertain and not standstill: + if dcam_uncertain and not lowspeed: self.dcam_uncertain_cnt += 1 self.dcam_reset_cnt = 0 else: @@ -296,14 +305,22 @@ class DriverMonitoring: elif self.face_detected and self.pose.low_std: self.hi_stds = 0 - def _update_events(self, driver_engaged, op_engaged, standstill, wrong_gear): + def _update_events(self, driver_engaged, op_engaged, lowspeed, wrong_gear): self.alert_level = AlertLevel.none self.driver_interacting = driver_engaged - if self.terminal_alert_cnt >= self.settings._MAX_TERMINAL_ALERTS or \ - self.terminal_time >= self.settings._MAX_TERMINAL_DURATION: + if self.alert_3_cnt >= self.settings._MAX_ALERT_3 or self.no_response_cnt >= self.settings._MAX_NO_RESPONSE: self.too_distracted = True + if self.too_distracted: + self.lockout_time += 1 + if self.lockout_time > self.settings._LOCKOUT_TIME: + self.too_distracted = False + self.alert_3_cnt = 0 + self.cnt_since_alert_3 = 0 + self.no_response_cnt = 0 + self.lockout_time = 0 + always_on_valid = self.always_on and not wrong_gear if (self.driver_interacting and self.awareness > 0 and self.active_policy == MonitoringPolicy.wheeltouch) or \ (not always_on_valid and not op_engaged) or \ @@ -315,11 +332,11 @@ class DriverMonitoring: awareness_prev = self.awareness _reaching_alert_1 = self.awareness - self.step_change <= self.threshold_alert_1 _reaching_alert_3 = self.awareness - self.step_change <= 0 - standstill_exemption = standstill and _reaching_alert_1 + lowspeed_exemption = lowspeed and _reaching_alert_1 always_on_exemption = always_on_valid and not op_engaged and _reaching_alert_3 if self.awareness > 0 and \ - ((self.driver_distraction_filter.x < 0.37 and self.face_detected and self.pose.low_std) or standstill_exemption): + ((self.driver_distraction_filter.x < 0.37 and self.face_detected and self.pose.low_std) or lowspeed_exemption): if self.driver_interacting: self._reset_awareness() return @@ -336,21 +353,26 @@ class DriverMonitoring: maybe_distracted = self.is_model_uncertain or not self.face_detected if certainly_distracted or maybe_distracted: - # should always be counting if distracted unless at standstill and reaching green + # should always be counting if distracted unless at low speed and reaching green # also will not be reaching 0 if DM is active when not engaged - if not (standstill_exemption or always_on_exemption): + if not (lowspeed_exemption or always_on_exemption): self.awareness = max(self.awareness - self.step_change, -0.1) if self.awareness <= 0.: # terminal alert: disengagement required self.alert_level = AlertLevel.three - self.terminal_time += 1 if awareness_prev > 0.: - self.terminal_alert_cnt += 1 - elif self.awareness <= self.threshold_alert_2: - self.alert_level = AlertLevel.two - elif self.awareness <= self.threshold_alert_1: - self.alert_level = AlertLevel.one + self.alert_3_cnt += 1 + self.cnt_since_alert_3 = 0 + else: + self.cnt_since_alert_3 += 1 + if self.cnt_since_alert_3 == self.no_response_timeout: + self.no_response_cnt += 1 + else: + if self.awareness <= self.threshold_alert_2: + self.alert_level = AlertLevel.two + elif self.awareness <= self.threshold_alert_1: + self.alert_level = AlertLevel.one def get_state_packet(self, valid=True): # build driverMonitoringState packet @@ -358,8 +380,10 @@ class DriverMonitoring: dm = dat.driverMonitoringState dm.lockout = self.too_distracted - dm.alertCountLockoutPercent = to_percent(self.terminal_alert_cnt / self.settings._MAX_TERMINAL_ALERTS) - dm.alertTimeLockoutPercent = to_percent(self.terminal_time / self.settings._MAX_TERMINAL_DURATION) + dm.lockoutRecoveryPercent = to_percent(self.lockout_time / self.settings._LOCKOUT_TIME) + dm.alert3Count = self.alert_3_cnt + dm.noResponseCount = self.no_response_cnt + dm.noResponseForceDecel = self.alert_level == AlertLevel.three and self.cnt_since_alert_3 >= self.no_response_timeout dm.alwaysOn = self.always_on dm.alwaysOnLockout = self.always_on and self.awareness <= self.threshold_alert_2 dm.alertLevel = self.alert_level @@ -396,7 +420,7 @@ class DriverMonitoring: car_speed = 30 enabled = True wrong_gear = False - standstill = False + lowspeed = False driver_engaged = False brake_disengage_prob = 1.0 steering_angle_deg = 0.0 @@ -405,7 +429,7 @@ class DriverMonitoring: car_speed = sm['carState'].vEgo enabled = sm['selfdriveState'].enabled wrong_gear = sm['carState'].gearShifter not in (car.CarState.GearShifter.drive, car.CarState.GearShifter.low) - standstill = sm['carState'].standstill + lowspeed = car_speed < self.settings._ALERT_MIN_SPEED driver_engaged = sm['carState'].steeringPressed or sm['carState'].gasPressed brake_disengage_prob = sm['modelV2'].meta.disengagePredictions.brakeDisengageProbs[0] # brake disengage prob in next 2s steering_angle_deg = sm['carState'].steeringAngleDeg @@ -422,7 +446,7 @@ class DriverMonitoring: cal_rpy=rpyCalib, car_speed=car_speed, op_engaged=enabled, - standstill=standstill, + lowspeed=lowspeed, demo_mode=demo, steering_angle_deg=steering_angle_deg, ) @@ -431,6 +455,6 @@ class DriverMonitoring: self._update_events( driver_engaged=driver_engaged, op_engaged=enabled, - standstill=standstill, + lowspeed=lowspeed, wrong_gear=wrong_gear, ) diff --git a/openpilot/selfdrive/monitoring/test_monitoring.py b/openpilot/selfdrive/monitoring/test_monitoring.py index c13f043ce9..48fffcc1c0 100644 --- a/openpilot/selfdrive/monitoring/test_monitoring.py +++ b/openpilot/selfdrive/monitoring/test_monitoring.py @@ -1,5 +1,3 @@ -import numpy as np - from openpilot.cereal import log from openpilot.common.realtime import DT_DMON from openpilot.selfdrive.monitoring.policy import DriverMonitoring, DRIVER_MONITOR_SETTINGS @@ -49,15 +47,15 @@ always_true = [True] * int(TEST_TIMESPAN / DT_DMON) always_false = [False] * int(TEST_TIMESPAN / DT_DMON) class TestMonitoring: - def _run_seq(self, msgs, interaction, engaged, standstill): + def _run_seq(self, msgs, interaction, engaged, lowspeed): DM = DriverMonitoring() alert_lvls = [] for idx in range(len(msgs)): - DM._update_states(msgs[idx], [0, 0, 0], 0, engaged[idx], standstill[idx]) + DM._update_states(msgs[idx], [0, 0, 0], 0, engaged[idx], lowspeed[idx]) # cal_rpy and car_speed don't matter here # evaluate events at 10Hz for tests - DM._update_events(interaction[idx], engaged[idx], standstill[idx], 0) + DM._update_events(interaction[idx], engaged[idx], lowspeed[idx], 0) alert_lvls.append(DM.alert_level) assert len(alert_lvls) == len(msgs), f"got {len(alert_lvls)} for {len(msgs)} driverState input msgs" return alert_lvls, DM @@ -82,6 +80,25 @@ class TestMonitoring: (TEST_TIMESPAN - 10 - s._VISION_POLICY_ALERT_3_TIMEOUT) / 2) / DT_DMON)] == 3 assert isinstance(d_status.awareness, float) + # engaged, distracted past red and beyond the no-response window -> unavailability response + lockout + def test_distracted_lockout(self): + alert_lvls, d_status = self._run_seq(always_distracted, always_false, always_true, always_false) + s = d_status.settings + assert alert_lvls[int(DISTRACTED_SECONDS_TO_RED / DT_DMON)] == 3 + assert d_status.alert_3_cnt == 1 + assert d_status.no_response_cnt == s._MAX_NO_RESPONSE + assert d_status.too_distracted + assert d_status.lockout_time > 0 + + # no face -> wheeltouch red, sustained past the no-response timeout -> unavailability response + lockout + def test_invisible_lockout(self): + _, d_status = self._run_seq(always_no_face, always_false, always_true, always_false) + s = d_status.settings + assert d_status.active_policy == log.DriverMonitoringState.MonitoringPolicy.wheeltouch + assert d_status.alert_3_cnt == 1 + assert d_status.no_response_cnt == s._MAX_NO_RESPONSE + assert d_status.too_distracted + # engaged, no face detected the whole time, no action def test_fully_invisible_driver(self): alert_lvls, d_status = self._run_seq(always_no_face, always_false, always_true, always_false) @@ -137,22 +154,22 @@ class TestMonitoring: # engaged, invisible driver, down to orange, driver touches wheel; then down to orange again, driver appears # - both actions should clear the alert, but momentary appearance should not def test_sometimes_transparent_commuter(self): - _visible_time = np.random.choice([0.5, 10]) - ds_vector = always_no_face[:]*2 - interaction_vector = always_false[:]*2 - ds_vector[int((2*INVISIBLE_SECONDS_TO_ORANGE+1)/DT_DMON):int((2*INVISIBLE_SECONDS_TO_ORANGE+1+_visible_time)/DT_DMON)] = \ - [msg_ATTENTIVE] * int(_visible_time/DT_DMON) - interaction_vector[int((INVISIBLE_SECONDS_TO_ORANGE)/DT_DMON):int((INVISIBLE_SECONDS_TO_ORANGE+1)/DT_DMON)] = [True] * int(1/DT_DMON) - alert_lvls, _ = self._run_seq(ds_vector, interaction_vector, 2*always_true, 2*always_false) - assert alert_lvls[int(INVISIBLE_SECONDS_TO_ORANGE*0.5/DT_DMON)] == 0 - assert alert_lvls[int((INVISIBLE_SECONDS_TO_ORANGE-0.1)/DT_DMON)] == 2 - assert alert_lvls[int((INVISIBLE_SECONDS_TO_ORANGE+0.1)/DT_DMON)] == 0 - if _visible_time == 0.5: - assert alert_lvls[int((INVISIBLE_SECONDS_TO_ORANGE*2+1-0.1)/DT_DMON)] == 2 - assert alert_lvls[int((INVISIBLE_SECONDS_TO_ORANGE*2+1+0.1+_visible_time)/DT_DMON)] == 1 - elif _visible_time == 10: - assert alert_lvls[int((INVISIBLE_SECONDS_TO_ORANGE*2+1-0.1)/DT_DMON)] == 2 - assert alert_lvls[int((INVISIBLE_SECONDS_TO_ORANGE*2+1+0.1+_visible_time)/DT_DMON)] == 0 + for _visible_time in (0.5, 10): + ds_vector = always_no_face[:]*2 + interaction_vector = always_false[:]*2 + ds_vector[int((2*INVISIBLE_SECONDS_TO_ORANGE+1)/DT_DMON):int((2*INVISIBLE_SECONDS_TO_ORANGE+1+_visible_time)/DT_DMON)] = \ + [msg_ATTENTIVE] * int(_visible_time/DT_DMON) + interaction_vector[int((INVISIBLE_SECONDS_TO_ORANGE)/DT_DMON):int((INVISIBLE_SECONDS_TO_ORANGE+1)/DT_DMON)] = [True] * int(1/DT_DMON) + alert_lvls, _ = self._run_seq(ds_vector, interaction_vector, 2*always_true, 2*always_false) + assert alert_lvls[int(dm_settings._WHEELTOUCH_POLICY_ALERT_1_TIMEOUT/2/DT_DMON)] == 0 + assert alert_lvls[int((INVISIBLE_SECONDS_TO_ORANGE-0.1)/DT_DMON)] == 2 + assert alert_lvls[int((INVISIBLE_SECONDS_TO_ORANGE+0.1)/DT_DMON)] == 0 + if _visible_time == 0.5: + assert alert_lvls[int((INVISIBLE_SECONDS_TO_ORANGE*2+1-0.1)/DT_DMON)] == 2 + assert alert_lvls[int((INVISIBLE_SECONDS_TO_ORANGE*2+1+0.1+_visible_time)/DT_DMON)] == 2 + elif _visible_time == 10: + assert alert_lvls[int((INVISIBLE_SECONDS_TO_ORANGE*2+1-0.1)/DT_DMON)] == 2 + assert alert_lvls[int((INVISIBLE_SECONDS_TO_ORANGE*2+1+0.1+_visible_time)/DT_DMON)] == 0 # engaged, invisible driver, down to red, driver appears and then touches wheel, then disengages/reengages # - only disengage will clear the alert @@ -165,7 +182,7 @@ class TestMonitoring: interaction_vector[int((INVISIBLE_SECONDS_TO_RED+_visible_time)/DT_DMON):int((INVISIBLE_SECONDS_TO_RED+_visible_time+1)/DT_DMON)] = [True] * int(1/DT_DMON) op_vector[int((INVISIBLE_SECONDS_TO_RED+_visible_time+1)/DT_DMON):int((INVISIBLE_SECONDS_TO_RED+_visible_time+0.5)/DT_DMON)] = [False] * int(0.5/DT_DMON) alert_lvls, _ = self._run_seq(ds_vector, interaction_vector, op_vector, always_false) - assert alert_lvls[int(INVISIBLE_SECONDS_TO_ORANGE*0.5/DT_DMON)] == 0 + assert alert_lvls[int(dm_settings._WHEELTOUCH_POLICY_ALERT_1_TIMEOUT/2/DT_DMON)] == 0 assert alert_lvls[int((INVISIBLE_SECONDS_TO_ORANGE-0.1)/DT_DMON)] == 2 assert alert_lvls[int((INVISIBLE_SECONDS_TO_RED-0.1)/DT_DMON)] == 3 assert alert_lvls[int((INVISIBLE_SECONDS_TO_RED+0.5*_visible_time)/DT_DMON)] == 3 @@ -182,9 +199,9 @@ class TestMonitoring: # - should only reach green when stopped, but continues counting down on launch def test_long_traffic_light_victim(self): _redlight_time = 60 # seconds - standstill_vector = always_true[:] - standstill_vector[int(_redlight_time/DT_DMON):] = [False] * int((TEST_TIMESPAN-_redlight_time)/DT_DMON) - alert_lvls, d_status = self._run_seq(always_distracted, always_false, always_true, standstill_vector) + lowspeed_vector = always_true[:] + lowspeed_vector[int(_redlight_time/DT_DMON):] = [False] * int((TEST_TIMESPAN-_redlight_time)/DT_DMON) + alert_lvls, d_status = self._run_seq(always_distracted, always_false, always_true, lowspeed_vector) s = d_status.settings assert alert_lvls[int((_redlight_time-0.1)/DT_DMON)] == 0 _alert_1_to_2 = s._VISION_POLICY_ALERT_2_TIMEOUT - s._VISION_POLICY_ALERT_1_TIMEOUT @@ -192,12 +209,12 @@ class TestMonitoring: assert alert_lvls[int((_redlight_time+_alert_1_to_2+0.5)/DT_DMON)] == 2 # engaged, distracted while moving, then car stops after reaching orange - # - should reset timer to pre green at standstill + # - should reset timer to pre green at low speed def test_distracted_then_stops(self): _stop_time = DISTRACTED_SECONDS_TO_ORANGE + 1 # stop 1 second after reaching orange - standstill_vector = always_false[:] - standstill_vector[int(_stop_time/DT_DMON):] = [True] * int((TEST_TIMESPAN-_stop_time)/DT_DMON) - alert_lvls, _ = self._run_seq(always_distracted, always_false, always_true, standstill_vector) + lowspeed_vector = always_false[:] + lowspeed_vector[int(_stop_time/DT_DMON):] = [True] * int((TEST_TIMESPAN-_stop_time)/DT_DMON) + alert_lvls, _ = self._run_seq(always_distracted, always_false, always_true, lowspeed_vector) # just before and briefly after stopping: orange alert; goes away quickly after stopped assert alert_lvls[int((_stop_time+0.1)/DT_DMON)] == 2 assert alert_lvls[int((_stop_time+0.5)/DT_DMON)] == 0 diff --git a/openpilot/selfdrive/selfdrived/events.py b/openpilot/selfdrive/selfdrived/events.py index 44814c2908..9d1aa3591d 100755 --- a/openpilot/selfdrive/selfdrived/events.py +++ b/openpilot/selfdrive/selfdrived/events.py @@ -10,8 +10,9 @@ from opendbc.car.structs import car import openpilot.cereal.messaging as messaging from openpilot.common.constants import CV from openpilot.common.git import get_short_branch -from openpilot.common.realtime import DT_CTRL +from openpilot.common.realtime import DT_CTRL, DT_DMON from openpilot.selfdrive.locationd.calibrationd import MIN_SPEED_FILTER +from openpilot.selfdrive.monitoring.policy import DRIVER_MONITOR_SETTINGS from openpilot.system.micd import SAMPLE_RATE, SAMPLE_BUFFER from openpilot.selfdrive.ui.feedback.feedbackd import FEEDBACK_MAX_DURATION from openpilot.common.hardware import HARDWARE @@ -22,6 +23,7 @@ VisualAlert = car.CarControl.HUDControl.VisualAlert AudibleAlert = log.SelfdriveState.AudibleAlert EventName = log.OnroadEvent.EventName +DMON_LOCKOUT_TIME = DRIVER_MONITOR_SETTINGS()._LOCKOUT_TIME # Alert priorities class Priority(IntEnum): @@ -264,6 +266,13 @@ def calibration_incomplete_alert(CP: car.CarParams, CS: car.CarState, sm: messag Priority.LOWEST, VisualAlert.none, AudibleAlert.none, .2) +def too_distracted_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality) -> Alert: + if sm['driverMonitoringState'].lockout: + mins_left = max(1, round((100 - sm['driverMonitoringState'].lockoutRecoveryPercent) / 100 * DMON_LOCKOUT_TIME * DT_DMON / 60.)) + return NoEntryAlert("Too Distracted", f"{mins_left} minute{'s' if mins_left != 1 else ''} Left") + return NoEntryAlert("Pay Attention to Engage") + + def audio_feedback_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality) -> Alert: duration = FEEDBACK_MAX_DURATION - ((sm['audioFeedback'].blockNum + 1) * SAMPLE_BUFFER / SAMPLE_RATE) return NormalPermanentAlert( @@ -518,7 +527,7 @@ EVENTS: dict[int, dict[str, Alert | AlertCallbackType]] = { "Pay Attention", "", AlertStatus.normal, AlertSize.small, - Priority.LOW, VisualAlert.none, AudibleAlert.none, .1), + Priority.LOW, VisualAlert.none, AudibleAlert.preAlert, .1), }, EventName.driverDistracted2: { @@ -785,7 +794,7 @@ EVENTS: dict[int, dict[str, Alert | AlertCallbackType]] = { }, EventName.tooDistracted: { - ET.NO_ENTRY: NoEntryAlert("Distraction Level Too High"), + ET.NO_ENTRY: too_distracted_alert, }, EventName.excessiveActuation: { @@ -1038,7 +1047,7 @@ if HARDWARE.get_device_type() == 'mici': "Pay Attention", "", AlertStatus.normal, AlertSize.small, - Priority.LOW, VisualAlert.none, AudibleAlert.none, 2), + Priority.LOW, VisualAlert.none, AudibleAlert.preAlert, 2), }, EventName.driverDistracted2: { ET.PERMANENT: Alert( diff --git a/openpilot/selfdrive/selfdrived/selfdrived.py b/openpilot/selfdrive/selfdrived/selfdrived.py index 064789dae8..d89c564925 100755 --- a/openpilot/selfdrive/selfdrived/selfdrived.py +++ b/openpilot/selfdrive/selfdrived/selfdrived.py @@ -189,10 +189,13 @@ class SelfdriveD: # Handle DM if not self.CP.notCar: - # Block engaging until ignition cycle after max number or time of distractions + # Block engaging until lockout times out or ignition reset if self.sm['driverMonitoringState'].lockout and not self.dm_lockout_set: self.params.put_bool("DriverTooDistracted", True) self.dm_lockout_set = True + elif not self.sm['driverMonitoringState'].lockout and self.dm_lockout_set: + self.params.remove("DriverTooDistracted") + self.dm_lockout_set = False # No entry conditions if self.sm['driverMonitoringState'].lockout or self.sm['driverMonitoringState'].alwaysOnLockout: self.events.add(EventName.tooDistracted) diff --git a/openpilot/selfdrive/ui/mici/onroad/driver_camera_dialog.py b/openpilot/selfdrive/ui/mici/onroad/driver_camera_dialog.py index 35ebc34955..e81877b402 100644 --- a/openpilot/selfdrive/ui/mici/onroad/driver_camera_dialog.py +++ b/openpilot/selfdrive/ui/mici/onroad/driver_camera_dialog.py @@ -106,6 +106,7 @@ class BaseDriverCameraDialog(Widget): AudibleAlert = log.SelfdriveState.AudibleAlert ALERT_SOUNDS = { + 'one': AudibleAlert.preAlert, 'two': AudibleAlert.promptDistracted, 'three': AudibleAlert.warningImmediate, } diff --git a/openpilot/selfdrive/ui/soundd.py b/openpilot/selfdrive/ui/soundd.py index 2eb731e9e1..d84c98710b 100644 --- a/openpilot/selfdrive/ui/soundd.py +++ b/openpilot/selfdrive/ui/soundd.py @@ -43,6 +43,8 @@ sound_list: dict[int, tuple[str, int | None, float]] = { AudibleAlert.promptRepeat: ("prompt.wav", None, MAX_VOLUME), AudibleAlert.promptDistracted: ("prompt_distracted.wav", None, MAX_VOLUME), + AudibleAlert.preAlert: ("pre_alert.wav", 1, MAX_VOLUME), + AudibleAlert.warningSoft: ("warning_soft.wav", None, MAX_VOLUME), AudibleAlert.warningImmediate: ("warning_immediate.wav", None, MAX_VOLUME), } diff --git a/openpilot/selfdrive/ui/tests/test_soundd.py b/openpilot/selfdrive/ui/tests/test_soundd.py index f878839c23..da7921a559 100644 --- a/openpilot/selfdrive/ui/tests/test_soundd.py +++ b/openpilot/selfdrive/ui/tests/test_soundd.py @@ -1,5 +1,4 @@ -from openpilot.cereal import log -from openpilot.cereal import messaging +from openpilot.cereal import log, messaging from openpilot.cereal.messaging import SubMaster, PubMaster from openpilot.selfdrive.ui.soundd import SELFDRIVE_STATE_TIMEOUT, check_selfdrive_timeout_alert From e9e5548edc9b34e8b502dd9fed701bbe3d24678b Mon Sep 17 00:00:00 2001 From: ZwX1616 Date: Fri, 26 Jun 2026 18:23:01 -0700 Subject: [PATCH 087/151] bump DM NoEntryAlert priority (#38253) --- openpilot/selfdrive/selfdrived/events.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/openpilot/selfdrive/selfdrived/events.py b/openpilot/selfdrive/selfdrived/events.py index 9d1aa3591d..00d0334ada 100755 --- a/openpilot/selfdrive/selfdrived/events.py +++ b/openpilot/selfdrive/selfdrived/events.py @@ -153,11 +153,12 @@ EmptyAlert = Alert("" , "", AlertStatus.normal, AlertSize.none, Priority.LOWEST, class NoEntryAlert(Alert): def __init__(self, alert_text_2: str, alert_text_1: str = "openpilot Unavailable", - visual_alert: car.CarControl.HUDControl.VisualAlert=VisualAlert.none): + visual_alert: car.CarControl.HUDControl.VisualAlert=VisualAlert.none, + priority: Priority = Priority.LOW): if HARDWARE.get_device_type() == 'mici': alert_text_1, alert_text_2 = alert_text_2, alert_text_1 super().__init__(alert_text_1, alert_text_2, AlertStatus.normal, - AlertSize.mid, Priority.LOW, visual_alert, + AlertSize.mid, priority, visual_alert, AudibleAlert.refuse, 3.) @@ -269,8 +270,8 @@ def calibration_incomplete_alert(CP: car.CarParams, CS: car.CarState, sm: messag def too_distracted_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality) -> Alert: if sm['driverMonitoringState'].lockout: mins_left = max(1, round((100 - sm['driverMonitoringState'].lockoutRecoveryPercent) / 100 * DMON_LOCKOUT_TIME * DT_DMON / 60.)) - return NoEntryAlert("Too Distracted", f"{mins_left} minute{'s' if mins_left != 1 else ''} Left") - return NoEntryAlert("Pay Attention to Engage") + return NoEntryAlert("Too Distracted", f"{mins_left} minute{'s' if mins_left != 1 else ''} Left", priority=Priority.HIGH) + return NoEntryAlert("Pay Attention to Engage", priority=Priority.HIGH) def audio_feedback_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality) -> Alert: From da6313dbe95b3f24bb5d8018b0e5f950f5823ca7 Mon Sep 17 00:00:00 2001 From: Jason Wen Date: Fri, 26 Jun 2026 21:31:55 -0400 Subject: [PATCH 088/151] Update CHANGELOG.md --- CHANGELOG.md | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e5e31c60ff..aeb2a969c8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,34 @@ -sunnypilot Version 2026.002.000 (2026-xx-xx) +sunnypilot Version 2026.002.000 (2026-06-28) ======================== +* What's Changed (sunnypilot/sunnypilot) + * ui: update gates for certain toggles by @sunnyhaibin in https://github.com/sunnypilot/sunnypilot/pull/1830 + * release: ignore upstream IsReleaseBranch by @sunnyhaibin in https://github.com/sunnypilot/sunnypilot/pull/1831 + * manager: disable DEVELOPMENT_ONLY reset by @sunnyhaibin in https://github.com/sunnypilot/sunnypilot/pull/1833 + * sunnylink: fix max time offroad values by @nayan8teen in https://github.com/sunnypilot/sunnypilot/pull/1835 + * ui: show default model name by @nayan8teen in https://github.com/sunnypilot/sunnypilot/pull/1837 + * sunnylink: add CarParams fallback for brand-specific capabilities by @sunnyhaibin in https://github.com/sunnypilot/sunnypilot/pull/1839 + * sunnylink SDUI: tweak DisableUpdate param for clarity by @sunnyhaibin in https://github.com/sunnypilot/sunnypilot/pull/1842 + * Revert "DM: Lancia Delta HF Integrale model" by @sunnyhaibin in https://github.com/sunnypilot/sunnypilot/pull/1849 + * modeld_v2: safe model validation by @Discountchubbs in https://github.com/sunnypilot/sunnypilot/pull/1855 + * Revert "deprecate `carState.brake`" for Honda Gas Interceptor by @mvl-boston in https://github.com/sunnypilot/sunnypilot/pull/1860 + * sunnylink: deprecate legacy params metadata by @sunnyhaibin in https://github.com/sunnypilot/sunnypilot/pull/1862 + * ui: reset Enforce Torque Control and NNLC if both are enabled by @sunnyhaibin in https://github.com/sunnypilot/sunnypilot/pull/1863 +* What's Changed (sunnypilot/opendbc) + * Rivian: suppress ACM hold-the-wheel warning during MADS-only lateral by @lukasloetkolben in https://github.com/sunnypilot/opendbc/pull/465 + * Sync: `commaai/opendbc:master` → `sunnypilot/opendbc:master` by @sunnyhaibin in https://github.com/sunnypilot/opendbc/pull/479 + * safety: add option to ignore frequency check for RX checks by @sunnyhaibin in https://github.com/sunnypilot/opendbc/pull/480 + * Revert "deprecate carState.brake" for Honda Gas Interceptor by @mvl-boston in https://github.com/sunnypilot/opendbc/pull/481 +* New Contributors (sunnypilot/sunnypilot) + * @mvl-boston made their first contribution in https://github.com/sunnypilot/sunnypilot/pull/1860 +* Full Changelog: https://github.com/sunnypilot/sunnypilot/compare/v2026.001.007...v2026.002.000 +************************ +* Synced with commaai's openpilot (v0.11.1) + * master commit 69e2c321e49760e52f7983eaa0a5f77cb95de637 (June 02, 2026) +* New driver monitoring model +* Improved image processing pipeline for driver camera +* Improved thermal policy for comma four +* Acura MDX 2022-24 support thanks to mvl-boston! +* Rivian R1S and R1T 2025 support thanks to lukasloetkolben! sunnypilot Version 2026.001.000 (2026-05-06) ======================== From 61b6d52b016b3d29ed77d36314b0d098b6c41a69 Mon Sep 17 00:00:00 2001 From: Toby Penner Date: Sun, 28 Jun 2026 10:40:05 -0700 Subject: [PATCH 089/151] Fix broken tools README link (#38260) --- docs/CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md index 393819830b..cbeb5f6d3a 100644 --- a/docs/CONTRIBUTING.md +++ b/docs/CONTRIBUTING.md @@ -6,7 +6,7 @@ Development is coordinated through [Discord](https://discord.comma.ai) and GitHu ### Getting Started -* Set up your [development environment](/openpilot/tools/) +* Set up your [development environment](/tools/) * Join our [Discord](https://discord.comma.ai) * Docs are at https://docs.comma.ai and https://blog.comma.ai From 31dc4d8e520f3b309acd05da79cc6ab448affad2 Mon Sep 17 00:00:00 2001 From: Jason Wen Date: Sun, 28 Jun 2026 22:56:17 -0400 Subject: [PATCH 090/151] ci: fix cereal validation for upstream directory restructure (#1869) --- .github/workflows/cereal_validation.yaml | 25 ++- .../tests/validate_sp_cereal_upstream.py | 185 +++++------------- 2 files changed, 69 insertions(+), 141 deletions(-) diff --git a/.github/workflows/cereal_validation.yaml b/.github/workflows/cereal_validation.yaml index d71354dd59..2ab617b2f0 100644 --- a/.github/workflows/cereal_validation.yaml +++ b/.github/workflows/cereal_validation.yaml @@ -35,18 +35,36 @@ jobs: - name: Init sunnypilot opendbc submodule run: git submodule update --init --depth 1 opendbc_repo - - name: Checkout upstream openpilot cereal + - name: Checkout upstream openpilot uses: actions/checkout@v6 with: repository: 'commaai/openpilot' path: upstream_openpilot - sparse-checkout: cereal ref: "refs/heads/master" - name: Init upstream opendbc submodule working-directory: upstream_openpilot run: git submodule update --init --depth 1 opendbc_repo + - name: Locate upstream capnp paths + id: locate-capnp + run: | + CEREAL_DIR=$(find upstream_openpilot -maxdepth 4 -name log.capnp -path '*/cereal/log.capnp' -printf '%h\n' -quit) + if [ -z "$CEREAL_DIR" ]; then + echo "::error::Could not locate cereal/log.capnp in upstream openpilot" + exit 1 + fi + echo "cereal_dir=$CEREAL_DIR" >> "$GITHUB_OUTPUT" + echo "Found upstream cereal at: $CEREAL_DIR" + + IMPORT_ARGS="" + CAR_CAPNP=$(find upstream_openpilot -maxdepth 5 -name car.capnp -path '*/opendbc/car/car.capnp' -printf '%h\n' -quit) + if [ -n "$CAR_CAPNP" ]; then + IMPORT_ARGS="-I $CAR_CAPNP" + echo "Found car.capnp at: $CAR_CAPNP" + fi + echo "import_args=$IMPORT_ARGS" >> "$GITHUB_OUTPUT" + - name: Install uv run: pip install uv @@ -62,4 +80,5 @@ jobs: PYCAPNP_VER=$(python3 -c "import re; m=re.search(r'name = \"pycapnp\"\nversion = \"([^\"]+)\"', open('uv.lock').read()); print(m.group(1))") uv run --isolated --with "pycapnp==${PYCAPNP_VER}" \ python3 cereal/messaging/tests/validate_sp_cereal_upstream.py \ - -r -f /tmp/sp_schema.json --cereal-dir upstream_openpilot/cereal + -r -f /tmp/sp_schema.json --cereal-dir ${{ steps.locate-capnp.outputs.cereal_dir }} \ + ${{ steps.locate-capnp.outputs.import_args }} diff --git a/cereal/messaging/tests/validate_sp_cereal_upstream.py b/cereal/messaging/tests/validate_sp_cereal_upstream.py index 11e39cd6ce..543b8b1b3e 100755 --- a/cereal/messaging/tests/validate_sp_cereal_upstream.py +++ b/cereal/messaging/tests/validate_sp_cereal_upstream.py @@ -1,12 +1,13 @@ #!/usr/bin/env python3 -"""Schema-level cereal compat check between sunnypilot and upstream openpilot. +"""Validate sunnypilot routes are parseable by stock commaai/openpilot. -Rules (per struct matched across sides by typeId): - R1 shared ordinal must reference the same type. - R2 sunnypilot-only ordinal in a union -> FAIL (unknown discriminant upstream). - R3 sunnypilot-only ordinal on a regular field -> OK (additive struct evolution). - R4 upstream-only ordinal -> OK. - R5 sunnypilot-only struct referenced via an upstream-shared field -> FAIL. +Cap'n Proto is wire-compatible across renames, type relocations, and +additive fields. The only breaking change is a union variant that +upstream doesn't recognize — an unknown discriminant makes the entire +union unreadable. + +This script checks: for every struct with a union that exists in both +schemas, does sunnypilot introduce union variants upstream doesn't have? """ from __future__ import annotations @@ -24,46 +25,19 @@ def hex_id(value: int) -> str: return f"0x{value:016x}" -def encode_type(type_node: Any) -> dict: - which = type_node.which() - if which == "struct": - return {"kind": "struct", "typeId": hex_id(type_node.struct.typeId)} - if which == "enum": - return {"kind": "enum", "typeId": hex_id(type_node.enum.typeId)} - if which == "interface": - return {"kind": "interface", "typeId": hex_id(type_node.interface.typeId)} - if which == "list": - return {"kind": "list", "element": encode_type(type_node.list.elementType)} - if which == "anyPointer": - return {"kind": "anyPointer"} - return {"kind": which} - - -def encode_field(name: str, field: Any) -> dict: - proto = field.proto - ordinal = proto.ordinal.explicit if proto.ordinal.which() == "explicit" else None - discriminant = proto.discriminantValue if proto.discriminantValue != NO_DISCRIMINANT else None - - if proto.which() == "group": - type_desc = {"kind": "group", "typeId": hex_id(proto.group.typeId)} - else: - type_desc = encode_type(proto.slot.type) - - return { - "name": name, - "ordinal": ordinal, - "discriminant": discriminant, - "type": type_desc, - } - - def encode_struct(schema: Any) -> dict: node = schema.node + fields = [] + for name, field in schema.fields.items(): + proto = field.proto + ordinal = proto.ordinal.explicit if proto.ordinal.which() == "explicit" else None + discriminant = proto.discriminantValue if proto.discriminantValue != NO_DISCRIMINANT else None + fields.append({"name": name, "ordinal": ordinal, "discriminant": discriminant}) return { "typeId": hex_id(node.id), "displayName": node.displayName, "hasUnion": node.struct.discriminantCount > 0, - "fields": [encode_field(name, field) for name, field in schema.fields.items()], + "fields": fields, } @@ -105,15 +79,16 @@ def collect_schema(root: Any) -> dict[str, dict]: return structs -def load_log(cereal_dir: str) -> Any: +def load_log(cereal_dir: str, extra_imports: list[str] | None = None) -> Any: import capnp cereal_dir = os.path.abspath(cereal_dir) capnp.remove_import_hook() - return capnp.load(os.path.join(cereal_dir, "log.capnp"), imports=[cereal_dir]) + imports = [cereal_dir] + [os.path.abspath(p) for p in (extra_imports or [])] + return capnp.load(os.path.join(cereal_dir, "log.capnp"), imports=imports) -def dump_schema(cereal_dir: str, path: str) -> None: - log = load_log(cereal_dir) +def dump_schema(cereal_dir: str, path: str, extra_imports: list[str] | None = None) -> None: + log = load_log(cereal_dir, extra_imports) payload = { "root": hex_id(log.Event.schema.node.id), "structs": collect_schema(log.Event.schema), @@ -123,100 +98,37 @@ def dump_schema(cereal_dir: str, path: str) -> None: print(f"wrote schema dump with {len(payload['structs'])} structs to {path}") -def types_equal(a: dict, b: dict) -> bool: - if a.get("kind") != b.get("kind"): - return False - kind = a["kind"] - if kind in ("struct", "enum", "interface", "group"): - return a.get("typeId") == b.get("typeId") - if kind == "list": - return types_equal(a["element"], b["element"]) - return True - - -def type_repr(t: dict) -> str: - kind = t.get("kind", "?") - if kind in ("struct", "enum", "interface", "group"): - return f"{kind}({t.get('typeId')})" - if kind == "list": - return f"list<{type_repr(t['element'])}>" - return kind - - -def field_is_union_variant(field: dict) -> bool: - return field.get("discriminant") is not None - - -def index_fields_by_ordinal(struct: dict) -> dict[int, dict]: - indexed: dict[int, dict] = {} - for field in struct["fields"]: - ordinal = field.get("ordinal") - if ordinal is None: - continue - indexed[ordinal] = field - return indexed - - def compare(sunnypilot_dump: dict, upstream_dump: dict) -> list[str]: violations: list[str] = [] - sunnypilot_structs: dict[str, dict] = sunnypilot_dump["structs"] - upstream_structs: dict[str, dict] = upstream_dump["structs"] + sunnypilot_structs = sunnypilot_dump["structs"] + upstream_structs = upstream_dump["structs"] - sunnypilot_struct_referenced_from_shared: set[str] = set() - - for type_id, sunnypilot_struct in sunnypilot_structs.items(): - upstream_struct = upstream_structs.get(type_id) - if upstream_struct is None: + for type_id, sp_struct in sunnypilot_structs.items(): + if not sp_struct["hasUnion"]: + continue + up_struct = upstream_structs.get(type_id) + if up_struct is None: continue - sunnypilot_fields = index_fields_by_ordinal(sunnypilot_struct) - upstream_fields = index_fields_by_ordinal(upstream_struct) - display = sunnypilot_struct["displayName"] + up_ordinals = {f["ordinal"] for f in up_struct["fields"] if f.get("discriminant") is not None} + display = sp_struct["displayName"] - for ordinal, sunnypilot_field in sunnypilot_fields.items(): - upstream_field = upstream_fields.get(ordinal) - if upstream_field is None: - if field_is_union_variant(sunnypilot_field): - violations.append( - f"[R2] {display} @{ordinal} ('{sunnypilot_field['name']}', {type_repr(sunnypilot_field['type'])}): " - f"union variant not present upstream. upstream cannot parse this discriminant." - ) + for field in sp_struct["fields"]: + if field.get("discriminant") is None: continue - - if not types_equal(sunnypilot_field["type"], upstream_field["type"]): + if field["ordinal"] not in up_ordinals: violations.append( - f"[R1] {display} @{ordinal}: type mismatch. " - f"sunnypilot='{sunnypilot_field['name']}' {type_repr(sunnypilot_field['type'])} vs " - f"upstream='{upstream_field['name']}' {type_repr(upstream_field['type'])}." + f"{display} @{field['ordinal']} '{field['name']}': " + f"union variant not present upstream (discriminant={field['discriminant']})" ) - continue - - cursor = sunnypilot_field["type"] - while cursor.get("kind") == "list": - cursor = cursor["element"] - if cursor.get("kind") in ("struct", "group", "interface") and cursor.get("typeId"): - sunnypilot_struct_referenced_from_shared.add(cursor["typeId"]) - - for type_id, sunnypilot_struct in sunnypilot_structs.items(): - if type_id in upstream_structs: - continue - if type_id in sunnypilot_struct_referenced_from_shared: - violations.append( - f"[R5] struct {sunnypilot_struct['displayName']} ({type_id}) exists only on sunnypilot " - f"but is referenced from an upstream-shared field. upstream cannot resolve this type." - ) return violations -def load_peer(path: str) -> dict: - with open(path, "r", encoding="utf-8") as handle: - return json.load(handle) - - -def run_read(cereal_dir: str, peer_path: str) -> int: - log = load_log(cereal_dir) - peer_dump = load_peer(peer_path) +def run_read(cereal_dir: str, peer_path: str, extra_imports: list[str] | None = None) -> int: + log = load_log(cereal_dir, extra_imports) + with open(peer_path, "r", encoding="utf-8") as f: + peer_dump = json.load(f) local_dump = { "root": hex_id(log.Event.schema.node.id), "structs": collect_schema(log.Event.schema), @@ -224,32 +136,29 @@ def run_read(cereal_dir: str, peer_path: str) -> int: violations = compare(sunnypilot_dump=peer_dump, upstream_dump=local_dump) if not violations: - print("cereal compat OK: upstream openpilot can parse sunnypilot routes " - "(no leaked structs, no ordinal collisions).") + print("cereal compat OK: upstream can parse sunnypilot routes.") return 0 - print(f"cereal compat FAIL: upstream openpilot would misparse sunnypilot routes " - f"({len(violations)} violation(s)):") + print(f"cereal compat FAIL ({len(violations)} leaked union variant(s)):") for v in violations: print(f" {v}") return 1 def main() -> int: - parser = argparse.ArgumentParser( - description="sunnypilot <-> upstream cereal compatibility validator (schema-level)." - ) + parser = argparse.ArgumentParser(description="sunnypilot cereal upstream compat check") mode = parser.add_mutually_exclusive_group(required=True) mode.add_argument("-g", "--generate", action="store_true", help="dump local schema to JSON") - mode.add_argument("-r", "--read", action="store_true", help="load peer JSON and diff against local") - parser.add_argument("-f", "--file", default="schema.json", help="JSON file path (default: schema.json)") - parser.add_argument("--cereal-dir", required=True, help="path to cereal directory containing log.capnp") + mode.add_argument("-r", "--read", action="store_true", help="validate against peer schema") + parser.add_argument("-f", "--file", default="schema.json", help="JSON file path") + parser.add_argument("--cereal-dir", required=True, help="path to cereal directory") + parser.add_argument("-I", "--import-path", action="append", default=[], help="extra capnp import paths") args = parser.parse_args() if args.generate: - dump_schema(args.cereal_dir, args.file) + dump_schema(args.cereal_dir, args.file, args.import_path) return 0 - return run_read(args.cereal_dir, args.file) + return run_read(args.cereal_dir, args.file, args.import_path) if __name__ == "__main__": From 97215b17d73d92445a3063e24589750cc55acfe4 Mon Sep 17 00:00:00 2001 From: Armand du Parc Locmaria Date: Mon, 29 Jun 2026 11:53:27 -0700 Subject: [PATCH 091/151] modeld: remove prepare_only (#38252) remove prepare_only --- openpilot/selfdrive/modeld/modeld.py | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/openpilot/selfdrive/modeld/modeld.py b/openpilot/selfdrive/modeld/modeld.py index 9722538b33..dca74d0a5b 100755 --- a/openpilot/selfdrive/modeld/modeld.py +++ b/openpilot/selfdrive/modeld/modeld.py @@ -101,7 +101,7 @@ class ModelState: return parsed_model_outputs def run(self, bufs: dict[str, VisionBuf], transforms: dict[str, np.ndarray], - inputs: dict[str, np.ndarray], prepare_only: bool) -> dict[str, np.ndarray] | None: + inputs: dict[str, np.ndarray]) -> dict[str, np.ndarray] | None: for key in bufs.keys(): ptr = np.frombuffer(bufs[key].data, dtype=np.uint8).ctypes.data yuv_size = self.frame_buf_params[key][3] @@ -122,9 +122,6 @@ class ModelState: img, big_img = self.warp_enqueue(**{k: self.input_queues[k] for k in WARP_INPUTS}, frame=self.full_frames['img'], big_frame=self.full_frames['big_img']) - if prepare_only: - return None - outs, = self.run_policy( **{k: self.input_queues[k] for k in POLICY_INPUTS if k in self.input_queues}, img=img, big_img=big_img ) @@ -272,9 +269,6 @@ def main(demo=False): run_count = run_count + 1 frame_drop_ratio = frames_dropped / (1 + frames_dropped) - prepare_only = vipc_dropped_frames > 0 - if prepare_only: - cloudlog.error(f"skipping model eval. Dropped {vipc_dropped_frames} frames") bufs = {name: buf_extra if 'big' in name else buf_main for name in model.vision_input_names} transforms = {name: model_transform_extra if 'big' in name else model_transform_main for name in model.vision_input_names} @@ -289,7 +283,7 @@ def main(demo=False): } mt1 = time.perf_counter() - model_output = model.run(bufs, transforms, inputs, prepare_only) + model_output = model.run(bufs, transforms, inputs) mt2 = time.perf_counter() model_execution_time = mt2 - mt1 From 8c927d0fc26be3ed696b9d9ebe4c9a838582dcb3 Mon Sep 17 00:00:00 2001 From: Armand du Parc Locmaria Date: Mon, 29 Jun 2026 13:08:37 -0700 Subject: [PATCH 092/151] modeld: enqueue in policy (#38264) * move enqueue to policy * typo * correct shape * correct shape --- openpilot/selfdrive/modeld/compile_modeld.py | 31 +++++++++++--------- openpilot/selfdrive/modeld/modeld.py | 6 ++-- 2 files changed, 20 insertions(+), 17 deletions(-) diff --git a/openpilot/selfdrive/modeld/compile_modeld.py b/openpilot/selfdrive/modeld/compile_modeld.py index 35f92d344f..247966aaf6 100755 --- a/openpilot/selfdrive/modeld/compile_modeld.py +++ b/openpilot/selfdrive/modeld/compile_modeld.py @@ -34,8 +34,8 @@ from tinygrad.engine.jit import TinyJit NV12Frame = namedtuple("NV12Frame", ['width', 'height', 'stride', 'y_height', 'uv_height', 'size']) -WARP_INPUTS = ['img_q', 'big_img_q', 'tfm', 'big_tfm'] -POLICY_INPUTS = ['feat_q', 'desire_q', 'packed_npy_inputs'] +WARP_INPUTS = ['tfm', 'big_tfm'] +POLICY_INPUTS = ['img_q', 'big_img_q', 'feat_q', 'desire_q', 'packed_npy_inputs'] UV_SCALE_MATRIX = np.array([[0.5, 0, 0], [0, 0.5, 0], [0, 0, 1]], dtype=np.float32) UV_SCALE_MATRIX_INV = np.linalg.inv(UV_SCALE_MATRIX) @@ -175,20 +175,17 @@ def sample_desire(buf, frame_skip): def make_warp(nv12, model_w, model_h, frame_skip): frame_prepare = make_frame_prepare(nv12, model_w, model_h) - sample_skip_fn = partial(sample_skip, frame_skip=frame_skip) - def warp_enqueue(img_q, big_img_q, tfm, big_tfm, frame, big_frame): + def warp(tfm, big_tfm, frame, big_frame): tfm = tfm.to(WARP_DEV) big_tfm = big_tfm.to(WARP_DEV) Tensor.realize(tfm, big_tfm) warped_frame = frame_prepare(frame, tfm).unsqueeze(0) warped_big_frame = frame_prepare(big_frame, big_tfm).unsqueeze(0) - warped = Tensor.cat(warped_frame, warped_big_frame).to(Device.DEFAULT) - img = shift_and_sample(img_q, warped[0:1], sample_skip_fn) - big_img = shift_and_sample(big_img_q, warped[1:2], sample_skip_fn) - return img, big_img - return warp_enqueue + return Tensor.cat(warped_frame, warped_big_frame) + + return warp def make_run_policy(model_runner, model_metadata, frame_skip): @@ -196,8 +193,14 @@ def make_run_policy(model_runner, model_metadata, frame_skip): sample_skip_fn = partial(sample_skip, frame_skip=frame_skip) npy_shapes, npy_sizes = get_policy_npy_shapes(model_metadata['input_shapes']) - def run_policy(img, big_img, feat_q, desire_q, packed_npy_inputs): - packed_npy_inputs = packed_npy_inputs.to(Device.DEFAULT).realize() + def run_policy(warped, img_q, big_img_q, feat_q, desire_q, packed_npy_inputs): + packed_npy_inputs = packed_npy_inputs.to(Device.DEFAULT) + warped = warped.to(Device.DEFAULT) + Tensor.realize(packed_npy_inputs, warped) + + img = shift_and_sample(img_q, warped[0:1], sample_skip_fn) + big_img = shift_and_sample(big_img_q, warped[1:2], sample_skip_fn) + desire, traffic_convention, action_t, prev_feat = (t.reshape(s) for t, s in zip(packed_npy_inputs.split(npy_sizes), npy_shapes.values(), strict=True)) desire_buf = shift_and_sample(desire_q, desire.reshape(1, 1, -1), sample_desire_fn) feat_buf = shift_and_sample(feat_q, prev_feat.reshape(1, 1, -1), sample_skip_fn) @@ -295,16 +298,16 @@ if __name__ == "__main__": run_policy_jit = TinyJit(make_run_policy(model_runner, out['metadata'], args.frame_skip), prune=True) make_policy_queues = partial(make_input_queues, out['metadata']['input_shapes'], args.frame_skip) - make_random_model_inputs = partial(make_random_images, keys=['img', 'big_img'], shape=out['metadata']['input_shapes']['img']) + make_random_model_inputs = partial(make_random_images, keys=['warped'], shape=(2, 6, *out['metadata']['input_shapes']['img'][2:])) out['run_policy'] = compile_jit(run_policy_jit, make_random_model_inputs, POLICY_INPUTS, make_policy_queues) for cam_w, cam_h in args.camera_resolutions: nv12 = NV12Frame(cam_w, cam_h, *get_nv12_info(cam_w, cam_h)) make_random_warp_inputs = partial(make_random_images, keys=['frame', 'big_frame'], shape=nv12.size, device=WARP_DEV) - warp_enqueue = TinyJit(make_warp(nv12, model_w, model_h, args.frame_skip), prune=True) + warp = TinyJit(make_warp(nv12, model_w, model_h, args.frame_skip), prune=True) make_warp_queues = partial(make_warp_input_queues, out['metadata']['input_shapes'], args.frame_skip) - out[(cam_w,cam_h)] = compile_jit(warp_enqueue, make_random_warp_inputs, WARP_INPUTS, make_warp_queues) + out[(cam_w,cam_h)] = compile_jit(warp, make_random_warp_inputs, WARP_INPUTS, make_warp_queues) with open(args.output, "wb") as f: pickle.dump(out, f) diff --git a/openpilot/selfdrive/modeld/modeld.py b/openpilot/selfdrive/modeld/modeld.py index dca74d0a5b..3d5e04873d 100755 --- a/openpilot/selfdrive/modeld/modeld.py +++ b/openpilot/selfdrive/modeld/modeld.py @@ -94,7 +94,7 @@ class ModelState: self.parser = Parser() self.frame_buf_params = {k: get_nv12_info(cam_w, cam_h) for k in ('img', 'big_img')} self.run_policy = jits['run_policy'] - self.warp_enqueue = jits[(cam_w,cam_h)] + self.warp = jits[(cam_w,cam_h)] def slice_outputs(self, model_outputs: np.ndarray, output_slices: dict[str, slice]) -> dict[str, np.ndarray]: parsed_model_outputs = {k: model_outputs[np.newaxis, v] for k,v in output_slices.items()} @@ -120,10 +120,10 @@ class ModelState: self.npy['tfm'][:,:] = transforms['img'][:,:] self.npy['big_tfm'][:,:] = transforms['big_img'][:,:] - img, big_img = self.warp_enqueue(**{k: self.input_queues[k] for k in WARP_INPUTS}, frame=self.full_frames['img'], big_frame=self.full_frames['big_img']) + warped = self.warp(**{k: self.input_queues[k] for k in WARP_INPUTS}, frame=self.full_frames['img'], big_frame=self.full_frames['big_img']) outs, = self.run_policy( - **{k: self.input_queues[k] for k in POLICY_INPUTS if k in self.input_queues}, img=img, big_img=big_img + **{k: self.input_queues[k] for k in POLICY_INPUTS if k in self.input_queues}, warped=warped ) model_output = outs.numpy()[0] outputs_dict = self.parser.parse_outputs(self.slice_outputs(model_output, self.output_slices)) From 8a3bbcdd4e800c918d319dde48c49d37fcff583f Mon Sep 17 00:00:00 2001 From: Armand du Parc Locmaria Date: Tue, 30 Jun 2026 00:15:50 -0700 Subject: [PATCH 093/151] Revert "modeld: enqueue in policy" (#38266) Revert "modeld: enqueue in policy (#38264)" This reverts commit 8c927d0fc26be3ed696b9d9ebe4c9a838582dcb3. --- openpilot/selfdrive/modeld/compile_modeld.py | 31 +++++++++----------- openpilot/selfdrive/modeld/modeld.py | 6 ++-- 2 files changed, 17 insertions(+), 20 deletions(-) diff --git a/openpilot/selfdrive/modeld/compile_modeld.py b/openpilot/selfdrive/modeld/compile_modeld.py index 247966aaf6..35f92d344f 100755 --- a/openpilot/selfdrive/modeld/compile_modeld.py +++ b/openpilot/selfdrive/modeld/compile_modeld.py @@ -34,8 +34,8 @@ from tinygrad.engine.jit import TinyJit NV12Frame = namedtuple("NV12Frame", ['width', 'height', 'stride', 'y_height', 'uv_height', 'size']) -WARP_INPUTS = ['tfm', 'big_tfm'] -POLICY_INPUTS = ['img_q', 'big_img_q', 'feat_q', 'desire_q', 'packed_npy_inputs'] +WARP_INPUTS = ['img_q', 'big_img_q', 'tfm', 'big_tfm'] +POLICY_INPUTS = ['feat_q', 'desire_q', 'packed_npy_inputs'] UV_SCALE_MATRIX = np.array([[0.5, 0, 0], [0, 0.5, 0], [0, 0, 1]], dtype=np.float32) UV_SCALE_MATRIX_INV = np.linalg.inv(UV_SCALE_MATRIX) @@ -175,17 +175,20 @@ def sample_desire(buf, frame_skip): def make_warp(nv12, model_w, model_h, frame_skip): frame_prepare = make_frame_prepare(nv12, model_w, model_h) + sample_skip_fn = partial(sample_skip, frame_skip=frame_skip) - def warp(tfm, big_tfm, frame, big_frame): + def warp_enqueue(img_q, big_img_q, tfm, big_tfm, frame, big_frame): tfm = tfm.to(WARP_DEV) big_tfm = big_tfm.to(WARP_DEV) Tensor.realize(tfm, big_tfm) warped_frame = frame_prepare(frame, tfm).unsqueeze(0) warped_big_frame = frame_prepare(big_frame, big_tfm).unsqueeze(0) - return Tensor.cat(warped_frame, warped_big_frame) - - return warp + warped = Tensor.cat(warped_frame, warped_big_frame).to(Device.DEFAULT) + img = shift_and_sample(img_q, warped[0:1], sample_skip_fn) + big_img = shift_and_sample(big_img_q, warped[1:2], sample_skip_fn) + return img, big_img + return warp_enqueue def make_run_policy(model_runner, model_metadata, frame_skip): @@ -193,14 +196,8 @@ def make_run_policy(model_runner, model_metadata, frame_skip): sample_skip_fn = partial(sample_skip, frame_skip=frame_skip) npy_shapes, npy_sizes = get_policy_npy_shapes(model_metadata['input_shapes']) - def run_policy(warped, img_q, big_img_q, feat_q, desire_q, packed_npy_inputs): - packed_npy_inputs = packed_npy_inputs.to(Device.DEFAULT) - warped = warped.to(Device.DEFAULT) - Tensor.realize(packed_npy_inputs, warped) - - img = shift_and_sample(img_q, warped[0:1], sample_skip_fn) - big_img = shift_and_sample(big_img_q, warped[1:2], sample_skip_fn) - + def run_policy(img, big_img, feat_q, desire_q, packed_npy_inputs): + packed_npy_inputs = packed_npy_inputs.to(Device.DEFAULT).realize() desire, traffic_convention, action_t, prev_feat = (t.reshape(s) for t, s in zip(packed_npy_inputs.split(npy_sizes), npy_shapes.values(), strict=True)) desire_buf = shift_and_sample(desire_q, desire.reshape(1, 1, -1), sample_desire_fn) feat_buf = shift_and_sample(feat_q, prev_feat.reshape(1, 1, -1), sample_skip_fn) @@ -298,16 +295,16 @@ if __name__ == "__main__": run_policy_jit = TinyJit(make_run_policy(model_runner, out['metadata'], args.frame_skip), prune=True) make_policy_queues = partial(make_input_queues, out['metadata']['input_shapes'], args.frame_skip) - make_random_model_inputs = partial(make_random_images, keys=['warped'], shape=(2, 6, *out['metadata']['input_shapes']['img'][2:])) + make_random_model_inputs = partial(make_random_images, keys=['img', 'big_img'], shape=out['metadata']['input_shapes']['img']) out['run_policy'] = compile_jit(run_policy_jit, make_random_model_inputs, POLICY_INPUTS, make_policy_queues) for cam_w, cam_h in args.camera_resolutions: nv12 = NV12Frame(cam_w, cam_h, *get_nv12_info(cam_w, cam_h)) make_random_warp_inputs = partial(make_random_images, keys=['frame', 'big_frame'], shape=nv12.size, device=WARP_DEV) - warp = TinyJit(make_warp(nv12, model_w, model_h, args.frame_skip), prune=True) + warp_enqueue = TinyJit(make_warp(nv12, model_w, model_h, args.frame_skip), prune=True) make_warp_queues = partial(make_warp_input_queues, out['metadata']['input_shapes'], args.frame_skip) - out[(cam_w,cam_h)] = compile_jit(warp, make_random_warp_inputs, WARP_INPUTS, make_warp_queues) + out[(cam_w,cam_h)] = compile_jit(warp_enqueue, make_random_warp_inputs, WARP_INPUTS, make_warp_queues) with open(args.output, "wb") as f: pickle.dump(out, f) diff --git a/openpilot/selfdrive/modeld/modeld.py b/openpilot/selfdrive/modeld/modeld.py index 3d5e04873d..dca74d0a5b 100755 --- a/openpilot/selfdrive/modeld/modeld.py +++ b/openpilot/selfdrive/modeld/modeld.py @@ -94,7 +94,7 @@ class ModelState: self.parser = Parser() self.frame_buf_params = {k: get_nv12_info(cam_w, cam_h) for k in ('img', 'big_img')} self.run_policy = jits['run_policy'] - self.warp = jits[(cam_w,cam_h)] + self.warp_enqueue = jits[(cam_w,cam_h)] def slice_outputs(self, model_outputs: np.ndarray, output_slices: dict[str, slice]) -> dict[str, np.ndarray]: parsed_model_outputs = {k: model_outputs[np.newaxis, v] for k,v in output_slices.items()} @@ -120,10 +120,10 @@ class ModelState: self.npy['tfm'][:,:] = transforms['img'][:,:] self.npy['big_tfm'][:,:] = transforms['big_img'][:,:] - warped = self.warp(**{k: self.input_queues[k] for k in WARP_INPUTS}, frame=self.full_frames['img'], big_frame=self.full_frames['big_img']) + img, big_img = self.warp_enqueue(**{k: self.input_queues[k] for k in WARP_INPUTS}, frame=self.full_frames['img'], big_frame=self.full_frames['big_img']) outs, = self.run_policy( - **{k: self.input_queues[k] for k in POLICY_INPUTS if k in self.input_queues}, warped=warped + **{k: self.input_queues[k] for k in POLICY_INPUTS if k in self.input_queues}, img=img, big_img=big_img ) model_output = outs.numpy()[0] outputs_dict = self.parser.parse_outputs(self.slice_outputs(model_output, self.output_slices)) From 4fc5e308f37520454da48115f0c90eccdc745e22 Mon Sep 17 00:00:00 2001 From: Armand du Parc Locmaria Date: Tue, 30 Jun 2026 00:31:54 -0700 Subject: [PATCH 094/151] Reapply "modeld: enqueue in policy" (#38267) * Reapply "modeld: enqueue in policy" (#38266) This reverts commit 8a3bbcdd4e800c918d319dde48c49d37fcff583f. * correct device for policy inputs --- openpilot/selfdrive/modeld/compile_modeld.py | 31 +++++++++++--------- openpilot/selfdrive/modeld/modeld.py | 6 ++-- 2 files changed, 20 insertions(+), 17 deletions(-) diff --git a/openpilot/selfdrive/modeld/compile_modeld.py b/openpilot/selfdrive/modeld/compile_modeld.py index 35f92d344f..20e2eeeded 100755 --- a/openpilot/selfdrive/modeld/compile_modeld.py +++ b/openpilot/selfdrive/modeld/compile_modeld.py @@ -34,8 +34,8 @@ from tinygrad.engine.jit import TinyJit NV12Frame = namedtuple("NV12Frame", ['width', 'height', 'stride', 'y_height', 'uv_height', 'size']) -WARP_INPUTS = ['img_q', 'big_img_q', 'tfm', 'big_tfm'] -POLICY_INPUTS = ['feat_q', 'desire_q', 'packed_npy_inputs'] +WARP_INPUTS = ['tfm', 'big_tfm'] +POLICY_INPUTS = ['img_q', 'big_img_q', 'feat_q', 'desire_q', 'packed_npy_inputs'] UV_SCALE_MATRIX = np.array([[0.5, 0, 0], [0, 0.5, 0], [0, 0, 1]], dtype=np.float32) UV_SCALE_MATRIX_INV = np.linalg.inv(UV_SCALE_MATRIX) @@ -175,20 +175,17 @@ def sample_desire(buf, frame_skip): def make_warp(nv12, model_w, model_h, frame_skip): frame_prepare = make_frame_prepare(nv12, model_w, model_h) - sample_skip_fn = partial(sample_skip, frame_skip=frame_skip) - def warp_enqueue(img_q, big_img_q, tfm, big_tfm, frame, big_frame): + def warp(tfm, big_tfm, frame, big_frame): tfm = tfm.to(WARP_DEV) big_tfm = big_tfm.to(WARP_DEV) Tensor.realize(tfm, big_tfm) warped_frame = frame_prepare(frame, tfm).unsqueeze(0) warped_big_frame = frame_prepare(big_frame, big_tfm).unsqueeze(0) - warped = Tensor.cat(warped_frame, warped_big_frame).to(Device.DEFAULT) - img = shift_and_sample(img_q, warped[0:1], sample_skip_fn) - big_img = shift_and_sample(big_img_q, warped[1:2], sample_skip_fn) - return img, big_img - return warp_enqueue + return Tensor.cat(warped_frame, warped_big_frame) + + return warp def make_run_policy(model_runner, model_metadata, frame_skip): @@ -196,8 +193,14 @@ def make_run_policy(model_runner, model_metadata, frame_skip): sample_skip_fn = partial(sample_skip, frame_skip=frame_skip) npy_shapes, npy_sizes = get_policy_npy_shapes(model_metadata['input_shapes']) - def run_policy(img, big_img, feat_q, desire_q, packed_npy_inputs): - packed_npy_inputs = packed_npy_inputs.to(Device.DEFAULT).realize() + def run_policy(warped, img_q, big_img_q, feat_q, desire_q, packed_npy_inputs): + packed_npy_inputs = packed_npy_inputs.to(Device.DEFAULT) + warped = warped.to(Device.DEFAULT) + Tensor.realize(packed_npy_inputs, warped) + + img = shift_and_sample(img_q, warped[0:1], sample_skip_fn) + big_img = shift_and_sample(big_img_q, warped[1:2], sample_skip_fn) + desire, traffic_convention, action_t, prev_feat = (t.reshape(s) for t, s in zip(packed_npy_inputs.split(npy_sizes), npy_shapes.values(), strict=True)) desire_buf = shift_and_sample(desire_q, desire.reshape(1, 1, -1), sample_desire_fn) feat_buf = shift_and_sample(feat_q, prev_feat.reshape(1, 1, -1), sample_skip_fn) @@ -295,16 +298,16 @@ if __name__ == "__main__": run_policy_jit = TinyJit(make_run_policy(model_runner, out['metadata'], args.frame_skip), prune=True) make_policy_queues = partial(make_input_queues, out['metadata']['input_shapes'], args.frame_skip) - make_random_model_inputs = partial(make_random_images, keys=['img', 'big_img'], shape=out['metadata']['input_shapes']['img']) + make_random_model_inputs = partial(make_random_images, keys=['warped'], shape=(2, 6, *out['metadata']['input_shapes']['img'][2:]), device=WARP_DEV) out['run_policy'] = compile_jit(run_policy_jit, make_random_model_inputs, POLICY_INPUTS, make_policy_queues) for cam_w, cam_h in args.camera_resolutions: nv12 = NV12Frame(cam_w, cam_h, *get_nv12_info(cam_w, cam_h)) make_random_warp_inputs = partial(make_random_images, keys=['frame', 'big_frame'], shape=nv12.size, device=WARP_DEV) - warp_enqueue = TinyJit(make_warp(nv12, model_w, model_h, args.frame_skip), prune=True) + warp = TinyJit(make_warp(nv12, model_w, model_h, args.frame_skip), prune=True) make_warp_queues = partial(make_warp_input_queues, out['metadata']['input_shapes'], args.frame_skip) - out[(cam_w,cam_h)] = compile_jit(warp_enqueue, make_random_warp_inputs, WARP_INPUTS, make_warp_queues) + out[(cam_w,cam_h)] = compile_jit(warp, make_random_warp_inputs, WARP_INPUTS, make_warp_queues) with open(args.output, "wb") as f: pickle.dump(out, f) diff --git a/openpilot/selfdrive/modeld/modeld.py b/openpilot/selfdrive/modeld/modeld.py index dca74d0a5b..3d5e04873d 100755 --- a/openpilot/selfdrive/modeld/modeld.py +++ b/openpilot/selfdrive/modeld/modeld.py @@ -94,7 +94,7 @@ class ModelState: self.parser = Parser() self.frame_buf_params = {k: get_nv12_info(cam_w, cam_h) for k in ('img', 'big_img')} self.run_policy = jits['run_policy'] - self.warp_enqueue = jits[(cam_w,cam_h)] + self.warp = jits[(cam_w,cam_h)] def slice_outputs(self, model_outputs: np.ndarray, output_slices: dict[str, slice]) -> dict[str, np.ndarray]: parsed_model_outputs = {k: model_outputs[np.newaxis, v] for k,v in output_slices.items()} @@ -120,10 +120,10 @@ class ModelState: self.npy['tfm'][:,:] = transforms['img'][:,:] self.npy['big_tfm'][:,:] = transforms['big_img'][:,:] - img, big_img = self.warp_enqueue(**{k: self.input_queues[k] for k in WARP_INPUTS}, frame=self.full_frames['img'], big_frame=self.full_frames['big_img']) + warped = self.warp(**{k: self.input_queues[k] for k in WARP_INPUTS}, frame=self.full_frames['img'], big_frame=self.full_frames['big_img']) outs, = self.run_policy( - **{k: self.input_queues[k] for k in POLICY_INPUTS if k in self.input_queues}, img=img, big_img=big_img + **{k: self.input_queues[k] for k in POLICY_INPUTS if k in self.input_queues}, warped=warped ) model_output = outs.numpy()[0] outputs_dict = self.parser.parse_outputs(self.slice_outputs(model_output, self.output_slices)) From 724971afc381b864edd6d3ab4ff57cb2710a4299 Mon Sep 17 00:00:00 2001 From: Armand du Parc Locmaria Date: Tue, 30 Jun 2026 00:35:12 -0700 Subject: [PATCH 095/151] usbgpu: never materialize model weights in RAM (#38265) * bigger big * don't load big model in ram * patch tg to allow out of band buffers * dump/load oob * roundtrip pkl to disk * streaming chunking * to_disk * fixup * linter * Revert "bigger big" This reverts commit 7a8147dd7fab88db963d512ab4008de940714025. --- openpilot/common/file_chunker.py | 41 ++++++++++++++----- openpilot/selfdrive/modeld/compile_modeld.py | 40 ++++++++++++++---- .../selfdrive/modeld/dmonitoringmodeld.py | 4 +- openpilot/selfdrive/modeld/helpers.py | 29 +++++++++++++ openpilot/selfdrive/modeld/modeld.py | 7 ++-- 5 files changed, 95 insertions(+), 26 deletions(-) diff --git a/openpilot/common/file_chunker.py b/openpilot/common/file_chunker.py index 57dfc35531..6af17495bb 100755 --- a/openpilot/common/file_chunker.py +++ b/openpilot/common/file_chunker.py @@ -1,4 +1,5 @@ #!/usr/bin/env python3 +import io import sys import math import os @@ -21,13 +22,12 @@ def get_chunk_targets(path, file_size): def chunk_file(path, targets): manifest_path, *chunk_paths = targets - with open(path, 'rb') as f: - data = f.read() - actual_num_chunks = max(1, math.ceil(len(data) / CHUNK_SIZE)) + actual_num_chunks = max(1, math.ceil(os.path.getsize(path) / CHUNK_SIZE)) assert len(chunk_paths) >= actual_num_chunks, f"Allowed {len(chunk_paths)} chunks but needs at least {actual_num_chunks}, for path {path}" - for i, chunk_path in enumerate(chunk_paths): - with open(chunk_path, 'wb') as f: - f.write(data[i * CHUNK_SIZE:(i + 1) * CHUNK_SIZE]) + with open(path, 'rb') as f: + for chunk_path in chunk_paths: + with open(chunk_path, 'wb') as out: + out.write(f.read(CHUNK_SIZE)) Path(manifest_path).write_text(str(len(chunk_paths))) os.remove(path) @@ -39,14 +39,33 @@ def get_existing_chunks(path): return _chunk_paths(path, num_chunks) raise FileNotFoundError(path) -def read_file_chunked(path): +class ChunkStream(io.RawIOBase): + def __init__(self, paths): + self._files = (open(p, 'rb') for p in paths) + self._cur = next(self._files, None) + + def readable(self): + return True + + def readinto(self, b): + while self._cur is not None: + n = self._cur.readinto(b) + if n: + return n + self._cur.close() + self._cur = next(self._files, None) + return 0 + +def open_file_chunked(path): manifest_path = get_manifest_path(path) if os.path.isfile(manifest_path): num_chunks = int(Path(manifest_path).read_text().strip()) - return b''.join(Path(get_chunk_name(path, i, num_chunks)).read_bytes() for i in range(num_chunks)) - if os.path.isfile(path): - return Path(path).read_bytes() - raise FileNotFoundError(path) + paths = [get_chunk_name(path, i, num_chunks) for i in range(num_chunks)] + elif os.path.isfile(path): + paths = [path] + else: + raise FileNotFoundError(path) + return io.BufferedReader(ChunkStream(paths)) if __name__ == "__main__": diff --git a/openpilot/selfdrive/modeld/compile_modeld.py b/openpilot/selfdrive/modeld/compile_modeld.py index 20e2eeeded..769fb69eb3 100755 --- a/openpilot/selfdrive/modeld/compile_modeld.py +++ b/openpilot/selfdrive/modeld/compile_modeld.py @@ -6,11 +6,14 @@ import os import pickle import tempfile import time +import shutil from functools import partial from collections import namedtuple import numpy as np +from openpilot.selfdrive.modeld.helpers import dump_oob, load_oob + def _patch_tinygrad_fetch_fw(): import hashlib import pathlib @@ -27,6 +30,23 @@ def _patch_tinygrad_fetch_fw(): helpers.fetch_fw = fetch_fw _patch_tinygrad_fetch_fw() +def _patch_tinygrad_buffer_reduce(): + from tinygrad.device import Buffer + def __reduce_ex__(self, protocol): + buf = None + if self._base is not None: + return self.__class__, (self.device, self.size, self.dtype, None, None, None, 0, self.base, self.offset, self.is_allocated()) + if self.device == "NPY": + return self.__class__, (self.device, self.size, self.dtype, self._buf, self.options, None, self.uop_refcount) + if self.is_allocated(): + buf = bytearray(self.nbytes) + self.copyout(memoryview(buf)) + if protocol >= 5: + buf = pickle.PickleBuffer(buf) + return self.__class__, (self.device, self.size, self.dtype, None, self.options, buf, self.uop_refcount) + Buffer.__reduce_ex__ = __reduce_ex__ +_patch_tinygrad_buffer_reduce() + from tinygrad.tensor import Tensor from tinygrad.helpers import Context from tinygrad.device import Device @@ -255,7 +275,10 @@ def compile_jit(jit, make_random_inputs, input_keys, make_queues): print('capture + replay') test_val, test_buffers = random_inputs_run(jit, SEED) print('pickle round trip') - jit = pickle.loads(pickle.dumps(jit)) + with tempfile.TemporaryFile(dir=".") as f: + dump_oob(jit, f) + f.seek(0) + jit = load_oob(f) random_inputs_run(jit, SEED, test_val, test_buffers, expect_match=True) random_inputs_run(jit, SEED+1, test_val, test_buffers, expect_match=False) return jit @@ -266,12 +289,11 @@ def _parse_size(s): return int(w), int(h) -def read_file_chunked_to_shm(path): - from openpilot.common.file_chunker import read_file_chunked - from openpilot.common.hardware.hw import Paths - with tempfile.NamedTemporaryFile(prefix='compile_modeld_', dir=Paths.shm_path(), delete=False) as f: - f.write(read_file_chunked(path)) - tmp_path = f.name +def read_file_chunked_to_disk(path): + from openpilot.common.file_chunker import open_file_chunked + tmp_path = f'{path}.unchunked' + with open(tmp_path, 'wb') as f, open_file_chunked(path) as src: + shutil.copyfileobj(src, f) atexit.register(lambda: os.path.exists(tmp_path) and os.remove(tmp_path)) return tmp_path @@ -289,7 +311,7 @@ if __name__ == "__main__": p.add_argument('--frame-skip', type=int, required=True) args = p.parse_args() - model_path = read_file_chunked_to_shm(args.onnx) + model_path = read_file_chunked_to_disk(args.onnx) model_w, model_h = args.model_size model_runner = OnnxRunner(model_path) @@ -310,5 +332,5 @@ if __name__ == "__main__": out[(cam_w,cam_h)] = compile_jit(warp, make_random_warp_inputs, WARP_INPUTS, make_warp_queues) with open(args.output, "wb") as f: - pickle.dump(out, f) + dump_oob(out, f) print(f"Saved JITs to {args.output} ({os.path.getsize(args.output) / 1e6:.2f} MB)") diff --git a/openpilot/selfdrive/modeld/dmonitoringmodeld.py b/openpilot/selfdrive/modeld/dmonitoringmodeld.py index 2c659d9ac6..554407a223 100755 --- a/openpilot/selfdrive/modeld/dmonitoringmodeld.py +++ b/openpilot/selfdrive/modeld/dmonitoringmodeld.py @@ -14,7 +14,7 @@ from openpilot.common.realtime import config_realtime_process from openpilot.common.transformations.model import dmonitoringmodel_intrinsics from openpilot.common.transformations.camera import _ar_ox_fisheye, _os_fisheye from openpilot.system.camerad.cameras.nv12_info import get_nv12_info -from openpilot.common.file_chunker import read_file_chunked +from openpilot.common.file_chunker import open_file_chunked from openpilot.selfdrive.modeld.parse_model_outputs import sigmoid, safe_exp PROCESS_NAME = "openpilot.selfdrive.modeld.dmonitoringmodeld" @@ -43,7 +43,7 @@ class ModelState: self.frame_buf_params = get_nv12_info(cam_w, cam_h) self.tensor_inputs = {k: Tensor(v, device='NPY').realize() for k,v in self.numpy_inputs.items()} self._blob_cache : dict[int, Tensor] = {} - self.model_run = pickle.loads(read_file_chunked(str(MODEL_PKL_PATH))) + self.model_run = pickle.load(open_file_chunked(str(MODEL_PKL_PATH))) with open(MODELS_DIR / f'dm_warp_{cam_w}x{cam_h}_tinygrad.pkl', "rb") as f: self.image_warp = pickle.load(f) diff --git a/openpilot/selfdrive/modeld/helpers.py b/openpilot/selfdrive/modeld/helpers.py index 64bf28873f..4a85248d90 100644 --- a/openpilot/selfdrive/modeld/helpers.py +++ b/openpilot/selfdrive/modeld/helpers.py @@ -1,4 +1,9 @@ +import io import json +import pickle +import shutil +import struct +import tempfile from pathlib import Path MODELS_DIR = Path(__file__).resolve().parent / 'models' @@ -15,6 +20,30 @@ def modeld_pkl_path(usbgpu: bool): prefix = 'big_' if usbgpu else '' return MODELS_DIR / f'{prefix}driving_tinygrad.pkl' +def dump_oob(obj, f): + with tempfile.TemporaryFile(dir=".") as tmp: + def buffer_callback(pb: pickle.PickleBuffer): + m = pb.raw() + tmp.write(struct.pack(' bool: for d in Path("/sys/bus/usb/devices").glob("*"): try: diff --git a/openpilot/selfdrive/modeld/modeld.py b/openpilot/selfdrive/modeld/modeld.py index 3d5e04873d..115873158f 100755 --- a/openpilot/selfdrive/modeld/modeld.py +++ b/openpilot/selfdrive/modeld/modeld.py @@ -3,7 +3,6 @@ import os os.environ['GMMU'] = '0' # for usbgpu fast loading, noop for qcom from tinygrad.tensor import Tensor import time -import pickle import numpy as np import openpilot.cereal.messaging as messaging from openpilot.cereal import log @@ -23,9 +22,9 @@ from openpilot.selfdrive.controls.lib.drive_helpers import get_accel_from_plan, from openpilot.selfdrive.modeld.parse_model_outputs import Parser from openpilot.selfdrive.modeld.compile_modeld import make_input_queues, WARP_INPUTS, POLICY_INPUTS from openpilot.selfdrive.modeld.fill_model_msg import fill_model_msg, fill_driving_model_data, fill_pose_msg, PublishState -from openpilot.common.file_chunker import read_file_chunked, get_manifest_path +from openpilot.common.file_chunker import open_file_chunked, get_manifest_path from openpilot.selfdrive.modeld.constants import ModelConstants, Plan -from openpilot.selfdrive.modeld.helpers import usbgpu_present, modeld_pkl_path, get_tg_input_devices +from openpilot.selfdrive.modeld.helpers import usbgpu_present, modeld_pkl_path, get_tg_input_devices, load_oob PROCESS_NAME = "openpilot.selfdrive.modeld.modeld" SEND_RAW_PRED = os.getenv('SEND_RAW_PRED') @@ -79,7 +78,7 @@ class ModelState: def __init__(self, cam_w: int, cam_h: int, usbgpu: bool): input_devices = get_tg_input_devices(PROCESS_NAME, usbgpu) self.WARP_DEV, self.QUEUE_DEV = input_devices['WARP_DEV'], input_devices['QUEUE_DEV'] - jits = pickle.loads(read_file_chunked(modeld_pkl_path(usbgpu))) + jits = load_oob(open_file_chunked(modeld_pkl_path(usbgpu))) metadata = jits['metadata'] self.input_shapes = metadata['input_shapes'] self.vision_input_names = [k for k in self.input_shapes if 'img' in k] From 8196b743afa5d321983bb0728e3e206c3af10e5d Mon Sep 17 00:00:00 2001 From: Armand du Parc Locmaria Date: Tue, 30 Jun 2026 13:13:23 -0700 Subject: [PATCH 096/151] Revert "usbgpu: never materialize model weights in RAM" (#38271) Revert "usbgpu: never materialize model weights in RAM (#38265)" This reverts commit 724971afc381b864edd6d3ab4ff57cb2710a4299. --- openpilot/common/file_chunker.py | 41 +++++-------------- openpilot/selfdrive/modeld/compile_modeld.py | 40 ++++-------------- .../selfdrive/modeld/dmonitoringmodeld.py | 4 +- openpilot/selfdrive/modeld/helpers.py | 29 ------------- openpilot/selfdrive/modeld/modeld.py | 7 ++-- 5 files changed, 26 insertions(+), 95 deletions(-) diff --git a/openpilot/common/file_chunker.py b/openpilot/common/file_chunker.py index 6af17495bb..57dfc35531 100755 --- a/openpilot/common/file_chunker.py +++ b/openpilot/common/file_chunker.py @@ -1,5 +1,4 @@ #!/usr/bin/env python3 -import io import sys import math import os @@ -22,12 +21,13 @@ def get_chunk_targets(path, file_size): def chunk_file(path, targets): manifest_path, *chunk_paths = targets - actual_num_chunks = max(1, math.ceil(os.path.getsize(path) / CHUNK_SIZE)) - assert len(chunk_paths) >= actual_num_chunks, f"Allowed {len(chunk_paths)} chunks but needs at least {actual_num_chunks}, for path {path}" with open(path, 'rb') as f: - for chunk_path in chunk_paths: - with open(chunk_path, 'wb') as out: - out.write(f.read(CHUNK_SIZE)) + data = f.read() + actual_num_chunks = max(1, math.ceil(len(data) / CHUNK_SIZE)) + assert len(chunk_paths) >= actual_num_chunks, f"Allowed {len(chunk_paths)} chunks but needs at least {actual_num_chunks}, for path {path}" + for i, chunk_path in enumerate(chunk_paths): + with open(chunk_path, 'wb') as f: + f.write(data[i * CHUNK_SIZE:(i + 1) * CHUNK_SIZE]) Path(manifest_path).write_text(str(len(chunk_paths))) os.remove(path) @@ -39,33 +39,14 @@ def get_existing_chunks(path): return _chunk_paths(path, num_chunks) raise FileNotFoundError(path) -class ChunkStream(io.RawIOBase): - def __init__(self, paths): - self._files = (open(p, 'rb') for p in paths) - self._cur = next(self._files, None) - - def readable(self): - return True - - def readinto(self, b): - while self._cur is not None: - n = self._cur.readinto(b) - if n: - return n - self._cur.close() - self._cur = next(self._files, None) - return 0 - -def open_file_chunked(path): +def read_file_chunked(path): manifest_path = get_manifest_path(path) if os.path.isfile(manifest_path): num_chunks = int(Path(manifest_path).read_text().strip()) - paths = [get_chunk_name(path, i, num_chunks) for i in range(num_chunks)] - elif os.path.isfile(path): - paths = [path] - else: - raise FileNotFoundError(path) - return io.BufferedReader(ChunkStream(paths)) + return b''.join(Path(get_chunk_name(path, i, num_chunks)).read_bytes() for i in range(num_chunks)) + if os.path.isfile(path): + return Path(path).read_bytes() + raise FileNotFoundError(path) if __name__ == "__main__": diff --git a/openpilot/selfdrive/modeld/compile_modeld.py b/openpilot/selfdrive/modeld/compile_modeld.py index 769fb69eb3..20e2eeeded 100755 --- a/openpilot/selfdrive/modeld/compile_modeld.py +++ b/openpilot/selfdrive/modeld/compile_modeld.py @@ -6,14 +6,11 @@ import os import pickle import tempfile import time -import shutil from functools import partial from collections import namedtuple import numpy as np -from openpilot.selfdrive.modeld.helpers import dump_oob, load_oob - def _patch_tinygrad_fetch_fw(): import hashlib import pathlib @@ -30,23 +27,6 @@ def _patch_tinygrad_fetch_fw(): helpers.fetch_fw = fetch_fw _patch_tinygrad_fetch_fw() -def _patch_tinygrad_buffer_reduce(): - from tinygrad.device import Buffer - def __reduce_ex__(self, protocol): - buf = None - if self._base is not None: - return self.__class__, (self.device, self.size, self.dtype, None, None, None, 0, self.base, self.offset, self.is_allocated()) - if self.device == "NPY": - return self.__class__, (self.device, self.size, self.dtype, self._buf, self.options, None, self.uop_refcount) - if self.is_allocated(): - buf = bytearray(self.nbytes) - self.copyout(memoryview(buf)) - if protocol >= 5: - buf = pickle.PickleBuffer(buf) - return self.__class__, (self.device, self.size, self.dtype, None, self.options, buf, self.uop_refcount) - Buffer.__reduce_ex__ = __reduce_ex__ -_patch_tinygrad_buffer_reduce() - from tinygrad.tensor import Tensor from tinygrad.helpers import Context from tinygrad.device import Device @@ -275,10 +255,7 @@ def compile_jit(jit, make_random_inputs, input_keys, make_queues): print('capture + replay') test_val, test_buffers = random_inputs_run(jit, SEED) print('pickle round trip') - with tempfile.TemporaryFile(dir=".") as f: - dump_oob(jit, f) - f.seek(0) - jit = load_oob(f) + jit = pickle.loads(pickle.dumps(jit)) random_inputs_run(jit, SEED, test_val, test_buffers, expect_match=True) random_inputs_run(jit, SEED+1, test_val, test_buffers, expect_match=False) return jit @@ -289,11 +266,12 @@ def _parse_size(s): return int(w), int(h) -def read_file_chunked_to_disk(path): - from openpilot.common.file_chunker import open_file_chunked - tmp_path = f'{path}.unchunked' - with open(tmp_path, 'wb') as f, open_file_chunked(path) as src: - shutil.copyfileobj(src, f) +def read_file_chunked_to_shm(path): + from openpilot.common.file_chunker import read_file_chunked + from openpilot.common.hardware.hw import Paths + with tempfile.NamedTemporaryFile(prefix='compile_modeld_', dir=Paths.shm_path(), delete=False) as f: + f.write(read_file_chunked(path)) + tmp_path = f.name atexit.register(lambda: os.path.exists(tmp_path) and os.remove(tmp_path)) return tmp_path @@ -311,7 +289,7 @@ if __name__ == "__main__": p.add_argument('--frame-skip', type=int, required=True) args = p.parse_args() - model_path = read_file_chunked_to_disk(args.onnx) + model_path = read_file_chunked_to_shm(args.onnx) model_w, model_h = args.model_size model_runner = OnnxRunner(model_path) @@ -332,5 +310,5 @@ if __name__ == "__main__": out[(cam_w,cam_h)] = compile_jit(warp, make_random_warp_inputs, WARP_INPUTS, make_warp_queues) with open(args.output, "wb") as f: - dump_oob(out, f) + pickle.dump(out, f) print(f"Saved JITs to {args.output} ({os.path.getsize(args.output) / 1e6:.2f} MB)") diff --git a/openpilot/selfdrive/modeld/dmonitoringmodeld.py b/openpilot/selfdrive/modeld/dmonitoringmodeld.py index 554407a223..2c659d9ac6 100755 --- a/openpilot/selfdrive/modeld/dmonitoringmodeld.py +++ b/openpilot/selfdrive/modeld/dmonitoringmodeld.py @@ -14,7 +14,7 @@ from openpilot.common.realtime import config_realtime_process from openpilot.common.transformations.model import dmonitoringmodel_intrinsics from openpilot.common.transformations.camera import _ar_ox_fisheye, _os_fisheye from openpilot.system.camerad.cameras.nv12_info import get_nv12_info -from openpilot.common.file_chunker import open_file_chunked +from openpilot.common.file_chunker import read_file_chunked from openpilot.selfdrive.modeld.parse_model_outputs import sigmoid, safe_exp PROCESS_NAME = "openpilot.selfdrive.modeld.dmonitoringmodeld" @@ -43,7 +43,7 @@ class ModelState: self.frame_buf_params = get_nv12_info(cam_w, cam_h) self.tensor_inputs = {k: Tensor(v, device='NPY').realize() for k,v in self.numpy_inputs.items()} self._blob_cache : dict[int, Tensor] = {} - self.model_run = pickle.load(open_file_chunked(str(MODEL_PKL_PATH))) + self.model_run = pickle.loads(read_file_chunked(str(MODEL_PKL_PATH))) with open(MODELS_DIR / f'dm_warp_{cam_w}x{cam_h}_tinygrad.pkl', "rb") as f: self.image_warp = pickle.load(f) diff --git a/openpilot/selfdrive/modeld/helpers.py b/openpilot/selfdrive/modeld/helpers.py index 4a85248d90..64bf28873f 100644 --- a/openpilot/selfdrive/modeld/helpers.py +++ b/openpilot/selfdrive/modeld/helpers.py @@ -1,9 +1,4 @@ -import io import json -import pickle -import shutil -import struct -import tempfile from pathlib import Path MODELS_DIR = Path(__file__).resolve().parent / 'models' @@ -20,30 +15,6 @@ def modeld_pkl_path(usbgpu: bool): prefix = 'big_' if usbgpu else '' return MODELS_DIR / f'{prefix}driving_tinygrad.pkl' -def dump_oob(obj, f): - with tempfile.TemporaryFile(dir=".") as tmp: - def buffer_callback(pb: pickle.PickleBuffer): - m = pb.raw() - tmp.write(struct.pack(' bool: for d in Path("/sys/bus/usb/devices").glob("*"): try: diff --git a/openpilot/selfdrive/modeld/modeld.py b/openpilot/selfdrive/modeld/modeld.py index 115873158f..3d5e04873d 100755 --- a/openpilot/selfdrive/modeld/modeld.py +++ b/openpilot/selfdrive/modeld/modeld.py @@ -3,6 +3,7 @@ import os os.environ['GMMU'] = '0' # for usbgpu fast loading, noop for qcom from tinygrad.tensor import Tensor import time +import pickle import numpy as np import openpilot.cereal.messaging as messaging from openpilot.cereal import log @@ -22,9 +23,9 @@ from openpilot.selfdrive.controls.lib.drive_helpers import get_accel_from_plan, from openpilot.selfdrive.modeld.parse_model_outputs import Parser from openpilot.selfdrive.modeld.compile_modeld import make_input_queues, WARP_INPUTS, POLICY_INPUTS from openpilot.selfdrive.modeld.fill_model_msg import fill_model_msg, fill_driving_model_data, fill_pose_msg, PublishState -from openpilot.common.file_chunker import open_file_chunked, get_manifest_path +from openpilot.common.file_chunker import read_file_chunked, get_manifest_path from openpilot.selfdrive.modeld.constants import ModelConstants, Plan -from openpilot.selfdrive.modeld.helpers import usbgpu_present, modeld_pkl_path, get_tg_input_devices, load_oob +from openpilot.selfdrive.modeld.helpers import usbgpu_present, modeld_pkl_path, get_tg_input_devices PROCESS_NAME = "openpilot.selfdrive.modeld.modeld" SEND_RAW_PRED = os.getenv('SEND_RAW_PRED') @@ -78,7 +79,7 @@ class ModelState: def __init__(self, cam_w: int, cam_h: int, usbgpu: bool): input_devices = get_tg_input_devices(PROCESS_NAME, usbgpu) self.WARP_DEV, self.QUEUE_DEV = input_devices['WARP_DEV'], input_devices['QUEUE_DEV'] - jits = load_oob(open_file_chunked(modeld_pkl_path(usbgpu))) + jits = pickle.loads(read_file_chunked(modeld_pkl_path(usbgpu))) metadata = jits['metadata'] self.input_shapes = metadata['input_shapes'] self.vision_input_names = [k for k in self.input_shapes if 'img' in k] From e1e9efb965775a1b14c8d78929ac83915b58a1a7 Mon Sep 17 00:00:00 2001 From: Daniel Koepping Date: Tue, 30 Jun 2026 16:17:26 -0700 Subject: [PATCH 097/151] add USB logging (#38186) * usb logging * fix test * discover by PID * hardwared, add counters * edit msg * add manufacturer * reorder * rm portli * rm this --- openpilot/cereal/log.capnp | 18 ++++++++ openpilot/common/hardware/usb.py | 63 ++++++++++++++++++++++++++ openpilot/system/hardware/hardwared.py | 7 ++- 3 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 openpilot/common/hardware/usb.py diff --git a/openpilot/cereal/log.capnp b/openpilot/cereal/log.capnp index 8d4d801161..2b43a95d7b 100644 --- a/openpilot/cereal/log.capnp +++ b/openpilot/cereal/log.capnp @@ -414,6 +414,10 @@ struct CanData { struct DeviceState @0xa4d8b5af2aa492eb { deviceType @45 :InitData.DeviceType; + # usb + chestnutPresent @51 :Bool; + usbState @52 :UsbState; + networkType @22 :NetworkType; networkInfo @31 :NetworkInfo; networkStrength @24 :NetworkStrength; @@ -684,6 +688,20 @@ struct PeripheralState { } } +struct UsbState { + devices @0 :List(Device); + + struct Device { + busnum @0 :UInt8; + devnum @1 :UInt8; + vendorId @2 :UInt16; + productId @3 :UInt16; + speedMbps @4 :UInt16; + manufacturer @6 :Text; + product @5 :Text; + } +} + struct RadarState @0x9a185389d6fdd05f { mdMonoTime @6 :UInt64; carStateMonoTime @11 :UInt64; diff --git a/openpilot/common/hardware/usb.py b/openpilot/common/hardware/usb.py new file mode 100644 index 0000000000..805f32407f --- /dev/null +++ b/openpilot/common/hardware/usb.py @@ -0,0 +1,63 @@ +from pathlib import Path + +CHESTNUT_VENDOR_ID = 0xADD1 +CHESTNUT_PRODUCT_ID = 0x0001 +USB_DEVICES_PATH = Path("/sys/bus/usb/devices") + + +def read(path: Path) -> str | None: + try: + return path.read_text().strip() + except OSError: + return None + + +def read_int(path: Path, base: int = 10) -> int: + try: + return int(path.read_text(), base) + except (OSError, ValueError): + return 0 + + +def usb_devices() -> list[Path]: + try: + devices = (d for d in USB_DEVICES_PATH.glob("*") if (d / "idVendor").exists()) + return sorted(devices, key=lambda p: p.name) + except OSError: + return [] + + +def get_usb_state() -> list[dict]: + devices = [] + for device in usb_devices(): + vendor_id = read_int(device / "idVendor", 16) + product_id = read_int(device / "idProduct", 16) + devices.append({ + "busnum": read_int(device / "busnum"), + "devnum": read_int(device / "devnum"), + "vendorId": vendor_id, + "productId": product_id, + "speedMbps": read_int(device / "speed"), + "manufacturer": read(device / "manufacturer") or "", + "product": read(device / "product") or "", + }) + return devices + + +def set_usb_state(device_state, devices: list[dict]) -> None: + entries = device_state.usbState.init('devices', len(devices)) + + chestnut_present = False + for entry, device in zip(entries, devices, strict=True): + entry.busnum = device["busnum"] + entry.devnum = device["devnum"] + entry.vendorId = device["vendorId"] + entry.productId = device["productId"] + entry.speedMbps = device["speedMbps"] + entry.manufacturer = device["manufacturer"] + entry.product = device["product"] + + if (entry.vendorId, entry.productId) == (CHESTNUT_VENDOR_ID, CHESTNUT_PRODUCT_ID): + chestnut_present = True + + device_state.chestnutPresent = chestnut_present diff --git a/openpilot/system/hardware/hardwared.py b/openpilot/system/hardware/hardwared.py index c56c37082f..077965e8ac 100755 --- a/openpilot/system/hardware/hardwared.py +++ b/openpilot/system/hardware/hardwared.py @@ -18,6 +18,7 @@ from openpilot.common.params import Params from openpilot.common.realtime import DT_HW from openpilot.selfdrive.selfdrived.alertmanager import set_offroad_alert from openpilot.common.hardware import HARDWARE, TICI, PC +from openpilot.common.hardware.usb import get_usb_state, set_usb_state from openpilot.system.loggerd.config import get_available_percent from openpilot.common.swaglog import cloudlog from openpilot.system.hardware.power_monitoring import PowerMonitoring @@ -36,7 +37,7 @@ ONROAD_CYCLE_TIME = 1 # seconds to wait offroad after requesting an onroad cycl ThermalBand = namedtuple("ThermalBand", ['min_temp', 'max_temp']) HardwareState = namedtuple("HardwareState", ['network_type', 'network_info', 'network_strength', 'network_stats', - 'network_metered', 'modem_temps']) + 'network_metered', 'modem_temps', 'usb_state']) # List of thermal bands. We will stay within this region as long as we are within the bounds. # When exiting the bounds, we'll jump to the lower or higher band. Bands are ordered in the dict. @@ -124,6 +125,7 @@ def hw_state_thread(end_event, hw_queue): network_stats={'wwanTx': tx, 'wwanRx': rx}, network_metered=HARDWARE.get_network_metered(network_type), modem_temps=modem_temps, + usb_state=get_usb_state(), ) try: @@ -166,6 +168,7 @@ def hardware_thread(end_event, hw_queue) -> None: network_strength=NetworkStrength.unknown, network_stats={'wwanTx': -1, 'wwanRx': -1}, modem_temps=[], + usb_state=[], ) all_temp_filter = FirstOrderFilter(0., TEMP_TAU, DT_HW, initialized=False) @@ -246,6 +249,8 @@ def hardware_thread(end_event, hw_queue) -> None: msg.deviceState.screenBrightnessPercent = HARDWARE.get_screen_brightness() + set_usb_state(msg.deviceState, last_hw_state.usb_state) + # this subset is only used for offroad temp_sources = [ msg.deviceState.memoryTempC, From a2c554805b9f751e8ef0efb9340a5546aeb17d2b Mon Sep 17 00:00:00 2001 From: Armand du Parc Locmaria Date: Wed, 1 Jul 2026 01:22:48 -0700 Subject: [PATCH 098/151] Reapply "usbgpu: never materialize model weights in RAM" (#38273) * Reapply "usbgpu: never materialize model weights in RAM" (#38271) This reverts commit 8196b743afa5d321983bb0728e3e206c3af10e5d. * release oob buffers as we load them * don't leak fds * lint * 10s faster loading time for big model --- openpilot/common/file_chunker.py | 48 ++++++++++++++----- openpilot/selfdrive/modeld/compile_modeld.py | 40 ++++++++++++---- .../selfdrive/modeld/dmonitoringmodeld.py | 4 +- openpilot/selfdrive/modeld/helpers.py | 33 +++++++++++++ openpilot/selfdrive/modeld/modeld.py | 7 ++- 5 files changed, 106 insertions(+), 26 deletions(-) diff --git a/openpilot/common/file_chunker.py b/openpilot/common/file_chunker.py index 57dfc35531..74f3013f71 100755 --- a/openpilot/common/file_chunker.py +++ b/openpilot/common/file_chunker.py @@ -1,4 +1,5 @@ #!/usr/bin/env python3 +import io import sys import math import os @@ -21,13 +22,12 @@ def get_chunk_targets(path, file_size): def chunk_file(path, targets): manifest_path, *chunk_paths = targets - with open(path, 'rb') as f: - data = f.read() - actual_num_chunks = max(1, math.ceil(len(data) / CHUNK_SIZE)) + actual_num_chunks = max(1, math.ceil(os.path.getsize(path) / CHUNK_SIZE)) assert len(chunk_paths) >= actual_num_chunks, f"Allowed {len(chunk_paths)} chunks but needs at least {actual_num_chunks}, for path {path}" - for i, chunk_path in enumerate(chunk_paths): - with open(chunk_path, 'wb') as f: - f.write(data[i * CHUNK_SIZE:(i + 1) * CHUNK_SIZE]) + with open(path, 'rb') as f: + for chunk_path in chunk_paths: + with open(chunk_path, 'wb') as out: + out.write(f.read(CHUNK_SIZE)) Path(manifest_path).write_text(str(len(chunk_paths))) os.remove(path) @@ -39,14 +39,40 @@ def get_existing_chunks(path): return _chunk_paths(path, num_chunks) raise FileNotFoundError(path) -def read_file_chunked(path): +class ChunkStream(io.RawIOBase): + def __init__(self, paths): + self._paths = iter(paths) + self._buf = memoryview(b'') + + def readable(self): + return True + + def readinto(self, b): + n = 0 + while n < len(b): + if not self._buf: + p = next(self._paths, None) + if p is None: + break + with open(p, 'rb') as f: + self._buf = memoryview(f.read()) + continue + take = min(len(b) - n, len(self._buf)) + b[n:n + take] = self._buf[:take] + self._buf = self._buf[take:] + n += take + return n + +def open_file_chunked(path): manifest_path = get_manifest_path(path) if os.path.isfile(manifest_path): num_chunks = int(Path(manifest_path).read_text().strip()) - return b''.join(Path(get_chunk_name(path, i, num_chunks)).read_bytes() for i in range(num_chunks)) - if os.path.isfile(path): - return Path(path).read_bytes() - raise FileNotFoundError(path) + paths = [get_chunk_name(path, i, num_chunks) for i in range(num_chunks)] + elif os.path.isfile(path): + paths = [path] + else: + raise FileNotFoundError(path) + return io.BufferedReader(ChunkStream(paths)) if __name__ == "__main__": diff --git a/openpilot/selfdrive/modeld/compile_modeld.py b/openpilot/selfdrive/modeld/compile_modeld.py index 20e2eeeded..769fb69eb3 100755 --- a/openpilot/selfdrive/modeld/compile_modeld.py +++ b/openpilot/selfdrive/modeld/compile_modeld.py @@ -6,11 +6,14 @@ import os import pickle import tempfile import time +import shutil from functools import partial from collections import namedtuple import numpy as np +from openpilot.selfdrive.modeld.helpers import dump_oob, load_oob + def _patch_tinygrad_fetch_fw(): import hashlib import pathlib @@ -27,6 +30,23 @@ def _patch_tinygrad_fetch_fw(): helpers.fetch_fw = fetch_fw _patch_tinygrad_fetch_fw() +def _patch_tinygrad_buffer_reduce(): + from tinygrad.device import Buffer + def __reduce_ex__(self, protocol): + buf = None + if self._base is not None: + return self.__class__, (self.device, self.size, self.dtype, None, None, None, 0, self.base, self.offset, self.is_allocated()) + if self.device == "NPY": + return self.__class__, (self.device, self.size, self.dtype, self._buf, self.options, None, self.uop_refcount) + if self.is_allocated(): + buf = bytearray(self.nbytes) + self.copyout(memoryview(buf)) + if protocol >= 5: + buf = pickle.PickleBuffer(buf) + return self.__class__, (self.device, self.size, self.dtype, None, self.options, buf, self.uop_refcount) + Buffer.__reduce_ex__ = __reduce_ex__ +_patch_tinygrad_buffer_reduce() + from tinygrad.tensor import Tensor from tinygrad.helpers import Context from tinygrad.device import Device @@ -255,7 +275,10 @@ def compile_jit(jit, make_random_inputs, input_keys, make_queues): print('capture + replay') test_val, test_buffers = random_inputs_run(jit, SEED) print('pickle round trip') - jit = pickle.loads(pickle.dumps(jit)) + with tempfile.TemporaryFile(dir=".") as f: + dump_oob(jit, f) + f.seek(0) + jit = load_oob(f) random_inputs_run(jit, SEED, test_val, test_buffers, expect_match=True) random_inputs_run(jit, SEED+1, test_val, test_buffers, expect_match=False) return jit @@ -266,12 +289,11 @@ def _parse_size(s): return int(w), int(h) -def read_file_chunked_to_shm(path): - from openpilot.common.file_chunker import read_file_chunked - from openpilot.common.hardware.hw import Paths - with tempfile.NamedTemporaryFile(prefix='compile_modeld_', dir=Paths.shm_path(), delete=False) as f: - f.write(read_file_chunked(path)) - tmp_path = f.name +def read_file_chunked_to_disk(path): + from openpilot.common.file_chunker import open_file_chunked + tmp_path = f'{path}.unchunked' + with open(tmp_path, 'wb') as f, open_file_chunked(path) as src: + shutil.copyfileobj(src, f) atexit.register(lambda: os.path.exists(tmp_path) and os.remove(tmp_path)) return tmp_path @@ -289,7 +311,7 @@ if __name__ == "__main__": p.add_argument('--frame-skip', type=int, required=True) args = p.parse_args() - model_path = read_file_chunked_to_shm(args.onnx) + model_path = read_file_chunked_to_disk(args.onnx) model_w, model_h = args.model_size model_runner = OnnxRunner(model_path) @@ -310,5 +332,5 @@ if __name__ == "__main__": out[(cam_w,cam_h)] = compile_jit(warp, make_random_warp_inputs, WARP_INPUTS, make_warp_queues) with open(args.output, "wb") as f: - pickle.dump(out, f) + dump_oob(out, f) print(f"Saved JITs to {args.output} ({os.path.getsize(args.output) / 1e6:.2f} MB)") diff --git a/openpilot/selfdrive/modeld/dmonitoringmodeld.py b/openpilot/selfdrive/modeld/dmonitoringmodeld.py index 2c659d9ac6..554407a223 100755 --- a/openpilot/selfdrive/modeld/dmonitoringmodeld.py +++ b/openpilot/selfdrive/modeld/dmonitoringmodeld.py @@ -14,7 +14,7 @@ from openpilot.common.realtime import config_realtime_process from openpilot.common.transformations.model import dmonitoringmodel_intrinsics from openpilot.common.transformations.camera import _ar_ox_fisheye, _os_fisheye from openpilot.system.camerad.cameras.nv12_info import get_nv12_info -from openpilot.common.file_chunker import read_file_chunked +from openpilot.common.file_chunker import open_file_chunked from openpilot.selfdrive.modeld.parse_model_outputs import sigmoid, safe_exp PROCESS_NAME = "openpilot.selfdrive.modeld.dmonitoringmodeld" @@ -43,7 +43,7 @@ class ModelState: self.frame_buf_params = get_nv12_info(cam_w, cam_h) self.tensor_inputs = {k: Tensor(v, device='NPY').realize() for k,v in self.numpy_inputs.items()} self._blob_cache : dict[int, Tensor] = {} - self.model_run = pickle.loads(read_file_chunked(str(MODEL_PKL_PATH))) + self.model_run = pickle.load(open_file_chunked(str(MODEL_PKL_PATH))) with open(MODELS_DIR / f'dm_warp_{cam_w}x{cam_h}_tinygrad.pkl', "rb") as f: self.image_warp = pickle.load(f) diff --git a/openpilot/selfdrive/modeld/helpers.py b/openpilot/selfdrive/modeld/helpers.py index 64bf28873f..608bc6aa64 100644 --- a/openpilot/selfdrive/modeld/helpers.py +++ b/openpilot/selfdrive/modeld/helpers.py @@ -1,4 +1,9 @@ +import io import json +import pickle +import shutil +import struct +import tempfile from pathlib import Path MODELS_DIR = Path(__file__).resolve().parent / 'models' @@ -15,6 +20,34 @@ def modeld_pkl_path(usbgpu: bool): prefix = 'big_' if usbgpu else '' return MODELS_DIR / f'{prefix}driving_tinygrad.pkl' +def dump_oob(obj, f): + with tempfile.TemporaryFile(dir=".") as tmp: + def buffer_callback(pb: pickle.PickleBuffer): + m = pb.raw() + tmp.write(struct.pack(' bool: for d in Path("/sys/bus/usb/devices").glob("*"): try: diff --git a/openpilot/selfdrive/modeld/modeld.py b/openpilot/selfdrive/modeld/modeld.py index 3d5e04873d..115873158f 100755 --- a/openpilot/selfdrive/modeld/modeld.py +++ b/openpilot/selfdrive/modeld/modeld.py @@ -3,7 +3,6 @@ import os os.environ['GMMU'] = '0' # for usbgpu fast loading, noop for qcom from tinygrad.tensor import Tensor import time -import pickle import numpy as np import openpilot.cereal.messaging as messaging from openpilot.cereal import log @@ -23,9 +22,9 @@ from openpilot.selfdrive.controls.lib.drive_helpers import get_accel_from_plan, from openpilot.selfdrive.modeld.parse_model_outputs import Parser from openpilot.selfdrive.modeld.compile_modeld import make_input_queues, WARP_INPUTS, POLICY_INPUTS from openpilot.selfdrive.modeld.fill_model_msg import fill_model_msg, fill_driving_model_data, fill_pose_msg, PublishState -from openpilot.common.file_chunker import read_file_chunked, get_manifest_path +from openpilot.common.file_chunker import open_file_chunked, get_manifest_path from openpilot.selfdrive.modeld.constants import ModelConstants, Plan -from openpilot.selfdrive.modeld.helpers import usbgpu_present, modeld_pkl_path, get_tg_input_devices +from openpilot.selfdrive.modeld.helpers import usbgpu_present, modeld_pkl_path, get_tg_input_devices, load_oob PROCESS_NAME = "openpilot.selfdrive.modeld.modeld" SEND_RAW_PRED = os.getenv('SEND_RAW_PRED') @@ -79,7 +78,7 @@ class ModelState: def __init__(self, cam_w: int, cam_h: int, usbgpu: bool): input_devices = get_tg_input_devices(PROCESS_NAME, usbgpu) self.WARP_DEV, self.QUEUE_DEV = input_devices['WARP_DEV'], input_devices['QUEUE_DEV'] - jits = pickle.loads(read_file_chunked(modeld_pkl_path(usbgpu))) + jits = load_oob(open_file_chunked(modeld_pkl_path(usbgpu))) metadata = jits['metadata'] self.input_shapes = metadata['input_shapes'] self.vision_input_names = [k for k in self.input_shapes if 'img' in k] From fa0c6876d3cf070e91e25e5353ceadc68a5b3285 Mon Sep 17 00:00:00 2001 From: Armand du Parc Locmaria Date: Wed, 1 Jul 2026 01:26:11 -0700 Subject: [PATCH 099/151] lebowski model (#38268) * Reapply "usbgpu: never materialize model weights in RAM" (#38271) This reverts commit 8196b743afa5d321983bb0728e3e206c3af10e5d. * release oob buffers as we load them * don't leak fds * lint * bigger big * don't roundtrip the features to qcom * Revert "don't roundtrip the features to qcom" This reverts commit 0d2ca73d7a71bd32c46beda425957339f1dbbcf8. * tmp bump allowed lag * faster * Revert "tmp bump allowed lag" This reverts commit b407702a0242074eb12abdff14e61789fc05109a. --- openpilot/selfdrive/modeld/models/big_driving_supercombo.onnx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openpilot/selfdrive/modeld/models/big_driving_supercombo.onnx b/openpilot/selfdrive/modeld/models/big_driving_supercombo.onnx index de84325912..4a04bd7833 100644 --- a/openpilot/selfdrive/modeld/models/big_driving_supercombo.onnx +++ b/openpilot/selfdrive/modeld/models/big_driving_supercombo.onnx @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:471f372751d5931e939320c211e35b7255f8fa8015125b3b3fd48ef43020257e -size 195490097 +oid sha256:a501760a9d1d5fef0eab2b8c5d122d06124fc26dc8e0782e0aa94b82a208f0ff +size 1757355221 From 8e0ba7a91e5a63585ba06c314a339a1854416c55 Mon Sep 17 00:00:00 2001 From: Jimmy <9859727+Quantizr@users.noreply.github.com> Date: Wed, 1 Jul 2026 17:17:25 -0700 Subject: [PATCH 100/151] modeld: use correct intrinsics for extra transform when wide camera disabled (#38239) use correct intrinsics for extra transform when wide camera disabled --- openpilot/selfdrive/modeld/modeld.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openpilot/selfdrive/modeld/modeld.py b/openpilot/selfdrive/modeld/modeld.py index 115873158f..7c70cdb14d 100755 --- a/openpilot/selfdrive/modeld/modeld.py +++ b/openpilot/selfdrive/modeld/modeld.py @@ -249,7 +249,8 @@ def main(demo=False): device_from_calib_euler = np.array(sm["liveCalibration"].rpyCalib, dtype=np.float32) dc = DEVICE_CAMERAS[(str(sm['deviceState'].deviceType), str(sm['roadCameraState'].sensor))] model_transform_main = get_warp_matrix(device_from_calib_euler, dc.ecam.intrinsics if main_wide_camera else dc.fcam.intrinsics, False).astype(np.float32) - model_transform_extra = get_warp_matrix(device_from_calib_euler, dc.ecam.intrinsics, True).astype(np.float32) + has_wide_camera = use_extra_client or main_wide_camera + model_transform_extra = get_warp_matrix(device_from_calib_euler, dc.ecam.intrinsics if has_wide_camera else dc.fcam.intrinsics, True).astype(np.float32) live_calib_seen = True traffic_convention = np.zeros(2) From 4c5bef5840cca038b17f51d0a26e91825f7c24ed Mon Sep 17 00:00:00 2001 From: YassineYousfi Date: Wed, 1 Jul 2026 18:50:52 -0700 Subject: [PATCH 101/151] rm modeld/models README --- openpilot/selfdrive/modeld/models/README.md | 64 --------------------- 1 file changed, 64 deletions(-) diff --git a/openpilot/selfdrive/modeld/models/README.md b/openpilot/selfdrive/modeld/models/README.md index ce84b1e28f..0055a0f1e3 100644 --- a/openpilot/selfdrive/modeld/models/README.md +++ b/openpilot/selfdrive/modeld/models/README.md @@ -1,66 +1,2 @@ ## Neural networks in openpilot To view the architecture of the ONNX networks, you can use [netron](https://netron.app/) - -## Driving Model (vision model + temporal policy model) -### Vision inputs (Full size: 799906 x float32) -* **image stream** - * Two consecutive images (256 * 512 * 3 in RGB) recorded at 20 Hz : 393216 = 2 * 6 * 128 * 256 - * Each 256 * 512 image is represented in YUV420 with 6 channels : 6 * 128 * 256 - * Channels 0,1,2,3 represent the full-res Y channel and are represented in numpy as Y[::2, ::2], Y[::2, 1::2], Y[1::2, ::2], and Y[1::2, 1::2] - * Channel 4 represents the half-res U channel - * Channel 5 represents the half-res V channel -* **wide image stream** - * Two consecutive images (256 * 512 * 3 in RGB) recorded at 20 Hz : 393216 = 2 * 6 * 128 * 256 - * Each 256 * 512 image is represented in YUV420 with 6 channels : 6 * 128 * 256 - * Channels 0,1,2,3 represent the full-res Y channel and are represented in numpy as Y[::2, ::2], Y[::2, 1::2], Y[1::2, ::2], and Y[1::2, 1::2] - * Channel 4 represents the half-res U channel - * Channel 5 represents the half-res V channel -### Policy inputs -* **desire** - * one-hot encoded buffer to command model to execute certain actions, bit needs to be sent for the past 5 seconds (at 20FPS) : 100 * 8 -* **traffic convention** - * one-hot encoded vector to tell model whether traffic is right-hand or left-hand traffic : 2 -* **lateral control params** - * speed and steering delay for predicting the desired curvature: 2 -* **previous desired curvatures** - * vector of previously predicted desired curvatures: 100 * 1 -* **feature buffer** - * a buffer of intermediate features including the current feature to form a 5 seconds temporal context (at 20FPS) : 100 * 512 - - -### Driving Model output format (Full size: XXX x float32) -Refer to **slice_outputs** and **parse_vision_outputs/parse_policy_outputs** in modeld. - - -## Driver Monitoring Model -* .onnx model can be run with onnx runtimes -* .dlc file is a pre-quantized model and only runs on qualcomm DSPs - -### input format -* single image W = 1440 H = 960 luminance channel (Y) from the planar YUV420 format: - * full input size is 1440 * 960 = 1382400 - * normalized ranging from 0.0 to 1.0 in float32 (onnx runner) or ranging from 0 to 255 in uint8 (snpe runner) -* camera calibration angles (roll, pitch, yaw) from liveCalibration: 3 x float32 inputs - -### output format -* 84 x float32 outputs = 2 + 41 * 2 ([parsing example](https://github.com/commaai/openpilot/blob/22ce4e17ba0d3bfcf37f8255a4dd1dc683fe0c38/openpilot/selfdrive/modeld/models/dmonitoring.cc#L33)) - * for each person in the front seats (2 * 41) - * face pose: 12 = 6 + 6 - * face orientation [pitch, yaw, roll] in camera frame: 3 - * face position [dx, dy] relative to image center: 2 - * normalized face size: 1 - * standard deviations for above outputs: 6 - * face visible probability: 1 - * eyes: 20 = (8 + 1) + (8 + 1) + 1 + 1 - * eye position and size, and their standard deviations: 8 - * eye visible probability: 1 - * eye closed probability: 1 - * wearing sunglasses probability: 1 - * face occluded probability: 1 - * touching wheel probability: 1 - * paying attention probability: 1 - * (deprecated) distracted probabilities: 2 - * using phone probability: 1 - * distracted probability: 1 - * common outputs 1 - * left hand drive probability: 1 From 4532320fb3b76417df39c6b78a84f250da9a31ba Mon Sep 17 00:00:00 2001 From: YassineYousfi Date: Wed, 1 Jul 2026 18:52:11 -0700 Subject: [PATCH 102/151] desire: enter preLaneChange if blinker before engaged (#38276) --- openpilot/selfdrive/controls/lib/desire_helper.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpilot/selfdrive/controls/lib/desire_helper.py b/openpilot/selfdrive/controls/lib/desire_helper.py index cbf4d95d38..3705823b70 100644 --- a/openpilot/selfdrive/controls/lib/desire_helper.py +++ b/openpilot/selfdrive/controls/lib/desire_helper.py @@ -68,7 +68,7 @@ class DesireHelper: self.lane_change_state = LaneChangeState.off self.lane_change_direction = LaneChangeDirection.none - self.prev_one_blinker = one_blinker + self.prev_one_blinker = one_blinker and lateral_active self.desire = log.Desire.none if self.lane_change_state == LaneChangeState.laneChangeStarting: From 9d03e737dde14f9985862a915ce9b3371f03a142 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Thu, 2 Jul 2026 14:41:36 -0700 Subject: [PATCH 103/151] test_onroad: fix service timing threshold --- openpilot/selfdrive/test/test_onroad.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openpilot/selfdrive/test/test_onroad.py b/openpilot/selfdrive/test/test_onroad.py index b2192b0d5a..b15d890452 100644 --- a/openpilot/selfdrive/test/test_onroad.py +++ b/openpilot/selfdrive/test/test_onroad.py @@ -175,8 +175,9 @@ class TestOnroad: if s in ('ubloxGnss', 'ubloxRaw', 'gnssMeasurements', 'gpsLocation', 'gpsLocationExternal', 'qcomGnss'): continue + duration = TEST_DURATION - 5.0 # subtract some selfdrived initializing time with subtests.test(service=s): - assert len(msgs) >= math.floor(SERVICE_LIST[s].frequency*int(TEST_DURATION*0.8)) + assert len(msgs) >= math.floor(SERVICE_LIST[s].frequency*int(duration*0.8)) def test_manager_starting_time(self): st = self.ts['managerState']['t'][0] From 07ec389f4ca1caf720e3af56fdc563465b86e978 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Thu, 2 Jul 2026 18:48:53 -0700 Subject: [PATCH 104/151] bump ty (#38277) * bump ty * cleanup --- .../cereal/messaging/tests/test_services.py | 6 +-- openpilot/common/hardware/tici/agnos.py | 2 +- openpilot/common/hardware/tici/hardware.py | 4 +- openpilot/common/utils.py | 4 +- .../selfdrive/ui/layouts/settings/software.py | 8 ++-- .../ui/mici/layouts/settings/software.py | 8 ++-- .../hardware/tests/test_fan_controller.py | 24 +++++------- .../system/sensord/tests/test_sensord.py | 3 +- openpilot/system/ui/mici_reset.py | 10 ++--- openpilot/system/ui/tici_reset.py | 12 +++--- .../tools/camerastream/compressed_vipc.py | 1 + uv.lock | 38 +++++++++---------- 12 files changed, 59 insertions(+), 61 deletions(-) diff --git a/openpilot/cereal/messaging/tests/test_services.py b/openpilot/cereal/messaging/tests/test_services.py index debe891375..9ae7c3d840 100644 --- a/openpilot/cereal/messaging/tests/test_services.py +++ b/openpilot/cereal/messaging/tests/test_services.py @@ -1,6 +1,6 @@ -import os +import subprocess import tempfile -from typing import Dict + from openpilot.common.parameterized import parameterized import openpilot.cereal.services as services @@ -17,5 +17,5 @@ class TestServices: def test_generated_header(self): with tempfile.NamedTemporaryFile(suffix=".h") as f: - ret = os.system(f"python3 {services.__file__} > {f.name} && clang++ {f.name} -std=c++11") + ret = subprocess.run(f"python3 {services.__file__} > {f.name} && clang++ {f.name} -std=c++11", shell=True).returncode assert ret == 0, "generated services header is not valid C" diff --git a/openpilot/common/hardware/tici/agnos.py b/openpilot/common/hardware/tici/agnos.py index 0210821a0d..e1f62c841c 100755 --- a/openpilot/common/hardware/tici/agnos.py +++ b/openpilot/common/hardware/tici/agnos.py @@ -228,7 +228,7 @@ def flash_agnos_update(manifest_path: str, target_slot_number: int, cloudlog, st cloudlog.info(f"Target slot {target_slot_number}") # set target slot as unbootable - os.system(f"abctl --set_unbootable {target_slot_number}") + subprocess.run(f"abctl --set_unbootable {target_slot_number}", shell=True) for partition in update: success = False diff --git a/openpilot/common/hardware/tici/hardware.py b/openpilot/common/hardware/tici/hardware.py index 1a2cb51d05..773cbd4bed 100644 --- a/openpilot/common/hardware/tici/hardware.py +++ b/openpilot/common/hardware/tici/hardware.py @@ -241,7 +241,7 @@ class Tici(HardwareBase): return (self.read_param_file("/sys/class/power_supply/bms/voltage_now", int) * self.read_param_file("/sys/class/power_supply/bms/current_now", int) / 1e12) def shutdown(self): - os.system("sudo poweroff") + subprocess.run("sudo poweroff", shell=True) def get_thermal_config(self): intake, exhaust, gnss, bottomSoc = None, None, None, None @@ -335,7 +335,7 @@ class Tici(HardwareBase): self.amplifier.initialize_configuration() # Allow hardwared to write engagement status to kmsg - os.system("sudo chmod a+w /dev/kmsg") + subprocess.run("sudo chmod a+w /dev/kmsg", shell=True) # Ensure fan gpio is enabled so fan runs until shutdown, also turned on at boot by the ABL gpio_init(GPIO.SOM_ST_IO, True) diff --git a/openpilot/common/utils.py b/openpilot/common/utils.py index 183363f39d..22d024fca7 100644 --- a/openpilot/common/utils.py +++ b/openpilot/common/utils.py @@ -37,13 +37,13 @@ def sudo_write(val: str, path: str) -> None: with open(path, 'w') as f: f.write(str(val)) except PermissionError: - os.system(f"sudo chmod a+w {path}") + subprocess.run(f"sudo chmod a+w {path}", shell=True) try: with open(path, 'w') as f: f.write(str(val)) except PermissionError: # fallback for debugfs files - os.system(f"sudo su -c 'echo {val} > {path}'") + subprocess.run(f"sudo su -c 'echo {val} > {path}'", shell=True) def sudo_read(path: str) -> str: diff --git a/openpilot/selfdrive/ui/layouts/settings/software.py b/openpilot/selfdrive/ui/layouts/settings/software.py index 3b05eef549..bf986e614e 100644 --- a/openpilot/selfdrive/ui/layouts/settings/software.py +++ b/openpilot/selfdrive/ui/layouts/settings/software.py @@ -1,4 +1,4 @@ -import os +import subprocess import time import datetime from openpilot.common.time_helpers import system_time_valid @@ -158,12 +158,12 @@ class SoftwareLayout(Widget): # Start checking for updates self._waiting_for_updater = True self._waiting_start_ts = time.monotonic() - os.system("pkill -SIGUSR1 -f openpilot.system.updated.updated") + subprocess.run("pkill -SIGUSR1 -f openpilot.system.updated.updated", shell=True) else: # Start downloading self._waiting_for_updater = True self._waiting_start_ts = time.monotonic() - os.system("pkill -SIGHUP -f openpilot.system.updated.updated") + subprocess.run("pkill -SIGHUP -f openpilot.system.updated.updated", shell=True) def _on_uninstall(self): def handle_uninstall_confirmation(result: DialogResult): @@ -197,7 +197,7 @@ class SoftwareLayout(Widget): selection = self._branch_dialog.selection ui_state.params.put("UpdaterTargetBranch", selection, block=True) self._branch_btn.action_item.set_value(selection) - os.system("pkill -SIGUSR1 -f openpilot.system.updated.updated") + subprocess.run("pkill -SIGUSR1 -f openpilot.system.updated.updated", shell=True) self._branch_dialog = None self._branch_dialog = MultiOptionDialog(tr("Select a branch"), branches, current_target, callback=handle_selection) diff --git a/openpilot/selfdrive/ui/mici/layouts/settings/software.py b/openpilot/selfdrive/ui/mici/layouts/settings/software.py index 115b560cc5..bd4b966f49 100644 --- a/openpilot/selfdrive/ui/mici/layouts/settings/software.py +++ b/openpilot/selfdrive/ui/mici/layouts/settings/software.py @@ -1,4 +1,4 @@ -import os +import subprocess import threading import pyray as rl from enum import IntEnum @@ -103,9 +103,9 @@ class CheckUpdateButton(BigButton): def run(): if self.get_value() == "download update": - os.system("pkill -SIGHUP -f openpilot.system.updated.updated") + subprocess.run("pkill -SIGHUP -f openpilot.system.updated.updated", shell=True) else: - os.system("pkill -SIGUSR1 -f openpilot.system.updated.updated") + subprocess.run("pkill -SIGUSR1 -f openpilot.system.updated.updated", shell=True) threading.Thread(target=run, daemon=True).start() @@ -251,7 +251,7 @@ class TargetBranchButton(BigButton): def _on_select(self, branch: str): ui_state.params.put("UpdaterTargetBranch", branch, block=True) self.set_value(branch) - os.system("pkill -SIGUSR1 -f openpilot.system.updated.updated") + subprocess.run("pkill -SIGUSR1 -f openpilot.system.updated.updated", shell=True) class SoftwareLayoutMici(NavScroller): diff --git a/openpilot/system/hardware/tests/test_fan_controller.py b/openpilot/system/hardware/tests/test_fan_controller.py index ee39a24f87..e1aceeb081 100644 --- a/openpilot/system/hardware/tests/test_fan_controller.py +++ b/openpilot/system/hardware/tests/test_fan_controller.py @@ -4,10 +4,6 @@ from openpilot.system.hardware.fan_controller import FanController ALL_CONTROLLERS = [FanController] -def patched_controller(mocker, controller_class): - mocker.patch("os.system", new=mocker.Mock()) - return controller_class(2) - class TestFanController: def wind_up(self, controller, ignition=True): for _ in range(1000): @@ -18,32 +14,32 @@ class TestFanController: controller.update(10, ignition) @pytest.mark.parametrize("controller_class", ALL_CONTROLLERS) - def test_hot_onroad(self, mocker, controller_class): - controller = patched_controller(mocker, controller_class) + def test_hot_onroad(self, controller_class): + controller = controller_class(2) self.wind_up(controller) assert controller.update(100, True) >= 70 @pytest.mark.parametrize("controller_class", ALL_CONTROLLERS) - def test_offroad_limits(self, mocker, controller_class): - controller = patched_controller(mocker, controller_class) + def test_offroad_limits(self, controller_class): + controller = controller_class(2) self.wind_up(controller) assert controller.update(100, False) <= 30 @pytest.mark.parametrize("controller_class", ALL_CONTROLLERS) - def test_no_fan_wear(self, mocker, controller_class): - controller = patched_controller(mocker, controller_class) + def test_no_fan_wear(self, controller_class): + controller = controller_class(2) self.wind_down(controller) assert controller.update(10, False) == 0 @pytest.mark.parametrize("controller_class", ALL_CONTROLLERS) - def test_limited(self, mocker, controller_class): - controller = patched_controller(mocker, controller_class) + def test_limited(self, controller_class): + controller = controller_class(2) self.wind_up(controller, True) assert controller.update(100, True) == 100 @pytest.mark.parametrize("controller_class", ALL_CONTROLLERS) - def test_windup_speed(self, mocker, controller_class): - controller = patched_controller(mocker, controller_class) + def test_windup_speed(self, controller_class): + controller = controller_class(2) self.wind_down(controller, True) for _ in range(10): controller.update(90, True) diff --git a/openpilot/system/sensord/tests/test_sensord.py b/openpilot/system/sensord/tests/test_sensord.py index 23811189f6..fc4e3061bc 100644 --- a/openpilot/system/sensord/tests/test_sensord.py +++ b/openpilot/system/sensord/tests/test_sensord.py @@ -1,4 +1,5 @@ import os +import subprocess import pytest import time import numpy as np @@ -61,7 +62,7 @@ class TestSensord: os.environ["LSM_SELF_TEST"] = "1" # read initial sensor values every test case can use - os.system("pkill -f \\\\./sensord") + subprocess.run("pkill -f \\\\./sensord", shell=True) try: managed_processes["sensord"].start() cls.sample_secs = int(os.getenv("SAMPLE_SECS", "10")) diff --git a/openpilot/system/ui/mici_reset.py b/openpilot/system/ui/mici_reset.py index 90de7843f9..97ecaf7024 100755 --- a/openpilot/system/ui/mici_reset.py +++ b/openpilot/system/ui/mici_reset.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -import os +import subprocess import sys import time import threading @@ -105,12 +105,12 @@ class Reset(Scroller): return # Removing data and formatting - rm = os.system("sudo rm -rf /data/*") - os.system(f"sudo umount {USERDATA}") - fmt = os.system(f"yes | sudo mkfs.ext4 {USERDATA}") + rm = subprocess.run("sudo rm -rf /data/*", shell=True).returncode + subprocess.run(f"sudo umount {USERDATA}", shell=True) + fmt = subprocess.run(f"yes | sudo mkfs.ext4 {USERDATA}", shell=True).returncode if rm == 0 or fmt == 0: - os.system("sudo reboot") + subprocess.run("sudo reboot", shell=True) else: self._reset_failed = True diff --git a/openpilot/system/ui/tici_reset.py b/openpilot/system/ui/tici_reset.py index cb5441a406..569faf45fe 100755 --- a/openpilot/system/ui/tici_reset.py +++ b/openpilot/system/ui/tici_reset.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -import os +import subprocess import sys import threading import time @@ -37,19 +37,19 @@ class Reset(Widget): self._reset_state = ResetState.NONE self._cancel_button = Button("Cancel", gui_app.request_close) self._confirm_button = Button("Confirm", self._confirm, button_style=ButtonStyle.PRIMARY) - self._reboot_button = Button("Reboot", lambda: os.system("sudo reboot")) + self._reboot_button = Button("Reboot", lambda: subprocess.run("sudo reboot", shell=True)) def _do_erase(self): if PC: return # Removing data and formatting - rm = os.system("sudo rm -rf /data/*") - os.system(f"sudo umount {USERDATA}") - fmt = os.system(f"yes | sudo mkfs.ext4 {USERDATA}") + rm = subprocess.run("sudo rm -rf /data/*", shell=True).returncode + subprocess.run(f"sudo umount {USERDATA}", shell=True) + fmt = subprocess.run(f"yes | sudo mkfs.ext4 {USERDATA}", shell=True).returncode if rm == 0 or fmt == 0: - os.system("sudo reboot") + subprocess.run("sudo reboot", shell=True) else: self._reset_state = ResetState.FAILED diff --git a/openpilot/tools/camerastream/compressed_vipc.py b/openpilot/tools/camerastream/compressed_vipc.py index 0b96223e8e..35e9d3dab2 100755 --- a/openpilot/tools/camerastream/compressed_vipc.py +++ b/openpilot/tools/camerastream/compressed_vipc.py @@ -1,5 +1,6 @@ #!/usr/bin/env python3 import av +import av.video.format import os import sys import argparse diff --git a/uv.lock b/uv.lock index 0804481dcd..8a5049acd5 100644 --- a/uv.lock +++ b/uv.lock @@ -1280,27 +1280,27 @@ wheels = [ [[package]] name = "ty" -version = "0.0.51" +version = "0.0.56" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/7e/ce/352fcdba5c72ea20e5d2e46e28809cdb617575b71209d971eff2ace8e6c4/ty-0.0.51.tar.gz", hash = "sha256:b90172d46365bb9d51a7011cbb5c60cc4f514f42c86635df6c092b717f85e1ac", size = 5953151, upload-time = "2026-06-19T01:48:58.015Z" } +sdist = { url = "https://files.pythonhosted.org/packages/55/07/fb29aea5235b0aa8ecfc4d1cc6ddf9fba8b863d67d96c6d345694d644c43/ty-0.0.56.tar.gz", hash = "sha256:84d114dc3796361c0fc72945016eabd74d46b9ee64f198cb0e485719704681e5", size = 6050123, upload-time = "2026-07-01T16:44:56.036Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/2b/8f/8fe7cab79a45320b2cdcd602f16d44c8108d2f418ff7ec316c6212f1f0cc/ty-0.0.51-py3-none-linux_armv6l.whl", hash = "sha256:947986bd82d324b3a5c58ce03f1dad160cdf36443d3e8f64b3484b861ba9bc64", size = 11884805, upload-time = "2026-06-19T01:48:20.184Z" }, - { url = "https://files.pythonhosted.org/packages/fa/b4/56fdc39a3f44c0564fd157e1e59e1f9c3fc5ba57ae4472ded85c67c63d74/ty-0.0.51-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:25a5b31e6f23fd5dc63ad29087ded09932409e4154e2fe07bbaed015035990bb", size = 11633593, upload-time = "2026-06-19T01:48:22.998Z" }, - { url = "https://files.pythonhosted.org/packages/33/57/136e83f24fc04f5afdcabff42f40fa27eae5ac3f0e3f12627d072a55f679/ty-0.0.51-py3-none-macosx_11_0_arm64.whl", hash = "sha256:2faed19a8f1505370de071c008df52a994fc03a204f3267c3a33a32ca26f854f", size = 11063076, upload-time = "2026-06-19T01:48:25.223Z" }, - { url = "https://files.pythonhosted.org/packages/32/f8/5d32f0df5692446440ab781b9b119aa3e0c0dbfa78c583fe9be8417d54fa/ty-0.0.51-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:08adbe53fb8bc9e7f00e89bf1d3c875a02cda76d83f109d2e6ab1ff35a7bfa8c", size = 11579542, upload-time = "2026-06-19T01:48:27.302Z" }, - { url = "https://files.pythonhosted.org/packages/7f/0c/4f54ef338e9623886809ecd508931b0cd5b3aba1e591586a2f6aeaa8bd11/ty-0.0.51-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dc5e93695ab5dcbf1eef663aee60ec23a413547cc9cb06adcb0d842e9166bd0f", size = 11676189, upload-time = "2026-06-19T01:48:29.518Z" }, - { url = "https://files.pythonhosted.org/packages/56/27/31729066f9b9d3596941edaf267894eefc0b30df4518f003dba5f7276258/ty-0.0.51-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:abd92913bc90d1705ef9391ff8c6822b61e2e827fa295eb30bf0dfabcf815645", size = 12188154, upload-time = "2026-06-19T01:48:31.68Z" }, - { url = "https://files.pythonhosted.org/packages/2f/38/d4301aa12d2283c7130908baf1417a37dfe3e10f5669cb4ce2853c2540b4/ty-0.0.51-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:429a997394dac73870d71b87cc90efc54da3efaf319e72ca18aeef35a78aef90", size = 12780597, upload-time = "2026-06-19T01:48:33.839Z" }, - { url = "https://files.pythonhosted.org/packages/c1/52/4b2e67e53f126d39abe201bd2299e467e27463a284e965ad195cbc217fa0/ty-0.0.51-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:62d94f06e8c317e89b6884f2bde443040e596b88c7c79bd944c84c105b06257a", size = 12491115, upload-time = "2026-06-19T01:48:36.169Z" }, - { url = "https://files.pythonhosted.org/packages/74/50/aabfe55c132ebe72b4d639cbf772d931e11b0990d29c1f691922b6ccabc1/ty-0.0.51-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8f52952cff665bc52a36147e610c10f5699d30007d7a14ab7f345cff93476ff", size = 12230135, upload-time = "2026-06-19T01:48:38.445Z" }, - { url = "https://files.pythonhosted.org/packages/0d/1b/9aa428052dbed91c50919cd080426a313cf20ce14c6bfe2b71345e548671/ty-0.0.51-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:c1bd1355aee86af01e4e21b0bc16fc460fb05905761f0d8b8d70841de0feade8", size = 12468123, upload-time = "2026-06-19T01:48:40.47Z" }, - { url = "https://files.pythonhosted.org/packages/0b/5a/f6ce69f2575259386c950c40e02578d0902760cb61f95045e9971182c24e/ty-0.0.51-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:79d1877e93460f936bc10ed1a31525702b7ce51075763ccba993be17f0b9e905", size = 11541672, upload-time = "2026-06-19T01:48:42.635Z" }, - { url = "https://files.pythonhosted.org/packages/35/3a/2af48924a683e959e95e5cc4dc88e5a8595206a0812b869032b95196f2b0/ty-0.0.51-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:cc233a6235fb23e2a44b14731a10043e37ba2f30f2c361cf49ad3633c5b9da9c", size = 11694015, upload-time = "2026-06-19T01:48:44.819Z" }, - { url = "https://files.pythonhosted.org/packages/a4/12/899875d8a60b198c8121cb92ce18e18cc072d23ca2130fcdaa176383ef72/ty-0.0.51-py3-none-musllinux_1_2_i686.whl", hash = "sha256:bc7459348a253247bbfb2669a021e614281b86bbea24c36112b8a6e1a2499a16", size = 11832856, upload-time = "2026-06-19T01:48:47.028Z" }, - { url = "https://files.pythonhosted.org/packages/e6/a2/88f681d826d97cc96ef9f6cadd4935f775758944cee07340aa46113bce28/ty-0.0.51-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:49a21237f6fd1de56beaff0a3e85fe022a09a3401e67e3abec41ce838a5d4d2e", size = 12333449, upload-time = "2026-06-19T01:48:49.091Z" }, - { url = "https://files.pythonhosted.org/packages/f8/61/535a4163b4452c6978c31fedfd7b5803cf3a2253e9455cde350f86638d6a/ty-0.0.51-py3-none-win32.whl", hash = "sha256:61b4b6a003c3ebe53a63a1125c9b6542aa01bc1b6c9a235d01ee328d000d61a9", size = 11177338, upload-time = "2026-06-19T01:48:51.433Z" }, - { url = "https://files.pythonhosted.org/packages/aa/4d/2334fbb74291a20129fa7aaa8f789619ec9b6883b27f997b8baa27e4674f/ty-0.0.51-py3-none-win_amd64.whl", hash = "sha256:608d417cd1eaf79bcbd713d9830d5e3db9d57ec225c3af3e4ac9a9ff66b45d70", size = 12325675, upload-time = "2026-06-19T01:48:53.774Z" }, - { url = "https://files.pythonhosted.org/packages/50/b5/d49096cd5f3694becb86a5a6ccd0f229ead695fc7430d6bc4dd0a104c6fe/ty-0.0.51-py3-none-win_arm64.whl", hash = "sha256:62ced5e380284f12b2dc4802a3e4ed3dac39913fc6719afde7978814a4c7f169", size = 11657350, upload-time = "2026-06-19T01:48:55.904Z" }, + { url = "https://files.pythonhosted.org/packages/dc/48/bce79e7ca5c1cc529d3e0d37ddd1121aea4b68a4f749974ad1cc77161871/ty-0.0.56-py3-none-linux_armv6l.whl", hash = "sha256:186d4a53e15747c947e1ec3d7eec8e345d8e40a1ca10e634c585db52497e87dd", size = 11643066, upload-time = "2026-07-01T16:44:18.374Z" }, + { url = "https://files.pythonhosted.org/packages/80/d1/22555d8a1d719661f10050f3865d877bbf497da908961c75fe22217dd18a/ty-0.0.56-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:aae1a980fd9535da0469b7ba2b2e1b54a907743a5e0f442dd57eee9f5bfd034c", size = 11407487, upload-time = "2026-07-01T16:44:20.956Z" }, + { url = "https://files.pythonhosted.org/packages/cf/2d/b3b7a74ce8bc59ef48843ad80179bb0d9598bbd6cfc0d11d519bdf6b1352/ty-0.0.56-py3-none-macosx_11_0_arm64.whl", hash = "sha256:afd3058c0a6c5f241e814734f133008c93ee805f61c9cf4ce7412b8822b5d9ad", size = 10962270, upload-time = "2026-07-01T16:44:22.959Z" }, + { url = "https://files.pythonhosted.org/packages/64/ac/6c2fd7de0304a8a7218a756af74f7e62a5e8540fdb175e0a869e51042345/ty-0.0.56-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:058b52f7a823ac13aae3cae30809dd6b5145794b64d8478f9ef38c75d79b4483", size = 11471406, upload-time = "2026-07-01T16:44:25.327Z" }, + { url = "https://files.pythonhosted.org/packages/50/b6/11d861156861c03c7726b74558f9a0e0092661aff83a4fda1279df28c425/ty-0.0.56-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2c66e00c1522add1f2bbdd2e45828c953b35c306b7bef03ec9169c75a63699a0", size = 11445612, upload-time = "2026-07-01T16:44:27.531Z" }, + { url = "https://files.pythonhosted.org/packages/fb/ba/09df108582090f3c0770ec4bc8675affed60248f6793a78d909be16211d9/ty-0.0.56-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40903d71c669a30691b5a5d5728056c7877a1bd6be4f233a38883a8b28cf34d7", size = 12093889, upload-time = "2026-07-01T16:44:29.548Z" }, + { url = "https://files.pythonhosted.org/packages/d7/f7/dbb4b4ccb69cd64c209ae55b1ab788ace8222c2bc1f6845be9e7cbedbf25/ty-0.0.56-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:63fe3947fe0c46c69a7d950e6832ee70a9ec17321fefbff3d2e3c20baf9e5bd0", size = 12666337, upload-time = "2026-07-01T16:44:31.586Z" }, + { url = "https://files.pythonhosted.org/packages/86/e9/73f903fe4a3d9ea02f26f57c1eb07e3b1029ec92b0e8c2364718893440e3/ty-0.0.56-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:71a0c1a72f9854532e710e119b6871ffe4542c8a65146f1f65dcd78fecd885b4", size = 12280247, upload-time = "2026-07-01T16:44:33.637Z" }, + { url = "https://files.pythonhosted.org/packages/d6/90/cebd222495832f1a00dcd321ba25f3cab804221a4991b992c2178bec68ee/ty-0.0.56-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70d1665596494e24d8ebd198438872b5a56ec3cae5f2bcf6c673be797acc4e3c", size = 11991107, upload-time = "2026-07-01T16:44:36.122Z" }, + { url = "https://files.pythonhosted.org/packages/b7/07/8f7337a07250f42d975cdb6decf47fc5b421e6c7da5e3e7be1e85f63a7e5/ty-0.0.56-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:778f99e51558afc1dbbe48ee38ab6aae7b31390ed8c1a1ef1499b295e9f1e82f", size = 12298970, upload-time = "2026-07-01T16:44:38.243Z" }, + { url = "https://files.pythonhosted.org/packages/3c/b9/a52cd59034a48f5f18c6b155cc2cc36861d874b6d0af204b12c898024c3d/ty-0.0.56-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:867bc5708e0066bb4ff6c7db524bd5deea2676c62bfe71d3303138b3be850af0", size = 11425683, upload-time = "2026-07-01T16:44:40.473Z" }, + { url = "https://files.pythonhosted.org/packages/1d/2e/48e42d33357d52eefb695c0c3fcfc96879b73668a7447d1d1e0ad774fedc/ty-0.0.56-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:a6012f4189c928edb330a37deb9930f982380bd4aa7c4b8e0428eec9651c7551", size = 11469258, upload-time = "2026-07-01T16:44:42.513Z" }, + { url = "https://files.pythonhosted.org/packages/d5/01/ad1b4138be1e3fa97863af3925aa2134f17a593240c35dc38c3429fb5ad1/ty-0.0.56-py3-none-musllinux_1_2_i686.whl", hash = "sha256:8ee83de1a7ff4cc32837ec06134ce391d441bc5b35ecd8d3cfe053f120f3e4c1", size = 11758736, upload-time = "2026-07-01T16:44:44.567Z" }, + { url = "https://files.pythonhosted.org/packages/09/34/9d81967ff240eaa57e9249728ef7b7790747cf6d3c9a98ec86b2cfdcc8ee/ty-0.0.56-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:62619b3b0e2c6248ef30d3f0e2f2217ae9893040585be07f32324242f197cd6f", size = 12100242, upload-time = "2026-07-01T16:44:46.584Z" }, + { url = "https://files.pythonhosted.org/packages/c3/36/f51d4666d2de6cf33c1f3a1fcc4bb6b70b197dd6ceaa491eef71d78fe8e8/ty-0.0.56-py3-none-win32.whl", hash = "sha256:b30687bb5cd9729d34c889a289edf32770388d9bb05243e534e723fb45e0381b", size = 11093759, upload-time = "2026-07-01T16:44:49.171Z" }, + { url = "https://files.pythonhosted.org/packages/5e/b4/8fb5d4acfa4afb152245b20fa263069a7547bd1f8e4bfca4eda280c897d7/ty-0.0.56-py3-none-win_amd64.whl", hash = "sha256:ad4c8c47b6f4e3f9ed3fc0b1a5d650088d229e17dd8f63c1826d6bbe94cc3235", size = 12100327, upload-time = "2026-07-01T16:44:51.26Z" }, + { url = "https://files.pythonhosted.org/packages/b8/fc/6a183e71edde90d0c35c2303f23f7a45b6891d1a2c45daf7b8f869831e19/ty-0.0.56-py3-none-win_arm64.whl", hash = "sha256:57538f273d444a5f1293fa7860e967178afe3917611fc5eff16b64e1204fe0d6", size = 11538780, upload-time = "2026-07-01T16:44:53.8Z" }, ] [[package]] From 70a6efb8fce329bf2b21e94d072850182235ea1a Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Thu, 2 Jul 2026 19:00:35 -0700 Subject: [PATCH 105/151] ci: update GitHub Actions to latest versions (#38278) * ci: update GitHub Actions to latest versions Bump all workflow actions to their latest releases, including major updates for checkout (v7), upload-artifact (v7), github-script (v9), action-download-artifact (v21), and thollander comment action (v3). * ci: pin third-party actions to commit SHAs Keep official GitHub actions on version tags, but pin community actions to immutable commit hashes for supply-chain safety. --- .github/workflows/auto_pr_review.yaml | 4 ++-- .github/workflows/diff_report.yaml | 14 ++++++------ .github/workflows/docs.yaml | 4 ++-- .github/workflows/jenkins-pr-trigger.yaml | 8 +++---- .github/workflows/model_review.yaml | 6 +++--- .github/workflows/release.yaml | 4 ++-- .github/workflows/repo-maintenance.yaml | 4 ++-- .github/workflows/tests.yaml | 26 +++++++++++------------ .github/workflows/ui_preview.yaml | 20 ++++++++--------- 9 files changed, 45 insertions(+), 45 deletions(-) diff --git a/.github/workflows/auto_pr_review.yaml b/.github/workflows/auto_pr_review.yaml index 99c3a258c6..9b67956484 100644 --- a/.github/workflows/auto_pr_review.yaml +++ b/.github/workflows/auto_pr_review.yaml @@ -11,7 +11,7 @@ jobs: pull-requests: write runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 with: submodules: false @@ -23,7 +23,7 @@ jobs: # Check PR target branch - name: check branch - uses: Vankka/pr-target-branch-action@def32ec9d93514138d6ac0132ee62e120a72aed5 + uses: Vankka/pr-target-branch-action@5da68a42bcb7b43d39104295a876a6f3f8d7908b if: github.repository == 'commaai/openpilot' env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/diff_report.yaml b/.github/workflows/diff_report.yaml index 2ddb850944..5ad7746fda 100644 --- a/.github/workflows/diff_report.yaml +++ b/.github/workflows/diff_report.yaml @@ -17,7 +17,7 @@ jobs: - name: Wait for process replay id: wait continue-on-error: true - uses: lewagon/wait-on-check-action@v1.3.4 + uses: lewagon/wait-on-check-action@1d57e2c51a58d812d2765e036a028b6bdb5a6154 with: ref: ${{ github.event.pull_request.head.sha }} check-name: process replay @@ -26,7 +26,7 @@ jobs: wait-interval: 20 - name: Download diff if: steps.wait.outcome == 'success' - uses: dawidd6/action-download-artifact@v6 + uses: dawidd6/action-download-artifact@b6e2e70617bc3265edd6dab6c906732b2f1ae151 with: github_token: ${{ secrets.GITHUB_TOKEN }} workflow: tests.yaml @@ -37,9 +37,9 @@ jobs: allow_forks: true - name: Comment on PR if: steps.wait.outcome == 'success' - uses: thollander/actions-comment-pull-request@v2 + uses: thollander/actions-comment-pull-request@24bffb9b452ba05a4f3f77933840a6a841d1b32b with: - filePath: diff_report.txt - comment_tag: diff_report - pr_number: ${{ github.event.number }} - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + file-path: diff_report.txt + comment-tag: diff_report + pr-number: ${{ github.event.number }} + github-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index d072cd71d1..2d7da672e7 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -22,7 +22,7 @@ jobs: steps: - uses: commaai/timeout@v1 - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 with: submodules: true @@ -34,7 +34,7 @@ jobs: python scripts/docs.py build # Push to docs.comma.ai - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 if: github.ref == 'refs/heads/master' && github.repository == 'commaai/openpilot' with: path: openpilot-docs diff --git a/.github/workflows/jenkins-pr-trigger.yaml b/.github/workflows/jenkins-pr-trigger.yaml index fdd26253fa..ebb14d5dba 100644 --- a/.github/workflows/jenkins-pr-trigger.yaml +++ b/.github/workflows/jenkins-pr-trigger.yaml @@ -11,7 +11,7 @@ jobs: contents: write steps: - name: Delete stale Jenkins branches - uses: actions/github-script@v8 + uses: actions/github-script@v9 with: script: | const cutoff = Date.now() - 24 * 60 * 60 * 1000; @@ -52,7 +52,7 @@ jobs: steps: - name: Check for trigger phrase id: check_comment - uses: actions/github-script@v8 + uses: actions/github-script@v9 with: script: | const triggerPhrase = "trigger-jenkins"; @@ -72,7 +72,7 @@ jobs: - name: Checkout repository if: steps.check_comment.outputs.result == 'true' - uses: actions/checkout@v6 + uses: actions/checkout@v7 with: ref: refs/pull/${{ github.event.issue.number }}/head @@ -86,7 +86,7 @@ jobs: - name: Delete trigger comment if: steps.check_comment.outputs.result == 'true' && always() - uses: actions/github-script@v8 + uses: actions/github-script@v9 with: script: | await github.rest.issues.deleteComment({ diff --git a/.github/workflows/model_review.yaml b/.github/workflows/model_review.yaml index 66f0398d09..82c732dc3b 100644 --- a/.github/workflows/model_review.yaml +++ b/.github/workflows/model_review.yaml @@ -16,11 +16,11 @@ jobs: if: github.repository == 'commaai/openpilot' steps: - name: Checkout - uses: actions/checkout@v6 + uses: actions/checkout@v7 with: submodules: true - name: Checkout master - uses: actions/checkout@v6 + uses: actions/checkout@v7 with: ref: master path: base @@ -36,7 +36,7 @@ jobs: echo "EOF" >> $GITHUB_OUTPUT - name: Post model report comment - uses: marocchino/sticky-pull-request-comment@baa7203ed60924babbe5dcd0ac8eae3b66ec5e16 + uses: marocchino/sticky-pull-request-comment@0ea0beb66eb9baf113663a64ec522f60e49231c0 with: header: model-review message: ${{ steps.report.outputs.content }} \ No newline at end of file diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 27faccae6e..02388f689f 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -15,14 +15,14 @@ jobs: steps: - name: Wait for green check mark if: ${{ github.event_name == 'schedule' }} - uses: lewagon/wait-on-check-action@ccfb013c15c8afb7bf2b7c028fb74dc5a068cccc + uses: lewagon/wait-on-check-action@1d57e2c51a58d812d2765e036a028b6bdb5a6154 with: ref: master wait-interval: 30 running-workflow-name: 'build master-ci' repo-token: ${{ secrets.GITHUB_TOKEN }} check-regexp: ^((?!.*(build prebuilt|create badges).*).)*$ - - uses: actions/checkout@v4 + - uses: actions/checkout@v7 with: submodules: true fetch-depth: 0 diff --git a/.github/workflows/repo-maintenance.yaml b/.github/workflows/repo-maintenance.yaml index 1a99852be1..a821f928ac 100644 --- a/.github/workflows/repo-maintenance.yaml +++ b/.github/workflows/repo-maintenance.yaml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest if: github.repository == 'commaai/openpilot' steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 with: submodules: true - run: ./tools/op.sh setup @@ -49,7 +49,7 @@ jobs: python openpilot/selfdrive/car/docs.py git add docs/CARS.md - name: Create Pull Request - uses: peter-evans/create-pull-request@c0f553fe549906ede9cf27b5156039d195d2ece0 + uses: peter-evans/create-pull-request@5f6978faf089d4d20b00c7766989d076bb2fc7f1 with: author: Vehicle Researcher token: ${{ secrets.ACTIONS_CREATE_PR_PAT }} diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 4fa3af3d5e..0b3d1c0d76 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -35,11 +35,11 @@ jobs: STRIPPED_DIR: /tmp/releasepilot PYTHONPATH: /tmp/releasepilot steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 with: submodules: true - name: Getting LFS files - uses: nick-fields/retry@7152eba30c6575329ac0576536151aca5a72780e + uses: nick-fields/retry@ad984534de44a9489a53aefd81eb77f87c70dc60 with: timeout_minutes: 2 max_attempts: 3 @@ -65,7 +65,7 @@ jobs: name: build macOS runs-on: ${{ ((github.repository == 'commaai/openpilot') && ((github.event_name != 'pull_request') || (github.event.pull_request.head.repo.full_name == 'commaai/openpilot'))) && 'namespace-profile-macos-8x14' || 'macos-latest' }} steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 with: submodules: true - name: Remove Homebrew from environment @@ -85,7 +85,7 @@ jobs: && fromJSON('["namespace-profile-amd64-8x16"]') || fromJSON('["ubuntu-24.04"]') }} steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 with: submodules: true - run: ./tools/op.sh setup @@ -102,7 +102,7 @@ jobs: && fromJSON('["namespace-profile-amd64-8x16"]') || fromJSON('["ubuntu-24.04"]') }} steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 with: submodules: true - run: ./tools/op.sh setup @@ -125,7 +125,7 @@ jobs: && fromJSON('["namespace-profile-amd64-8x16"]') || fromJSON('["ubuntu-24.04"]') }} steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 with: submodules: true - run: ./tools/op.sh setup @@ -142,14 +142,14 @@ jobs: - name: Print diff report if: always() run: cat openpilot/selfdrive/test/process_replay/diff_report.txt - - uses: actions/upload-artifact@v6 + - uses: actions/upload-artifact@v7 if: always() continue-on-error: true with: name: process_replay_diff.txt path: openpilot/selfdrive/test/process_replay/diff.txt - name: Upload diff report - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 if: always() && github.event_name == 'pull_request' continue-on-error: true with: @@ -157,7 +157,7 @@ jobs: path: openpilot/selfdrive/test/process_replay/diff_report.txt - name: Checkout ci-artifacts if: github.repository == 'commaai/openpilot' && github.ref == 'refs/heads/master' - uses: actions/checkout@v4 + uses: actions/checkout@v7 with: repository: commaai/ci-artifacts ssh-key: ${{ secrets.CI_ARTIFACTS_DEPLOY_KEY }} @@ -176,7 +176,7 @@ jobs: git commit -m "process-replay refs for ${{ github.repository }}@${{ github.sha }}" || echo "No changes to commit" - name: Push refs if: github.repository == 'commaai/openpilot' && github.ref == 'refs/heads/master' - uses: nick-fields/retry@7152eba30c6575329ac0576536151aca5a72780e + uses: nick-fields/retry@ad984534de44a9489a53aefd81eb77f87c70dc60 with: timeout_minutes: 2 max_attempts: 3 @@ -198,7 +198,7 @@ jobs: || fromJSON('["ubuntu-24.04"]') }} if: false # FIXME: Started to timeout recently steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 with: submodules: true - run: ./tools/op.sh setup @@ -219,7 +219,7 @@ jobs: && fromJSON('["namespace-profile-amd64-8x16"]') || fromJSON('["ubuntu-24.04"]') }} steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 with: submodules: true - run: ./tools/op.sh setup @@ -231,7 +231,7 @@ jobs: python3 openpilot/selfdrive/ui/tests/diff/replay.py python3 openpilot/selfdrive/ui/tests/diff/replay.py --big - name: Upload UI Report - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: name: ui-report-${{ inputs.run_number || '1' }}-${{ github.event_name == 'push' && github.ref == 'refs/heads/master' && 'master' || github.event.number }} path: openpilot/selfdrive/ui/tests/diff/report diff --git a/.github/workflows/ui_preview.yaml b/.github/workflows/ui_preview.yaml index 7bfaea63aa..20927740bb 100644 --- a/.github/workflows/ui_preview.yaml +++ b/.github/workflows/ui_preview.yaml @@ -34,12 +34,12 @@ jobs: pull-requests: write actions: read steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 with: submodules: true - name: Waiting for ui generation to end - uses: lewagon/wait-on-check-action@v1.3.4 + uses: lewagon/wait-on-check-action@1d57e2c51a58d812d2765e036a028b6bdb5a6154 with: ref: ${{ env.SHA }} check-name: ${{ env.UI_JOB_NAME }} @@ -53,7 +53,7 @@ jobs: echo "run_id=$(curl https://api.github.com/repos/${{ github.repository }}/commits/${{ env.SHA }}/check-runs | jq -r '.check_runs[] | select(.name == "${{ env.UI_JOB_NAME }}") | .html_url | capture("(?[0-9]+)") | .number')" >> $GITHUB_OUTPUT - name: Getting proposed ui - uses: dawidd6/action-download-artifact@v6 + uses: dawidd6/action-download-artifact@b6e2e70617bc3265edd6dab6c906732b2f1ae151 with: github_token: ${{ secrets.GITHUB_TOKEN }} run_id: ${{ steps.get_run_id.outputs.run_id }} @@ -62,7 +62,7 @@ jobs: path: ${{ github.workspace }}/pr_ui - name: Getting mici master ui - uses: actions/checkout@v6 + uses: actions/checkout@v7 with: repository: commaai/ci-artifacts ssh-key: ${{ secrets.CI_ARTIFACTS_DEPLOY_KEY }} @@ -70,7 +70,7 @@ jobs: ref: openpilot_master_ui_mici_raylib - name: Getting big master ui - uses: actions/checkout@v6 + uses: actions/checkout@v7 with: repository: commaai/ci-artifacts ssh-key: ${{ secrets.CI_ARTIFACTS_DEPLOY_KEY }} @@ -97,7 +97,7 @@ jobs: done - name: Setup FFmpeg - uses: AnimMouse/setup-ffmpeg@ae28d57dabbb148eff63170b6bf7f2b60062cbae + uses: AnimMouse/setup-ffmpeg@178e0b4a408f06ce40d896c3cd79f50fa6f8b0c3 - name: Finding diffs if: github.event_name == 'pull_request_target' @@ -164,12 +164,12 @@ jobs: - name: Comment on PR if: github.event_name == 'pull_request_target' - uses: thollander/actions-comment-pull-request@v2 + uses: thollander/actions-comment-pull-request@24bffb9b452ba05a4f3f77933840a6a841d1b32b with: message: | ## UI Preview ${{ steps.find_diff.outputs.COMMENT }} - comment_tag: run_id_ui_preview - pr_number: ${{ github.event.number }} - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + comment-tag: run_id_ui_preview + pr-number: ${{ github.event.number }} + github-token: ${{ secrets.GITHUB_TOKEN }} From 2aa934e7c2de0dcc72771168fcc1c53b342cbfce Mon Sep 17 00:00:00 2001 From: commaci-public <60409688+commaci-public@users.noreply.github.com> Date: Thu, 2 Jul 2026 19:04:06 -0700 Subject: [PATCH 106/151] [bot] Update Python packages (#38263) Update Python packages Co-authored-by: Vehicle Researcher --- opendbc_repo | 2 +- rednose_repo | 2 +- tinygrad_repo | 2 +- uv.lock | 192 +++++++++++++++++++++++++------------------------- 4 files changed, 98 insertions(+), 100 deletions(-) diff --git a/opendbc_repo b/opendbc_repo index 58b89559ed..8c0b1367c5 160000 --- a/opendbc_repo +++ b/opendbc_repo @@ -1 +1 @@ -Subproject commit 58b89559ede390a9a4b389f2276ab3863a3ecc52 +Subproject commit 8c0b1367c5178f919c05ae58a1dcf7439ed3eb37 diff --git a/rednose_repo b/rednose_repo index 7ffefa3d88..6c2abeb471 160000 --- a/rednose_repo +++ b/rednose_repo @@ -1 +1 @@ -Subproject commit 7ffefa3d8811a842f8ec97d311103ce3a45dfae0 +Subproject commit 6c2abeb471c830b38abb0f95d3aa348ca2b8dbc6 diff --git a/tinygrad_repo b/tinygrad_repo index f9c8c697d6..e6fbede157 160000 --- a/tinygrad_repo +++ b/tinygrad_repo @@ -1 +1 @@ -Subproject commit f9c8c697d6bfb76ba0bd79e15704ed376f0c45ec +Subproject commit e6fbede1576f0a201e0b2c112499552a61280abd diff --git a/uv.lock b/uv.lock index 8a5049acd5..cbfa688050 100644 --- a/uv.lock +++ b/uv.lock @@ -5,7 +5,7 @@ requires-python = ">=3.12.3, <3.13" [[package]] name = "acados" version = "0.2.2" -source = { git = "https://github.com/commaai/dependencies.git?subdirectory=acados&rev=release-acados#acfa1f7978b450d30fd346d61ae10e18bb4434c7" } +source = { git = "https://github.com/commaai/dependencies.git?subdirectory=acados&rev=release-acados#8ea54be6bf1096b131493dbb38e8bd721a6727de" } dependencies = [ { name = "numpy" }, ] @@ -68,22 +68,22 @@ wheels = [ [[package]] name = "bootstrap-icons" version = "1.10.5.0" -source = { git = "https://github.com/commaai/dependencies.git?subdirectory=bootstrap-icons&rev=release-bootstrap-icons#8baa670f1b5c588e92ee8b9aa0ac821002b2e0f0" } +source = { git = "https://github.com/commaai/dependencies.git?subdirectory=bootstrap-icons&rev=release-bootstrap-icons#65bc63d354432ad83294c8ecfc3ef01733a46e12" } [[package]] name = "bzip2" version = "1.0.8" -source = { git = "https://github.com/commaai/dependencies.git?subdirectory=bzip2&rev=release-bzip2#c998c0bbd86966dfaf6508a10454d58bc9941549" } +source = { git = "https://github.com/commaai/dependencies.git?subdirectory=bzip2&rev=release-bzip2#83b0dd263eff2d9633a86096056fe16543a42244" } [[package]] name = "capnproto" version = "1.0.1" -source = { git = "https://github.com/commaai/dependencies.git?subdirectory=capnproto&rev=release-capnproto#e85b11061487aa5e2015b96f44b25a5bde8ed7d9" } +source = { git = "https://github.com/commaai/dependencies.git?subdirectory=capnproto&rev=release-capnproto#71cb13543c7d9691064fd01854e228f1481efab6" } [[package]] name = "catch2" version = "2.13.10" -source = { git = "https://github.com/commaai/dependencies.git?subdirectory=catch2&rev=release-catch2#802399c0b7e28325066bf3e880bf12010b771257" } +source = { git = "https://github.com/commaai/dependencies.git?subdirectory=catch2&rev=release-catch2#2bce880125320350b54d9d6696713ae847d06485" } [[package]] name = "certifi" @@ -144,14 +144,14 @@ wheels = [ [[package]] name = "click" -version = "8.4.1" +version = "8.4.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/9b/98/518d8e5081007684232226f475082b30087d0f585e8457db087298259f49/click-8.4.1.tar.gz", hash = "sha256:918b5633eddf6b41c32d4f454bf0de810065c74e3f7dbf8ee5452f8be88d3e96", size = 353007, upload-time = "2026-05-22T04:08:37.769Z" } +sdist = { url = "https://files.pythonhosted.org/packages/76/d4/81420972a676e8ffea40450d8c8c92943e7218a78fe9b64359836cc9876b/click-8.4.2.tar.gz", hash = "sha256:9a6cea6e60b17ebe0a44c5cc636d94f09bd66142c1cd7d8b4cd731c4917a15f6", size = 338000, upload-time = "2026-06-24T17:45:15.148Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c7/0d/67e5b4109ea4a837e80daa87c2c696711955e40449a97e8926672534def2/click-8.4.1-py3-none-any.whl", hash = "sha256:482be17c6991b8c19c5429a1e995d9b0efdbb63172824c41f99965dc0ade8ec2", size = 116639, upload-time = "2026-05-22T04:08:35.26Z" }, + { url = "https://files.pythonhosted.org/packages/fb/e2/79c688af8b210d232694e31e59da9f6ec747bae31c3f5946e4e9b98860d5/click-8.4.2-py3-none-any.whl", hash = "sha256:e6f9f66136c816745b9d65817da91d61d957fb16e02e4dcd0552553c5a197b76", size = 119243, upload-time = "2026-06-24T17:45:13.73Z" }, ] [[package]] @@ -196,26 +196,26 @@ wheels = [ [[package]] name = "coverage" -version = "7.14.2" +version = "7.15.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/9c/a3/3834a5564fe8f32154cd7032400d3c2f9c565b2a373fa671f2bbdad6f634/coverage-7.14.2.tar.gz", hash = "sha256:7a2da3d81cfe17c18038c6d98e6592aa9147d596d056119b0ee612c3c8bd5230", size = 923982, upload-time = "2026-06-20T14:49:30.885Z" } +sdist = { url = "https://files.pythonhosted.org/packages/cc/8b/adeb62ea8951f13c4c7fef2e7a85e1a06b499c8d8237ea589d496029e53f/coverage-7.15.0.tar.gz", hash = "sha256:9ac3fe7a1435986463eaa8ee253ae2f2a268709ba4ae5c7dd1f52a05391ad78f", size = 925362, upload-time = "2026-07-02T13:10:50.535Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d0/d9/bdd141aa2c605096a8ef63b8435fd4f5fec78946a3cb7b9145840ec78291/coverage-7.14.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:37c94712e533ea06f0b1e4d934811c520b1914ce0e4da3916220717aa7a86bc6", size = 220528, upload-time = "2026-06-20T14:47:49.652Z" }, - { url = "https://files.pythonhosted.org/packages/02/97/d24ae7d2afc62c54a36313d4dedb655c9afbba3003f0f7f1ae81e97af31f/coverage-7.14.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c050bbc7bba94c77e4ed7438f4fda1babe98ab145691d80aa6f60df934a1468b", size = 220883, upload-time = "2026-06-20T14:47:51.036Z" }, - { url = "https://files.pythonhosted.org/packages/f8/0e/d8f00efd3df0d63e6843ebcbade9e4119d60f5376753c9705d84b014c775/coverage-7.14.2-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:a7af571767a2ee342a171c16fc1b1a07a0bf511606d381703fb7cf397fe49d46", size = 252395, upload-time = "2026-06-20T14:47:52.627Z" }, - { url = "https://files.pythonhosted.org/packages/1c/1c/ab9510dfe1a16a35a10f90efad0d9a9cf61b9876973752968f2ba882f73f/coverage-7.14.2-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:8b4910cce599cd2438f8da65f5ef199a70a1cdb6ab314926df78271ca5954240", size = 255131, upload-time = "2026-06-20T14:47:54.235Z" }, - { url = "https://files.pythonhosted.org/packages/ba/dd/70171e9371003b33dc6b20f527ac216ff91bbe5c1088e754eb8950d79193/coverage-7.14.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c33e9e4878972f430b0cc06de3bf2a28d054a9efb4f8426d27de0d9cb81396ff", size = 256246, upload-time = "2026-06-20T14:47:55.61Z" }, - { url = "https://files.pythonhosted.org/packages/0f/80/a68b1dd81d5c011e17fd6ab0d707d33297df1d0c618114b9b750a2219c80/coverage-7.14.2-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e7967ea55c6dea6becba4d5870e2fa0aa4915a8be7ebff1bb79e6207aa75ce8d", size = 258504, upload-time = "2026-06-20T14:47:56.979Z" }, - { url = "https://files.pythonhosted.org/packages/8e/7b/40baaa946189f5317cd77d484e39b9b0727d02ebada0a12162374f2faee2/coverage-7.14.2-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:d1322f237c2979b84096f4239c17828ff17fea6b3bbe96c44381c5f587c44c26", size = 252808, upload-time = "2026-06-20T14:47:58.418Z" }, - { url = "https://files.pythonhosted.org/packages/d5/05/b19517b09c43d1e8591de6c13178b0c03166c31e1adbebda378e64c66b9a/coverage-7.14.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:77849525340c99f516d793dddbcee16b18d50af892ac43c8de1a6f343d41e3b5", size = 254166, upload-time = "2026-06-20T14:48:00.004Z" }, - { url = "https://files.pythonhosted.org/packages/ae/f5/6e65da5957e041d2094a9b97736628dd80160f1cc007a50790bbb2668c1a/coverage-7.14.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:ef11695493ec3f06f7b2678ca274bcabb4ca04057317df268ddbfd8b05f661a8", size = 252310, upload-time = "2026-06-20T14:48:01.458Z" }, - { url = "https://files.pythonhosted.org/packages/2d/de/01b5274f0db63175b04d9354eff68d2d268b8b57a1b2db7d3dcb1f2c9dbb/coverage-7.14.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:8134f0e0723e080d1c27bbe8fc149f0162e429fa1852482150015d0fce83eaf1", size = 256379, upload-time = "2026-06-20T14:48:02.981Z" }, - { url = "https://files.pythonhosted.org/packages/71/d6/9a2ffbca41e2f8f86f61e8b78b86afa433ec8cdeac4908ace93a28fe3ff0/coverage-7.14.2-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:914eead2b843fc357f733b3fe39cc94f1b53d466e8cfe03080b1ed9d24ccfc73", size = 251880, upload-time = "2026-06-20T14:48:04.463Z" }, - { url = "https://files.pythonhosted.org/packages/e3/ff/20bd54a43c88c08f474e6cb355a97e024e38412873ef0a581629abe1e26f/coverage-7.14.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e4b2d5e847fb7958583b74910cc19e5ec4ece514487385677b26433b2546116e", size = 253753, upload-time = "2026-06-20T14:48:05.99Z" }, - { url = "https://files.pythonhosted.org/packages/35/2a/2b3482c30d8344f301d8df6ff232a321f2ab87d5ac97ba21891a68638131/coverage-7.14.2-cp312-cp312-win32.whl", hash = "sha256:e753db9e40dda7302e0ac3e1e6e1325fb7f7b4694f87a7314ab15dd5d57911a7", size = 222584, upload-time = "2026-06-20T14:48:07.361Z" }, - { url = "https://files.pythonhosted.org/packages/f6/5e/83934ffff147edd313fe925db426e8f7ccad9e4663262eb5c4db4e345658/coverage-7.14.2-cp312-cp312-win_amd64.whl", hash = "sha256:d32e5ca5f16dafb269ee50b60d32b00c704b3f6f78e238105f1d94a3a5f24bf5", size = 223118, upload-time = "2026-06-20T14:48:08.837Z" }, - { url = "https://files.pythonhosted.org/packages/bb/ee/616b4f38a34f076f3045d3eedfa764d34d82e6a6cc6b300acb0f1ff22a98/coverage-7.14.2-cp312-cp312-win_arm64.whl", hash = "sha256:dc366f158e2fb2add9d4e57338ca48f12611024278688ee657eb0b853fcb5de5", size = 222504, upload-time = "2026-06-20T14:48:10.436Z" }, - { url = "https://files.pythonhosted.org/packages/a3/5e/a8ba14ceb014f39bd5e3f7077150718c7de61c01ce326bfe7e8eae9b19b2/coverage-7.14.2-py3-none-any.whl", hash = "sha256:04d92589e481a8b68a005a5a1e0646a91c76f322c397c4635298c57cf63699b5", size = 212325, upload-time = "2026-06-20T14:49:28.991Z" }, + { url = "https://files.pythonhosted.org/packages/2a/74/fd4c0901137c4f8d81a76ada99e43c65163b4c94a02ece107a4ec0c6b615/coverage-7.15.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b75ee5e8cb7575636ac598719b4307ac529ec8fcd79608a35c3cd4d4dada812d", size = 220838, upload-time = "2026-07-02T13:09:02.084Z" }, + { url = "https://files.pythonhosted.org/packages/0f/2e/2347583467bd7f0402635101a916961915cc68fce652cd0db5f173ea04fc/coverage-7.15.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ffb31267816b93b075302248cc1737506081b4f163df4401e9df1a6424aafabe", size = 221197, upload-time = "2026-07-02T13:09:03.617Z" }, + { url = "https://files.pythonhosted.org/packages/f0/17/99fa688541ae1d6e84543a0e544f83de0c944815b63e9e7b1ed411d15036/coverage-7.15.0-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:e4d0bb73455bf97ab243a8f12c37c686ccf1c13bb614b7b85f1d062f06f42b2c", size = 252705, upload-time = "2026-07-02T13:09:05.059Z" }, + { url = "https://files.pythonhosted.org/packages/fb/02/6a95a5cd83b74839017ef9cf48d2d8c9ae60af919e17a3f336e6f9f1b7bd/coverage-7.15.0-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:20d9ccc4ebd0edc434d86dfd2a1dd2a8efa6b6b3073d0485a394fee86459ebb4", size = 255441, upload-time = "2026-07-02T13:09:06.559Z" }, + { url = "https://files.pythonhosted.org/packages/67/f2/406f6c57d600f68185942422c4c00f1a3255d60aee6e5fd961425cd9987e/coverage-7.15.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:20c8a976c365c8cb12f0cbd099508772ea41fb5fa80657a8506df0e11bd278c5", size = 256556, upload-time = "2026-07-02T13:09:08.197Z" }, + { url = "https://files.pythonhosted.org/packages/74/8e/d3fa48489c15ecdec1ba48fd61f68798555dddd2f6716f9ad42adeb1a2a9/coverage-7.15.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f948fd5ba1b9cbca91f0ae08b4c1ce2b139509149a435e2585d056d57d70bf01", size = 258815, upload-time = "2026-07-02T13:09:09.691Z" }, + { url = "https://files.pythonhosted.org/packages/47/2e/2d40ddd110462c6a2769677cf7f1c119a52b45f568978fc6c98e4cc0dd0f/coverage-7.15.0-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f58185f06edf6ad68ec9fb155d63ef650c82f3fbd7e1770e2867751fb13158f4", size = 253117, upload-time = "2026-07-02T13:09:11.212Z" }, + { url = "https://files.pythonhosted.org/packages/51/c0/310782f0d7c3cb2b5ac05ba8d205fe91f24a36f6bf3256098f1782181c38/coverage-7.15.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:02adc79a920c73c647c5d117f55747df7f2de94571884758ce8bc58e04f0a796", size = 254475, upload-time = "2026-07-02T13:09:13.029Z" }, + { url = "https://files.pythonhosted.org/packages/86/f7/702da6c275f8ae6ade423d2877243122932c9b27f5403003b9ef8c927d12/coverage-7.15.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:6eb7c300fbed667fd6e3588eba71c1904cdb06110ca6fdf908c26bdd88b8e382", size = 252619, upload-time = "2026-07-02T13:09:14.699Z" }, + { url = "https://files.pythonhosted.org/packages/fb/84/c5b15a7e5ecba4e56218d772d99fe80a63e63f8d11f12783723a6005ab45/coverage-7.15.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:b5fb23fa2de9dce1f5c36c09066d8fcda16cd96e8e26686caa2d7cb9b567d65c", size = 256689, upload-time = "2026-07-02T13:09:16.103Z" }, + { url = "https://files.pythonhosted.org/packages/95/2f/c8b07559b57701230c61b23a953858c052890c12ef568d81780c6c46e92e/coverage-7.15.0-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:cec79341dbe6281484024979976d0c7f22beae08b4a254655decd25d42cbe766", size = 252189, upload-time = "2026-07-02T13:09:17.828Z" }, + { url = "https://files.pythonhosted.org/packages/6b/80/6d2f049dd3fd3dbfd60b62ba6b2162a04009e2c002ce70b24cf3878dec7a/coverage-7.15.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:6c664c5444b1d970b1b2a450e21fb19ee5c9cfdf151ded2dda37260031cca0da", size = 254059, upload-time = "2026-07-02T13:09:19.304Z" }, + { url = "https://files.pythonhosted.org/packages/ce/92/b0287a2c42031d25c628f815f89a3cd9f8268ee78bb1252c9356cda1c689/coverage-7.15.0-cp312-cp312-win32.whl", hash = "sha256:5f764a3fa339bde6b3aa97657f5a6a3a9451e4a5b4ea98a2892c773a43525f77", size = 222893, upload-time = "2026-07-02T13:09:20.812Z" }, + { url = "https://files.pythonhosted.org/packages/a9/69/e34c481915fecb499b3146975061dac528752e37706edc1804f32c822469/coverage-7.15.0-cp312-cp312-win_amd64.whl", hash = "sha256:52f9a4d2c4c56c8848bc2f524916698354b0211488b38c49ad9ae54f6cafbff6", size = 223429, upload-time = "2026-07-02T13:09:22.315Z" }, + { url = "https://files.pythonhosted.org/packages/fe/98/6e878f0b571d32684ef3f38d7c03db241ca5b82a5da8a5391596a8f209c4/coverage-7.15.0-cp312-cp312-win_arm64.whl", hash = "sha256:31e5c3e70c85307ea35a12964e2e40f56ca2ee4b1c8c721ccf4609d17071080b", size = 222810, upload-time = "2026-07-02T13:09:23.812Z" }, + { url = "https://files.pythonhosted.org/packages/52/30/21b2ad45959cd50e909e02ebac1e30b4ceb7162e91c11d4c570223a458b7/coverage-7.15.0-py3-none-any.whl", hash = "sha256:56da6a4cbe8f7e9e80bd072ca9cefe67d7106a440a7ec06519ec6507ac94ad19", size = 212632, upload-time = "2026-07-02T13:10:48.641Z" }, ] [[package]] @@ -282,24 +282,24 @@ wheels = [ [[package]] name = "cython" -version = "3.2.5" +version = "3.2.8" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/3f/3b/ebd94c8b85f8e41b5015a9ed94ee3df866024d480d05cd08b774684fb81d/cython-3.2.5.tar.gz", hash = "sha256:3dd42e4cf36ad15f265bdfec2337cc00c688c8eb6d374ffd13bb19437c27bba1", size = 3286381, upload-time = "2026-05-23T19:34:08.439Z" } +sdist = { url = "https://files.pythonhosted.org/packages/b6/6b/80101e02ebacaf9232ecf32bf6a788d36b27d820ee02434746252569ef98/cython-3.2.8.tar.gz", hash = "sha256:f4f23a56b25221a06f91817fe8f3114ab8b48a4fac73187dbb64bc2c4a87961f", size = 3290300, upload-time = "2026-06-30T07:41:57.874Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/20/a6/efc97000fdb2f34e2431eb09a6ab4de9fbd3bcdb73a8f9d224afa4a9abd3/cython-3.2.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:eb38b89e5a8eb2508a1a0832063826b0703dfb02be84e4aa34b8818ce0ca50fe", size = 2979670, upload-time = "2026-05-23T19:34:41.281Z" }, - { url = "https://files.pythonhosted.org/packages/84/b7/951206add609c11f3bb9e82329a653c39a8bc9039c13bce57362caf84bb6/cython-3.2.5-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c80e1e5cba5b4b9890364e9360939fc298c474f25754bb4bb861270d24bda6d6", size = 3232779, upload-time = "2026-05-23T19:34:43.347Z" }, - { url = "https://files.pythonhosted.org/packages/a1/aa/8a1d02eabe8bc1e5066fde920010a4a4a4c5f0bac3625d8e7c946f72ef98/cython-3.2.5-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4d00e2c976ee96da4deff50506c7882ccebb4a932fc178ef27eb42bfde959839", size = 3400054, upload-time = "2026-05-23T19:34:45.6Z" }, - { url = "https://files.pythonhosted.org/packages/57/30/67a1b6192c828456f096d4bf4d840b9a749904b9030d9f857549fc1f9b53/cython-3.2.5-cp312-cp312-win_amd64.whl", hash = "sha256:29243859d6824e2d33bae92fc83d591c3671b6d9ac1b757fa264b894ae906c2b", size = 2759539, upload-time = "2026-05-23T19:34:47.341Z" }, - { url = "https://files.pythonhosted.org/packages/a3/de/e3e0cf5704fe569d54b8cd5dc316c9fbf08b1b74728732f86e90168b7a3f/cython-3.2.5-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:224149d18d980e6ea5001b70fc7ce096c1891d59035dfa9cc5ede50f55804913", size = 2879054, upload-time = "2026-05-23T19:35:18.265Z" }, - { url = "https://files.pythonhosted.org/packages/3c/d1/0a6a8caa35c4c57a1f1866b1141c2d00c6af67f73edbe34b2baec6919ccf/cython-3.2.5-cp39-abi3-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:992a50e90d01813333752f374a4405863113059ec67102ab8d6a431a171ee328", size = 3210422, upload-time = "2026-05-23T19:35:20.641Z" }, - { url = "https://files.pythonhosted.org/packages/07/b8/2523398ec96bb0c9bf69ada625a2256a581940b09fe11fcd0029f26ef4ad/cython-3.2.5-cp39-abi3-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:8d7b81e6a52a84a02993f01aa5873786ba1dd593c892d93d5fe9866da0bad297", size = 2863809, upload-time = "2026-05-23T19:35:22.416Z" }, - { url = "https://files.pythonhosted.org/packages/ff/3d/6b2f316d97bdb02283d79934e50da5cedfec65a536cdd3d69cc3a93486f9/cython-3.2.5-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:34d21aeb08477c9173e8be7a566b19e880a7c8109ec6bb47a4b20cb680141114", size = 2992518, upload-time = "2026-05-23T19:35:24.737Z" }, - { url = "https://files.pythonhosted.org/packages/68/2c/c9238db1eba208e226d363c00c8b74bf531a6b40c75df2334baa85e142bf/cython-3.2.5-cp39-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:c4c79e697db55f082a2d3ba97702e71881d5bb1f56f0a80fa338e69101e4c59b", size = 2886221, upload-time = "2026-05-23T19:35:26.64Z" }, - { url = "https://files.pythonhosted.org/packages/2d/15/229cc5c2ed92bb8b43c73a3d31c2b4eaf498409300c34a06d93147f7a42b/cython-3.2.5-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:39acb30eba78ba6d995d5cf3d97d57d450663d93aac6f8b93753d2b89d768c60", size = 3226990, upload-time = "2026-05-23T19:35:28.979Z" }, - { url = "https://files.pythonhosted.org/packages/56/31/9c0024f2c772fc303f8cae2a204bcad2fedfaf921ba71cf13a878639432d/cython-3.2.5-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:382122de8d6b6024fc374fabc3a2b14ba5860ed981c25055ed14fe44278b9dc7", size = 3111004, upload-time = "2026-05-23T19:35:30.957Z" }, - { url = "https://files.pythonhosted.org/packages/82/71/8b528247e42ee63cbe1c1d53805d30b28663fa782c88da4a9b69a1a412dd/cython-3.2.5-cp39-abi3-win32.whl", hash = "sha256:0bc29c7f870b09efdb1f583fbec9592b33af81a7ce273b89c8f5163d7572d5c1", size = 2440395, upload-time = "2026-05-23T19:35:33.082Z" }, - { url = "https://files.pythonhosted.org/packages/50/4d/81c91d3279d156ee2c9ead7ed9eaa862e498066d759e92fb83d0d842c5a7/cython-3.2.5-cp39-abi3-win_arm64.whl", hash = "sha256:85b2944c3eddfc230f9082720195a2e9f869908e5a8b3185be1be832755ee7fc", size = 2446963, upload-time = "2026-05-23T19:35:35.267Z" }, - { url = "https://files.pythonhosted.org/packages/d4/5c/9cd909e6a8bb178e4e0f9a2a9227c8201a2be38abe45ada4a4c3e9154277/cython-3.2.5-py3-none-any.whl", hash = "sha256:dc1c8cebb7df5bce37f5f8dc1e5bf04313272a5973d50a55c0ec76c83812911b", size = 1257622, upload-time = "2026-05-23T19:34:05.163Z" }, + { url = "https://files.pythonhosted.org/packages/ed/c4/47e0bcfc15b36b1c5cbde5235c60bf88df552ab216ddb836d7f816386ae6/cython-3.2.8-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f2547a31fbd3b1610a8859a16edee2a141f7781691cb98a2c6fd54870c5f7541", size = 2995546, upload-time = "2026-06-30T07:42:23.618Z" }, + { url = "https://files.pythonhosted.org/packages/4a/f4/bc5830abeb57a7c7498cd9a0f2df953fd9fc7f33e3f5352c9824802b83bb/cython-3.2.8-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ab1fe11ebd61e497a848622cdd157a4324ac06e7935b1219715408844e15dd13", size = 3179546, upload-time = "2026-06-30T07:42:25.566Z" }, + { url = "https://files.pythonhosted.org/packages/89/38/a70e879ea52debac11d2810e066a5a2cb16e71229edae303f024506bc142/cython-3.2.8-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f3bce1f079734753649f8a3d3a95832297207feb120d0ef4fd5db4c813cc6c04", size = 3351714, upload-time = "2026-06-30T07:42:27.513Z" }, + { url = "https://files.pythonhosted.org/packages/45/f1/f071c5e7050a7924ffad9822558c74d489afe4764f7486cb68555a509219/cython-3.2.8-cp312-cp312-win_amd64.whl", hash = "sha256:8297efe129e6421c34ddbeb09ed5627ef6c0fc4868bf7f9bdf6c147f595ccaed", size = 2774196, upload-time = "2026-06-30T07:42:29.47Z" }, + { url = "https://files.pythonhosted.org/packages/92/a2/0f2eaa5076bcaef52567471a54ce02ffd70007bf8688cd054f7aab9bc3b8/cython-3.2.8-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:127bc4039be48c6eebe7f1d68c33d23eb3a0c5ae95e1d730bdd048837751438b", size = 2892527, upload-time = "2026-06-30T07:42:55.45Z" }, + { url = "https://files.pythonhosted.org/packages/a4/08/b5488aef44662e48ac09b42d4cb398207f591c770797036fb1d6fbeb7a52/cython-3.2.8-cp39-abi3-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:e480ae9f195cd29e5ce334e3d434c83dbac0783c0cc88f2407e31ba997724192", size = 3220335, upload-time = "2026-06-30T07:42:57.403Z" }, + { url = "https://files.pythonhosted.org/packages/7c/96/d04a3621045e9fe9c7c5e406a688ee3d6e04a65f545ea7c622ead4b4afd8/cython-3.2.8-cp39-abi3-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3142407b9d63f233c766e17000e2aac782411bf0409b9adc97cb7c320aecd199", size = 2876481, upload-time = "2026-06-30T07:42:59.406Z" }, + { url = "https://files.pythonhosted.org/packages/71/9a/daa259b638c5eabb8a8c36f203b85b01b5362101ff8fc4ec6ad592d34bb3/cython-3.2.8-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:41c118fd91d320cd72af26e29232ff3f1a0a170c47d477c9a176d766067a4718", size = 2999974, upload-time = "2026-06-30T07:43:01.29Z" }, + { url = "https://files.pythonhosted.org/packages/21/de/71cc5b4be5ee4d34c3302b6e7272189106a4072e9890d284d05239d2b645/cython-3.2.8-cp39-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:6335c6e8737a39734e20d25f89f425bf3274c104fc7efc05aacc7ed1a4858c9d", size = 2897932, upload-time = "2026-06-30T07:43:03.606Z" }, + { url = "https://files.pythonhosted.org/packages/5d/0c/da68b9d3056e90b2060970b50d575cd7fcd1c778e8f23cc467f346e1d471/cython-3.2.8-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:1034facc082cb882e1e5beb61e136ae8e282df2eafa11e9771e9b0a15c860801", size = 3235980, upload-time = "2026-06-30T07:43:05.486Z" }, + { url = "https://files.pythonhosted.org/packages/36/0b/d88bc50e66fd1f1160dd2677d9af18273a2fb2f102c086d21f64a5a9c78b/cython-3.2.8-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:8896ff6b133f346ebcf22aa23706c4031e8d9d5ae184433dfc67dc1053318b69", size = 3118504, upload-time = "2026-06-30T07:43:07.485Z" }, + { url = "https://files.pythonhosted.org/packages/db/de/511c4364808b3b4036d051a0301b0b142a3ddf8a319bfdbbd474fcfdc879/cython-3.2.8-cp39-abi3-win32.whl", hash = "sha256:3fd6464433d925cba66ae31bf5780c8a469a06da1d109180cffb39ee3c88ae20", size = 2435866, upload-time = "2026-06-30T07:43:09.367Z" }, + { url = "https://files.pythonhosted.org/packages/18/4f/911b2b2a0a02be15829ccbf0c906029a318efbf53d9f8e021e438261c206/cython-3.2.8-cp39-abi3-win_arm64.whl", hash = "sha256:4e9447d9b652396a285cdfbd4f9f0721842c63c6df281720e87dcc4b9ea65af5", size = 2457829, upload-time = "2026-06-30T07:43:11.645Z" }, + { url = "https://files.pythonhosted.org/packages/c4/19/31aa63ab719b2e1eea5f200a8a54e2591dc1966a6b75e3de30ef8be9bc2c/cython-3.2.8-py3-none-any.whl", hash = "sha256:f635e113677666de13a2ec2979e9b1d5b90617cdfd1a691d3559be81e2dd6cb9", size = 1258688, upload-time = "2026-06-30T07:41:55.624Z" }, ] [[package]] @@ -323,7 +323,7 @@ wheels = [ [[package]] name = "eigen" version = "3.4.0" -source = { git = "https://github.com/commaai/dependencies.git?subdirectory=eigen&rev=release-eigen#9d2dba116fa763abf9bfaea17037ab7ed15c20a7" } +source = { git = "https://github.com/commaai/dependencies.git?subdirectory=eigen&rev=release-eigen#7fd5584ae72d8b4b89df7fd52e4b4761ad5e51f4" } [[package]] name = "execnet" @@ -337,7 +337,7 @@ wheels = [ [[package]] name = "ffmpeg" version = "7.1.0" -source = { git = "https://github.com/commaai/dependencies.git?subdirectory=ffmpeg&rev=release-ffmpeg#fefb542cea16c9e151a05684591cf956c3ebfe0c" } +source = { git = "https://github.com/commaai/dependencies.git?subdirectory=ffmpeg&rev=release-ffmpeg#f8021e2d6476b9b46343ad21f7b3773f12fd7414" } [[package]] name = "fonttools" @@ -359,12 +359,12 @@ wheels = [ [[package]] name = "gcc-arm-none-eabi" version = "13.2.1" -source = { git = "https://github.com/commaai/dependencies.git?subdirectory=gcc-arm-none-eabi&rev=release-gcc-arm-none-eabi#89a0ae5aa2f36057351e8ae392a82dd0b9506174" } +source = { git = "https://github.com/commaai/dependencies.git?subdirectory=gcc-arm-none-eabi&rev=release-gcc-arm-none-eabi#6942c457205971ada312cc0f5ef7d10ff108b8cc" } [[package]] name = "git-lfs" version = "3.6.1" -source = { git = "https://github.com/commaai/dependencies.git?subdirectory=git-lfs&rev=release-git-lfs#866e78eb06963c78721e01f8cd4a0dadcf187a14" } +source = { git = "https://github.com/commaai/dependencies.git?subdirectory=git-lfs&rev=release-git-lfs#0a1fccce026554b4f3ef1feb2b611bf045a171e2" } [[package]] name = "google-crc32c" @@ -413,7 +413,7 @@ wheels = [ [[package]] name = "imgui" version = "1.92.7" -source = { git = "https://github.com/commaai/dependencies.git?subdirectory=imgui&rev=release-imgui#6e183051fcfedebc1d765571f10c4f1e27e6c8e6" } +source = { git = "https://github.com/commaai/dependencies.git?subdirectory=imgui&rev=release-imgui#1964d125f4b1eded94b85b1da485f46a794f84a3" } [[package]] name = "iniconfig" @@ -466,7 +466,7 @@ wheels = [ [[package]] name = "json11" version = "20170411.0" -source = { git = "https://github.com/commaai/dependencies.git?subdirectory=json11&rev=release-json11#39d9a6fcb2b85f1d30486861da761a9d5b8b523b" } +source = { git = "https://github.com/commaai/dependencies.git?subdirectory=json11&rev=release-json11#f65ae63ea938062f00cdc142c6f01d60141da9c2" } [[package]] name = "kiwisolver" @@ -498,12 +498,12 @@ wheels = [ [[package]] name = "libjpeg" version = "3.1.0" -source = { git = "https://github.com/commaai/dependencies.git?subdirectory=libjpeg&rev=release-libjpeg#f39de7bd84f043d280e843ec89a8b3185ff7db6e" } +source = { git = "https://github.com/commaai/dependencies.git?subdirectory=libjpeg&rev=release-libjpeg#3f9a0796d1985576b0cb172456e08bb918f3afeb" } [[package]] name = "libusb" version = "1.0.29" -source = { git = "https://github.com/commaai/dependencies.git?subdirectory=libusb&rev=release-libusb#d35ca758bf9d77a757a56c7f3e4a8ecead82d3e4" } +source = { git = "https://github.com/commaai/dependencies.git?subdirectory=libusb&rev=release-libusb#9c268a75b3f29495f154065064c6ee3ac79bd416" } [[package]] name = "libusb1" @@ -519,7 +519,7 @@ wheels = [ [[package]] name = "libyuv" version = "1922.0" -source = { git = "https://github.com/commaai/dependencies.git?subdirectory=libyuv&rev=release-libyuv#c6d2856b35c3965308ef1a6eff4b474ea6fd1d28" } +source = { git = "https://github.com/commaai/dependencies.git?subdirectory=libyuv&rev=release-libyuv#606fbcc349db62aa8c337b49520b7361e374b67d" } [[package]] name = "markdown" @@ -587,7 +587,7 @@ wheels = [ [[package]] name = "ncurses" version = "6.5" -source = { git = "https://github.com/commaai/dependencies.git?subdirectory=ncurses&rev=release-ncurses#c46bad849b29b29bb041805a4c895c7e1d5c0b7e" } +source = { git = "https://github.com/commaai/dependencies.git?subdirectory=ncurses&rev=release-ncurses#97d56492b9257d021596fc89927af2ec4433da58" } [[package]] name = "numpy" @@ -767,21 +767,19 @@ wheels = [ [[package]] name = "pillow" -version = "12.2.0" +version = "12.3.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/8c/21/c2bcdd5906101a30244eaffc1b6e6ce71a31bd0742a01eb89e660ebfac2d/pillow-12.2.0.tar.gz", hash = "sha256:a830b1a40919539d07806aa58e1b114df53ddd43213d9c8b75847eee6c0182b5", size = 46987819, upload-time = "2026-04-01T14:46:17.687Z" } +sdist = { url = "https://files.pythonhosted.org/packages/1c/3d/bb7fca845737cf9d7dbde16ed1843984665ff2e0a518f5db43e77ec540b9/pillow-12.3.0.tar.gz", hash = "sha256:3b8182a766685eaa002637e28b4ec8d6b18819a0c71f579bf0dbaa5830297cce", size = 47025035, upload-time = "2026-07-01T11:56:38.965Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/58/be/7482c8a5ebebbc6470b3eb791812fff7d5e0216c2be3827b30b8bb6603ed/pillow-12.2.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:2d192a155bbcec180f8564f693e6fd9bccff5a7af9b32e2e4bf8c9c69dbad6b5", size = 5308279, upload-time = "2026-04-01T14:43:13.246Z" }, - { url = "https://files.pythonhosted.org/packages/d8/95/0a351b9289c2b5cbde0bacd4a83ebc44023e835490a727b2a3bd60ddc0f4/pillow-12.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f3f40b3c5a968281fd507d519e444c35f0ff171237f4fdde090dd60699458421", size = 4695490, upload-time = "2026-04-01T14:43:15.584Z" }, - { url = "https://files.pythonhosted.org/packages/de/af/4e8e6869cbed569d43c416fad3dc4ecb944cb5d9492defaed89ddd6fe871/pillow-12.2.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:03e7e372d5240cc23e9f07deca4d775c0817bffc641b01e9c3af208dbd300987", size = 6284462, upload-time = "2026-04-01T14:43:18.268Z" }, - { url = "https://files.pythonhosted.org/packages/e9/9e/c05e19657fd57841e476be1ab46c4d501bffbadbafdc31a6d665f8b737b6/pillow-12.2.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:b86024e52a1b269467a802258c25521e6d742349d760728092e1bc2d135b4d76", size = 8094744, upload-time = "2026-04-01T14:43:20.716Z" }, - { url = "https://files.pythonhosted.org/packages/2b/54/1789c455ed10176066b6e7e6da1b01e50e36f94ba584dc68d9eebfe9156d/pillow-12.2.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7371b48c4fa448d20d2714c9a1f775a81155050d383333e0a6c15b1123dda005", size = 6398371, upload-time = "2026-04-01T14:43:23.443Z" }, - { url = "https://files.pythonhosted.org/packages/43/e3/fdc657359e919462369869f1c9f0e973f353f9a9ee295a39b1fea8ee1a77/pillow-12.2.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:62f5409336adb0663b7caa0da5c7d9e7bdbaae9ce761d34669420c2a801b2780", size = 7087215, upload-time = "2026-04-01T14:43:26.758Z" }, - { url = "https://files.pythonhosted.org/packages/8b/f8/2f6825e441d5b1959d2ca5adec984210f1ec086435b0ed5f52c19b3b8a6e/pillow-12.2.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:01afa7cf67f74f09523699b4e88c73fb55c13346d212a59a2db1f86b0a63e8c5", size = 6509783, upload-time = "2026-04-01T14:43:29.56Z" }, - { url = "https://files.pythonhosted.org/packages/67/f9/029a27095ad20f854f9dba026b3ea6428548316e057e6fc3545409e86651/pillow-12.2.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fc3d34d4a8fbec3e88a79b92e5465e0f9b842b628675850d860b8bd300b159f5", size = 7212112, upload-time = "2026-04-01T14:43:32.091Z" }, - { url = "https://files.pythonhosted.org/packages/be/42/025cfe05d1be22dbfdb4f264fe9de1ccda83f66e4fc3aac94748e784af04/pillow-12.2.0-cp312-cp312-win32.whl", hash = "sha256:58f62cc0f00fd29e64b29f4fd923ffdb3859c9f9e6105bfc37ba1d08994e8940", size = 6378489, upload-time = "2026-04-01T14:43:34.601Z" }, - { url = "https://files.pythonhosted.org/packages/5d/7b/25a221d2c761c6a8ae21bfa3874988ff2583e19cf8a27bf2fee358df7942/pillow-12.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:7f84204dee22a783350679a0333981df803dac21a0190d706a50475e361c93f5", size = 7084129, upload-time = "2026-04-01T14:43:37.213Z" }, - { url = "https://files.pythonhosted.org/packages/10/e1/542a474affab20fd4a0f1836cb234e8493519da6b76899e30bcc5d990b8b/pillow-12.2.0-cp312-cp312-win_arm64.whl", hash = "sha256:af73337013e0b3b46f175e79492d96845b16126ddf79c438d7ea7ff27783a414", size = 2463612, upload-time = "2026-04-01T14:43:39.421Z" }, + { url = "https://files.pythonhosted.org/packages/37/bf/fb3ebff8ddcb76aac5a01389251bbbb9519922a9b520d8247c1ca864a25d/pillow-12.3.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:ba09209fbe443b4acccebe845d8a138b89a8f4fbaeedd44953490b5315d5e965", size = 5345969, upload-time = "2026-07-01T11:54:06.397Z" }, + { url = "https://files.pythonhosted.org/packages/d8/66/9a386a92561f402389a4fc70c18838bf6d35eb5eb5c6850b4b2dc64f5048/pillow-12.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ffd0c5368496f41b0944be820fcb7a838aa6e623d250b01acf2643939c3f99d7", size = 4780323, upload-time = "2026-07-01T11:54:09.351Z" }, + { url = "https://files.pythonhosted.org/packages/25/27/ac8f99618ffd3dde21db0f4d4b1d2ab00c0880595bfd17df103f7f39fd0c/pillow-12.3.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d9c7f76c0673154f044e9d78c8655fb4213f6ca31a836df48b40fe5d187717b9", size = 6266838, upload-time = "2026-07-01T11:54:11.71Z" }, + { url = "https://files.pythonhosted.org/packages/84/21/a35af28dcc61f37ed850a2d64c65c701321dfbf25085e469d5559360cbbf/pillow-12.3.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:78cb2c6865a35ab8ff8b75fd122f6033b92a62c82801110e48ddd6c936a45d91", size = 6940830, upload-time = "2026-07-01T11:54:13.732Z" }, + { url = "https://files.pythonhosted.org/packages/eb/51/8b08617af3ad95e33ce6d7dd2c99ed6c8298f7fb131636303956be022e25/pillow-12.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e491916b378fba47242221bb9ead245211b70d504f495d105d17b14a24b4907c", size = 6344383, upload-time = "2026-07-01T11:54:15.756Z" }, + { url = "https://files.pythonhosted.org/packages/1d/72/cf78ac9780bb93c28328f408973845a309d4d145041665f734572ced1b52/pillow-12.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0dd2064cbc55aaec028ef5fbb60fa47bb6c3e7918e07ff17935284b227a9d2df", size = 7052934, upload-time = "2026-07-01T11:54:17.721Z" }, + { url = "https://files.pythonhosted.org/packages/20/20/25e0f4dc178a6bc0696793720055519a0de89e7661dae886992decbd2f81/pillow-12.3.0-cp312-cp312-win32.whl", hash = "sha256:dbce0b29841537a2fa4a214c2bbf14de3587c9680caa9b4e217568472490b28f", size = 6472684, upload-time = "2026-07-01T11:54:19.839Z" }, + { url = "https://files.pythonhosted.org/packages/45/89/da2f7971a317f83d807fdd4065c0af40208e59e692cc43d315a71a0e96d1/pillow-12.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:a2b55dd6b2a4c4b7d87ffa56bdb33fdc5fdb9a462173861a7bc097f17d91cb09", size = 7227137, upload-time = "2026-07-01T11:54:22.025Z" }, + { url = "https://files.pythonhosted.org/packages/de/47/4845a0a6c0dbf1db8456bd9fc791f13c5ced7ced20606d08a0aacfd25b49/pillow-12.3.0-cp312-cp312-win_arm64.whl", hash = "sha256:331b624368d4f1d069149002f25f44bc61c8919ce8ddb3c45bdad8f6e2d89510", size = 2568267, upload-time = "2026-07-01T11:54:24.051Z" }, ] [[package]] @@ -923,15 +921,15 @@ wheels = [ [[package]] name = "pymdown-extensions" -version = "10.21.3" +version = "11.0.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "markdown" }, { name = "pyyaml" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/9e/26/d1015444da4d952a1ca487a236b522eb979766f0295a0bd0c5fc089989a9/pymdown_extensions-10.21.3.tar.gz", hash = "sha256:72cfcf55f07aea0d4af2c4f11dd4e52466ddfb1bb819673146398e0bd3a77354", size = 854140, upload-time = "2026-05-13T12:57:32.267Z" } +sdist = { url = "https://files.pythonhosted.org/packages/21/a9/5f0c535ba3b08fe09270c16808e053a968868242ecbd5676d4e3a488bf28/pymdown_extensions-11.0.1.tar.gz", hash = "sha256:dd2905ae6fc5b75582fafb139a1266ffc754705efa902aa50067fa7ff4f94ec0", size = 857113, upload-time = "2026-07-02T17:59:22.955Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7e/85/545a951eecc270fcd688288c600017e2050a1aacb56c711d208586d3e470/pymdown_extensions-10.21.3-py3-none-any.whl", hash = "sha256:d7a5d08014fc571e80ca21dd6f854e31f94c489800350564d55d15b3c41e76b6", size = 269002, upload-time = "2026-05-13T12:57:30.296Z" }, + { url = "https://files.pythonhosted.org/packages/d6/54/da572c98c0b77626a91b5d3b89f0231d8bff5125c225420908632f8b342d/pymdown_extensions-11.0.1-py3-none-any.whl", hash = "sha256:db3943a62bab7e03af1364f0c4083e64b91fb097675a4b6cceccfbe9a77e5eb2", size = 269455, upload-time = "2026-07-02T17:59:21.271Z" }, ] [[package]] @@ -1093,7 +1091,7 @@ wheels = [ [[package]] name = "raylib" version = "6.0.0.0" -source = { git = "https://github.com/commaai/dependencies.git?subdirectory=raylib&rev=release-raylib#ed1a3f64532efe2f3761a681fd9133a88e5da664" } +source = { git = "https://github.com/commaai/dependencies.git?subdirectory=raylib&rev=release-raylib#c5ba350ea0b9f6454a71cfc1f7250811db98dbff" } dependencies = [ { name = "cffi" }, ] @@ -1124,27 +1122,27 @@ wheels = [ [[package]] name = "ruff" -version = "0.15.18" +version = "0.15.20" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/74/98/1295ad5a5aa9bc85bdcdfa5d82fe7b49c61af5657df4f227637ff9de0da6/ruff-0.15.18.tar.gz", hash = "sha256:2698a964c70e8bf402dcb99c8810472d270d141e7aa8c4e13599fd52033a2f33", size = 4761437, upload-time = "2026-06-18T18:25:39.224Z" } +sdist = { url = "https://files.pythonhosted.org/packages/43/dc/35b341fc554ba02f217fc10da57d1a75168cfbcf75b0ef2202176d4c4f2d/ruff-0.15.20.tar.gz", hash = "sha256:1416eb04349192646b54de98f146c4f59afe37d0decfc02c3cbbf396f3a28566", size = 4755489, upload-time = "2026-06-25T17:20:37.578Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b9/d0/686e984941269621e2be72612d5c1e461f8f7b38415a2a7d7a81c8ae6715/ruff-0.15.18-py3-none-linux_armv6l.whl", hash = "sha256:8b6850172348c8381b8b3084c5915a4393c2373b9b54cd5b5e1ea15812bc10df", size = 10887308, upload-time = "2026-06-18T18:25:03.062Z" }, - { url = "https://files.pythonhosted.org/packages/ed/21/bc4123e3f5515ee99f8ce1eb93a14a0628fe4d1678663cd08f933ac16931/ruff-0.15.18-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:3fccc153a85417dcd976883160cacce486997b0a0058dd18f54b8aaaac7d1ce2", size = 11281305, upload-time = "2026-06-18T18:25:30.026Z" }, - { url = "https://files.pythonhosted.org/packages/51/93/4769464c25cf7ab2acb3c7dda9cad3d867eb41c59565b3e2a9d17249c90c/ruff-0.15.18-py3-none-macosx_11_0_arm64.whl", hash = "sha256:08d4c86a68f2c3ec2c9d56380a71fb4a4f65373055cbb8caabd645e9102f38d4", size = 10641215, upload-time = "2026-06-18T18:25:15.802Z" }, - { url = "https://files.pythonhosted.org/packages/6c/42/56926d17120db2c208d76bf60a1a019644dd9e91dc27f0f95c9caddb1366/ruff-0.15.18-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:37e5108745c2c0705da916d7d4de533ddf547051ef45f62888c31bae73f66318", size = 10957224, upload-time = "2026-06-18T18:25:36.955Z" }, - { url = "https://files.pythonhosted.org/packages/22/4f/d43fab8d8189afde803103022d000a8ef9f230616d436d52a8b2b8d63b50/ruff-0.15.18-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:56949a6ce8b3abde54c0bcb22cebfe57e8771cadc84b407ae8b8eaf67ebdcd43", size = 10699024, upload-time = "2026-06-18T18:25:05.707Z" }, - { url = "https://files.pythonhosted.org/packages/63/42/1e3e4c68bd408b9768cf3e439acbe2c78245225faef253f7028a0cdb63e0/ruff-0.15.18-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01a754cd6a1b630d3f97e33eb452cf7a98040482318e870f8bc52a5a30e62657", size = 11491458, upload-time = "2026-06-18T18:25:20.275Z" }, - { url = "https://files.pythonhosted.org/packages/20/77/47a3484bea8521e14a203d98c389c5c97846675e4f02734672da4a69b52a/ruff-0.15.18-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6ba7a07e03a44dbf10bb086ee06705b173625014ec99f73a7e6836a5e5590a0c", size = 12383752, upload-time = "2026-06-18T18:25:22.535Z" }, - { url = "https://files.pythonhosted.org/packages/0a/ca/054159590787023d83b658a1a1819c4c8910114e7015069340b71c0961cb/ruff-0.15.18-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5a2c40a41a4cadbcf5897b548ab29dfe248b20c540961c0247d98a3973c70403", size = 11577923, upload-time = "2026-06-18T18:25:10.702Z" }, - { url = "https://files.pythonhosted.org/packages/6d/ff/d353d6b7bbd73cc0ec37f4463d7540e45e894338abdd9964eee0de332708/ruff-0.15.18-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f0480ce690cbb6c4db6e5d08f19fce98e10ba131a8b60c1bcdac42771e3ae2d", size = 11583925, upload-time = "2026-06-18T18:25:32.391Z" }, - { url = "https://files.pythonhosted.org/packages/c1/4a/891f89b9c296ed3e5f3ece1a5629badc989d9a8fdaa30431aaf4774bc1c2/ruff-0.15.18-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:2330215f1f393fa8733f55edce04fcf94c36a2c460fcde31f78cc84e4951e9b1", size = 11582834, upload-time = "2026-06-18T18:25:27.309Z" }, - { url = "https://files.pythonhosted.org/packages/32/a3/ed9e370154bf85de360b93c03026157f02d4943b2d01ff4945f4429f8e8a/ruff-0.15.18-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:a6aa6a3d979e48ae617578183674bf264fbe7d0114a796a26bd678d67963c7ff", size = 10927328, upload-time = "2026-06-18T18:25:34.676Z" }, - { url = "https://files.pythonhosted.org/packages/f5/d1/5cf5909329fedb5d39d555ee818ba5cf4638e1a301b89785d34f2905bfcb/ruff-0.15.18-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:a81beadbbff2c9c245561ae3f77b16709d87f35eec650d0501679239d3449b22", size = 10693187, upload-time = "2026-06-18T18:25:08.245Z" }, - { url = "https://files.pythonhosted.org/packages/fd/44/ff6c635cf2c4f4e7b618b6640da057376baa36014695487d88aed4794268/ruff-0.15.18-py3-none-musllinux_1_2_i686.whl", hash = "sha256:2186d9e940ae332ab293623a75b5f4fe49565f449954d50a72a046683aa6b809", size = 11208721, upload-time = "2026-06-18T18:25:41.327Z" }, - { url = "https://files.pythonhosted.org/packages/88/d9/5baa2a30861adfb7022cf33c1e35b2fc18085b08c16f83eff4c7b99a5f48/ruff-0.15.18-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:5c2abf140438032bc77b2284a6c9944ecd8a19e5f1c7b52b1b8e4a0a80d19a7a", size = 11678599, upload-time = "2026-06-18T18:25:13.607Z" }, - { url = "https://files.pythonhosted.org/packages/c3/1a/0725a7cfdc32ff769efb96ee782bec882e16448c5d9e3be947ec4c04ce27/ruff-0.15.18-py3-none-win32.whl", hash = "sha256:02299e6e9fa5b297a3f6d5d10d7bcd655c925b028bb8b9d4588214549c6b9ec4", size = 10901903, upload-time = "2026-06-18T18:25:24.755Z" }, - { url = "https://files.pythonhosted.org/packages/f3/51/805d9f6fb7970505c3504794a5ec350f605361b807fef4dcf214ebd35e72/ruff-0.15.18-py3-none-win_amd64.whl", hash = "sha256:dac80dc8d26b2257dbefabed62f5d255c3937b4ccb122da1fc634794fa3578b3", size = 12041189, upload-time = "2026-06-18T18:25:17.915Z" }, - { url = "https://files.pythonhosted.org/packages/29/4c/67bb45e41609eb4726f1bfeb59e083cf91d14c696d4bd14c234a980be93d/ruff-0.15.18-py3-none-win_arm64.whl", hash = "sha256:b2c9257fcbd4a3e5b977a1904e6facca016bafe2edc17df24db67cfaee03b4e4", size = 11329958, upload-time = "2026-06-18T18:25:43.686Z" }, + { url = "https://files.pythonhosted.org/packages/94/d9/2d5014f0253ba541d2061d9fa7193f48e941c8b21bb88a7ff9bbe0bd0596/ruff-0.15.20-py3-none-linux_armv6l.whl", hash = "sha256:00e188c53e499c3c1637f73c91dcf2fb56d576cab76ce1be50a27c4e80e37078", size = 10839665, upload-time = "2026-06-25T17:19:44.702Z" }, + { url = "https://files.pythonhosted.org/packages/c6/d3/ac1798ba64f670698867fcfc591d50e7e421bef137db564858f619a30fcf/ruff-0.15.20-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:9ebd1fd9b9c95fc0bd7b2761aebec1f030013d2e193a2901b224af68fe47251b", size = 11208649, upload-time = "2026-06-25T17:19:48.787Z" }, + { url = "https://files.pythonhosted.org/packages/47/47/d3ac899991202095dfcf3d5176be4272642be3cf981a2f1a30f72a2afb95/ruff-0.15.20-py3-none-macosx_11_0_arm64.whl", hash = "sha256:c5b16cdd67ca108185cd36dce98c576350c03b1660a751de725fb049193a0632", size = 10622638, upload-time = "2026-06-25T17:19:51.354Z" }, + { url = "https://files.pythonhosted.org/packages/33/13/4e043fe30aa94d4ff5213a9881fc296d12960f5971b234a5263fdc225312/ruff-0.15.20-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3413bb3c3d2ca6a8208f1f4809cd2dca3c6de6d0b491c0e70847672bde6e6efd", size = 10984227, upload-time = "2026-06-25T17:19:54.044Z" }, + { url = "https://files.pythonhosted.org/packages/76/e6/92e7bf40388bc5800073b96564f56264f7e48bfd1a498f5ced6ae6d5a769/ruff-0.15.20-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bd7ec42b3bb3da066488db093308a69c4ac5ee6d2af333a86ba6e2eb2e7dd44b", size = 10622882, upload-time = "2026-06-25T17:19:57.037Z" }, + { url = "https://files.pythonhosted.org/packages/13/7a/43460be3f24495a3aa46d4b16873e2c4941b3b5f0b00cf88c03b7b94b339/ruff-0.15.20-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e1a36ad0eb77fba9aabfb69ede54de6f376d04ac18ebea022847046d340a8267", size = 11474808, upload-time = "2026-06-25T17:20:00.357Z" }, + { url = "https://files.pythonhosted.org/packages/27/a0/f37077884873221c6b33b4ab49eb18f9f88e54a16a25a5bca59bef46dd66/ruff-0.15.20-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b6df3b1e4610432f0386dba04d853b5f08cbbc903410c6fcc02f620f05aff53c", size = 12293094, upload-time = "2026-06-25T17:20:03.446Z" }, + { url = "https://files.pythonhosted.org/packages/a6/74/165545b60256a9704c21ac0ec4a0d07933b320812f9584836c9f4aca4292/ruff-0.15.20-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e89f198a1ea6ef0d727c1cf16088bc91a6cb0ab947dedc966715691647186eae", size = 11526176, upload-time = "2026-06-25T17:20:06.301Z" }, + { url = "https://files.pythonhosted.org/packages/86/b1/a976a136d40ade83ce743578399865f57001003a409acadc0ecbb3051082/ruff-0.15.20-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309809086c2acb67624950a3c8133e80f32d0d3e27106c0cd60ff26657c9f24b", size = 11520767, upload-time = "2026-06-25T17:20:09.191Z" }, + { url = "https://files.pythonhosted.org/packages/19/0f/f032696cb01c9b54c0263fa393474d7758f1cdc021a01b04e3cbc2500999/ruff-0.15.20-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:2d2374caa2f2c2f9e2b7da0a50802cfb8b79f55a9b5e49379f564544fbf56487", size = 11500132, upload-time = "2026-06-25T17:20:13.602Z" }, + { url = "https://files.pythonhosted.org/packages/4b/f4/51b1a14bc69e8c224b15dab9cce8e99b425e0455d462caa2b3c9be2b6a8e/ruff-0.15.20-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:a1ed17b65293e0c2f22fc387bc13198a5de94bf4429589b0ff6946b0feaf21a3", size = 10943828, upload-time = "2026-06-25T17:20:16.635Z" }, + { url = "https://files.pythonhosted.org/packages/71/4b/fe267640783cd02bf6c5cc290b1df1051be2ec294c678b5c15fe19e52343/ruff-0.15.20-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:f701305e66b38ea6c91882490eb73459796808e4c6362a1b765255e0cdcd4053", size = 10645418, upload-time = "2026-06-25T17:20:19.4Z" }, + { url = "https://files.pythonhosted.org/packages/b0/c0/a65aa4ec2f5e87a1df32dc3ec1fede434fe3dfd5cbcf3b503cafc676ab54/ruff-0.15.20-py3-none-musllinux_1_2_i686.whl", hash = "sha256:5b9c0c367ad8e5d0d5b5b8537864c469a0a0e55417aadfbeca41fa61333be9f4", size = 11211770, upload-time = "2026-06-25T17:20:22.033Z" }, + { url = "https://files.pythonhosted.org/packages/5a/a4/0caa331d954ae2723d729d351c989cb4ca8b6077d5c6c2cb6de75e98c041/ruff-0.15.20-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:01cc00dd58f0df339d0e902219dd53990ea99996a0344e5d9cc8d45d5307e460", size = 11618698, upload-time = "2026-06-25T17:20:25.259Z" }, + { url = "https://files.pythonhosted.org/packages/10/9b/5f14927848d2fd4aa891fd88d883788c5a7baba561c7874732364045708c/ruff-0.15.20-py3-none-win32.whl", hash = "sha256:ed65ef510e43a137207e0f01cfcf998aeddb1aeeda5c9d35023e910284d7cf21", size = 10857322, upload-time = "2026-06-25T17:20:28.612Z" }, + { url = "https://files.pythonhosted.org/packages/fa/f0/fe47c501f9dea92a26d788ff98bb5d92ed4cb4c88792c5c88af6b697dc8e/ruff-0.15.20-py3-none-win_amd64.whl", hash = "sha256:a525c81c70fb0380344dd1d8745d8cc1c890b7fc94a58d5a07bd8eb9557b8415", size = 11993274, upload-time = "2026-06-25T17:20:31.871Z" }, + { url = "https://files.pythonhosted.org/packages/d7/2b/9555445e1201d92b3195f45cdb153a0b68f24e0a4273f6e3d5ab46e212bb/ruff-0.15.20-py3-none-win_arm64.whl", hash = "sha256:2f5b2a6d614e8700388806a14996c40fab2c47b819ef57d790a34878858ed9ca", size = 11343498, upload-time = "2026-06-25T17:20:35.03Z" }, ] [[package]] @@ -1158,15 +1156,15 @@ wheels = [ [[package]] name = "sentry-sdk" -version = "2.63.0" +version = "2.64.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "certifi" }, { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ba/c8/b3c970a5b186722d276cd40a05b3254e03bccc0208560aff20f612e018e8/sentry_sdk-2.63.0.tar.gz", hash = "sha256:2a1502bf864769275dbc8c2c9fc7a0f7f5e18358180b615d262d13a31ffba216", size = 912449, upload-time = "2026-06-16T12:45:57.553Z" } +sdist = { url = "https://files.pythonhosted.org/packages/60/31/b7341f156a5f6f36f0b4845d6f1c28a2ae4799171dba7007f3a1e9b234b4/sentry_sdk-2.64.0.tar.gz", hash = "sha256:68be2c29e14ae310f8a39e1a79916b6d85c6cb41dcce789d14ff05fe293e4c55", size = 921020, upload-time = "2026-06-30T08:13:47.682Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7b/57/cb205f7d93373120f666b9c5736dc0815524d96a9b278e7a728f018dc22a/sentry_sdk-2.63.0-py3-none-any.whl", hash = "sha256:3a9b5ddd403f79eb73bd670f75f04485819db53d28f76ced7bc09041cb0dfd6a", size = 495950, upload-time = "2026-06-16T12:45:55.819Z" }, + { url = "https://files.pythonhosted.org/packages/36/a8/3fb9a4319efa3b26f5be0e90e6d8918df43fa7c7e977d26390f589501d82/sentry_sdk-2.64.0-py3-none-any.whl", hash = "sha256:715ea91ca860a819e8d8a50a7bde3a80d0df3b4ed7b6660a20fb9a2d084188f1", size = 498901, upload-time = "2026-06-30T08:13:45.566Z" }, ] [[package]] @@ -1305,11 +1303,11 @@ wheels = [ [[package]] name = "typing-extensions" -version = "4.15.0" +version = "4.16.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", size = 109391, upload-time = "2025-08-25T13:49:26.313Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f6/cc/6253133b5bb138fc3306cebfbda2c520f545d36b5be2c7255cc528bb45d6/typing_extensions-4.16.0.tar.gz", hash = "sha256:dc983d19a509c94dba722ee6abd33940f7c05a89e243c47e907eb4db6f1a43e5", size = 113555, upload-time = "2026-07-02T08:40:05.92Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614, upload-time = "2025-08-25T13:49:24.86Z" }, + { url = "https://files.pythonhosted.org/packages/49/d3/b8441a820a491ddfc024b0b0cf0393375b75ea13866d9c66727e54c2fc80/typing_extensions-4.16.0-py3-none-any.whl", hash = "sha256:481caa481374e813c1b176ada14e97f1f67a4539ce9cfeb3f350d78d6370c2e8", size = 45571, upload-time = "2026-07-02T08:40:04.659Z" }, ] [[package]] @@ -1351,7 +1349,7 @@ wheels = [ [[package]] name = "xvfb" version = "1.20.11.post1" -source = { git = "https://github.com/commaai/dependencies.git?subdirectory=xvfb&rev=release-xvfb#94b5f8acfb7d8f3b3034f2b85851512ffc7bee65" } +source = { git = "https://github.com/commaai/dependencies.git?subdirectory=xvfb&rev=release-xvfb#bd5a45c85c86d1cc6fe2bd36381b4ff8d7f728c4" } [[package]] name = "zensical" @@ -1386,7 +1384,7 @@ wheels = [ [[package]] name = "zeromq" version = "4.3.5" -source = { git = "https://github.com/commaai/dependencies.git?subdirectory=zeromq&rev=release-zeromq#28563a27b2f333688399a03c3bebea41b0cead32" } +source = { git = "https://github.com/commaai/dependencies.git?subdirectory=zeromq&rev=release-zeromq#dbdee00796b9714d318a883029bf05e844646c3b" } [[package]] name = "zstandard" @@ -1416,4 +1414,4 @@ wheels = [ [[package]] name = "zstd" version = "1.5.6" -source = { git = "https://github.com/commaai/dependencies.git?subdirectory=zstd&rev=release-zstd#96e569f08cf4a7b4a0f8181859fc791f45d0bc4e" } +source = { git = "https://github.com/commaai/dependencies.git?subdirectory=zstd&rev=release-zstd#66b1dbae3110f047af4262c1b561641d8c764e85" } From d606014ce23944d1e29e573a4d5213f2dd56f3b7 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Fri, 3 Jul 2026 09:45:08 -0700 Subject: [PATCH 107/151] ci: delete closed PR branches automatically (#38280) --- .github/workflows/repo-maintenance.yaml | 46 ++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/.github/workflows/repo-maintenance.yaml b/.github/workflows/repo-maintenance.yaml index a821f928ac..0fb1027a8d 100644 --- a/.github/workflows/repo-maintenance.yaml +++ b/.github/workflows/repo-maintenance.yaml @@ -3,6 +3,8 @@ name: repo maintenance on: schedule: - cron: "0 14 * * 1" # every Monday at 2am UTC (6am PST) + pull_request: + types: [closed] workflow_dispatch: env: @@ -12,7 +14,9 @@ jobs: package_updates: name: package_updates runs-on: ubuntu-latest - if: github.repository == 'commaai/openpilot' + if: >- + github.repository == 'commaai/openpilot' && + (github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') steps: - uses: actions/checkout@v7 with: @@ -71,3 +75,43 @@ jobs: ${{ steps.pip_tree.outputs.PIP_TREE }} ``` labels: bot + + cleanup_closed_branches: + if: github.repository == 'commaai/openpilot' + runs-on: ubuntu-latest + permissions: + contents: write + pull-requests: read + steps: + - uses: actions/github-script@v9 + with: + script: | + const { owner, repo } = context.repo; + const upstream = `${owner}/${repo}`; + + for await (const response of github.paginate.iterator(github.rest.pulls.list, { + owner, + repo, + state: 'closed', + per_page: 100, + })) { + for (const pr of response.data) { + if (pr.head.repo?.full_name !== upstream) continue; + + const branch = pr.head.ref; + try { + await github.rest.git.deleteRef({ + owner, + repo, + ref: `heads/${branch}`, + }); + console.log(`Deleted branch ${branch} (PR #${pr.number})`); + } catch (error) { + if (error.status === 422 || error.status === 403) { + console.log(`Skipping branch ${branch} (PR #${pr.number}): ${error.message}`); + continue; + } + throw error; + } + } + } From 92f3d24c8ac429436d60aa8e8a5b40b44871e4f2 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Fri, 3 Jul 2026 17:17:51 -0700 Subject: [PATCH 108/151] Remove lateral MPC library (#38281) --- SConstruct | 1 - .../controls/lib/lateral_mpc_lib/.gitignore | 2 - .../controls/lib/lateral_mpc_lib/SConscript | 104 --------- .../controls/lib/lateral_mpc_lib/__init__.py | 0 .../controls/lib/lateral_mpc_lib/lat_mpc.py | 199 ------------------ .../controls/tests/test_lateral_mpc.py | 85 -------- 6 files changed, 391 deletions(-) delete mode 100644 openpilot/selfdrive/controls/lib/lateral_mpc_lib/.gitignore delete mode 100644 openpilot/selfdrive/controls/lib/lateral_mpc_lib/SConscript delete mode 100644 openpilot/selfdrive/controls/lib/lateral_mpc_lib/__init__.py delete mode 100755 openpilot/selfdrive/controls/lib/lateral_mpc_lib/lat_mpc.py delete mode 100644 openpilot/selfdrive/controls/tests/test_lateral_mpc.py diff --git a/SConstruct b/SConstruct index 031984bf4c..b5e2d04c22 100644 --- a/SConstruct +++ b/SConstruct @@ -247,7 +247,6 @@ if arch == "larch64": # Build selfdrive SConscript([ 'openpilot/selfdrive/pandad/SConscript', - 'openpilot/selfdrive/controls/lib/lateral_mpc_lib/SConscript', 'openpilot/selfdrive/controls/lib/longitudinal_mpc_lib/SConscript', 'openpilot/selfdrive/locationd/SConscript', 'openpilot/selfdrive/modeld/SConscript', diff --git a/openpilot/selfdrive/controls/lib/lateral_mpc_lib/.gitignore b/openpilot/selfdrive/controls/lib/lateral_mpc_lib/.gitignore deleted file mode 100644 index aff2eb082b..0000000000 --- a/openpilot/selfdrive/controls/lib/lateral_mpc_lib/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -acados_ocp_lat.json -c_generated_code/ diff --git a/openpilot/selfdrive/controls/lib/lateral_mpc_lib/SConscript b/openpilot/selfdrive/controls/lib/lateral_mpc_lib/SConscript deleted file mode 100644 index 575e5c1af5..0000000000 --- a/openpilot/selfdrive/controls/lib/lateral_mpc_lib/SConscript +++ /dev/null @@ -1,104 +0,0 @@ -Import('env', 'envCython', 'arch', 'msgq_python', 'common_python', 'np_version', 'acados') - -gen = "c_generated_code" - -casadi_model = [ - f'{gen}/lat_model/lat_expl_ode_fun.c', - f'{gen}/lat_model/lat_expl_vde_forw.c', -] - -casadi_cost_y = [ - f'{gen}/lat_cost/lat_cost_y_fun.c', - f'{gen}/lat_cost/lat_cost_y_fun_jac_ut_xt.c', - f'{gen}/lat_cost/lat_cost_y_hess.c', -] - -casadi_cost_e = [ - f'{gen}/lat_cost/lat_cost_y_e_fun.c', - f'{gen}/lat_cost/lat_cost_y_e_fun_jac_ut_xt.c', - f'{gen}/lat_cost/lat_cost_y_e_hess.c', -] - -casadi_cost_0 = [ - f'{gen}/lat_cost/lat_cost_y_0_fun.c', - f'{gen}/lat_cost/lat_cost_y_0_fun_jac_ut_xt.c', - f'{gen}/lat_cost/lat_cost_y_0_hess.c', -] - -build_files = [f'{gen}/acados_solver_lat.c'] + casadi_model + casadi_cost_y + casadi_cost_e + casadi_cost_0 - -# extra generated files used to trigger a rebuild -generated_files = [ - f'{gen}/Makefile', - - f'{gen}/main_lat.c', - f'{gen}/main_sim_lat.c', - f'{gen}/acados_solver_lat.h', - f'{gen}/acados_sim_solver_lat.h', - f'{gen}/acados_sim_solver_lat.c', - f'{gen}/acados_solver.pxd', - - f'{gen}/lat_model/lat_expl_vde_adj.c', - - f'{gen}/lat_model/lat_model.h', - f'{gen}/lat_constraints/lat_constraints.h', - f'{gen}/lat_cost/lat_cost.h', -] + build_files - -acados_include_dir = Dir(acados.INCLUDE_DIR) -acados_template_dir = Dir(acados.TEMPLATE_DIR) - -source_list = ['lat_mpc.py', - '#openpilot/selfdrive/modeld/constants.py', - acados_include_dir.File('acados_c/ocp_nlp_interface.h'), - acados_template_dir.File('c_templates_tera/acados_solver.in.c'), -] - -lenv = env.Clone() -copied_acados_libs = [] -if arch != "Darwin": - for lib in ["libacados.so", "libblasfeo.so", "libhpipm.so", "libqpOASES_e.so.3.1"]: - copied_acados_libs += lenv.Command(f"{gen}/{lib}", Dir(acados.LIB_DIR).File(lib), [Mkdir(Dir(gen)), Copy("$TARGET", "$SOURCE")]) - lenv["RPATH"] += [lenv.Literal('\\$$ORIGIN')] -else: - acados_rel_path = Dir(gen).rel_path(Dir(acados.LIB_DIR)) - lenv["RPATH"] += [lenv.Literal(f'\\$$ORIGIN/{acados_rel_path}')] -lenv.Clean(generated_files, Dir(gen)) - -generated_lat = lenv.Command(generated_files, - source_list, - f"cd {Dir('.').abspath} && python3 lat_mpc.py") -lenv.Depends(generated_lat, [msgq_python, common_python]) - -lenv["CFLAGS"].append("-DACADOS_WITH_QPOASES") -lenv["CXXFLAGS"].append("-DACADOS_WITH_QPOASES") -lenv["CCFLAGS"].append("-Wno-unused") -if arch != "Darwin": - lenv["LINKFLAGS"].append("-Wl,--disable-new-dtags") -else: - lenv["LINKFLAGS"].append("-Wl,-install_name,@loader_path/libacados_ocp_solver_lat.dylib") - lenv["LINKFLAGS"].append(f"-Wl,-rpath,@loader_path/{acados_rel_path}") -lib_solver = lenv.SharedLibrary(f"{gen}/acados_ocp_solver_lat", - build_files, - LIBS=['m', 'acados', 'hpipm', 'blasfeo', 'qpOASES_e']) - -# generate cython stuff -acados_ocp_solver_pyx = acados_template_dir.File('acados_ocp_solver_pyx.pyx') -acados_ocp_solver_common = acados_template_dir.File('acados_solver_common.pxd') -libacados_ocp_solver_pxd = File(f'{gen}/acados_solver.pxd') -libacados_ocp_solver_c = File(f'{gen}/acados_ocp_solver_pyx.c') - -lenv2 = envCython.Clone() -lenv2["LIBPATH"] += [lib_solver[0].dir.abspath] -lenv2["RPATH"] += [lenv2.Literal('\\$$ORIGIN')] -lenv2.Command(libacados_ocp_solver_c, - [acados_ocp_solver_pyx, acados_ocp_solver_common, libacados_ocp_solver_pxd], - f'cython' + \ - f' -o {libacados_ocp_solver_c.get_labspath()}' + \ - f' -I {libacados_ocp_solver_pxd.get_dir().get_labspath()}' + \ - f' -I {acados_ocp_solver_common.get_dir().get_labspath()}' + \ - f' {acados_ocp_solver_pyx.get_labspath()}') -lib_cython = lenv2.Program(f'{gen}/acados_ocp_solver_pyx.so', [libacados_ocp_solver_c], LIBS=['acados_ocp_solver_lat']) -lenv2.Depends(lib_cython, lib_solver) -lenv2.Depends(lib_cython, copied_acados_libs) -lenv2.Depends(libacados_ocp_solver_c, np_version) diff --git a/openpilot/selfdrive/controls/lib/lateral_mpc_lib/__init__.py b/openpilot/selfdrive/controls/lib/lateral_mpc_lib/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/openpilot/selfdrive/controls/lib/lateral_mpc_lib/lat_mpc.py b/openpilot/selfdrive/controls/lib/lateral_mpc_lib/lat_mpc.py deleted file mode 100755 index 3b597b2e42..0000000000 --- a/openpilot/selfdrive/controls/lib/lateral_mpc_lib/lat_mpc.py +++ /dev/null @@ -1,199 +0,0 @@ -#!/usr/bin/env python3 -import os -import time -import numpy as np - -from casadi import SX, vertcat, sin, cos -# WARNING: imports outside of constants will not trigger a rebuild -from openpilot.selfdrive.modeld.constants import ModelConstants - -if __name__ == '__main__': # generating code - from acados.acados_template import AcadosModel, AcadosOcp, AcadosOcpSolver -else: - from openpilot.selfdrive.controls.lib.lateral_mpc_lib.c_generated_code.acados_ocp_solver_pyx import AcadosOcpSolverCython - -LAT_MPC_DIR = os.path.dirname(os.path.abspath(__file__)) -EXPORT_DIR = os.path.join(LAT_MPC_DIR, "c_generated_code") -JSON_FILE = os.path.join(LAT_MPC_DIR, "acados_ocp_lat.json") -X_DIM = 4 -P_DIM = 2 -COST_E_DIM = 3 -COST_DIM = COST_E_DIM + 2 -SPEED_OFFSET = 10.0 -MODEL_NAME = 'lat' -ACADOS_SOLVER_TYPE = 'SQP_RTI' -N = 32 - -def gen_lat_model(): - model = AcadosModel() - model.name = MODEL_NAME - - # set up states & controls - x_ego = SX.sym('x_ego') - y_ego = SX.sym('y_ego') - psi_ego = SX.sym('psi_ego') - psi_rate_ego = SX.sym('psi_rate_ego') - model.x = vertcat(x_ego, y_ego, psi_ego, psi_rate_ego) - - # parameters - v_ego = SX.sym('v_ego') - rotation_radius = SX.sym('rotation_radius') - model.p = vertcat(v_ego, rotation_radius) - - # controls - psi_accel_ego = SX.sym('psi_accel_ego') - model.u = vertcat(psi_accel_ego) - - # xdot - x_ego_dot = SX.sym('x_ego_dot') - y_ego_dot = SX.sym('y_ego_dot') - psi_ego_dot = SX.sym('psi_ego_dot') - psi_rate_ego_dot = SX.sym('psi_rate_ego_dot') - - model.xdot = vertcat(x_ego_dot, y_ego_dot, psi_ego_dot, psi_rate_ego_dot) - - # dynamics model - f_expl = vertcat(v_ego * cos(psi_ego) - rotation_radius * sin(psi_ego) * psi_rate_ego, - v_ego * sin(psi_ego) + rotation_radius * cos(psi_ego) * psi_rate_ego, - psi_rate_ego, - psi_accel_ego) - model.f_impl_expr = model.xdot - f_expl - model.f_expl_expr = f_expl - return model - - -def gen_lat_ocp(): - ocp = AcadosOcp() - ocp.model = gen_lat_model() - - Tf = np.array(ModelConstants.T_IDXS)[N] - - # set dimensions - ocp.dims.N = N - - # set cost module - ocp.cost.cost_type = 'NONLINEAR_LS' - ocp.cost.cost_type_e = 'NONLINEAR_LS' - - Q = np.diag(np.zeros(COST_E_DIM)) - QR = np.diag(np.zeros(COST_DIM)) - - ocp.cost.W = QR - ocp.cost.W_e = Q - - y_ego, psi_ego, psi_rate_ego = ocp.model.x[1], ocp.model.x[2], ocp.model.x[3] - psi_rate_ego_dot = ocp.model.u[0] - v_ego = ocp.model.p[0] - - ocp.parameter_values = np.zeros((P_DIM, )) - - ocp.cost.yref = np.zeros((COST_DIM, )) - ocp.cost.yref_e = np.zeros((COST_E_DIM, )) - # Add offset to smooth out low speed control - # TODO unclear if this right solution long term - v_ego_offset = v_ego + SPEED_OFFSET - # TODO there are two costs on psi_rate_ego_dot, one - # is correlated to jerk the other to steering wheel movement - # the steering wheel movement cost is added to prevent excessive - # wheel movements - ocp.model.cost_y_expr = vertcat(y_ego, - v_ego_offset * psi_ego, - v_ego_offset * psi_rate_ego, - v_ego_offset * psi_rate_ego_dot, - psi_rate_ego_dot / (v_ego + 0.1)) - ocp.model.cost_y_expr_e = vertcat(y_ego, - v_ego_offset * psi_ego, - v_ego_offset * psi_rate_ego) - - # set constraints - ocp.constraints.constr_type = 'BGH' - ocp.constraints.idxbx = np.array([2,3]) - ocp.constraints.ubx = np.array([np.radians(90), np.radians(50)]) - ocp.constraints.lbx = np.array([-np.radians(90), -np.radians(50)]) - x0 = np.zeros((X_DIM,)) - ocp.constraints.x0 = x0 - - ocp.solver_options.qp_solver = 'PARTIAL_CONDENSING_HPIPM' - ocp.solver_options.hessian_approx = 'GAUSS_NEWTON' - ocp.solver_options.integrator_type = 'ERK' - ocp.solver_options.nlp_solver_type = ACADOS_SOLVER_TYPE - ocp.solver_options.qp_solver_iter_max = 1 - ocp.solver_options.qp_solver_cond_N = 1 - - # set prediction horizon - ocp.solver_options.tf = Tf - ocp.solver_options.shooting_nodes = np.array(ModelConstants.T_IDXS)[:N+1] - - ocp.code_export_directory = EXPORT_DIR - return ocp - - -class LateralMpc: - def __init__(self, x0=None): - if x0 is None: - x0 = np.zeros(X_DIM) - self.solver = AcadosOcpSolverCython(MODEL_NAME, ACADOS_SOLVER_TYPE, N) - self.reset(x0) - - def reset(self, x0=None): - if x0 is None: - x0 = np.zeros(X_DIM) - self.x_sol = np.zeros((N+1, X_DIM)) - self.u_sol = np.zeros((N, 1)) - self.yref = np.zeros((N+1, COST_DIM)) - for i in range(N): - self.solver.cost_set(i, "yref", self.yref[i]) - self.solver.cost_set(N, "yref", self.yref[N][:COST_E_DIM]) - - # Somehow needed for stable init - for i in range(N+1): - self.solver.set(i, 'x', np.zeros(X_DIM)) - self.solver.set(i, 'p', np.zeros(P_DIM)) - self.solver.constraints_set(0, "lbx", x0) - self.solver.constraints_set(0, "ubx", x0) - self.solver.solve() - self.solution_status = 0 - self.solve_time = 0.0 - self.cost = 0 - - def set_weights(self, path_weight, heading_weight, - lat_accel_weight, lat_jerk_weight, - steering_rate_weight): - W = np.asfortranarray(np.diag([path_weight, heading_weight, - lat_accel_weight, lat_jerk_weight, - steering_rate_weight])) - for i in range(N): - self.solver.cost_set(i, 'W', W) - self.solver.cost_set(N, 'W', W[:COST_E_DIM,:COST_E_DIM]) - - def run(self, x0, p, y_pts, heading_pts, yaw_rate_pts): - x0_cp = np.copy(x0) - p_cp = np.copy(p) - self.solver.constraints_set(0, "lbx", x0_cp) - self.solver.constraints_set(0, "ubx", x0_cp) - self.yref[:,0] = y_pts - v_ego = p_cp[0, 0] - # rotation_radius = p_cp[1] - self.yref[:,1] = heading_pts * (v_ego + SPEED_OFFSET) - self.yref[:,2] = yaw_rate_pts * (v_ego + SPEED_OFFSET) - for i in range(N): - self.solver.cost_set(i, "yref", self.yref[i]) - self.solver.set(i, "p", p_cp[i]) - self.solver.set(N, "p", p_cp[N]) - self.solver.cost_set(N, "yref", self.yref[N][:COST_E_DIM]) - - t = time.monotonic() - self.solution_status = self.solver.solve() - self.solve_time = time.monotonic() - t - - for i in range(N+1): - self.x_sol[i] = self.solver.get(i, 'x') - for i in range(N): - self.u_sol[i] = self.solver.get(i, 'u') - self.cost = self.solver.get_cost() - - -if __name__ == "__main__": - ocp = gen_lat_ocp() - AcadosOcpSolver.generate(ocp, json_file=JSON_FILE) - # AcadosOcpSolver.build(ocp.code_export_directory, with_cython=True) diff --git a/openpilot/selfdrive/controls/tests/test_lateral_mpc.py b/openpilot/selfdrive/controls/tests/test_lateral_mpc.py deleted file mode 100644 index 3aa0fd1bce..0000000000 --- a/openpilot/selfdrive/controls/tests/test_lateral_mpc.py +++ /dev/null @@ -1,85 +0,0 @@ -import pytest -import numpy as np -from openpilot.selfdrive.controls.lib.lateral_mpc_lib.lat_mpc import LateralMpc -from openpilot.selfdrive.controls.lib.drive_helpers import CAR_ROTATION_RADIUS -from openpilot.selfdrive.controls.lib.lateral_mpc_lib.lat_mpc import N as LAT_MPC_N - - -def run_mpc(lat_mpc=None, v_ref=30., x_init=0., y_init=0., psi_init=0., curvature_init=0., - lane_width=3.6, poly_shift=0.): - - if lat_mpc is None: - lat_mpc = LateralMpc() - lat_mpc.set_weights(1., .1, 0.0, .05, 800) - - y_pts = poly_shift * np.ones(LAT_MPC_N + 1) - heading_pts = np.zeros(LAT_MPC_N + 1) - curv_rate_pts = np.zeros(LAT_MPC_N + 1) - - x0 = np.array([x_init, y_init, psi_init, curvature_init]) - p = np.column_stack([v_ref * np.ones(LAT_MPC_N + 1), - CAR_ROTATION_RADIUS * np.ones(LAT_MPC_N + 1)]) - - # converge in no more than 10 iterations - for _ in range(10): - lat_mpc.run(x0, p, - y_pts, heading_pts, curv_rate_pts) - return lat_mpc.x_sol - - -class TestLateralMpc: - - def _assert_null(self, sol, curvature=1e-6): - for i in range(len(sol)): - assert sol[0,i,1] == pytest.approx(0, abs=curvature) - assert sol[0,i,2] == pytest.approx(0, abs=curvature) - assert sol[0,i,3] == pytest.approx(0, abs=curvature) - - def _assert_simmetry(self, sol, curvature=1e-6): - for i in range(len(sol)): - assert sol[0,i,1] == pytest.approx(-sol[1,i,1], abs=curvature) - assert sol[0,i,2] == pytest.approx(-sol[1,i,2], abs=curvature) - assert sol[0,i,3] == pytest.approx(-sol[1,i,3], abs=curvature) - assert sol[0,i,0] == pytest.approx(sol[1,i,0], abs=curvature) - - def test_straight(self): - sol = run_mpc() - self._assert_null(np.array([sol])) - - def test_y_symmetry(self): - sol = [] - for y_init in [-0.5, 0.5]: - sol.append(run_mpc(y_init=y_init)) - self._assert_simmetry(np.array(sol)) - - def test_poly_symmetry(self): - sol = [] - for poly_shift in [-1., 1.]: - sol.append(run_mpc(poly_shift=poly_shift)) - self._assert_simmetry(np.array(sol)) - - def test_curvature_symmetry(self): - sol = [] - for curvature_init in [-0.1, 0.1]: - sol.append(run_mpc(curvature_init=curvature_init)) - self._assert_simmetry(np.array(sol)) - - def test_psi_symmetry(self): - sol = [] - for psi_init in [-0.1, 0.1]: - sol.append(run_mpc(psi_init=psi_init)) - self._assert_simmetry(np.array(sol)) - - def test_no_overshoot(self): - y_init = 1. - sol = run_mpc(y_init=y_init) - for y in list(sol[:,1]): - assert y_init >= abs(y) - - def test_switch_convergence(self): - lat_mpc = LateralMpc() - sol = run_mpc(lat_mpc=lat_mpc, poly_shift=3.0, v_ref=7.0) - right_psi_deg = np.degrees(sol[:,2]) - sol = run_mpc(lat_mpc=lat_mpc, poly_shift=-3.0, v_ref=7.0) - left_psi_deg = np.degrees(sol[:,2]) - np.testing.assert_almost_equal(right_psi_deg, -left_psi_deg, decimal=3) From 6de5d2c23a66bf3dae604a5285fc846f950d9c42 Mon Sep 17 00:00:00 2001 From: stef <19478336+stefpi@users.noreply.github.com> Date: Sun, 5 Jul 2026 20:04:06 -0700 Subject: [PATCH 109/151] revert checkout@v7 to fix nightly release (#38294) * revert back to checkout@v4 * add comment --- .github/workflows/release.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 02388f689f..6916fd5ce8 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -22,7 +22,7 @@ jobs: running-workflow-name: 'build master-ci' repo-token: ${{ secrets.GITHUB_TOKEN }} check-regexp: ^((?!.*(build prebuilt|create badges).*).)*$ - - uses: actions/checkout@v7 + - uses: actions/checkout@v4 # checkout version > v4 breaks nightly release script with: submodules: true fetch-depth: 0 From 0d93f0e820fbc103b2c02363c833a66d92e8e212 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Tue, 7 Jul 2026 10:36:49 -0700 Subject: [PATCH 110/151] declare submodules as dependencies in pyproject (#38300) * declare submodules as dependencies in pyproject * spidev * lock --- msgq_repo | 2 +- panda | 2 +- pyproject.toml | 34 ++-- uv.lock | 514 ++++++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 533 insertions(+), 19 deletions(-) diff --git a/msgq_repo b/msgq_repo index 9beb84af67..1d422a23c3 160000 --- a/msgq_repo +++ b/msgq_repo @@ -1 +1 @@ -Subproject commit 9beb84af67527f7b6bfee349dcbe3dbb8d4f4789 +Subproject commit 1d422a23c31e5b8384e9464e1bb37e7f9b677aed diff --git a/panda b/panda index 1a40b79413..9da8467a7c 160000 --- a/panda +++ b/panda @@ -1 +1 @@ -Subproject commit 1a40b79413d36222f029f46a4d5adf95766d0193 +Subproject commit 9da8467a7c3789733ba2afe751e558f6a0ea750c diff --git a/pyproject.toml b/pyproject.toml index df57623b8a..45539f534b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -48,10 +48,6 @@ dependencies = [ "av", "aiortc", - # panda - "libusb1", - "spidev; platform_system == 'Linux'", - # logging "pyzmq", "sentry-sdk", @@ -67,7 +63,6 @@ dependencies = [ # these should be removed "psutil", - "pycryptodome", # used in panda, body, and a test "setproctitle", # logreader @@ -115,6 +110,16 @@ tools = [ [project.urls] Homepage = "https://github.com/commaai/openpilot" +[dependency-groups] +submodules = [ + "msgq", + "opendbc", + "pandacan", + "rednose", + "teleoprtc", + "tinygrad", +] + [build-system] requires = ["hatchling"] build-backend = "hatchling.build" @@ -122,12 +127,6 @@ build-backend = "hatchling.build" [tool.hatch.build.targets.wheel] packages = [ "openpilot", - "msgq", - "opendbc", - "panda", - "rednose", - "teleoprtc", - "tinygrad", ] [tool.hatch.metadata] @@ -217,3 +216,16 @@ not-subscriptable = "ignore" # false positives from dynamic types [tool.uv] python-preference = "only-managed" +default-groups = ["submodules"] +override-dependencies = [ + "opendbc", # panda pins opendbc from git for standalone use; always use our submodule + "av", # teleoprtc's av<13 pin is stale +] + +[tool.uv.sources] +msgq = { path = "msgq_repo", editable = true } +opendbc = { path = "opendbc_repo", editable = true } +pandacan = { path = "panda", editable = true } +rednose = { path = "rednose_repo", editable = true } +teleoprtc = { path = "teleoprtc_repo", editable = true } +tinygrad = { path = "tinygrad_repo", editable = true } diff --git a/uv.lock b/uv.lock index cbfa688050..d32ef9121f 100644 --- a/uv.lock +++ b/uv.lock @@ -2,6 +2,12 @@ version = 1 revision = 3 requires-python = ">=3.12.3, <3.13" +[manifest] +overrides = [ + { name = "av" }, + { name = "opendbc", editable = "opendbc_repo" }, +] + [[package]] name = "acados" version = "0.2.2" @@ -10,6 +16,51 @@ dependencies = [ { name = "numpy" }, ] +[[package]] +name = "aiohappyeyeballs" +version = "2.7.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ce/f4/eec0465c2f67b2664688d0240b3212d5196fd89e741df67ddb81f8d35658/aiohappyeyeballs-2.7.1.tar.gz", hash = "sha256:065665c041c42a5938ed220bdcd7230f22527fbec085e1853d2402c8a3615d9d", size = 24757, upload-time = "2026-07-01T17:11:55.501Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/71/43/1947f06babed6b3f1d7f38b0c767f52df66bfb2bc10b468c4a7de9eceff2/aiohappyeyeballs-2.7.1-py3-none-any.whl", hash = "sha256:9243213661e29250eb41368e5daa826fc017156c3b8a11440826b2e3ed376472", size = 15038, upload-time = "2026-07-01T17:11:54.055Z" }, +] + +[[package]] +name = "aiohttp" +version = "3.14.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "aiohappyeyeballs" }, + { name = "aiosignal" }, + { name = "attrs" }, + { name = "frozenlist" }, + { name = "multidict" }, + { name = "propcache" }, + { name = "typing-extensions" }, + { name = "yarl" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/82/78/8ea7308cac6934de8c74a14f3d5f65d1c89287426688be79538d0e5c013d/aiohttp-3.14.1.tar.gz", hash = "sha256:307f2cff90a764d329e77040603fa032db89c5c24fdad50c4c15334cba744035", size = 7955794, upload-time = "2026-06-07T21:09:35.529Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1d/21/151624b51cd92553d95424daf4bf19f19ce9be9002d19253e7e7ce67197b/aiohttp-3.14.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:d35143e27778b4bb0fb189562d7f275bff79c62ab8e98459717c0ea617ff2480", size = 757402, upload-time = "2026-06-07T21:06:40.311Z" }, + { url = "https://files.pythonhosted.org/packages/c2/82/280619e0bd7bf2454987e19282616e84762255dd9c8468f62382e8c191f1/aiohttp-3.14.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:bcfb80a2cc36fba2534e5e5b5264dc7ae6fcd9bf15256da3e53d2f499e6fa29d", size = 512310, upload-time = "2026-06-07T21:06:42.207Z" }, + { url = "https://files.pythonhosted.org/packages/55/b2/2aac325583aaa1353045f96dffa586d8a34e8322e14a7ba49cffeb103ab4/aiohttp-3.14.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:27fd7c91e51729b4f7e1577865fa6d34c9adccbc39aabe9000285b48af9f0ec2", size = 512448, upload-time = "2026-06-07T21:06:43.813Z" }, + { url = "https://files.pythonhosted.org/packages/8a/72/a60607cb849faa8af8a356c9329ea2eb6f395d49e82cc82ccba1fd8deb8f/aiohttp-3.14.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:64c567bf9eaf664280116a8688f63016e6b32db2505908e2bdaca1b6438142f2", size = 1766854, upload-time = "2026-06-07T21:06:45.391Z" }, + { url = "https://files.pythonhosted.org/packages/b5/d3/d9fe1c9ec7557ab4d0d82bebaa728c6418f0b93295ec2f4ab015f7710cc7/aiohttp-3.14.1-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:f5e6ff2bdbb8f4cd3fbe41f99e25bbcd58e3bf9f13d3dd31a11e7917251cc77a", size = 1740884, upload-time = "2026-06-07T21:06:47.413Z" }, + { url = "https://files.pythonhosted.org/packages/c1/dc/f2cecfaf9337ba3e63f181500814ff502aa3d00d9c7ec93a9d23d10a27b2/aiohttp-3.14.1-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2f73e01dc37122325caf079982621262f96d74823c179038a82fddfc50359264", size = 1810034, upload-time = "2026-06-07T21:06:50.165Z" }, + { url = "https://files.pythonhosted.org/packages/66/d7/2ff65c5e65c0d7476daf7e15c032e0805e36811185b9623e3238ad6c763e/aiohttp-3.14.1-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:bb2c0c80d431c0d03f2c7dbf125150fedd4f0de17366a7ca33f7ccb822391842", size = 1904054, upload-time = "2026-06-07T21:06:52.035Z" }, + { url = "https://files.pythonhosted.org/packages/20/9c/d445818389df371f56d141d881153ba23183c4735a03f7356ffb43f7757d/aiohttp-3.14.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3e6fc1a85fa7194a1a7d19f44e8609180f4a8eb5fa4c7ed8b4355f080fad235c", size = 1790278, upload-time = "2026-06-07T21:06:54.049Z" }, + { url = "https://files.pythonhosted.org/packages/4d/aa/bf04cb4d865fc6101c2229a294ad744973b72e513fdc5a6b791e6983d72a/aiohttp-3.14.1-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:686b6c0d3911ec387b444ddf5dc62fb7f7c0a7d5186a7861626496a5ab4aff95", size = 1591795, upload-time = "2026-06-07T21:06:55.911Z" }, + { url = "https://files.pythonhosted.org/packages/dc/b4/4dac0038960427ba832f6609dfb4ea5437d7fd80c72001b9e48f834f428b/aiohttp-3.14.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:c6fa4dc7ad6f8109c70bb1499e589f76b0b792baf39f9b017eb92c8a81d0a199", size = 1728397, upload-time = "2026-06-07T21:06:57.777Z" }, + { url = "https://files.pythonhosted.org/packages/2b/f9/7cd4e8ad7aa3b75f17d56bb5498dd604a93d4e6eece822ba0568c413fff0/aiohttp-3.14.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:87a5eea1b2a5e21e1ebdbb33ad4165359189327e63fc4e4894693e7f821ac817", size = 1766504, upload-time = "2026-06-07T21:07:00.009Z" }, + { url = "https://files.pythonhosted.org/packages/f9/df/fc01d9fcad0f73fed3f3d361f1f94f975947b50dff82919f6dc2bf4316cc/aiohttp-3.14.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:1c1421eb01d4fd608d88cc8290211d177a58532b55ad94076fb349c5bf467f0a", size = 1777806, upload-time = "2026-06-07T21:07:02.064Z" }, + { url = "https://files.pythonhosted.org/packages/41/09/47e2d090bddcc8fb4ccb4c314aadc32d7c5d9bb55f50f6ad1c92fc15d501/aiohttp-3.14.1-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:34b257ec41345c1e8f2df68fa908a7952f5de932723871eb633ecbbff396c9a4", size = 1580707, upload-time = "2026-06-07T21:07:03.942Z" }, + { url = "https://files.pythonhosted.org/packages/3d/36/f1a4ce904ae0b6930cfe9afc96d0896f7ec1a620c400405d63783bb95a9c/aiohttp-3.14.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:de538791a80e5d862addbc183f70f0158ac9b9bb872bb147f1fd2a683691e087", size = 1798121, upload-time = "2026-06-07T21:07:05.987Z" }, + { url = "https://files.pythonhosted.org/packages/70/0a/e0075ce9ca0279ee1d4f0c0b85f54fea02ebc83c3007651a72bece658fec/aiohttp-3.14.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:6f71173be42d3241d428f760122febb748de0623f44308a6f120d0dd9ec572e3", size = 1767580, upload-time = "2026-06-07T21:07:07.873Z" }, + { url = "https://files.pythonhosted.org/packages/3e/61/a0c0a8f327a9c52095cdd8e312391b00d3ed64ab6c72bb5c33d8ec251cf7/aiohttp-3.14.1-cp312-cp312-win32.whl", hash = "sha256:ec8dc383ee57ea3e883477dcca3f11b65d58199f1080acaf4cd6ad9a99698be4", size = 452771, upload-time = "2026-06-07T21:07:09.669Z" }, + { url = "https://files.pythonhosted.org/packages/df/d9/ea367c75f16ac9c6cdc8febb25e8318fa21a2b1bc8d6514d4b2d890bface/aiohttp-3.14.1-cp312-cp312-win_amd64.whl", hash = "sha256:2aa92c87868cd13674989f9ee83e5f9f7ea4237589b728048e1f0c8f6caa3271", size = 479873, upload-time = "2026-06-07T21:07:11.538Z" }, + { url = "https://files.pythonhosted.org/packages/03/64/8d96784a7851156db8a4c6c3f6f91042fdf39fb15a4cc38c8b3c14833c45/aiohttp-3.14.1-cp312-cp312-win_arm64.whl", hash = "sha256:2c840c90759922cb5e6dda94596e079a30fb5a5ba548e7e0dc00574703940847", size = 448073, upload-time = "2026-06-07T21:07:13.637Z" }, +] + [[package]] name = "aioice" version = "0.10.2" @@ -41,6 +92,19 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/57/ab/31646a49209568cde3b97eeade0d28bb78b400e6645c56422c101df68932/aiortc-1.14.0-py3-none-any.whl", hash = "sha256:4b244d7e482f4e1f67e685b3468269628eca1ec91fa5b329ab517738cfca086e", size = 93183, upload-time = "2025-10-13T21:40:36.59Z" }, ] +[[package]] +name = "aiosignal" +version = "1.4.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "frozenlist" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/61/62/06741b579156360248d1ec624842ad0edf697050bbaf7c3e46394e106ad1/aiosignal-1.4.0.tar.gz", hash = "sha256:f47eecd9468083c2029cc99945502cb7708b082c232f9aca65da147157b251c7", size = 25007, upload-time = "2025-07-03T22:54:43.528Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl", hash = "sha256:053243f8b92b990551949e63930a839ff0cf0b0ebbe0597b0f3fb19e1a0fe82e", size = 7490, upload-time = "2025-07-03T22:54:42.156Z" }, +] + [[package]] name = "attrs" version = "26.1.0" @@ -218,6 +282,43 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/52/30/21b2ad45959cd50e909e02ebac1e30b4ceb7162e91c11d4c570223a458b7/coverage-7.15.0-py3-none-any.whl", hash = "sha256:56da6a4cbe8f7e9e80bd072ca9cefe67d7106a440a7ec06519ec6507ac94ad19", size = 212632, upload-time = "2026-07-02T13:10:48.641Z" }, ] +[[package]] +name = "cppcheck" +version = "1.5.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "importlib-metadata" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/9f/99/44221d5ef868b4ff2d6333fe79aaed566e62645d362e15e0bdc17dd88057/cppcheck-1.5.1.tar.gz", hash = "sha256:143e273900e35fff65396e33253f13c342df55473fe097ca1673ed3cd72b98eb", size = 36283, upload-time = "2025-04-18T05:30:40.064Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b5/04/4265922dd083da7e1002ca6fa08c0f8052aadd26dc7642ad74dcb9ca21f5/cppcheck-1.5.1-py3-none-macosx_10_9_x86_64.whl", hash = "sha256:34da2499a21ab1c7fa1934d716ce61b994d6acdce5fbfc415bf2b5b7855b6c46", size = 3168504, upload-time = "2025-04-18T05:30:15.241Z" }, + { url = "https://files.pythonhosted.org/packages/14/57/cd6d373dafc839e1bd0a77404adee971513ea098bfc1822a7b67ccc6060d/cppcheck-1.5.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:c45a1ca07a51a937f78e1d711f5104416634649afca4378f5cb5e9470a7ab969", size = 3059051, upload-time = "2025-04-18T05:30:17.193Z" }, + { url = "https://files.pythonhosted.org/packages/d5/1c/740d14f9b55e0cfad958d3555117c1d16b58b27bdaee406f633de13bd2c3/cppcheck-1.5.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ea5c2933d22df1a2ddccabbe0b071a12b9b14f07dc5d448beee4270e2049547", size = 3027427, upload-time = "2025-04-18T05:30:18.406Z" }, + { url = "https://files.pythonhosted.org/packages/04/56/ef686941c7668eaf959f72eda8304ef12f413f166b62bb2ccea92454c446/cppcheck-1.5.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2d6436afd5e1766c2070fda158af4f64639845e348d8a75740a2fb77d1dbfc54", size = 3320719, upload-time = "2025-04-18T05:30:19.984Z" }, + { url = "https://files.pythonhosted.org/packages/93/f3/0bd3b54fbd769433e87ac221f10df24a8be508605414351b901ab6ef9341/cppcheck-1.5.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:86ab2169cabf96794cf48a59ed090105f6343499c81c21f1bd607a491f57a89e", size = 3320415, upload-time = "2025-04-18T05:30:21.984Z" }, + { url = "https://files.pythonhosted.org/packages/0f/1a/06d1aa879bb223e183522d92c022e30710cadc151c841b063fdc8038e964/cppcheck-1.5.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a7c90a6b874bcb4a41568c20d786ce2ba49ec541505c1876999ca6548e4f3f52", size = 2945737, upload-time = "2025-04-18T05:30:23.637Z" }, + { url = "https://files.pythonhosted.org/packages/44/55/c3da11e6835721c92923a0f995b3bcede20daa9fd8df1462f863ae9b6a64/cppcheck-1.5.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ca87f5ed64386a40aaf156f295eac4efa6a7a819dd0415eb2d11577572e89405", size = 3136477, upload-time = "2025-04-18T05:30:25.279Z" }, + { url = "https://files.pythonhosted.org/packages/fe/bf/36bac23318403cf77cc743a15604f8153e818c366480cbdbf12080888637/cppcheck-1.5.1-py3-none-manylinux_2_31_armv7l.whl", hash = "sha256:81e79343e66bc7344d970b5f0d9a3ecafa6c5d5f7058e618e388462141c08e46", size = 2944184, upload-time = "2025-04-18T05:30:26.434Z" }, + { url = "https://files.pythonhosted.org/packages/7f/4a/488ccf07426be9fa0f54a3f5eed0762ebe9b7e692e21ade5a7578d987233/cppcheck-1.5.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:716a05569620c936acc7b2e48111d147a9d509bebc0078e926f65f5bf5f83865", size = 4216110, upload-time = "2025-04-18T05:30:27.633Z" }, + { url = "https://files.pythonhosted.org/packages/b4/ad/fbfb7a965d5cf862b40829017668c28fb358da41bde895d99fdfe61d289f/cppcheck-1.5.1-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:658d65d7842ea627241fd63f5f6dbbbc95f9f895444a8fafdc1322d6e391deab", size = 3900429, upload-time = "2025-04-18T05:30:29.395Z" }, + { url = "https://files.pythonhosted.org/packages/6c/74/01038bc7a6a64a845364e3ede7a66af5e08e197abbd6ed592d74cb23ac36/cppcheck-1.5.1-py3-none-musllinux_1_2_i686.whl", hash = "sha256:f9ac419167f2ca99b3ebd01c5777f22e06ef5ed29e26af6b0bb3060055ea3ae0", size = 4892684, upload-time = "2025-04-18T05:30:31.041Z" }, + { url = "https://files.pythonhosted.org/packages/13/62/35192d3971a5d15cfe991e3c4ae5a20db4a7ba064ea9805359635c06dff2/cppcheck-1.5.1-py3-none-musllinux_1_2_ppc64le.whl", hash = "sha256:fad05036ce457f889d9b841c0effec6aaf63634097dc8d654399ef768e2c12ea", size = 4692566, upload-time = "2025-04-18T05:30:32.299Z" }, + { url = "https://files.pythonhosted.org/packages/3d/5d/2b320e16b672e6c8a6055de2bce7f59be51bb23cb8bfbea473b121af14c3/cppcheck-1.5.1-py3-none-musllinux_1_2_s390x.whl", hash = "sha256:ded3f6b7ef0b0d71659fb653c14f3808e12cfdbe29f6bd601d29b8d2349ba47f", size = 4563106, upload-time = "2025-04-18T05:30:34.071Z" }, + { url = "https://files.pythonhosted.org/packages/32/a3/760145a26ca282ec3151e9b5be28a0598459fd389c8bc6385ca628f086f9/cppcheck-1.5.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:907d3ad5a8dabc7f73ec6e5b071f873e02044368459f1c585e5bc2067a8cce2a", size = 4545920, upload-time = "2025-04-18T05:30:35.297Z" }, + { url = "https://files.pythonhosted.org/packages/d8/f1/d46f09402e76ac878a6e458008cb9729bbe6cb2733c8f1b0c480aa15f5bb/cppcheck-1.5.1-py3-none-win32.whl", hash = "sha256:8f4733aee0dda4009725caf7592a7843fc022d043381f26de85584de84e7de29", size = 2491577, upload-time = "2025-04-18T05:30:36.419Z" }, + { url = "https://files.pythonhosted.org/packages/d0/3f/603d9db83b20fb170345483400cd1871df1bb31338af2288e49a7b431267/cppcheck-1.5.1-py3-none-win_amd64.whl", hash = "sha256:00678b255018773a3c70a106bf2112a21e05d29b2325102ea417f495944ecce9", size = 2725180, upload-time = "2025-04-18T05:30:37.491Z" }, + { url = "https://files.pythonhosted.org/packages/c5/69/a6eb66788ccc03c58f277b59c851b38485f0cf0fb1c9995680d8dc99d5b2/cppcheck-1.5.1-py3-none-win_arm64.whl", hash = "sha256:abb8265e3f692c1734db048d8df6fc380b4bbbbd0bd3f4697dbbc7a484181467", size = 2608967, upload-time = "2025-04-18T05:30:39.062Z" }, +] + +[[package]] +name = "cpplint" +version = "2.0.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c5/83/47a9e7513ba4d943a9dac2f6752b444377c91880f4f4968799b4f42d89cc/cpplint-2.0.2.tar.gz", hash = "sha256:8a5971e4b5490133e425284f0c566c7ade0b959e61018d2c9af3ff7f357ddc57", size = 373781, upload-time = "2025-04-08T01:22:26.017Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/66/65/08d3a5039b565231c501b31d1a973d4222e9803c03b2c31a9c08bdec3e30/cpplint-2.0.2-py3-none-any.whl", hash = "sha256:7ec188b5a08e604294ae7e7f88ec3ece2699de857f0533b305620c8cf237cad5", size = 81987, upload-time = "2025-04-08T01:22:24.101Z" }, +] + [[package]] name = "crcmod-plus" version = "2.3.1" @@ -356,6 +457,31 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/2c/47/c99d5268f354002ce80f8d029cd9d7d872969da1de8b93d32de4dc56d6f4/fonttools-4.63.0-py3-none-any.whl", hash = "sha256:445af2eab030a16b9171ea8bdda7ebf7d96bda2df88ee182a464252f6e05e20d", size = 1164562, upload-time = "2026-05-14T12:04:29.092Z" }, ] +[[package]] +name = "frozenlist" +version = "1.8.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/2d/f5/c831fac6cc817d26fd54c7eaccd04ef7e0288806943f7cc5bbf69f3ac1f0/frozenlist-1.8.0.tar.gz", hash = "sha256:3ede829ed8d842f6cd48fc7081d7a41001a56f1f38603f9d49bf3020d59a31ad", size = 45875, upload-time = "2025-10-06T05:38:17.865Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/69/29/948b9aa87e75820a38650af445d2ef2b6b8a6fab1a23b6bb9e4ef0be2d59/frozenlist-1.8.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:78f7b9e5d6f2fdb88cdde9440dc147259b62b9d3b019924def9f6478be254ac1", size = 87782, upload-time = "2025-10-06T05:36:06.649Z" }, + { url = "https://files.pythonhosted.org/packages/64/80/4f6e318ee2a7c0750ed724fa33a4bdf1eacdc5a39a7a24e818a773cd91af/frozenlist-1.8.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:229bf37d2e4acdaf808fd3f06e854a4a7a3661e871b10dc1f8f1896a3b05f18b", size = 50594, upload-time = "2025-10-06T05:36:07.69Z" }, + { url = "https://files.pythonhosted.org/packages/2b/94/5c8a2b50a496b11dd519f4a24cb5496cf125681dd99e94c604ccdea9419a/frozenlist-1.8.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f833670942247a14eafbb675458b4e61c82e002a148f49e68257b79296e865c4", size = 50448, upload-time = "2025-10-06T05:36:08.78Z" }, + { url = "https://files.pythonhosted.org/packages/6a/bd/d91c5e39f490a49df14320f4e8c80161cfcce09f1e2cde1edd16a551abb3/frozenlist-1.8.0-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:494a5952b1c597ba44e0e78113a7266e656b9794eec897b19ead706bd7074383", size = 242411, upload-time = "2025-10-06T05:36:09.801Z" }, + { url = "https://files.pythonhosted.org/packages/8f/83/f61505a05109ef3293dfb1ff594d13d64a2324ac3482be2cedc2be818256/frozenlist-1.8.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:96f423a119f4777a4a056b66ce11527366a8bb92f54e541ade21f2374433f6d4", size = 243014, upload-time = "2025-10-06T05:36:11.394Z" }, + { url = "https://files.pythonhosted.org/packages/d8/cb/cb6c7b0f7d4023ddda30cf56b8b17494eb3a79e3fda666bf735f63118b35/frozenlist-1.8.0-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3462dd9475af2025c31cc61be6652dfa25cbfb56cbbf52f4ccfe029f38decaf8", size = 234909, upload-time = "2025-10-06T05:36:12.598Z" }, + { url = "https://files.pythonhosted.org/packages/31/c5/cd7a1f3b8b34af009fb17d4123c5a778b44ae2804e3ad6b86204255f9ec5/frozenlist-1.8.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c4c800524c9cd9bac5166cd6f55285957fcfc907db323e193f2afcd4d9abd69b", size = 250049, upload-time = "2025-10-06T05:36:14.065Z" }, + { url = "https://files.pythonhosted.org/packages/c0/01/2f95d3b416c584a1e7f0e1d6d31998c4a795f7544069ee2e0962a4b60740/frozenlist-1.8.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d6a5df73acd3399d893dafc71663ad22534b5aa4f94e8a2fabfe856c3c1b6a52", size = 256485, upload-time = "2025-10-06T05:36:15.39Z" }, + { url = "https://files.pythonhosted.org/packages/ce/03/024bf7720b3abaebcff6d0793d73c154237b85bdf67b7ed55e5e9596dc9a/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:405e8fe955c2280ce66428b3ca55e12b3c4e9c336fb2103a4937e891c69a4a29", size = 237619, upload-time = "2025-10-06T05:36:16.558Z" }, + { url = "https://files.pythonhosted.org/packages/69/fa/f8abdfe7d76b731f5d8bd217827cf6764d4f1d9763407e42717b4bed50a0/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:908bd3f6439f2fef9e85031b59fd4f1297af54415fb60e4254a95f75b3cab3f3", size = 250320, upload-time = "2025-10-06T05:36:17.821Z" }, + { url = "https://files.pythonhosted.org/packages/f5/3c/b051329f718b463b22613e269ad72138cc256c540f78a6de89452803a47d/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:294e487f9ec720bd8ffcebc99d575f7eff3568a08a253d1ee1a0378754b74143", size = 246820, upload-time = "2025-10-06T05:36:19.046Z" }, + { url = "https://files.pythonhosted.org/packages/0f/ae/58282e8f98e444b3f4dd42448ff36fa38bef29e40d40f330b22e7108f565/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:74c51543498289c0c43656701be6b077f4b265868fa7f8a8859c197006efb608", size = 250518, upload-time = "2025-10-06T05:36:20.763Z" }, + { url = "https://files.pythonhosted.org/packages/8f/96/007e5944694d66123183845a106547a15944fbbb7154788cbf7272789536/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:776f352e8329135506a1d6bf16ac3f87bc25b28e765949282dcc627af36123aa", size = 239096, upload-time = "2025-10-06T05:36:22.129Z" }, + { url = "https://files.pythonhosted.org/packages/66/bb/852b9d6db2fa40be96f29c0d1205c306288f0684df8fd26ca1951d461a56/frozenlist-1.8.0-cp312-cp312-win32.whl", hash = "sha256:433403ae80709741ce34038da08511d4a77062aa924baf411ef73d1146e74faf", size = 39985, upload-time = "2025-10-06T05:36:23.661Z" }, + { url = "https://files.pythonhosted.org/packages/b8/af/38e51a553dd66eb064cdf193841f16f077585d4d28394c2fa6235cb41765/frozenlist-1.8.0-cp312-cp312-win_amd64.whl", hash = "sha256:34187385b08f866104f0c0617404c8eb08165ab1272e884abc89c112e9c00746", size = 44591, upload-time = "2025-10-06T05:36:24.958Z" }, + { url = "https://files.pythonhosted.org/packages/a7/06/1dc65480ab147339fecc70797e9c2f69d9cea9cf38934ce08df070fdb9cb/frozenlist-1.8.0-cp312-cp312-win_arm64.whl", hash = "sha256:fe3c58d2f5db5fbd18c2987cba06d51b0529f52bc3a6cdc33d3f4eab725104bd", size = 40102, upload-time = "2025-10-06T05:36:26.333Z" }, + { url = "https://files.pythonhosted.org/packages/9a/9a/e35b4a917281c0b8419d4207f4334c8e8c5dbf4f3f5f9ada73958d937dcc/frozenlist-1.8.0-py3-none-any.whl", hash = "sha256:0c18a16eab41e82c295618a77502e17b195883241c563b00f0aa5106fc4eaa0d", size = 13409, upload-time = "2025-10-06T05:38:16.721Z" }, +] + [[package]] name = "gcc-arm-none-eabi" version = "13.2.1" @@ -415,6 +541,27 @@ name = "imgui" version = "1.92.7" source = { git = "https://github.com/commaai/dependencies.git?subdirectory=imgui&rev=release-imgui#1964d125f4b1eded94b85b1da485f46a794f84a3" } +[[package]] +name = "importlib-metadata" +version = "9.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "zipp" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a9/01/15bb152d77b21318514a96f43af312635eb2500c96b55398d020c93d86ea/importlib_metadata-9.0.0.tar.gz", hash = "sha256:a4f57ab599e6a2e3016d7595cfd72eb4661a5106e787a95bcc90c7105b831efc", size = 56405, upload-time = "2026-03-20T06:42:56.999Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/38/3d/2d244233ac4f76e38533cfcb2991c9eb4c7bf688ae0a036d30725b8faafe/importlib_metadata-9.0.0-py3-none-any.whl", hash = "sha256:2d21d1cc5a017bd0559e36150c21c830ab1dc304dedd1b7ea85d20f45ef3edd7", size = 27789, upload-time = "2026-03-20T06:42:55.665Z" }, +] + +[[package]] +name = "importlib-resources" +version = "7.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e4/06/b56dfa750b44e86157093bc8fca0ab81dccbf5260510de4eaf1cb69b5b99/importlib_resources-7.1.0.tar.gz", hash = "sha256:0722d4c6212489c530f2a145a34c0a7a3b4721bc96a15fada5930e2a0b760708", size = 44985, upload-time = "2026-04-12T16:36:09.232Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8a/db/55a262f3606bebcae07cc14095338471ad7c0bbcaa37707e6f0ee49725b7/importlib_resources-7.1.0-py3-none-any.whl", hash = "sha256:1bd7b48b4088eddb2cd16382150bb515af0bd2c70128194392725f82ad2c96a1", size = 37232, upload-time = "2026-04-12T16:36:08.219Z" }, +] + [[package]] name = "iniconfig" version = "2.3.0" @@ -495,6 +642,19 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/b5/91/53255615acd2a1eaca307ede3c90eb550bae9c94581f8c00081b6b1c8f44/kiwisolver-1.5.0-graalpy312-graalpy250_312_native-win_amd64.whl", hash = "sha256:1f1489f769582498610e015a8ef2d36f28f505ab3096d0e16b4858a9ec214f57", size = 75987, upload-time = "2026-03-09T13:15:39.65Z" }, ] +[[package]] +name = "lefthook" +version = "2.1.9" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/92/5e/2cbfb93902906f82fa1d106b30a42e455c71599b968ab9edb86bdd487ca1/lefthook-2.1.9-py3-none-macosx_10_15_x86_64.whl", hash = "sha256:b4be037dffa2aacb312770c2c7981bb7547e0d07459e897053839b8375f66400", size = 5532741, upload-time = "2026-05-29T08:39:22.995Z" }, + { url = "https://files.pythonhosted.org/packages/b7/0e/983781b9084ef8317b45164abd3335a754973b4910dcc7d0a93c7fc4737c/lefthook-2.1.9-py3-none-macosx_11_0_arm64.whl", hash = "sha256:06754e8a56520811079063fe227b361ac8d306e5f004d103248fa57e55f997a1", size = 5053231, upload-time = "2026-05-29T08:39:31.1Z" }, + { url = "https://files.pythonhosted.org/packages/71/e3/0e8dcd17c392e13e6bdea605683f0a93bed57e72df6aea8c030d0e5d98d9/lefthook-2.1.9-py3-none-manylinux_2_17_aarch64.whl", hash = "sha256:74fa383dfb3a31913256220c59207b8d6f3d66798f50600f1683872a07c99cb5", size = 4880938, upload-time = "2026-05-29T08:39:25.637Z" }, + { url = "https://files.pythonhosted.org/packages/74/35/63cf009271a11f693691aeb47dd25d270b346a7c854a8966faf09999e8b9/lefthook-2.1.9-py3-none-manylinux_2_17_x86_64.whl", hash = "sha256:5df17f57e5e4bc3cb1b4788eda68df929a23f273ff255c632edaf1f30808a6d5", size = 5463037, upload-time = "2026-05-29T08:39:27.358Z" }, + { url = "https://files.pythonhosted.org/packages/7b/04/5dbf2107e0727e1d8cdfc20aba62d37e357577998c1abc3991cccb2a1632/lefthook-2.1.9-py3-none-win_amd64.whl", hash = "sha256:dc121e492b681e1128290fe4a0c857f6b46b6f4491c0d1b0be58dc5592e62c77", size = 5614416, upload-time = "2026-05-29T08:39:29.226Z" }, + { url = "https://files.pythonhosted.org/packages/48/e8/7923893f08504f28e0b5fb8b21795fc388d0363cfa2f412e2541c9464cb1/lefthook-2.1.9-py3-none-win_arm64.whl", hash = "sha256:6d8e3923c42a04e9375f88314ebc8c86f68879d3d0c9d856b6adbed109890e90", size = 4959833, upload-time = "2026-05-29T08:39:32.882Z" }, +] + [[package]] name = "libjpeg" version = "3.1.0" @@ -505,6 +665,24 @@ name = "libusb" version = "1.0.29" source = { git = "https://github.com/commaai/dependencies.git?subdirectory=libusb&rev=release-libusb#9c268a75b3f29495f154065064c6ee3ac79bd416" } +[[package]] +name = "libusb-package" +version = "1.0.30.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "importlib-resources" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/42/a8/8b3d5dae7340880d556f9f866874b9674b2e3a22fee1e2b96f1ab0feae36/libusb_package-1.0.30.0-py3-none-macosx_10_9_x86_64.whl", hash = "sha256:2b98784bac3bedda7e95bb5039dd0eded84b02f36110e4d5d607375366c61090", size = 69516, upload-time = "2026-06-30T07:41:02.451Z" }, + { url = "https://files.pythonhosted.org/packages/52/6f/26de4e9f858ab50e87931f0be268f3c1bbfce33e8584add60da857632142/libusb_package-1.0.30.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:4ad25f8d254bbbdd234446d5580b24d62d59bb0e690d8090457dac347f044437", size = 65700, upload-time = "2026-06-30T07:41:03.557Z" }, + { url = "https://files.pythonhosted.org/packages/11/12/9ba8fa91dc95b1cbfa4a68207d4048b08b900fd3686fa72b99846608de01/libusb_package-1.0.30.0-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c71b5f8c65b286425c02c7d624eee1fd7f08bfb1dfa492ddc20e27f06fee3829", size = 76166, upload-time = "2026-06-30T07:41:04.462Z" }, + { url = "https://files.pythonhosted.org/packages/6f/e1/a7c83535749332825f02d6693868f8ee9ae99c4104e60a483773bb652c0e/libusb_package-1.0.30.0-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f502ad5a0527b8c0431de817662325c88a1bba2cc334173665b04ad168d7b6d3", size = 76159, upload-time = "2026-06-30T07:41:05.543Z" }, + { url = "https://files.pythonhosted.org/packages/de/56/a1fb1726fc96a8ee3bd0e04e5e505500f022dd310dd348ecebf5cdae7a60/libusb_package-1.0.30.0-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:7a2a1c82f6ef85d9920cbe2898aa6927d4c487744ef9f20b0d7d6d95705095bb", size = 77162, upload-time = "2026-06-30T07:41:06.581Z" }, + { url = "https://files.pythonhosted.org/packages/7b/03/264cefc51275ecb047194c4973bc40b3b278566a64bbe6e74f86bf1e0afc/libusb_package-1.0.30.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:2ee5ef8ac6f08402b4e8334f7404850316bdd26037c9a97f2a7456ee9a5d1550", size = 76676, upload-time = "2026-06-30T07:41:07.505Z" }, + { url = "https://files.pythonhosted.org/packages/e5/95/d166eeefe0d9dd5833d5724a97b023ec380c3a2d364040ec0485fd57703c/libusb_package-1.0.30.0-py3-none-win32.whl", hash = "sha256:79728146e1f01e525786900b2ccd8298a8eca53cd94b37fb0885e56aa6f9d60a", size = 78769, upload-time = "2026-06-30T07:41:08.432Z" }, + { url = "https://files.pythonhosted.org/packages/60/4a/ff49bd77f33af05ca26fee29d601beb1e19ca791bb86efece82a3833885c/libusb_package-1.0.30.0-py3-none-win_amd64.whl", hash = "sha256:90808da724c8939a333d931d0c7226372ca5fefd98e2f2f3ef79fd918aa37522", size = 90711, upload-time = "2026-06-30T07:41:09.318Z" }, +] + [[package]] name = "libusb1" version = "3.4.0" @@ -584,6 +762,66 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/43/e3/7d92a15f894aa0c9c4b49b8ee9ac9850d6e63b03c9c32c0367a13ae62209/mpmath-1.3.0-py3-none-any.whl", hash = "sha256:a0b2b9fe80bbcd81a6647ff13108738cfb482d481d826cc0e02f5b35e5c88d2c", size = 536198, upload-time = "2023-03-07T16:47:09.197Z" }, ] +[[package]] +name = "msgq" +version = "0.0.1" +source = { editable = "msgq_repo" } +dependencies = [ + { name = "catch2" }, + { name = "codespell" }, + { name = "cppcheck" }, + { name = "cpplint" }, + { name = "cython" }, + { name = "lefthook" }, + { name = "parameterized" }, + { name = "ruff" }, + { name = "scons" }, + { name = "setuptools" }, + { name = "ty" }, +] + +[package.metadata] +requires-dist = [ + { name = "catch2", git = "https://github.com/commaai/dependencies.git?subdirectory=catch2&rev=release-catch2" }, + { name = "codespell" }, + { name = "cppcheck" }, + { name = "cpplint" }, + { name = "cython" }, + { name = "lefthook" }, + { name = "parameterized" }, + { name = "ruff" }, + { name = "scons" }, + { name = "setuptools" }, + { name = "ty" }, +] + +[[package]] +name = "multidict" +version = "6.7.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/1a/c2/c2d94cbe6ac1753f3fc980da97b3d930efe1da3af3c9f5125354436c073d/multidict-6.7.1.tar.gz", hash = "sha256:ec6652a1bee61c53a3e5776b6049172c53b6aaba34f18c9ad04f82712bac623d", size = 102010, upload-time = "2026-01-26T02:46:45.979Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8d/9c/f20e0e2cf80e4b2e4b1c365bf5fe104ee633c751a724246262db8f1a0b13/multidict-6.7.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:a90f75c956e32891a4eda3639ce6dd86e87105271f43d43442a3aedf3cddf172", size = 76893, upload-time = "2026-01-26T02:43:52.754Z" }, + { url = "https://files.pythonhosted.org/packages/fe/cf/18ef143a81610136d3da8193da9d80bfe1cb548a1e2d1c775f26b23d024a/multidict-6.7.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:3fccb473e87eaa1382689053e4a4618e7ba7b9b9b8d6adf2027ee474597128cd", size = 45456, upload-time = "2026-01-26T02:43:53.893Z" }, + { url = "https://files.pythonhosted.org/packages/a9/65/1caac9d4cd32e8433908683446eebc953e82d22b03d10d41a5f0fefe991b/multidict-6.7.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b0fa96985700739c4c7853a43c0b3e169360d6855780021bfc6d0f1ce7c123e7", size = 43872, upload-time = "2026-01-26T02:43:55.041Z" }, + { url = "https://files.pythonhosted.org/packages/cf/3b/d6bd75dc4f3ff7c73766e04e705b00ed6dbbaccf670d9e05a12b006f5a21/multidict-6.7.1-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:cb2a55f408c3043e42b40cc8eecd575afa27b7e0b956dfb190de0f8499a57a53", size = 251018, upload-time = "2026-01-26T02:43:56.198Z" }, + { url = "https://files.pythonhosted.org/packages/fd/80/c959c5933adedb9ac15152e4067c702a808ea183a8b64cf8f31af8ad3155/multidict-6.7.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:eb0ce7b2a32d09892b3dd6cc44877a0d02a33241fafca5f25c8b6b62374f8b75", size = 258883, upload-time = "2026-01-26T02:43:57.499Z" }, + { url = "https://files.pythonhosted.org/packages/86/85/7ed40adafea3d4f1c8b916e3b5cc3a8e07dfcdcb9cd72800f4ed3ca1b387/multidict-6.7.1-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:c3a32d23520ee37bf327d1e1a656fec76a2edd5c038bf43eddfa0572ec49c60b", size = 242413, upload-time = "2026-01-26T02:43:58.755Z" }, + { url = "https://files.pythonhosted.org/packages/d2/57/b8565ff533e48595503c785f8361ff9a4fde4d67de25c207cd0ba3befd03/multidict-6.7.1-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:9c90fed18bffc0189ba814749fdcc102b536e83a9f738a9003e569acd540a733", size = 268404, upload-time = "2026-01-26T02:44:00.216Z" }, + { url = "https://files.pythonhosted.org/packages/e0/50/9810c5c29350f7258180dfdcb2e52783a0632862eb334c4896ac717cebcb/multidict-6.7.1-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:da62917e6076f512daccfbbde27f46fed1c98fee202f0559adec8ee0de67f71a", size = 269456, upload-time = "2026-01-26T02:44:02.202Z" }, + { url = "https://files.pythonhosted.org/packages/f3/8d/5e5be3ced1d12966fefb5c4ea3b2a5b480afcea36406559442c6e31d4a48/multidict-6.7.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bfde23ef6ed9db7eaee6c37dcec08524cb43903c60b285b172b6c094711b3961", size = 256322, upload-time = "2026-01-26T02:44:03.56Z" }, + { url = "https://files.pythonhosted.org/packages/31/6e/d8a26d81ac166a5592782d208dd90dfdc0a7a218adaa52b45a672b46c122/multidict-6.7.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3758692429e4e32f1ba0df23219cd0b4fc0a52f476726fff9337d1a57676a582", size = 253955, upload-time = "2026-01-26T02:44:04.845Z" }, + { url = "https://files.pythonhosted.org/packages/59/4c/7c672c8aad41534ba619bcd4ade7a0dc87ed6b8b5c06149b85d3dd03f0cd/multidict-6.7.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:398c1478926eca669f2fd6a5856b6de9c0acf23a2cb59a14c0ba5844fa38077e", size = 251254, upload-time = "2026-01-26T02:44:06.133Z" }, + { url = "https://files.pythonhosted.org/packages/7b/bd/84c24de512cbafbdbc39439f74e967f19570ce7924e3007174a29c348916/multidict-6.7.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:c102791b1c4f3ab36ce4101154549105a53dc828f016356b3e3bcae2e3a039d3", size = 252059, upload-time = "2026-01-26T02:44:07.518Z" }, + { url = "https://files.pythonhosted.org/packages/fa/ba/f5449385510825b73d01c2d4087bf6d2fccc20a2d42ac34df93191d3dd03/multidict-6.7.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:a088b62bd733e2ad12c50dad01b7d0166c30287c166e137433d3b410add807a6", size = 263588, upload-time = "2026-01-26T02:44:09.382Z" }, + { url = "https://files.pythonhosted.org/packages/d7/11/afc7c677f68f75c84a69fe37184f0f82fce13ce4b92f49f3db280b7e92b3/multidict-6.7.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:3d51ff4785d58d3f6c91bdbffcb5e1f7ddfda557727043aa20d20ec4f65e324a", size = 259642, upload-time = "2026-01-26T02:44:10.73Z" }, + { url = "https://files.pythonhosted.org/packages/2b/17/ebb9644da78c4ab36403739e0e6e0e30ebb135b9caf3440825001a0bddcb/multidict-6.7.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fc5907494fccf3e7d3f94f95c91d6336b092b5fc83811720fae5e2765890dfba", size = 251377, upload-time = "2026-01-26T02:44:12.042Z" }, + { url = "https://files.pythonhosted.org/packages/ca/a4/840f5b97339e27846c46307f2530a2805d9d537d8b8bd416af031cad7fa0/multidict-6.7.1-cp312-cp312-win32.whl", hash = "sha256:28ca5ce2fd9716631133d0e9a9b9a745ad7f60bac2bccafb56aa380fc0b6c511", size = 41887, upload-time = "2026-01-26T02:44:14.245Z" }, + { url = "https://files.pythonhosted.org/packages/80/31/0b2517913687895f5904325c2069d6a3b78f66cc641a86a2baf75a05dcbb/multidict-6.7.1-cp312-cp312-win_amd64.whl", hash = "sha256:fcee94dfbd638784645b066074b338bc9cc155d4b4bffa4adce1615c5a426c19", size = 46053, upload-time = "2026-01-26T02:44:15.371Z" }, + { url = "https://files.pythonhosted.org/packages/0c/5b/aba28e4ee4006ae4c7df8d327d31025d760ffa992ea23812a601d226e682/multidict-6.7.1-cp312-cp312-win_arm64.whl", hash = "sha256:ba0a9fb644d0c1a2194cf7ffb043bd852cea63a57f66fbd33959f7dae18517bf", size = 43307, upload-time = "2026-01-26T02:44:16.852Z" }, + { url = "https://files.pythonhosted.org/packages/81/08/7036c080d7117f28a4af526d794aab6a84463126db031b007717c1a6676e/multidict-6.7.1-py3-none-any.whl", hash = "sha256:55d97cc6dae627efa6a6e548885712d4864b81110ac76fa4e534c03819fa4a56", size = 12319, upload-time = "2026-01-26T02:46:44.004Z" }, +] + [[package]] name = "ncurses" version = "6.5" @@ -608,6 +846,46 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/86/26/2e0882f4044d1b1a1b63e875151fb2393389032022a8b7f5657a7996d3b2/numpy-2.5.0-cp312-cp312-win_arm64.whl", hash = "sha256:a55e1eb2bca2cfd17a16b213c99dfc8502d47b0d494224d2122277d0400935ca", size = 10339912, upload-time = "2026-06-21T20:56:38.733Z" }, ] +[[package]] +name = "opendbc" +version = "0.3.1" +source = { editable = "opendbc_repo" } +dependencies = [ + { name = "numpy" }, + { name = "pycapnp" }, + { name = "pycryptodome" }, + { name = "tqdm" }, +] + +[package.metadata] +requires-dist = [ + { name = "cffi", marker = "extra == 'testing'" }, + { name = "codespell", marker = "extra == 'testing'" }, + { name = "cpplint", marker = "extra == 'testing'" }, + { name = "gcovr", marker = "extra == 'testing'" }, + { name = "hypothesis", marker = "extra == 'testing'", specifier = "==6.47.*" }, + { name = "inputs", marker = "extra == 'examples'" }, + { name = "jinja2", marker = "extra == 'docs'" }, + { name = "lefthook", marker = "extra == 'testing'" }, + { name = "numpy" }, + { name = "pycapnp" }, + { name = "pycryptodome" }, + { name = "ruff", marker = "extra == 'testing'" }, + { name = "tqdm" }, + { name = "tree-sitter", marker = "extra == 'testing'" }, + { name = "tree-sitter-c", marker = "extra == 'testing'" }, + { name = "ty", marker = "extra == 'testing'" }, + { name = "unittest-parallel", marker = "extra == 'testing'" }, + { name = "zstandard", marker = "extra == 'testing'" }, +] +provides-extras = ["testing", "docs", "examples"] + +[package.metadata.requires-dev] +testing = [ + { name = "comma-car-segments", url = "https://huggingface.co/datasets/commaai/commaCarSegments/resolve/main/dist/comma_car_segments-0.1.0-py3-none-any.whl" }, + { name = "cppcheck", git = "https://github.com/commaai/dependencies.git?subdirectory=cppcheck&rev=release-cppcheck" }, +] + [[package]] name = "openpilot" version = "0.1.0" @@ -633,14 +911,12 @@ dependencies = [ { name = "json11" }, { name = "libjpeg" }, { name = "libusb" }, - { name = "libusb1" }, { name = "libyuv" }, { name = "ncurses" }, { name = "numpy" }, { name = "pillow" }, { name = "psutil" }, { name = "pycapnp" }, - { name = "pycryptodome" }, { name = "pyjwt" }, { name = "pyserial" }, { name = "pyzmq" }, @@ -652,7 +928,6 @@ dependencies = [ { name = "setproctitle" }, { name = "setuptools" }, { name = "sounddevice" }, - { name = "spidev", marker = "sys_platform == 'linux'" }, { name = "sympy" }, { name = "tqdm" }, { name = "websocket-client" }, @@ -688,6 +963,16 @@ tools = [ { name = "imgui" }, ] +[package.dev-dependencies] +submodules = [ + { name = "msgq" }, + { name = "opendbc" }, + { name = "pandacan" }, + { name = "rednose" }, + { name = "teleoprtc" }, + { name = "tinygrad" }, +] + [package.metadata] requires-dist = [ { name = "acados", git = "https://github.com/commaai/dependencies.git?subdirectory=acados&rev=release-acados" }, @@ -715,7 +1000,6 @@ requires-dist = [ { name = "json11", git = "https://github.com/commaai/dependencies.git?subdirectory=json11&rev=release-json11" }, { name = "libjpeg", git = "https://github.com/commaai/dependencies.git?subdirectory=libjpeg&rev=release-libjpeg" }, { name = "libusb", git = "https://github.com/commaai/dependencies.git?subdirectory=libusb&rev=release-libusb" }, - { name = "libusb1" }, { name = "libyuv", git = "https://github.com/commaai/dependencies.git?subdirectory=libyuv&rev=release-libyuv" }, { name = "matplotlib", marker = "extra == 'dev'" }, { name = "ncurses", git = "https://github.com/commaai/dependencies.git?subdirectory=ncurses&rev=release-ncurses" }, @@ -724,7 +1008,6 @@ requires-dist = [ { name = "pre-commit-hooks", marker = "extra == 'testing'" }, { name = "psutil" }, { name = "pycapnp", specifier = "==2.1.0" }, - { name = "pycryptodome" }, { name = "pyjwt" }, { name = "pyserial" }, { name = "pytest", marker = "extra == 'testing'" }, @@ -742,7 +1025,6 @@ requires-dist = [ { name = "setproctitle" }, { name = "setuptools" }, { name = "sounddevice" }, - { name = "spidev", marker = "sys_platform == 'linux'" }, { name = "sympy" }, { name = "tqdm" }, { name = "ty", marker = "extra == 'testing'" }, @@ -756,6 +1038,16 @@ requires-dist = [ ] provides-extras = ["docs", "testing", "dev", "tools"] +[package.metadata.requires-dev] +submodules = [ + { name = "msgq", editable = "msgq_repo" }, + { name = "opendbc", editable = "opendbc_repo" }, + { name = "pandacan", editable = "panda" }, + { name = "rednose", editable = "rednose_repo" }, + { name = "teleoprtc", editable = "teleoprtc_repo" }, + { name = "tinygrad", editable = "tinygrad_repo" }, +] + [[package]] name = "packaging" version = "26.2" @@ -765,6 +1057,47 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/df/b2/87e62e8c3e2f4b32e5fe99e0b86d576da1312593b39f47d8ceef365e95ed/packaging-26.2-py3-none-any.whl", hash = "sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e", size = 100195, upload-time = "2026-04-24T20:15:22.081Z" }, ] +[[package]] +name = "pandacan" +version = "0.0.10" +source = { editable = "panda" } +dependencies = [ + { name = "libusb-package" }, + { name = "libusb1" }, + { name = "opendbc" }, + { name = "spidev", marker = "sys_platform == 'linux'" }, +] + +[package.metadata] +requires-dist = [ + { name = "cffi", marker = "extra == 'dev'" }, + { name = "cppcheck", marker = "extra == 'dev'", git = "https://github.com/commaai/dependencies.git?subdirectory=cppcheck&rev=release-cppcheck" }, + { name = "flaky", marker = "extra == 'dev'" }, + { name = "gcc-arm-none-eabi", marker = "extra == 'dev'", git = "https://github.com/commaai/dependencies.git?subdirectory=gcc-arm-none-eabi&rev=release-gcc-arm-none-eabi" }, + { name = "libusb-package" }, + { name = "libusb1" }, + { name = "opendbc", git = "https://github.com/commaai/opendbc.git?rev=master" }, + { name = "pycryptodome", marker = "extra == 'dev'", specifier = ">=3.9.8" }, + { name = "pytest", marker = "extra == 'dev'" }, + { name = "pytest-mock", marker = "extra == 'dev'" }, + { name = "pytest-timeout", marker = "extra == 'dev'" }, + { name = "pytest-xdist", marker = "extra == 'dev'" }, + { name = "ruff", marker = "extra == 'dev'" }, + { name = "scons", marker = "extra == 'dev'" }, + { name = "setuptools", marker = "extra == 'dev'" }, + { name = "spidev", marker = "sys_platform == 'linux'" }, +] +provides-extras = ["dev"] + +[[package]] +name = "parameterized" +version = "0.9.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ea/49/00c0c0cc24ff4266025a53e41336b79adaa5a4ebfad214f433d623f9865e/parameterized-0.9.0.tar.gz", hash = "sha256:7fc905272cefa4f364c1a3429cbbe9c0f98b793988efb5bf90aac80f08db09b1", size = 24351, upload-time = "2023-03-27T02:01:11.592Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/00/2f/804f58f0b856ab3bf21617cccf5b39206e6c4c94c2cd227bde125ea6105f/parameterized-0.9.0-py2.py3-none-any.whl", hash = "sha256:4e0758e3d41bea3bbd05ec14fc2c24736723f243b28d702081aef438c9372b1b", size = 20475, upload-time = "2023-03-27T02:01:09.31Z" }, +] + [[package]] name = "pillow" version = "12.3.0" @@ -803,6 +1136,32 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/12/46/eba9be9daa403fa94854ce16a458c29df9a01c6c047931c3d8be6016cd9a/pre_commit_hooks-6.0.0-py2.py3-none-any.whl", hash = "sha256:76161b76d321d2f8ee2a8e0b84c30ee8443e01376121fd1c90851e33e3bd7ee2", size = 41338, upload-time = "2025-08-09T19:25:03.513Z" }, ] +[[package]] +name = "propcache" +version = "0.5.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ec/44/c87281c333769159c50594f22610f77398a47ccbfbbf23074e744e86f87c/propcache-0.5.2.tar.gz", hash = "sha256:01c4fc7480cd0598bb4b57022df55b9ca296da7fc5a8760bd8451a7e63a7d427", size = 50208, upload-time = "2026-05-08T21:02:12.199Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4a/cb/e27bc2b2737a0bb49962b275efa051e8f1c35a936df7d5139b6b658b7dc9/propcache-0.5.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:806719138ecd720339a12410fb9614ac9b2b2d3a5fdf8235d56981c36f4039ba", size = 95887, upload-time = "2026-05-08T21:00:11.277Z" }, + { url = "https://files.pythonhosted.org/packages/e6/13/b8ae04c59392f8d11c6cd9fb4011d1dc7c86b81225c770280300e259ffe1/propcache-0.5.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:db2b80ea58eab4f86b2beec3cc8b39e8ff9276ac20e96b7cce43c8ae84cd6b5a", size = 54654, upload-time = "2026-05-08T21:00:12.604Z" }, + { url = "https://files.pythonhosted.org/packages/2c/7d/49777a3e20b55863d4794384a38acd460c04157b0a00f8602b0d508b8431/propcache-0.5.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:e5cbfac9f61484f7e9f3597775500cd3ebe8274e9b050c38f9525c77c97520bf", size = 55190, upload-time = "2026-05-08T21:00:13.935Z" }, + { url = "https://files.pythonhosted.org/packages/44/c7/085d0cd63062e84044e3f05797749c3f8e3938ff3aeb0eb2f69d43fafc91/propcache-0.5.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5dbc581d2814337da56222fab8dc5f161cd798a434e49bac27930aaef798e144", size = 59995, upload-time = "2026-05-08T21:00:15.526Z" }, + { url = "https://files.pythonhosted.org/packages/9c/42/32cf8e3009e92b2645cf1e944f701e8ea4e924dffde1ee26db860bcbf7e4/propcache-0.5.2-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:857187f381f88c8e2fa2fe56ab94879d011b883d5a2ee5a1b60a8cd2a06846d9", size = 63422, upload-time = "2026-05-08T21:00:16.824Z" }, + { url = "https://files.pythonhosted.org/packages/9e/1b/f112433f99fc979431b87a39ef169e3f8df070d99a72792c56d6937ac48b/propcache-0.5.2-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:178b4a2cdaac1818e2bf1c5a99b94383fa73ea5382e032a48dec07dc5668dc42", size = 64342, upload-time = "2026-05-08T21:00:18.362Z" }, + { url = "https://files.pythonhosted.org/packages/14/15/5574111ae50dd6e879456888c0eadd4c5a869959775854e18e18a6b345f3/propcache-0.5.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6f328175a2cde1f0ff2c4ed8ce968b9dcfb55f3a7153f39e2957ed994da13476", size = 61639, upload-time = "2026-05-08T21:00:19.692Z" }, + { url = "https://files.pythonhosted.org/packages/cc/da/4d775080b1490c0ae604acda868bd71aabe3a89ed16f2aa4339eb8a283e7/propcache-0.5.2-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:5671d09a36b06d0fd4a3da0fccbcae360e9b1570924171a15e9e0997f0249fba", size = 61588, upload-time = "2026-05-08T21:00:21.155Z" }, + { url = "https://files.pythonhosted.org/packages/04/ac/f076982cbe2195ee9cf32de5a1e46951d9fb399fc207f390562dd0fd8fb2/propcache-0.5.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:80168e2ebe4d3ec6599d10ad8f520304ae1cad9b6c5a95372aef1b66b7bfb53a", size = 60029, upload-time = "2026-05-08T21:00:22.713Z" }, + { url = "https://files.pythonhosted.org/packages/70/60/189be62e0dd898dce3b331e1b8c7a543cd3a405ac0c81fe8ee8a9d5d77e1/propcache-0.5.2-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:45f11346f884bc47444f6e6647131055844134c3175b629f84952e2b5cd62b64", size = 56774, upload-time = "2026-05-08T21:00:24.001Z" }, + { url = "https://files.pythonhosted.org/packages/ea/9e/93377b9c7939c1ffae98f878dee955efadfd638078bc86dbc21f9d52f651/propcache-0.5.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:8e778ebd44ef4f66ed60a0416b06b489687db264a9c0b3620362f26489492913", size = 63532, upload-time = "2026-05-08T21:00:25.545Z" }, + { url = "https://files.pythonhosted.org/packages/14/f9/590ef6cfb9b8028d516d287812ece32bb0bc5f11fbb9c8bf6b2e6313fec8/propcache-0.5.2-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:c0cb9ed24c8964e172768d455a38254c2dd8a552905729ce006cad3d3dda59b1", size = 61592, upload-time = "2026-05-08T21:00:27.186Z" }, + { url = "https://files.pythonhosted.org/packages/b4/5e/70958b3034c297a630bba2f17ca7abc2d5f39a803ad7e370ab79d1ecd022/propcache-0.5.2-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:1d1ad32d9d4355e2be65574fd0bfd3677e7066b009cd5b9b2dee8aa6a6393b33", size = 64788, upload-time = "2026-05-08T21:00:28.8Z" }, + { url = "https://files.pythonhosted.org/packages/12/fd/77fe5936d8c3086ca9048f7f415f122ed82e53884a9ec193646b42deef06/propcache-0.5.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c80f4ba3e8f00189165999a742ee526ebeccedf6c3f7beb0c7df821e9772435a", size = 62514, upload-time = "2026-05-08T21:00:30.098Z" }, + { url = "https://files.pythonhosted.org/packages/cf/74/66bd798b5b3be70aa1b391f5cc9d6a0a5532d7fd3b19ec0b213e72e6ad9d/propcache-0.5.2-cp312-cp312-win32.whl", hash = "sha256:8c7972d8f193740d9175f0998ab38717e6cd322d5935c5b0fef8c0d323fd9031", size = 39018, upload-time = "2026-05-08T21:00:31.622Z" }, + { url = "https://files.pythonhosted.org/packages/61/7c/5c0d34aa3024694d6dcb9271cdbdd08c4e47c1c0ad95ec7e7bc74cdea145/propcache-0.5.2-cp312-cp312-win_amd64.whl", hash = "sha256:d9ee8826a7d47863a08ac44e1a5f611a462eefc3a194b492da242128bec75b42", size = 42322, upload-time = "2026-05-08T21:00:32.918Z" }, + { url = "https://files.pythonhosted.org/packages/4d/91/875812f1a3feb20ceba818ef39fbe4d92f1081e04ac815c822496d0d038b/propcache-0.5.2-cp312-cp312-win_arm64.whl", hash = "sha256:2800a4a8ead6b28cccd1ec54b59346f0def7922ee1c7598e8499c733cfbb7c84", size = 38172, upload-time = "2026-05-08T21:00:35.124Z" }, + { url = "https://files.pythonhosted.org/packages/3a/ed/1cdcab6ba3d6ab7feca11fc14f0eeea80755bb53ef4e892079f31b10a25f/propcache-0.5.2-py3-none-any.whl", hash = "sha256:be1ddfcbb376e3de5d2e2db1d58d6d67463e6b4f9f040c000de8e300295465fe", size = 14036, upload-time = "2026-05-08T21:02:10.673Z" }, +] + [[package]] name = "psutil" version = "7.2.2" @@ -1096,6 +1455,25 @@ dependencies = [ { name = "cffi" }, ] +[[package]] +name = "rednose" +version = "0.0.1" +source = { editable = "rednose_repo" } +dependencies = [ + { name = "cffi" }, + { name = "numpy" }, + { name = "sympy" }, +] + +[package.metadata] +requires-dist = [ + { name = "cffi" }, + { name = "numpy" }, + { name = "scipy", marker = "extra == 'dev'" }, + { name = "sympy" }, +] +provides-extras = ["dev"] + [[package]] name = "requests" version = "2.34.2" @@ -1246,6 +1624,90 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/a2/09/77d55d46fd61b4a135c444fc97158ef34a095e5681d0a6c10b75bf356191/sympy-1.14.0-py3-none-any.whl", hash = "sha256:e091cc3e99d2141a0ba2847328f5479b05d94a6635cb96148ccb3f34671bd8f5", size = 6299353, upload-time = "2025-04-27T18:04:59.103Z" }, ] +[[package]] +name = "teleoprtc" +version = "1.0.1" +source = { editable = "teleoprtc_repo" } +dependencies = [ + { name = "aiohttp" }, + { name = "aiortc" }, + { name = "av" }, + { name = "numpy" }, +] + +[package.metadata] +requires-dist = [ + { name = "aiohttp", specifier = ">=3.7.0" }, + { name = "aiortc", specifier = ">=1.6.0" }, + { name = "av", specifier = ">=11.0.0,<13.0.0" }, + { name = "numpy", specifier = ">=1.19.0" }, + { name = "parameterized", marker = "extra == 'dev'", specifier = ">=0.8" }, + { name = "pre-commit", marker = "extra == 'dev'" }, + { name = "pytest", marker = "extra == 'dev'" }, + { name = "pytest-asyncio", marker = "extra == 'dev'" }, + { name = "pytest-xdist", marker = "extra == 'dev'" }, +] +provides-extras = ["dev"] + +[[package]] +name = "tinygrad" +version = "0.13.0" +source = { editable = "tinygrad_repo" } + +[package.metadata] +requires-dist = [ + { name = "black", marker = "extra == 'docs'" }, + { name = "blobfile", marker = "extra == 'testing'" }, + { name = "boto3", marker = "extra == 'testing'" }, + { name = "bottle", marker = "extra == 'testing'" }, + { name = "capstone", marker = "extra == 'testing-unit'" }, + { name = "gguf", marker = "extra == 'testing-unit'", specifier = ">=0.18" }, + { name = "hypothesis", marker = "extra == 'testing-minimal'", specifier = ">=6.148.9" }, + { name = "influxdb3-python", marker = "extra == 'testing'" }, + { name = "librosa", marker = "extra == 'testing'" }, + { name = "markdown-callouts", marker = "extra == 'docs'" }, + { name = "markdown-exec", extras = ["ansi"], marker = "extra == 'docs'" }, + { name = "mkdocs", marker = "extra == 'docs'" }, + { name = "mkdocs-material", marker = "extra == 'docs'" }, + { name = "mkdocstrings", extras = ["python"], marker = "extra == 'docs'" }, + { name = "mypy", marker = "extra == 'linting'", specifier = "==1.19.1" }, + { name = "networkx", marker = "extra == 'testing'" }, + { name = "nibabel", marker = "extra == 'testing'" }, + { name = "numba", marker = "extra == 'testing'", specifier = ">=0.55" }, + { name = "numpy", marker = "extra == 'docs'" }, + { name = "numpy", marker = "extra == 'linting'" }, + { name = "numpy", marker = "extra == 'testing-minimal'" }, + { name = "onnx", marker = "extra == 'testing'", specifier = "==1.19.0" }, + { name = "onnx2torch", marker = "extra == 'testing'" }, + { name = "onnxruntime", marker = "extra == 'testing'" }, + { name = "openai", marker = "extra == 'testing-unit'" }, + { name = "opencv-python", marker = "extra == 'testing'" }, + { name = "pandas", marker = "extra == 'testing'" }, + { name = "pillow", marker = "extra == 'testing'" }, + { name = "pre-commit", marker = "extra == 'linting'" }, + { name = "pycocotools", marker = "extra == 'testing'" }, + { name = "pylint", marker = "extra == 'linting'" }, + { name = "pytest", marker = "extra == 'testing-minimal'" }, + { name = "pytest-split", marker = "extra == 'testing-minimal'" }, + { name = "pytest-timeout", marker = "extra == 'testing-minimal'" }, + { name = "pytest-xdist", marker = "extra == 'testing-minimal'" }, + { name = "ruff", marker = "extra == 'linting'", specifier = "==0.14.10" }, + { name = "safetensors", marker = "extra == 'testing-unit'" }, + { name = "sentencepiece", marker = "extra == 'testing'" }, + { name = "tabulate", marker = "extra == 'testing-unit'" }, + { name = "tiktoken", marker = "extra == 'testing'" }, + { name = "tinygrad", extras = ["testing-minimal"], marker = "extra == 'testing-unit'" }, + { name = "tinygrad", extras = ["testing-unit"], marker = "extra == 'testing'" }, + { name = "tinymesa", marker = "extra == 'mesa'", specifier = "==25.2.7.2" }, + { name = "torch", marker = "extra == 'testing-minimal'", specifier = "==2.9.1" }, + { name = "tqdm", marker = "extra == 'testing-unit'" }, + { name = "transformers", marker = "extra == 'testing'" }, + { name = "typeguard", marker = "extra == 'linting'" }, + { name = "typing-extensions", marker = "extra == 'linting'" }, + { name = "z3-solver", marker = "extra == 'testing-minimal'", specifier = "<4.15.4" }, +] +provides-extras = ["linting", "testing-minimal", "testing-unit", "testing", "docs", "mesa"] + [[package]] name = "tomli" version = "2.4.1" @@ -1351,6 +1813,37 @@ name = "xvfb" version = "1.20.11.post1" source = { git = "https://github.com/commaai/dependencies.git?subdirectory=xvfb&rev=release-xvfb#bd5a45c85c86d1cc6fe2bd36381b4ff8d7f728c4" } +[[package]] +name = "yarl" +version = "1.24.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "idna" }, + { name = "multidict" }, + { name = "propcache" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/79/12/1e8f37460ea0f7eb59c221fdaf0ed75e7ac43e97f8093b9c6f411df50a78/yarl-1.24.2.tar.gz", hash = "sha256:9ac374123c6fd7abf64d1fec93962b0bd4ee2c19751755a762a72dd96c0378f8", size = 210798, upload-time = "2026-05-19T21:31:05.599Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f0/da/866bcb01076ba49d2b42b309867bed3826421f1c479655eb7a607b44f20b/yarl-1.24.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:b975866c184564c827e0877380f0dae57dcca7e52782128381b72feff6dfceb8", size = 129957, upload-time = "2026-05-19T21:28:51.695Z" }, + { url = "https://files.pythonhosted.org/packages/bf/1d/fcefb70922ea2268a8971d8e5874d9a8218644200fb8465f1dcad55e6851/yarl-1.24.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:3b075301a2836a0e297b1b658cb6d6135df535d62efefdd60366bd589c2c82f2", size = 92164, upload-time = "2026-05-19T21:28:53.242Z" }, + { url = "https://files.pythonhosted.org/packages/29/b6/170e2b8d4e3bc30e6bfdcca53556537f5bf595e938632dfcb059311f3ff6/yarl-1.24.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8ae44649b00947634ab0dab2a374a638f52923a6e67083f2c156cd5cbd1a881d", size = 91688, upload-time = "2026-05-19T21:28:54.865Z" }, + { url = "https://files.pythonhosted.org/packages/fe/a5/c9f655d5553ea0b99fdac9d6a99ad3f9b3e73b8e5758bb46f58c9831f74c/yarl-1.24.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:507cc19f0b45454e2d6dcd62ff7d062b9f77a2812404e62dbdaec05b50faa035", size = 102902, upload-time = "2026-05-19T21:28:56.963Z" }, + { url = "https://files.pythonhosted.org/packages/5d/bc/6b9664d815d79af4ee553337f9d606c56bbf269186ada9172de45f1b5f60/yarl-1.24.2-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:c4c17bad5a530912d2111825d3f05e89bab2dd376aaa8cbc77e449e6db63e576", size = 97931, upload-time = "2026-05-19T21:28:58.56Z" }, + { url = "https://files.pythonhosted.org/packages/98/ec/32ba48acae30fecd60928f5791188b80a9d6ee3840507ffda29fecd37b71/yarl-1.24.2-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f5f0cbb112838a4a293985b6ed73948a547dadcc1ba6d2089938e7abdedceef8", size = 111030, upload-time = "2026-05-19T21:29:00.148Z" }, + { url = "https://files.pythonhosted.org/packages/82/5a/6f4cd081e5f4934d2ae3a8ef4abe3afacc010d26f0035ee91b35cd7d7c37/yarl-1.24.2-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5ec8356b8a6afcf81fc7aeeef13b1ff7a49dec00f313394bbb9e83830d32ccd7", size = 110392, upload-time = "2026-05-19T21:29:02.155Z" }, + { url = "https://files.pythonhosted.org/packages/7a/da/323a01c349bd5fb01bb6652e314d9bb218cee630a736bdb810ad50e4013f/yarl-1.24.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7e7ebcdef69dec6c6451e616f32b622a6d4a2e92b445c992f7c8e5274a6bbc4c", size = 105612, upload-time = "2026-05-19T21:29:04.247Z" }, + { url = "https://files.pythonhosted.org/packages/7c/80/264ab684f181e1a876389374519ff05d10248725535ae2ac4e8ac4e563d6/yarl-1.24.2-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:47a55d6cf6db2f401017a9e96e5288844e5051911fb4e0c8311a3980f5e59a7d", size = 104487, upload-time = "2026-05-19T21:29:06.491Z" }, + { url = "https://files.pythonhosted.org/packages/41/07/efabe5df87e96d7ad5959760b888344be48cd6884db127b407c6b5503adc/yarl-1.24.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3065657c80a2321225e804048597ad55658a7e76b32d6f5ee4074d04c50401db", size = 102333, upload-time = "2026-05-19T21:29:08.267Z" }, + { url = "https://files.pythonhosted.org/packages/44/0c/bcf7c42603e1009295f586d8890f2ba032c8b53310e815adf0a202c73d9f/yarl-1.24.2-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:cb84b80d88e19ede158619b80813968713d8d008b0e2497a576e6a0557d50712", size = 99025, upload-time = "2026-05-19T21:29:10.682Z" }, + { url = "https://files.pythonhosted.org/packages/4f/82/84482ab1a57a0f21a08afe6a7004c61d741f8f2ecc3b05c321577c612164/yarl-1.24.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:990de4f680b1c217e77ff0d6aa0029f9eb79889c11fb3e9a3942c7eba29c1996", size = 110507, upload-time = "2026-05-19T21:29:12.954Z" }, + { url = "https://files.pythonhosted.org/packages/c4/8d/a546ba1dfe1b0f290e05fef145cd07614c0f15df1a707195e512d1e39d1d/yarl-1.24.2-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:abb8ec0323b80161e3802da3150ef660b41d0e9be2048b76a363d93eee992c2b", size = 103719, upload-time = "2026-05-19T21:29:14.893Z" }, + { url = "https://files.pythonhosted.org/packages/1a/b6/267f2a09213138473adfce6b8a6e17791d7fee70bd4d9003218e4dec58b0/yarl-1.24.2-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:e7977781f83638a4c73e0f88425563d70173e0dfd90ac006a45c65036293ee3c", size = 110438, upload-time = "2026-05-19T21:29:16.485Z" }, + { url = "https://files.pythonhosted.org/packages/48/2d/1c8d89c7c5f9cad9fb2902445d94e2ab1d7aa35de029afbb8ae95c42d00f/yarl-1.24.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e30dd55825dc554ec5b66a94953b8eda8745926514c5089dfcacecb9c99b5bd1", size = 105719, upload-time = "2026-05-19T21:29:18.367Z" }, + { url = "https://files.pythonhosted.org/packages/a7/25/722e3b93bd687009afb2d59a35e13d30ddd8f80571445bb0c4e4ce26ec66/yarl-1.24.2-cp312-cp312-win_amd64.whl", hash = "sha256:7dafe10c12ddd4d120d528c4b5599c953bd7b12845347d507b95451195bb6cad", size = 92901, upload-time = "2026-05-19T21:29:20.014Z" }, + { url = "https://files.pythonhosted.org/packages/39/47/4486ccfb674c04854a1ef8aa77868b6a6f765feaf69633409d7ca4f02cb8/yarl-1.24.2-cp312-cp312-win_arm64.whl", hash = "sha256:044a09d8401fcf8681977faef6d286b8ade1e2d2e9dceda175d1cfa5ca496f30", size = 87229, upload-time = "2026-05-19T21:29:22.1Z" }, + { url = "https://files.pythonhosted.org/packages/fd/4d/4b880086bd0d3e034d25647be1d830afc3e3f610e98c4ab3490af6b1b6d5/yarl-1.24.2-py3-none-any.whl", hash = "sha256:2783d9226db8797636cd6896e4de81feed252d1db72265686c9558d97a4d94b9", size = 53576, upload-time = "2026-05-19T21:31:03.909Z" }, +] + [[package]] name = "zensical" version = "0.0.46" @@ -1386,6 +1879,15 @@ name = "zeromq" version = "4.3.5" source = { git = "https://github.com/commaai/dependencies.git?subdirectory=zeromq&rev=release-zeromq#dbdee00796b9714d318a883029bf05e844646c3b" } +[[package]] +name = "zipp" +version = "4.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b9/d8/eab98a517c14134c0b2eb4e2387bc5f457334293ec5d2dd3857ec2966802/zipp-4.1.0.tar.gz", hash = "sha256:4cb57381f544315db7688e976e922a2b18cdb513d21cc194eb42232ba2a3e602", size = 26214, upload-time = "2026-05-18T20:08:57.967Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3a/13/547360d81e6d88d58492968ffda9f9542854f11310ee556fef14260cc886/zipp-4.1.0-py3-none-any.whl", hash = "sha256:25ad4e16390cd314347dd8f1de67a2ac538ae658ed4ab9db16029c07c188e97f", size = 10238, upload-time = "2026-05-18T20:08:57.045Z" }, +] + [[package]] name = "zstandard" version = "0.25.0" From c02cf706a6c9cbc2bc417a2f1f35df2ea4433196 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Tue, 7 Jul 2026 14:09:32 -0700 Subject: [PATCH 111/151] fix cabana launch script --- openpilot/tools/cabana/cabana | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openpilot/tools/cabana/cabana b/openpilot/tools/cabana/cabana index a51b395090..db613b5391 100755 --- a/openpilot/tools/cabana/cabana +++ b/openpilot/tools/cabana/cabana @@ -2,7 +2,7 @@ set -e DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" -ROOT="$(cd "$DIR/../../" && pwd)" +ROOT="$(cd "$DIR/../../../" && pwd)" install_qt() { if [[ "$(uname)" == "Darwin" ]]; then @@ -33,6 +33,6 @@ fi # Build _cabana cd "$ROOT" -scons openpilot/tools/cabana/_cabana openpilot/cereal/messaging/bridge +scons -u openpilot/tools/cabana/_cabana openpilot/cereal/messaging/bridge exec "$DIR/_cabana" "$@" From 1b6e127e6838cb6cf25e5f6c3f13f02631e5d0b5 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Tue, 7 Jul 2026 15:40:56 -0700 Subject: [PATCH 112/151] fix juggle.py --- openpilot/tools/plotjuggler/juggle.py | 1 + 1 file changed, 1 insertion(+) diff --git a/openpilot/tools/plotjuggler/juggle.py b/openpilot/tools/plotjuggler/juggle.py index 593192ed30..6ddbdbeb3e 100755 --- a/openpilot/tools/plotjuggler/juggle.py +++ b/openpilot/tools/plotjuggler/juggle.py @@ -96,6 +96,7 @@ def start_juggler(fn=None, dbc=None, layout=None, route_or_segment_name=None, pl dst.write(contents) os.symlink(os.path.join(BASEDIR, "openpilot", "cereal", "include"), os.path.join(tmp_cereal, "include"), target_is_directory=True) os.symlink(os.path.join(BASEDIR, "opendbc_repo", "opendbc", "car", "car.capnp"), os.path.join(tmp_cereal, "car.capnp")) + os.symlink(os.path.join(BASEDIR, "opendbc_repo", "opendbc"), os.path.join(schema_root, "opendbc"), target_is_directory=True) env["BASEDIR"] = schema_root subprocess.call(cmd, shell=True, env=env, cwd=juggle_dir) From 05cf8023a90d039f4c123f3a912a71e5ed0b475a Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Tue, 7 Jul 2026 16:14:26 -0700 Subject: [PATCH 113/151] fix cabana --- openpilot/tools/cabana/SConscript | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpilot/tools/cabana/SConscript b/openpilot/tools/cabana/SConscript index 92e95d3cc2..5a6ea7baf5 100644 --- a/openpilot/tools/cabana/SConscript +++ b/openpilot/tools/cabana/SConscript @@ -78,7 +78,7 @@ cabana_env['LIBPATH'] += [libusb.LIB_DIR] cabana_libs = [cereal, messaging, visionipc, replay_lib, 'avformat', 'avcodec', 'swresample', 'avutil', 'x264', 'z', 'bz2', 'zstd', 'yuv', 'usb-1.0'] + base_libs if arch != "Darwin": cabana_libs += ['va', 'va-drm', 'drm'] -opendbc_path = '-DOPENDBC_FILE_PATH=\'"%s"\'' % (cabana_env.Dir("../../opendbc/dbc").abspath) +opendbc_path = '-DOPENDBC_FILE_PATH=\'"%s"\'' % (cabana_env.Dir("../../../opendbc/dbc").abspath) cabana_env['CXXFLAGS'] += [opendbc_path] def write_assets_qrc(target, source, env): From 960c988355826ee1c51facb7fdee8bea534c22a8 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Wed, 8 Jul 2026 11:53:47 -0700 Subject: [PATCH 114/151] Replace xvfb with headless raylib backend (#38298) --- .github/workflows/tests.yaml | 13 ++++++++----- openpilot/selfdrive/test/setup_xvfb.sh | 22 ---------------------- pyproject.toml | 1 - uv.lock | 19 ++----------------- 4 files changed, 10 insertions(+), 45 deletions(-) delete mode 100755 openpilot/selfdrive/test/setup_xvfb.sh diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 0b3d1c0d76..d732dd83dc 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -110,8 +110,9 @@ jobs: run: scons - name: Run unit tests timeout-minutes: ${{ contains(runner.name, 'nsc') && 2 || 20 }} + env: + RAYLIB_BACKEND: headless run: | - source openpilot/selfdrive/test/setup_xvfb.sh # Pre-compile Python bytecode so each pytest worker doesn't need to $PYTEST --collect-only -m 'not slow' -qq MAX_EXAMPLES=1 $PYTEST -m 'not slow' @@ -206,9 +207,10 @@ jobs: run: scons - name: Driving test timeout-minutes: 2 - run: | - source openpilot/selfdrive/test/setup_xvfb.sh - pytest -s openpilot/tools/sim/tests/test_metadrive_bridge.py + env: + # MetaDrive renders offscreen through panda3d's EGL pipe on llvmpipe + EGL_PLATFORM: surfaceless + run: pytest -s openpilot/tools/sim/tests/test_metadrive_bridge.py create_ui_report: name: Create UI Report @@ -226,8 +228,9 @@ jobs: - name: Build openpilot run: scons - name: Create UI Report + env: + RAYLIB_BACKEND: headless run: | - source openpilot/selfdrive/test/setup_xvfb.sh python3 openpilot/selfdrive/ui/tests/diff/replay.py python3 openpilot/selfdrive/ui/tests/diff/replay.py --big - name: Upload UI Report diff --git a/openpilot/selfdrive/test/setup_xvfb.sh b/openpilot/selfdrive/test/setup_xvfb.sh deleted file mode 100755 index 50b313658d..0000000000 --- a/openpilot/selfdrive/test/setup_xvfb.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/usr/bin/env bash - -# Sets up a virtual display for running map renderer and simulator without an X11 display - -if uname -r | grep -q "WSL2"; then - DISP_ID=0 # WSLg uses display :0 -else - DISP_ID=99 # Standard Xvfb display -fi -export DISPLAY=:$DISP_ID - -Xvfb $DISPLAY -screen 0 2160x1080x24 2>/dev/null & - -# check for x11 socket for the specified display ID -while [ ! -S /tmp/.X11-unix/X$DISP_ID ] -do - echo "Waiting for Xvfb..." - sleep 1 -done - -touch ~/.Xauthority -export XDG_SESSION_TYPE="x11" \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index 45539f534b..99c38023c9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -42,7 +42,6 @@ dependencies = [ "json11 @ git+https://github.com/commaai/dependencies.git@release-json11#subdirectory=json11", "git-lfs @ git+https://github.com/commaai/dependencies.git@release-git-lfs#subdirectory=git-lfs", "gcc-arm-none-eabi @ git+https://github.com/commaai/dependencies.git@release-gcc-arm-none-eabi#subdirectory=gcc-arm-none-eabi", - "xvfb @ git+https://github.com/commaai/dependencies.git@release-xvfb#subdirectory=xvfb", # body / webrtcd "av", diff --git a/uv.lock b/uv.lock index d32ef9121f..d64cf10cd6 100644 --- a/uv.lock +++ b/uv.lock @@ -932,7 +932,6 @@ dependencies = [ { name = "tqdm" }, { name = "websocket-client" }, { name = "xattr" }, - { name = "xvfb" }, { name = "zeromq" }, { name = "zstandard" }, { name = "zstd" }, @@ -1030,7 +1029,6 @@ requires-dist = [ { name = "ty", marker = "extra == 'testing'" }, { name = "websocket-client" }, { name = "xattr" }, - { name = "xvfb", git = "https://github.com/commaai/dependencies.git?subdirectory=xvfb&rev=release-xvfb" }, { name = "zensical", marker = "extra == 'docs'" }, { name = "zeromq", git = "https://github.com/commaai/dependencies.git?subdirectory=zeromq&rev=release-zeromq" }, { name = "zstandard" }, @@ -1065,7 +1063,6 @@ dependencies = [ { name = "libusb-package" }, { name = "libusb1" }, { name = "opendbc" }, - { name = "spidev", marker = "sys_platform == 'linux'" }, ] [package.metadata] @@ -1085,7 +1082,6 @@ requires-dist = [ { name = "ruff", marker = "extra == 'dev'" }, { name = "scons", marker = "extra == 'dev'" }, { name = "setuptools", marker = "extra == 'dev'" }, - { name = "spidev", marker = "sys_platform == 'linux'" }, ] provides-extras = ["dev"] @@ -1449,8 +1445,8 @@ wheels = [ [[package]] name = "raylib" -version = "6.0.0.0" -source = { git = "https://github.com/commaai/dependencies.git?subdirectory=raylib&rev=release-raylib#c5ba350ea0b9f6454a71cfc1f7250811db98dbff" } +version = "6.0.0.1" +source = { git = "https://github.com/commaai/dependencies.git?subdirectory=raylib&rev=release-raylib#b5439c0c8178e5c2fee90eb396708ae1524a2662" } dependencies = [ { name = "cffi" }, ] @@ -1606,12 +1602,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/4e/39/a61d4b83a7746b70d23d9173be688c0c6bfc7173772344b7442c2c155497/sounddevice-0.5.5-py3-none-win_arm64.whl", hash = "sha256:3861901ddd8230d2e0e8ae62ac320cdd4c688d81df89da036dcb812f757bb3e6", size = 317115, upload-time = "2026-01-23T18:36:42.235Z" }, ] -[[package]] -name = "spidev" -version = "3.8" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/67/87/039b6eeea781598015b538691bc174cc0bf77df9d4d2d3b8bf9245c0de8c/spidev-3.8.tar.gz", hash = "sha256:2bc02fb8c6312d519ebf1f4331067427c0921d3f77b8bcaf05189a2e8b8382c0", size = 13893, upload-time = "2025-09-15T18:56:20.672Z" } - [[package]] name = "sympy" version = "1.14.0" @@ -1808,11 +1798,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/38/63/188f7cb41ab35d795558325d5cc8ab552171d5498cfb178fd14409651e18/xattr-1.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2aaa5d66af6523332189108f34e966ca120ff816dfa077ca34b31e6263f8a236", size = 37754, upload-time = "2025-10-13T22:16:15.306Z" }, ] -[[package]] -name = "xvfb" -version = "1.20.11.post1" -source = { git = "https://github.com/commaai/dependencies.git?subdirectory=xvfb&rev=release-xvfb#bd5a45c85c86d1cc6fe2bd36381b4ff8d7f728c4" } - [[package]] name = "yarl" version = "1.24.2" From cb82722dd558425f2c365ca29e96e8fc63f80ee3 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Wed, 8 Jul 2026 12:21:22 -0700 Subject: [PATCH 115/151] remove libjpeg (#38305) * remove libjpeg * lil smaller * happy linter --- SConstruct | 2 +- openpilot/system/loggerd/SConscript | 2 +- .../system/loggerd/encoder/jpeg_encoder.cc | 118 ++++++++++-------- .../system/loggerd/encoder/jpeg_encoder.h | 21 ++-- pyproject.toml | 1 - uv.lock | 6 - 6 files changed, 78 insertions(+), 72 deletions(-) diff --git a/SConstruct b/SConstruct index b5e2d04c22..d73bb4b22c 100644 --- a/SConstruct +++ b/SConstruct @@ -40,7 +40,7 @@ assert arch in [ "Darwin", # macOS arm64 (x86 not supported) ] -pkg_names = ['acados', 'bzip2', 'capnproto', 'catch2', 'eigen', 'ffmpeg', 'json11', 'libjpeg', 'libyuv', 'ncurses', 'zeromq', 'zstd'] +pkg_names = ['acados', 'bzip2', 'capnproto', 'catch2', 'eigen', 'ffmpeg', 'json11', 'libyuv', 'ncurses', 'zeromq', 'zstd'] pkgs = [importlib.import_module(name) for name in pkg_names] acados = pkgs[pkg_names.index('acados')] acados_include_dirs = [ diff --git a/openpilot/system/loggerd/SConscript b/openpilot/system/loggerd/SConscript index a638704dca..f83e3f04ff 100644 --- a/openpilot/system/loggerd/SConscript +++ b/openpilot/system/loggerd/SConscript @@ -21,7 +21,7 @@ logger_lib = env.Library('logger', src) libs.insert(0, logger_lib) env.Program('loggerd', ['loggerd.cc'], LIBS=libs, FRAMEWORKS=frameworks) -env.Program('encoderd', ['encoderd.cc'], LIBS=libs + ["jpeg"], FRAMEWORKS=frameworks) +env.Program('encoderd', ['encoderd.cc'], LIBS=libs, FRAMEWORKS=frameworks) env.Program('bootlog.cc', LIBS=libs, FRAMEWORKS=frameworks) if GetOption('extras'): diff --git a/openpilot/system/loggerd/encoder/jpeg_encoder.cc b/openpilot/system/loggerd/encoder/jpeg_encoder.cc index 6bb946157c..79f5e1b80f 100644 --- a/openpilot/system/loggerd/encoder/jpeg_encoder.cc +++ b/openpilot/system/loggerd/encoder/jpeg_encoder.cc @@ -3,16 +3,50 @@ #include #include -JpegEncoder::JpegEncoder(const std::string &pusblish_name, int width, int height) - : publish_name(pusblish_name), thumbnail_width(width), thumbnail_height(height) { - yuv_buffer.resize((thumbnail_width * ((thumbnail_height + 15) & ~15) * 3) / 2); - pm = std::make_unique(std::vector{pusblish_name.c_str()}); +#include "common/swaglog.h" + +// Lower qscale = higher quality / bigger files for MJPEG. +constexpr int MJPEG_QSCALE = 7; + +JpegEncoder::JpegEncoder(const std::string &publish_name, int width, int height) + : publish_name(publish_name), thumbnail_width(width), thumbnail_height(height) { + yuv_buffer.resize((thumbnail_width * thumbnail_height * 3) / 2); + pm = std::make_unique(std::vector{publish_name.c_str()}); + + const AVCodec *codec = avcodec_find_encoder(AV_CODEC_ID_MJPEG); + assert(codec); + + codec_ctx = avcodec_alloc_context3(codec); + assert(codec_ctx); + codec_ctx->width = thumbnail_width; + codec_ctx->height = thumbnail_height; + codec_ctx->pix_fmt = AV_PIX_FMT_YUV420P; + codec_ctx->time_base = (AVRational){1, 1}; + codec_ctx->color_range = AVCOL_RANGE_JPEG; + codec_ctx->flags |= AV_CODEC_FLAG_QSCALE; + codec_ctx->global_quality = FF_QP2LAMBDA * MJPEG_QSCALE; + + int err = avcodec_open2(codec_ctx, codec, NULL); + assert(err >= 0); + + frame = av_frame_alloc(); + assert(frame); + frame->format = codec_ctx->pix_fmt; + frame->width = thumbnail_width; + frame->height = thumbnail_height; + frame->linesize[0] = thumbnail_width; + frame->linesize[1] = thumbnail_width / 2; + frame->linesize[2] = thumbnail_width / 2; + frame->color_range = AVCOL_RANGE_JPEG; + + pkt = av_packet_alloc(); + assert(pkt); } JpegEncoder::~JpegEncoder() { - if (out_buffer) { - free(out_buffer); - } + av_packet_free(&pkt); + av_frame_free(&frame); + avcodec_free_context(&codec_ctx); } void JpegEncoder::pushThumbnail(VisionBuf *buf, const VisionIpcBufExtra &extra) { @@ -22,7 +56,7 @@ void JpegEncoder::pushThumbnail(VisionBuf *buf, const VisionIpcBufExtra &extra) auto thumbnaild = msg.initEvent().initThumbnail(); thumbnaild.setFrameId(extra.frame_id); thumbnaild.setTimestampEof(extra.timestamp_eof); - thumbnaild.setThumbnail({out_buffer, out_size}); + thumbnaild.setThumbnail({out_buffer.data(), out_buffer.size()}); pm->send(publish_name.c_str(), msg); } @@ -31,12 +65,11 @@ void JpegEncoder::generateThumbnail(const uint8_t *y_addr, const uint8_t *uv_add int downscale = width / thumbnail_width; assert(downscale * thumbnail_height == height); - // make the buffer big enough. jpeg_write_raw_data requires 16-pixels aligned height to be used. uint8_t *y_plane = yuv_buffer.data(); uint8_t *u_plane = y_plane + thumbnail_width * thumbnail_height; uint8_t *v_plane = u_plane + (thumbnail_width * thumbnail_height) / 4; { - // subsampled conversion from nv12 to yuv + // subsampled conversion from nv12 to yuv420p for (int hy = 0; hy < thumbnail_height / 2; hy++) { for (int hx = 0; hx < thumbnail_width / 2; hx++) { int ix = hx * downscale + (downscale - 1) / 2; @@ -55,51 +88,28 @@ void JpegEncoder::generateThumbnail(const uint8_t *y_addr, const uint8_t *uv_add } void JpegEncoder::compressToJpeg(uint8_t *y_plane, uint8_t *u_plane, uint8_t *v_plane) { - struct jpeg_compress_struct cinfo; - struct jpeg_error_mgr jerr; - cinfo.err = jpeg_std_error(&jerr); - jpeg_create_compress(&cinfo); + frame->data[0] = y_plane; + frame->data[1] = u_plane; + frame->data[2] = v_plane; + // Required for MJPEG qscale to take effect (global_quality alone is not enough). + frame->quality = FF_QP2LAMBDA * MJPEG_QSCALE; + frame->pts = 0; - if (out_buffer) { - free(out_buffer); - out_buffer = nullptr; - out_size = 0; - } - jpeg_mem_dest(&cinfo, &out_buffer, &out_size); - - cinfo.image_width = thumbnail_width; - cinfo.image_height = thumbnail_height; - cinfo.input_components = 3; - - jpeg_set_defaults(&cinfo); - jpeg_set_colorspace(&cinfo, JCS_YCbCr); - // configure sampling factors for yuv420. - cinfo.comp_info[0].h_samp_factor = 2; // Y - cinfo.comp_info[0].v_samp_factor = 2; - cinfo.comp_info[1].h_samp_factor = 1; // U - cinfo.comp_info[1].v_samp_factor = 1; - cinfo.comp_info[2].h_samp_factor = 1; // V - cinfo.comp_info[2].v_samp_factor = 1; - cinfo.raw_data_in = TRUE; - - jpeg_set_quality(&cinfo, 50, TRUE); - jpeg_start_compress(&cinfo, TRUE); - - JSAMPROW y[16], u[8], v[8]; - JSAMPARRAY planes[3]{y, u, v}; - - for (int line = 0; line < cinfo.image_height; line += 16) { - for (int i = 0; i < 16; ++i) { - y[i] = y_plane + (line + i) * cinfo.image_width; - if (i % 2 == 0) { - int offset = (cinfo.image_width / 2) * ((i + line) / 2); - u[i / 2] = u_plane + offset; - v[i / 2] = v_plane + offset; - } - } - jpeg_write_raw_data(&cinfo, planes, 16); + int err = avcodec_send_frame(codec_ctx, frame); + if (err < 0) { + LOGE("thumbnail avcodec_send_frame error %d", err); + out_buffer.clear(); + return; } - jpeg_finish_compress(&cinfo); - jpeg_destroy_compress(&cinfo); + av_packet_unref(pkt); + err = avcodec_receive_packet(codec_ctx, pkt); + if (err < 0) { + LOGE("thumbnail avcodec_receive_packet error %d", err); + out_buffer.clear(); + return; + } + + out_buffer.assign(pkt->data, pkt->data + pkt->size); + av_packet_unref(pkt); } diff --git a/openpilot/system/loggerd/encoder/jpeg_encoder.h b/openpilot/system/loggerd/encoder/jpeg_encoder.h index 3bd1308b4b..10cec52657 100644 --- a/openpilot/system/loggerd/encoder/jpeg_encoder.h +++ b/openpilot/system/loggerd/encoder/jpeg_encoder.h @@ -1,18 +1,20 @@ #pragma once -#include -#include -#include #include -#include -#include #include +#include +#include + #include "openpilot/cereal/messaging/messaging.h" #include "msgq/visionipc/visionbuf.h" +extern "C" { +#include +} + class JpegEncoder { public: - JpegEncoder(const std::string &pusblish_name, int width, int height); + JpegEncoder(const std::string &publish_name, int width, int height); ~JpegEncoder(); void pushThumbnail(VisionBuf *buf, const VisionIpcBufExtra &extra); @@ -24,9 +26,10 @@ private: int thumbnail_height; std::string publish_name; std::vector yuv_buffer; + std::vector out_buffer; std::unique_ptr pm; - // JPEG output buffer - unsigned char* out_buffer = nullptr; - unsigned long out_size = 0; + AVCodecContext *codec_ctx = nullptr; + AVFrame *frame = nullptr; + AVPacket *pkt = nullptr; }; diff --git a/pyproject.toml b/pyproject.toml index 99c38023c9..57e953986a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -33,7 +33,6 @@ dependencies = [ "acados @ git+https://github.com/commaai/dependencies.git@release-acados#subdirectory=acados", "eigen @ git+https://github.com/commaai/dependencies.git@release-eigen#subdirectory=eigen", "ffmpeg @ git+https://github.com/commaai/dependencies.git@release-ffmpeg#subdirectory=ffmpeg", - "libjpeg @ git+https://github.com/commaai/dependencies.git@release-libjpeg#subdirectory=libjpeg", "libyuv @ git+https://github.com/commaai/dependencies.git@release-libyuv#subdirectory=libyuv", "zstd @ git+https://github.com/commaai/dependencies.git@release-zstd#subdirectory=zstd", "ncurses @ git+https://github.com/commaai/dependencies.git@release-ncurses#subdirectory=ncurses", diff --git a/uv.lock b/uv.lock index d64cf10cd6..bcd96d53d8 100644 --- a/uv.lock +++ b/uv.lock @@ -655,10 +655,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/48/e8/7923893f08504f28e0b5fb8b21795fc388d0363cfa2f412e2541c9464cb1/lefthook-2.1.9-py3-none-win_arm64.whl", hash = "sha256:6d8e3923c42a04e9375f88314ebc8c86f68879d3d0c9d856b6adbed109890e90", size = 4959833, upload-time = "2026-05-29T08:39:32.882Z" }, ] -[[package]] -name = "libjpeg" -version = "3.1.0" -source = { git = "https://github.com/commaai/dependencies.git?subdirectory=libjpeg&rev=release-libjpeg#3f9a0796d1985576b0cb172456e08bb918f3afeb" } [[package]] name = "libusb" @@ -909,7 +905,6 @@ dependencies = [ { name = "jeepney" }, { name = "json-rpc" }, { name = "json11" }, - { name = "libjpeg" }, { name = "libusb" }, { name = "libyuv" }, { name = "ncurses" }, @@ -997,7 +992,6 @@ requires-dist = [ { name = "jinja2", marker = "extra == 'docs'" }, { name = "json-rpc" }, { name = "json11", git = "https://github.com/commaai/dependencies.git?subdirectory=json11&rev=release-json11" }, - { name = "libjpeg", git = "https://github.com/commaai/dependencies.git?subdirectory=libjpeg&rev=release-libjpeg" }, { name = "libusb", git = "https://github.com/commaai/dependencies.git?subdirectory=libusb&rev=release-libusb" }, { name = "libyuv", git = "https://github.com/commaai/dependencies.git?subdirectory=libyuv&rev=release-libyuv" }, { name = "matplotlib", marker = "extra == 'dev'" }, From 1ab1ed745391a680a6cfa8025a2e993493a4b463 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Wed, 8 Jul 2026 19:35:39 -0700 Subject: [PATCH 116/151] Use PyPI comma-deps packages (#38295) --- pyproject.toml | 34 ++--- uv.lock | 335 +++++++++++++++++++++++++++++++------------------ 2 files changed, 231 insertions(+), 138 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 57e953986a..1c4e551b81 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -26,21 +26,21 @@ dependencies = [ "numpy >=2.0", # vendored native dependencies - "bzip2 @ git+https://github.com/commaai/dependencies.git@release-bzip2#subdirectory=bzip2", - "bootstrap-icons @ git+https://github.com/commaai/dependencies.git@release-bootstrap-icons#subdirectory=bootstrap-icons", - "capnproto @ git+https://github.com/commaai/dependencies.git@release-capnproto#subdirectory=capnproto", - "catch2 @ git+https://github.com/commaai/dependencies.git@release-catch2#subdirectory=catch2", - "acados @ git+https://github.com/commaai/dependencies.git@release-acados#subdirectory=acados", - "eigen @ git+https://github.com/commaai/dependencies.git@release-eigen#subdirectory=eigen", - "ffmpeg @ git+https://github.com/commaai/dependencies.git@release-ffmpeg#subdirectory=ffmpeg", - "libyuv @ git+https://github.com/commaai/dependencies.git@release-libyuv#subdirectory=libyuv", - "zstd @ git+https://github.com/commaai/dependencies.git@release-zstd#subdirectory=zstd", - "ncurses @ git+https://github.com/commaai/dependencies.git@release-ncurses#subdirectory=ncurses", - "zeromq @ git+https://github.com/commaai/dependencies.git@release-zeromq#subdirectory=zeromq", - "libusb @ git+https://github.com/commaai/dependencies.git@release-libusb#subdirectory=libusb", - "json11 @ git+https://github.com/commaai/dependencies.git@release-json11#subdirectory=json11", - "git-lfs @ git+https://github.com/commaai/dependencies.git@release-git-lfs#subdirectory=git-lfs", - "gcc-arm-none-eabi @ git+https://github.com/commaai/dependencies.git@release-gcc-arm-none-eabi#subdirectory=gcc-arm-none-eabi", + "comma-deps-bzip2", + "comma-deps-bootstrap-icons", + "comma-deps-capnproto", + "comma-deps-catch2", + "comma-deps-acados", + "comma-deps-eigen", + "comma-deps-ffmpeg", + "comma-deps-libyuv", + "comma-deps-zstd", + "comma-deps-ncurses", + "comma-deps-zeromq", + "comma-deps-libusb", + "comma-deps-json11", + "comma-deps-git-lfs", + "comma-deps-gcc-arm-none-eabi", # body / webrtcd "av", @@ -67,7 +67,7 @@ dependencies = [ "zstandard", # ui - "raylib @ git+https://github.com/commaai/dependencies.git@release-raylib#subdirectory=raylib", + "comma-deps-raylib", "qrcode", "jeepney", "pillow", @@ -99,7 +99,7 @@ dev = [ ] tools = [ - "imgui @ git+https://github.com/commaai/dependencies.git@release-imgui#subdirectory=imgui", + "comma-deps-imgui", # this can be added back once it's stripped down some more #"metadrive-simulator @ git+https://github.com/commaai/metadrive.git@minimal ; (platform_machine != 'aarch64')", diff --git a/uv.lock b/uv.lock index bcd96d53d8..0fb7dddd0c 100644 --- a/uv.lock +++ b/uv.lock @@ -8,14 +8,6 @@ overrides = [ { name = "opendbc", editable = "opendbc_repo" }, ] -[[package]] -name = "acados" -version = "0.2.2" -source = { git = "https://github.com/commaai/dependencies.git?subdirectory=acados&rev=release-acados#8ea54be6bf1096b131493dbb38e8bd721a6727de" } -dependencies = [ - { name = "numpy" }, -] - [[package]] name = "aiohappyeyeballs" version = "2.7.1" @@ -129,21 +121,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/c8/b9/275df9607f7fb44317ccb1d4be74827185c0d410f52b6e2cd770fe209118/av-16.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:f49243b1d27c91cd8c66fdba90a674e344eb8eb917264f36117bf2b6879118fd", size = 31752045, upload-time = "2026-01-11T09:57:45.106Z" }, ] -[[package]] -name = "bootstrap-icons" -version = "1.10.5.0" -source = { git = "https://github.com/commaai/dependencies.git?subdirectory=bootstrap-icons&rev=release-bootstrap-icons#65bc63d354432ad83294c8ecfc3ef01733a46e12" } - -[[package]] -name = "bzip2" -version = "1.0.8" -source = { git = "https://github.com/commaai/dependencies.git?subdirectory=bzip2&rev=release-bzip2#83b0dd263eff2d9633a86096056fe16543a42244" } - -[[package]] -name = "capnproto" -version = "1.0.1" -source = { git = "https://github.com/commaai/dependencies.git?subdirectory=capnproto&rev=release-capnproto#71cb13543c7d9691064fd01854e228f1481efab6" } - [[package]] name = "catch2" version = "2.13.10" @@ -236,6 +213,178 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, ] +[[package]] +name = "comma-deps-acados" +version = "0.2.2.post95" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/58/83/e76d3f89de07a672c5fc452d81b6f00f972721342eb75de2171d2c3a8b19/comma_deps_acados-0.2.2.post95-py3-none-macosx_11_0_arm64.whl", hash = "sha256:fd7c583ac2a33b414540c0601173e3a9c28c5d8f825cb24736c64e3c07271f56", size = 10631724, upload-time = "2026-06-24T23:58:31.726Z" }, + { url = "https://files.pythonhosted.org/packages/64/96/4b8e50a153dcb5f34628f854dc58774588b8dbfb26b6bedd0b99acb4aa71/comma_deps_acados-0.2.2.post95-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:1f47c3a665193937c993d3ee15989be5ba75eb427c9733fe1b9e800bf33c56aa", size = 11663713, upload-time = "2026-06-24T23:58:33.725Z" }, + { url = "https://files.pythonhosted.org/packages/1b/2f/bf57b9656e86950ba19c7a88992fccc0abb89878f9c30fb1b2252d57f0a7/comma_deps_acados-0.2.2.post95-py3-none-manylinux_2_28_x86_64.whl", hash = "sha256:00b49d5b691fa97d07fa5e5b842e0d2e1a6faa6856d2a081eefcee649f93329b", size = 13167209, upload-time = "2026-06-24T23:58:35.941Z" }, +] + +[[package]] +name = "comma-deps-bootstrap-icons" +version = "1.10.5.0.post95" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/44/0b/bb713dd4bed94b0b2b21657b7337e264953bd785a2b2f5c1b0706cdcde29/comma_deps_bootstrap_icons-1.10.5.0.post95-py3-none-any.whl", hash = "sha256:d59fc8d3e642e00f83d7a4854164f1dee21c3d17c726d5537b1b72b149f5788b", size = 386001, upload-time = "2026-06-24T23:58:37.84Z" }, +] + +[[package]] +name = "comma-deps-bzip2" +version = "1.0.8.post95" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f8/ac/539d76e9bcebbc53d62274a19c47522b118dce3261fc6baea045f93c98b6/comma_deps_bzip2-1.0.8.post95-py3-none-macosx_11_0_arm64.whl", hash = "sha256:be466743b7fc56fa18c2c389a46bdeb0fc885cf3cf39b779d748ce540609ebd5", size = 42832, upload-time = "2026-06-24T23:58:39.592Z" }, + { url = "https://files.pythonhosted.org/packages/a1/fe/5206bd6d716022cea259c4878c6a1927ab3555f4caa48a74efaa83d8f418/comma_deps_bzip2-1.0.8.post95-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:7c015d720cc5462f87062b4482c54684de6a237b4edb60612c2f58721413682f", size = 38629, upload-time = "2026-06-24T23:58:40.496Z" }, + { url = "https://files.pythonhosted.org/packages/39/0e/78218f9a645ad9d27000153795d6819b3b52ca62d882aa46a413e40887be/comma_deps_bzip2-1.0.8.post95-py3-none-manylinux_2_28_x86_64.whl", hash = "sha256:3188a197aaf3efbfac975193887c59600b91a3b4eb7f62cc975377133cd48834", size = 36271, upload-time = "2026-06-24T23:58:41.2Z" }, +] + +[[package]] +name = "comma-deps-capnproto" +version = "1.0.1.post93" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/19/a6/97c22a112e23f530db28f8ecf7b191ec16685d282fdbe892dff7437bdf6d/comma_deps_capnproto-1.0.1.post93-py3-none-macosx_11_0_arm64.whl", hash = "sha256:6717e8e34ef12116502f244b23f092984c1d15afa4e40b956450b74a0d4d2520", size = 2407330, upload-time = "2026-07-08T19:30:41.395Z" }, + { url = "https://files.pythonhosted.org/packages/6d/f2/79a15ff5f2c97a741923a97357f6a4235e4ced928ba1d4079d01c66df4b0/comma_deps_capnproto-1.0.1.post93-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:a70349446e2ec17b281ebaaae02ca4c35495f4210043c716c55139a05a826090", size = 2506341, upload-time = "2026-07-08T19:30:45.607Z" }, + { url = "https://files.pythonhosted.org/packages/80/a9/f61fe62045c4ea867f51f2d74b4edfabd6c272c62a3281a9f1f33825a725/comma_deps_capnproto-1.0.1.post93-py3-none-manylinux_2_28_x86_64.whl", hash = "sha256:f98cdba8f8c7f08a7a0c0a4b7cc0bfcf515e29ad8f1b5cb8eda4e253bef5e6e3", size = 2590769, upload-time = "2026-07-08T19:30:49.728Z" }, +] + +[[package]] +name = "comma-deps-catch2" +version = "2.13.10.post93" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/88/ee/b4ef7758d04a024775d49558ca930fec19aa37cd691ad9182b7141f4d4d7/comma_deps_catch2-2.13.10.post93-py3-none-any.whl", hash = "sha256:8f23293251b5db48c08885d8816ca252b3fb11b0c1c26775bae36e8b217e865e", size = 137085, upload-time = "2026-07-08T19:30:53.44Z" }, +] + +[[package]] +name = "comma-deps-eigen" +version = "3.4.0.post93" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fa/3c/b262d6103a3b7a5cb0296b821eb4f1385b349e527bba75d7efe057cea802/comma_deps_eigen-3.4.0.post93-py3-none-macosx_11_0_arm64.whl", hash = "sha256:f90433cea3f59f1b9ed58bd92d0f1b55721eff8b473d579ed40fa2fcdc2c1787", size = 2275895, upload-time = "2026-07-08T19:31:08.983Z" }, + { url = "https://files.pythonhosted.org/packages/00/a1/b9bf332a096267ff26ebd546b104d9a92b905857c59bae899794897c790b/comma_deps_eigen-3.4.0.post93-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:3169d82b825ca8accdae5f3e1a9cddd9f28f8bd5f66e4353fedae68b23f13cdb", size = 2275897, upload-time = "2026-07-08T19:31:12.66Z" }, + { url = "https://files.pythonhosted.org/packages/bd/c6/1132467acd1257ea159cf4608c6f00ef0b3ca353fd86aaced0d76dcce62c/comma_deps_eigen-3.4.0.post93-py3-none-manylinux_2_28_x86_64.whl", hash = "sha256:d0b042c817070a0124b8c0e78b87ff5e8b44db21a1abea740afe7115f5bd8447", size = 2275900, upload-time = "2026-07-08T19:31:16.352Z" }, +] + +[[package]] +name = "comma-deps-ffmpeg" +version = "7.1.0.post93" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/65/02/7e21345a4b6493b94dcacdf14024d24fc143469b3b596dbe0a0433b9055d/comma_deps_ffmpeg-7.1.0.post93-py3-none-macosx_11_0_arm64.whl", hash = "sha256:129f05e177ae8abfb758ff6b56efdb8caa4c10c435f73c774dd4470349c05502", size = 10673113, upload-time = "2026-07-08T19:31:20.253Z" }, + { url = "https://files.pythonhosted.org/packages/18/ac/579bbb4d8724406738b0eef41f4e49bb0dff17eb4b9b5397296f5d65c84e/comma_deps_ffmpeg-7.1.0.post93-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:185bab6cd683448a1fba9338b11da7e7454b798e27a52d789ea02dd827e944fe", size = 11748947, upload-time = "2026-07-08T19:31:24.618Z" }, + { url = "https://files.pythonhosted.org/packages/6e/bc/feb5dc8e2e75ecf147281801b1a2a864996c1e1a3be934aeb5cebdcf7323/comma_deps_ffmpeg-7.1.0.post93-py3-none-manylinux_2_28_x86_64.whl", hash = "sha256:161e3bcbee02b0d5d2b7bcff2c249904fe7b9c9b3f7820b954a4fb2d24c0fe21", size = 12433434, upload-time = "2026-07-08T19:31:28.965Z" }, +] + +[[package]] +name = "comma-deps-gcc-arm-none-eabi" +version = "13.2.1.post93" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c0/9f/9a6c7f04faf18fdc4ab3e5b55ecfdbcb3998333a450fd5a1c986af571d15/comma_deps_gcc_arm_none_eabi-13.2.1.post93-py3-none-macosx_11_0_arm64.whl", hash = "sha256:00de06a94ecf4379c79b150d36b3116d0f37bc341bbf1ef2ad850c8a5985eeb1", size = 15238809, upload-time = "2026-07-08T19:31:33.509Z" }, + { url = "https://files.pythonhosted.org/packages/83/94/1cdb11c170b96f2677dfd1be7cfb9a2994d3518555c154f2a131929057da/comma_deps_gcc_arm_none_eabi-13.2.1.post93-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:de1cf3ff89ea84fac5df62c65d843af877eaa2634439d793f527f0cfeea66e59", size = 17367238, upload-time = "2026-07-08T19:31:38.137Z" }, + { url = "https://files.pythonhosted.org/packages/23/3c/4b2f60274f080b9583da2fdaad54f692f4f8719bd360558d4460d79f8fb4/comma_deps_gcc_arm_none_eabi-13.2.1.post93-py3-none-manylinux_2_28_x86_64.whl", hash = "sha256:3cf7f022ffa1b3d3e20eb32610c7e59f84932e516d9ed11236df787546d82d67", size = 16941134, upload-time = "2026-07-08T19:31:43.102Z" }, +] + +[[package]] +name = "comma-deps-git-lfs" +version = "3.6.1.post93" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/df/62/e06ea6fb98b8cee2686fb409fb28426d902f3318b077cbd78d9bbec0354b/comma_deps_git_lfs-3.6.1.post93-py3-none-macosx_11_0_arm64.whl", hash = "sha256:89cbffd3d6800fa8e366301b98c09c4ccbc973fb59721aa2546b36158b9b64c0", size = 4685107, upload-time = "2026-07-08T19:31:47.273Z" }, + { url = "https://files.pythonhosted.org/packages/ce/cf/f08dc359e8bc7e1b21b7f4a93167a14ac61dc78f1bfb27a0e7554c78cb09/comma_deps_git_lfs-3.6.1.post93-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:39844960733a3885d99bbfdf4f7b414e7d0bf4b4d56f9d77a88ea10d72f549c5", size = 4485276, upload-time = "2026-07-08T19:31:51.253Z" }, + { url = "https://files.pythonhosted.org/packages/2f/af/3dfae2a56320165b45ceab0d7a2c6dea69cc5766928f408d17997ff2a525/comma_deps_git_lfs-3.6.1.post93-py3-none-manylinux_2_28_x86_64.whl", hash = "sha256:e445cbadec41856997de775d5d415d1e707db0ba563c705df1b55ce198179bbe", size = 4889583, upload-time = "2026-07-08T19:31:55.153Z" }, +] + +[[package]] +name = "comma-deps-imgui" +version = "1.92.7.post93" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/48/e8/a5f99714d4b2ef85744bd6af9ee46b016a70cea8383c9cca3097847c6940/comma_deps_imgui-1.92.7.post93-py3-none-macosx_11_0_arm64.whl", hash = "sha256:ae7cbb655cd61157b785e7f388cc1bfe17bf6a2bf8c40ff9484702bd9be71074", size = 1688022, upload-time = "2026-07-08T19:31:58.849Z" }, + { url = "https://files.pythonhosted.org/packages/86/f1/0ebcbb7d55ef1ad0f516831c52f37cafdf0ed94b73e0396c531ecd89dbc1/comma_deps_imgui-1.92.7.post93-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:efc689e8279900c10e3922e9bf188fe34e16ab28d8660878e82b7192d7d86c68", size = 2522798, upload-time = "2026-07-08T19:32:02.435Z" }, + { url = "https://files.pythonhosted.org/packages/c3/94/6f0bd31d599f5748736b57e0b71a42d15ec0782906155f268bc7056fd0ac/comma_deps_imgui-1.92.7.post93-py3-none-manylinux_2_28_x86_64.whl", hash = "sha256:b08a763c00a1f037dc5e2e2e0322c46960fe8a2cc972ce17781d547ccce3eaa6", size = 2655457, upload-time = "2026-07-08T19:32:06.273Z" }, +] + +[[package]] +name = "comma-deps-json11" +version = "20170411.0.post93" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b7/3e/f2bb5d0e0d9e63535007c64859b2ab5e17164ca1f4cfa279fd228dbcef80/comma_deps_json11-20170411.0.post93-py3-none-macosx_11_0_arm64.whl", hash = "sha256:0088d66fd76ea27712d09f2ffa783596f7d70b5b152a039c36d65befcebe3863", size = 34033, upload-time = "2026-07-08T19:32:10.175Z" }, + { url = "https://files.pythonhosted.org/packages/b8/6e/9576bb1ba5d8371f32664268401fa61231ca1092aa5da45141c37984d868/comma_deps_json11-20170411.0.post93-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:659c18d4b2634bf7d2388c6e855c6f083f384d2a70052945c1c9ddabbb0dcb21", size = 41846, upload-time = "2026-07-08T19:32:13.457Z" }, + { url = "https://files.pythonhosted.org/packages/cc/34/6d673c311c9a23e65a0db56352878b53b575aca0539e57c71121d2fe544b/comma_deps_json11-20170411.0.post93-py3-none-manylinux_2_28_x86_64.whl", hash = "sha256:4c24a9c9db71b38192ec9c515f13fd14b4495b8080bb1f687b84b193613d95be", size = 42603, upload-time = "2026-07-08T19:32:16.601Z" }, +] + +[[package]] +name = "comma-deps-libusb" +version = "1.0.29.post93" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/56/a3/4fb912d8af7af134a0a54eeb893beecc9e1cb3ed8371e055319faa74a580/comma_deps_libusb-1.0.29.post93-py3-none-macosx_11_0_arm64.whl", hash = "sha256:1dba5fe7832877994ea9ff3daf056851f1b5c9a47552525af08b35074c5ff65e", size = 102339, upload-time = "2026-07-08T19:32:19.785Z" }, + { url = "https://files.pythonhosted.org/packages/ce/ad/6d36327352fa1030997409ee650de3f307cc26e3fec4f2a8ea6254430e6a/comma_deps_libusb-1.0.29.post93-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:c2a29c888668cb4c0ab549ac71206d6b53da8d2db5e581a55a113574aaabe950", size = 94439, upload-time = "2026-07-08T19:32:23.104Z" }, + { url = "https://files.pythonhosted.org/packages/84/47/f4f2da67db202bacc3fa578fdebdb916f45c97bee0c3d2c5fbe845a6f129/comma_deps_libusb-1.0.29.post93-py3-none-manylinux_2_28_x86_64.whl", hash = "sha256:f136dbbfc461d228378731361cc66a90a483e17d55f8ba43f23eeab6bcf41963", size = 93461, upload-time = "2026-07-08T19:32:26.434Z" }, +] + +[[package]] +name = "comma-deps-libyuv" +version = "1922.0.post93" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/19/91/f68b07f4ef01860d85e716b5095e10326de74455970cb279d70cdf45ee51/comma_deps_libyuv-1922.0.post93-py3-none-macosx_11_0_arm64.whl", hash = "sha256:f5e0d1550229efdc9aabcaa90b421902322ac7ddadd6e2118596916571c0619b", size = 269554, upload-time = "2026-07-08T19:32:29.709Z" }, + { url = "https://files.pythonhosted.org/packages/ee/6b/ca7ab7c00a16470f03a25c1079a50a2b7933516584056f15fb05385f377c/comma_deps_libyuv-1922.0.post93-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:3c55195bc905144ef157b8d2f8f36b25250d0a489bb07f2964327e48a0009669", size = 268385, upload-time = "2026-07-08T19:32:33.141Z" }, + { url = "https://files.pythonhosted.org/packages/0b/9d/ecdbbeef4c3797091ea990bbe4dcc10389e5d6bff27e20bed3b4e4a85eed/comma_deps_libyuv-1922.0.post93-py3-none-manylinux_2_28_x86_64.whl", hash = "sha256:1309769c64394294cbd399c77584f7d674753e6dda39b57243ab156711b6d353", size = 273326, upload-time = "2026-07-08T19:32:36.807Z" }, +] + +[[package]] +name = "comma-deps-ncurses" +version = "6.5.post93" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1c/3d/f85c036037e9d72c8cc444a1613ae8ca6967c0997148fbc8c03b8cdeb21c/comma_deps_ncurses-6.5.post93-py3-none-macosx_11_0_arm64.whl", hash = "sha256:0fbc94bdb42577389ec9e475deb7425f027b4e6a097b7b326ee0ee3ecb4c26ff", size = 264892, upload-time = "2026-07-08T22:08:58.325Z" }, + { url = "https://files.pythonhosted.org/packages/f4/da/13881cefe9ca963665a57f066683fd9995c15349839f0268686741942cd7/comma_deps_ncurses-6.5.post93-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:a8786c9e7693fbe235044ed068292ddae1e8c25e9cc3ffba9364c233b6df9f9c", size = 260837, upload-time = "2026-07-08T22:09:02.514Z" }, + { url = "https://files.pythonhosted.org/packages/11/98/6a278e4436ca901c084ae111dc23f064e3eb5f64481dc970111aff8a91fd/comma_deps_ncurses-6.5.post93-py3-none-manylinux_2_28_x86_64.whl", hash = "sha256:1de1011e71833d46d545a0d64150316f980385d13731eb138f9fc53642942c55", size = 248341, upload-time = "2026-07-08T22:09:06.591Z" }, +] + +[[package]] +name = "comma-deps-raylib" +version = "6.0.0.1.post93" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cffi" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/ee/5a/1abdc781fc242e0db517e22c53fa676fc81b76344c5d6c86677bdd5d6a9a/comma_deps_raylib-6.0.0.1.post93-py3-none-macosx_11_0_arm64.whl", hash = "sha256:ef4dbc7036e4449f9ee029cec077c23f64975b55b60cce0be818b70640c1732a", size = 2004199, upload-time = "2026-07-08T22:09:10.731Z" }, + { url = "https://files.pythonhosted.org/packages/79/90/919fd98aa72c8c1d31e657abc0bc28b3933d7408f4dc8ccbb7272ef638a9/comma_deps_raylib-6.0.0.1.post93-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:a64f2a77ad55b05350ed4301f3a1a814176810d1d408c77bdbaa1bd5a3ab5135", size = 7203010, upload-time = "2026-07-08T22:09:15.323Z" }, + { url = "https://files.pythonhosted.org/packages/ef/b6/419b387b132efe43ace20dced9852448f36195d71d1305fccfd5e0617083/comma_deps_raylib-6.0.0.1.post93-py3-none-manylinux_2_28_x86_64.whl", hash = "sha256:11bf076441b636434bc76a00b2e349c22a825e0b83416a4fb3dd4b8217638f8a", size = 5055450, upload-time = "2026-07-08T22:09:19.844Z" }, +] + +[[package]] +name = "comma-deps-zeromq" +version = "4.3.5.post93" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fb/6f/d50752a3a6f6ecd4b4289bf76090fd35c11ac8d4b9353534e91e9a640512/comma_deps_zeromq-4.3.5.post93-py3-none-macosx_11_0_arm64.whl", hash = "sha256:b5951b302ec3db7ad3638161af00dff6ad1d8e0272aa242a0b57d692a093bacc", size = 815166, upload-time = "2026-07-08T22:09:24.48Z" }, + { url = "https://files.pythonhosted.org/packages/57/24/0fa08db746438533a67e44886bffb1cd7e2a587c68d57fba745e84036965/comma_deps_zeromq-4.3.5.post93-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:a7d4813155ea13548158204a60e6a37e2dedfcf7ae34cbb78491474ac784ac24", size = 833412, upload-time = "2026-07-08T22:09:28.872Z" }, + { url = "https://files.pythonhosted.org/packages/c5/83/9083466d8269bf273a7ff4ff154fbcd300a8d9c79ca7754fb98215caf602/comma_deps_zeromq-4.3.5.post93-py3-none-manylinux_2_28_x86_64.whl", hash = "sha256:378f121eea1084c7cd45ee73c3dbc437e3d07547e8333d230174711e963f958d", size = 798729, upload-time = "2026-07-08T22:09:32.859Z" }, +] + +[[package]] +name = "comma-deps-zstd" +version = "1.5.6.post93" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b4/32/e62e39d77d356675b07fa0c03286d3f5620bb39fe8619285bfaf3c085f6b/comma_deps_zstd-1.5.6.post93-py3-none-macosx_11_0_arm64.whl", hash = "sha256:9c40c10fa541c5ed975a06327f4e5cc5fe380d49c50fd2899f367c52e0d535a1", size = 1065092, upload-time = "2026-07-08T22:09:37.023Z" }, + { url = "https://files.pythonhosted.org/packages/a8/f9/80e530ffed74b767591e50367dd51413c99e8aa10a975745086f2f10eac8/comma_deps_zstd-1.5.6.post93-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:3a1da859191a9b4c778498afdaa80a7000e5967d4851d827e422c467aa159f9a", size = 1006181, upload-time = "2026-07-08T22:09:41.332Z" }, + { url = "https://files.pythonhosted.org/packages/ad/b1/5b544af0a50235b1efe9a9de469180ded30814feb8e6a2cd89d4064f995e/comma_deps_zstd-1.5.6.post93-py3-none-manylinux_2_28_x86_64.whl", hash = "sha256:fe85e5fd24ac81964cac30ad04327ae157b5976a69725604ec960e773f06a9a8", size = 1030331, upload-time = "2026-07-08T22:09:45.535Z" }, +] + [[package]] name = "contourpy" version = "1.3.3" @@ -421,11 +570,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ba/5a/18ad964b0086c6e62e2e7500f7edc89e3faa45033c71c1893d34eed2b2de/dnspython-2.8.0-py3-none-any.whl", hash = "sha256:01d9bbc4a2d76bf0db7c1f729812ded6d912bd318d3b1cf81d30c0f845dbf3af", size = 331094, upload-time = "2025-09-07T18:57:58.071Z" }, ] -[[package]] -name = "eigen" -version = "3.4.0" -source = { git = "https://github.com/commaai/dependencies.git?subdirectory=eigen&rev=release-eigen#7fd5584ae72d8b4b89df7fd52e4b4761ad5e51f4" } - [[package]] name = "execnet" version = "2.1.2" @@ -435,11 +579,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl", hash = "sha256:67fba928dd5a544b783f6056f449e5e3931a5c378b128bc18501f7ea79e296ec", size = 40708, upload-time = "2025-11-12T09:56:36.333Z" }, ] -[[package]] -name = "ffmpeg" -version = "7.1.0" -source = { git = "https://github.com/commaai/dependencies.git?subdirectory=ffmpeg&rev=release-ffmpeg#f8021e2d6476b9b46343ad21f7b3773f12fd7414" } - [[package]] name = "fonttools" version = "4.63.0" @@ -482,16 +621,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/9a/9a/e35b4a917281c0b8419d4207f4334c8e8c5dbf4f3f5f9ada73958d937dcc/frozenlist-1.8.0-py3-none-any.whl", hash = "sha256:0c18a16eab41e82c295618a77502e17b195883241c563b00f0aa5106fc4eaa0d", size = 13409, upload-time = "2025-10-06T05:38:16.721Z" }, ] -[[package]] -name = "gcc-arm-none-eabi" -version = "13.2.1" -source = { git = "https://github.com/commaai/dependencies.git?subdirectory=gcc-arm-none-eabi&rev=release-gcc-arm-none-eabi#6942c457205971ada312cc0f5ef7d10ff108b8cc" } - -[[package]] -name = "git-lfs" -version = "3.6.1" -source = { git = "https://github.com/commaai/dependencies.git?subdirectory=git-lfs&rev=release-git-lfs#0a1fccce026554b4f3ef1feb2b611bf045a171e2" } - [[package]] name = "google-crc32c" version = "1.8.0" @@ -536,11 +665,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/9c/1f/19ebc343cc71a7ffa78f17018535adc5cbdd87afb31d7c34874680148b32/ifaddr-0.2.0-py3-none-any.whl", hash = "sha256:085e0305cfe6f16ab12d72e2024030f5d52674afad6911bb1eee207177b8a748", size = 12314, upload-time = "2022-06-15T21:40:25.756Z" }, ] -[[package]] -name = "imgui" -version = "1.92.7" -source = { git = "https://github.com/commaai/dependencies.git?subdirectory=imgui&rev=release-imgui#1964d125f4b1eded94b85b1da485f46a794f84a3" } - [[package]] name = "importlib-metadata" version = "9.0.0" @@ -610,11 +734,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/94/9e/820c4b086ad01ba7d77369fb8b11470a01fac9b4977f02e18659cf378b6b/json_rpc-1.15.0-py2.py3-none-any.whl", hash = "sha256:4a4668bbbe7116feb4abbd0f54e64a4adcf4b8f648f19ffa0848ad0f6606a9bf", size = 39450, upload-time = "2023-06-11T09:45:47.136Z" }, ] -[[package]] -name = "json11" -version = "20170411.0" -source = { git = "https://github.com/commaai/dependencies.git?subdirectory=json11&rev=release-json11#f65ae63ea938062f00cdc142c6f01d60141da9c2" } - [[package]] name = "kiwisolver" version = "1.5.0" @@ -655,12 +774,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/48/e8/7923893f08504f28e0b5fb8b21795fc388d0363cfa2f412e2541c9464cb1/lefthook-2.1.9-py3-none-win_arm64.whl", hash = "sha256:6d8e3923c42a04e9375f88314ebc8c86f68879d3d0c9d856b6adbed109890e90", size = 4959833, upload-time = "2026-05-29T08:39:32.882Z" }, ] - -[[package]] -name = "libusb" -version = "1.0.29" -source = { git = "https://github.com/commaai/dependencies.git?subdirectory=libusb&rev=release-libusb#9c268a75b3f29495f154065064c6ee3ac79bd416" } - [[package]] name = "libusb-package" version = "1.0.30.0" @@ -690,11 +803,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/5f/08/02aecf6dad627534a5835244ece14d7f187ef430354d9b8551199934d059/libusb1-3.4.0-py3-none-win_amd64.whl", hash = "sha256:b7dcc1f324a895af6aac708bc5513a17373f97349cc2ab8a277519c788bd18ca", size = 141212, upload-time = "2026-05-16T20:59:17.286Z" }, ] -[[package]] -name = "libyuv" -version = "1922.0" -source = { git = "https://github.com/commaai/dependencies.git?subdirectory=libyuv&rev=release-libyuv#606fbcc349db62aa8c337b49520b7361e374b67d" } - [[package]] name = "markdown" version = "3.10.2" @@ -818,11 +926,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/81/08/7036c080d7117f28a4af526d794aab6a84463126db031b007717c1a6676e/multidict-6.7.1-py3-none-any.whl", hash = "sha256:55d97cc6dae627efa6a6e548885712d4864b81110ac76fa4e534c03819fa4a56", size = 12319, upload-time = "2026-01-26T02:46:44.004Z" }, ] -[[package]] -name = "ncurses" -version = "6.5" -source = { git = "https://github.com/commaai/dependencies.git?subdirectory=ncurses&rev=release-ncurses#97d56492b9257d021596fc89927af2ec4433da58" } - [[package]] name = "numpy" version = "2.5.0" @@ -887,27 +990,30 @@ name = "openpilot" version = "0.1.0" source = { editable = "." } dependencies = [ - { name = "acados" }, { name = "aiortc" }, { name = "av" }, - { name = "bootstrap-icons" }, - { name = "bzip2" }, - { name = "capnproto" }, - { name = "catch2" }, { name = "cffi" }, + { name = "comma-deps-acados" }, + { name = "comma-deps-bootstrap-icons" }, + { name = "comma-deps-bzip2" }, + { name = "comma-deps-capnproto" }, + { name = "comma-deps-catch2" }, + { name = "comma-deps-eigen" }, + { name = "comma-deps-ffmpeg" }, + { name = "comma-deps-gcc-arm-none-eabi" }, + { name = "comma-deps-git-lfs" }, + { name = "comma-deps-json11" }, + { name = "comma-deps-libusb" }, + { name = "comma-deps-libyuv" }, + { name = "comma-deps-ncurses" }, + { name = "comma-deps-raylib" }, + { name = "comma-deps-zeromq" }, + { name = "comma-deps-zstd" }, { name = "crcmod-plus" }, { name = "cython" }, - { name = "eigen" }, - { name = "ffmpeg" }, - { name = "gcc-arm-none-eabi" }, - { name = "git-lfs" }, { name = "inputs" }, { name = "jeepney" }, { name = "json-rpc" }, - { name = "json11" }, - { name = "libusb" }, - { name = "libyuv" }, - { name = "ncurses" }, { name = "numpy" }, { name = "pillow" }, { name = "psutil" }, @@ -916,7 +1022,6 @@ dependencies = [ { name = "pyserial" }, { name = "pyzmq" }, { name = "qrcode" }, - { name = "raylib" }, { name = "requests" }, { name = "scons" }, { name = "sentry-sdk" }, @@ -927,9 +1032,7 @@ dependencies = [ { name = "tqdm" }, { name = "websocket-client" }, { name = "xattr" }, - { name = "zeromq" }, { name = "zstandard" }, - { name = "zstd" }, ] [package.optional-dependencies] @@ -954,7 +1057,7 @@ testing = [ { name = "ty" }, ] tools = [ - { name = "imgui" }, + { name = "comma-deps-imgui" }, ] [package.dev-dependencies] @@ -969,33 +1072,36 @@ submodules = [ [package.metadata] requires-dist = [ - { name = "acados", git = "https://github.com/commaai/dependencies.git?subdirectory=acados&rev=release-acados" }, { name = "aiortc" }, { name = "av" }, - { name = "bootstrap-icons", git = "https://github.com/commaai/dependencies.git?subdirectory=bootstrap-icons&rev=release-bootstrap-icons" }, - { name = "bzip2", git = "https://github.com/commaai/dependencies.git?subdirectory=bzip2&rev=release-bzip2" }, - { name = "capnproto", git = "https://github.com/commaai/dependencies.git?subdirectory=capnproto&rev=release-capnproto" }, - { name = "catch2", git = "https://github.com/commaai/dependencies.git?subdirectory=catch2&rev=release-catch2" }, { name = "cffi" }, { name = "codespell", marker = "extra == 'testing'" }, + { name = "comma-deps-acados" }, + { name = "comma-deps-bootstrap-icons" }, + { name = "comma-deps-bzip2" }, + { name = "comma-deps-capnproto" }, + { name = "comma-deps-catch2" }, + { name = "comma-deps-eigen" }, + { name = "comma-deps-ffmpeg" }, + { name = "comma-deps-gcc-arm-none-eabi" }, + { name = "comma-deps-git-lfs" }, + { name = "comma-deps-imgui", marker = "extra == 'tools'" }, + { name = "comma-deps-json11" }, + { name = "comma-deps-libusb" }, + { name = "comma-deps-libyuv" }, + { name = "comma-deps-ncurses" }, + { name = "comma-deps-raylib" }, + { name = "comma-deps-zeromq" }, + { name = "comma-deps-zstd" }, { name = "coverage", marker = "extra == 'testing'" }, { name = "crcmod-plus" }, { name = "cython" }, - { name = "eigen", git = "https://github.com/commaai/dependencies.git?subdirectory=eigen&rev=release-eigen" }, - { name = "ffmpeg", git = "https://github.com/commaai/dependencies.git?subdirectory=ffmpeg&rev=release-ffmpeg" }, - { name = "gcc-arm-none-eabi", git = "https://github.com/commaai/dependencies.git?subdirectory=gcc-arm-none-eabi&rev=release-gcc-arm-none-eabi" }, - { name = "git-lfs", git = "https://github.com/commaai/dependencies.git?subdirectory=git-lfs&rev=release-git-lfs" }, { name = "hypothesis", marker = "extra == 'testing'", specifier = "==6.47.*" }, - { name = "imgui", marker = "extra == 'tools'", git = "https://github.com/commaai/dependencies.git?subdirectory=imgui&rev=release-imgui" }, { name = "inputs" }, { name = "jeepney" }, { name = "jinja2", marker = "extra == 'docs'" }, { name = "json-rpc" }, - { name = "json11", git = "https://github.com/commaai/dependencies.git?subdirectory=json11&rev=release-json11" }, - { name = "libusb", git = "https://github.com/commaai/dependencies.git?subdirectory=libusb&rev=release-libusb" }, - { name = "libyuv", git = "https://github.com/commaai/dependencies.git?subdirectory=libyuv&rev=release-libyuv" }, { name = "matplotlib", marker = "extra == 'dev'" }, - { name = "ncurses", git = "https://github.com/commaai/dependencies.git?subdirectory=ncurses&rev=release-ncurses" }, { name = "numpy", specifier = ">=2.0" }, { name = "pillow" }, { name = "pre-commit-hooks", marker = "extra == 'testing'" }, @@ -1010,7 +1116,6 @@ requires-dist = [ { name = "pytest-xdist", marker = "extra == 'testing'", git = "https://github.com/sshane/pytest-xdist?rev=2b4372bd62699fb412c4fe2f95bf9f01bd2018da" }, { name = "pyzmq" }, { name = "qrcode" }, - { name = "raylib", git = "https://github.com/commaai/dependencies.git?subdirectory=raylib&rev=release-raylib" }, { name = "requests" }, { name = "ruff", marker = "extra == 'testing'" }, { name = "scons" }, @@ -1024,9 +1129,7 @@ requires-dist = [ { name = "websocket-client" }, { name = "xattr" }, { name = "zensical", marker = "extra == 'docs'" }, - { name = "zeromq", git = "https://github.com/commaai/dependencies.git?subdirectory=zeromq&rev=release-zeromq" }, { name = "zstandard" }, - { name = "zstd", git = "https://github.com/commaai/dependencies.git?subdirectory=zstd&rev=release-zstd" }, ] provides-extras = ["docs", "testing", "dev", "tools"] @@ -1057,6 +1160,7 @@ dependencies = [ { name = "libusb-package" }, { name = "libusb1" }, { name = "opendbc" }, + { name = "spidev", marker = "sys_platform == 'linux'" }, ] [package.metadata] @@ -1076,6 +1180,7 @@ requires-dist = [ { name = "ruff", marker = "extra == 'dev'" }, { name = "scons", marker = "extra == 'dev'" }, { name = "setuptools", marker = "extra == 'dev'" }, + { name = "spidev", marker = "sys_platform == 'linux'" }, ] provides-extras = ["dev"] @@ -1437,14 +1542,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/dd/b8/d2d6d731733f51684bbf76bf34dab3b70a9148e8f2cef2bb544fccec681a/qrcode-8.2-py3-none-any.whl", hash = "sha256:16e64e0716c14960108e85d853062c9e8bba5ca8252c0b4d0231b9df4060ff4f", size = 45986, upload-time = "2025-05-01T15:44:22.781Z" }, ] -[[package]] -name = "raylib" -version = "6.0.0.1" -source = { git = "https://github.com/commaai/dependencies.git?subdirectory=raylib&rev=release-raylib#b5439c0c8178e5c2fee90eb396708ae1524a2662" } -dependencies = [ - { name = "cffi" }, -] - [[package]] name = "rednose" version = "0.0.1" @@ -1596,6 +1693,12 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/4e/39/a61d4b83a7746b70d23d9173be688c0c6bfc7173772344b7442c2c155497/sounddevice-0.5.5-py3-none-win_arm64.whl", hash = "sha256:3861901ddd8230d2e0e8ae62ac320cdd4c688d81df89da036dcb812f757bb3e6", size = 317115, upload-time = "2026-01-23T18:36:42.235Z" }, ] +[[package]] +name = "spidev" +version = "3.8" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/67/87/039b6eeea781598015b538691bc174cc0bf77df9d4d2d3b8bf9245c0de8c/spidev-3.8.tar.gz", hash = "sha256:2bc02fb8c6312d519ebf1f4331067427c0921d3f77b8bcaf05189a2e8b8382c0", size = 13893, upload-time = "2025-09-15T18:56:20.672Z" } + [[package]] name = "sympy" version = "1.14.0" @@ -1853,11 +1956,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/73/26/fc7ef081acbdada8436825221cb728ee84a81d4d78a7bb79aa58bd150d31/zensical-0.0.46-cp310-abi3-win_amd64.whl", hash = "sha256:1543a693a160de60e86ca589592401b584670e7e12c5ae30e3c2ba76786f7ec3", size = 12599687, upload-time = "2026-06-21T18:52:37.913Z" }, ] -[[package]] -name = "zeromq" -version = "4.3.5" -source = { git = "https://github.com/commaai/dependencies.git?subdirectory=zeromq&rev=release-zeromq#dbdee00796b9714d318a883029bf05e844646c3b" } - [[package]] name = "zipp" version = "4.1.0" @@ -1891,8 +1989,3 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/79/3b/fa54d9015f945330510cb5d0b0501e8253c127cca7ebe8ba46a965df18c5/zstandard-0.25.0-cp312-cp312-win_amd64.whl", hash = "sha256:ffef5a74088f1e09947aecf91011136665152e0b4b359c42be3373897fb39b01", size = 506276, upload-time = "2025-09-14T22:17:21.429Z" }, { url = "https://files.pythonhosted.org/packages/ea/6b/8b51697e5319b1f9ac71087b0af9a40d8a6288ff8025c36486e0c12abcc4/zstandard-0.25.0-cp312-cp312-win_arm64.whl", hash = "sha256:181eb40e0b6a29b3cd2849f825e0fa34397f649170673d385f3598ae17cca2e9", size = 462679, upload-time = "2025-09-14T22:17:23.147Z" }, ] - -[[package]] -name = "zstd" -version = "1.5.6" -source = { git = "https://github.com/commaai/dependencies.git?subdirectory=zstd&rev=release-zstd#66b1dbae3110f047af4262c1b561641d8c764e85" } From 9877f6ac0ecd9d3cdc0e9abeb7f6994a8458d42a Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Wed, 8 Jul 2026 20:20:24 -0700 Subject: [PATCH 117/151] ffmpeg: use shared libraries (#38308) --- SConstruct | 19 +++++++++++++++++-- openpilot/system/loggerd/SConscript | 9 ++------- openpilot/tools/cabana/SConscript | 6 ++---- openpilot/tools/jotpluggler/SConscript | 8 ++++---- openpilot/tools/replay/SConscript | 6 ++---- uv.lock | 8 ++++---- 6 files changed, 31 insertions(+), 25 deletions(-) diff --git a/SConstruct b/SConstruct index d73bb4b22c..0f7854dcd4 100644 --- a/SConstruct +++ b/SConstruct @@ -43,6 +43,21 @@ assert arch in [ pkg_names = ['acados', 'bzip2', 'capnproto', 'catch2', 'eigen', 'ffmpeg', 'json11', 'libyuv', 'ncurses', 'zeromq', 'zstd'] pkgs = [importlib.import_module(name) for name in pkg_names] acados = pkgs[pkg_names.index('acados')] +ffmpeg = pkgs[pkg_names.index('ffmpeg')] +# Shared package ships .so/.dylib; older device venvs still have static .a only. +# Keep static link deps (x264/z/va/drm) when the installed package is static so +# TICI CI works without upgrading the device venv yet. +# TODO: drop the static fallback once device venvs have comma-deps-ffmpeg>=7.1.0.post94 +_ffmpeg_lib_names = os.listdir(ffmpeg.LIB_DIR) if os.path.isdir(ffmpeg.LIB_DIR) else [] +ffmpeg_shared = any( + n.startswith('libavcodec.so') or (n.startswith('libavcodec') and n.endswith('.dylib')) + for n in _ffmpeg_lib_names +) +ffmpeg_libs = ['avformat', 'avcodec', 'swresample', 'avutil'] +if not ffmpeg_shared: + ffmpeg_libs += ['x264', 'z'] + if arch != "Darwin": + ffmpeg_libs += ['va', 'va-drm', 'drm'] acados_include_dirs = [ acados.INCLUDE_DIR, os.path.join(acados.INCLUDE_DIR, "blasfeo", "include"), @@ -126,7 +141,7 @@ env = Environment( "#rednose/helpers", [x.LIB_DIR for x in pkgs], ], - RPATH=[], + RPATH=[ffmpeg.LIB_DIR] if ffmpeg_shared else [], CYTHONCFILESUFFIX=".cpp", COMPILATIONDB_USE_ABSPATH=True, REDNOSE_ROOT="#", @@ -192,7 +207,7 @@ else: np_version = SCons.Script.Value(np.__version__) Export('envCython', 'np_version') -Export('env', 'arch', 'acados') +Export('env', 'arch', 'acados', 'ffmpeg_libs') # Setup cache dir cache_dir = '/data/scons_cache' if arch == "larch64" else '/tmp/scons_cache' diff --git a/openpilot/system/loggerd/SConscript b/openpilot/system/loggerd/SConscript index f83e3f04ff..0bba1d1771 100644 --- a/openpilot/system/loggerd/SConscript +++ b/openpilot/system/loggerd/SConscript @@ -1,8 +1,6 @@ -Import('env', 'arch', 'messaging', 'common', 'visionipc') +Import('env', 'arch', 'messaging', 'common', 'visionipc', 'ffmpeg_libs') -libs = [common, messaging, visionipc, - 'avformat', 'avcodec', 'swresample', 'avutil', 'x264', - 'pthread', 'z', 'm', 'zstd'] +libs = [common, messaging, visionipc] + ffmpeg_libs + ['pthread', 'm', 'zstd'] frameworks = [] src = ['logger.cc', 'zstd_writer.cc', 'video_writer.cc', 'encoder/encoder.cc', 'encoder/jpeg_encoder.cc'] @@ -14,9 +12,6 @@ else: if arch == "Darwin": frameworks += ['VideoToolbox', 'CoreMedia', 'CoreFoundation', 'CoreVideo'] -if arch != "Darwin": - libs += ['va', 'va-drm', 'drm'] - logger_lib = env.Library('logger', src) libs.insert(0, logger_lib) diff --git a/openpilot/tools/cabana/SConscript b/openpilot/tools/cabana/SConscript index 5a6ea7baf5..aa91514510 100644 --- a/openpilot/tools/cabana/SConscript +++ b/openpilot/tools/cabana/SConscript @@ -5,7 +5,7 @@ import shutil import bootstrap_icons import libusb -Import('env', 'arch', 'common', 'messaging', 'visionipc', 'cereal', 'replay_lib') +Import('env', 'arch', 'common', 'messaging', 'visionipc', 'cereal', 'replay_lib', 'ffmpeg_libs') # Detect Qt - skip build if not available if arch == "Darwin": @@ -75,9 +75,7 @@ cabana_env = qt_env.Clone() cabana_env['CPPPATH'] += [libusb.INCLUDE_DIR] cabana_env['LIBPATH'] += [libusb.LIB_DIR] -cabana_libs = [cereal, messaging, visionipc, replay_lib, 'avformat', 'avcodec', 'swresample', 'avutil', 'x264', 'z', 'bz2', 'zstd', 'yuv', 'usb-1.0'] + base_libs -if arch != "Darwin": - cabana_libs += ['va', 'va-drm', 'drm'] +cabana_libs = [cereal, messaging, visionipc, replay_lib] + ffmpeg_libs + ['bz2', 'zstd', 'yuv', 'usb-1.0'] + base_libs opendbc_path = '-DOPENDBC_FILE_PATH=\'"%s"\'' % (cabana_env.Dir("../../../opendbc/dbc").abspath) cabana_env['CXXFLAGS'] += [opendbc_path] diff --git a/openpilot/tools/jotpluggler/SConscript b/openpilot/tools/jotpluggler/SConscript index 3e235bb07a..dda9c8fac4 100644 --- a/openpilot/tools/jotpluggler/SConscript +++ b/openpilot/tools/jotpluggler/SConscript @@ -9,7 +9,7 @@ from opendbc.car.fingerprints import MIGRATION from opendbc.car.values import PLATFORMS from openpilot.common.basedir import BASEDIR -Import('env', 'arch', 'common', 'messaging', 'visionipc', 'cereal', 'replay_lib') +Import('env', 'arch', 'common', 'messaging', 'visionipc', 'cereal', 'replay_lib', 'ffmpeg_libs') jot_env = env.Clone() jot_env["LIBPATH"] += [imgui.MESA_DIR, libusb.LIB_DIR] @@ -101,12 +101,12 @@ event_extractors = jot_env.Command("generated_event_extractors.h", [ generate_event_extractors, ) -libs = [replay_lib, common, messaging, visionipc, cereal, File(f"{imgui.LIB_DIR}/libimgui.a"), File(f"{imgui.LIB_DIR}/libglfw3.a"), - "avformat", "avcodec", "avutil", "x264", "yuv", "z", "bz2", "zstd", "m", "pthread", "usb-1.0"] +libs = [replay_lib, common, messaging, visionipc, cereal, File(f"{imgui.LIB_DIR}/libimgui.a"), File(f"{imgui.LIB_DIR}/libglfw3.a")] + \ + ffmpeg_libs + ["yuv", "bz2", "zstd", "m", "pthread", "usb-1.0"] if arch == "Darwin": jot_env["FRAMEWORKS"] = ["OpenGL", "Cocoa", "IOKit", "CoreFoundation", "CoreVideo", "CoreMedia", "VideoToolbox"] else: - libs += ["GL", "dl", "va", "va-drm", "drm"] + libs += ["GL", "dl"] program = jot_env.Program("jotpluggler", jot_env.Glob("*.cc"), LIBS=libs) jot_env.Depends(program, generated_dbc_stamp) diff --git a/openpilot/tools/replay/SConscript b/openpilot/tools/replay/SConscript index d047415f58..c1f5618523 100644 --- a/openpilot/tools/replay/SConscript +++ b/openpilot/tools/replay/SConscript @@ -1,4 +1,4 @@ -Import('env', 'arch', 'common', 'messaging', 'visionipc', 'cereal') +Import('env', 'arch', 'common', 'messaging', 'visionipc', 'cereal', 'ffmpeg_libs') replay_env = env.Clone() replay_env['CCFLAGS'] += ['-Wno-deprecated-declarations'] @@ -12,9 +12,7 @@ if arch != "Darwin": replay_lib_src.append("qcom_decoder.cc") replay_lib = replay_env.Library("replay", replay_lib_src, LIBS=base_libs, FRAMEWORKS=base_frameworks) Export('replay_lib') -replay_libs = [replay_lib, 'avformat', 'avcodec', 'swresample', 'avutil', 'x264', 'z', 'bz2', 'zstd', 'yuv', 'ncurses'] + base_libs -if arch != "Darwin": - replay_libs += ['va', 'va-drm', 'drm'] +replay_libs = [replay_lib] + ffmpeg_libs + ['bz2', 'zstd', 'yuv', 'ncurses'] + base_libs replay_env.Program("replay", ["main.cc"], LIBS=replay_libs, FRAMEWORKS=base_frameworks) if GetOption('extras'): diff --git a/uv.lock b/uv.lock index 0fb7dddd0c..8d14aeb3bb 100644 --- a/uv.lock +++ b/uv.lock @@ -274,12 +274,12 @@ wheels = [ [[package]] name = "comma-deps-ffmpeg" -version = "7.1.0.post93" +version = "7.1.0.post94" source = { registry = "https://pypi.org/simple" } wheels = [ - { url = "https://files.pythonhosted.org/packages/65/02/7e21345a4b6493b94dcacdf14024d24fc143469b3b596dbe0a0433b9055d/comma_deps_ffmpeg-7.1.0.post93-py3-none-macosx_11_0_arm64.whl", hash = "sha256:129f05e177ae8abfb758ff6b56efdb8caa4c10c435f73c774dd4470349c05502", size = 10673113, upload-time = "2026-07-08T19:31:20.253Z" }, - { url = "https://files.pythonhosted.org/packages/18/ac/579bbb4d8724406738b0eef41f4e49bb0dff17eb4b9b5397296f5d65c84e/comma_deps_ffmpeg-7.1.0.post93-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:185bab6cd683448a1fba9338b11da7e7454b798e27a52d789ea02dd827e944fe", size = 11748947, upload-time = "2026-07-08T19:31:24.618Z" }, - { url = "https://files.pythonhosted.org/packages/6e/bc/feb5dc8e2e75ecf147281801b1a2a864996c1e1a3be934aeb5cebdcf7323/comma_deps_ffmpeg-7.1.0.post93-py3-none-manylinux_2_28_x86_64.whl", hash = "sha256:161e3bcbee02b0d5d2b7bcff2c249904fe7b9c9b3f7820b954a4fb2d24c0fe21", size = 12433434, upload-time = "2026-07-08T19:31:28.965Z" }, + { url = "https://files.pythonhosted.org/packages/7d/5c/47e10049fd96b581e8ddc9fba31c3397562732fcc99db6c062690e862300/comma_deps_ffmpeg-7.1.0.post94-py3-none-macosx_11_0_arm64.whl", hash = "sha256:2e87b4dd0fb0fc25d6992167ee266b5c9e92305aefa3d343ddd22a17219363b8", size = 7329953, upload-time = "2026-07-09T03:07:11.516Z" }, + { url = "https://files.pythonhosted.org/packages/a7/d5/c4edfbbe488983ff45fb6cacab78342fc56cc0f28010a946e8697613ffe2/comma_deps_ffmpeg-7.1.0.post94-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:7ea34368c5b564cecab0fd77d6423bc15d8f100051648f64ad79a3499f43dafb", size = 4441314, upload-time = "2026-07-09T03:07:15.679Z" }, + { url = "https://files.pythonhosted.org/packages/80/8f/76a876a26572c52d52dbcf8ed39227f5023d343201a32af4b992c4b9f13e/comma_deps_ffmpeg-7.1.0.post94-py3-none-manylinux_2_28_x86_64.whl", hash = "sha256:5b2d6cfbba59ecd673dd0c8bd8eb5a5b3472bdfa025e1063c011e6234877fe84", size = 4685134, upload-time = "2026-07-09T03:07:19.596Z" }, ] [[package]] From 1e49eac4d12e8a9204dccd240fdb90c5daa75a5d Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Wed, 8 Jul 2026 20:27:27 -0700 Subject: [PATCH 118/151] rm libyuv (#38306) * rm libyuv * cleanup --- SConstruct | 2 +- openpilot/common/SConscript | 1 + openpilot/common/yuv.cc | 132 ++++++++++++++++++ openpilot/common/yuv.h | 42 ++++++ openpilot/system/loggerd/SConscript | 1 - .../system/loggerd/encoder/ffmpeg_encoder.cc | 32 ++--- openpilot/tools/cabana/SConscript | 2 +- openpilot/tools/jotpluggler/SConscript | 2 +- openpilot/tools/jotpluggler/runtime.cc | 34 ++--- openpilot/tools/replay/SConscript | 2 +- openpilot/tools/replay/framereader.cc | 14 +- pyproject.toml | 1 - uv.lock | 12 -- 13 files changed, 218 insertions(+), 59 deletions(-) create mode 100644 openpilot/common/yuv.cc create mode 100644 openpilot/common/yuv.h diff --git a/SConstruct b/SConstruct index 0f7854dcd4..7e102add90 100644 --- a/SConstruct +++ b/SConstruct @@ -40,7 +40,7 @@ assert arch in [ "Darwin", # macOS arm64 (x86 not supported) ] -pkg_names = ['acados', 'bzip2', 'capnproto', 'catch2', 'eigen', 'ffmpeg', 'json11', 'libyuv', 'ncurses', 'zeromq', 'zstd'] +pkg_names = ['acados', 'bzip2', 'capnproto', 'catch2', 'eigen', 'ffmpeg', 'json11', 'ncurses', 'zeromq', 'zstd'] pkgs = [importlib.import_module(name) for name in pkg_names] acados = pkgs[pkg_names.index('acados')] ffmpeg = pkgs[pkg_names.index('ffmpeg')] diff --git a/openpilot/common/SConscript b/openpilot/common/SConscript index c9bd1c72d1..68dcc84171 100644 --- a/openpilot/common/SConscript +++ b/openpilot/common/SConscript @@ -5,6 +5,7 @@ common_libs = [ 'swaglog.cc', 'util.cc', 'ratekeeper.cc', + 'yuv.cc', ] _common = env.Library('common', common_libs, LIBS="json11") diff --git a/openpilot/common/yuv.cc b/openpilot/common/yuv.cc new file mode 100644 index 0000000000..a7a64fb594 --- /dev/null +++ b/openpilot/common/yuv.cc @@ -0,0 +1,132 @@ +#include "common/yuv.h" + +#include +#include + +namespace yuv { + +namespace { + +inline uint8_t clamp_u8(int v) { + return static_cast(std::clamp(v, 0, 255)); +} + +void copy_plane(const uint8_t *src, int src_stride, + uint8_t *dst, int dst_stride, + int width, int height) { + if (src_stride == width && dst_stride == width) { + std::memcpy(dst, src, static_cast(width) * height); + return; + } + for (int y = 0; y < height; ++y) { + std::memcpy(dst + y * dst_stride, src + y * src_stride, width); + } +} + +void scale_plane_point(const uint8_t *src, int src_stride, int src_width, int src_height, + uint8_t *dst, int dst_stride, int dst_width, int dst_height) { + if (src_width == dst_width && src_height == dst_height) { + copy_plane(src, src_stride, dst, dst_stride, dst_width, dst_height); + return; + } + for (int y = 0; y < dst_height; ++y) { + const int sy = y * src_height / dst_height; + const uint8_t *src_row = src + sy * src_stride; + uint8_t *dst_row = dst + y * dst_stride; + for (int x = 0; x < dst_width; ++x) { + dst_row[x] = src_row[x * src_width / dst_width]; + } + } +} + +// BT.601 limited range → RGB (integer form used widely, incl. similar to libyuv). +inline void yuv_to_rgb(int y, int u, int v, uint8_t *r, uint8_t *g, uint8_t *b) { + const int c = (y - 16) * 298; + const int d = u - 128; + const int e = v - 128; + *r = clamp_u8((c + 409 * e + 128) >> 8); + *g = clamp_u8((c - 100 * d - 208 * e + 128) >> 8); + *b = clamp_u8((c + 516 * d + 128) >> 8); +} + +} // namespace + +void nv12_to_i420(const uint8_t *src_y, int src_stride_y, + const uint8_t *src_uv, int src_stride_uv, + uint8_t *dst_y, int dst_stride_y, + uint8_t *dst_u, int dst_stride_u, + uint8_t *dst_v, int dst_stride_v, + int width, int height) { + copy_plane(src_y, src_stride_y, dst_y, dst_stride_y, width, height); + + const int uv_width = width / 2; + const int uv_height = height / 2; + for (int y = 0; y < uv_height; ++y) { + const uint8_t *uv = src_uv + y * src_stride_uv; + uint8_t *u = dst_u + y * dst_stride_u; + uint8_t *v = dst_v + y * dst_stride_v; + for (int x = 0; x < uv_width; ++x) { + u[x] = uv[2 * x]; + v[x] = uv[2 * x + 1]; + } + } +} + +void i420_to_nv12(const uint8_t *src_y, int src_stride_y, + const uint8_t *src_u, int src_stride_u, + const uint8_t *src_v, int src_stride_v, + uint8_t *dst_y, int dst_stride_y, + uint8_t *dst_uv, int dst_stride_uv, + int width, int height) { + copy_plane(src_y, src_stride_y, dst_y, dst_stride_y, width, height); + + const int uv_width = width / 2; + const int uv_height = height / 2; + for (int y = 0; y < uv_height; ++y) { + const uint8_t *u = src_u + y * src_stride_u; + const uint8_t *v = src_v + y * src_stride_v; + uint8_t *uv = dst_uv + y * dst_stride_uv; + for (int x = 0; x < uv_width; ++x) { + uv[2 * x] = u[x]; + uv[2 * x + 1] = v[x]; + } + } +} + +void i420_scale(const uint8_t *src_y, int src_stride_y, + const uint8_t *src_u, int src_stride_u, + const uint8_t *src_v, int src_stride_v, + int src_width, int src_height, + uint8_t *dst_y, int dst_stride_y, + uint8_t *dst_u, int dst_stride_u, + uint8_t *dst_v, int dst_stride_v, + int dst_width, int dst_height) { + scale_plane_point(src_y, src_stride_y, src_width, src_height, + dst_y, dst_stride_y, dst_width, dst_height); + scale_plane_point(src_u, src_stride_u, src_width / 2, src_height / 2, + dst_u, dst_stride_u, dst_width / 2, dst_height / 2); + scale_plane_point(src_v, src_stride_v, src_width / 2, src_height / 2, + dst_v, dst_stride_v, dst_width / 2, dst_height / 2); +} + +void nv12_to_rgba(const uint8_t *src_y, int src_stride_y, + const uint8_t *src_uv, int src_stride_uv, + uint8_t *dst_rgba, int dst_stride_rgba, + int width, int height) { + for (int y = 0; y < height; ++y) { + const uint8_t *y_row = src_y + y * src_stride_y; + const uint8_t *uv_row = src_uv + (y / 2) * src_stride_uv; + uint8_t *dst = dst_rgba + y * dst_stride_rgba; + for (int x = 0; x < width; ++x) { + const int uv_x = (x & ~1); + uint8_t r, g, b; + yuv_to_rgb(y_row[x], uv_row[uv_x], uv_row[uv_x + 1], &r, &g, &b); + dst[4 * x + 0] = r; + dst[4 * x + 1] = g; + dst[4 * x + 2] = b; + dst[4 * x + 3] = 255; + } + } +} + +} // namespace yuv diff --git a/openpilot/common/yuv.h b/openpilot/common/yuv.h new file mode 100644 index 0000000000..7ab096f764 --- /dev/null +++ b/openpilot/common/yuv.h @@ -0,0 +1,42 @@ +#pragma once + +#include + +// NV12: Y plane + interleaved UV. I420: planar Y, U, V. + +namespace yuv { + +// Deinterleave NV12 UV into planar I420. +void nv12_to_i420(const uint8_t *src_y, int src_stride_y, + const uint8_t *src_uv, int src_stride_uv, + uint8_t *dst_y, int dst_stride_y, + uint8_t *dst_u, int dst_stride_u, + uint8_t *dst_v, int dst_stride_v, + int width, int height); + +// Interleave planar I420 UV into NV12. +void i420_to_nv12(const uint8_t *src_y, int src_stride_y, + const uint8_t *src_u, int src_stride_u, + const uint8_t *src_v, int src_stride_v, + uint8_t *dst_y, int dst_stride_y, + uint8_t *dst_uv, int dst_stride_uv, + int width, int height); + +// Point-sample scale I420 (equivalent to libyuv::I420Scale + kFilterNone). +void i420_scale(const uint8_t *src_y, int src_stride_y, + const uint8_t *src_u, int src_stride_u, + const uint8_t *src_v, int src_stride_v, + int src_width, int src_height, + uint8_t *dst_y, int dst_stride_y, + uint8_t *dst_u, int dst_stride_u, + uint8_t *dst_v, int dst_stride_v, + int dst_width, int dst_height); + +// Convert NV12 to packed RGBA (R,G,B,A bytes — suitable for GL_RGBA). +// BT.601 limited-range, matching common libyuv defaults. +void nv12_to_rgba(const uint8_t *src_y, int src_stride_y, + const uint8_t *src_uv, int src_stride_uv, + uint8_t *dst_rgba, int dst_stride_rgba, + int width, int height); + +} diff --git a/openpilot/system/loggerd/SConscript b/openpilot/system/loggerd/SConscript index 0bba1d1771..7f6d4faf0c 100644 --- a/openpilot/system/loggerd/SConscript +++ b/openpilot/system/loggerd/SConscript @@ -8,7 +8,6 @@ if arch == "larch64": src += ['encoder/v4l_encoder.cc'] else: src += ['encoder/ffmpeg_encoder.cc'] - libs += ['yuv'] if arch == "Darwin": frameworks += ['VideoToolbox', 'CoreMedia', 'CoreFoundation', 'CoreVideo'] diff --git a/openpilot/system/loggerd/encoder/ffmpeg_encoder.cc b/openpilot/system/loggerd/encoder/ffmpeg_encoder.cc index 40f3bdee42..451445e5a0 100644 --- a/openpilot/system/loggerd/encoder/ffmpeg_encoder.cc +++ b/openpilot/system/loggerd/encoder/ffmpeg_encoder.cc @@ -9,8 +9,6 @@ #define __STDC_CONSTANT_MACROS -#include "libyuv.h" - extern "C" { #include #include @@ -19,6 +17,7 @@ extern "C" { #include "common/swaglog.h" #include "common/util.h" +#include "common/yuv.h" const int env_debug_encoder = (getenv("DEBUG_ENCODER") != NULL) ? atoi(getenv("DEBUG_ENCODER")) : 0; @@ -87,26 +86,25 @@ int FfmpegEncoder::encode_frame(VisionBuf* buf, VisionIpcBufExtra *extra) { uint8_t *cy = convert_buf.data(); uint8_t *cu = cy + in_width * in_height; uint8_t *cv = cu + (in_width / 2) * (in_height / 2); - libyuv::NV12ToI420(buf->y, buf->stride, - buf->uv, buf->stride, - cy, in_width, - cu, in_width/2, - cv, in_width/2, - in_width, in_height); + yuv::nv12_to_i420(buf->y, buf->stride, + buf->uv, buf->stride, + cy, in_width, + cu, in_width/2, + cv, in_width/2, + in_width, in_height); if (downscale_buf.size() > 0) { uint8_t *out_y = downscale_buf.data(); uint8_t *out_u = out_y + frame->width * frame->height; uint8_t *out_v = out_u + (frame->width / 2) * (frame->height / 2); - libyuv::I420Scale(cy, in_width, - cu, in_width/2, - cv, in_width/2, - in_width, in_height, - out_y, frame->width, - out_u, frame->width/2, - out_v, frame->width/2, - frame->width, frame->height, - libyuv::kFilterNone); + yuv::i420_scale(cy, in_width, + cu, in_width/2, + cv, in_width/2, + in_width, in_height, + out_y, frame->width, + out_u, frame->width/2, + out_v, frame->width/2, + frame->width, frame->height); frame->data[0] = out_y; frame->data[1] = out_u; frame->data[2] = out_v; diff --git a/openpilot/tools/cabana/SConscript b/openpilot/tools/cabana/SConscript index aa91514510..ec94fec266 100644 --- a/openpilot/tools/cabana/SConscript +++ b/openpilot/tools/cabana/SConscript @@ -75,7 +75,7 @@ cabana_env = qt_env.Clone() cabana_env['CPPPATH'] += [libusb.INCLUDE_DIR] cabana_env['LIBPATH'] += [libusb.LIB_DIR] -cabana_libs = [cereal, messaging, visionipc, replay_lib] + ffmpeg_libs + ['bz2', 'zstd', 'yuv', 'usb-1.0'] + base_libs +cabana_libs = [cereal, messaging, visionipc, replay_lib] + ffmpeg_libs + ['bz2', 'zstd', 'usb-1.0'] + base_libs opendbc_path = '-DOPENDBC_FILE_PATH=\'"%s"\'' % (cabana_env.Dir("../../../opendbc/dbc").abspath) cabana_env['CXXFLAGS'] += [opendbc_path] diff --git a/openpilot/tools/jotpluggler/SConscript b/openpilot/tools/jotpluggler/SConscript index dda9c8fac4..d5ebaffb98 100644 --- a/openpilot/tools/jotpluggler/SConscript +++ b/openpilot/tools/jotpluggler/SConscript @@ -102,7 +102,7 @@ event_extractors = jot_env.Command("generated_event_extractors.h", [ ) libs = [replay_lib, common, messaging, visionipc, cereal, File(f"{imgui.LIB_DIR}/libimgui.a"), File(f"{imgui.LIB_DIR}/libglfw3.a")] + \ - ffmpeg_libs + ["yuv", "bz2", "zstd", "m", "pthread", "usb-1.0"] + ffmpeg_libs + ["bz2", "zstd", "m", "pthread", "usb-1.0"] if arch == "Darwin": jot_env["FRAMEWORKS"] = ["OpenGL", "Cocoa", "IOKit", "CoreFoundation", "CoreVideo", "CoreMedia", "VideoToolbox"] else: diff --git a/openpilot/tools/jotpluggler/runtime.cc b/openpilot/tools/jotpluggler/runtime.cc index 4e98f96c3d..a1e47c7e8e 100644 --- a/openpilot/tools/jotpluggler/runtime.cc +++ b/openpilot/tools/jotpluggler/runtime.cc @@ -7,7 +7,7 @@ #include "imgui_impl_opengl3.h" #include "imgui_impl_opengl3_loader.h" #include "implot.h" -#include "libyuv.h" +#include "common/yuv.h" #include "msgq_repo/msgq/ipc.h" #include "tools/replay/framereader.h" @@ -1173,14 +1173,14 @@ struct CameraFeedView::Impl { result.width = reader->width; result.height = reader->height; result.rgba.resize(static_cast(result.width) * static_cast(result.height) * 4U, 0); - libyuv::NV12ToABGR(decode_buffer.y, - static_cast(decode_buffer.stride), - decode_buffer.uv, - static_cast(decode_buffer.stride), - result.rgba.data(), - result.width * 4, - result.width, - result.height); + yuv::nv12_to_rgba(decode_buffer.y, + static_cast(decode_buffer.stride), + decode_buffer.uv, + static_cast(decode_buffer.stride), + result.rgba.data(), + result.width * 4, + result.width, + result.height); result.success = true; result.decode_ms = std::chrono::duration(std::chrono::steady_clock::now() - decode_begin).count(); publish_result(*request, std::move(result)); @@ -1203,14 +1203,14 @@ struct CameraFeedView::Impl { .height = reader->height, }; prefetched.rgba.resize(static_cast(prefetched.width) * static_cast(prefetched.height) * 4U, 0); - libyuv::NV12ToABGR(decode_buffer.y, - static_cast(decode_buffer.stride), - decode_buffer.uv, - static_cast(decode_buffer.stride), - prefetched.rgba.data(), - prefetched.width * 4, - prefetched.width, - prefetched.height); + yuv::nv12_to_rgba(decode_buffer.y, + static_cast(decode_buffer.stride), + decode_buffer.uv, + static_cast(decode_buffer.stride), + prefetched.rgba.data(), + prefetched.width * 4, + prefetched.width, + prefetched.height); remember_cached_result(prefetched); } } diff --git a/openpilot/tools/replay/SConscript b/openpilot/tools/replay/SConscript index c1f5618523..643de97bb9 100644 --- a/openpilot/tools/replay/SConscript +++ b/openpilot/tools/replay/SConscript @@ -12,7 +12,7 @@ if arch != "Darwin": replay_lib_src.append("qcom_decoder.cc") replay_lib = replay_env.Library("replay", replay_lib_src, LIBS=base_libs, FRAMEWORKS=base_frameworks) Export('replay_lib') -replay_libs = [replay_lib] + ffmpeg_libs + ['bz2', 'zstd', 'yuv', 'ncurses'] + base_libs +replay_libs = [replay_lib] + ffmpeg_libs + ['bz2', 'zstd', 'ncurses'] + base_libs replay_env.Program("replay", ["main.cc"], LIBS=replay_libs, FRAMEWORKS=base_frameworks) if GetOption('extras'): diff --git a/openpilot/tools/replay/framereader.cc b/openpilot/tools/replay/framereader.cc index 52db658add..7c6f144148 100644 --- a/openpilot/tools/replay/framereader.cc +++ b/openpilot/tools/replay/framereader.cc @@ -6,7 +6,7 @@ #include #include "common/util.h" -#include "libyuv.h" +#include "common/yuv.h" #include "tools/replay/py_downloader.h" #include "tools/replay/util.h" #include "common/hardware/hw.h" @@ -258,12 +258,12 @@ bool FFmpegVideoDecoder::copyBuffer(AVFrame *f, VisionBuf *buf) { memcpy(buf->uv + i*buf->stride, f->data[1] + i*f->linesize[1], width); } } else { - libyuv::I420ToNV12(f->data[0], f->linesize[0], - f->data[1], f->linesize[1], - f->data[2], f->linesize[2], - buf->y, buf->stride, - buf->uv, buf->stride, - width, height); + yuv::i420_to_nv12(f->data[0], f->linesize[0], + f->data[1], f->linesize[1], + f->data[2], f->linesize[2], + buf->y, buf->stride, + buf->uv, buf->stride, + width, height); } return true; } diff --git a/pyproject.toml b/pyproject.toml index 1c4e551b81..a609ccf134 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -33,7 +33,6 @@ dependencies = [ "comma-deps-acados", "comma-deps-eigen", "comma-deps-ffmpeg", - "comma-deps-libyuv", "comma-deps-zstd", "comma-deps-ncurses", "comma-deps-zeromq", diff --git a/uv.lock b/uv.lock index 8d14aeb3bb..2ea503628f 100644 --- a/uv.lock +++ b/uv.lock @@ -332,16 +332,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/84/47/f4f2da67db202bacc3fa578fdebdb916f45c97bee0c3d2c5fbe845a6f129/comma_deps_libusb-1.0.29.post93-py3-none-manylinux_2_28_x86_64.whl", hash = "sha256:f136dbbfc461d228378731361cc66a90a483e17d55f8ba43f23eeab6bcf41963", size = 93461, upload-time = "2026-07-08T19:32:26.434Z" }, ] -[[package]] -name = "comma-deps-libyuv" -version = "1922.0.post93" -source = { registry = "https://pypi.org/simple" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/19/91/f68b07f4ef01860d85e716b5095e10326de74455970cb279d70cdf45ee51/comma_deps_libyuv-1922.0.post93-py3-none-macosx_11_0_arm64.whl", hash = "sha256:f5e0d1550229efdc9aabcaa90b421902322ac7ddadd6e2118596916571c0619b", size = 269554, upload-time = "2026-07-08T19:32:29.709Z" }, - { url = "https://files.pythonhosted.org/packages/ee/6b/ca7ab7c00a16470f03a25c1079a50a2b7933516584056f15fb05385f377c/comma_deps_libyuv-1922.0.post93-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:3c55195bc905144ef157b8d2f8f36b25250d0a489bb07f2964327e48a0009669", size = 268385, upload-time = "2026-07-08T19:32:33.141Z" }, - { url = "https://files.pythonhosted.org/packages/0b/9d/ecdbbeef4c3797091ea990bbe4dcc10389e5d6bff27e20bed3b4e4a85eed/comma_deps_libyuv-1922.0.post93-py3-none-manylinux_2_28_x86_64.whl", hash = "sha256:1309769c64394294cbd399c77584f7d674753e6dda39b57243ab156711b6d353", size = 273326, upload-time = "2026-07-08T19:32:36.807Z" }, -] - [[package]] name = "comma-deps-ncurses" version = "6.5.post93" @@ -1004,7 +994,6 @@ dependencies = [ { name = "comma-deps-git-lfs" }, { name = "comma-deps-json11" }, { name = "comma-deps-libusb" }, - { name = "comma-deps-libyuv" }, { name = "comma-deps-ncurses" }, { name = "comma-deps-raylib" }, { name = "comma-deps-zeromq" }, @@ -1088,7 +1077,6 @@ requires-dist = [ { name = "comma-deps-imgui", marker = "extra == 'tools'" }, { name = "comma-deps-json11" }, { name = "comma-deps-libusb" }, - { name = "comma-deps-libyuv" }, { name = "comma-deps-ncurses" }, { name = "comma-deps-raylib" }, { name = "comma-deps-zeromq" }, From 3b3f5967ec2ecfdf390cf7c6d17c9501ce4dd916 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Wed, 8 Jul 2026 20:43:12 -0700 Subject: [PATCH 119/151] rm crcmod-plus (#38309) * rm crcmod-plus * cleanup --- openpilot/system/qcomgpsd/modemdiag.py | 30 ++++++++++++++++++++++---- pyproject.toml | 1 - uv.lock | 18 ---------------- 3 files changed, 26 insertions(+), 23 deletions(-) diff --git a/openpilot/system/qcomgpsd/modemdiag.py b/openpilot/system/qcomgpsd/modemdiag.py index 5d72aeba9e..453084f4c8 100644 --- a/openpilot/system/qcomgpsd/modemdiag.py +++ b/openpilot/system/qcomgpsd/modemdiag.py @@ -1,8 +1,31 @@ import select from serial import Serial -from crcmod import mkCrcFun from struct import pack, unpack_from, calcsize + +def _gen_crc16_reflected_table(poly: int) -> list[int]: + # poly is the reflected form (e.g. 0x8408 for CRC-16 poly 0x1021) + table = [] + for i in range(256): + crc = i + for _ in range(8): + if crc & 1: + crc = (crc >> 1) ^ poly + else: + crc >>= 1 + table.append(crc) + return table + +# CRC-16/IBM-SDLC (aka X-25 / ISO-HDLC): poly 0x1021, refin/refout, init/xor 0xFFFF +_CRC16_X25_TABLE = _gen_crc16_reflected_table(0x8408) + +def crc16_x25(data: bytes) -> int: + crc = 0xFFFF + for b in data: + crc = _CRC16_X25_TABLE[(crc ^ b) & 0xFF] ^ (crc >> 8) + return crc ^ 0xFFFF + + class ModemDiag: def __init__(self): self.serial = self.open_serial() @@ -15,12 +38,11 @@ class ModemDiag: serial.reset_output_buffer() return serial - ccitt_crc16 = mkCrcFun(0x11021, initCrc=0, xorOut=0xffff) ESCAPE_CHAR = b'\x7d' TRAILER_CHAR = b'\x7e' def hdlc_encapsulate(self, payload): - payload += pack(' Date: Wed, 8 Jul 2026 21:06:53 -0700 Subject: [PATCH 120/151] rm pyserial (#38311) * rm pyserial * lil more * lil more --- openpilot/common/esim/lpa.py | 12 +- openpilot/common/hardware/tici/modem.py | 7 +- openpilot/common/serial.py | 272 ++++++++++++++++++++++++ openpilot/system/qcomgpsd/modemdiag.py | 4 +- openpilot/system/qcomgpsd/qcomgpsd.py | 2 +- openpilot/system/ubloxd/pigeond.py | 4 +- pyproject.toml | 1 - uv.lock | 11 - 8 files changed, 287 insertions(+), 26 deletions(-) create mode 100644 openpilot/common/serial.py diff --git a/openpilot/common/esim/lpa.py b/openpilot/common/esim/lpa.py index 4009823323..80138b54ae 100644 --- a/openpilot/common/esim/lpa.py +++ b/openpilot/common/esim/lpa.py @@ -6,7 +6,6 @@ import fcntl import hashlib import os import requests -import serial import subprocess import sys import termios @@ -20,6 +19,7 @@ from pathlib import Path from openpilot.common.time_helpers import system_time_valid from openpilot.common.esim.base import LPABase, LPAError, LPAProfileNotFoundError, Profile +from openpilot.common.serial import Serial, SerialException GSMA_CI_BUNDLE = str(Path(__file__).parent / "gsma_ci_bundle.pem") @@ -133,7 +133,7 @@ class AtClient: self._device = device self._baud = baud self._timeout = timeout - self._serial: serial.Serial | None = None + self._serial: Serial | None = None def send_raw(self, data: bytes) -> None: self._ensure_serial() @@ -185,14 +185,14 @@ class AtClient: pass self._serial = None if self._serial is None: - self._serial = serial.Serial(self._device, baudrate=self._baud, timeout=self._timeout) + self._serial = Serial(self._device, baudrate=self._baud, timeout=self._timeout) def query(self, cmd: str) -> list[str]: self._ensure_serial() try: self._send(cmd) return self._expect() - except serial.SerialException: + except SerialException: self._ensure_serial(reconnect=True) self._send(cmd) return self._expect() @@ -208,7 +208,7 @@ class AtClient: if self._serial: try: self._serial.reset_input_buffer() - except (OSError, serial.SerialException, termios.error): + except (OSError, SerialException, termios.error): self._ensure_serial(reconnect=True) for line in self.query(f'AT+CCHO="{ISDR_AID}"'): if line.startswith("+CCHO:") and (ch := line.split(":", 1)[1].strip()): @@ -230,7 +230,7 @@ class AtClient: try: self._open_isdr_once() return - except (RuntimeError, TimeoutError, termios.error, serial.SerialException): + except (RuntimeError, TimeoutError, termios.error, SerialException): time.sleep(OPEN_ISDR_RETRY_DELAY_S) if attempt == OPEN_ISDR_RESET_ATTEMPT: self._reset_modem() diff --git a/openpilot/common/hardware/tici/modem.py b/openpilot/common/hardware/tici/modem.py index 78f4e2a492..0d30c49328 100755 --- a/openpilot/common/hardware/tici/modem.py +++ b/openpilot/common/hardware/tici/modem.py @@ -3,7 +3,6 @@ import fcntl import json import logging import os -import serial import signal import subprocess import tempfile @@ -13,6 +12,8 @@ from ipaddress import IPv4Address, AddressValueError from enum import Enum +from openpilot.common.serial import Serial + logging.basicConfig( level=logging.INFO, format="%(asctime)s.%(msecs)03d %(levelname)-7s modem: %(message)s", @@ -96,7 +97,7 @@ class PPPSession: def reset_data_port(): """Drop DTR on PPP_PORT so the modem terminates any stuck PPP session.""" try: - with serial.Serial(PPP_PORT, 460800, timeout=1) as s: + with Serial(PPP_PORT, baudrate=460800, timeout=1) as s: s.dtr = False time.sleep(0.2) s.dtr = True @@ -220,7 +221,7 @@ class Modem: os.close(fd) return [] try: - with serial.Serial(AT_PORT, 9600, timeout=5) as ser: + with Serial(AT_PORT, baudrate=9600, timeout=5) as ser: ser.reset_input_buffer() ser.write((cmd + "\r").encode()) lines = [] diff --git a/openpilot/common/serial.py b/openpilot/common/serial.py new file mode 100644 index 0000000000..68083f40a6 --- /dev/null +++ b/openpilot/common/serial.py @@ -0,0 +1,272 @@ +import errno +import fcntl +import os +import select +import struct +import termios +import time + + +# Modem control lines (linux/termios.h); fall back to common x86_64 values. +TIOCMBIS = getattr(termios, "TIOCMBIS", 0x5416) +TIOCMBIC = getattr(termios, "TIOCMBIC", 0x5417) +TIOCM_DTR = getattr(termios, "TIOCM_DTR", 0x002) +TIOCM_RTS = getattr(termios, "TIOCM_RTS", 0x004) +_TIOCM_DTR = struct.pack("I", TIOCM_DTR) +_TIOCM_RTS = struct.pack("I", TIOCM_RTS) + + +class SerialException(OSError): + pass + + +class Serial: + def __init__(self, port: str, baudrate: int = 9600, timeout: float | None = None, *, + rtscts: bool = False, dsrdtr: bool = False, exclusive: bool = False): + self._port = port + self._baudrate = baudrate + self._timeout = timeout + self._rtscts = rtscts + self._dsrdtr = dsrdtr + self._exclusive = exclusive + self._dtr = True + self._fd = -1 + self.open() + + def __enter__(self): + return self + + def __exit__(self, *args) -> None: + self.close() + + @property + def fd(self) -> int: + self._ensure_open() + return self._fd + + @property + def baudrate(self) -> int: + return self._baudrate + + @baudrate.setter + def baudrate(self, value: int) -> None: + self._baudrate = int(value) + if self._fd >= 0: + self._configure() + + @property + def dtr(self) -> bool: + return self._dtr + + @dtr.setter + def dtr(self, value: bool) -> None: + self._dtr = bool(value) + if self._fd >= 0: + self._set_line(TIOCM_DTR, _TIOCM_DTR, self._dtr) + + def open(self) -> None: + if self._fd >= 0: + return + try: + self._fd = os.open(self._port, os.O_RDWR | os.O_NOCTTY | os.O_NONBLOCK) + except OSError as e: + self._fd = -1 + raise SerialException(e.errno, f"could not open port {self._port}: {e}") from e + + try: + if self._exclusive: + try: + fcntl.flock(self._fd, fcntl.LOCK_EX | fcntl.LOCK_NB) + except OSError as e: + raise SerialException(e.errno, f"could not exclusively lock port {self._port}: {e}") from e + + self._configure() + + # When not using hardware DSR/DTR handshaking, drive lines ourselves. + if not self._dsrdtr: + try: + self._set_line(TIOCM_DTR, _TIOCM_DTR, self._dtr) + if not self._rtscts: + self._set_line(TIOCM_RTS, _TIOCM_RTS, True) + except OSError as e: + if e.errno not in (errno.EINVAL, errno.ENOTTY): + raise + + self.reset_input_buffer() + except BaseException: + self._close_fd() + raise + + def close(self) -> None: + self._close_fd() + + def read(self, size: int = 1) -> bytes: + self._ensure_open() + if size <= 0: + return b"" + + buf = bytearray() + deadline = self._deadline() + while len(buf) < size: + remaining = None if deadline is None else max(0.0, deadline - time.monotonic()) + if not self._wait_readable(remaining): + break + try: + chunk = os.read(self._fd, size - len(buf)) + except InterruptedError: + continue + except OSError as e: + if e.errno in (errno.EAGAIN, errno.EWOULDBLOCK): + if self._timeout == 0: + break + continue + raise SerialException(e.errno, f"read failed: {e}") from e + if not chunk: + break + buf.extend(chunk) + return bytes(buf) + + def readline(self) -> bytes: + self._ensure_open() + buf = bytearray() + deadline = self._deadline() + while True: + remaining = None if deadline is None else max(0.0, deadline - time.monotonic()) + if deadline is not None and remaining == 0.0 and not buf: + # match pyserial: timed-out readline returns empty + if not self._wait_readable(0.0): + return b"" + elif not self._wait_readable(remaining): + return bytes(buf) + + try: + chunk = os.read(self._fd, 1) + except InterruptedError: + continue + except OSError as e: + if e.errno in (errno.EAGAIN, errno.EWOULDBLOCK): + if self._timeout == 0: + return bytes(buf) + continue + raise SerialException(e.errno, f"read failed: {e}") from e + if not chunk: + return bytes(buf) + buf.extend(chunk) + if chunk == b"\n": + return bytes(buf) + + def write(self, data: bytes) -> int: + self._ensure_open() + if not data: + return 0 + view = memoryview(data) + total = 0 + while total < len(data): + try: + n = os.write(self._fd, view[total:]) + except InterruptedError: + continue + except OSError as e: + if e.errno in (errno.EAGAIN, errno.EWOULDBLOCK): + select.select([], [self._fd], [], None) + continue + raise SerialException(e.errno, f"write failed: {e}") from e + if n == 0: + raise SerialException("write returned 0") + total += n + return total + + def flush(self) -> None: + self._ensure_open() + termios.tcdrain(self._fd) + + def reset_input_buffer(self) -> None: + self._ensure_open() + termios.tcflush(self._fd, termios.TCIFLUSH) + + def reset_output_buffer(self) -> None: + self._ensure_open() + termios.tcflush(self._fd, termios.TCOFLUSH) + + def _close_fd(self) -> None: + if self._fd >= 0: + try: + if self._exclusive: + fcntl.flock(self._fd, fcntl.LOCK_UN) + except OSError: + pass + try: + os.close(self._fd) + except OSError: + pass + self._fd = -1 + + def _ensure_open(self) -> None: + if self._fd < 0: + raise SerialException("port is not open") + + def _deadline(self) -> float | None: + if self._timeout is None: + return None + if self._timeout == 0: + return time.monotonic() + return time.monotonic() + self._timeout + + def _wait_readable(self, timeout: float | None) -> bool: + """Return True if fd is readable. timeout None blocks; 0 polls.""" + if timeout is not None and timeout < 0: + timeout = 0.0 + try: + ready, _, _ = select.select([self._fd], [], [], timeout) + except InterruptedError: + return False + return bool(ready) + + def _baud_constant(self, baudrate: int) -> int: + try: + return getattr(termios, f"B{baudrate}") + except AttributeError as e: + raise ValueError(f"unsupported baud rate: {baudrate}") from e + + def _configure(self) -> None: + self._ensure_open() + try: + attrs = termios.tcgetattr(self._fd) + except termios.error as e: + raise SerialException(f"could not get port attributes: {e}") from e + + iflag, oflag, cflag, lflag, _ispeed, _ospeed, cc = attrs + + # raw binary 8N1 + iflag = 0 + oflag = 0 + lflag = 0 + cflag |= termios.CLOCAL | termios.CREAD + cflag &= ~termios.CSIZE + cflag |= termios.CS8 + cflag &= ~(termios.PARENB | termios.PARODD | termios.CSTOPB) + + if hasattr(termios, "CRTSCTS"): + if self._rtscts: + cflag |= termios.CRTSCTS + else: + cflag &= ~termios.CRTSCTS + + speed = self._baud_constant(self._baudrate) + cc = list(cc) + # Non-blocking reads are handled via select + O_NONBLOCK; keep VMIN/VTIME at 0. + cc[termios.VMIN] = 0 + cc[termios.VTIME] = 0 + + try: + termios.tcsetattr(self._fd, termios.TCSANOW, [iflag, oflag, cflag, lflag, speed, speed, cc]) + except termios.error as e: + raise SerialException(f"could not configure port: {e}") from e + + # Keep the fd non-blocking so timeout=0 and select work consistently. + flags = fcntl.fcntl(self._fd, fcntl.F_GETFL) + fcntl.fcntl(self._fd, fcntl.F_SETFL, flags | os.O_NONBLOCK) + + def _set_line(self, _bit: int, packed: bytes, enabled: bool) -> None: + request = TIOCMBIS if enabled else TIOCMBIC + fcntl.ioctl(self._fd, request, packed) diff --git a/openpilot/system/qcomgpsd/modemdiag.py b/openpilot/system/qcomgpsd/modemdiag.py index 453084f4c8..313563a314 100644 --- a/openpilot/system/qcomgpsd/modemdiag.py +++ b/openpilot/system/qcomgpsd/modemdiag.py @@ -1,7 +1,8 @@ import select -from serial import Serial from struct import pack, unpack_from, calcsize +from openpilot.common.serial import Serial + def _gen_crc16_reflected_table(poly: int) -> list[int]: # poly is the reflected form (e.g. 0x8408 for CRC-16 poly 0x1021) @@ -25,7 +26,6 @@ def crc16_x25(data: bytes) -> int: crc = _CRC16_X25_TABLE[(crc ^ b) & 0xFF] ^ (crc >> 8) return crc ^ 0xFFFF - class ModemDiag: def __init__(self): self.serial = self.open_serial() diff --git a/openpilot/system/qcomgpsd/qcomgpsd.py b/openpilot/system/qcomgpsd/qcomgpsd.py index e1a7dc39c9..4e52154419 100755 --- a/openpilot/system/qcomgpsd/qcomgpsd.py +++ b/openpilot/system/qcomgpsd/qcomgpsd.py @@ -6,7 +6,6 @@ import signal import itertools import math import time -from serial import Serial import datetime from typing import NoReturn from struct import unpack_from, calcsize, pack @@ -17,6 +16,7 @@ from openpilot.common.gpio import gpio_init, gpio_set from openpilot.common.utils import retry from openpilot.common.time_helpers import system_time_valid from openpilot.common.hardware.tici.pins import GPIO +from openpilot.common.serial import Serial from openpilot.common.swaglog import cloudlog from openpilot.system.qcomgpsd.modemdiag import ModemDiag, DIAG_LOG_F, setup_logs, send_recv from openpilot.system.qcomgpsd.structs import (dict_unpacker, position_report, relist, diff --git a/openpilot/system/ubloxd/pigeond.py b/openpilot/system/ubloxd/pigeond.py index ce9c71db61..9891285465 100755 --- a/openpilot/system/ubloxd/pigeond.py +++ b/openpilot/system/ubloxd/pigeond.py @@ -2,7 +2,6 @@ import sys import time import signal -import serial import struct import requests import urllib.parse @@ -11,6 +10,7 @@ from datetime import datetime, UTC from openpilot.cereal import messaging from openpilot.common.time_helpers import system_time_valid from openpilot.common.params import Params +from openpilot.common.serial import Serial from openpilot.common.swaglog import cloudlog from openpilot.common.hardware import TICI from openpilot.common.gpio import gpio_init, gpio_set @@ -64,7 +64,7 @@ def get_assistnow_messages(token: str) -> list[bytes]: class TTYPigeon: def __init__(self): - self.tty = serial.VTIMESerial(UBLOX_TTY, baudrate=9600, timeout=0) + self.tty = Serial(UBLOX_TTY, baudrate=9600, timeout=0) def send(self, dat: bytes) -> None: self.tty.write(dat) diff --git a/pyproject.toml b/pyproject.toml index f961401686..8430683abb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,7 +11,6 @@ authors = [ dependencies = [ # multiple users "sounddevice", # micd + soundd - "pyserial", # pigeond + qcomgpsd "requests", # many one-off uses "sympy", # rednose + friends "tqdm", # cars (fw_versions.py) on start + many one-off uses diff --git a/uv.lock b/uv.lock index b6478ec464..7c30add6c0 100644 --- a/uv.lock +++ b/uv.lock @@ -991,7 +991,6 @@ dependencies = [ { name = "psutil" }, { name = "pycapnp" }, { name = "pyjwt" }, - { name = "pyserial" }, { name = "pyzmq" }, { name = "qrcode" }, { name = "requests" }, @@ -1078,7 +1077,6 @@ requires-dist = [ { name = "psutil" }, { name = "pycapnp", specifier = "==2.1.0" }, { name = "pyjwt" }, - { name = "pyserial" }, { name = "pytest", marker = "extra == 'testing'" }, { name = "pytest-cpp", marker = "extra == 'testing'" }, { name = "pytest-mock", marker = "extra == 'testing'" }, @@ -1378,15 +1376,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl", hash = "sha256:850ba148bd908d7e2411587e247a1e4f0327839c40e2e5e6d05a007ecc69911d", size = 122781, upload-time = "2026-01-21T03:57:55.912Z" }, ] -[[package]] -name = "pyserial" -version = "3.5" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/1e/7d/ae3f0a63f41e4d2f6cb66a5b57197850f919f59e558159a4dd3a818f5082/pyserial-3.5.tar.gz", hash = "sha256:3c77e014170dfffbd816e6ffc205e9842efb10be9f58ec16d3e8675b4925cddb", size = 159125, upload-time = "2020-11-23T03:59:15.045Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/07/bc/587a445451b253b285629263eb51c2d8e9bcea4fc97826266d186f96f558/pyserial-3.5-py2.py3-none-any.whl", hash = "sha256:c4451db6ba391ca6ca299fb3ec7bae67a5c55dde170964c7a14ceefec02f2cf0", size = 90585, upload-time = "2020-11-23T03:59:13.41Z" }, -] - [[package]] name = "pytest" version = "9.1.1" From b827c0f55e65f8c3ffeefd9c0994dde054656982 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Wed, 8 Jul 2026 21:11:39 -0700 Subject: [PATCH 121/151] try removing submodule symlinks (#38310) --- .gitignore | 7 +++++ SConstruct | 29 +++++++++++++++++--- launch_chffrplus.sh | 8 ++++++ msgq | 1 - opendbc | 1 - openpilot/selfdrive/test/setup_device_ci.sh | 8 ++++++ openpilot/tools/cabana/SConscript | 2 +- openpilot/tools/jotpluggler/layout.cc | 2 +- openpilot/tools/jotpluggler/sketch_layout.cc | 4 +-- rednose | 1 - teleoprtc | 1 - tinygrad | 1 - 12 files changed, 52 insertions(+), 13 deletions(-) delete mode 120000 msgq delete mode 120000 opendbc delete mode 120000 rednose delete mode 120000 teleoprtc delete mode 120000 tinygrad diff --git a/.gitignore b/.gitignore index 6581b90e7c..5c99567581 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,13 @@ a.out .cache/ bin/ +# created at launch for TICI PYTHONPATH (PC uses editable installs via pyproject.toml) +/msgq +/opendbc +/rednose +/teleoprtc +/tinygrad + *.mp4 *.dylib *.DSYM diff --git a/SConstruct b/SConstruct index 7e102add90..548553da91 100644 --- a/SConstruct +++ b/SConstruct @@ -27,6 +27,24 @@ AddOption('--minimal', default=(not TICI and not release), help='the minimum build to run openpilot. no tests, tools, etc.') +# Package symlinks are no longer tracked in git (created at launch on device). +# Create them here so PYTHONPATH-based imports find in-tree packages and +# Cython extensions during the build (especially release builds). +_repo_root = Dir('#').abspath +for _pkg, _target in ( + ('msgq', 'msgq_repo/msgq'), + ('opendbc', 'opendbc_repo/opendbc'), + ('rednose', 'rednose_repo/rednose'), + ('teleoprtc', 'teleoprtc_repo/teleoprtc'), + ('tinygrad', 'tinygrad_repo/tinygrad'), +): + _link = os.path.join(_repo_root, _pkg) + if os.path.lexists(_link): + if os.path.islink(_link) and os.readlink(_link) == _target: + continue + os.unlink(_link) + os.symlink(_target, _link) + # Detect platform arch = subprocess.check_output(["uname", "-m"], encoding='utf8').rstrip() if platform.system() == "Darwin": @@ -128,7 +146,10 @@ env = Environment( CXXFLAGS=["-std=c++1z"], CPPPATH=[ "#openpilot", - "#msgq", + "#msgq_repo", # #include "msgq/..." + "#opendbc_repo", # #include "opendbc/..." + "#rednose_repo", # #include "rednose/..." + "#rednose_repo/rednose", # #include "logger/..." (rednose package root) "#openpilot/cereal/gen/cpp", acados_include_dirs, [x.INCLUDE_DIR for x in pkgs], @@ -138,13 +159,13 @@ env = Environment( "#openpilot/common", "#msgq_repo", "#openpilot/selfdrive/pandad", - "#rednose/helpers", + "#rednose_repo/rednose/helpers", [x.LIB_DIR for x in pkgs], ], RPATH=[ffmpeg.LIB_DIR] if ffmpeg_shared else [], CYTHONCFILESUFFIX=".cpp", COMPILATIONDB_USE_ABSPATH=True, - REDNOSE_ROOT="#", + REDNOSE_ROOT="#rednose_repo", tools=["default", "cython", "compilation_db", "rednose_filter"], toolpath=["#site_scons/site_tools", "#rednose_repo/site_scons/site_tools"], ) @@ -249,7 +270,7 @@ Export('messaging') SConscript(['panda/SConscript']) # Build rednose library -SConscript(['rednose/SConscript']) +SConscript(['rednose_repo/rednose/SConscript']) # Build system services SConscript([ diff --git a/launch_chffrplus.sh b/launch_chffrplus.sh index 17a765e076..4f767f3b19 100755 --- a/launch_chffrplus.sh +++ b/launch_chffrplus.sh @@ -70,6 +70,14 @@ function launch { ln -sfn $(pwd) /data/pythonpath export PYTHONPATH="$PWD" + # submodule package symlinks for PYTHONPATH imports on device. + # on PC these come from editable installs via pyproject.toml / uv. + ln -sfn msgq_repo/msgq msgq + ln -sfn opendbc_repo/opendbc opendbc + ln -sfn rednose_repo/rednose rednose + ln -sfn teleoprtc_repo/teleoprtc teleoprtc + ln -sfn tinygrad_repo/tinygrad tinygrad + # hardware specific init if [ -f /AGNOS ]; then agnos_init diff --git a/msgq b/msgq deleted file mode 120000 index df09146f62..0000000000 --- a/msgq +++ /dev/null @@ -1 +0,0 @@ -msgq_repo/msgq \ No newline at end of file diff --git a/opendbc b/opendbc deleted file mode 120000 index 7cd9a5bd1e..0000000000 --- a/opendbc +++ /dev/null @@ -1 +0,0 @@ -opendbc_repo/opendbc \ No newline at end of file diff --git a/openpilot/selfdrive/test/setup_device_ci.sh b/openpilot/selfdrive/test/setup_device_ci.sh index 3fe353e72c..d458e047a5 100755 --- a/openpilot/selfdrive/test/setup_device_ci.sh +++ b/openpilot/selfdrive/test/setup_device_ci.sh @@ -124,4 +124,12 @@ else safe_checkout fi +# submodule package symlinks for PYTHONPATH imports on device (same as launch_chffrplus.sh) +cd $TEST_DIR +ln -sfn msgq_repo/msgq msgq +ln -sfn opendbc_repo/opendbc opendbc +ln -sfn rednose_repo/rednose rednose +ln -sfn teleoprtc_repo/teleoprtc teleoprtc +ln -sfn tinygrad_repo/tinygrad tinygrad + echo "$TEST_DIR synced with $GIT_COMMIT, t=$SECONDS" diff --git a/openpilot/tools/cabana/SConscript b/openpilot/tools/cabana/SConscript index ec94fec266..26c20ddba1 100644 --- a/openpilot/tools/cabana/SConscript +++ b/openpilot/tools/cabana/SConscript @@ -76,7 +76,7 @@ cabana_env['CPPPATH'] += [libusb.INCLUDE_DIR] cabana_env['LIBPATH'] += [libusb.LIB_DIR] cabana_libs = [cereal, messaging, visionipc, replay_lib] + ffmpeg_libs + ['bz2', 'zstd', 'usb-1.0'] + base_libs -opendbc_path = '-DOPENDBC_FILE_PATH=\'"%s"\'' % (cabana_env.Dir("../../../opendbc/dbc").abspath) +opendbc_path = '-DOPENDBC_FILE_PATH=\'"%s"\'' % (cabana_env.Dir("../../../opendbc_repo/opendbc/dbc").abspath) cabana_env['CXXFLAGS'] += [opendbc_path] def write_assets_qrc(target, source, env): diff --git a/openpilot/tools/jotpluggler/layout.cc b/openpilot/tools/jotpluggler/layout.cc index dc7109808a..6bc3a6168a 100644 --- a/openpilot/tools/jotpluggler/layout.cc +++ b/openpilot/tools/jotpluggler/layout.cc @@ -276,7 +276,7 @@ std::string default_dbc_template() { DbcEditorSource resolve_dbc_editor_source(const std::string &dbc_name) { const fs::path generated_dbc_dir = repo_root() / "openpilot" / "tools" / "jotpluggler" / "generated_dbcs"; const std::array candidates = {{ - {.path = repo_root() / "opendbc" / "dbc" / (dbc_name + ".dbc"), .kind = DbcEditorState::SourceKind::Opendbc}, + {.path = repo_root() / "opendbc_repo" / "opendbc" / "dbc" / (dbc_name + ".dbc"), .kind = DbcEditorState::SourceKind::Opendbc}, {.path = generated_dbc_dir / (dbc_name + ".dbc"), .kind = DbcEditorState::SourceKind::Generated}, }}; for (const DbcEditorSource &candidate : candidates) { diff --git a/openpilot/tools/jotpluggler/sketch_layout.cc b/openpilot/tools/jotpluggler/sketch_layout.cc index fcc4b183d0..ee307653f6 100644 --- a/openpilot/tools/jotpluggler/sketch_layout.cc +++ b/openpilot/tools/jotpluggler/sketch_layout.cc @@ -385,7 +385,7 @@ std::string detect_dbc_for_fingerprint(std::string_view car_fingerprint) { std::vector available_dbc_names_impl() { std::set names; for (const fs::path &dbc_dir : { - repo_root() / "opendbc" / "dbc", + repo_root() / "opendbc_repo" / "opendbc" / "dbc", repo_root() / "openpilot" / "tools" / "jotpluggler" / "generated_dbcs", }) { if (fs::exists(dbc_dir) && fs::is_directory(dbc_dir)) { @@ -407,7 +407,7 @@ std::vector available_dbc_names_impl() { fs::path resolve_dbc_path(const std::string &dbc_name) { for (const fs::path &candidate : { - repo_root() / "opendbc" / "dbc" / (dbc_name + ".dbc"), + repo_root() / "opendbc_repo" / "opendbc" / "dbc" / (dbc_name + ".dbc"), repo_root() / "openpilot" / "tools" / "jotpluggler" / "generated_dbcs" / (dbc_name + ".dbc"), }) { if (fs::exists(candidate)) return candidate; diff --git a/rednose b/rednose deleted file mode 120000 index 674cfec35f..0000000000 --- a/rednose +++ /dev/null @@ -1 +0,0 @@ -rednose_repo/rednose \ No newline at end of file diff --git a/teleoprtc b/teleoprtc deleted file mode 120000 index 3d3dbc8dea..0000000000 --- a/teleoprtc +++ /dev/null @@ -1 +0,0 @@ -teleoprtc_repo/teleoprtc \ No newline at end of file diff --git a/tinygrad b/tinygrad deleted file mode 120000 index cb003823c6..0000000000 --- a/tinygrad +++ /dev/null @@ -1 +0,0 @@ -tinygrad_repo/tinygrad \ No newline at end of file From f283f6703c08807de326707addc6f77098064e3f Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Wed, 8 Jul 2026 21:12:12 -0700 Subject: [PATCH 122/151] Revert "try removing submodule symlinks (#38310)" This reverts commit b827c0f55e65f8c3ffeefd9c0994dde054656982. --- .gitignore | 7 ----- SConstruct | 29 +++----------------- launch_chffrplus.sh | 8 ------ msgq | 1 + opendbc | 1 + openpilot/selfdrive/test/setup_device_ci.sh | 8 ------ openpilot/tools/cabana/SConscript | 2 +- openpilot/tools/jotpluggler/layout.cc | 2 +- openpilot/tools/jotpluggler/sketch_layout.cc | 4 +-- rednose | 1 + teleoprtc | 1 + tinygrad | 1 + 12 files changed, 13 insertions(+), 52 deletions(-) create mode 120000 msgq create mode 120000 opendbc create mode 120000 rednose create mode 120000 teleoprtc create mode 120000 tinygrad diff --git a/.gitignore b/.gitignore index 5c99567581..6581b90e7c 100644 --- a/.gitignore +++ b/.gitignore @@ -15,13 +15,6 @@ a.out .cache/ bin/ -# created at launch for TICI PYTHONPATH (PC uses editable installs via pyproject.toml) -/msgq -/opendbc -/rednose -/teleoprtc -/tinygrad - *.mp4 *.dylib *.DSYM diff --git a/SConstruct b/SConstruct index 548553da91..7e102add90 100644 --- a/SConstruct +++ b/SConstruct @@ -27,24 +27,6 @@ AddOption('--minimal', default=(not TICI and not release), help='the minimum build to run openpilot. no tests, tools, etc.') -# Package symlinks are no longer tracked in git (created at launch on device). -# Create them here so PYTHONPATH-based imports find in-tree packages and -# Cython extensions during the build (especially release builds). -_repo_root = Dir('#').abspath -for _pkg, _target in ( - ('msgq', 'msgq_repo/msgq'), - ('opendbc', 'opendbc_repo/opendbc'), - ('rednose', 'rednose_repo/rednose'), - ('teleoprtc', 'teleoprtc_repo/teleoprtc'), - ('tinygrad', 'tinygrad_repo/tinygrad'), -): - _link = os.path.join(_repo_root, _pkg) - if os.path.lexists(_link): - if os.path.islink(_link) and os.readlink(_link) == _target: - continue - os.unlink(_link) - os.symlink(_target, _link) - # Detect platform arch = subprocess.check_output(["uname", "-m"], encoding='utf8').rstrip() if platform.system() == "Darwin": @@ -146,10 +128,7 @@ env = Environment( CXXFLAGS=["-std=c++1z"], CPPPATH=[ "#openpilot", - "#msgq_repo", # #include "msgq/..." - "#opendbc_repo", # #include "opendbc/..." - "#rednose_repo", # #include "rednose/..." - "#rednose_repo/rednose", # #include "logger/..." (rednose package root) + "#msgq", "#openpilot/cereal/gen/cpp", acados_include_dirs, [x.INCLUDE_DIR for x in pkgs], @@ -159,13 +138,13 @@ env = Environment( "#openpilot/common", "#msgq_repo", "#openpilot/selfdrive/pandad", - "#rednose_repo/rednose/helpers", + "#rednose/helpers", [x.LIB_DIR for x in pkgs], ], RPATH=[ffmpeg.LIB_DIR] if ffmpeg_shared else [], CYTHONCFILESUFFIX=".cpp", COMPILATIONDB_USE_ABSPATH=True, - REDNOSE_ROOT="#rednose_repo", + REDNOSE_ROOT="#", tools=["default", "cython", "compilation_db", "rednose_filter"], toolpath=["#site_scons/site_tools", "#rednose_repo/site_scons/site_tools"], ) @@ -270,7 +249,7 @@ Export('messaging') SConscript(['panda/SConscript']) # Build rednose library -SConscript(['rednose_repo/rednose/SConscript']) +SConscript(['rednose/SConscript']) # Build system services SConscript([ diff --git a/launch_chffrplus.sh b/launch_chffrplus.sh index 4f767f3b19..17a765e076 100755 --- a/launch_chffrplus.sh +++ b/launch_chffrplus.sh @@ -70,14 +70,6 @@ function launch { ln -sfn $(pwd) /data/pythonpath export PYTHONPATH="$PWD" - # submodule package symlinks for PYTHONPATH imports on device. - # on PC these come from editable installs via pyproject.toml / uv. - ln -sfn msgq_repo/msgq msgq - ln -sfn opendbc_repo/opendbc opendbc - ln -sfn rednose_repo/rednose rednose - ln -sfn teleoprtc_repo/teleoprtc teleoprtc - ln -sfn tinygrad_repo/tinygrad tinygrad - # hardware specific init if [ -f /AGNOS ]; then agnos_init diff --git a/msgq b/msgq new file mode 120000 index 0000000000..df09146f62 --- /dev/null +++ b/msgq @@ -0,0 +1 @@ +msgq_repo/msgq \ No newline at end of file diff --git a/opendbc b/opendbc new file mode 120000 index 0000000000..7cd9a5bd1e --- /dev/null +++ b/opendbc @@ -0,0 +1 @@ +opendbc_repo/opendbc \ No newline at end of file diff --git a/openpilot/selfdrive/test/setup_device_ci.sh b/openpilot/selfdrive/test/setup_device_ci.sh index d458e047a5..3fe353e72c 100755 --- a/openpilot/selfdrive/test/setup_device_ci.sh +++ b/openpilot/selfdrive/test/setup_device_ci.sh @@ -124,12 +124,4 @@ else safe_checkout fi -# submodule package symlinks for PYTHONPATH imports on device (same as launch_chffrplus.sh) -cd $TEST_DIR -ln -sfn msgq_repo/msgq msgq -ln -sfn opendbc_repo/opendbc opendbc -ln -sfn rednose_repo/rednose rednose -ln -sfn teleoprtc_repo/teleoprtc teleoprtc -ln -sfn tinygrad_repo/tinygrad tinygrad - echo "$TEST_DIR synced with $GIT_COMMIT, t=$SECONDS" diff --git a/openpilot/tools/cabana/SConscript b/openpilot/tools/cabana/SConscript index 26c20ddba1..ec94fec266 100644 --- a/openpilot/tools/cabana/SConscript +++ b/openpilot/tools/cabana/SConscript @@ -76,7 +76,7 @@ cabana_env['CPPPATH'] += [libusb.INCLUDE_DIR] cabana_env['LIBPATH'] += [libusb.LIB_DIR] cabana_libs = [cereal, messaging, visionipc, replay_lib] + ffmpeg_libs + ['bz2', 'zstd', 'usb-1.0'] + base_libs -opendbc_path = '-DOPENDBC_FILE_PATH=\'"%s"\'' % (cabana_env.Dir("../../../opendbc_repo/opendbc/dbc").abspath) +opendbc_path = '-DOPENDBC_FILE_PATH=\'"%s"\'' % (cabana_env.Dir("../../../opendbc/dbc").abspath) cabana_env['CXXFLAGS'] += [opendbc_path] def write_assets_qrc(target, source, env): diff --git a/openpilot/tools/jotpluggler/layout.cc b/openpilot/tools/jotpluggler/layout.cc index 6bc3a6168a..dc7109808a 100644 --- a/openpilot/tools/jotpluggler/layout.cc +++ b/openpilot/tools/jotpluggler/layout.cc @@ -276,7 +276,7 @@ std::string default_dbc_template() { DbcEditorSource resolve_dbc_editor_source(const std::string &dbc_name) { const fs::path generated_dbc_dir = repo_root() / "openpilot" / "tools" / "jotpluggler" / "generated_dbcs"; const std::array candidates = {{ - {.path = repo_root() / "opendbc_repo" / "opendbc" / "dbc" / (dbc_name + ".dbc"), .kind = DbcEditorState::SourceKind::Opendbc}, + {.path = repo_root() / "opendbc" / "dbc" / (dbc_name + ".dbc"), .kind = DbcEditorState::SourceKind::Opendbc}, {.path = generated_dbc_dir / (dbc_name + ".dbc"), .kind = DbcEditorState::SourceKind::Generated}, }}; for (const DbcEditorSource &candidate : candidates) { diff --git a/openpilot/tools/jotpluggler/sketch_layout.cc b/openpilot/tools/jotpluggler/sketch_layout.cc index ee307653f6..fcc4b183d0 100644 --- a/openpilot/tools/jotpluggler/sketch_layout.cc +++ b/openpilot/tools/jotpluggler/sketch_layout.cc @@ -385,7 +385,7 @@ std::string detect_dbc_for_fingerprint(std::string_view car_fingerprint) { std::vector available_dbc_names_impl() { std::set names; for (const fs::path &dbc_dir : { - repo_root() / "opendbc_repo" / "opendbc" / "dbc", + repo_root() / "opendbc" / "dbc", repo_root() / "openpilot" / "tools" / "jotpluggler" / "generated_dbcs", }) { if (fs::exists(dbc_dir) && fs::is_directory(dbc_dir)) { @@ -407,7 +407,7 @@ std::vector available_dbc_names_impl() { fs::path resolve_dbc_path(const std::string &dbc_name) { for (const fs::path &candidate : { - repo_root() / "opendbc_repo" / "opendbc" / "dbc" / (dbc_name + ".dbc"), + repo_root() / "opendbc" / "dbc" / (dbc_name + ".dbc"), repo_root() / "openpilot" / "tools" / "jotpluggler" / "generated_dbcs" / (dbc_name + ".dbc"), }) { if (fs::exists(candidate)) return candidate; diff --git a/rednose b/rednose new file mode 120000 index 0000000000..674cfec35f --- /dev/null +++ b/rednose @@ -0,0 +1 @@ +rednose_repo/rednose \ No newline at end of file diff --git a/teleoprtc b/teleoprtc new file mode 120000 index 0000000000..3d3dbc8dea --- /dev/null +++ b/teleoprtc @@ -0,0 +1 @@ +teleoprtc_repo/teleoprtc \ No newline at end of file diff --git a/tinygrad b/tinygrad new file mode 120000 index 0000000000..cb003823c6 --- /dev/null +++ b/tinygrad @@ -0,0 +1 @@ +tinygrad_repo/tinygrad \ No newline at end of file From 1478d0c4763977d055f84246dd75c132a2a5ca9d Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Wed, 8 Jul 2026 21:25:43 -0700 Subject: [PATCH 123/151] Fix diff report artifact download (#38313) --- .github/workflows/diff_report.yaml | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/.github/workflows/diff_report.yaml b/.github/workflows/diff_report.yaml index 5ad7746fda..0f706ea2ed 100644 --- a/.github/workflows/diff_report.yaml +++ b/.github/workflows/diff_report.yaml @@ -24,17 +24,29 @@ jobs: repo-token: ${{ secrets.GITHUB_TOKEN }} allowed-conclusions: success,failure wait-interval: 20 + - name: Get tests run ID + if: steps.wait.outcome == 'success' + id: tests-run + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + run_id=$(gh api \ + "repos/${{ github.repository }}/actions/workflows/tests.yaml/runs?event=pull_request&head_sha=${{ github.event.pull_request.head.sha }}&per_page=1" \ + --jq '.workflow_runs[0].id // empty') + if [ -z "$run_id" ]; then + echo "No tests.yaml run found for ${{ github.event.pull_request.head.sha }}" >&2 + exit 1 + fi + echo "run-id=$run_id" >> "$GITHUB_OUTPUT" - name: Download diff if: steps.wait.outcome == 'success' - uses: dawidd6/action-download-artifact@b6e2e70617bc3265edd6dab6c906732b2f1ae151 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c with: - github_token: ${{ secrets.GITHUB_TOKEN }} - workflow: tests.yaml - workflow_conclusion: '' - pr: ${{ github.event.number }} + github-token: ${{ secrets.GITHUB_TOKEN }} + repository: ${{ github.repository }} + run-id: ${{ steps.tests-run.outputs.run-id }} name: diff_report_${{ github.event.number }} path: . - allow_forks: true - name: Comment on PR if: steps.wait.outcome == 'success' uses: thollander/actions-comment-pull-request@24bffb9b452ba05a4f3f77933840a6a841d1b32b From 39117a5879a3450a928555ab89c062ca513e2995 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Wed, 8 Jul 2026 21:30:17 -0700 Subject: [PATCH 124/151] remove submodule symlinks (#38312) --- .gitignore | 7 +++++ SConstruct | 28 ++++++++++++++++---- launch_chffrplus.sh | 8 ++++++ msgq | 1 - opendbc | 1 - openpilot/selfdrive/test/setup_device_ci.sh | 8 ++++++ openpilot/tools/cabana/SConscript | 2 +- openpilot/tools/jotpluggler/layout.cc | 2 +- openpilot/tools/jotpluggler/sketch_layout.cc | 4 +-- rednose | 1 - teleoprtc | 1 - tinygrad | 1 - 12 files changed, 50 insertions(+), 14 deletions(-) delete mode 120000 msgq delete mode 120000 opendbc delete mode 120000 rednose delete mode 120000 teleoprtc delete mode 120000 tinygrad diff --git a/.gitignore b/.gitignore index 6581b90e7c..5c99567581 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,13 @@ a.out .cache/ bin/ +# created at launch for TICI PYTHONPATH (PC uses editable installs via pyproject.toml) +/msgq +/opendbc +/rednose +/teleoprtc +/tinygrad + *.mp4 *.dylib *.DSYM diff --git a/SConstruct b/SConstruct index 7e102add90..3ce34a86f7 100644 --- a/SConstruct +++ b/SConstruct @@ -27,6 +27,21 @@ AddOption('--minimal', default=(not TICI and not release), help='the minimum build to run openpilot. no tests, tools, etc.') +submodule_python_paths = [ + Dir("#").abspath, + Dir("#msgq_repo").abspath, + Dir("#opendbc_repo").abspath, + Dir("#rednose_repo").abspath, + Dir("#teleoprtc_repo").abspath, + Dir("#tinygrad_repo").abspath, +] +for p in reversed(submodule_python_paths): + if p not in sys.path: + sys.path.insert(0, p) + +if external_pythonpath := os.environ.get("PYTHONPATH"): + submodule_python_paths += [p for p in external_pythonpath.split(os.pathsep) if p and p not in submodule_python_paths] + # Detect platform arch = subprocess.check_output(["uname", "-m"], encoding='utf8').rstrip() if platform.system() == "Darwin": @@ -106,7 +121,7 @@ def _libflags(target, source, env, for_signature): env = Environment( ENV={ "PATH": os.environ['PATH'], - "PYTHONPATH": Dir("#").abspath, + "PYTHONPATH": os.pathsep.join(submodule_python_paths), "ACADOS_SOURCE_DIR": acados.DIR, "ACADOS_PYTHON_INTERFACE_PATH": acados.TEMPLATE_DIR, "TERA_PATH": acados.TERA_PATH @@ -128,7 +143,10 @@ env = Environment( CXXFLAGS=["-std=c++1z"], CPPPATH=[ "#openpilot", - "#msgq", + "#msgq_repo", # #include "msgq/..." + "#opendbc_repo", # #include "opendbc/..." + "#rednose_repo", # #include "rednose/..." + "#rednose_repo/rednose", # #include "logger/..." (rednose package root) "#openpilot/cereal/gen/cpp", acados_include_dirs, [x.INCLUDE_DIR for x in pkgs], @@ -138,13 +156,13 @@ env = Environment( "#openpilot/common", "#msgq_repo", "#openpilot/selfdrive/pandad", - "#rednose/helpers", + "#rednose_repo/rednose/helpers", [x.LIB_DIR for x in pkgs], ], RPATH=[ffmpeg.LIB_DIR] if ffmpeg_shared else [], CYTHONCFILESUFFIX=".cpp", COMPILATIONDB_USE_ABSPATH=True, - REDNOSE_ROOT="#", + REDNOSE_ROOT="#rednose_repo", tools=["default", "cython", "compilation_db", "rednose_filter"], toolpath=["#site_scons/site_tools", "#rednose_repo/site_scons/site_tools"], ) @@ -249,7 +267,7 @@ Export('messaging') SConscript(['panda/SConscript']) # Build rednose library -SConscript(['rednose/SConscript']) +SConscript(['rednose_repo/rednose/SConscript']) # Build system services SConscript([ diff --git a/launch_chffrplus.sh b/launch_chffrplus.sh index 17a765e076..4f767f3b19 100755 --- a/launch_chffrplus.sh +++ b/launch_chffrplus.sh @@ -70,6 +70,14 @@ function launch { ln -sfn $(pwd) /data/pythonpath export PYTHONPATH="$PWD" + # submodule package symlinks for PYTHONPATH imports on device. + # on PC these come from editable installs via pyproject.toml / uv. + ln -sfn msgq_repo/msgq msgq + ln -sfn opendbc_repo/opendbc opendbc + ln -sfn rednose_repo/rednose rednose + ln -sfn teleoprtc_repo/teleoprtc teleoprtc + ln -sfn tinygrad_repo/tinygrad tinygrad + # hardware specific init if [ -f /AGNOS ]; then agnos_init diff --git a/msgq b/msgq deleted file mode 120000 index df09146f62..0000000000 --- a/msgq +++ /dev/null @@ -1 +0,0 @@ -msgq_repo/msgq \ No newline at end of file diff --git a/opendbc b/opendbc deleted file mode 120000 index 7cd9a5bd1e..0000000000 --- a/opendbc +++ /dev/null @@ -1 +0,0 @@ -opendbc_repo/opendbc \ No newline at end of file diff --git a/openpilot/selfdrive/test/setup_device_ci.sh b/openpilot/selfdrive/test/setup_device_ci.sh index 3fe353e72c..d458e047a5 100755 --- a/openpilot/selfdrive/test/setup_device_ci.sh +++ b/openpilot/selfdrive/test/setup_device_ci.sh @@ -124,4 +124,12 @@ else safe_checkout fi +# submodule package symlinks for PYTHONPATH imports on device (same as launch_chffrplus.sh) +cd $TEST_DIR +ln -sfn msgq_repo/msgq msgq +ln -sfn opendbc_repo/opendbc opendbc +ln -sfn rednose_repo/rednose rednose +ln -sfn teleoprtc_repo/teleoprtc teleoprtc +ln -sfn tinygrad_repo/tinygrad tinygrad + echo "$TEST_DIR synced with $GIT_COMMIT, t=$SECONDS" diff --git a/openpilot/tools/cabana/SConscript b/openpilot/tools/cabana/SConscript index ec94fec266..26c20ddba1 100644 --- a/openpilot/tools/cabana/SConscript +++ b/openpilot/tools/cabana/SConscript @@ -76,7 +76,7 @@ cabana_env['CPPPATH'] += [libusb.INCLUDE_DIR] cabana_env['LIBPATH'] += [libusb.LIB_DIR] cabana_libs = [cereal, messaging, visionipc, replay_lib] + ffmpeg_libs + ['bz2', 'zstd', 'usb-1.0'] + base_libs -opendbc_path = '-DOPENDBC_FILE_PATH=\'"%s"\'' % (cabana_env.Dir("../../../opendbc/dbc").abspath) +opendbc_path = '-DOPENDBC_FILE_PATH=\'"%s"\'' % (cabana_env.Dir("../../../opendbc_repo/opendbc/dbc").abspath) cabana_env['CXXFLAGS'] += [opendbc_path] def write_assets_qrc(target, source, env): diff --git a/openpilot/tools/jotpluggler/layout.cc b/openpilot/tools/jotpluggler/layout.cc index dc7109808a..6bc3a6168a 100644 --- a/openpilot/tools/jotpluggler/layout.cc +++ b/openpilot/tools/jotpluggler/layout.cc @@ -276,7 +276,7 @@ std::string default_dbc_template() { DbcEditorSource resolve_dbc_editor_source(const std::string &dbc_name) { const fs::path generated_dbc_dir = repo_root() / "openpilot" / "tools" / "jotpluggler" / "generated_dbcs"; const std::array candidates = {{ - {.path = repo_root() / "opendbc" / "dbc" / (dbc_name + ".dbc"), .kind = DbcEditorState::SourceKind::Opendbc}, + {.path = repo_root() / "opendbc_repo" / "opendbc" / "dbc" / (dbc_name + ".dbc"), .kind = DbcEditorState::SourceKind::Opendbc}, {.path = generated_dbc_dir / (dbc_name + ".dbc"), .kind = DbcEditorState::SourceKind::Generated}, }}; for (const DbcEditorSource &candidate : candidates) { diff --git a/openpilot/tools/jotpluggler/sketch_layout.cc b/openpilot/tools/jotpluggler/sketch_layout.cc index fcc4b183d0..ee307653f6 100644 --- a/openpilot/tools/jotpluggler/sketch_layout.cc +++ b/openpilot/tools/jotpluggler/sketch_layout.cc @@ -385,7 +385,7 @@ std::string detect_dbc_for_fingerprint(std::string_view car_fingerprint) { std::vector available_dbc_names_impl() { std::set names; for (const fs::path &dbc_dir : { - repo_root() / "opendbc" / "dbc", + repo_root() / "opendbc_repo" / "opendbc" / "dbc", repo_root() / "openpilot" / "tools" / "jotpluggler" / "generated_dbcs", }) { if (fs::exists(dbc_dir) && fs::is_directory(dbc_dir)) { @@ -407,7 +407,7 @@ std::vector available_dbc_names_impl() { fs::path resolve_dbc_path(const std::string &dbc_name) { for (const fs::path &candidate : { - repo_root() / "opendbc" / "dbc" / (dbc_name + ".dbc"), + repo_root() / "opendbc_repo" / "opendbc" / "dbc" / (dbc_name + ".dbc"), repo_root() / "openpilot" / "tools" / "jotpluggler" / "generated_dbcs" / (dbc_name + ".dbc"), }) { if (fs::exists(candidate)) return candidate; diff --git a/rednose b/rednose deleted file mode 120000 index 674cfec35f..0000000000 --- a/rednose +++ /dev/null @@ -1 +0,0 @@ -rednose_repo/rednose \ No newline at end of file diff --git a/teleoprtc b/teleoprtc deleted file mode 120000 index 3d3dbc8dea..0000000000 --- a/teleoprtc +++ /dev/null @@ -1 +0,0 @@ -teleoprtc_repo/teleoprtc \ No newline at end of file diff --git a/tinygrad b/tinygrad deleted file mode 120000 index cb003823c6..0000000000 --- a/tinygrad +++ /dev/null @@ -1 +0,0 @@ -tinygrad_repo/tinygrad \ No newline at end of file From 6392096de58290d80a03dcbfbfe8bba5742ad532 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Thu, 9 Jul 2026 09:31:34 -0700 Subject: [PATCH 125/151] op setup: init submodules before uv sync (#38314) --- tools/op.sh | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/tools/op.sh b/tools/op.sh index d8de248c24..cde29efd8c 100755 --- a/tools/op.sh +++ b/tools/op.sh @@ -199,6 +199,17 @@ function op_setup() { op_check_openpilot_dir op_check_os + # Submodules must be present before uv sync: pyproject path sources + # (pandacan, opendbc, msgq, ...) live in the submodule checkouts. + echo "Getting git submodules..." + st="$(date +%s)" + if ! retry 3 git submodule update --jobs 4 --init --recursive; then + echo -e " ↳ [${RED}✗${NC}] Getting git submodules failed!" + return 1 + fi + et="$(date +%s)" + echo -e " ↳ [${GREEN}✔${NC}] Submodules installed successfully in $((et - st)) seconds." + echo "Installing dependencies..." st="$(date +%s)" SETUP_SCRIPT="tools/setup_dependencies.sh" @@ -211,15 +222,6 @@ function op_setup() { op_activate_venv - echo "Getting git submodules..." - st="$(date +%s)" - if ! retry 3 git submodule update --jobs 4 --init --recursive; then - echo -e " ↳ [${RED}✗${NC}] Getting git submodules failed!" - return 1 - fi - et="$(date +%s)" - echo -e " ↳ [${GREEN}✔${NC}] Submodules installed successfully in $((et - st)) seconds." - echo "Pulling git lfs files..." st="$(date +%s)" if ! retry 3 git lfs pull; then From ee11c24cf4ff6c0e8f8fdf2d40b6689680ed0053 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Thu, 9 Jul 2026 12:26:56 -0700 Subject: [PATCH 126/151] ci: test op setup with empty submodules (#38316) * ci: test op setup with empty submodules * ci: init submodules via op setup instead of checkout * ci: keep submodules for build release * ci: drop explicit submodules: false * ci: remove checkout comment --- .github/workflows/tests.yaml | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index d732dd83dc..08206ee1e2 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -66,8 +66,6 @@ jobs: runs-on: ${{ ((github.repository == 'commaai/openpilot') && ((github.event_name != 'pull_request') || (github.event.pull_request.head.repo.full_name == 'commaai/openpilot'))) && 'namespace-profile-macos-8x14' || 'macos-latest' }} steps: - uses: actions/checkout@v7 - with: - submodules: true - name: Remove Homebrew from environment run: | FILTERED=$(echo "$PATH" | tr ':' '\n' | grep -v '/opt/homebrew' | tr '\n' ':') @@ -86,8 +84,6 @@ jobs: || fromJSON('["ubuntu-24.04"]') }} steps: - uses: actions/checkout@v7 - with: - submodules: true - run: ./tools/op.sh setup - name: Static analysis timeout-minutes: 1 @@ -103,8 +99,6 @@ jobs: || fromJSON('["ubuntu-24.04"]') }} steps: - uses: actions/checkout@v7 - with: - submodules: true - run: ./tools/op.sh setup - name: Build openpilot run: scons @@ -127,8 +121,6 @@ jobs: || fromJSON('["ubuntu-24.04"]') }} steps: - uses: actions/checkout@v7 - with: - submodules: true - run: ./tools/op.sh setup - name: Build openpilot run: scons @@ -200,8 +192,6 @@ jobs: if: false # FIXME: Started to timeout recently steps: - uses: actions/checkout@v7 - with: - submodules: true - run: ./tools/op.sh setup - name: Build openpilot run: scons @@ -222,8 +212,6 @@ jobs: || fromJSON('["ubuntu-24.04"]') }} steps: - uses: actions/checkout@v7 - with: - submodules: true - run: ./tools/op.sh setup - name: Build openpilot run: scons From 60924556f60125a234f6013527d13103bda8df00 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Thu, 9 Jul 2026 16:55:49 -0700 Subject: [PATCH 127/151] athena: minimal json-rpc implementation (#38318) * athena: minimal json-rpc implementation * lil more --- openpilot/system/athena/athenad.py | 20 ++--- openpilot/system/athena/rpc.py | 116 +++++++++++++++++++++++++++++ pyproject.toml | 1 - uv.lock | 11 --- 4 files changed, 122 insertions(+), 26 deletions(-) create mode 100644 openpilot/system/athena/rpc.py diff --git a/openpilot/system/athena/athenad.py b/openpilot/system/athena/athenad.py index 3949a7b201..12715e1427 100755 --- a/openpilot/system/athena/athenad.py +++ b/openpilot/system/athena/athenad.py @@ -23,7 +23,6 @@ from collections.abc import Callable import requests from requests.adapters import HTTPAdapter, DEFAULT_POOLBLOCK -from jsonrpc import JSONRPCResponseManager, dispatcher from websocket import (ABNF, WebSocket, WebSocketException, WebSocketTimeoutException, create_connection) @@ -40,6 +39,7 @@ from openpilot.system.loggerd.xattr_cache import getxattr, setxattr from openpilot.common.swaglog import cloudlog from openpilot.common.version import get_build_metadata from openpilot.common.hardware.hw import Paths +from openpilot.system.athena.rpc import dispatcher, dumps_call, handle, is_call, is_response, loads ATHENA_HOST = os.getenv('ATHENA_HOST', 'wss://athena.comma.ai') @@ -211,11 +211,11 @@ def jsonrpc_handler(end_event: threading.Event) -> None: while not end_event.is_set(): try: data = recv_queue.get(timeout=1) - if "method" in data: + msg = loads(data) + if is_call(msg): cloudlog.event("athena.jsonrpc_handler.call_method", data=data) - response = JSONRPCResponseManager.handle(data, dispatcher) - send_queue_push(response.json, SEND_PRIORITY_HIGH) - elif "id" in data and ("result" in data or "error" in data): + send_queue_push(handle(msg, dispatcher), SEND_PRIORITY_HIGH) + elif is_response(msg): log_recv_queue.put_nowait(data) else: raise Exception("not a valid request or response") @@ -655,15 +655,7 @@ def log_handler(end_event: threading.Event) -> None: log_path = os.path.join(Paths.swaglog_root(), log_entry) setxattr(log_path, LOG_ATTR_NAME, int.to_bytes(curr_time, 4, sys.byteorder)) with open(log_path) as f: - jsonrpc = { - "method": "forwardLogs", - "params": { - "logs": f.read() - }, - "jsonrpc": "2.0", - "id": log_entry - } - send_queue_push(json.dumps(jsonrpc), SEND_PRIORITY_LOW) + send_queue_push(dumps_call("forwardLogs", {"logs": f.read()}, request_id=log_entry), SEND_PRIORITY_LOW) curr_log = log_entry except OSError: pass # file could be deleted by log rotation diff --git a/openpilot/system/athena/rpc.py b/openpilot/system/athena/rpc.py new file mode 100644 index 0000000000..aaf7f41fc3 --- /dev/null +++ b/openpilot/system/athena/rpc.py @@ -0,0 +1,116 @@ +import json +from collections.abc import Callable, Mapping +from typing import Any + +# a minimal implementation of json-rpc 2.0 https://www.jsonrpc.org/specification + +JSONRPC_VERSION = "2.0" + +# JSON-RPC 2.0 reserved / application error codes +PARSE_ERROR = -32700 +INVALID_REQUEST = -32600 +METHOD_NOT_FOUND = -32601 +INVALID_PARAMS = -32602 +SERVER_ERROR = -32000 + +JsonDict = dict[str, Any] +MethodMap = Mapping[str, Callable[..., Any]] + + +class Dispatcher(dict[str, Callable[..., Any]]): + def add_method(self, f: Callable[..., Any] | None = None, *, name: str | None = None): + def decorator(fn: Callable[..., Any]) -> Callable[..., Any]: + self[name or fn.__name__] = fn + return fn + return decorator(f) if f is not None else decorator + + +dispatcher = Dispatcher() + + +def dumps_call(method: str, params: Any = None, request_id: Any = None) -> str: + msg: JsonDict = {"jsonrpc": JSONRPC_VERSION, "method": method, "id": request_id} + if params is not None: + msg["params"] = params + return json.dumps(msg) + + +def dumps_result(request_id: Any, result: Any) -> str: + return json.dumps({"jsonrpc": JSONRPC_VERSION, "id": request_id, "result": result}) + + +def dumps_error(request_id: Any, message: str, code: int = SERVER_ERROR) -> str: + return json.dumps({ + "jsonrpc": JSONRPC_VERSION, + "id": request_id, + "error": {"code": code, "message": message}, + }) + + +def loads(raw: str | bytes) -> JsonDict: + if isinstance(raw, bytes): + raw = raw.decode() + data = json.loads(raw) + if not isinstance(data, dict): + raise ValueError("message must be a JSON object") + return data + + +def is_call(msg: JsonDict) -> bool: + return "method" in msg + + +def is_response(msg: JsonDict) -> bool: + return "id" in msg and ("result" in msg or "error" in msg) + + +def error_message(err: Any) -> str: + """Normalize JSON-RPC object errors and plain-string errors.""" + if isinstance(err, str): + return err + if isinstance(err, dict): + data = err.get("data") + if isinstance(data, dict) and data.get("message"): + return str(data["message"]) + if err.get("message") is not None: + return str(err["message"]) + return str(err) + + +def _invoke(fn: Callable[..., Any], params: Any) -> Any: + if params is None: + return fn() + if isinstance(params, dict): + return fn(**params) + if isinstance(params, (list, tuple)): + return fn(*params) + raise TypeError("params must be a list, object, or omitted") + + +def handle(raw: str | bytes | JsonDict, methods: MethodMap | None = None) -> str: + methods = dispatcher if methods is None else methods + + try: + msg = raw if isinstance(raw, dict) else loads(raw) + except (TypeError, ValueError, UnicodeDecodeError): + return dumps_error(None, "parse error", PARSE_ERROR) + + if not is_call(msg): + raise ValueError("not a call") + + req_id = msg.get("id") + name = msg.get("method") + if not isinstance(name, str): + return dumps_error(req_id, "invalid request", INVALID_REQUEST) + + try: + fn = methods[name] + except KeyError: + return dumps_error(req_id, f"method not found: {name}", METHOD_NOT_FOUND) + + try: + return dumps_result(req_id, _invoke(fn, msg.get("params"))) + except TypeError as e: + return dumps_error(req_id, str(e), INVALID_PARAMS) + except Exception as e: + return dumps_error(req_id, str(e), SERVER_ERROR) diff --git a/pyproject.toml b/pyproject.toml index 8430683abb..4118553595 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -50,7 +50,6 @@ dependencies = [ # athena "PyJWT", - "json-rpc", "websocket_client", # joystickd diff --git a/uv.lock b/uv.lock index 7c30add6c0..56d67b3a2d 100644 --- a/uv.lock +++ b/uv.lock @@ -699,15 +699,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899, upload-time = "2025-03-05T20:05:00.369Z" }, ] -[[package]] -name = "json-rpc" -version = "1.15.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/6d/9e/59f4a5b7855ced7346ebf40a2e9a8942863f644378d956f68bcef2c88b90/json-rpc-1.15.0.tar.gz", hash = "sha256:e6441d56c1dcd54241c937d0a2dcd193bdf0bdc539b5316524713f554b7f85b9", size = 28854, upload-time = "2023-06-11T09:45:49.078Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/94/9e/820c4b086ad01ba7d77369fb8b11470a01fac9b4977f02e18659cf378b6b/json_rpc-1.15.0-py2.py3-none-any.whl", hash = "sha256:4a4668bbbe7116feb4abbd0f54e64a4adcf4b8f648f19ffa0848ad0f6606a9bf", size = 39450, upload-time = "2023-06-11T09:45:47.136Z" }, -] - [[package]] name = "kiwisolver" version = "1.5.0" @@ -985,7 +976,6 @@ dependencies = [ { name = "cython" }, { name = "inputs" }, { name = "jeepney" }, - { name = "json-rpc" }, { name = "numpy" }, { name = "pillow" }, { name = "psutil" }, @@ -1069,7 +1059,6 @@ requires-dist = [ { name = "inputs" }, { name = "jeepney" }, { name = "jinja2", marker = "extra == 'docs'" }, - { name = "json-rpc" }, { name = "matplotlib", marker = "extra == 'dev'" }, { name = "numpy", specifier = ">=2.0" }, { name = "pillow" }, From c91731b13a82c3f102621503fe7404767bae194c Mon Sep 17 00:00:00 2001 From: stef <19478336+stefpi@users.noreply.github.com> Date: Thu, 9 Jul 2026 19:15:23 -0700 Subject: [PATCH 128/151] athena: remove take snapshot (#38319) remove snapshot --- openpilot/common/params_keys.h | 2 - .../selfdrive/selfdrived/alerts_offroad.json | 4 -- .../selfdrive/ui/tests/diff/replay_script.py | 1 - openpilot/system/athena/athenad.py | 20 ------ openpilot/system/camerad/snapshot.py | 64 ------------------- openpilot/system/hardware/hardwared.py | 1 - 6 files changed, 92 deletions(-) diff --git a/openpilot/common/params_keys.h b/openpilot/common/params_keys.h index 02bdc616da..7efa5721dc 100644 --- a/openpilot/common/params_keys.h +++ b/openpilot/common/params_keys.h @@ -63,7 +63,6 @@ inline static std::unordered_map keys = { {"IsOffroad", {CLEAR_ON_MANAGER_START, BOOL}}, {"IsRhdDetected", {PERSISTENT, BOOL}}, {"IsReleaseBranch", {CLEAR_ON_MANAGER_START, BOOL}}, - {"IsTakingSnapshot", {CLEAR_ON_MANAGER_START, BOOL}}, {"IsTestedBranch", {CLEAR_ON_MANAGER_START, BOOL}}, {"JoystickDebugMode", {CLEAR_ON_MANAGER_START | CLEAR_ON_OFFROAD_TRANSITION, BOOL}}, {"LanguageSetting", {PERSISTENT, STRING, "en"}}, @@ -94,7 +93,6 @@ inline static std::unordered_map keys = { {"Offroad_ConnectivityNeeded", {CLEAR_ON_MANAGER_START, JSON}}, {"Offroad_ConnectivityNeededPrompt", {CLEAR_ON_MANAGER_START, JSON}}, {"Offroad_ExcessiveActuation", {PERSISTENT, JSON}}, - {"Offroad_IsTakingSnapshot", {CLEAR_ON_MANAGER_START, JSON}}, {"Offroad_NeosUpdate", {CLEAR_ON_MANAGER_START, JSON}}, {"Offroad_NoFirmware", {CLEAR_ON_MANAGER_START | CLEAR_ON_ONROAD_TRANSITION, JSON}}, {"Offroad_Recalibration", {CLEAR_ON_MANAGER_START | CLEAR_ON_ONROAD_TRANSITION, JSON}}, diff --git a/openpilot/selfdrive/selfdrived/alerts_offroad.json b/openpilot/selfdrive/selfdrived/alerts_offroad.json index 0fc11b9636..add8d89550 100644 --- a/openpilot/selfdrive/selfdrived/alerts_offroad.json +++ b/openpilot/selfdrive/selfdrived/alerts_offroad.json @@ -17,10 +17,6 @@ "severity": 1, "_comment": "Set extra field to the failed reason." }, - "Offroad_IsTakingSnapshot": { - "text": "Taking camera snapshots. System won't start until finished.", - "severity": 0 - }, "Offroad_NeosUpdate": { "text": "An update to your device's operating system is downloading in the background. You will be prompted to update when it's ready to install.", "severity": 0 diff --git a/openpilot/selfdrive/ui/tests/diff/replay_script.py b/openpilot/selfdrive/ui/tests/diff/replay_script.py index 60c4a21ce4..8517f0dece 100644 --- a/openpilot/selfdrive/ui/tests/diff/replay_script.py +++ b/openpilot/selfdrive/ui/tests/diff/replay_script.py @@ -122,7 +122,6 @@ def set_prime_state(prime_type: PrimeType) -> None: def setup_offroad_alerts() -> None: set_offroad_alert("Offroad_TemperatureTooHigh", True, extra_text='99C') set_offroad_alert("Offroad_ExcessiveActuation", True, extra_text='longitudinal') - set_offroad_alert("Offroad_IsTakingSnapshot", True) def setup_update_available(available: bool = True) -> None: diff --git a/openpilot/system/athena/athenad.py b/openpilot/system/athena/athenad.py index 12715e1427..cf590afb40 100755 --- a/openpilot/system/athena/athenad.py +++ b/openpilot/system/athena/athenad.py @@ -1,9 +1,7 @@ #!/usr/bin/env python3 from __future__ import annotations -import base64 import hashlib -import io import itertools import json import os @@ -594,24 +592,6 @@ def startStream(sdp: str, enabled: bool) -> dict: return post_stream_request(StreamRequestBody(sdp, "wideRoad", enabled, bridge_services_in, ["carState", "deviceState"])) -@dispatcher.add_method -def takeSnapshot() -> str | dict[str, str] | None: - from openpilot.system.camerad.snapshot import jpeg_write, snapshot - ret = snapshot() - if ret is not None: - def b64jpeg(x): - if x is not None: - f = io.BytesIO() - jpeg_write(f, x) - return base64.b64encode(f.getvalue()).decode("utf-8") - else: - return None - return {'jpegBack': b64jpeg(ret[0]), - 'jpegFront': b64jpeg(ret[1])} - else: - raise Exception("not available while camerad is started") - - def get_logs_to_send_sorted() -> list[str]: # TODO: scan once then use inotify to detect file creation/deletion curr_time = int(time.time()) # noqa: TID251 diff --git a/openpilot/system/camerad/snapshot.py b/openpilot/system/camerad/snapshot.py index 1e73718abd..8383865fce 100755 --- a/openpilot/system/camerad/snapshot.py +++ b/openpilot/system/camerad/snapshot.py @@ -1,17 +1,10 @@ #!/usr/bin/env python3 -import subprocess -import time import numpy as np -from PIL import Image import openpilot.cereal.messaging as messaging from msgq.visionipc import VisionIpcClient, VisionStreamType -from openpilot.common.params import Params from openpilot.common.realtime import DT_MDL -from openpilot.common.hardware import PC -from openpilot.selfdrive.selfdrived.alertmanager import set_offroad_alert -from openpilot.system.manager.process_config import managed_processes VISION_STREAMS = { @@ -21,11 +14,6 @@ VISION_STREAMS = { } -def jpeg_write(fn, dat): - img = Image.fromarray(dat) - img.save(fn, "JPEG") - - def yuv_to_rgb(y, u, v): ul = np.repeat(np.repeat(u, 2).reshape(u.shape[0], y.shape[1]), 2, axis=0).reshape(y.shape) vl = np.repeat(np.repeat(v, 2).reshape(v.shape[0], y.shape[1]), 2, axis=0).reshape(y.shape) @@ -77,55 +65,3 @@ def get_snapshots(frame="roadCameraState", front_frame="driverCameraState"): c = vipc_clients[front_frame] front = extract_image(c.recv()) return rear, front - - -def snapshot(): - params = Params() - - if (not params.get_bool("IsOffroad")) or params.get_bool("IsTakingSnapshot"): - print("Already taking snapshot") - return None, None - - front_camera_allowed = params.get_bool("RecordFront") - params.put_bool("IsTakingSnapshot", True, block=True) - set_offroad_alert("Offroad_IsTakingSnapshot", True) - time.sleep(2.0) # Give hardwared time to read the param, or if just started give camerad time to start - - # Check if camerad is already started - try: - subprocess.check_call(["pgrep", "camerad"]) - print("Camerad already running") - params.put_bool("IsTakingSnapshot", False, block=True) - params.remove("Offroad_IsTakingSnapshot") - return None, None - except subprocess.CalledProcessError: - pass - - try: - # Allow testing on replay on PC - if not PC: - managed_processes['camerad'].start() - - frame = "wideRoadCameraState" - front_frame = "driverCameraState" if front_camera_allowed else None - rear, front = get_snapshots(frame, front_frame) - finally: - managed_processes['camerad'].stop() - params.put_bool("IsTakingSnapshot", False, block=True) - set_offroad_alert("Offroad_IsTakingSnapshot", False) - - if not front_camera_allowed: - front = None - - return rear, front - - -if __name__ == "__main__": - pic, fpic = snapshot() - if pic is not None: - print(pic.shape) - jpeg_write("/tmp/back.jpg", pic) - if fpic is not None: - jpeg_write("/tmp/front.jpg", fpic) - else: - print("Error taking snapshot") diff --git a/openpilot/system/hardware/hardwared.py b/openpilot/system/hardware/hardwared.py index 077965e8ac..6b86ce552f 100755 --- a/openpilot/system/hardware/hardwared.py +++ b/openpilot/system/hardware/hardwared.py @@ -290,7 +290,6 @@ def hardware_thread(end_event, hw_queue) -> None: startup_conditions["free_space"] = msg.deviceState.freeSpacePercent > 2 startup_conditions["completed_training"] = params.get("CompletedTrainingVersion") == training_version startup_conditions["not_driver_view"] = not params.get_bool("IsDriverViewEnabled") - startup_conditions["not_taking_snapshot"] = not params.get_bool("IsTakingSnapshot") # must be at an engageable thermal band to go onroad startup_conditions["device_temp_engageable"] = thermal_status < ThermalStatus.overheated From a26254304f28befecc20f375339c7cf61aaa952d Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Sat, 11 Jul 2026 12:59:49 -0700 Subject: [PATCH 129/151] Move eigen dependency into rednose (#38321) * Move eigen dependency into rednose * Declare complete rednose package dependencies * Update rednose submodule * Update rednose submodule * Update rednose submodule * Fix rednose dependency integration * bump rednose --- SConstruct | 2 +- pyproject.toml | 2 -- rednose_repo | 2 +- tools/release/build_stripped.sh | 2 +- uv.lock | 16 ++++++++++++---- 5 files changed, 15 insertions(+), 9 deletions(-) diff --git a/SConstruct b/SConstruct index 3ce34a86f7..72a25e12d4 100644 --- a/SConstruct +++ b/SConstruct @@ -55,7 +55,7 @@ assert arch in [ "Darwin", # macOS arm64 (x86 not supported) ] -pkg_names = ['acados', 'bzip2', 'capnproto', 'catch2', 'eigen', 'ffmpeg', 'json11', 'ncurses', 'zeromq', 'zstd'] +pkg_names = ['acados', 'bzip2', 'capnproto', 'catch2', 'ffmpeg', 'json11', 'ncurses', 'zeromq', 'zstd'] pkgs = [importlib.import_module(name) for name in pkg_names] acados = pkgs[pkg_names.index('acados')] ffmpeg = pkgs[pkg_names.index('ffmpeg')] diff --git a/pyproject.toml b/pyproject.toml index 4118553595..c4df3aabe1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,7 +12,6 @@ dependencies = [ # multiple users "sounddevice", # micd + soundd "requests", # many one-off uses - "sympy", # rednose + friends "tqdm", # cars (fw_versions.py) on start + many one-off uses # core @@ -29,7 +28,6 @@ dependencies = [ "comma-deps-capnproto", "comma-deps-catch2", "comma-deps-acados", - "comma-deps-eigen", "comma-deps-ffmpeg", "comma-deps-zstd", "comma-deps-ncurses", diff --git a/rednose_repo b/rednose_repo index 6c2abeb471..9e19086c26 160000 --- a/rednose_repo +++ b/rednose_repo @@ -1 +1 @@ -Subproject commit 6c2abeb471c830b38abb0f95d3aa348ca2b8dbc6 +Subproject commit 9e19086c26ca35708870d50ebcf237d65d0b163e diff --git a/tools/release/build_stripped.sh b/tools/release/build_stripped.sh index 1892360f6d..0e957c9212 100755 --- a/tools/release/build_stripped.sh +++ b/tools/release/build_stripped.sh @@ -38,7 +38,7 @@ git submodule foreach --recursive git clean -xdff # do the files copy echo "[-] copying files T=$SECONDS" cd $SOURCE_DIR -cp -pR --parents $(./tools/release/release_files.py) $TARGET_DIR/ +./tools/release/release_files.py | xargs -d '\n' cp -pR --parents -t "$TARGET_DIR" # in the directory cd $TARGET_DIR diff --git a/uv.lock b/uv.lock index 56d67b3a2d..1f5dd07cd4 100644 --- a/uv.lock +++ b/uv.lock @@ -963,7 +963,6 @@ dependencies = [ { name = "comma-deps-bzip2" }, { name = "comma-deps-capnproto" }, { name = "comma-deps-catch2" }, - { name = "comma-deps-eigen" }, { name = "comma-deps-ffmpeg" }, { name = "comma-deps-gcc-arm-none-eabi" }, { name = "comma-deps-git-lfs" }, @@ -989,7 +988,6 @@ dependencies = [ { name = "setproctitle" }, { name = "setuptools" }, { name = "sounddevice" }, - { name = "sympy" }, { name = "tqdm" }, { name = "websocket-client" }, { name = "xattr" }, @@ -1042,7 +1040,6 @@ requires-dist = [ { name = "comma-deps-bzip2" }, { name = "comma-deps-capnproto" }, { name = "comma-deps-catch2" }, - { name = "comma-deps-eigen" }, { name = "comma-deps-ffmpeg" }, { name = "comma-deps-gcc-arm-none-eabi" }, { name = "comma-deps-git-lfs" }, @@ -1080,7 +1077,6 @@ requires-dist = [ { name = "setproctitle" }, { name = "setuptools" }, { name = "sounddevice" }, - { name = "sympy" }, { name = "tqdm" }, { name = "ty", marker = "extra == 'testing'" }, { name = "websocket-client" }, @@ -1496,15 +1492,27 @@ version = "0.0.1" source = { editable = "rednose_repo" } dependencies = [ { name = "cffi" }, + { name = "comma-deps-eigen" }, + { name = "cython" }, { name = "numpy" }, + { name = "scons" }, + { name = "setuptools" }, { name = "sympy" }, ] [package.metadata] requires-dist = [ { name = "cffi" }, + { name = "comma-deps-eigen" }, + { name = "cython" }, { name = "numpy" }, + { name = "pre-commit", marker = "extra == 'dev'" }, + { name = "pytest", marker = "extra == 'dev'" }, + { name = "pytest-xdist", marker = "extra == 'dev'" }, + { name = "ruff", marker = "extra == 'dev'" }, { name = "scipy", marker = "extra == 'dev'" }, + { name = "scons" }, + { name = "setuptools" }, { name = "sympy" }, ] provides-extras = ["dev"] From a52da0d3df8dd6101aba1d23528b071172be9645 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Sat, 11 Jul 2026 13:08:39 -0700 Subject: [PATCH 130/151] bump msgq, no runtime deps --- msgq_repo | 2 +- uv.lock | 125 ++++++------------------------------------------------ 2 files changed, 14 insertions(+), 113 deletions(-) diff --git a/msgq_repo b/msgq_repo index 1d422a23c3..a771d031ec 160000 --- a/msgq_repo +++ b/msgq_repo @@ -1 +1 @@ -Subproject commit 1d422a23c31e5b8384e9464e1bb37e7f9b677aed +Subproject commit a771d031ec58716824f365a89f0607fd786a1161 diff --git a/uv.lock b/uv.lock index 1f5dd07cd4..d5b0006658 100644 --- a/uv.lock +++ b/uv.lock @@ -121,11 +121,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/c8/b9/275df9607f7fb44317ccb1d4be74827185c0d410f52b6e2cd770fe209118/av-16.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:f49243b1d27c91cd8c66fdba90a674e344eb8eb917264f36117bf2b6879118fd", size = 31752045, upload-time = "2026-01-11T09:57:45.106Z" }, ] -[[package]] -name = "catch2" -version = "2.13.10" -source = { git = "https://github.com/commaai/dependencies.git?subdirectory=catch2&rev=release-catch2#2bce880125320350b54d9d6696713ae847d06485" } - [[package]] name = "certifi" version = "2026.6.17" @@ -421,43 +416,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/52/30/21b2ad45959cd50e909e02ebac1e30b4ceb7162e91c11d4c570223a458b7/coverage-7.15.0-py3-none-any.whl", hash = "sha256:56da6a4cbe8f7e9e80bd072ca9cefe67d7106a440a7ec06519ec6507ac94ad19", size = 212632, upload-time = "2026-07-02T13:10:48.641Z" }, ] -[[package]] -name = "cppcheck" -version = "1.5.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "importlib-metadata" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/9f/99/44221d5ef868b4ff2d6333fe79aaed566e62645d362e15e0bdc17dd88057/cppcheck-1.5.1.tar.gz", hash = "sha256:143e273900e35fff65396e33253f13c342df55473fe097ca1673ed3cd72b98eb", size = 36283, upload-time = "2025-04-18T05:30:40.064Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/b5/04/4265922dd083da7e1002ca6fa08c0f8052aadd26dc7642ad74dcb9ca21f5/cppcheck-1.5.1-py3-none-macosx_10_9_x86_64.whl", hash = "sha256:34da2499a21ab1c7fa1934d716ce61b994d6acdce5fbfc415bf2b5b7855b6c46", size = 3168504, upload-time = "2025-04-18T05:30:15.241Z" }, - { url = "https://files.pythonhosted.org/packages/14/57/cd6d373dafc839e1bd0a77404adee971513ea098bfc1822a7b67ccc6060d/cppcheck-1.5.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:c45a1ca07a51a937f78e1d711f5104416634649afca4378f5cb5e9470a7ab969", size = 3059051, upload-time = "2025-04-18T05:30:17.193Z" }, - { url = "https://files.pythonhosted.org/packages/d5/1c/740d14f9b55e0cfad958d3555117c1d16b58b27bdaee406f633de13bd2c3/cppcheck-1.5.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ea5c2933d22df1a2ddccabbe0b071a12b9b14f07dc5d448beee4270e2049547", size = 3027427, upload-time = "2025-04-18T05:30:18.406Z" }, - { url = "https://files.pythonhosted.org/packages/04/56/ef686941c7668eaf959f72eda8304ef12f413f166b62bb2ccea92454c446/cppcheck-1.5.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2d6436afd5e1766c2070fda158af4f64639845e348d8a75740a2fb77d1dbfc54", size = 3320719, upload-time = "2025-04-18T05:30:19.984Z" }, - { url = "https://files.pythonhosted.org/packages/93/f3/0bd3b54fbd769433e87ac221f10df24a8be508605414351b901ab6ef9341/cppcheck-1.5.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:86ab2169cabf96794cf48a59ed090105f6343499c81c21f1bd607a491f57a89e", size = 3320415, upload-time = "2025-04-18T05:30:21.984Z" }, - { url = "https://files.pythonhosted.org/packages/0f/1a/06d1aa879bb223e183522d92c022e30710cadc151c841b063fdc8038e964/cppcheck-1.5.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a7c90a6b874bcb4a41568c20d786ce2ba49ec541505c1876999ca6548e4f3f52", size = 2945737, upload-time = "2025-04-18T05:30:23.637Z" }, - { url = "https://files.pythonhosted.org/packages/44/55/c3da11e6835721c92923a0f995b3bcede20daa9fd8df1462f863ae9b6a64/cppcheck-1.5.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ca87f5ed64386a40aaf156f295eac4efa6a7a819dd0415eb2d11577572e89405", size = 3136477, upload-time = "2025-04-18T05:30:25.279Z" }, - { url = "https://files.pythonhosted.org/packages/fe/bf/36bac23318403cf77cc743a15604f8153e818c366480cbdbf12080888637/cppcheck-1.5.1-py3-none-manylinux_2_31_armv7l.whl", hash = "sha256:81e79343e66bc7344d970b5f0d9a3ecafa6c5d5f7058e618e388462141c08e46", size = 2944184, upload-time = "2025-04-18T05:30:26.434Z" }, - { url = "https://files.pythonhosted.org/packages/7f/4a/488ccf07426be9fa0f54a3f5eed0762ebe9b7e692e21ade5a7578d987233/cppcheck-1.5.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:716a05569620c936acc7b2e48111d147a9d509bebc0078e926f65f5bf5f83865", size = 4216110, upload-time = "2025-04-18T05:30:27.633Z" }, - { url = "https://files.pythonhosted.org/packages/b4/ad/fbfb7a965d5cf862b40829017668c28fb358da41bde895d99fdfe61d289f/cppcheck-1.5.1-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:658d65d7842ea627241fd63f5f6dbbbc95f9f895444a8fafdc1322d6e391deab", size = 3900429, upload-time = "2025-04-18T05:30:29.395Z" }, - { url = "https://files.pythonhosted.org/packages/6c/74/01038bc7a6a64a845364e3ede7a66af5e08e197abbd6ed592d74cb23ac36/cppcheck-1.5.1-py3-none-musllinux_1_2_i686.whl", hash = "sha256:f9ac419167f2ca99b3ebd01c5777f22e06ef5ed29e26af6b0bb3060055ea3ae0", size = 4892684, upload-time = "2025-04-18T05:30:31.041Z" }, - { url = "https://files.pythonhosted.org/packages/13/62/35192d3971a5d15cfe991e3c4ae5a20db4a7ba064ea9805359635c06dff2/cppcheck-1.5.1-py3-none-musllinux_1_2_ppc64le.whl", hash = "sha256:fad05036ce457f889d9b841c0effec6aaf63634097dc8d654399ef768e2c12ea", size = 4692566, upload-time = "2025-04-18T05:30:32.299Z" }, - { url = "https://files.pythonhosted.org/packages/3d/5d/2b320e16b672e6c8a6055de2bce7f59be51bb23cb8bfbea473b121af14c3/cppcheck-1.5.1-py3-none-musllinux_1_2_s390x.whl", hash = "sha256:ded3f6b7ef0b0d71659fb653c14f3808e12cfdbe29f6bd601d29b8d2349ba47f", size = 4563106, upload-time = "2025-04-18T05:30:34.071Z" }, - { url = "https://files.pythonhosted.org/packages/32/a3/760145a26ca282ec3151e9b5be28a0598459fd389c8bc6385ca628f086f9/cppcheck-1.5.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:907d3ad5a8dabc7f73ec6e5b071f873e02044368459f1c585e5bc2067a8cce2a", size = 4545920, upload-time = "2025-04-18T05:30:35.297Z" }, - { url = "https://files.pythonhosted.org/packages/d8/f1/d46f09402e76ac878a6e458008cb9729bbe6cb2733c8f1b0c480aa15f5bb/cppcheck-1.5.1-py3-none-win32.whl", hash = "sha256:8f4733aee0dda4009725caf7592a7843fc022d043381f26de85584de84e7de29", size = 2491577, upload-time = "2025-04-18T05:30:36.419Z" }, - { url = "https://files.pythonhosted.org/packages/d0/3f/603d9db83b20fb170345483400cd1871df1bb31338af2288e49a7b431267/cppcheck-1.5.1-py3-none-win_amd64.whl", hash = "sha256:00678b255018773a3c70a106bf2112a21e05d29b2325102ea417f495944ecce9", size = 2725180, upload-time = "2025-04-18T05:30:37.491Z" }, - { url = "https://files.pythonhosted.org/packages/c5/69/a6eb66788ccc03c58f277b59c851b38485f0cf0fb1c9995680d8dc99d5b2/cppcheck-1.5.1-py3-none-win_arm64.whl", hash = "sha256:abb8265e3f692c1734db048d8df6fc380b4bbbbd0bd3f4697dbbc7a484181467", size = 2608967, upload-time = "2025-04-18T05:30:39.062Z" }, -] - -[[package]] -name = "cpplint" -version = "2.0.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/c5/83/47a9e7513ba4d943a9dac2f6752b444377c91880f4f4968799b4f42d89cc/cpplint-2.0.2.tar.gz", hash = "sha256:8a5971e4b5490133e425284f0c566c7ade0b959e61018d2c9af3ff7f357ddc57", size = 373781, upload-time = "2025-04-08T01:22:26.017Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/66/65/08d3a5039b565231c501b31d1a973d4222e9803c03b2c31a9c08bdec3e30/cpplint-2.0.2-py3-none-any.whl", hash = "sha256:7ec188b5a08e604294ae7e7f88ec3ece2699de857f0533b305620c8cf237cad5", size = 81987, upload-time = "2025-04-08T01:22:24.101Z" }, -] - [[package]] name = "cryptography" version = "49.0.0" @@ -639,18 +597,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/9c/1f/19ebc343cc71a7ffa78f17018535adc5cbdd87afb31d7c34874680148b32/ifaddr-0.2.0-py3-none-any.whl", hash = "sha256:085e0305cfe6f16ab12d72e2024030f5d52674afad6911bb1eee207177b8a748", size = 12314, upload-time = "2022-06-15T21:40:25.756Z" }, ] -[[package]] -name = "importlib-metadata" -version = "9.0.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "zipp" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/a9/01/15bb152d77b21318514a96f43af312635eb2500c96b55398d020c93d86ea/importlib_metadata-9.0.0.tar.gz", hash = "sha256:a4f57ab599e6a2e3016d7595cfd72eb4661a5106e787a95bcc90c7105b831efc", size = 56405, upload-time = "2026-03-20T06:42:56.999Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/38/3d/2d244233ac4f76e38533cfcb2991c9eb4c7bf688ae0a036d30725b8faafe/importlib_metadata-9.0.0-py3-none-any.whl", hash = "sha256:2d21d1cc5a017bd0559e36150c21c830ab1dc304dedd1b7ea85d20f45ef3edd7", size = 27789, upload-time = "2026-03-20T06:42:55.665Z" }, -] - [[package]] name = "importlib-resources" version = "7.1.0" @@ -726,19 +672,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/b5/91/53255615acd2a1eaca307ede3c90eb550bae9c94581f8c00081b6b1c8f44/kiwisolver-1.5.0-graalpy312-graalpy250_312_native-win_amd64.whl", hash = "sha256:1f1489f769582498610e015a8ef2d36f28f505ab3096d0e16b4858a9ec214f57", size = 75987, upload-time = "2026-03-09T13:15:39.65Z" }, ] -[[package]] -name = "lefthook" -version = "2.1.9" -source = { registry = "https://pypi.org/simple" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/92/5e/2cbfb93902906f82fa1d106b30a42e455c71599b968ab9edb86bdd487ca1/lefthook-2.1.9-py3-none-macosx_10_15_x86_64.whl", hash = "sha256:b4be037dffa2aacb312770c2c7981bb7547e0d07459e897053839b8375f66400", size = 5532741, upload-time = "2026-05-29T08:39:22.995Z" }, - { url = "https://files.pythonhosted.org/packages/b7/0e/983781b9084ef8317b45164abd3335a754973b4910dcc7d0a93c7fc4737c/lefthook-2.1.9-py3-none-macosx_11_0_arm64.whl", hash = "sha256:06754e8a56520811079063fe227b361ac8d306e5f004d103248fa57e55f997a1", size = 5053231, upload-time = "2026-05-29T08:39:31.1Z" }, - { url = "https://files.pythonhosted.org/packages/71/e3/0e8dcd17c392e13e6bdea605683f0a93bed57e72df6aea8c030d0e5d98d9/lefthook-2.1.9-py3-none-manylinux_2_17_aarch64.whl", hash = "sha256:74fa383dfb3a31913256220c59207b8d6f3d66798f50600f1683872a07c99cb5", size = 4880938, upload-time = "2026-05-29T08:39:25.637Z" }, - { url = "https://files.pythonhosted.org/packages/74/35/63cf009271a11f693691aeb47dd25d270b346a7c854a8966faf09999e8b9/lefthook-2.1.9-py3-none-manylinux_2_17_x86_64.whl", hash = "sha256:5df17f57e5e4bc3cb1b4788eda68df929a23f273ff255c632edaf1f30808a6d5", size = 5463037, upload-time = "2026-05-29T08:39:27.358Z" }, - { url = "https://files.pythonhosted.org/packages/7b/04/5dbf2107e0727e1d8cdfc20aba62d37e357577998c1abc3991cccb2a1632/lefthook-2.1.9-py3-none-win_amd64.whl", hash = "sha256:dc121e492b681e1128290fe4a0c857f6b46b6f4491c0d1b0be58dc5592e62c77", size = 5614416, upload-time = "2026-05-29T08:39:29.226Z" }, - { url = "https://files.pythonhosted.org/packages/48/e8/7923893f08504f28e0b5fb8b21795fc388d0363cfa2f412e2541c9464cb1/lefthook-2.1.9-py3-none-win_arm64.whl", hash = "sha256:6d8e3923c42a04e9375f88314ebc8c86f68879d3d0c9d856b6adbed109890e90", size = 4959833, upload-time = "2026-05-29T08:39:32.882Z" }, -] - [[package]] name = "libusb-package" version = "1.0.30.0" @@ -835,34 +768,22 @@ wheels = [ name = "msgq" version = "0.0.1" source = { editable = "msgq_repo" } -dependencies = [ - { name = "catch2" }, - { name = "codespell" }, - { name = "cppcheck" }, - { name = "cpplint" }, - { name = "cython" }, - { name = "lefthook" }, - { name = "parameterized" }, - { name = "ruff" }, - { name = "scons" }, - { name = "setuptools" }, - { name = "ty" }, -] [package.metadata] requires-dist = [ - { name = "catch2", git = "https://github.com/commaai/dependencies.git?subdirectory=catch2&rev=release-catch2" }, - { name = "codespell" }, - { name = "cppcheck" }, - { name = "cpplint" }, - { name = "cython" }, - { name = "lefthook" }, - { name = "parameterized" }, - { name = "ruff" }, - { name = "scons" }, - { name = "setuptools" }, - { name = "ty" }, + { name = "catch2", marker = "extra == 'dev'", git = "https://github.com/commaai/dependencies.git?subdirectory=catch2&rev=release-catch2" }, + { name = "codespell", marker = "extra == 'dev'" }, + { name = "cppcheck", marker = "extra == 'dev'" }, + { name = "cpplint", marker = "extra == 'dev'" }, + { name = "cython", marker = "extra == 'dev'" }, + { name = "lefthook", marker = "extra == 'dev'" }, + { name = "parameterized", marker = "extra == 'dev'" }, + { name = "ruff", marker = "extra == 'dev'" }, + { name = "scons", marker = "extra == 'dev'" }, + { name = "setuptools", marker = "extra == 'dev'" }, + { name = "ty", marker = "extra == 'dev'" }, ] +provides-extras = ["dev"] [[package]] name = "multidict" @@ -1137,15 +1058,6 @@ requires-dist = [ ] provides-extras = ["dev"] -[[package]] -name = "parameterized" -version = "0.9.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ea/49/00c0c0cc24ff4266025a53e41336b79adaa5a4ebfad214f433d623f9865e/parameterized-0.9.0.tar.gz", hash = "sha256:7fc905272cefa4f364c1a3429cbbe9c0f98b793988efb5bf90aac80f08db09b1", size = 24351, upload-time = "2023-03-27T02:01:11.592Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/00/2f/804f58f0b856ab3bf21617cccf5b39206e6c4c94c2cd227bde125ea6105f/parameterized-0.9.0-py2.py3-none-any.whl", hash = "sha256:4e0758e3d41bea3bbd05ec14fc2c24736723f243b28d702081aef438c9372b1b", size = 20475, upload-time = "2023-03-27T02:01:09.31Z" }, -] - [[package]] name = "pillow" version = "12.3.0" @@ -1506,14 +1418,12 @@ requires-dist = [ { name = "comma-deps-eigen" }, { name = "cython" }, { name = "numpy" }, - { name = "pre-commit", marker = "extra == 'dev'" }, - { name = "pytest", marker = "extra == 'dev'" }, - { name = "pytest-xdist", marker = "extra == 'dev'" }, { name = "ruff", marker = "extra == 'dev'" }, { name = "scipy", marker = "extra == 'dev'" }, { name = "scons" }, { name = "setuptools" }, { name = "sympy" }, + { name = "ty", marker = "extra == 'dev'" }, ] provides-extras = ["dev"] @@ -1912,15 +1822,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/73/26/fc7ef081acbdada8436825221cb728ee84a81d4d78a7bb79aa58bd150d31/zensical-0.0.46-cp310-abi3-win_amd64.whl", hash = "sha256:1543a693a160de60e86ca589592401b584670e7e12c5ae30e3c2ba76786f7ec3", size = 12599687, upload-time = "2026-06-21T18:52:37.913Z" }, ] -[[package]] -name = "zipp" -version = "4.1.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b9/d8/eab98a517c14134c0b2eb4e2387bc5f457334293ec5d2dd3857ec2966802/zipp-4.1.0.tar.gz", hash = "sha256:4cb57381f544315db7688e976e922a2b18cdb513d21cc194eb42232ba2a3e602", size = 26214, upload-time = "2026-05-18T20:08:57.967Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/3a/13/547360d81e6d88d58492968ffda9f9542854f11310ee556fef14260cc886/zipp-4.1.0-py3-none-any.whl", hash = "sha256:25ad4e16390cd314347dd8f1de67a2ac538ae658ed4ab9db16029c07c188e97f", size = 10238, upload-time = "2026-05-18T20:08:57.045Z" }, -] - [[package]] name = "zstandard" version = "0.25.0" From 503531ab384cd34a7114c7e0748d6c20232e0f88 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Sat, 11 Jul 2026 13:51:22 -0700 Subject: [PATCH 131/151] replace psutil with simple /proc helper (#38326) * replace psutil with simple /proc helper * mv to common --- openpilot/common/linux.py | 50 +++++++++++ openpilot/system/hardware/hardwared.py | 8 +- openpilot/system/updated/updated.py | 6 -- pyproject.toml | 1 - tools/scripts/cpu_usage_stat.py | 120 ------------------------- uv.lock | 18 ---- 6 files changed, 54 insertions(+), 149 deletions(-) create mode 100644 openpilot/common/linux.py delete mode 100755 tools/scripts/cpu_usage_stat.py diff --git a/openpilot/common/linux.py b/openpilot/common/linux.py new file mode 100644 index 0000000000..73ea77b509 --- /dev/null +++ b/openpilot/common/linux.py @@ -0,0 +1,50 @@ +class LinuxSystemStats: + def __init__(self) -> None: + self._last_cpu_times = self._read_cpu_times() + + @staticmethod + def _read_cpu_times() -> dict[int, tuple[int, int]]: + cpu_times = {} + with open('/proc/stat') as f: + for line in f: + name, *values = line.split() + if not name.startswith('cpu') or not name[3:].isdigit(): + continue + + times = [int(value) for value in values] + idle = sum(times[3:5]) + total = sum(times[:8]) + cpu_times[int(name[3:])] = (idle, total) + return cpu_times + + def cpu_usage_percent(self) -> list[float]: + current_cpu_times = self._read_cpu_times() + usage = [] + for cpu, (idle, total) in sorted(current_cpu_times.items()): + last_times = self._last_cpu_times.get(cpu) + if last_times is None: + usage.append(0.) + continue + + last_idle, last_total = last_times + idle_delta = idle - last_idle + total_delta = total - last_total + if idle_delta < 0 or total_delta <= 0: + usage.append(0.) + else: + usage.append(max(0., min(100., 100. * (total_delta - idle_delta) / total_delta))) + + self._last_cpu_times = current_cpu_times + return usage + + @staticmethod + def memory_usage_percent() -> float: + memory = {} + with open('/proc/meminfo') as f: + for line in f: + key, value, *_ = line.split() + if key in ('MemTotal:', 'MemAvailable:'): + memory[key] = int(value) + + total = memory['MemTotal:'] + return max(0., min(100., 100. * (total - memory['MemAvailable:']) / total)) diff --git a/openpilot/system/hardware/hardwared.py b/openpilot/system/hardware/hardwared.py index 6b86ce552f..581ac7f1e0 100755 --- a/openpilot/system/hardware/hardwared.py +++ b/openpilot/system/hardware/hardwared.py @@ -7,8 +7,6 @@ import threading import time from collections import OrderedDict, namedtuple -import psutil - import openpilot.cereal.messaging as messaging from openpilot.cereal import log from openpilot.cereal.services import SERVICE_LIST @@ -19,6 +17,7 @@ from openpilot.common.realtime import DT_HW from openpilot.selfdrive.selfdrived.alertmanager import set_offroad_alert from openpilot.common.hardware import HARDWARE, TICI, PC from openpilot.common.hardware.usb import get_usb_state, set_usb_state +from openpilot.common.linux import LinuxSystemStats from openpilot.system.loggerd.config import get_available_percent from openpilot.common.swaglog import cloudlog from openpilot.system.hardware.power_monitoring import PowerMonitoring @@ -142,6 +141,7 @@ def hw_state_thread(end_event, hw_queue): def hardware_thread(end_event, hw_queue) -> None: + system_stats = LinuxSystemStats() pm = messaging.PubMaster(['deviceState']) sm = messaging.SubMaster(["peripheralState", "gpsLocationExternal", "selfdriveState", "pandaStates"], poll="pandaStates") @@ -232,9 +232,9 @@ def hardware_thread(end_event, hw_queue) -> None: pass msg.deviceState.freeSpacePercent = get_available_percent(default=100.0) - msg.deviceState.memoryUsagePercent = int(round(psutil.virtual_memory().percent)) + msg.deviceState.memoryUsagePercent = int(round(system_stats.memory_usage_percent())) msg.deviceState.gpuUsagePercent = int(round(HARDWARE.get_gpu_usage_percent())) - online_cpu_usage = [int(round(n)) for n in psutil.cpu_percent(percpu=True)] + online_cpu_usage = [int(round(n)) for n in system_stats.cpu_usage_percent()] offline_cpu_usage = [0., ] * (len(msg.deviceState.cpuTempC) - len(online_cpu_usage)) msg.deviceState.cpuUsagePercent = online_cpu_usage + offline_cpu_usage diff --git a/openpilot/system/updated/updated.py b/openpilot/system/updated/updated.py index c8f45fdb56..ac8111d5c5 100755 --- a/openpilot/system/updated/updated.py +++ b/openpilot/system/updated/updated.py @@ -3,7 +3,6 @@ import os import re import datetime import subprocess -import psutil import shutil import signal import fcntl @@ -427,11 +426,6 @@ def main() -> None: except OSError as e: raise RuntimeError("couldn't get overlay lock; is another instance running?") from e - # Set low io priority - proc = psutil.Process() - if psutil.LINUX: - proc.ionice(psutil.IOPRIO_CLASS_BE, value=7) - # Check if we just performed an update if Path(os.path.join(STAGING_ROOT, "old_openpilot")).is_dir(): cloudlog.event("update installed") diff --git a/pyproject.toml b/pyproject.toml index c4df3aabe1..9f13917190 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -54,7 +54,6 @@ dependencies = [ "inputs", # these should be removed - "psutil", "setproctitle", # logreader diff --git a/tools/scripts/cpu_usage_stat.py b/tools/scripts/cpu_usage_stat.py deleted file mode 100755 index 902df1c778..0000000000 --- a/tools/scripts/cpu_usage_stat.py +++ /dev/null @@ -1,120 +0,0 @@ -#!/usr/bin/env python3 -''' -System tools like top/htop can only show current cpu usage values, so I write this script to do statistics jobs. - Features: - Use psutil library to sample cpu usage(avergage for all cores) of openpilot processes, at a rate of 5 samples/sec. - Do cpu usage statistics periodically, 5 seconds as a cycle. - Calculate the average cpu usage within this cycle. - Calculate minumium/maximum/accumulated_average cpu usage as long term inspections. - Monitor multiple processes simuteneously. - Sample usage: - root@localhost:/data/openpilot$ python openpilot/tools/scripts/cpu_usage_stat.py pandad,ubloxd - ('Add monitored proc:', './pandad') - ('Add monitored proc:', 'python locationd/ubloxd.py') - pandad: 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 - -from openpilot.system.manager.process_config import managed_processes - -# Do statistics every 5 seconds -PRINT_INTERVAL = 5 -SLEEP_INTERVAL = 0.2 - -monitored_proc_names = [ - # android procs - 'SurfaceFlinger', 'sensors.qcom' -] + list(managed_processes.keys()) - -cpu_time_names = ['user', 'system', 'children_user', 'children_system'] - - -def get_arg_parser(): - parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter) - - parser.add_argument("proc_names", nargs="?", default='', - help="Process names to be monitored, comma separated") - parser.add_argument("--list_all", action='store_true', - help="Show all running processes' cmdline") - parser.add_argument("--detailed_times", action='store_true', - help="show cpu time details (split by user, system, child user, child system)") - return parser - - -if __name__ == "__main__": - args = get_arg_parser().parse_args(sys.argv[1:]) - if args.list_all: - for p in psutil.process_iter(): - print('cmdline', p.cmdline(), 'name', p.name()) - sys.exit(0) - - if len(args.proc_names) > 0: - monitored_proc_names = args.proc_names.split(',') - monitored_procs = [] - stats = {} - for p in psutil.process_iter(): - if p == psutil.Process(): - continue - matched = any(l for l in p.cmdline() if any(pn for pn in monitored_proc_names if re.match(fr'.*{pn}.*', l, re.M | re.I))) - if matched: - k = ' '.join(p.cmdline()) - print('Add monitored proc:', k) - stats[k] = {'cpu_samples': defaultdict(list), 'min': defaultdict(lambda: None), 'max': defaultdict(lambda: None), - 'avg': defaultdict(float), 'last_cpu_times': None, 'last_sys_time': None} - stats[k]['last_sys_time'] = time.monotonic() - stats[k]['last_cpu_times'] = p.cpu_times() - monitored_procs.append(p) - i = 0 - interval_int = int(PRINT_INTERVAL / SLEEP_INTERVAL) - while True: - for p in monitored_procs: - k = ' '.join(p.cmdline()) - cur_sys_time = time.monotonic() - cur_cpu_times = p.cpu_times() - cpu_times = np.subtract(cur_cpu_times, stats[k]['last_cpu_times']) / (cur_sys_time - stats[k]['last_sys_time']) - stats[k]['last_sys_time'] = cur_sys_time - stats[k]['last_cpu_times'] = cur_cpu_times - cpu_percent = 0 - for num, name in enumerate(cpu_time_names): - stats[k]['cpu_samples'][name].append(cpu_times[num]) - cpu_percent += cpu_times[num] - stats[k]['cpu_samples']['total'].append(cpu_percent) - time.sleep(SLEEP_INTERVAL) - i += 1 - if i % interval_int == 0: - l = [] - for k, stat in stats.items(): - if len(stat['cpu_samples']) <= 0: - continue - for name, samples in stat['cpu_samples'].items(): - samples = np.array(samples) - avg = samples.mean() - c = samples.size - min_cpu = np.amin(samples) - max_cpu = np.amax(samples) - if stat['min'][name] is None or min_cpu < stat['min'][name]: - stat['min'][name] = min_cpu - if stat['max'][name] is None or max_cpu > stat['max'][name]: - stat['max'][name] = max_cpu - stat['avg'][name] = (stat['avg'][name] * (i - c) + avg * c) / (i) - stat['cpu_samples'][name] = [] - - msg = f"avg: {stat['avg']['total']:.2%}, min: {stat['min']['total']:.2%}, max: {stat['max']['total']:.2%} {os.path.basename(k)}" - if args.detailed_times: - for stat_type in ['avg', 'min', 'max']: - msg += f"\n {stat_type}: {[(name + ':' + str(round(stat[stat_type][name] * 100, 2))) for name in cpu_time_names]}" - l.append((os.path.basename(k), stat['avg']['total'], msg)) - l.sort(key=lambda x: -x[1]) - for x in l: - print(x[2]) - print('avg sum: {:.2%} over {} samples {} seconds\n'.format( - sum(stat['avg']['total'] for k, stat in stats.items()), i, i * SLEEP_INTERVAL - )) diff --git a/uv.lock b/uv.lock index d5b0006658..2284243b55 100644 --- a/uv.lock +++ b/uv.lock @@ -898,7 +898,6 @@ dependencies = [ { name = "jeepney" }, { name = "numpy" }, { name = "pillow" }, - { name = "psutil" }, { name = "pycapnp" }, { name = "pyjwt" }, { name = "pyzmq" }, @@ -981,7 +980,6 @@ requires-dist = [ { name = "numpy", specifier = ">=2.0" }, { name = "pillow" }, { name = "pre-commit-hooks", marker = "extra == 'testing'" }, - { name = "psutil" }, { name = "pycapnp", specifier = "==2.1.0" }, { name = "pyjwt" }, { name = "pytest", marker = "extra == 'testing'" }, @@ -1122,22 +1120,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/3a/ed/1cdcab6ba3d6ab7feca11fc14f0eeea80755bb53ef4e892079f31b10a25f/propcache-0.5.2-py3-none-any.whl", hash = "sha256:be1ddfcbb376e3de5d2e2db1d58d6d67463e6b4f9f040c000de8e300295465fe", size = 14036, upload-time = "2026-05-08T21:02:10.673Z" }, ] -[[package]] -name = "psutil" -version = "7.2.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/aa/c6/d1ddf4abb55e93cebc4f2ed8b5d6dbad109ecb8d63748dd2b20ab5e57ebe/psutil-7.2.2.tar.gz", hash = "sha256:0746f5f8d406af344fd547f1c8daa5f5c33dbc293bb8d6a16d80b4bb88f59372", size = 493740, upload-time = "2026-01-28T18:14:54.428Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/e7/36/5ee6e05c9bd427237b11b3937ad82bb8ad2752d72c6969314590dd0c2f6e/psutil-7.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:ed0cace939114f62738d808fdcecd4c869222507e266e574799e9c0faa17d486", size = 129090, upload-time = "2026-01-28T18:15:22.168Z" }, - { url = "https://files.pythonhosted.org/packages/80/c4/f5af4c1ca8c1eeb2e92ccca14ce8effdeec651d5ab6053c589b074eda6e1/psutil-7.2.2-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:1a7b04c10f32cc88ab39cbf606e117fd74721c831c98a27dc04578deb0c16979", size = 129859, upload-time = "2026-01-28T18:15:23.795Z" }, - { url = "https://files.pythonhosted.org/packages/b5/70/5d8df3b09e25bce090399cf48e452d25c935ab72dad19406c77f4e828045/psutil-7.2.2-cp36-abi3-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:076a2d2f923fd4821644f5ba89f059523da90dc9014e85f8e45a5774ca5bc6f9", size = 155560, upload-time = "2026-01-28T18:15:25.976Z" }, - { url = "https://files.pythonhosted.org/packages/63/65/37648c0c158dc222aba51c089eb3bdfa238e621674dc42d48706e639204f/psutil-7.2.2-cp36-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b0726cecd84f9474419d67252add4ac0cd9811b04d61123054b9fb6f57df6e9e", size = 156997, upload-time = "2026-01-28T18:15:27.794Z" }, - { url = "https://files.pythonhosted.org/packages/8e/13/125093eadae863ce03c6ffdbae9929430d116a246ef69866dad94da3bfbc/psutil-7.2.2-cp36-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:fd04ef36b4a6d599bbdb225dd1d3f51e00105f6d48a28f006da7f9822f2606d8", size = 148972, upload-time = "2026-01-28T18:15:29.342Z" }, - { url = "https://files.pythonhosted.org/packages/04/78/0acd37ca84ce3ddffaa92ef0f571e073faa6d8ff1f0559ab1272188ea2be/psutil-7.2.2-cp36-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:b58fabe35e80b264a4e3bb23e6b96f9e45a3df7fb7eed419ac0e5947c61e47cc", size = 148266, upload-time = "2026-01-28T18:15:31.597Z" }, - { url = "https://files.pythonhosted.org/packages/b4/90/e2159492b5426be0c1fef7acba807a03511f97c5f86b3caeda6ad92351a7/psutil-7.2.2-cp37-abi3-win_amd64.whl", hash = "sha256:eb7e81434c8d223ec4a219b5fc1c47d0417b12be7ea866e24fb5ad6e84b3d988", size = 137737, upload-time = "2026-01-28T18:15:33.849Z" }, - { url = "https://files.pythonhosted.org/packages/8c/c7/7bb2e321574b10df20cbde462a94e2b71d05f9bbda251ef27d104668306a/psutil-7.2.2-cp37-abi3-win_arm64.whl", hash = "sha256:8c233660f575a5a89e6d4cb65d9f938126312bca76d8fe087b947b3a1aaac9ee", size = 134617, upload-time = "2026-01-28T18:15:36.514Z" }, -] - [[package]] name = "pycapnp" version = "2.1.0" From 4fd4ddb438258a743e3aa7bfdf2860896f9e71b8 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Tue, 14 Jul 2026 15:55:04 -0700 Subject: [PATCH 132/151] long_mpc: remove unused solver state and timings (#38335) --- .../controls/lib/longitudinal_mpc_lib/long_mpc.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/openpilot/selfdrive/controls/lib/longitudinal_mpc_lib/long_mpc.py b/openpilot/selfdrive/controls/lib/longitudinal_mpc_lib/long_mpc.py index 02a424c4c2..99d0c7ae68 100755 --- a/openpilot/selfdrive/controls/lib/longitudinal_mpc_lib/long_mpc.py +++ b/openpilot/selfdrive/controls/lib/longitudinal_mpc_lib/long_mpc.py @@ -240,14 +240,10 @@ class LongitudinalMpc: self.solver.set(i, 'x', np.zeros(X_DIM)) self.last_cloudlog_t = 0 - self.status = False self.crash_cnt = 0.0 self.solution_status = 0 # timers self.solve_time = 0.0 - self.time_qp_solution = 0.0 - self.time_linearization = 0.0 - self.time_integrator = 0.0 self.x0 = np.zeros(X_DIM) self.set_weights() @@ -316,7 +312,6 @@ class LongitudinalMpc: def update(self, radarstate, v_cruise, personality=log.LongitudinalPersonality.standard): t_follow = get_T_FOLLOW(personality) v_ego = self.x0[1] - self.status = radarstate.leadOne.status or radarstate.leadTwo.status lead_xv_0 = self.process_lead(radarstate.leadOne) lead_xv_1 = self.process_lead(radarstate.leadTwo) @@ -365,9 +360,6 @@ class LongitudinalMpc: self.solution_status = self.solver.solve() self.solve_time = float(self.solver.get_stats('time_tot')[0]) - self.time_qp_solution = float(self.solver.get_stats('time_qp')[0]) - self.time_linearization = float(self.solver.get_stats('time_lin')[0]) - self.time_integrator = float(self.solver.get_stats('time_sim')[0]) for i in range(N+1): self.x_sol[i] = self.solver.get(i, 'x') From f42dbbb01c8d78bd555ffd343ca1e229989ff847 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Tue, 14 Jul 2026 16:01:45 -0700 Subject: [PATCH 133/151] longitudinal planner: remove unused model trajectory parsing (#38336) --- .../controls/lib/longitudinal_planner.py | 23 ++----------------- 1 file changed, 2 insertions(+), 21 deletions(-) diff --git a/openpilot/selfdrive/controls/lib/longitudinal_planner.py b/openpilot/selfdrive/controls/lib/longitudinal_planner.py index a2547f99bf..f413903aa0 100755 --- a/openpilot/selfdrive/controls/lib/longitudinal_planner.py +++ b/openpilot/selfdrive/controls/lib/longitudinal_planner.py @@ -63,26 +63,6 @@ class LongitudinalPlanner: self.a_desired_trajectory = np.zeros(CONTROL_N) self.j_desired_trajectory = np.zeros(CONTROL_N) - @staticmethod - def parse_model(model_msg): - if (len(model_msg.position.x) == ModelConstants.IDX_N and - len(model_msg.velocity.x) == ModelConstants.IDX_N and - len(model_msg.acceleration.x) == ModelConstants.IDX_N): - x = np.interp(T_IDXS_MPC, ModelConstants.T_IDXS, model_msg.position.x) - v = np.interp(T_IDXS_MPC, ModelConstants.T_IDXS, model_msg.velocity.x) - a = np.interp(T_IDXS_MPC, ModelConstants.T_IDXS, model_msg.acceleration.x) - j = np.zeros(len(T_IDXS_MPC)) - else: - x = np.zeros(len(T_IDXS_MPC)) - v = np.zeros(len(T_IDXS_MPC)) - a = np.zeros(len(T_IDXS_MPC)) - j = np.zeros(len(T_IDXS_MPC)) - if len(model_msg.meta.disengagePredictions.gasPressProbs) > 1: - throttle_prob = model_msg.meta.disengagePredictions.gasPressProbs[1] - else: - throttle_prob = 1.0 - return x, v, a, j, throttle_prob - def update(self, sm): if len(sm['carControl'].orientationNED) == 3: accel_coast = get_coast_accel(sm['carControl'].orientationNED[1]) @@ -116,7 +96,8 @@ class LongitudinalPlanner: # Prevent divergence, smooth in current v_ego self.v_desired_filter.x = max(0.0, self.v_desired_filter.update(v_ego)) - _, _, _, _, throttle_prob = self.parse_model(sm['modelV2']) + throttle_probs = sm['modelV2'].meta.disengagePredictions.gasPressProbs + throttle_prob = throttle_probs[1] if len(throttle_probs) > 1 else 1.0 # Don't clip at low speeds since throttle_prob doesn't account for creep self.allow_throttle = throttle_prob > ALLOW_THROTTLE_THRESHOLD or v_ego <= MIN_ALLOW_THROTTLE_SPEED From cf8371c2c51b6b51d71c19ad8b8e491b4016d352 Mon Sep 17 00:00:00 2001 From: Daniel Koepping Date: Tue, 14 Jul 2026 17:44:46 -0700 Subject: [PATCH 134/151] add usb link err counter (#38338) * add usb link err counter * ci --- openpilot/cereal/log.capnp | 1 + openpilot/common/hardware/usb.py | 10 ++++++++++ 2 files changed, 11 insertions(+) diff --git a/openpilot/cereal/log.capnp b/openpilot/cereal/log.capnp index 2b43a95d7b..296cba3b25 100644 --- a/openpilot/cereal/log.capnp +++ b/openpilot/cereal/log.capnp @@ -699,6 +699,7 @@ struct UsbState { speedMbps @4 :UInt16; manufacturer @6 :Text; product @5 :Text; + linkErrorCount @7 :UInt16; } } diff --git a/openpilot/common/hardware/usb.py b/openpilot/common/hardware/usb.py index 805f32407f..983002b538 100644 --- a/openpilot/common/hardware/usb.py +++ b/openpilot/common/hardware/usb.py @@ -27,11 +27,19 @@ def usb_devices() -> list[Path]: return [] +def controller(device: Path) -> Path | None: + try: + return next((parent for parent in device.resolve().parents if parent.name.endswith(".ssusb")), None) + except OSError: + return None + + def get_usb_state() -> list[dict]: devices = [] for device in usb_devices(): vendor_id = read_int(device / "idVendor", 16) product_id = read_int(device / "idProduct", 16) + ctrl = controller(device) devices.append({ "busnum": read_int(device / "busnum"), "devnum": read_int(device / "devnum"), @@ -40,6 +48,7 @@ def get_usb_state() -> list[dict]: "speedMbps": read_int(device / "speed"), "manufacturer": read(device / "manufacturer") or "", "product": read(device / "product") or "", + "linkErrorCount": read_int(ctrl / "portli", 0) & 0xFFFF if ctrl is not None else 0, }) return devices @@ -56,6 +65,7 @@ def set_usb_state(device_state, devices: list[dict]) -> None: entry.speedMbps = device["speedMbps"] entry.manufacturer = device["manufacturer"] entry.product = device["product"] + entry.linkErrorCount = device["linkErrorCount"] if (entry.vendorId, entry.productId) == (CHESTNUT_VENDOR_ID, CHESTNUT_PRODUCT_ID): chestnut_present = True From 45b53cf66ac564326a78e024eb974f742c2ca69b Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Tue, 14 Jul 2026 18:54:07 -0700 Subject: [PATCH 135/151] Rename LeadData.status to LeadData.present (#38339) * rename LeadData.status to LeadData.present * rename LeadData.status to LeadData.present * resolve longitudinal MPC merge conflict --- openpilot/cereal/log.capnp | 2 +- .../controls/lib/longitudinal_mpc_lib/long_mpc.py | 2 +- openpilot/selfdrive/controls/lib/longitudinal_planner.py | 2 +- openpilot/selfdrive/controls/radard.py | 8 ++++---- openpilot/selfdrive/test/longitudinal_maneuvers/plant.py | 2 +- openpilot/selfdrive/ui/mici/onroad/model_renderer.py | 4 ++-- openpilot/selfdrive/ui/onroad/model_renderer.py | 4 ++-- openpilot/tools/replay/lib/ui_helpers.py | 2 +- 8 files changed, 13 insertions(+), 13 deletions(-) diff --git a/openpilot/cereal/log.capnp b/openpilot/cereal/log.capnp index 296cba3b25..c7923bd373 100644 --- a/openpilot/cereal/log.capnp +++ b/openpilot/cereal/log.capnp @@ -722,7 +722,7 @@ struct RadarState @0x9a185389d6fdd05f { vLeadK @8 :Float32; aLeadK @9 :Float32; fcw @10 :Bool; - status @11 :Bool; + present @11 :Bool; aLeadTau @12 :Float32; modelProb @13 :Float32; radar @14 :Bool; diff --git a/openpilot/selfdrive/controls/lib/longitudinal_mpc_lib/long_mpc.py b/openpilot/selfdrive/controls/lib/longitudinal_mpc_lib/long_mpc.py index 99d0c7ae68..de1ba0c278 100755 --- a/openpilot/selfdrive/controls/lib/longitudinal_mpc_lib/long_mpc.py +++ b/openpilot/selfdrive/controls/lib/longitudinal_mpc_lib/long_mpc.py @@ -288,7 +288,7 @@ class LongitudinalMpc: def process_lead(self, lead): v_ego = self.x0[1] - if lead is not None and lead.status: + if lead is not None and lead.present: x_lead = lead.dRel v_lead = lead.vLead a_lead = lead.aLeadK diff --git a/openpilot/selfdrive/controls/lib/longitudinal_planner.py b/openpilot/selfdrive/controls/lib/longitudinal_planner.py index f413903aa0..cf5a4b13a8 100755 --- a/openpilot/selfdrive/controls/lib/longitudinal_planner.py +++ b/openpilot/selfdrive/controls/lib/longitudinal_planner.py @@ -161,7 +161,7 @@ class LongitudinalPlanner: longitudinalPlan.accels = self.a_desired_trajectory.tolist() longitudinalPlan.jerks = self.j_desired_trajectory.tolist() - longitudinalPlan.hasLead = sm['radarState'].leadOne.status + longitudinalPlan.hasLead = sm['radarState'].leadOne.present longitudinalPlan.longitudinalPlanSource = self.mpc.source longitudinalPlan.fcw = self.fcw diff --git a/openpilot/selfdrive/controls/radard.py b/openpilot/selfdrive/controls/radard.py index 94400f3357..1474b31cf1 100755 --- a/openpilot/selfdrive/controls/radard.py +++ b/openpilot/selfdrive/controls/radard.py @@ -91,7 +91,7 @@ class Track: "vLeadK": float(self.vLeadK), "aLeadK": float(self.aLeadK), "aLeadTau": float(self.aLeadTau.x), - "status": True, + "present": True, "fcw": self.is_potential_fcw(model_prob), "modelProb": model_prob, "radar": True, @@ -151,7 +151,7 @@ def get_RadarState_from_vision(lead_msg: capnp._DynamicStructReader, v_ego: floa "aLeadTau": 0.3, "fcw": False, "modelProb": float(lead_prob), - "status": True, + "present": True, "radar": False, "radarTrackId": -1, } @@ -165,7 +165,7 @@ def get_lead(v_ego: float, ready: bool, tracks: dict[int, Track], lead_msg: capn else: track = None - lead_dict = {'status': False} + lead_dict = {'present': False} if track is not None: lead_dict = track.get_RadarState(lead_prob) elif (track is None) and ready and (lead_prob > .5): @@ -177,7 +177,7 @@ def get_lead(v_ego: float, ready: bool, tracks: dict[int, Track], lead_msg: capn closest_track = min(low_speed_tracks, key=lambda c: c.dRel) # Only choose new track if it is actually closer than the previous one - if (not lead_dict['status']) or (closest_track.dRel < lead_dict['dRel']): + if (not lead_dict['present']) or (closest_track.dRel < lead_dict['dRel']): lead_dict = closest_track.get_RadarState() return lead_dict diff --git a/openpilot/selfdrive/test/longitudinal_maneuvers/plant.py b/openpilot/selfdrive/test/longitudinal_maneuvers/plant.py index fbffde911a..733c1ab2fd 100755 --- a/openpilot/selfdrive/test/longitudinal_maneuvers/plant.py +++ b/openpilot/selfdrive/test/longitudinal_maneuvers/plant.py @@ -95,7 +95,7 @@ class Plant: lead.aLeadK = float(a_lead) # TODO use real radard logic for this lead.aLeadTau = float(_LEAD_ACCEL_TAU) - lead.status = status + lead.present = status lead.modelProb = float(prob_lead) if not self.only_lead2: radar.radarState.leadOne = lead diff --git a/openpilot/selfdrive/ui/mici/onroad/model_renderer.py b/openpilot/selfdrive/ui/mici/onroad/model_renderer.py index 0442aa2b65..adf9814364 100644 --- a/openpilot/selfdrive/ui/mici/onroad/model_renderer.py +++ b/openpilot/selfdrive/ui/mici/onroad/model_renderer.py @@ -166,7 +166,7 @@ class ModelRenderer(Widget): leads = [radar_state.leadOne, radar_state.leadTwo] for i, lead_data in enumerate(leads): - if lead_data and lead_data.status: + if lead_data and lead_data.present: d_rel, y_rel, v_rel = lead_data.dRel, lead_data.yRel, lead_data.vRel idx = self._get_path_length_idx(path_x_array, d_rel) @@ -195,7 +195,7 @@ class ModelRenderer(Widget): road_edge.projected_points = self._map_line_to_polygon(road_edge.raw_points, line_width_factor, 0.0, max_idx) # Update path using raw points - if lead and lead.status: + if lead and lead.present: lead_d = lead.dRel * 2.0 max_distance = np.clip(lead_d - min(lead_d * 0.35, 10.0), 0.0, max_distance) diff --git a/openpilot/selfdrive/ui/onroad/model_renderer.py b/openpilot/selfdrive/ui/onroad/model_renderer.py index e21ca4f271..50ff3b1c53 100644 --- a/openpilot/selfdrive/ui/onroad/model_renderer.py +++ b/openpilot/selfdrive/ui/onroad/model_renderer.py @@ -150,7 +150,7 @@ class ModelRenderer(Widget): leads = [radar_state.leadOne, radar_state.leadTwo] for i, lead_data in enumerate(leads): - if lead_data and lead_data.status: + if lead_data and lead_data.present: d_rel, y_rel, v_rel = lead_data.dRel, lead_data.yRel, lead_data.vRel idx = self._get_path_length_idx(path_x_array, d_rel) @@ -176,7 +176,7 @@ class ModelRenderer(Widget): road_edge.projected_points = self._map_line_to_polygon(road_edge.raw_points, 0.025, 0.0, max_idx, max_distance) # Update path using raw points - if lead and lead.status: + if lead and lead.present: lead_d = lead.dRel * 2.0 max_distance = np.clip(lead_d - min(lead_d * 0.35, 10.0), 0.0, max_distance) diff --git a/openpilot/tools/replay/lib/ui_helpers.py b/openpilot/tools/replay/lib/ui_helpers.py index 039dd4f235..b5fdd18025 100644 --- a/openpilot/tools/replay/lib/ui_helpers.py +++ b/openpilot/tools/replay/lib/ui_helpers.py @@ -187,7 +187,7 @@ def plot_model(m, img, calibration, top_down): def plot_lead(rs, top_down): for lead in [rs.leadOne, rs.leadTwo]: - if not lead.status: + if not lead.present: continue x = lead.dRel From d1e143ac984aec60c79917e3c4a82f3b26a3d5cf Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Tue, 14 Jul 2026 19:01:22 -0700 Subject: [PATCH 136/151] longcontrol: simplify state machine (#38337) --- openpilot/selfdrive/controls/lib/longcontrol.py | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/openpilot/selfdrive/controls/lib/longcontrol.py b/openpilot/selfdrive/controls/lib/longcontrol.py index 1132fedda6..977add1285 100644 --- a/openpilot/selfdrive/controls/lib/longcontrol.py +++ b/openpilot/selfdrive/controls/lib/longcontrol.py @@ -12,11 +12,9 @@ LongCtrlState = car.CarControl.Actuators.LongControlState def long_control_state_trans(CP, active, long_control_state, v_ego, should_stop, brake_pressed, cruise_standstill): - stopping_condition = should_stop starting_condition = (not should_stop and not cruise_standstill and not brake_pressed) - started_condition = v_ego > CP.vEgoStarting if not active: long_control_state = LongCtrlState.off @@ -25,11 +23,10 @@ def long_control_state_trans(CP, active, long_control_state, v_ego, if long_control_state == LongCtrlState.off: if not starting_condition: long_control_state = LongCtrlState.stopping + elif CP.startingState: + long_control_state = LongCtrlState.starting else: - if starting_condition and CP.startingState: - long_control_state = LongCtrlState.starting - else: - long_control_state = LongCtrlState.pid + long_control_state = LongCtrlState.pid elif long_control_state == LongCtrlState.stopping: if starting_condition and CP.startingState: @@ -38,9 +35,9 @@ def long_control_state_trans(CP, active, long_control_state, v_ego, long_control_state = LongCtrlState.pid elif long_control_state in [LongCtrlState.starting, LongCtrlState.pid]: - if stopping_condition: + if should_stop: long_control_state = LongCtrlState.stopping - elif started_condition: + elif v_ego > CP.vEgoStarting: long_control_state = LongCtrlState.pid return long_control_state From c16039e0bcc2a770bf7724cba27765cc59719122 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20R=C4=85czy?= Date: Wed, 15 Jul 2026 02:17:30 +0000 Subject: [PATCH 137/151] lagd: lower max lag (#38307) * Max lag 0.6 * Fix tests * 650ms --- openpilot/selfdrive/locationd/lagd.py | 2 +- openpilot/selfdrive/locationd/test/test_lagd.py | 13 +++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/openpilot/selfdrive/locationd/lagd.py b/openpilot/selfdrive/locationd/lagd.py index 78c673a3bd..d3c0c5195b 100755 --- a/openpilot/selfdrive/locationd/lagd.py +++ b/openpilot/selfdrive/locationd/lagd.py @@ -25,7 +25,7 @@ MIN_VEGO = 50.0 * CV.MPH_TO_MS MIN_ABS_YAW_RATE = 0.0 MAX_YAW_RATE_SANITY_CHECK = 1.0 MIN_NCC = 0.95 -MAX_LAG = 1.0 +MAX_LAG = 0.65 MIN_LAG = 0.15 MAX_LAG_STD = 0.1 MAX_LAT_ACCEL = 2.0 diff --git a/openpilot/selfdrive/locationd/test/test_lagd.py b/openpilot/selfdrive/locationd/test/test_lagd.py index af401187f5..128c19332f 100644 --- a/openpilot/selfdrive/locationd/test/test_lagd.py +++ b/openpilot/selfdrive/locationd/test/test_lagd.py @@ -6,7 +6,7 @@ import pytest from openpilot.cereal import messaging, log from opendbc.car.structs import car from openpilot.selfdrive.locationd.lagd import LateralLagEstimator, retrieve_initial_lag, masked_normalized_cross_correlation, \ - BLOCK_NUM_NEEDED, BLOCK_SIZE, MIN_OKAY_WINDOW_SEC, VERSION + BLOCK_NUM_NEEDED, BLOCK_SIZE, MIN_OKAY_WINDOW_SEC, VERSION, MIN_LAG, MAX_LAG from openpilot.selfdrive.test.process_replay.migration import migrate, migrate_carParams from openpilot.selfdrive.locationd.test.test_locationd_scenarios import TEST_ROUTE from openpilot.common.params import Params @@ -15,6 +15,7 @@ from openpilot.common.hardware import PC MAX_ERR_FRAMES = 1 DT = 0.05 +LAGD_MIN_LAG_FRAMES, LAGD_MAX_LAG_FRAMES = int(round(MIN_LAG / DT)), int(round(MAX_LAG / DT)) def process_messages(estimator, lag_frames, n_frames, vego=25.0, rejection_threshold=0.0): @@ -103,7 +104,7 @@ class TestLagd: assert np.argmax(corr) in range(lag_frames - MAX_ERR_FRAMES, lag_frames + MAX_ERR_FRAMES + 1) def test_empty_estimator(self): - mocked_CP = car.CarParams(steerActuatorDelay=0.8) + mocked_CP = car.CarParams(steerActuatorDelay=0.5) estimator = LateralLagEstimator(mocked_CP, DT) msg = estimator.get_msg(True) assert msg.liveDelay.status == 'unestimated' @@ -113,9 +114,9 @@ class TestLagd: assert msg.liveDelay.calPerc == 0 def test_estimator_basics(self, subtests): - for lag_frames in range(3, 10): + for lag_frames in range(LAGD_MIN_LAG_FRAMES, LAGD_MAX_LAG_FRAMES - 1): with subtests.test(msg=f"lag_frames={lag_frames}"): - mocked_CP = car.CarParams(steerActuatorDelay=0.8) + mocked_CP = car.CarParams(steerActuatorDelay=0.5) estimator = LateralLagEstimator(mocked_CP, DT, min_recovery_buffer_sec=0.0, min_yr=0.0) process_messages(estimator, lag_frames, int(MIN_OKAY_WINDOW_SEC / DT) + BLOCK_NUM_NEEDED * BLOCK_SIZE) msg = estimator.get_msg(True) @@ -127,7 +128,7 @@ class TestLagd: assert msg.liveDelay.calPerc == 100 def test_estimator_masking(self): - mocked_CP, lag_frames = car.CarParams(steerActuatorDelay=0.8), random.randint(3, 19) + mocked_CP, lag_frames = car.CarParams(steerActuatorDelay=0.5), random.randint(LAGD_MIN_LAG_FRAMES, LAGD_MAX_LAG_FRAMES - 1) estimator = LateralLagEstimator(mocked_CP, DT, min_recovery_buffer_sec=0.0, min_yr=0.0, min_valid_block_count=1) process_messages(estimator, lag_frames, (int(MIN_OKAY_WINDOW_SEC / DT) + BLOCK_SIZE) * 2, rejection_threshold=0.4) msg = estimator.get_msg(True) @@ -137,7 +138,7 @@ class TestLagd: @pytest.mark.skipif(PC, reason="only on device") def test_estimator_performance(self): - mocked_CP = car.CarParams(steerActuatorDelay=0.8) + mocked_CP = car.CarParams(steerActuatorDelay=0.5) estimator = LateralLagEstimator(mocked_CP, DT) ds = [] From 45661ee8c0c4179788a6a5d75ef53923cecab854 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Tue, 14 Jul 2026 19:24:16 -0700 Subject: [PATCH 138/151] tmp disable ui_report --- .github/workflows/ui_preview.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ui_preview.yaml b/.github/workflows/ui_preview.yaml index 20927740bb..d084bba7c0 100644 --- a/.github/workflows/ui_preview.yaml +++ b/.github/workflows/ui_preview.yaml @@ -25,7 +25,8 @@ env: jobs: preview: - if: github.repository == 'commaai/openpilot' + if: false # tmp disable due to GH API rate limiting flakiness + #if: github.repository == 'commaai/openpilot' name: preview runs-on: ubuntu-latest timeout-minutes: 20 From a9ffebe96e88a664ce71e76a86f7b3b6719eb3f4 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Tue, 14 Jul 2026 20:40:15 -0700 Subject: [PATCH 139/151] plannerd: check all services for validity (#38341) * longitudinal planner: carControl must be valid * plannerd: check all services for validity --- openpilot/selfdrive/controls/lib/longitudinal_planner.py | 2 +- openpilot/selfdrive/controls/plannerd.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/openpilot/selfdrive/controls/lib/longitudinal_planner.py b/openpilot/selfdrive/controls/lib/longitudinal_planner.py index cf5a4b13a8..884b4d00bc 100755 --- a/openpilot/selfdrive/controls/lib/longitudinal_planner.py +++ b/openpilot/selfdrive/controls/lib/longitudinal_planner.py @@ -150,7 +150,7 @@ class LongitudinalPlanner: def publish(self, sm, pm): plan_send = messaging.new_message('longitudinalPlan') - plan_send.valid = sm.all_checks(service_list=['carState', 'controlsState', 'selfdriveState', 'radarState']) + plan_send.valid = sm.all_checks() longitudinalPlan = plan_send.longitudinalPlan longitudinalPlan.modelMonoTime = sm.logMonoTime['modelV2'] diff --git a/openpilot/selfdrive/controls/plannerd.py b/openpilot/selfdrive/controls/plannerd.py index e8ee4395b8..60a6525853 100755 --- a/openpilot/selfdrive/controls/plannerd.py +++ b/openpilot/selfdrive/controls/plannerd.py @@ -30,7 +30,7 @@ def main(): ldw.update(sm.frame, sm['modelV2'], sm['carState'], sm['carControl']) msg = messaging.new_message('driverAssistance') - msg.valid = sm.all_checks(['carState', 'carControl', 'modelV2', 'liveParameters']) + msg.valid = sm.all_checks() msg.driverAssistance.leftLaneDeparture = ldw.left msg.driverAssistance.rightLaneDeparture = ldw.right pm.send('driverAssistance', msg) From d275c65f7501fe695331e864c78a5ddf7c8e6819 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Tue, 14 Jul 2026 23:53:52 -0700 Subject: [PATCH 140/151] fix ui.py --- openpilot/tools/replay/ui.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpilot/tools/replay/ui.py b/openpilot/tools/replay/ui.py index 932b3f9b8c..f5bd3f1d78 100755 --- a/openpilot/tools/replay/ui.py +++ b/openpilot/tools/replay/ui.py @@ -176,7 +176,7 @@ def ui_thread(addr): plot_arr[-1, name_to_arr_idx['gas']] = sm['carState'].gasDEPRECATED # TODO gas is deprecated plot_arr[-1, name_to_arr_idx['computer_gas']] = np.clip(sm['carControl'].actuators.accel / 4.0, 0.0, 1.0) - plot_arr[-1, name_to_arr_idx['user_brake']] = sm['carState'].brake + plot_arr[-1, name_to_arr_idx['user_brake']] = sm['carState'].brakePressed plot_arr[-1, name_to_arr_idx['steer_torque']] = sm['carControl'].actuators.torque * ANGLE_SCALE # TODO brake is deprecated plot_arr[-1, name_to_arr_idx['computer_brake']] = np.clip(-sm['carControl'].actuators.accel / 4.0, 0.0, 1.0) From eee13472ce780f852cd13b8cf501560d71b22c12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Harald=20Sch=C3=A4fer?= Date: Wed, 15 Jul 2026 10:31:03 -0700 Subject: [PATCH 141/151] longitudinal: add e2e flag to tuning report (#38345) --- .../mpc_longitudinal_tuning_report.py | 25 ++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/openpilot/tools/longitudinal_maneuvers/mpc_longitudinal_tuning_report.py b/openpilot/tools/longitudinal_maneuvers/mpc_longitudinal_tuning_report.py index ae3fee7355..6b711a0847 100644 --- a/openpilot/tools/longitudinal_maneuvers/mpc_longitudinal_tuning_report.py +++ b/openpilot/tools/longitudinal_maneuvers/mpc_longitudinal_tuning_report.py @@ -25,7 +25,7 @@ def get_html_from_results(results, labels, AXIS): plt.close(fig) return fig_buffer.getvalue() + '
' -def generate_mpc_tuning_report(): +def generate_mpc_tuning_report(e2e=False): htmls = [] results = {} @@ -42,6 +42,7 @@ def generate_mpc_tuning_report(): cruise_values=[100, 100], prob_lead_values=[1.0, 1.0], breakpoints=[1., 11], + e2e=e2e, ) valid, results[lead_accel] = man.evaluate() labels.append(f'{lead_accel} m/s^2 lead acceleration') @@ -63,6 +64,7 @@ def generate_mpc_tuning_report(): initial_distance_lead=140., speed_lead_values=[0.0, 0.], breakpoints=[0., 30.], + e2e=e2e, ) valid, results[speed] = man.evaluate() labels.append(f'{speed} m/s approach speed') @@ -85,6 +87,7 @@ def generate_mpc_tuning_report(): initial_distance_lead=desired_follow_distance(speed, speed), speed_lead_values=[speed, speed, speed - oscil, speed + oscil, speed - oscil, speed + oscil, speed - oscil], breakpoints=[0.,2., 5, 8, 15, 18, 25.], + e2e=e2e, ) valid, results[oscil] = man.evaluate() labels.append(f'{oscil} m/s oscillation size') @@ -112,6 +115,7 @@ def generate_mpc_tuning_report(): initial_distance_lead=desired_follow_distance(speed, speed), speed_lead_values=lead_speeds, breakpoints=bps, + e2e=e2e, ) valid, results[oscil] = man.evaluate() labels.append(f'{oscil} m/s oscillation size') @@ -134,6 +138,7 @@ def generate_mpc_tuning_report(): initial_distance_lead=distance, speed_lead_values=[30.0], breakpoints=[0.], + e2e=e2e, ) valid, results[distance] = man.evaluate() labels.append(f'{distance} m initial distance') @@ -155,6 +160,7 @@ def generate_mpc_tuning_report(): initial_distance_lead=distance, speed_lead_values=[20.0], breakpoints=[0.], + e2e=e2e, ) valid, results[distance] = man.evaluate() labels.append(f'{distance} m initial distance') @@ -177,6 +183,7 @@ def generate_mpc_tuning_report(): initial_distance_lead=60.0, speed_lead_values=[30.0, 30.0, 0.0], breakpoints=[0., 5., 5 + stop_time], + e2e=e2e, ) valid, results[stop_time] = man.evaluate() labels.append(f'{stop_time} seconds stop time') @@ -200,6 +207,7 @@ def generate_mpc_tuning_report(): speed_lead_values=[speed, speed, speed], prob_lead_values=[0.0, 0.0, 1.0], breakpoints=[0., 5.0, 5.01], + e2e=e2e, ) valid, results[speed] = man.evaluate() labels.append(f'{speed} m/s speed') @@ -222,6 +230,7 @@ def generate_mpc_tuning_report(): speed_lead_values=[0.0, 0.0, speed], prob_lead_values=[1.0, 1.0, 1.0], breakpoints=[0., 1.0, speed/2], + e2e=e2e, ) valid, results[speed] = man.evaluate() labels.append(f'{speed} m/s speed') @@ -245,6 +254,7 @@ def generate_mpc_tuning_report(): cruise_values=[0.0, speed], prob_lead_values=[0.0, 0.0], breakpoints=[1., 1.01], + e2e=e2e, ) valid, results[speed] = man.evaluate() labels.append(f'{speed} m/s speed') @@ -268,6 +278,7 @@ def generate_mpc_tuning_report(): cruise_values=[speed, 10.0], prob_lead_values=[0.0, 0.0], breakpoints=[1., 1.01], + e2e=e2e, ) valid, results[speed] = man.evaluate() labels.append(f'{speed} m/s speed') @@ -279,12 +290,14 @@ def generate_mpc_tuning_report(): return htmls if __name__ == '__main__': - htmls = generate_mpc_tuning_report() + e2e = '--e2e' in sys.argv + file_name = 'long_mpc_tune_report.html' + for arg in sys.argv[1:]: + if not arg.startswith('-'): + file_name = arg + break - if len(sys.argv) < 2: - file_name = 'long_mpc_tune_report.html' - else: - file_name = sys.argv[1] + htmls = generate_mpc_tuning_report(e2e=e2e) with open(file_name, 'w') as f: f.write(markdown.markdown('# MPC longitudinal tuning report')) From ec72ee096db000287290042dec4b24c6461c1afe Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Wed, 15 Jul 2026 11:52:31 -0700 Subject: [PATCH 142/151] cleanup unused radar fields (#38346) * cleanup unused radar fields * bump opendbc * this is nice for debugging * bring that back too * bring these back * more revert --- opendbc_repo | 2 +- openpilot/cereal/log.capnp | 24 +++++++++---------- openpilot/selfdrive/controls/radard.py | 14 +++-------- .../test/longitudinal_maneuvers/plant.py | 2 +- .../test/process_replay/migration.py | 2 -- openpilot/tools/replay/lib/ui_helpers.py | 2 +- 6 files changed, 18 insertions(+), 28 deletions(-) diff --git a/opendbc_repo b/opendbc_repo index 8c0b1367c5..402335de16 160000 --- a/opendbc_repo +++ b/opendbc_repo @@ -1 +1 @@ -Subproject commit 8c0b1367c5178f919c05ae58a1dcf7439ed3eb37 +Subproject commit 402335de16dc75946ac4727b1513156411bdf3e0 diff --git a/openpilot/cereal/log.capnp b/openpilot/cereal/log.capnp index c7923bd373..722213daa3 100644 --- a/openpilot/cereal/log.capnp +++ b/openpilot/cereal/log.capnp @@ -704,8 +704,7 @@ struct UsbState { } struct RadarState @0x9a185389d6fdd05f { - mdMonoTime @6 :UInt64; - carStateMonoTime @11 :UInt64; + mdMonoTime @6 :UInt64; # for debugging radarErrors @13 :Car.RadarData.Error; leadOne @3 :LeadData; @@ -715,21 +714,21 @@ struct RadarState @0x9a185389d6fdd05f { dRel @0 :Float32; yRel @1 :Float32; vRel @2 :Float32; - aRel @3 :Float32; vLead @4 :Float32; - dPath @6 :Float32; - vLat @7 :Float32; - vLeadK @8 :Float32; - aLeadK @9 :Float32; - fcw @10 :Bool; + vLeadK @8 :Float32; # kalman-filtered lead speed + aLeadK @9 :Float32; # kalman-filtered lead accel present @11 :Bool; aLeadTau @12 :Float32; modelProb @13 :Float32; - radar @14 :Bool; - radarTrackId @15 :Int32 = -1; + radar @14 :Bool; # true if lead is radar-matched (vs vision-only) + radarTrackId @15 :Int32 = -1; # for debugging deprecated :group { + aRel @3 :Float32; aLead @5 :Float32; + dPath @6 :Float32; + vLat @7 :Float32; + fcw @10 :Bool; } } @@ -742,6 +741,7 @@ struct RadarState @0x9a185389d6fdd05f { calPerc @9 :Int8; canMonoTimes @10 :List(UInt64); cumLagMs @5 :Float32; + carStateMonoTime @11 :UInt64; radarErrors @12 :List(Car.RadarData.ErrorDEPRECATED); } } @@ -1041,7 +1041,6 @@ struct ModelDataV2 { roadEdgeStds @14 :List(Float32); # predicted lead cars - leads @11 :List(LeadDataV2); leadsV3 @18 :List(LeadDataV3); meta @12 :MetaData; @@ -1051,8 +1050,9 @@ struct ModelDataV2 { action @26: Action; lateralPlannerSolutionDEPRECATED @25: Deprecated.LateralPlannerSolution; + leadsDEPRECATED @11 :List(LeadDataV2DEPRECATED); - struct LeadDataV2 { + struct LeadDataV2DEPRECATED { prob @0 :Float32; # probability that car is your lead at time t t @1 :Float32; diff --git a/openpilot/selfdrive/controls/radard.py b/openpilot/selfdrive/controls/radard.py index 1474b31cf1..30824c07b8 100755 --- a/openpilot/selfdrive/controls/radard.py +++ b/openpilot/selfdrive/controls/radard.py @@ -23,7 +23,6 @@ SPEED, ACCEL = 0, 1 # Kalman filter states enum # stationary qualification parameters V_EGO_STATIONARY = 4. # no stationary object flag below this speed -RADAR_TO_CENTER = 2.7 # (deprecated) RADAR is ~ 2.7m ahead from center of car RADAR_TO_CAMERA = 1.52 # RADAR is ~ 1.5m ahead from center of mesh frame @@ -59,13 +58,12 @@ class Track: self.K_K = kalman_params.K self.kf = KF1D([[v_lead], [0.0]], self.K_A, self.K_C, self.K_K) - def update(self, d_rel: float, y_rel: float, v_rel: float, v_lead: float, measured: float): + def update(self, d_rel: float, y_rel: float, v_rel: float, v_lead: float): # relative values, copy self.dRel = d_rel # LONG_DIST self.yRel = y_rel # -LAT_DIST self.vRel = v_rel # REL_SPEED self.vLead = v_lead - self.measured = measured # measured or estimate # computed velocity and accelerations if self.cnt > 0: @@ -92,7 +90,6 @@ class Track: "aLeadK": float(self.aLeadK), "aLeadTau": float(self.aLeadTau.x), "present": True, - "fcw": self.is_potential_fcw(model_prob), "modelProb": model_prob, "radar": True, "radarTrackId": self.identifier, @@ -103,9 +100,6 @@ class Track: # Radar points closer than 0.75, are almost always glitches on toyota radars return abs(self.yRel) < 1.0 and (v_ego < V_EGO_STATIONARY) and (0.75 < self.dRel < 25) - def is_potential_fcw(self, model_prob: float): - return model_prob > .9 - def __str__(self): ret = f"x: {self.dRel:4.1f} y: {self.yRel:4.1f} v: {self.vRel:4.1f} a: {self.aLeadK:4.1f}" return ret @@ -149,7 +143,6 @@ def get_RadarState_from_vision(lead_msg: capnp._DynamicStructReader, v_ego: floa "vLeadK": float(v_ego + lead_v_rel_pred), "aLeadK": float(lead_msg.a[0]), "aLeadTau": 0.3, - "fcw": False, "modelProb": float(lead_prob), "present": True, "radar": False, @@ -209,7 +202,7 @@ class RadarD: self.v_ego_hist.append(self.v_ego) self.last_v_ego_frame = sm.recv_frame['carState'] - ar_pts = {pt.trackId: [pt.dRel, pt.yRel, pt.vRel, pt.measured] for pt in rr.points} + ar_pts = {pt.trackId: [pt.dRel, pt.yRel, pt.vRel] for pt in rr.points} # *** remove missing points from meta data *** for ids in list(self.tracks.keys()): @@ -226,14 +219,13 @@ class RadarD: # create the track if it doesn't exist or it's a new track if ids not in self.tracks: self.tracks[ids] = Track(ids, v_lead, self.kalman_params) - self.tracks[ids].update(rpt[0], rpt[1], rpt[2], v_lead, rpt[3]) + self.tracks[ids].update(rpt[0], rpt[1], rpt[2], v_lead) # *** publish radarState *** self.radar_state_valid = sm.all_checks() self.radar_state = log.RadarState.new_message() self.radar_state.mdMonoTime = sm.logMonoTime['modelV2'] self.radar_state.radarErrors = rr.errors - self.radar_state.carStateMonoTime = sm.logMonoTime['carState'] if len(sm['modelV2'].velocity.x): model_v_ego = sm['modelV2'].velocity.x[0] diff --git a/openpilot/selfdrive/test/longitudinal_maneuvers/plant.py b/openpilot/selfdrive/test/longitudinal_maneuvers/plant.py index 733c1ab2fd..23ccbdb85d 100755 --- a/openpilot/selfdrive/test/longitudinal_maneuvers/plant.py +++ b/openpilot/selfdrive/test/longitudinal_maneuvers/plant.py @@ -89,7 +89,6 @@ class Plant: lead.dRel = float(d_rel) lead.yRel = 0.0 lead.vRel = float(v_rel) - lead.aRel = float(a_lead - self.acceleration) lead.vLead = float(v_lead) lead.vLeadK = float(v_lead) lead.aLeadK = float(a_lead) @@ -97,6 +96,7 @@ class Plant: lead.aLeadTau = float(_LEAD_ACCEL_TAU) lead.present = status lead.modelProb = float(prob_lead) + lead.radar = True if not self.only_lead2: radar.radarState.leadOne = lead radar.radarState.leadTwo = lead diff --git a/openpilot/selfdrive/test/process_replay/migration.py b/openpilot/selfdrive/test/process_replay/migration.py index 0045fa8a87..a6e466bef5 100644 --- a/openpilot/selfdrive/test/process_replay/migration.py +++ b/openpilot/selfdrive/test/process_replay/migration.py @@ -175,8 +175,6 @@ def migrate_liveTracks(msgs): pt.dRel = track.dRel pt.yRel = track.yRel pt.vRel = track.vRel - pt.aRel = track.aRel - pt.measured = True pts.append(pt) new_msg.liveTracks.points = pts diff --git a/openpilot/tools/replay/lib/ui_helpers.py b/openpilot/tools/replay/lib/ui_helpers.py index b5fdd18025..6a3e8c20ed 100644 --- a/openpilot/tools/replay/lib/ui_helpers.py +++ b/openpilot/tools/replay/lib/ui_helpers.py @@ -201,7 +201,7 @@ def maybe_update_radar_points(lt, lid_overlay): if lt is not None: ar_pts = {} for track in lt: - ar_pts[track.trackId] = [track.dRel, track.yRel, track.vRel, track.aRel] + ar_pts[track.trackId] = [track.dRel, track.yRel, track.vRel] for pt in ar_pts.values(): # negative here since radar is left positive px, py = to_topdown_pt(pt[0], -pt[1]) From 2b1fd89064bcc97e9eb644ad777a634ce5811024 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Wed, 15 Jul 2026 12:01:46 -0700 Subject: [PATCH 143/151] annotate radar fields (#38347) --- openpilot/cereal/log.capnp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/openpilot/cereal/log.capnp b/openpilot/cereal/log.capnp index 722213daa3..8ce9f868af 100644 --- a/openpilot/cereal/log.capnp +++ b/openpilot/cereal/log.capnp @@ -711,15 +711,15 @@ struct RadarState @0x9a185389d6fdd05f { leadTwo @4 :LeadData; struct LeadData { - dRel @0 :Float32; - yRel @1 :Float32; - vRel @2 :Float32; - vLead @4 :Float32; + dRel @0 :Float32; # m from the front bumper of the car + yRel @1 :Float32; # m in car frame, left positive + vRel @2 :Float32; # m/s relative longitudinal speed + vLead @4 :Float32; # m/s absolute lead speed vLeadK @8 :Float32; # kalman-filtered lead speed aLeadK @9 :Float32; # kalman-filtered lead accel - present @11 :Bool; - aLeadTau @12 :Float32; - modelProb @13 :Float32; + present @11 :Bool; # true if a lead is present + aLeadTau @12 :Float32; # lead accel time constant + modelProb @13 :Float32; # vision model lead probability radar @14 :Bool; # true if lead is radar-matched (vs vision-only) radarTrackId @15 :Int32 = -1; # for debugging From 79b79edd2fdc60544905360f24361241c5985df1 Mon Sep 17 00:00:00 2001 From: Jason Wen Date: Wed, 15 Jul 2026 17:02:34 -0400 Subject: [PATCH 144/151] MADS: add tests and prevent re-enable at standstill in Pause mode (#1871) * tests * lateral mismatch * no unittest oops --- sunnypilot/mads/mads.py | 2 +- .../mads/tests/test_mads_steering_mode.py | 242 ++++++++++++++++++ 2 files changed, 243 insertions(+), 1 deletion(-) create mode 100644 sunnypilot/mads/tests/test_mads_steering_mode.py diff --git a/sunnypilot/mads/mads.py b/sunnypilot/mads/mads.py index bd9c8d78ff..b0a90f82b5 100644 --- a/sunnypilot/mads/mads.py +++ b/sunnypilot/mads/mads.py @@ -69,7 +69,7 @@ class ModularAssistiveDrivingSystem: return False def should_silent_lkas_enable(self, CS: structs.CarState) -> bool: - if self.steering_mode_on_brake == MadsSteeringModeOnBrake.PAUSE and self.pedal_pressed_non_gas_pressed(CS): + if self.steering_mode_on_brake == MadsSteeringModeOnBrake.PAUSE and (CS.brakePressed or CS.regenBraking or self.pedal_pressed_non_gas_pressed(CS)): return False if self.events_sp.contains_in_list(GEARS_ALLOW_PAUSED_SILENT): diff --git a/sunnypilot/mads/tests/test_mads_steering_mode.py b/sunnypilot/mads/tests/test_mads_steering_mode.py new file mode 100644 index 0000000000..8765324cfd --- /dev/null +++ b/sunnypilot/mads/tests/test_mads_steering_mode.py @@ -0,0 +1,242 @@ +""" +Copyright (c) 2021-, Haibin Wen, sunnypilot, and a number of other contributors. + +This file is part of sunnypilot and is licensed under the MIT License. +See the LICENSE.md file in the root directory for more details. +""" + +import pytest + +from cereal import log, custom +from opendbc.car import structs +from openpilot.selfdrive.selfdrived.events import Events +from openpilot.sunnypilot.selfdrive.selfdrived.events import EventsSP +from openpilot.sunnypilot.mads.helpers import MadsSteeringModeOnBrake, read_steering_mode_param +from openpilot.sunnypilot.mads.mads import ModularAssistiveDrivingSystem +from opendbc.sunnypilot.car.tesla.values import TeslaFlagsSP + +State = custom.ModularAssistiveDrivingSystem.ModularAssistiveDrivingSystemState +EventName = log.OnroadEvent.EventName +EventNameSP = custom.OnroadEventSP.EventName +SafetyModel = structs.CarParams.SafetyModel + + +def make_car_state(brake_pressed=False, regen_braking=False, standstill=False, v_ego=0.0): + cs = structs.CarState() + cs.brakePressed = brake_pressed + cs.regenBraking = regen_braking + cs.standstill = standstill + cs.vEgo = v_ego + cs.cruiseState.available = True + return cs + + +def make_panda_state(mocker, controls_allowed_lateral=True): + ps = mocker.MagicMock() + ps.controlsAllowedLateral = controls_allowed_lateral + ps.safetyModel = SafetyModel.hyundai + return ps + + +def make_mads(mocker, steering_mode): + sd = mocker.MagicMock() + sd.CP = structs.CarParams() + sd.CP.brand = "hyundai" + sd.CP_SP = structs.CarParamsSP() + sd.params = mocker.MagicMock() + sd.params.get_bool = mocker.MagicMock(side_effect=lambda k: { + "Mads": True, "MadsMainCruiseAllowed": False, + "DisengageOnAccelerator": True, "MadsUnifiedEngagementMode": False, + }.get(k, False)) + sd.params.get = mocker.MagicMock(return_value=steering_mode) + sd.events = Events() + sd.events_sp = EventsSP() + sd.enabled = False + sd.enabled_prev = False + sd.initialized = True + sd.CS_prev = make_car_state() + sd.sm = {'pandaStates': [make_panda_state(mocker)]} + sd.state_machine = mocker.MagicMock() + + mads = ModularAssistiveDrivingSystem(sd) + mads.enabled_toggle = True + mads.steering_mode_on_brake = steering_mode + return mads, sd + + +def run_frames(mads, sd, cs, n=1): + for _ in range(n): + mads.update(cs) + sd.CS_prev = cs + sd.events.clear() + sd.events_sp.clear() + + +# should_silent_lkas_enable across all modes + +class TestShouldSilentLkasEnable: + @pytest.mark.parametrize("brake,regen", [(True, False), (False, True)]) + def test_pause_blocks_reenable_on_braking_at_standstill(self, mocker, brake, regen): + mads, _ = make_mads(mocker, MadsSteeringModeOnBrake.PAUSE) + cs = make_car_state(brake_pressed=brake, regen_braking=regen, standstill=True) + assert mads.should_silent_lkas_enable(cs) is False + + def test_pause_allows_reenable_on_brake_release(self, mocker): + mads, _ = make_mads(mocker, MadsSteeringModeOnBrake.PAUSE) + cs = make_car_state(standstill=True) + assert mads.should_silent_lkas_enable(cs) is True + + def test_remain_active_ignores_brake(self, mocker): + mads, _ = make_mads(mocker, MadsSteeringModeOnBrake.REMAIN_ACTIVE) + cs = make_car_state(brake_pressed=True, standstill=True) + assert mads.should_silent_lkas_enable(cs) is True + + def test_disengage_ignores_brake_for_silent_enable(self, mocker): + mads, _ = make_mads(mocker, MadsSteeringModeOnBrake.DISENGAGE) + cs = make_car_state(brake_pressed=True, standstill=True) + assert mads.should_silent_lkas_enable(cs) is True + + +# pause + +class TestPauseMode: + def test_stays_paused_at_standstill_brake_held(self, mocker): + mads, sd = make_mads(mocker, MadsSteeringModeOnBrake.PAUSE) + mads.state_machine.state = State.enabled + mads.enabled = True + mads.active = True + + sd.events.add(EventName.pedalPressed) + run_frames(mads, sd, make_car_state(brake_pressed=True, v_ego=15.0)) + assert mads.state_machine.state == State.paused + + sd.sm['pandaStates'] = [make_panda_state(mocker, False)] + run_frames(mads, sd, make_car_state(brake_pressed=True, standstill=True), n=250) + assert mads.state_machine.state == State.paused + + def test_resumes_on_brake_release_at_standstill(self, mocker): + mads, sd = make_mads(mocker, MadsSteeringModeOnBrake.PAUSE) + mads.state_machine.state = State.paused + mads.enabled = True + mads.active = False + + run_frames(mads, sd, make_car_state(standstill=True)) + assert mads.state_machine.state == State.enabled + + def test_full_cycle_moving_to_standstill(self, mocker): + mads, sd = make_mads(mocker, MadsSteeringModeOnBrake.PAUSE) + mads.state_machine.state = State.enabled + mads.enabled = True + mads.active = True + + sd.events.add(EventName.pedalPressed) + run_frames(mads, sd, make_car_state(brake_pressed=True, v_ego=15.0)) + assert mads.state_machine.state == State.paused + + sd.sm['pandaStates'] = [make_panda_state(mocker, False)] + run_frames(mads, sd, make_car_state(brake_pressed=True, standstill=True), n=250) + assert mads.state_machine.state == State.paused + + sd.sm['pandaStates'] = [make_panda_state(mocker, True)] + run_frames(mads, sd, make_car_state(standstill=True)) + assert mads.state_machine.state == State.enabled + + +# disengage + +class TestDisengageMode: + def test_brake_while_enabled_disables(self, mocker): + mads, sd = make_mads(mocker, MadsSteeringModeOnBrake.DISENGAGE) + mads.state_machine.state = State.enabled + mads.enabled = True + mads.active = True + + sd.events.add(EventName.pedalPressed) + run_frames(mads, sd, make_car_state(brake_pressed=True, v_ego=10.0)) + assert mads.state_machine.state == State.disabled + + def test_brake_sends_lkas_disable_when_enabled(self, mocker): + mads, sd = make_mads(mocker, MadsSteeringModeOnBrake.DISENGAGE) + mads.state_machine.state = State.enabled + mads.enabled = True + mads.active = True + + sd.events.add(EventName.pedalPressed) + mads.update_events(make_car_state(brake_pressed=True, v_ego=5.0)) + assert sd.events_sp.has(EventNameSP.lkasDisable) + + +# remain active + +class TestRemainActiveMode: + def test_brake_does_not_pause_or_disable(self, mocker): + mads, sd = make_mads(mocker, MadsSteeringModeOnBrake.REMAIN_ACTIVE) + mads.state_machine.state = State.enabled + mads.enabled = True + mads.active = True + + sd.events.add(EventName.pedalPressed) + run_frames(mads, sd, make_car_state(brake_pressed=True, v_ego=10.0)) + assert mads.state_machine.state == State.enabled + + +# lateral mismatch counter + +class TestLateralMismatchCounter: + def test_no_accumulation_while_paused(self, mocker): + mads, sd = make_mads(mocker, MadsSteeringModeOnBrake.PAUSE) + mads.state_machine.state = State.paused + mads.enabled = True + mads.active = False + sd.sm['pandaStates'] = [make_panda_state(mocker, False)] + + run_frames(mads, sd, make_car_state(brake_pressed=True, standstill=True), n=250) + assert mads.lateral_mismatch_counter == 0 + + def test_accumulates_when_active_and_panda_disagrees(self, mocker): + mads, sd = make_mads(mocker, MadsSteeringModeOnBrake.PAUSE) + mads.enabled = True + mads.active = True + sd.sm['pandaStates'] = [make_panda_state(mocker, False)] + + for _ in range(200): + mads.data_sample() + assert mads.lateral_mismatch_counter == 200 + + +# brand restrictions + +class TestBrandSteeringModeRestrictions: + def test_rivian_forced_to_disengage(self, mocker): + CP = structs.CarParams() + CP.brand = "rivian" + CP_SP = structs.CarParamsSP() + params = mocker.MagicMock() + assert read_steering_mode_param(CP, CP_SP, params) == MadsSteeringModeOnBrake.DISENGAGE + params.get.assert_not_called() + + def test_tesla_without_vehicle_bus_forced_to_disengage(self, mocker): + CP = structs.CarParams() + CP.brand = "tesla" + CP_SP = structs.CarParamsSP() + CP_SP.flags = 0 + params = mocker.MagicMock() + assert read_steering_mode_param(CP, CP_SP, params) == MadsSteeringModeOnBrake.DISENGAGE + + def test_tesla_with_vehicle_bus_uses_param(self, mocker): + CP = structs.CarParams() + CP.brand = "tesla" + CP_SP = structs.CarParamsSP() + CP_SP.flags = TeslaFlagsSP.HAS_VEHICLE_BUS + params = mocker.MagicMock() + params.get = mocker.MagicMock(return_value=MadsSteeringModeOnBrake.REMAIN_ACTIVE) + assert read_steering_mode_param(CP, CP_SP, params) == MadsSteeringModeOnBrake.REMAIN_ACTIVE + + @pytest.mark.parametrize("brand", ["hyundai", "toyota", "honda", "gm"]) + def test_other_brands_use_param(self, mocker, brand): + CP = structs.CarParams() + CP.brand = brand + CP_SP = structs.CarParamsSP() + params = mocker.MagicMock() + params.get = mocker.MagicMock(return_value=MadsSteeringModeOnBrake.REMAIN_ACTIVE) + assert read_steering_mode_param(CP, CP_SP, params) == MadsSteeringModeOnBrake.REMAIN_ACTIVE From 48a5bdc8e4a06dd0fd409c1fa22eb67d8531416f Mon Sep 17 00:00:00 2001 From: Jason Wen Date: Wed, 15 Jul 2026 17:18:14 -0400 Subject: [PATCH 145/151] Revert "msgq: point back to comma's" (#1874) * Revert "msgq: point back to comma's (#1498)" This reverts commit 04eac60983141a4a615bda33b37515f5d8fa1c51. * point --- .gitmodules | 2 +- msgq_repo | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitmodules b/.gitmodules index 5c5d72a7dc..e2088276e2 100644 --- a/.gitmodules +++ b/.gitmodules @@ -6,7 +6,7 @@ url = https://github.com/sunnypilot/opendbc.git [submodule "msgq"] path = msgq_repo - url = https://github.com/commaai/msgq.git + url = https://github.com/sunnypilot/msgq.git [submodule "rednose_repo"] path = rednose_repo url = https://github.com/commaai/rednose.git diff --git a/msgq_repo b/msgq_repo index 9beb84af67..3e3611ee2d 160000 --- a/msgq_repo +++ b/msgq_repo @@ -1 +1 @@ -Subproject commit 9beb84af67527f7b6bfee349dcbe3dbb8d4f4789 +Subproject commit 3e3611ee2d485ed5b87ac233ee126729f22ad79f From db99c8e5a6ed75440769fe800edb11b7b63e463e Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Wed, 15 Jul 2026 15:39:56 -0700 Subject: [PATCH 146/151] op: add `-u` to scons command line (#38348) --- tools/op.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tools/op.sh b/tools/op.sh index cde29efd8c..1ee7b232b0 100755 --- a/tools/op.sh +++ b/tools/op.sh @@ -311,8 +311,7 @@ function op_build() { # needed on AGNOS to not run out of memory op_run_command openpilot/system/manager/build.py else - # scons is fine on PC - op_run_command scons "$@" + op_run_command scons -u "$@" fi } From 680dd7cf3bcd62362830f6f4993e3ed2dcb9b474 Mon Sep 17 00:00:00 2001 From: Daniel Koepping Date: Wed, 15 Jul 2026 16:52:25 -0700 Subject: [PATCH 147/151] bump opendbc (#38352) --- opendbc_repo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opendbc_repo b/opendbc_repo index 402335de16..f95568e03c 160000 --- a/opendbc_repo +++ b/opendbc_repo @@ -1 +1 @@ -Subproject commit 402335de16dc75946ac4727b1513156411bdf3e0 +Subproject commit f95568e03cc5de650b7935c18ac56ee347caaae2 From 41886a90dac704365d47d8c3a65ad23da420339e Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Wed, 15 Jul 2026 18:40:08 -0700 Subject: [PATCH 148/151] rm redundant params tests --- openpilot/common/tests/test_params.cc | 27 --------------------------- 1 file changed, 27 deletions(-) delete mode 100644 openpilot/common/tests/test_params.cc diff --git a/openpilot/common/tests/test_params.cc b/openpilot/common/tests/test_params.cc deleted file mode 100644 index f8d6c79f55..0000000000 --- a/openpilot/common/tests/test_params.cc +++ /dev/null @@ -1,27 +0,0 @@ -#include "catch2/catch.hpp" -#define private public -#include "common/params.h" -#include "common/util.h" - -TEST_CASE("params_nonblocking_put") { - char tmp_path[] = "/tmp/asyncWriter_XXXXXX"; - const std::string param_path = mkdtemp(tmp_path); - auto param_names = {"CarParams", "IsMetric"}; - { - Params params(param_path); - for (const auto &name : param_names) { - params.putNonBlocking(name, "1"); - // param is empty - REQUIRE(params.get(name).empty()); - } - - // check if thread is running - REQUIRE(params.future.valid()); - REQUIRE(params.future.wait_for(std::chrono::milliseconds(0)) == std::future_status::timeout); - } - // check results - Params p(param_path); - for (const auto &name : param_names) { - REQUIRE(p.get(name) == "1"); - } -} From 91b067cca0913d0cc9f8b5dab68e3302e278efdc Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Wed, 15 Jul 2026 18:43:48 -0700 Subject: [PATCH 149/151] jenkins speedups (#38328) * power draw first * speedup encoder * speed up hardware test suites * refresh IRQ actions after hardware setup * skip unused big model in device checkout * move LFS pruning off device checkout path * wtf is that for? * reverts * locality * rm that --- openpilot/common/SConscript | 2 +- .../hardware/tici/tests/test_amplifier.py | 3 +- .../selfdrive/pandad/tests/test_pandad_spi.py | 12 ++++++-- openpilot/selfdrive/test/setup_device_ci.sh | 29 ++++++++++++++++--- openpilot/selfdrive/test/test_power_draw.py | 5 +--- .../system/loggerd/tests/test_encoder.py | 12 ++------ openpilot/system/manager/test/test_manager.py | 4 --- 7 files changed, 40 insertions(+), 27 deletions(-) diff --git a/openpilot/common/SConscript b/openpilot/common/SConscript index 68dcc84171..13935b80d5 100644 --- a/openpilot/common/SConscript +++ b/openpilot/common/SConscript @@ -13,7 +13,7 @@ Export('_common') if GetOption('extras'): env.Program('tests/test_common', - ['tests/test_runner.cc', 'tests/test_params.cc', 'tests/test_util.cc', 'tests/test_swaglog.cc'], + ['tests/test_runner.cc', 'tests/test_util.cc', 'tests/test_swaglog.cc'], LIBS=[_common, 'json11', 'zmq', 'pthread']) # Cython bindings diff --git a/openpilot/common/hardware/tici/tests/test_amplifier.py b/openpilot/common/hardware/tici/tests/test_amplifier.py index 39628b53cc..3e36ff3a3d 100644 --- a/openpilot/common/hardware/tici/tests/test_amplifier.py +++ b/openpilot/common/hardware/tici/tests/test_amplifier.py @@ -1,6 +1,5 @@ import pytest import time -import random import subprocess from panda import Panda @@ -57,7 +56,7 @@ class TestAmplifier: time.sleep(0.1) self.panda.set_siren(True) - time.sleep(random.randint(0, 5)) + time.sleep(0.1) amp = Amplifier(debug=True) r = amp.initialize_configuration() diff --git a/openpilot/selfdrive/pandad/tests/test_pandad_spi.py b/openpilot/selfdrive/pandad/tests/test_pandad_spi.py index 672244026f..02f5accfd6 100644 --- a/openpilot/selfdrive/pandad/tests/test_pandad_spi.py +++ b/openpilot/selfdrive/pandad/tests/test_pandad_spi.py @@ -6,6 +6,7 @@ import random import openpilot.cereal.messaging as messaging from openpilot.cereal.services import SERVICE_LIST +from openpilot.common.timeout import Timeout from openpilot.selfdrive.test.helpers import with_processes from openpilot.selfdrive.pandad.tests.test_pandad_loopback import setup_pandad, send_random_can_messages @@ -26,9 +27,14 @@ class TestBoarddSpi: sendcan = messaging.pub_sock('sendcan') socks = {s: messaging.sub_sock(s, conflate=False, timeout=100) for s in ('can', 'pandaStates', 'peripheralState')} - time.sleep(2) - for s in socks.values(): - messaging.drain_sock_raw(s) + readiness_services = {'pandaStates', 'peripheralState'} + ready = set() + with Timeout(2, "pandad services didn't become ready"): + while not readiness_services <= ready: + for service, sock in socks.items(): + if messaging.drain_sock_raw(sock): + ready.add(service) + time.sleep(0.01) total_recv_count = 0 total_sent_count = 0 diff --git a/openpilot/selfdrive/test/setup_device_ci.sh b/openpilot/selfdrive/test/setup_device_ci.sh index d458e047a5..60631ce037 100755 --- a/openpilot/selfdrive/test/setup_device_ci.sh +++ b/openpilot/selfdrive/test/setup_device_ci.sh @@ -3,6 +3,7 @@ set -e set -x + if [ -z "$SOURCE_DIR" ]; then echo "SOURCE_DIR must be set" exit 1 @@ -55,6 +56,28 @@ sleep infinity EOF chmod +x $CONTINUE_PATH +export GIT_LFS_SKIP_SMUDGE=1 +pull_lfs() { + # The big driving model is not used on these devices yet. Keep its pointer in + # the worktree, but don't download or copy the 1.8 GB LFS object. + LFS_EXCLUDE="openpilot/selfdrive/modeld/models/big_driving_supercombo.onnx" + + git config --local lfs.fetchexclude "$LFS_EXCLUDE" + git lfs pull --exclude="$LFS_EXCLUDE" + if git cat-file -e "HEAD:$LFS_EXCLUDE"; then + rm -f "$LFS_EXCLUDE" + git checkout -- "$LFS_EXCLUDE" + + # `git lfs prune` retains objects referenced by HEAD, even when excluded. + # Remove this one explicitly so safe checkout doesn't rsync it either. + oid=$(git show "HEAD:$LFS_EXCLUDE" | sed -n 's/^oid sha256://p') + lfs_objects=$(git lfs env | sed -n 's/^LocalMediaDir=//p') + if [[ "$oid" =~ ^[0-9a-f]{64}$ && -n "$lfs_objects" ]]; then + rm -f "$lfs_objects/${oid:0:2}/${oid:2:2}/$oid" + fi + fi +} + safe_checkout() { # completely clean TEST_DIR @@ -74,8 +97,7 @@ safe_checkout() { git submodule update --init --recursive git submodule foreach --recursive "git reset --hard && git clean -xdff" - git lfs pull - (ulimit -n 65535 && git lfs prune) + pull_lfs echo "git checkout done, t=$SECONDS" du -hs $SOURCE_DIR $SOURCE_DIR/.git @@ -100,8 +122,7 @@ unsafe_checkout() {( set -e git submodule update --init --recursive git submodule foreach --recursive "git reset --hard && git clean -df" - git lfs pull - (ulimit -n 65535 && git lfs prune) + pull_lfs )} export GIT_PACK_THREADS=8 diff --git a/openpilot/selfdrive/test/test_power_draw.py b/openpilot/selfdrive/test/test_power_draw.py index d5bb3d324d..9bc012ceaa 100644 --- a/openpilot/selfdrive/test/test_power_draw.py +++ b/openpilot/selfdrive/test/test_power_draw.py @@ -14,7 +14,7 @@ from openpilot.common.hardware.tici.power_monitor import get_power from openpilot.system.manager.process_config import managed_processes from openpilot.system.manager.manager import manager_cleanup -SAMPLE_TIME = 8 # seconds to sample power +SAMPLE_TIME = 2 # seconds to sample power MAX_WARMUP_TIME = 30 # seconds to wait for SAMPLE_TIME consecutive valid samples @dataclass @@ -44,9 +44,6 @@ class TestPowerDraw: def setup_method(self): Params().put("CarParams", get_demo_car_params().to_bytes(), block=True) - # wait a bit for power save to disable - time.sleep(5) - def teardown_method(self): manager_cleanup() diff --git a/openpilot/system/loggerd/tests/test_encoder.py b/openpilot/system/loggerd/tests/test_encoder.py index 416c158ed3..05bc211cbe 100644 --- a/openpilot/system/loggerd/tests/test_encoder.py +++ b/openpilot/system/loggerd/tests/test_encoder.py @@ -1,13 +1,11 @@ import math import os import pytest -import random import shutil import subprocess import time from pathlib import Path -from openpilot.common.parameterized import parameterized from tqdm import trange from openpilot.common.params import Params @@ -51,9 +49,8 @@ class TestEncoder: return os.path.join(Paths.log_root(), last_route) # TODO: this should run faster than real time - @parameterized.expand([(True, ), (False, )]) - def test_log_rotation(self, record_front): - Params().put_bool("RecordFront", record_front, block=True) + def test_log_rotation(self): + Params().put_bool("RecordFront", True, block=True) managed_processes['sensord'].start() managed_processes['loggerd'].start() @@ -62,7 +59,7 @@ class TestEncoder: time.sleep(1.0) managed_processes['camerad'].start() - num_segments = int(os.getenv("SEGMENTS", random.randint(2, 8))) + num_segments = 3 # wait for loggerd to make the dir for first segment route_prefix_path = None @@ -78,9 +75,6 @@ class TestEncoder: counts = [] first_frames = [] for camera, fps, size_lambda, encode_idx_name in CAMERAS: - if not record_front and "dcamera" in camera: - continue - file_path = f"{route_prefix_path}--{i}/{camera}" # check file exists diff --git a/openpilot/system/manager/test/test_manager.py b/openpilot/system/manager/test/test_manager.py index 273ddc8fd9..a3808bf29f 100644 --- a/openpilot/system/manager/test/test_manager.py +++ b/openpilot/system/manager/test/test_manager.py @@ -27,10 +27,6 @@ class TestManager: def teardown_method(self): manager.manager_cleanup() - def test_manager_prepare(self): - os.environ['PREPAREONLY'] = '1' - manager.main() - def test_duplicate_procs(self): assert len(procs) == len(managed_processes), "Duplicate process names" From 560cde61aeb5dcd9321798743a86af00916f84a1 Mon Sep 17 00:00:00 2001 From: royjr Date: Thu, 16 Jul 2026 01:04:49 -0400 Subject: [PATCH 150/151] sync: fix upstream conflicts Co-authored-by: royjr --- .github/workflows/badges.yaml | 35 --- .../workflows/build-all-tinygrad-models.yaml | 2 +- .github/workflows/cereal_validation.yaml | 35 ++- .github/workflows/sunnypilot-build-model.yaml | 15 +- .../workflows/sunnypilot-build-prebuilt.yaml | 32 ++- .github/workflows/tests.yaml | 8 +- .gitmodules | 2 +- SConstruct | 4 +- launch_openpilot.sh | 2 +- msgq_repo | 2 +- opendbc_repo | 2 +- {common => openpilot/common}/api/__init__.py | 0 {common => openpilot/common}/api/base.py | 2 +- .../common}/api/comma_connect.py | 0 openpilot/selfdrive/car/helpers.py | 2 +- openpilot/selfdrive/modeld/compile_warp.py | 201 ----------------- .../selfdrive/monitoring/test_monitoring.py | 5 +- .../selfdrive}/ui/sunnypilot/__init__.py | 0 .../ui/sunnypilot/layouts/__init__.py | 0 .../ui/sunnypilot/layouts/onboarding.py | 2 +- .../sunnypilot/layouts/settings/__init__.py | 0 .../ui/sunnypilot/layouts/settings/cruise.py | 0 .../cruise_sub_layouts/speed_limit_policy.py | 0 .../speed_limit_settings.py | 0 .../sunnypilot/layouts/settings/developer.py | 0 .../ui/sunnypilot/layouts/settings/device.py | 0 .../ui/sunnypilot/layouts/settings/display.py | 0 .../ui/sunnypilot/layouts/settings/models.py | 2 +- .../sunnypilot/layouts/settings/navigation.py | 0 .../ui/sunnypilot/layouts/settings/network.py | 0 .../ui/sunnypilot/layouts/settings/osm.py | 0 .../sunnypilot/layouts/settings/settings.py | 0 .../sunnypilot/layouts/settings/software.py | 4 +- .../sunnypilot/layouts/settings/steering.py | 2 +- .../lane_change_settings.py | 0 .../steering_sub_layouts/mads_settings.py | 0 .../steering_sub_layouts/torque_settings.py | 2 +- .../sunnypilot/layouts/settings/sunnylink.py | 4 +- .../ui/sunnypilot/layouts/settings/trips.py | 0 .../layouts/settings/vehicle/__init__.py | 0 .../settings/vehicle/brands/__init__.py | 0 .../layouts/settings/vehicle/brands/base.py | 0 .../layouts/settings/vehicle/brands/body.py | 0 .../settings/vehicle/brands/chrysler.py | 0 .../settings/vehicle/brands/factory.py | 0 .../layouts/settings/vehicle/brands/ford.py | 0 .../layouts/settings/vehicle/brands/gm.py | 0 .../layouts/settings/vehicle/brands/honda.py | 0 .../settings/vehicle/brands/hyundai.py | 0 .../layouts/settings/vehicle/brands/mazda.py | 0 .../layouts/settings/vehicle/brands/nissan.py | 0 .../layouts/settings/vehicle/brands/psa.py | 0 .../layouts/settings/vehicle/brands/rivian.py | 0 .../layouts/settings/vehicle/brands/subaru.py | 0 .../layouts/settings/vehicle/brands/tesla.py | 0 .../layouts/settings/vehicle/brands/toyota.py | 0 .../settings/vehicle/brands/volkswagen.py | 0 .../settings/vehicle/platform_selector.py | 2 +- .../ui/sunnypilot/layouts/settings/visuals.py | 0 .../ui/sunnypilot/layouts/sidebar.py | 0 .../selfdrive}/ui/sunnypilot/mici/__init__.py | 0 .../ui/sunnypilot/mici/layouts/__init__.py | 0 .../ui/sunnypilot/mici/layouts/models.py | 2 +- .../ui/sunnypilot/mici/layouts/onboarding.py | 0 .../ui/sunnypilot/mici/layouts/settings.py | 0 .../ui/sunnypilot/mici/layouts/sunnylink.py | 4 +- .../ui/sunnypilot/mici/onroad/__init__.py | 0 .../sunnypilot/mici/onroad/confidence_ball.py | 0 .../ui/sunnypilot/mici/onroad/hud_renderer.py | 0 .../sunnypilot/mici/onroad/model_renderer.py | 0 .../ui/sunnypilot/mici/widgets/__init__.py | 0 .../mici/widgets/sunnylink_pairing_dialog.py | 0 .../ui/sunnypilot/onroad/__init__.py | 0 .../ui/sunnypilot/onroad/alert_renderer.py | 0 .../sunnypilot/onroad/augmented_road_view.py | 0 .../onroad/blind_spot_indicators.py | 0 .../ui/sunnypilot/onroad/chevron_metrics.py | 4 +- .../ui/sunnypilot/onroad/circular_alerts.py | 2 +- .../onroad/developer_ui/__init__.py | 0 .../onroad/developer_ui/elements.py | 2 +- .../ui/sunnypilot/onroad/driver_state.py | 0 .../ui/sunnypilot/onroad/hud_renderer.py | 0 .../ui/sunnypilot/onroad/model_renderer.py | 0 .../ui/sunnypilot/onroad/rainbow_path.py | 0 .../ui/sunnypilot/onroad/road_name.py | 0 .../ui/sunnypilot/onroad/rocket_fuel.py | 0 .../sunnypilot/onroad/smart_cruise_control.py | 0 .../ui/sunnypilot/onroad/speed_limit.py | 2 +- .../ui/sunnypilot/onroad/speed_renderer.py | 0 .../ui/sunnypilot/onroad/turn_signal.py | 0 .../selfdrive}/ui/sunnypilot/ui_state.py | 3 +- openpilot/sunnypilot | 1 - .../sunnypilot}/SConscript | 0 .../sunnypilot}/__init__.py | 0 .../common/transformations/SConscript | 0 .../common/transformations/coordinates.cc | 0 .../common/transformations/coordinates.hpp | 0 .../common/transformations/orientation.cc | 0 .../common/transformations/orientation.hpp | 0 .../sunnypilot}/common/version.h | 0 .../sunnypilot}/livedelay/__init__.py | 0 .../sunnypilot}/livedelay/helpers.py | 0 .../sunnypilot}/livedelay/lagd_toggle.py | 2 +- .../sunnypilot}/mads/helpers.py | 0 .../sunnypilot}/mads/mads.py | 2 +- .../sunnypilot}/mads/state.py | 2 +- .../mads/tests/test_mads_state_machine.py | 2 +- .../mads/tests/test_mads_steering_mode.py | 2 +- .../sunnypilot}/mapd/__init__.py | 2 +- .../mapd/live_map_data/__init__.py | 0 .../mapd/live_map_data/base_map_data.py | 2 +- .../sunnypilot}/mapd/live_map_data/debug.py | 6 +- .../mapd/live_map_data/osm_map_data.py | 2 +- .../mapd/live_map_data/standalone.py | 0 .../sunnypilot}/mapd/mapd_installer.py | 4 +- .../sunnypilot}/mapd/mapd_manager.py | 0 .../sunnypilot}/mapd/tests/__init__.py | 0 .../sunnypilot}/mapd/tests/mapd_hash | 0 .../mapd/tests/test_mapd_version.py | 0 .../sunnypilot}/mapd/update_version.py | 4 +- .../sunnypilot}/mapd/version.py | 0 .../sunnypilot}/modeld_v2/.gitignore | 0 .../sunnypilot}/modeld_v2/SConscript | 6 +- .../sunnypilot}/modeld_v2/__init__.py | 0 .../modeld_v2/camera_offset_helper.py | 0 .../sunnypilot}/modeld_v2/compile_modeld.py | 0 .../sunnypilot}/modeld_v2/constants.py | 0 .../sunnypilot}/modeld_v2/fill_model_msg.py | 2 +- .../modeld_v2/get_model_metadata.py | 0 .../modeld_v2/install_models_pc.py | 2 +- .../sunnypilot}/modeld_v2/meta_20hz.py | 0 .../sunnypilot}/modeld_v2/meta_helper.py | 2 +- .../sunnypilot}/modeld_v2/modeld | 0 .../sunnypilot}/modeld_v2/modeld.py | 13 +- .../sunnypilot}/modeld_v2/modeld_base.py | 0 .../modeld_v2/parse_model_outputs.py | 0 .../modeld_v2/parse_model_outputs_split.py | 0 .../sunnypilot}/modeld_v2/tests/__init__.py | 0 .../sunnypilot}/modeld_v2/tests/conftest.py | 0 .../tests/test_camera_offset_helper.py | 0 .../tests/test_combined_pkl_loader.py | 0 .../modeld_v2/tests/test_compile_modeld.py | 0 .../modeld_v2/tests/test_recovery_power.py | 2 +- .../sunnypilot}/modeld_v2/tests/test_warp.py | 0 .../sunnypilot}/modeld_v2/warp.py | 0 .../sunnypilot}/models/README.md | 0 .../sunnypilot}/models/__init__.py | 0 .../sunnypilot}/models/constants.py | 0 .../sunnypilot}/models/default_model.py | 6 +- .../sunnypilot}/models/fetcher.py | 2 +- .../sunnypilot}/models/helpers.py | 7 +- .../sunnypilot}/models/manager.py | 2 +- .../sunnypilot}/models/model_name.py | 0 .../sunnypilot}/models/runners/constants.py | 2 +- .../sunnypilot}/models/runners/helpers.py | 0 .../models/runners/model_runner.py | 0 .../models/runners/tinygrad/model_types.py | 0 .../runners/tinygrad/tinygrad_runner.py | 0 .../models/split_model_constants.py | 0 .../sunnypilot}/models/tests/__init__.py | 0 .../sunnypilot}/models/tests/model_hash | 0 .../models/tests/model_manager_audit.py | 2 +- .../models/tests/test_default_model.py | 0 .../models/tests/test_tinygrad_ref.py | 0 .../sunnypilot}/models/tinygrad_ref.py | 0 .../sunnypilot}/navd/helpers.py | 0 .../sunnypilot}/neural_network_data | 0 .../sunnypilot}/selfdrive/__init__.py | 0 .../selfdrive/assets/icons/clock.png | 0 .../selfdrive/assets/icons/star-empty.png | 0 .../selfdrive/assets/icons/star-filled.png | 0 .../assets/icons_mici/always_offroad.png | 0 .../assets/icons_mici/disable_offroad.png | 0 .../selfdrive/assets/images/green_light.png | 0 .../selfdrive/assets/images/lead_depart.png | 0 .../assets/images/spinner_sunnypilot.png | 0 .../selfdrive/assets/img_minus_arrow_down.png | 0 .../selfdrive/assets/img_plus_arrow_up.png | 0 .../sunnypilot}/selfdrive/assets/logo.png | 0 .../selfdrive/assets/offroad/icon_display.png | 0 .../assets/offroad/icon_exit_offroad.png | 0 .../assets/offroad/icon_firehose.png | 0 .../assets/offroad/icon_firehose.svg | 0 .../selfdrive/assets/offroad/icon_home.png | 0 .../selfdrive/assets/offroad/icon_home.svg | 0 .../selfdrive/assets/offroad/icon_lateral.png | 0 .../selfdrive/assets/offroad/icon_map.png | 0 .../selfdrive/assets/offroad/icon_models.png | 0 .../assets/offroad/icon_software.png | 0 .../selfdrive/assets/offroad/icon_toggle.png | 0 .../selfdrive/assets/offroad/icon_trips.png | 0 .../selfdrive/assets/offroad/icon_vehicle.png | 0 .../selfdrive/assets/offroad/icon_visuals.png | 0 .../sunnypilot}/selfdrive/car/__init__.py | 0 .../sunnypilot/selfdrive/car/car_list.json | 1 + .../sunnypilot}/selfdrive/car/car_specific.py | 2 +- .../sunnypilot}/selfdrive/car/cruise_ext.py | 3 +- .../selfdrive/car/cruise_helpers.py | 3 +- .../__init__.py | 0 .../controller.py | 3 +- .../helpers.py | 0 .../sunnypilot}/selfdrive/car/interfaces.py | 0 .../selfdrive/car/sync_sunnylink_params.py | 2 +- .../selfdrive/car/tests/__init__.py | 0 .../selfdrive/car/tests/test_cruise_mode.py | 2 +- .../selfdrive/car/tests/test_custom_cruise.py | 2 +- .../selfdrive/controls/__init__.py | 0 .../selfdrive/controls/controlsd_ext.py | 14 +- .../selfdrive/controls/lib/__init__.py | 0 .../controls/lib/auto_lane_change.py | 2 +- .../controls/lib/blinker_pause_lateral.py | 2 +- .../selfdrive/controls/lib/dec/__init__.py | 0 .../selfdrive/controls/lib/dec/constants.py | 0 .../selfdrive/controls/lib/dec/dec.py | 4 +- .../controls/lib/dec/tests/__init__.py | 0 .../dec/tests/pytest_dynamic_controller.py | 0 .../controls/lib/e2e_alerts_helper.py | 4 +- .../controls/lib/lane_turn_desire.py | 2 +- .../controls/lib/latcontrol_torque_ext.py | 0 .../lib/latcontrol_torque_ext_base.py | 0 .../lib/latcontrol_torque_ext_override.py | 0 .../controls/lib/latcontrol_torque_v0.py | 2 +- .../lib/latcontrol_torque_versions.json | 0 .../controls/lib/longitudinal_planner.py | 2 +- .../selfdrive/controls/lib/nnlc/__init__.py | 0 .../selfdrive/controls/lib/nnlc/helpers.py | 4 +- .../selfdrive/controls/lib/nnlc/model.py | 0 .../selfdrive/controls/lib/nnlc/nnlc.py | 0 .../controls/lib/nnlc/tests/__init__.py | 0 .../lib/nnlc/tests/test_fingerprint.py | 0 .../lib/nnlc/tests/test_load_model.py | 0 .../controls/lib/nnlc/tests/test_nnlc.py | 3 +- .../lib/smart_cruise_control/__init__.py | 0 .../smart_cruise_control/map_controller.py | 2 +- .../smart_cruise_control.py | 2 +- .../tests/test_map_controller.py | 2 +- .../tests/test_vision_controller.py | 4 +- .../smart_cruise_control/vision_controller.py | 4 +- .../controls/lib/speed_limit/__init__.py | 0 .../controls/lib/speed_limit/common.py | 0 .../controls/lib/speed_limit/helpers.py | 3 +- .../lib/speed_limit/speed_limit_assist.py | 3 +- .../lib/speed_limit/speed_limit_resolver.py | 4 +- .../lib/speed_limit/tests/__init__.py | 0 .../tests/test_speed_limit_assist.py | 2 +- .../tests/test_speed_limit_resolver.py | 2 +- .../lib/tests/test_auto_lane_change.py | 0 .../lib/tests/test_blinker_pause_lateral.py | 2 +- .../lib/tests/test_lane_turn_desire.py | 2 +- .../selfdrive/locationd/.gitignore | 0 .../selfdrive/locationd/SConscript | 0 .../selfdrive/locationd/__init__.py | 0 .../selfdrive/locationd/locationd.cc | 0 .../selfdrive/locationd/locationd.h | 0 .../selfdrive/locationd/models/.gitignore | 0 .../selfdrive/locationd/models/__init__.py | 0 .../selfdrive/locationd/models/car_kf.py | 0 .../selfdrive/locationd/models/constants.py | 0 .../selfdrive/locationd/models/live_kf.cc | 0 .../selfdrive/locationd/models/live_kf.h | 0 .../selfdrive/locationd/models/live_kf.py | 0 .../selfdrive/locationd/tests/.gitignore | 0 .../selfdrive/locationd/tests/__init__.py | 0 .../locationd/tests/test_locationd.py | 4 +- .../selfdrive/locationd/torqued_ext.py | 2 +- .../sunnypilot}/selfdrive/pandad/__init__.py | 0 .../selfdrive/pandad/rivian_long_flasher.py | 3 +- .../pandad/rivian_long_fw.bin.signed | Bin .../selfdrive/selfdrived/__init__.py | 0 .../selfdrive/selfdrived/events.py | 5 +- .../selfdrive/selfdrived/events_base.py | 18 +- .../sunnypilot}/selfdrive/ui/quiet_mode.py | 2 +- .../sunnypilot}/sunnylink/__init__.py | 0 .../sunnypilot}/sunnylink/api.py | 0 .../sunnypilot}/sunnylink/athena/__init__.py | 0 .../sunnylink/athena/manage_sunnylinkd.py | 2 +- .../sunnylink/athena/sunnylinkd.py | 4 +- .../sunnylink/athena/tests/test_sunnylinkd.py | 0 .../sunnylink/backups/AESCipher.py | 0 .../sunnypilot}/sunnylink/backups/__init__.py | 0 .../sunnypilot}/sunnylink/backups/manager.py | 4 +- .../sunnypilot}/sunnylink/backups/utils.py | 0 .../sunnypilot}/sunnylink/capabilities.py | 3 +- .../sunnypilot}/sunnylink/docs/README.md | 0 .../sunnylink/registration_manager.py | 2 +- .../sunnypilot}/sunnylink/settings_ui.json | 0 .../sunnylink/settings_ui.schema.json | 0 .../sunnylink/settings_ui_src/_macros.yaml | 0 .../_schemas/macros.schema.json | 0 .../settings_ui_src/_schemas/page.schema.json | 0 .../settings_ui_src/_schemas/rule.schema.json | 0 .../settings_ui_src/pages/cruise.yaml | 0 .../settings_ui_src/pages/developer.yaml | 0 .../settings_ui_src/pages/device.yaml | 0 .../settings_ui_src/pages/display.yaml | 0 .../settings_ui_src/pages/models.yaml | 0 .../settings_ui_src/pages/software.yaml | 0 .../settings_ui_src/pages/steering.yaml | 0 .../settings_ui_src/pages/toggles.yaml | 0 .../settings_ui_src/pages/vehicle.yaml | 0 .../settings_ui_src/pages/visuals.yaml | 0 .../sunnypilot}/sunnylink/statsd.py | 6 +- .../sunnypilot}/sunnylink/sunnylink_state.py | 2 +- .../sunnylink/tests/test_capabilities.py | 0 .../tests/test_compile_settings_ui.py | 0 .../sunnylink/tests/test_settings_changes.py | 0 .../sunnylink/tests/test_settings_schema.py | 0 .../sunnylink/tools/apply_macros.py | 0 .../sunnylink/tools/compile_settings_ui.py | 0 .../sunnylink/tools/extract_settings_ui.py | 0 .../tools/generate_settings_schema.py | 0 .../sunnylink/tools/validate_settings_ui.py | 0 .../sunnypilot}/sunnylink/uploader.py | 4 +- .../sunnypilot}/sunnylink/utils.py | 2 +- .../sunnypilot}/system/__init__.py | 0 .../sunnypilot}/system/hardware/c3/README.md | 0 .../sunnypilot}/system/hardware/c3/agnos.json | 0 .../system/hardware/c3/launch_chffrplus.sh | 16 +- .../system/hardware/c3/launch_env.sh | 0 .../sunnypilot}/system/params_migration.py | 0 .../sunnypilot}/system/sensord/.gitignore | 0 .../sunnypilot}/system/sensord/SConscript | 0 .../system/sensord/sensors/bmx055_accel.cc | 0 .../system/sensord/sensors/bmx055_accel.h | 0 .../system/sensord/sensors/bmx055_gyro.cc | 0 .../system/sensord/sensors/bmx055_gyro.h | 0 .../system/sensord/sensors/bmx055_magn.cc | 0 .../system/sensord/sensors/bmx055_magn.h | 0 .../system/sensord/sensors/bmx055_temp.cc | 0 .../system/sensord/sensors/bmx055_temp.h | 0 .../system/sensord/sensors/constants.h | 0 .../system/sensord/sensors/i2c_sensor.cc | 0 .../system/sensord/sensors/i2c_sensor.h | 0 .../system/sensord/sensors/lsm6ds3_accel.cc | 0 .../system/sensord/sensors/lsm6ds3_accel.h | 0 .../system/sensord/sensors/lsm6ds3_gyro.cc | 0 .../system/sensord/sensors/lsm6ds3_gyro.h | 0 .../system/sensord/sensors/lsm6ds3_temp.cc | 0 .../system/sensord/sensors/lsm6ds3_temp.h | 0 .../system/sensord/sensors/mmc5603nj_magn.cc | 0 .../system/sensord/sensors/mmc5603nj_magn.h | 0 .../system/sensord/sensors/sensor.h | 0 .../system/sensord/sensors_qcom2.cc | 0 .../system/sensord/tests/test_sensord.py | 9 +- .../system/sensord/tests/ttff_test.py | 2 +- .../sunnypilot/system}/statsd.py | 4 +- .../tests/test_sp_branch_migrations.py | 0 .../sunnypilot}/tools/__init__.py | 0 .../tools/memory_profiler/__init__.py | 0 .../tools/memory_profiler/mem_usage.py | 0 .../sunnypilot}/tools/pull_footage.py | 0 openpilot/system/athena/athenad.py | 22 +- openpilot/system/athena/manage_athenad.py | 2 +- openpilot/system/hardware/hardwared.py | 24 +- openpilot/system/hardware/power_monitoring.py | 2 + openpilot/system/manager/process_config.py | 88 +++++++- .../system}/ui/sunnypilot/lib/application.py | 0 .../system}/ui/sunnypilot/lib/styles.py | 0 .../system}/ui/sunnypilot/lib/utils.py | 0 .../system}/ui/sunnypilot/widgets/__init__.py | 0 .../ui/sunnypilot/widgets/helpers/__init__.py | 0 .../widgets/helpers/fuzzy_search.py | 0 .../sunnypilot/widgets/helpers/star_icon.py | 0 .../ui/sunnypilot/widgets/html_render.py | 0 .../ui/sunnypilot/widgets/input_dialog.py | 0 .../ui/sunnypilot/widgets/list_view.py | 0 .../ui/sunnypilot/widgets/option_control.py | 0 .../ui/sunnypilot/widgets/progress_bar.py | 0 .../widgets/sunnylink_pairing_dialog.py | 0 .../system}/ui/sunnypilot/widgets/toggle.py | 0 .../ui/sunnypilot/widgets/tree_dialog.py | 0 .../third_party}/copyparty/copyparty-sfx.py | 0 .../third_party}/mapd_pfeiferj/README.md | 0 .../third_party}/mapd_pfeiferj/mapd | Bin panda | 2 +- release/ci/publish.sh | 4 +- scripts/lint/lint.sh | 3 +- sunnypilot/selfdrive/car/car_list.json | 1 - system/manager/process_config.py | 209 ------------------ uv.lock | 17 +- 380 files changed, 357 insertions(+), 665 deletions(-) delete mode 100644 .github/workflows/badges.yaml rename {common => openpilot/common}/api/__init__.py (100%) rename {common => openpilot/common}/api/base.py (98%) rename {common => openpilot/common}/api/comma_connect.py (100%) delete mode 100755 openpilot/selfdrive/modeld/compile_warp.py rename {selfdrive => openpilot/selfdrive}/ui/sunnypilot/__init__.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/sunnypilot/layouts/__init__.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/sunnypilot/layouts/onboarding.py (98%) rename {selfdrive => openpilot/selfdrive}/ui/sunnypilot/layouts/settings/__init__.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/sunnypilot/layouts/settings/cruise.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/sunnypilot/layouts/settings/cruise_sub_layouts/speed_limit_policy.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/sunnypilot/layouts/settings/cruise_sub_layouts/speed_limit_settings.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/sunnypilot/layouts/settings/developer.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/sunnypilot/layouts/settings/device.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/sunnypilot/layouts/settings/display.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/sunnypilot/layouts/settings/models.py (99%) rename {selfdrive => openpilot/selfdrive}/ui/sunnypilot/layouts/settings/navigation.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/sunnypilot/layouts/settings/network.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/sunnypilot/layouts/settings/osm.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/sunnypilot/layouts/settings/settings.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/sunnypilot/layouts/settings/software.py (97%) rename {selfdrive => openpilot/selfdrive}/ui/sunnypilot/layouts/settings/steering.py (99%) rename {selfdrive => openpilot/selfdrive}/ui/sunnypilot/layouts/settings/steering_sub_layouts/lane_change_settings.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/sunnypilot/layouts/settings/steering_sub_layouts/mads_settings.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/sunnypilot/layouts/settings/steering_sub_layouts/torque_settings.py (98%) rename {selfdrive => openpilot/selfdrive}/ui/sunnypilot/layouts/settings/sunnylink.py (99%) rename {selfdrive => openpilot/selfdrive}/ui/sunnypilot/layouts/settings/trips.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/sunnypilot/layouts/settings/vehicle/__init__.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/sunnypilot/layouts/settings/vehicle/brands/__init__.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/sunnypilot/layouts/settings/vehicle/brands/base.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/sunnypilot/layouts/settings/vehicle/brands/body.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/sunnypilot/layouts/settings/vehicle/brands/chrysler.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/sunnypilot/layouts/settings/vehicle/brands/factory.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/sunnypilot/layouts/settings/vehicle/brands/ford.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/sunnypilot/layouts/settings/vehicle/brands/gm.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/sunnypilot/layouts/settings/vehicle/brands/honda.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/sunnypilot/layouts/settings/vehicle/brands/hyundai.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/sunnypilot/layouts/settings/vehicle/brands/mazda.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/sunnypilot/layouts/settings/vehicle/brands/nissan.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/sunnypilot/layouts/settings/vehicle/brands/psa.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/sunnypilot/layouts/settings/vehicle/brands/rivian.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/sunnypilot/layouts/settings/vehicle/brands/subaru.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/sunnypilot/layouts/settings/vehicle/brands/tesla.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/sunnypilot/layouts/settings/vehicle/brands/toyota.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/sunnypilot/layouts/settings/vehicle/brands/volkswagen.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/sunnypilot/layouts/settings/vehicle/platform_selector.py (98%) rename {selfdrive => openpilot/selfdrive}/ui/sunnypilot/layouts/settings/visuals.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/sunnypilot/layouts/sidebar.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/sunnypilot/mici/__init__.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/sunnypilot/mici/layouts/__init__.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/sunnypilot/mici/layouts/models.py (99%) rename {selfdrive => openpilot/selfdrive}/ui/sunnypilot/mici/layouts/onboarding.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/sunnypilot/mici/layouts/settings.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/sunnypilot/mici/layouts/sunnylink.py (99%) rename {selfdrive => openpilot/selfdrive}/ui/sunnypilot/mici/onroad/__init__.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/sunnypilot/mici/onroad/confidence_ball.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/sunnypilot/mici/onroad/hud_renderer.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/sunnypilot/mici/onroad/model_renderer.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/sunnypilot/mici/widgets/__init__.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/sunnypilot/mici/widgets/sunnylink_pairing_dialog.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/sunnypilot/onroad/__init__.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/sunnypilot/onroad/alert_renderer.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/sunnypilot/onroad/augmented_road_view.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/sunnypilot/onroad/blind_spot_indicators.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/sunnypilot/onroad/chevron_metrics.py (97%) rename {selfdrive => openpilot/selfdrive}/ui/sunnypilot/onroad/circular_alerts.py (99%) rename {selfdrive => openpilot/selfdrive}/ui/sunnypilot/onroad/developer_ui/__init__.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/sunnypilot/onroad/developer_ui/elements.py (99%) rename {selfdrive => openpilot/selfdrive}/ui/sunnypilot/onroad/driver_state.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/sunnypilot/onroad/hud_renderer.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/sunnypilot/onroad/model_renderer.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/sunnypilot/onroad/rainbow_path.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/sunnypilot/onroad/road_name.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/sunnypilot/onroad/rocket_fuel.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/sunnypilot/onroad/smart_cruise_control.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/sunnypilot/onroad/speed_limit.py (99%) rename {selfdrive => openpilot/selfdrive}/ui/sunnypilot/onroad/speed_renderer.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/sunnypilot/onroad/turn_signal.py (100%) rename {selfdrive => openpilot/selfdrive}/ui/sunnypilot/ui_state.py (99%) delete mode 120000 openpilot/sunnypilot rename {sunnypilot => openpilot/sunnypilot}/SConscript (100%) rename {sunnypilot => openpilot/sunnypilot}/__init__.py (100%) rename {sunnypilot => openpilot/sunnypilot}/common/transformations/SConscript (100%) rename {sunnypilot => openpilot/sunnypilot}/common/transformations/coordinates.cc (100%) rename {sunnypilot => openpilot/sunnypilot}/common/transformations/coordinates.hpp (100%) rename {sunnypilot => openpilot/sunnypilot}/common/transformations/orientation.cc (100%) rename {sunnypilot => openpilot/sunnypilot}/common/transformations/orientation.hpp (100%) rename {sunnypilot => openpilot/sunnypilot}/common/version.h (100%) rename {sunnypilot => openpilot/sunnypilot}/livedelay/__init__.py (100%) rename {sunnypilot => openpilot/sunnypilot}/livedelay/helpers.py (100%) rename {sunnypilot => openpilot/sunnypilot}/livedelay/lagd_toggle.py (97%) rename {sunnypilot => openpilot/sunnypilot}/mads/helpers.py (100%) rename {sunnypilot => openpilot/sunnypilot}/mads/mads.py (99%) rename {sunnypilot => openpilot/sunnypilot}/mads/state.py (99%) rename {sunnypilot => openpilot/sunnypilot}/mads/tests/test_mads_state_machine.py (99%) rename {sunnypilot => openpilot/sunnypilot}/mads/tests/test_mads_steering_mode.py (99%) rename {sunnypilot => openpilot/sunnypilot}/mapd/__init__.py (56%) rename {sunnypilot => openpilot/sunnypilot}/mapd/live_map_data/__init__.py (100%) rename {sunnypilot => openpilot/sunnypilot}/mapd/live_map_data/base_map_data.py (97%) rename {sunnypilot => openpilot/sunnypilot}/mapd/live_map_data/debug.py (87%) rename {sunnypilot => openpilot/sunnypilot}/mapd/live_map_data/osm_map_data.py (98%) rename {sunnypilot => openpilot/sunnypilot}/mapd/live_map_data/standalone.py (100%) rename {sunnypilot => openpilot/sunnypilot}/mapd/mapd_installer.py (98%) rename {sunnypilot => openpilot/sunnypilot}/mapd/mapd_manager.py (100%) rename {sunnypilot => openpilot/sunnypilot}/mapd/tests/__init__.py (100%) rename {sunnypilot => openpilot/sunnypilot}/mapd/tests/mapd_hash (100%) rename {sunnypilot => openpilot/sunnypilot}/mapd/tests/test_mapd_version.py (100%) rename {sunnypilot => openpilot/sunnypilot}/mapd/update_version.py (93%) rename {sunnypilot => openpilot/sunnypilot}/mapd/version.py (100%) rename {sunnypilot => openpilot/sunnypilot}/modeld_v2/.gitignore (100%) rename {sunnypilot => openpilot/sunnypilot}/modeld_v2/SConscript (93%) rename {sunnypilot => openpilot/sunnypilot}/modeld_v2/__init__.py (100%) rename {sunnypilot => openpilot/sunnypilot}/modeld_v2/camera_offset_helper.py (100%) rename {sunnypilot => openpilot/sunnypilot}/modeld_v2/compile_modeld.py (100%) rename {sunnypilot => openpilot/sunnypilot}/modeld_v2/constants.py (100%) rename {sunnypilot => openpilot/sunnypilot}/modeld_v2/fill_model_msg.py (99%) rename {sunnypilot => openpilot/sunnypilot}/modeld_v2/get_model_metadata.py (100%) rename {sunnypilot => openpilot/sunnypilot}/modeld_v2/install_models_pc.py (94%) rename {sunnypilot => openpilot/sunnypilot}/modeld_v2/meta_20hz.py (100%) rename {sunnypilot => openpilot/sunnypilot}/modeld_v2/meta_helper.py (96%) rename {sunnypilot => openpilot/sunnypilot}/modeld_v2/modeld (100%) rename {sunnypilot => openpilot/sunnypilot}/modeld_v2/modeld.py (98%) rename {sunnypilot => openpilot/sunnypilot}/modeld_v2/modeld_base.py (100%) rename {sunnypilot => openpilot/sunnypilot}/modeld_v2/parse_model_outputs.py (100%) rename {sunnypilot => openpilot/sunnypilot}/modeld_v2/parse_model_outputs_split.py (100%) rename {sunnypilot => openpilot/sunnypilot}/modeld_v2/tests/__init__.py (100%) rename {sunnypilot => openpilot/sunnypilot}/modeld_v2/tests/conftest.py (100%) rename {sunnypilot => openpilot/sunnypilot}/modeld_v2/tests/test_camera_offset_helper.py (100%) rename {sunnypilot => openpilot/sunnypilot}/modeld_v2/tests/test_combined_pkl_loader.py (100%) rename {sunnypilot => openpilot/sunnypilot}/modeld_v2/tests/test_compile_modeld.py (100%) rename {sunnypilot => openpilot/sunnypilot}/modeld_v2/tests/test_recovery_power.py (98%) rename {sunnypilot => openpilot/sunnypilot}/modeld_v2/tests/test_warp.py (100%) rename {sunnypilot => openpilot/sunnypilot}/modeld_v2/warp.py (100%) rename {sunnypilot => openpilot/sunnypilot}/models/README.md (100%) rename {sunnypilot => openpilot/sunnypilot}/models/__init__.py (100%) rename {sunnypilot => openpilot/sunnypilot}/models/constants.py (100%) rename {sunnypilot => openpilot/sunnypilot}/models/default_model.py (84%) rename {sunnypilot => openpilot/sunnypilot}/models/fetcher.py (99%) rename {sunnypilot => openpilot/sunnypilot}/models/helpers.py (97%) rename {sunnypilot => openpilot/sunnypilot}/models/manager.py (99%) rename {sunnypilot => openpilot/sunnypilot}/models/model_name.py (100%) rename {sunnypilot => openpilot/sunnypilot}/models/runners/constants.py (91%) rename {sunnypilot => openpilot/sunnypilot}/models/runners/helpers.py (100%) rename {sunnypilot => openpilot/sunnypilot}/models/runners/model_runner.py (100%) rename {sunnypilot => openpilot/sunnypilot}/models/runners/tinygrad/model_types.py (100%) rename {sunnypilot => openpilot/sunnypilot}/models/runners/tinygrad/tinygrad_runner.py (100%) rename {sunnypilot => openpilot/sunnypilot}/models/split_model_constants.py (100%) rename {sunnypilot => openpilot/sunnypilot}/models/tests/__init__.py (100%) rename {sunnypilot => openpilot/sunnypilot}/models/tests/model_hash (100%) rename {sunnypilot => openpilot/sunnypilot}/models/tests/model_manager_audit.py (93%) rename {sunnypilot => openpilot/sunnypilot}/models/tests/test_default_model.py (100%) rename {sunnypilot => openpilot/sunnypilot}/models/tests/test_tinygrad_ref.py (100%) rename {sunnypilot => openpilot/sunnypilot}/models/tinygrad_ref.py (100%) rename {sunnypilot => openpilot/sunnypilot}/navd/helpers.py (100%) rename {sunnypilot => openpilot/sunnypilot}/neural_network_data (100%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/__init__.py (100%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/assets/icons/clock.png (100%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/assets/icons/star-empty.png (100%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/assets/icons/star-filled.png (100%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/assets/icons_mici/always_offroad.png (100%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/assets/icons_mici/disable_offroad.png (100%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/assets/images/green_light.png (100%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/assets/images/lead_depart.png (100%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/assets/images/spinner_sunnypilot.png (100%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/assets/img_minus_arrow_down.png (100%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/assets/img_plus_arrow_up.png (100%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/assets/logo.png (100%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/assets/offroad/icon_display.png (100%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/assets/offroad/icon_exit_offroad.png (100%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/assets/offroad/icon_firehose.png (100%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/assets/offroad/icon_firehose.svg (100%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/assets/offroad/icon_home.png (100%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/assets/offroad/icon_home.svg (100%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/assets/offroad/icon_lateral.png (100%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/assets/offroad/icon_map.png (100%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/assets/offroad/icon_models.png (100%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/assets/offroad/icon_software.png (100%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/assets/offroad/icon_toggle.png (100%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/assets/offroad/icon_trips.png (100%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/assets/offroad/icon_vehicle.png (100%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/assets/offroad/icon_visuals.png (100%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/car/__init__.py (100%) create mode 120000 openpilot/sunnypilot/selfdrive/car/car_list.json rename {sunnypilot => openpilot/sunnypilot}/selfdrive/car/car_specific.py (97%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/car/cruise_ext.py (98%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/car/cruise_helpers.py (96%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/car/intelligent_cruise_button_management/__init__.py (100%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/car/intelligent_cruise_button_management/controller.py (98%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/car/intelligent_cruise_button_management/helpers.py (100%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/car/interfaces.py (100%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/car/sync_sunnylink_params.py (88%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/car/tests/__init__.py (100%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/car/tests/test_cruise_mode.py (98%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/car/tests/test_custom_cruise.py (99%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/controls/__init__.py (100%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/controls/controlsd_ext.py (94%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/controls/lib/__init__.py (100%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/controls/lib/auto_lane_change.py (99%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/controls/lib/blinker_pause_lateral.py (97%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/controls/lib/dec/__init__.py (100%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/controls/lib/dec/constants.py (100%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/controls/lib/dec/dec.py (99%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/controls/lib/dec/tests/__init__.py (100%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/controls/lib/dec/tests/pytest_dynamic_controller.py (100%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/controls/lib/e2e_alerts_helper.py (98%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/controls/lib/lane_turn_desire.py (97%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/controls/lib/latcontrol_torque_ext.py (100%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/controls/lib/latcontrol_torque_ext_base.py (100%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/controls/lib/latcontrol_torque_ext_override.py (100%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/controls/lib/latcontrol_torque_v0.py (99%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/controls/lib/latcontrol_torque_versions.json (100%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/controls/lib/longitudinal_planner.py (99%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/controls/lib/nnlc/__init__.py (100%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/controls/lib/nnlc/helpers.py (92%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/controls/lib/nnlc/model.py (100%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/controls/lib/nnlc/nnlc.py (100%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/controls/lib/nnlc/tests/__init__.py (100%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/controls/lib/nnlc/tests/test_fingerprint.py (100%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/controls/lib/nnlc/tests/test_load_model.py (100%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/controls/lib/nnlc/tests/test_nnlc.py (98%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/controls/lib/smart_cruise_control/__init__.py (100%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/controls/lib/smart_cruise_control/map_controller.py (99%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/controls/lib/smart_cruise_control/smart_cruise_control.py (94%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/controls/lib/smart_cruise_control/tests/test_map_controller.py (98%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/controls/lib/smart_cruise_control/tests/test_vision_controller.py (98%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/controls/lib/smart_cruise_control/vision_controller.py (98%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/controls/lib/speed_limit/__init__.py (100%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/controls/lib/speed_limit/common.py (100%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/controls/lib/speed_limit/helpers.py (95%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/controls/lib/speed_limit/speed_limit_assist.py (99%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/controls/lib/speed_limit/speed_limit_resolver.py (98%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/controls/lib/speed_limit/tests/__init__.py (100%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/controls/lib/speed_limit/tests/test_speed_limit_assist.py (99%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/controls/lib/speed_limit/tests/test_speed_limit_resolver.py (99%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/controls/lib/tests/test_auto_lane_change.py (100%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/controls/lib/tests/test_blinker_pause_lateral.py (99%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/controls/lib/tests/test_lane_turn_desire.py (99%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/locationd/.gitignore (100%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/locationd/SConscript (100%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/locationd/__init__.py (100%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/locationd/locationd.cc (100%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/locationd/locationd.h (100%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/locationd/models/.gitignore (100%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/locationd/models/__init__.py (100%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/locationd/models/car_kf.py (100%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/locationd/models/constants.py (100%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/locationd/models/live_kf.cc (100%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/locationd/models/live_kf.h (100%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/locationd/models/live_kf.py (100%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/locationd/tests/.gitignore (100%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/locationd/tests/__init__.py (100%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/locationd/tests/test_locationd.py (97%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/locationd/torqued_ext.py (98%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/pandad/__init__.py (100%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/pandad/rivian_long_flasher.py (97%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/pandad/rivian_long_fw.bin.signed (100%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/selfdrived/__init__.py (100%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/selfdrived/events.py (98%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/selfdrived/events_base.py (94%) rename {sunnypilot => openpilot/sunnypilot}/selfdrive/ui/quiet_mode.py (96%) rename {sunnypilot => openpilot/sunnypilot}/sunnylink/__init__.py (100%) rename {sunnypilot => openpilot/sunnypilot}/sunnylink/api.py (100%) rename {sunnypilot => openpilot/sunnypilot}/sunnylink/athena/__init__.py (100%) rename {sunnypilot => openpilot/sunnypilot}/sunnylink/athena/manage_sunnylinkd.py (76%) rename {sunnypilot => openpilot/sunnypilot}/sunnylink/athena/sunnylinkd.py (99%) rename {sunnypilot => openpilot/sunnypilot}/sunnylink/athena/tests/test_sunnylinkd.py (100%) rename {sunnypilot => openpilot/sunnypilot}/sunnylink/backups/AESCipher.py (100%) rename {sunnypilot => openpilot/sunnypilot}/sunnylink/backups/__init__.py (100%) rename {sunnypilot => openpilot/sunnypilot}/sunnylink/backups/manager.py (99%) rename {sunnypilot => openpilot/sunnypilot}/sunnylink/backups/utils.py (100%) rename {sunnypilot => openpilot/sunnypilot}/sunnylink/capabilities.py (98%) rename {sunnypilot => openpilot/sunnypilot}/sunnylink/docs/README.md (100%) rename {sunnypilot => openpilot/sunnypilot}/sunnylink/registration_manager.py (95%) rename {sunnypilot => openpilot/sunnypilot}/sunnylink/settings_ui.json (100%) rename {sunnypilot => openpilot/sunnypilot}/sunnylink/settings_ui.schema.json (100%) rename {sunnypilot => openpilot/sunnypilot}/sunnylink/settings_ui_src/_macros.yaml (100%) rename {sunnypilot => openpilot/sunnypilot}/sunnylink/settings_ui_src/_schemas/macros.schema.json (100%) rename {sunnypilot => openpilot/sunnypilot}/sunnylink/settings_ui_src/_schemas/page.schema.json (100%) rename {sunnypilot => openpilot/sunnypilot}/sunnylink/settings_ui_src/_schemas/rule.schema.json (100%) rename {sunnypilot => openpilot/sunnypilot}/sunnylink/settings_ui_src/pages/cruise.yaml (100%) rename {sunnypilot => openpilot/sunnypilot}/sunnylink/settings_ui_src/pages/developer.yaml (100%) rename {sunnypilot => openpilot/sunnypilot}/sunnylink/settings_ui_src/pages/device.yaml (100%) rename {sunnypilot => openpilot/sunnypilot}/sunnylink/settings_ui_src/pages/display.yaml (100%) rename {sunnypilot => openpilot/sunnypilot}/sunnylink/settings_ui_src/pages/models.yaml (100%) rename {sunnypilot => openpilot/sunnypilot}/sunnylink/settings_ui_src/pages/software.yaml (100%) rename {sunnypilot => openpilot/sunnypilot}/sunnylink/settings_ui_src/pages/steering.yaml (100%) rename {sunnypilot => openpilot/sunnypilot}/sunnylink/settings_ui_src/pages/toggles.yaml (100%) rename {sunnypilot => openpilot/sunnypilot}/sunnylink/settings_ui_src/pages/vehicle.yaml (100%) rename {sunnypilot => openpilot/sunnypilot}/sunnylink/settings_ui_src/pages/visuals.yaml (100%) rename {sunnypilot => openpilot/sunnypilot}/sunnylink/statsd.py (97%) rename {sunnypilot => openpilot/sunnypilot}/sunnylink/sunnylink_state.py (99%) rename {sunnypilot => openpilot/sunnypilot}/sunnylink/tests/test_capabilities.py (100%) rename {sunnypilot => openpilot/sunnypilot}/sunnylink/tests/test_compile_settings_ui.py (100%) rename {sunnypilot => openpilot/sunnypilot}/sunnylink/tests/test_settings_changes.py (100%) rename {sunnypilot => openpilot/sunnypilot}/sunnylink/tests/test_settings_schema.py (100%) rename {sunnypilot => openpilot/sunnypilot}/sunnylink/tools/apply_macros.py (100%) rename {sunnypilot => openpilot/sunnypilot}/sunnylink/tools/compile_settings_ui.py (100%) rename {sunnypilot => openpilot/sunnypilot}/sunnylink/tools/extract_settings_ui.py (100%) rename {sunnypilot => openpilot/sunnypilot}/sunnylink/tools/generate_settings_schema.py (100%) rename {sunnypilot => openpilot/sunnypilot}/sunnylink/tools/validate_settings_ui.py (100%) rename {sunnypilot => openpilot/sunnypilot}/sunnylink/uploader.py (99%) rename {sunnypilot => openpilot/sunnypilot}/sunnylink/utils.py (98%) rename {sunnypilot => openpilot/sunnypilot}/system/__init__.py (100%) rename {sunnypilot => openpilot/sunnypilot}/system/hardware/c3/README.md (100%) rename {sunnypilot => openpilot/sunnypilot}/system/hardware/c3/agnos.json (100%) rename {sunnypilot => openpilot/sunnypilot}/system/hardware/c3/launch_chffrplus.sh (82%) rename {sunnypilot => openpilot/sunnypilot}/system/hardware/c3/launch_env.sh (100%) rename {sunnypilot => openpilot/sunnypilot}/system/params_migration.py (100%) rename {sunnypilot => openpilot/sunnypilot}/system/sensord/.gitignore (100%) rename {sunnypilot => openpilot/sunnypilot}/system/sensord/SConscript (100%) rename {sunnypilot => openpilot/sunnypilot}/system/sensord/sensors/bmx055_accel.cc (100%) rename {sunnypilot => openpilot/sunnypilot}/system/sensord/sensors/bmx055_accel.h (100%) rename {sunnypilot => openpilot/sunnypilot}/system/sensord/sensors/bmx055_gyro.cc (100%) rename {sunnypilot => openpilot/sunnypilot}/system/sensord/sensors/bmx055_gyro.h (100%) rename {sunnypilot => openpilot/sunnypilot}/system/sensord/sensors/bmx055_magn.cc (100%) rename {sunnypilot => openpilot/sunnypilot}/system/sensord/sensors/bmx055_magn.h (100%) rename {sunnypilot => openpilot/sunnypilot}/system/sensord/sensors/bmx055_temp.cc (100%) rename {sunnypilot => openpilot/sunnypilot}/system/sensord/sensors/bmx055_temp.h (100%) rename {sunnypilot => openpilot/sunnypilot}/system/sensord/sensors/constants.h (100%) rename {sunnypilot => openpilot/sunnypilot}/system/sensord/sensors/i2c_sensor.cc (100%) rename {sunnypilot => openpilot/sunnypilot}/system/sensord/sensors/i2c_sensor.h (100%) rename {sunnypilot => openpilot/sunnypilot}/system/sensord/sensors/lsm6ds3_accel.cc (100%) rename {sunnypilot => openpilot/sunnypilot}/system/sensord/sensors/lsm6ds3_accel.h (100%) rename {sunnypilot => openpilot/sunnypilot}/system/sensord/sensors/lsm6ds3_gyro.cc (100%) rename {sunnypilot => openpilot/sunnypilot}/system/sensord/sensors/lsm6ds3_gyro.h (100%) rename {sunnypilot => openpilot/sunnypilot}/system/sensord/sensors/lsm6ds3_temp.cc (100%) rename {sunnypilot => openpilot/sunnypilot}/system/sensord/sensors/lsm6ds3_temp.h (100%) rename {sunnypilot => openpilot/sunnypilot}/system/sensord/sensors/mmc5603nj_magn.cc (100%) rename {sunnypilot => openpilot/sunnypilot}/system/sensord/sensors/mmc5603nj_magn.h (100%) rename {sunnypilot => openpilot/sunnypilot}/system/sensord/sensors/sensor.h (100%) rename {sunnypilot => openpilot/sunnypilot}/system/sensord/sensors_qcom2.cc (100%) rename {sunnypilot => openpilot/sunnypilot}/system/sensord/tests/test_sensord.py (97%) rename {sunnypilot => openpilot/sunnypilot}/system/sensord/tests/ttff_test.py (96%) rename {system => openpilot/sunnypilot/system}/statsd.py (98%) rename {sunnypilot => openpilot/sunnypilot}/system/updated/tests/test_sp_branch_migrations.py (100%) rename {sunnypilot => openpilot/sunnypilot}/tools/__init__.py (100%) rename {sunnypilot => openpilot/sunnypilot}/tools/memory_profiler/__init__.py (100%) rename {sunnypilot => openpilot/sunnypilot}/tools/memory_profiler/mem_usage.py (100%) rename {sunnypilot => openpilot/sunnypilot}/tools/pull_footage.py (100%) rename {system => openpilot/system}/ui/sunnypilot/lib/application.py (100%) rename {system => openpilot/system}/ui/sunnypilot/lib/styles.py (100%) rename {system => openpilot/system}/ui/sunnypilot/lib/utils.py (100%) rename {system => openpilot/system}/ui/sunnypilot/widgets/__init__.py (100%) rename {system => openpilot/system}/ui/sunnypilot/widgets/helpers/__init__.py (100%) rename {system => openpilot/system}/ui/sunnypilot/widgets/helpers/fuzzy_search.py (100%) rename {system => openpilot/system}/ui/sunnypilot/widgets/helpers/star_icon.py (100%) rename {system => openpilot/system}/ui/sunnypilot/widgets/html_render.py (100%) rename {system => openpilot/system}/ui/sunnypilot/widgets/input_dialog.py (100%) rename {system => openpilot/system}/ui/sunnypilot/widgets/list_view.py (100%) rename {system => openpilot/system}/ui/sunnypilot/widgets/option_control.py (100%) rename {system => openpilot/system}/ui/sunnypilot/widgets/progress_bar.py (100%) rename {system => openpilot/system}/ui/sunnypilot/widgets/sunnylink_pairing_dialog.py (100%) rename {system => openpilot/system}/ui/sunnypilot/widgets/toggle.py (100%) rename {system => openpilot/system}/ui/sunnypilot/widgets/tree_dialog.py (100%) rename {third_party => openpilot/third_party}/copyparty/copyparty-sfx.py (100%) rename {third_party => openpilot/third_party}/mapd_pfeiferj/README.md (100%) rename {third_party => openpilot/third_party}/mapd_pfeiferj/mapd (100%) delete mode 120000 sunnypilot/selfdrive/car/car_list.json delete mode 100644 system/manager/process_config.py diff --git a/.github/workflows/badges.yaml b/.github/workflows/badges.yaml deleted file mode 100644 index d170a96368..0000000000 --- a/.github/workflows/badges.yaml +++ /dev/null @@ -1,35 +0,0 @@ -name: badges -on: - schedule: - - cron: '0 * * * *' - workflow_dispatch: - -env: - PYTHONPATH: ${{ github.workspace }} - -jobs: - badges: - name: create badges - runs-on: ubuntu-latest - if: github.repository == 'sunnypilot/sunnypilot' - permissions: - contents: write - steps: - - uses: actions/checkout@v6 - with: - submodules: true - - run: ./tools/op.sh setup - - name: Push badges - run: | - python3 selfdrive/ui/translations/create_badges.py - - rm .gitattributes - - git checkout --orphan badges - git rm -rf --cached . - git config user.email "badge-researcher@sunnypilot.ai" - git config user.name "Badge Researcher" - - git add translation_badge.svg - git commit -m "Add/Update badges" - git push -f origin HEAD diff --git a/.github/workflows/build-all-tinygrad-models.yaml b/.github/workflows/build-all-tinygrad-models.yaml index 1e341cb8ec..0eedb04703 100644 --- a/.github/workflows/build-all-tinygrad-models.yaml +++ b/.github/workflows/build-all-tinygrad-models.yaml @@ -30,7 +30,7 @@ jobs: run: | cd sunnypilot export PYTHONPATH=$(pwd) - ref=$(python3 sunnypilot/models/tinygrad_ref.py) + ref=$(python3 openpilot/sunnypilot/models/tinygrad_ref.py) echo "tinygrad_ref=$ref" >> $GITHUB_OUTPUT echo "tinygrad_ref is $ref" diff --git a/.github/workflows/cereal_validation.yaml b/.github/workflows/cereal_validation.yaml index 2ab617b2f0..0c87688bf1 100644 --- a/.github/workflows/cereal_validation.yaml +++ b/.github/workflows/cereal_validation.yaml @@ -6,7 +6,7 @@ on: - master pull_request: paths: - - 'cereal/**' + - 'openpilot/cereal/**' workflow_dispatch: workflow_call: inputs: @@ -30,11 +30,25 @@ jobs: - name: Checkout sunnypilot cereal uses: actions/checkout@v6 with: - sparse-checkout: cereal + sparse-checkout: | + openpilot/cereal + uv.lock + submodules: false - name: Init sunnypilot opendbc submodule run: git submodule update --init --depth 1 opendbc_repo + - name: Locate sunnypilot capnp import paths + id: locate-sp-capnp + run: | + SP_IMPORT_ARGS="" + SP_CAR_CAPNP=$(find opendbc_repo -maxdepth 4 -name car.capnp -path '*/opendbc/car/car.capnp' -printf '%h\n' -quit) + if [ -n "$SP_CAR_CAPNP" ]; then + SP_IMPORT_ARGS="-I $SP_CAR_CAPNP" + echo "Found sunnypilot car.capnp at: $SP_CAR_CAPNP" + fi + echo "import_args=$SP_IMPORT_ARGS" >> "$GITHUB_OUTPUT" + - name: Checkout upstream openpilot uses: actions/checkout@v6 with: @@ -65,20 +79,19 @@ jobs: fi echo "import_args=$IMPORT_ARGS" >> "$GITHUB_OUTPUT" - - name: Install uv - run: pip install uv + - name: Install pycapnp + run: | + PYCAPNP_VER=$(python3 -c "import re; m=re.search(r'name = \"pycapnp\"\nversion = \"([^\"]+)\"', open('uv.lock').read()); print(m.group(1))") + pip install "pycapnp==${PYCAPNP_VER}" - name: Generate sunnypilot schema run: | - PYCAPNP_VER=$(python3 -c "import re; m=re.search(r'name = \"pycapnp\"\nversion = \"([^\"]+)\"', open('uv.lock').read()); print(m.group(1))") - uv run --isolated --with "pycapnp==${PYCAPNP_VER}" \ - python3 cereal/messaging/tests/validate_sp_cereal_upstream.py \ - -g -f /tmp/sp_schema.json --cereal-dir cereal + python3 openpilot/cereal/messaging/tests/validate_sp_cereal_upstream.py \ + -g -f /tmp/sp_schema.json --cereal-dir openpilot/cereal \ + ${{ steps.locate-sp-capnp.outputs.import_args }} - name: Validate against upstream run: | - PYCAPNP_VER=$(python3 -c "import re; m=re.search(r'name = \"pycapnp\"\nversion = \"([^\"]+)\"', open('uv.lock').read()); print(m.group(1))") - uv run --isolated --with "pycapnp==${PYCAPNP_VER}" \ - python3 cereal/messaging/tests/validate_sp_cereal_upstream.py \ + python3 openpilot/cereal/messaging/tests/validate_sp_cereal_upstream.py \ -r -f /tmp/sp_schema.json --cereal-dir ${{ steps.locate-capnp.outputs.cereal_dir }} \ ${{ steps.locate-capnp.outputs.import_args }} diff --git a/.github/workflows/sunnypilot-build-model.yaml b/.github/workflows/sunnypilot-build-model.yaml index 3c5554fcc4..acb75af55e 100644 --- a/.github/workflows/sunnypilot-build-model.yaml +++ b/.github/workflows/sunnypilot-build-model.yaml @@ -6,7 +6,7 @@ env: SCONS_CACHE_DIR: ${{ github.workspace }}/release/ci/scons_cache UPSTREAM_REPO: "commaai/openpilot" TINYGRAD_PATH: ${{ github.workspace }}/tinygrad_repo - MODELS_DIR: ${{ github.workspace }}/selfdrive/modeld/models + MODELS_DIR: ${{ github.workspace }}/openpilot/selfdrive/modeld/models on: workflow_call: @@ -92,7 +92,7 @@ jobs: uses: actions/upload-artifact@v4 with: name: models-${{ env.REF }}${{ inputs.artifact_suffix }} - path: ${{ github.workspace }}/openpilot/selfdrive/modeld/models/*.onnx + path: ${{ github.workspace }}/openpilot/openpilot/selfdrive/modeld/models/*.onnx build_model: runs-on: [self-hosted, tici] @@ -128,7 +128,10 @@ jobs: # Set up common environment source /etc/profile; export UV_PROJECT_ENVIRONMENT=${HOME}/venv + export UV_PYTHON_PREFERENCE=managed + export UV_PYTHON_INSTALL_DIR=${HOME}/uv/python export VIRTUAL_ENV=$UV_PROJECT_ENVIRONMENT + uv sync printenv >> $GITHUB_ENV if [[ "${{ runner.debug }}" == "1" ]]; then cat $GITHUB_OUTPUT @@ -148,6 +151,7 @@ jobs: if [[ "${{ runner.debug }}" == "1" ]]; then printenv fi + source ${UV_PROJECT_ENVIRONMENT}/bin/activate PYTHONPATH=$PYTHONPATH:${{ github.workspace }}/ ${{ github.workspace }}/scripts/manage-powersave.py --disable rm -rf ${{ env.MODELS_DIR }}/*.onnx @@ -155,9 +159,9 @@ jobs: uses: actions/download-artifact@v4 with: name: models-${{ env.REF }}${{ inputs.artifact_suffix }} - path: ${{ github.workspace }}/selfdrive/modeld/models + path: ${{ env.MODELS_DIR }} - run: | - rm -f ${{ github.workspace }}/selfdrive/modeld/models/{dmonitoring_model,big_driving_policy,big_driving_vision}.onnx + rm -f ${{ env.MODELS_DIR }}/{dmonitoring_model,big_driving_policy,big_driving_vision}.onnx - name: Build Model run: | @@ -166,7 +170,7 @@ jobs: export VIRTUAL_ENV=$UV_PROJECT_ENVIRONMENT export PYTHONPATH="${PYTHONPATH}:${{ env.TINYGRAD_PATH }}:${{ github.workspace }}" - COMPILE_MODELD="${{ github.workspace }}/sunnypilot/modeld_v2/compile_modeld.py" + COMPILE_MODELD="${{ github.workspace }}/openpilot/sunnypilot/modeld_v2/compile_modeld.py" MODEL_SIZE=$(python3 -c "from openpilot.common.transformations.model import MEDMODEL_INPUT_SIZE as s; print(f'{s[0]}x{s[1]}')") CAMERA_RES=$(python3 -c "from openpilot.common.transformations.camera import _ar_ox_fisheye as a, _os_fisheye as o; print(f'{a.width}x{a.height} {o.width}x{o.height}')") TG_FLAGS="DEV=QCOM IMAGE=1 FLOAT16=1 NOLOCALS=1 JIT_BATCH_SIZE=0 OPENPILOT_HACKS=1" @@ -264,4 +268,5 @@ jobs: - name: Re-enable powersave if: always() run: | + source ${UV_PROJECT_ENVIRONMENT}/bin/activate PYTHONPATH=$PYTHONPATH:${{ github.workspace }}/ ${{ github.workspace }}/scripts/manage-powersave.py --enable diff --git a/.github/workflows/sunnypilot-build-prebuilt.yaml b/.github/workflows/sunnypilot-build-prebuilt.yaml index 977dc94972..12a3a7bce0 100644 --- a/.github/workflows/sunnypilot-build-prebuilt.yaml +++ b/.github/workflows/sunnypilot-build-prebuilt.yaml @@ -79,7 +79,7 @@ jobs: is_stable_branch="$(echo "$CONFIG" | jq -r '.stable_branch // false')"; echo "is_stable_branch=$is_stable_branch" >> $GITHUB_OUTPUT - stable_version=$(cat sunnypilot/common/version.h | grep SUNNYPILOT_VERSION | sed -e 's/[^0-9|.]//g'); + stable_version=$(cat openpilot/sunnypilot/common/version.h | grep SUNNYPILOT_VERSION | sed -e 's/[^0-9|.]//g'); echo "version=$([ "$is_stable_branch" = "true" ] && echo "$stable_version" || echo "$BUILD")" >> $GITHUB_OUTPUT echo "extra_version_identifier=${environment}" >> $GITHUB_OUTPUT fi @@ -152,7 +152,10 @@ jobs: # Set up common environment source /etc/profile; export UV_PROJECT_ENVIRONMENT=${HOME}/venv + export UV_PYTHON_PREFERENCE=managed + export UV_PYTHON_INSTALL_DIR=${HOME}/uv/python export VIRTUAL_ENV=$UV_PROJECT_ENVIRONMENT + uv sync printenv >> $GITHUB_ENV if [[ "${{ runner.debug }}" == "1" ]]; then cat $GITHUB_OUTPUT @@ -172,20 +175,26 @@ jobs: if [[ "${{ runner.debug }}" == "1" ]]; then printenv fi + source ${UV_PROJECT_ENVIRONMENT}/bin/activate PYTHONPATH=$PYTHONPATH:${{ github.workspace }}/ ${{ github.workspace }}/scripts/manage-powersave.py --disable - name: Build Main Project run: | export PYTHONPATH="$BUILD_DIR" - ./release/release_files.py | sort | uniq | rsync -rRl${RUNNER_DEBUG:+v} --files-from=- . $BUILD_DIR/ + ./tools/release/release_files.py | sort | uniq | rsync -rRl${RUNNER_DEBUG:+v} --files-from=- . $BUILD_DIR/ cd $BUILD_DIR + ln -sfn msgq_repo/msgq msgq + ln -sfn opendbc_repo/opendbc opendbc + ln -sfn rednose_repo/rednose rednose + ln -sfn teleoprtc_repo/teleoprtc teleoprtc + ln -sfn tinygrad_repo/tinygrad tinygrad sed -i '/from .board.jungle import PandaJungle, PandaJungleDFU/s/^/#/' panda/__init__.py echo "Building sunnypilot's modeld_v2..." - scons -j$(nproc) cache_dir=${{env.SCONS_CACHE_DIR}} --minimal sunnypilot/modeld_v2 + scons -j$(nproc) cache_dir=${{env.SCONS_CACHE_DIR}} --minimal openpilot/sunnypilot/modeld_v2 echo "Building sunnypilot's locationd..." - scons -j2 cache_dir=${{env.SCONS_CACHE_DIR}} --minimal sunnypilot/selfdrive/locationd + scons -j2 cache_dir=${{env.SCONS_CACHE_DIR}} --minimal openpilot/sunnypilot/selfdrive/locationd echo "Building openpilot's locationd..." - scons -j1 cache_dir=${{env.SCONS_CACHE_DIR}} --minimal selfdrive/locationd + scons -j1 cache_dir=${{env.SCONS_CACHE_DIR}} --minimal openpilot/selfdrive/locationd echo "Building rest of sunnypilot" scons -j$(nproc) cache_dir=${{env.SCONS_CACHE_DIR}} --minimal touch ${BUILD_DIR}/prebuilt @@ -208,17 +217,17 @@ jobs: --exclude='Jenkinsfile' \ --exclude='**/release/' \ --exclude='**/.github/' \ - --exclude='**/selfdrive/ui/replay/' \ + --exclude='**/openpilot/selfdrive/ui/replay/' \ --exclude='**/__pycache__/' \ --exclude='${{env.SCONS_CACHE_DIR}}' \ --exclude='**/.git/' \ --exclude='**/SConstruct' \ --exclude='**/SConscript' \ --exclude='**/.venv/' \ - --exclude='selfdrive/modeld/models/*.onnx*' \ - --exclude='sunnypilot/modeld*/models/*.onnx*' \ - --exclude='third_party/*x86*' \ - --exclude='third_party/*Darwin*' \ + --exclude='openpilot/selfdrive/modeld/models/*.onnx*' \ + --exclude='openpilot/sunnypilot/modeld*/models/*.onnx*' \ + --exclude='openpilot/third_party/*x86*' \ + --exclude='openpilot/third_party/*Darwin*' \ --delete-excluded \ --chown=comma:comma \ ${BUILD_DIR}/ ${OUTPUT_DIR}/ @@ -237,6 +246,7 @@ jobs: - name: Re-enable powersave if: always() run: | + source ${UV_PROJECT_ENVIRONMENT}/bin/activate PYTHONPATH=$PYTHONPATH:${{ github.workspace }}/ ${{ github.workspace }}/scripts/manage-powersave.py --enable @@ -363,7 +373,7 @@ jobs: owner: context.repo.owner, repo: context.repo.repo, issue_number: prNumber, - name: process.env.LABEL + name: process.env.LABELf }); console.log(`Removed '${process.env.LABEL}' label from PR #${prNumber}`); diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index b3ad59b346..b5f941fc76 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -45,7 +45,7 @@ jobs: max_attempts: 3 command: git lfs pull - name: Build devel - timeout-minutes: 1 + timeout-minutes: 3 run: TARGET_DIR=$STRIPPED_DIR tools/release/build_stripped.sh - run: ./tools/op.sh setup - name: Build openpilot and run checks @@ -116,6 +116,9 @@ jobs: steps: - uses: actions/checkout@v7 - run: ./tools/op.sh setup + - name: Install raylib headless dependencies + if: ${{ !contains(runner.name, 'nsc') }} + run: sudo apt-get install -y --no-install-recommends libgles2 libegl1 - name: Build openpilot run: scons - name: Run unit tests @@ -230,6 +233,9 @@ jobs: steps: - uses: actions/checkout@v7 - run: ./tools/op.sh setup + - name: Install raylib headless dependencies + if: ${{ !contains(runner.name, 'nsc') }} + run: sudo apt-get install -y --no-install-recommends libgles2 libegl1 - name: Build openpilot run: scons - name: Create UI Report diff --git a/.gitmodules b/.gitmodules index e2088276e2..a2d892d07f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -17,5 +17,5 @@ path = tinygrad_repo url = https://github.com/sunnypilot/tinygrad.git [submodule "sunnypilot/neural_network_data"] - path = sunnypilot/neural_network_data + path = openpilot/sunnypilot/neural_network_data url = https://github.com/sunnypilot/neural-network-data.git diff --git a/SConstruct b/SConstruct index 474f7f2090..fa3ba952c3 100644 --- a/SConstruct +++ b/SConstruct @@ -55,7 +55,7 @@ assert arch in [ "Darwin", # macOS arm64 (x86 not supported) ] -pkg_names = ['acados', 'bzip2', 'capnproto', 'catch2', 'ffmpeg', 'json11', 'ncurses', 'zeromq', 'zstd'] +pkg_names = ['acados', 'bzip2', 'capnproto', 'catch2', 'eigen', 'ffmpeg', 'json11', 'ncurses', 'zeromq', 'zstd'] pkgs = [importlib.import_module(name) for name in pkg_names] acados = pkgs[pkg_names.index('acados')] ffmpeg = pkgs[pkg_names.index('ffmpeg')] @@ -287,7 +287,7 @@ SConscript([ 'openpilot/selfdrive/ui/SConscript', ]) -SConscript(['sunnypilot/SConscript']) +SConscript(['openpilot/sunnypilot/SConscript']) # Build desktop-only tools if GetOption('extras') and arch != "larch64": diff --git a/launch_openpilot.sh b/launch_openpilot.sh index d4841b601f..0b3550aba8 100755 --- a/launch_openpilot.sh +++ b/launch_openpilot.sh @@ -4,7 +4,7 @@ IFS=$'\n\t' # On any failure, run the fallback launcher trap 'exec ./launch_chffrplus.sh' ERR -C3_LAUNCH_SH="./sunnypilot/system/hardware/c3/launch_chffrplus.sh" +C3_LAUNCH_SH="./openpilot/sunnypilot/system/hardware/c3/launch_chffrplus.sh" MODEL="$(tr -d '\0' < "/sys/firmware/devicetree/base/model")" export MODEL diff --git a/msgq_repo b/msgq_repo index a771d031ec..bb6cc57ef4 160000 --- a/msgq_repo +++ b/msgq_repo @@ -1 +1 @@ -Subproject commit a771d031ec58716824f365a89f0607fd786a1161 +Subproject commit bb6cc57ef4d9a3f9952d9ca84bfa580575e7e2a0 diff --git a/opendbc_repo b/opendbc_repo index 94858c07a9..0ed33dae96 160000 --- a/opendbc_repo +++ b/opendbc_repo @@ -1 +1 @@ -Subproject commit 94858c07a96924857f17823dd984feef292062e0 +Subproject commit 0ed33dae965d2f9cc2248a5946a4aa88d4531d63 diff --git a/common/api/__init__.py b/openpilot/common/api/__init__.py similarity index 100% rename from common/api/__init__.py rename to openpilot/common/api/__init__.py diff --git a/common/api/base.py b/openpilot/common/api/base.py similarity index 98% rename from common/api/base.py rename to openpilot/common/api/base.py index ddda6e6ae2..b58dd6bbd0 100644 --- a/common/api/base.py +++ b/openpilot/common/api/base.py @@ -4,7 +4,7 @@ import requests import unicodedata from datetime import datetime, timedelta, UTC from openpilot.common.hardware.hw import Paths -from openpilot.system.version import get_version +from openpilot.common.version import get_version # name: jwt signature algorithm KEYS = {"id_rsa": "RS256", diff --git a/common/api/comma_connect.py b/openpilot/common/api/comma_connect.py similarity index 100% rename from common/api/comma_connect.py rename to openpilot/common/api/comma_connect.py diff --git a/openpilot/selfdrive/car/helpers.py b/openpilot/selfdrive/car/helpers.py index 384152c71b..ec9e3efeeb 100644 --- a/openpilot/selfdrive/car/helpers.py +++ b/openpilot/selfdrive/car/helpers.py @@ -1,7 +1,7 @@ import capnp from typing import Any -from cereal import custom +from openpilot.cereal import custom from opendbc.car import structs _FIELDS = '__dataclass_fields__' # copy of dataclasses._FIELDS diff --git a/openpilot/selfdrive/modeld/compile_warp.py b/openpilot/selfdrive/modeld/compile_warp.py deleted file mode 100755 index 1144fc69c3..0000000000 --- a/openpilot/selfdrive/modeld/compile_warp.py +++ /dev/null @@ -1,201 +0,0 @@ -#!/usr/bin/env python3 -import time -import pickle -import numpy as np -from pathlib import Path -from tinygrad.tensor import Tensor -from tinygrad.helpers import Context -from tinygrad.device import Device -from tinygrad.engine.jit import TinyJit - -from openpilot.system.camerad.cameras.nv12_info import get_nv12_info -from openpilot.common.transformations.model import MEDMODEL_INPUT_SIZE, DM_INPUT_SIZE -from openpilot.common.transformations.camera import _ar_ox_fisheye, _os_fisheye - -MODELS_DIR = Path(__file__).parent / 'models' - -CAMERA_CONFIGS = [ - (_ar_ox_fisheye.width, _ar_ox_fisheye.height), # tici: 1928x1208 - (_os_fisheye.width, _os_fisheye.height), # mici: 1344x760 -] - -UV_SCALE_MATRIX = np.array([[0.5, 0, 0], [0, 0.5, 0], [0, 0, 1]], dtype=np.float32) -UV_SCALE_MATRIX_INV = np.linalg.inv(UV_SCALE_MATRIX) - -IMG_BUFFER_SHAPE = (30, MEDMODEL_INPUT_SIZE[1] // 2, MEDMODEL_INPUT_SIZE[0] // 2) - - -def warp_pkl_path(w, h): - return MODELS_DIR / f'warp_{w}x{h}_tinygrad.pkl' - - -def dm_warp_pkl_path(w, h): - return MODELS_DIR / f'dm_warp_{w}x{h}_tinygrad.pkl' - - -def warp_perspective_tinygrad(src_flat, M_inv, dst_shape, src_shape, stride_pad): - w_dst, h_dst = dst_shape - h_src, w_src = src_shape - - x = Tensor.arange(w_dst).reshape(1, w_dst).expand(h_dst, w_dst).reshape(-1) - y = Tensor.arange(h_dst).reshape(h_dst, 1).expand(h_dst, w_dst).reshape(-1) - - # inline 3x3 matmul as elementwise to avoid reduce op (enables fusion with gather) - src_x = M_inv[0, 0] * x + M_inv[0, 1] * y + M_inv[0, 2] - src_y = M_inv[1, 0] * x + M_inv[1, 1] * y + M_inv[1, 2] - src_w = M_inv[2, 0] * x + M_inv[2, 1] * y + M_inv[2, 2] - - src_x = src_x / src_w - src_y = src_y / src_w - - x_nn_clipped = Tensor.round(src_x).clip(0, w_src - 1).cast('int') - y_nn_clipped = Tensor.round(src_y).clip(0, h_src - 1).cast('int') - idx = y_nn_clipped * (w_src + stride_pad) + x_nn_clipped - - return src_flat[idx] - - -def frames_to_tensor(frames, model_w, model_h): - H = (frames.shape[0] * 2) // 3 - W = frames.shape[1] - in_img1 = Tensor.cat(frames[0:H:2, 0::2], - frames[1:H:2, 0::2], - frames[0:H:2, 1::2], - frames[1:H:2, 1::2], - frames[H:H+H//4].reshape((H//2, W//2)), - frames[H+H//4:H+H//2].reshape((H//2, W//2)), dim=0).reshape((6, H//2, W//2)) - return in_img1 - - -def make_frame_prepare(cam_w, cam_h, model_w, model_h): - stride, y_height, uv_height, _ = get_nv12_info(cam_w, cam_h) - uv_offset = stride * y_height - stride_pad = stride - cam_w - - def frame_prepare_tinygrad(input_frame, M_inv): - # UV_SCALE @ M_inv @ UV_SCALE_INV simplifies to elementwise scaling - M_inv_uv = M_inv * Tensor([[1.0, 1.0, 0.5], [1.0, 1.0, 0.5], [2.0, 2.0, 1.0]]) - # deinterleave NV12 UV plane (UVUV... -> separate U, V) - uv = input_frame[uv_offset:uv_offset + uv_height * stride].reshape(uv_height, stride) - with Context(SPLIT_REDUCEOP=0): - y = warp_perspective_tinygrad(input_frame[:cam_h*stride], - M_inv, (model_w, model_h), - (cam_h, cam_w), stride_pad).realize() - u = warp_perspective_tinygrad(uv[:cam_h//2, :cam_w:2].flatten(), - M_inv_uv, (model_w//2, model_h//2), - (cam_h//2, cam_w//2), 0).realize() - v = warp_perspective_tinygrad(uv[:cam_h//2, 1:cam_w:2].flatten(), - M_inv_uv, (model_w//2, model_h//2), - (cam_h//2, cam_w//2), 0).realize() - yuv = y.cat(u).cat(v).reshape((model_h * 3 // 2, model_w)) - tensor = frames_to_tensor(yuv, model_w, model_h) - return tensor - return frame_prepare_tinygrad - - -def make_update_img_input(frame_prepare, model_w, model_h): - def update_img_input_tinygrad(tensor, frame, M_inv): - M_inv = M_inv.to(Device.DEFAULT) - new_img = frame_prepare(frame, M_inv) - tensor.assign(tensor[6:].cat(new_img, dim=0).contiguous()) - return Tensor.cat(tensor[:6], tensor[-6:], dim=0).contiguous().reshape(1, 12, model_h//2, model_w//2) - return update_img_input_tinygrad - - -def make_update_both_imgs(frame_prepare, model_w, model_h): - update_img = make_update_img_input(frame_prepare, model_w, model_h) - - def update_both_imgs_tinygrad(calib_img_buffer, new_img, M_inv, - calib_big_img_buffer, new_big_img, M_inv_big): - calib_img_pair = update_img(calib_img_buffer, new_img, M_inv) - calib_big_img_pair = update_img(calib_big_img_buffer, new_big_img, M_inv_big) - return calib_img_pair, calib_big_img_pair - return update_both_imgs_tinygrad - - -def make_warp_dm(cam_w, cam_h, dm_w, dm_h): - stride, y_height, _, _ = get_nv12_info(cam_w, cam_h) - stride_pad = stride - cam_w - - def warp_dm(input_frame, M_inv): - M_inv = M_inv.to(Device.DEFAULT) - result = warp_perspective_tinygrad(input_frame[:cam_h*stride], M_inv, (dm_w, dm_h), (cam_h, cam_w), stride_pad).reshape(-1, dm_h * dm_w) - return result - return warp_dm - - -def compile_modeld_warp(cam_w, cam_h): - model_w, model_h = MEDMODEL_INPUT_SIZE - _, _, _, yuv_size = get_nv12_info(cam_w, cam_h) - - print(f"Compiling modeld warp for {cam_w}x{cam_h}...") - - frame_prepare = make_frame_prepare(cam_w, cam_h, model_w, model_h) - update_both_imgs = make_update_both_imgs(frame_prepare, model_w, model_h) - update_img_jit = TinyJit(update_both_imgs, prune=True) - - full_buffer = Tensor.zeros(IMG_BUFFER_SHAPE, dtype='uint8').contiguous().realize() - big_full_buffer = Tensor.zeros(IMG_BUFFER_SHAPE, dtype='uint8').contiguous().realize() - new_frame_np = np.random.randint(0, 256, yuv_size, dtype=np.uint8) - new_big_frame_np = np.random.randint(0, 256, yuv_size, dtype=np.uint8) - for i in range(10): - img_inputs = [full_buffer, - Tensor.from_blob(new_frame_np.ctypes.data, (yuv_size,), dtype='uint8').realize(), - Tensor(Tensor.randn(3, 3).mul(8).realize().numpy(), device='NPY')] - big_img_inputs = [big_full_buffer, - Tensor.from_blob(new_big_frame_np.ctypes.data, (yuv_size,), dtype='uint8').realize(), - Tensor(Tensor.randn(3, 3).mul(8).realize().numpy(), device='NPY')] - inputs = img_inputs + big_img_inputs - Device.default.synchronize() - - st = time.perf_counter() - _ = update_img_jit(*inputs) - mt = time.perf_counter() - Device.default.synchronize() - et = time.perf_counter() - print(f" [{i+1}/10] enqueue {(mt-st)*1e3:6.2f} ms -- total {(et-st)*1e3:6.2f} ms") - - pkl_path = warp_pkl_path(cam_w, cam_h) - with open(pkl_path, "wb") as f: - pickle.dump(update_img_jit, f) - print(f" Saved to {pkl_path}") - - jit = pickle.load(open(pkl_path, "rb")) - jit(*inputs) - - -def compile_dm_warp(cam_w, cam_h): - dm_w, dm_h = DM_INPUT_SIZE - _, _, _, yuv_size = get_nv12_info(cam_w, cam_h) - - print(f"Compiling DM warp for {cam_w}x{cam_h}...") - - warp_dm = make_warp_dm(cam_w, cam_h, dm_w, dm_h) - warp_dm_jit = TinyJit(warp_dm, prune=True) - - new_frame_np = np.random.randint(0, 256, yuv_size, dtype=np.uint8) - for i in range(10): - inputs = [Tensor.from_blob(new_frame_np.ctypes.data, (yuv_size,), dtype='uint8').realize(), - Tensor(Tensor.randn(3, 3).mul(8).realize().numpy(), device='NPY')] - Device.default.synchronize() - st = time.perf_counter() - warp_dm_jit(*inputs) - mt = time.perf_counter() - Device.default.synchronize() - et = time.perf_counter() - print(f" [{i+1}/10] enqueue {(mt-st)*1e3:6.2f} ms -- total {(et-st)*1e3:6.2f} ms") - - pkl_path = dm_warp_pkl_path(cam_w, cam_h) - with open(pkl_path, "wb") as f: - pickle.dump(warp_dm_jit, f) - print(f" Saved to {pkl_path}") - - -def run_and_save_pickle(): - for cam_w, cam_h in CAMERA_CONFIGS: - compile_modeld_warp(cam_w, cam_h) - compile_dm_warp(cam_w, cam_h) - - -if __name__ == "__main__": - run_and_save_pickle() diff --git a/openpilot/selfdrive/monitoring/test_monitoring.py b/openpilot/selfdrive/monitoring/test_monitoring.py index 2312afb2f5..e42e72d645 100644 --- a/openpilot/selfdrive/monitoring/test_monitoring.py +++ b/openpilot/selfdrive/monitoring/test_monitoring.py @@ -1,4 +1,3 @@ -import numpy as np import pytest from openpilot.cereal import log @@ -271,10 +270,10 @@ def test_run_step_engagement(selfdrive_enabled, lat_active, steering, gas, captured = {} orig = dm._update_events - def spy(driver_engaged, op_engaged, standstill, wrong_gear): + def spy(driver_engaged, op_engaged, lowspeed, wrong_gear): captured['driver_engaged'] = driver_engaged captured['op_engaged'] = op_engaged - return orig(driver_engaged, op_engaged, standstill, wrong_gear) + return orig(driver_engaged, op_engaged, lowspeed, wrong_gear) dm._update_events = spy dm.run_step(sm, demo=False) diff --git a/selfdrive/ui/sunnypilot/__init__.py b/openpilot/selfdrive/ui/sunnypilot/__init__.py similarity index 100% rename from selfdrive/ui/sunnypilot/__init__.py rename to openpilot/selfdrive/ui/sunnypilot/__init__.py diff --git a/selfdrive/ui/sunnypilot/layouts/__init__.py b/openpilot/selfdrive/ui/sunnypilot/layouts/__init__.py similarity index 100% rename from selfdrive/ui/sunnypilot/layouts/__init__.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/__init__.py diff --git a/selfdrive/ui/sunnypilot/layouts/onboarding.py b/openpilot/selfdrive/ui/sunnypilot/layouts/onboarding.py similarity index 98% rename from selfdrive/ui/sunnypilot/layouts/onboarding.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/onboarding.py index 7e532678b0..a86677a7b1 100644 --- a/selfdrive/ui/sunnypilot/layouts/onboarding.py +++ b/openpilot/selfdrive/ui/sunnypilot/layouts/onboarding.py @@ -11,7 +11,7 @@ from openpilot.system.ui.lib.multilang import tr from openpilot.system.ui.widgets import Widget from openpilot.system.ui.widgets.button import Button, ButtonStyle from openpilot.system.ui.widgets.label import Label -from openpilot.system.version import sunnylink_consent_version, sunnylink_consent_declined +from openpilot.common.version import sunnylink_consent_version, sunnylink_consent_declined class SunnylinkConsentPage(Widget): diff --git a/selfdrive/ui/sunnypilot/layouts/settings/__init__.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/__init__.py similarity index 100% rename from selfdrive/ui/sunnypilot/layouts/settings/__init__.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/settings/__init__.py diff --git a/selfdrive/ui/sunnypilot/layouts/settings/cruise.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/cruise.py similarity index 100% rename from selfdrive/ui/sunnypilot/layouts/settings/cruise.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/settings/cruise.py diff --git a/selfdrive/ui/sunnypilot/layouts/settings/cruise_sub_layouts/speed_limit_policy.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/cruise_sub_layouts/speed_limit_policy.py similarity index 100% rename from selfdrive/ui/sunnypilot/layouts/settings/cruise_sub_layouts/speed_limit_policy.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/settings/cruise_sub_layouts/speed_limit_policy.py diff --git a/selfdrive/ui/sunnypilot/layouts/settings/cruise_sub_layouts/speed_limit_settings.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/cruise_sub_layouts/speed_limit_settings.py similarity index 100% rename from selfdrive/ui/sunnypilot/layouts/settings/cruise_sub_layouts/speed_limit_settings.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/settings/cruise_sub_layouts/speed_limit_settings.py diff --git a/selfdrive/ui/sunnypilot/layouts/settings/developer.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/developer.py similarity index 100% rename from selfdrive/ui/sunnypilot/layouts/settings/developer.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/settings/developer.py diff --git a/selfdrive/ui/sunnypilot/layouts/settings/device.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/device.py similarity index 100% rename from selfdrive/ui/sunnypilot/layouts/settings/device.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/settings/device.py diff --git a/selfdrive/ui/sunnypilot/layouts/settings/display.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/display.py similarity index 100% rename from selfdrive/ui/sunnypilot/layouts/settings/display.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/settings/display.py diff --git a/selfdrive/ui/sunnypilot/layouts/settings/models.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/models.py similarity index 99% rename from selfdrive/ui/sunnypilot/layouts/settings/models.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/settings/models.py index 587c3560c9..7a175b4037 100644 --- a/selfdrive/ui/sunnypilot/layouts/settings/models.py +++ b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/models.py @@ -9,7 +9,7 @@ import re import time import pyray as rl -from cereal import custom +from openpilot.cereal import custom from openpilot.sunnypilot.models.default_model import DEFAULT_MODEL from openpilot.common.constants import CV from openpilot.selfdrive.ui.ui_state import device, ui_state diff --git a/selfdrive/ui/sunnypilot/layouts/settings/navigation.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/navigation.py similarity index 100% rename from selfdrive/ui/sunnypilot/layouts/settings/navigation.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/settings/navigation.py diff --git a/selfdrive/ui/sunnypilot/layouts/settings/network.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/network.py similarity index 100% rename from selfdrive/ui/sunnypilot/layouts/settings/network.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/settings/network.py diff --git a/selfdrive/ui/sunnypilot/layouts/settings/osm.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/osm.py similarity index 100% rename from selfdrive/ui/sunnypilot/layouts/settings/osm.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/settings/osm.py diff --git a/selfdrive/ui/sunnypilot/layouts/settings/settings.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/settings.py similarity index 100% rename from selfdrive/ui/sunnypilot/layouts/settings/settings.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/settings/settings.py diff --git a/selfdrive/ui/sunnypilot/layouts/settings/software.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/software.py similarity index 97% rename from selfdrive/ui/sunnypilot/layouts/settings/software.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/settings/software.py index a07bda1e34..d067f1330d 100644 --- a/selfdrive/ui/sunnypilot/layouts/settings/software.py +++ b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/software.py @@ -4,7 +4,7 @@ Copyright (c) 2021-, Haibin Wen, sunnypilot, and a number of other contributors. This file is part of sunnypilot and is licensed under the MIT License. See the LICENSE.md file in the root directory for more details. """ -import os +import subprocess from openpilot.selfdrive.ui.layouts.settings.software import SoftwareLayout from openpilot.selfdrive.ui.ui_state import ui_state @@ -78,7 +78,7 @@ class SoftwareLayoutSP(SoftwareLayout): if selection: ui_state.params.put("UpdaterTargetBranch", selection) self._branch_btn.action_item.set_value(selection) - os.system("pkill -SIGUSR1 -f system.updated.updated") + subprocess.run(["pkill", "-SIGUSR1", "-f", "openpilot.system.updated.updated"], check=False) self._branch_dialog = None self._branch_dialog = TreeOptionDialog(tr("Select a branch"), folders, current_target, "", diff --git a/selfdrive/ui/sunnypilot/layouts/settings/steering.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/steering.py similarity index 99% rename from selfdrive/ui/sunnypilot/layouts/settings/steering.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/settings/steering.py index a5cd626483..15cb6a15e0 100644 --- a/selfdrive/ui/sunnypilot/layouts/settings/steering.py +++ b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/steering.py @@ -4,7 +4,7 @@ Copyright (c) 2021-, Haibin Wen, sunnypilot, and a number of other contributors. This file is part of sunnypilot and is licensed under the MIT License. See the LICENSE.md file in the root directory for more details. """ -from cereal import car +from opendbc.car.structs import car from enum import IntEnum from openpilot.selfdrive.ui.ui_state import ui_state diff --git a/selfdrive/ui/sunnypilot/layouts/settings/steering_sub_layouts/lane_change_settings.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/steering_sub_layouts/lane_change_settings.py similarity index 100% rename from selfdrive/ui/sunnypilot/layouts/settings/steering_sub_layouts/lane_change_settings.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/settings/steering_sub_layouts/lane_change_settings.py diff --git a/selfdrive/ui/sunnypilot/layouts/settings/steering_sub_layouts/mads_settings.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/steering_sub_layouts/mads_settings.py similarity index 100% rename from selfdrive/ui/sunnypilot/layouts/settings/steering_sub_layouts/mads_settings.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/settings/steering_sub_layouts/mads_settings.py diff --git a/selfdrive/ui/sunnypilot/layouts/settings/steering_sub_layouts/torque_settings.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/steering_sub_layouts/torque_settings.py similarity index 98% rename from selfdrive/ui/sunnypilot/layouts/settings/steering_sub_layouts/torque_settings.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/settings/steering_sub_layouts/torque_settings.py index d4976b1295..f3c4419e45 100644 --- a/selfdrive/ui/sunnypilot/layouts/settings/steering_sub_layouts/torque_settings.py +++ b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/steering_sub_layouts/torque_settings.py @@ -21,7 +21,7 @@ from openpilot.system.ui.widgets import Widget, DialogResult from openpilot.system.ui.widgets.network import NavButton from openpilot.system.ui.widgets.scroller_tici import Scroller -TORQUE_VERSIONS_PATH = os.path.join(BASEDIR, "sunnypilot", "selfdrive", "controls", "lib", "latcontrol_torque_versions.json") +TORQUE_VERSIONS_PATH = os.path.join(BASEDIR, "openpilot", "sunnypilot", "selfdrive", "controls", "lib", "latcontrol_torque_versions.json") class TorqueSettingsLayout(Widget): diff --git a/selfdrive/ui/sunnypilot/layouts/settings/sunnylink.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/sunnylink.py similarity index 99% rename from selfdrive/ui/sunnypilot/layouts/settings/sunnylink.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/settings/sunnylink.py index 1d9b99d5fd..5e75e797cb 100644 --- a/selfdrive/ui/sunnypilot/layouts/settings/sunnylink.py +++ b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/sunnylink.py @@ -5,7 +5,7 @@ This file is part of sunnypilot and is licensed under the MIT License. See the LICENSE.md file in the root directory for more details. """ import pyray as rl -from cereal import custom +from openpilot.cereal import custom from openpilot.selfdrive.ui.sunnypilot.layouts.onboarding import SunnylinkConsentPage from openpilot.selfdrive.ui.ui_state import ui_state from openpilot.sunnypilot.sunnylink.api import UNREGISTERED_SUNNYLINK_DONGLE_ID @@ -20,7 +20,7 @@ from openpilot.system.ui.widgets.confirm_dialog import alert_dialog, ConfirmDial from openpilot.system.ui.widgets.label import UnifiedLabel from openpilot.system.ui.widgets.list_view import dual_button_item from openpilot.system.ui.widgets.scroller_tici import Scroller, LineSeparator -from openpilot.system.version import sunnylink_consent_version +from openpilot.common.version import sunnylink_consent_version class SunnylinkHeader(Widget): diff --git a/selfdrive/ui/sunnypilot/layouts/settings/trips.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/trips.py similarity index 100% rename from selfdrive/ui/sunnypilot/layouts/settings/trips.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/settings/trips.py diff --git a/selfdrive/ui/sunnypilot/layouts/settings/vehicle/__init__.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/__init__.py similarity index 100% rename from selfdrive/ui/sunnypilot/layouts/settings/vehicle/__init__.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/__init__.py diff --git a/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/__init__.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/__init__.py similarity index 100% rename from selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/__init__.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/__init__.py diff --git a/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/base.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/base.py similarity index 100% rename from selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/base.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/base.py diff --git a/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/body.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/body.py similarity index 100% rename from selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/body.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/body.py diff --git a/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/chrysler.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/chrysler.py similarity index 100% rename from selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/chrysler.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/chrysler.py diff --git a/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/factory.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/factory.py similarity index 100% rename from selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/factory.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/factory.py diff --git a/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/ford.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/ford.py similarity index 100% rename from selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/ford.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/ford.py diff --git a/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/gm.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/gm.py similarity index 100% rename from selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/gm.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/gm.py diff --git a/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/honda.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/honda.py similarity index 100% rename from selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/honda.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/honda.py diff --git a/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/hyundai.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/hyundai.py similarity index 100% rename from selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/hyundai.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/hyundai.py diff --git a/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/mazda.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/mazda.py similarity index 100% rename from selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/mazda.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/mazda.py diff --git a/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/nissan.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/nissan.py similarity index 100% rename from selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/nissan.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/nissan.py diff --git a/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/psa.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/psa.py similarity index 100% rename from selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/psa.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/psa.py diff --git a/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/rivian.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/rivian.py similarity index 100% rename from selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/rivian.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/rivian.py diff --git a/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/subaru.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/subaru.py similarity index 100% rename from selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/subaru.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/subaru.py diff --git a/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/tesla.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/tesla.py similarity index 100% rename from selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/tesla.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/tesla.py diff --git a/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/toyota.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/toyota.py similarity index 100% rename from selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/toyota.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/toyota.py diff --git a/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/volkswagen.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/volkswagen.py similarity index 100% rename from selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/volkswagen.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/volkswagen.py diff --git a/selfdrive/ui/sunnypilot/layouts/settings/vehicle/platform_selector.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/platform_selector.py similarity index 98% rename from selfdrive/ui/sunnypilot/layouts/settings/vehicle/platform_selector.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/platform_selector.py index 6102e8e9b7..aab935d4b8 100644 --- a/selfdrive/ui/sunnypilot/layouts/settings/vehicle/platform_selector.py +++ b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/vehicle/platform_selector.py @@ -21,7 +21,7 @@ from openpilot.system.ui.sunnypilot.lib.styles import style from openpilot.system.ui.sunnypilot.widgets.tree_dialog import TreeOptionDialog, TreeNode, TreeFolder from openpilot.selfdrive.ui.ui_state import ui_state -CAR_LIST_JSON_OUT = os.path.join(BASEDIR, "sunnypilot", "selfdrive", "car", "car_list.json") +CAR_LIST_JSON_OUT = os.path.join(BASEDIR, "openpilot", "sunnypilot", "selfdrive", "car", "car_list.json") class LegendWidget(Widget): diff --git a/selfdrive/ui/sunnypilot/layouts/settings/visuals.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/visuals.py similarity index 100% rename from selfdrive/ui/sunnypilot/layouts/settings/visuals.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/settings/visuals.py diff --git a/selfdrive/ui/sunnypilot/layouts/sidebar.py b/openpilot/selfdrive/ui/sunnypilot/layouts/sidebar.py similarity index 100% rename from selfdrive/ui/sunnypilot/layouts/sidebar.py rename to openpilot/selfdrive/ui/sunnypilot/layouts/sidebar.py diff --git a/selfdrive/ui/sunnypilot/mici/__init__.py b/openpilot/selfdrive/ui/sunnypilot/mici/__init__.py similarity index 100% rename from selfdrive/ui/sunnypilot/mici/__init__.py rename to openpilot/selfdrive/ui/sunnypilot/mici/__init__.py diff --git a/selfdrive/ui/sunnypilot/mici/layouts/__init__.py b/openpilot/selfdrive/ui/sunnypilot/mici/layouts/__init__.py similarity index 100% rename from selfdrive/ui/sunnypilot/mici/layouts/__init__.py rename to openpilot/selfdrive/ui/sunnypilot/mici/layouts/__init__.py diff --git a/selfdrive/ui/sunnypilot/mici/layouts/models.py b/openpilot/selfdrive/ui/sunnypilot/mici/layouts/models.py similarity index 99% rename from selfdrive/ui/sunnypilot/mici/layouts/models.py rename to openpilot/selfdrive/ui/sunnypilot/mici/layouts/models.py index 138ff87b75..5f3f77d62c 100644 --- a/selfdrive/ui/sunnypilot/mici/layouts/models.py +++ b/openpilot/selfdrive/ui/sunnypilot/mici/layouts/models.py @@ -7,7 +7,7 @@ See the LICENSE.md file in the root directory for more details. from collections.abc import Callable import pyray as rl -from cereal import custom +from openpilot.cereal import custom from openpilot.sunnypilot.models.default_model import DEFAULT_MODEL from openpilot.selfdrive.ui.mici.widgets.button import BigButton from openpilot.selfdrive.ui.sunnypilot.layouts.settings.models import ModelsLayout diff --git a/selfdrive/ui/sunnypilot/mici/layouts/onboarding.py b/openpilot/selfdrive/ui/sunnypilot/mici/layouts/onboarding.py similarity index 100% rename from selfdrive/ui/sunnypilot/mici/layouts/onboarding.py rename to openpilot/selfdrive/ui/sunnypilot/mici/layouts/onboarding.py diff --git a/selfdrive/ui/sunnypilot/mici/layouts/settings.py b/openpilot/selfdrive/ui/sunnypilot/mici/layouts/settings.py similarity index 100% rename from selfdrive/ui/sunnypilot/mici/layouts/settings.py rename to openpilot/selfdrive/ui/sunnypilot/mici/layouts/settings.py diff --git a/selfdrive/ui/sunnypilot/mici/layouts/sunnylink.py b/openpilot/selfdrive/ui/sunnypilot/mici/layouts/sunnylink.py similarity index 99% rename from selfdrive/ui/sunnypilot/mici/layouts/sunnylink.py rename to openpilot/selfdrive/ui/sunnypilot/mici/layouts/sunnylink.py index 85ebf55f46..e804c78035 100644 --- a/selfdrive/ui/sunnypilot/mici/layouts/sunnylink.py +++ b/openpilot/selfdrive/ui/sunnypilot/mici/layouts/sunnylink.py @@ -8,7 +8,7 @@ import pyray as rl from collections.abc import Callable -from cereal import custom +from openpilot.cereal import custom from openpilot.selfdrive.ui.mici.widgets.button import BigButton, BigToggle from openpilot.selfdrive.ui.mici.widgets.dialog import BigDialog, BigConfirmationDialog from openpilot.selfdrive.ui.sunnypilot.mici.layouts.onboarding import SunnylinkConsentPage @@ -20,7 +20,7 @@ from openpilot.system.ui.lib.multilang import tr from openpilot.system.ui.widgets import Widget from openpilot.system.ui.widgets.label import UnifiedLabel from openpilot.system.ui.widgets.scroller import NavScroller -from openpilot.system.version import sunnylink_consent_version, sunnylink_consent_declined +from openpilot.common.version import sunnylink_consent_version, sunnylink_consent_declined class SunnylinkInfo(Widget): def __init__(self): diff --git a/selfdrive/ui/sunnypilot/mici/onroad/__init__.py b/openpilot/selfdrive/ui/sunnypilot/mici/onroad/__init__.py similarity index 100% rename from selfdrive/ui/sunnypilot/mici/onroad/__init__.py rename to openpilot/selfdrive/ui/sunnypilot/mici/onroad/__init__.py diff --git a/selfdrive/ui/sunnypilot/mici/onroad/confidence_ball.py b/openpilot/selfdrive/ui/sunnypilot/mici/onroad/confidence_ball.py similarity index 100% rename from selfdrive/ui/sunnypilot/mici/onroad/confidence_ball.py rename to openpilot/selfdrive/ui/sunnypilot/mici/onroad/confidence_ball.py diff --git a/selfdrive/ui/sunnypilot/mici/onroad/hud_renderer.py b/openpilot/selfdrive/ui/sunnypilot/mici/onroad/hud_renderer.py similarity index 100% rename from selfdrive/ui/sunnypilot/mici/onroad/hud_renderer.py rename to openpilot/selfdrive/ui/sunnypilot/mici/onroad/hud_renderer.py diff --git a/selfdrive/ui/sunnypilot/mici/onroad/model_renderer.py b/openpilot/selfdrive/ui/sunnypilot/mici/onroad/model_renderer.py similarity index 100% rename from selfdrive/ui/sunnypilot/mici/onroad/model_renderer.py rename to openpilot/selfdrive/ui/sunnypilot/mici/onroad/model_renderer.py diff --git a/selfdrive/ui/sunnypilot/mici/widgets/__init__.py b/openpilot/selfdrive/ui/sunnypilot/mici/widgets/__init__.py similarity index 100% rename from selfdrive/ui/sunnypilot/mici/widgets/__init__.py rename to openpilot/selfdrive/ui/sunnypilot/mici/widgets/__init__.py diff --git a/selfdrive/ui/sunnypilot/mici/widgets/sunnylink_pairing_dialog.py b/openpilot/selfdrive/ui/sunnypilot/mici/widgets/sunnylink_pairing_dialog.py similarity index 100% rename from selfdrive/ui/sunnypilot/mici/widgets/sunnylink_pairing_dialog.py rename to openpilot/selfdrive/ui/sunnypilot/mici/widgets/sunnylink_pairing_dialog.py diff --git a/selfdrive/ui/sunnypilot/onroad/__init__.py b/openpilot/selfdrive/ui/sunnypilot/onroad/__init__.py similarity index 100% rename from selfdrive/ui/sunnypilot/onroad/__init__.py rename to openpilot/selfdrive/ui/sunnypilot/onroad/__init__.py diff --git a/selfdrive/ui/sunnypilot/onroad/alert_renderer.py b/openpilot/selfdrive/ui/sunnypilot/onroad/alert_renderer.py similarity index 100% rename from selfdrive/ui/sunnypilot/onroad/alert_renderer.py rename to openpilot/selfdrive/ui/sunnypilot/onroad/alert_renderer.py diff --git a/selfdrive/ui/sunnypilot/onroad/augmented_road_view.py b/openpilot/selfdrive/ui/sunnypilot/onroad/augmented_road_view.py similarity index 100% rename from selfdrive/ui/sunnypilot/onroad/augmented_road_view.py rename to openpilot/selfdrive/ui/sunnypilot/onroad/augmented_road_view.py diff --git a/selfdrive/ui/sunnypilot/onroad/blind_spot_indicators.py b/openpilot/selfdrive/ui/sunnypilot/onroad/blind_spot_indicators.py similarity index 100% rename from selfdrive/ui/sunnypilot/onroad/blind_spot_indicators.py rename to openpilot/selfdrive/ui/sunnypilot/onroad/blind_spot_indicators.py diff --git a/selfdrive/ui/sunnypilot/onroad/chevron_metrics.py b/openpilot/selfdrive/ui/sunnypilot/onroad/chevron_metrics.py similarity index 97% rename from selfdrive/ui/sunnypilot/onroad/chevron_metrics.py rename to openpilot/selfdrive/ui/sunnypilot/onroad/chevron_metrics.py index a8a342c129..1dded3fc62 100644 --- a/selfdrive/ui/sunnypilot/onroad/chevron_metrics.py +++ b/openpilot/selfdrive/ui/sunnypilot/onroad/chevron_metrics.py @@ -128,8 +128,8 @@ class ChevronMetrics: lead_one = radar_state.leadOne lead_two = radar_state.leadTwo - has_lead_one = lead_one.status if lead_one else False - has_lead_two = lead_two.status if lead_two else False + has_lead_one = lead_one.present if lead_one else False + has_lead_two = lead_two.present if lead_two else False self.update_alpha(has_lead_one or has_lead_two) diff --git a/selfdrive/ui/sunnypilot/onroad/circular_alerts.py b/openpilot/selfdrive/ui/sunnypilot/onroad/circular_alerts.py similarity index 99% rename from selfdrive/ui/sunnypilot/onroad/circular_alerts.py rename to openpilot/selfdrive/ui/sunnypilot/onroad/circular_alerts.py index f90fc81914..c44e4455eb 100644 --- a/selfdrive/ui/sunnypilot/onroad/circular_alerts.py +++ b/openpilot/selfdrive/ui/sunnypilot/onroad/circular_alerts.py @@ -6,7 +6,7 @@ See the LICENSE.md file in the root directory for more details. """ import pyray as rl -from cereal import log +from openpilot.cereal import log from openpilot.selfdrive.ui import UI_BORDER_SIZE from openpilot.selfdrive.ui.ui_state import ui_state from openpilot.selfdrive.ui.sunnypilot.onroad.developer_ui import DeveloperUiState diff --git a/selfdrive/ui/sunnypilot/onroad/developer_ui/__init__.py b/openpilot/selfdrive/ui/sunnypilot/onroad/developer_ui/__init__.py similarity index 100% rename from selfdrive/ui/sunnypilot/onroad/developer_ui/__init__.py rename to openpilot/selfdrive/ui/sunnypilot/onroad/developer_ui/__init__.py diff --git a/selfdrive/ui/sunnypilot/onroad/developer_ui/elements.py b/openpilot/selfdrive/ui/sunnypilot/onroad/developer_ui/elements.py similarity index 99% rename from selfdrive/ui/sunnypilot/onroad/developer_ui/elements.py rename to openpilot/selfdrive/ui/sunnypilot/onroad/developer_ui/elements.py index 389692d30b..4119990f22 100644 --- a/selfdrive/ui/sunnypilot/onroad/developer_ui/elements.py +++ b/openpilot/selfdrive/ui/sunnypilot/onroad/developer_ui/elements.py @@ -42,7 +42,7 @@ class LeadInfoElement: @staticmethod def get_lead_status(sm): lead_one = sm['radarState'].leadOne - return lead_one.status, lead_one.dRel, lead_one.vRel + return lead_one.present, lead_one.dRel, lead_one.vRel @staticmethod def get_lead_color(lead_d_rel: float, lead_v_rel: float = 0.0, use_v_rel: bool = False) -> rl.Color: diff --git a/selfdrive/ui/sunnypilot/onroad/driver_state.py b/openpilot/selfdrive/ui/sunnypilot/onroad/driver_state.py similarity index 100% rename from selfdrive/ui/sunnypilot/onroad/driver_state.py rename to openpilot/selfdrive/ui/sunnypilot/onroad/driver_state.py diff --git a/selfdrive/ui/sunnypilot/onroad/hud_renderer.py b/openpilot/selfdrive/ui/sunnypilot/onroad/hud_renderer.py similarity index 100% rename from selfdrive/ui/sunnypilot/onroad/hud_renderer.py rename to openpilot/selfdrive/ui/sunnypilot/onroad/hud_renderer.py diff --git a/selfdrive/ui/sunnypilot/onroad/model_renderer.py b/openpilot/selfdrive/ui/sunnypilot/onroad/model_renderer.py similarity index 100% rename from selfdrive/ui/sunnypilot/onroad/model_renderer.py rename to openpilot/selfdrive/ui/sunnypilot/onroad/model_renderer.py diff --git a/selfdrive/ui/sunnypilot/onroad/rainbow_path.py b/openpilot/selfdrive/ui/sunnypilot/onroad/rainbow_path.py similarity index 100% rename from selfdrive/ui/sunnypilot/onroad/rainbow_path.py rename to openpilot/selfdrive/ui/sunnypilot/onroad/rainbow_path.py diff --git a/selfdrive/ui/sunnypilot/onroad/road_name.py b/openpilot/selfdrive/ui/sunnypilot/onroad/road_name.py similarity index 100% rename from selfdrive/ui/sunnypilot/onroad/road_name.py rename to openpilot/selfdrive/ui/sunnypilot/onroad/road_name.py diff --git a/selfdrive/ui/sunnypilot/onroad/rocket_fuel.py b/openpilot/selfdrive/ui/sunnypilot/onroad/rocket_fuel.py similarity index 100% rename from selfdrive/ui/sunnypilot/onroad/rocket_fuel.py rename to openpilot/selfdrive/ui/sunnypilot/onroad/rocket_fuel.py diff --git a/selfdrive/ui/sunnypilot/onroad/smart_cruise_control.py b/openpilot/selfdrive/ui/sunnypilot/onroad/smart_cruise_control.py similarity index 100% rename from selfdrive/ui/sunnypilot/onroad/smart_cruise_control.py rename to openpilot/selfdrive/ui/sunnypilot/onroad/smart_cruise_control.py diff --git a/selfdrive/ui/sunnypilot/onroad/speed_limit.py b/openpilot/selfdrive/ui/sunnypilot/onroad/speed_limit.py similarity index 99% rename from selfdrive/ui/sunnypilot/onroad/speed_limit.py rename to openpilot/selfdrive/ui/sunnypilot/onroad/speed_limit.py index bfa311c357..7851698683 100644 --- a/selfdrive/ui/sunnypilot/onroad/speed_limit.py +++ b/openpilot/selfdrive/ui/sunnypilot/onroad/speed_limit.py @@ -9,7 +9,7 @@ from dataclasses import dataclass from enum import StrEnum import pyray as rl -from cereal import custom +from openpilot.cereal import custom from openpilot.common.constants import CV from openpilot.selfdrive.ui.onroad.hud_renderer import UI_CONFIG from openpilot.selfdrive.ui.ui_state import ui_state diff --git a/selfdrive/ui/sunnypilot/onroad/speed_renderer.py b/openpilot/selfdrive/ui/sunnypilot/onroad/speed_renderer.py similarity index 100% rename from selfdrive/ui/sunnypilot/onroad/speed_renderer.py rename to openpilot/selfdrive/ui/sunnypilot/onroad/speed_renderer.py diff --git a/selfdrive/ui/sunnypilot/onroad/turn_signal.py b/openpilot/selfdrive/ui/sunnypilot/onroad/turn_signal.py similarity index 100% rename from selfdrive/ui/sunnypilot/onroad/turn_signal.py rename to openpilot/selfdrive/ui/sunnypilot/onroad/turn_signal.py diff --git a/selfdrive/ui/sunnypilot/ui_state.py b/openpilot/selfdrive/ui/sunnypilot/ui_state.py similarity index 99% rename from selfdrive/ui/sunnypilot/ui_state.py rename to openpilot/selfdrive/ui/sunnypilot/ui_state.py index 1c21c35c6f..4b91bd4021 100644 --- a/selfdrive/ui/sunnypilot/ui_state.py +++ b/openpilot/selfdrive/ui/sunnypilot/ui_state.py @@ -6,7 +6,8 @@ See the LICENSE.md file in the root directory for more details. """ from enum import Enum -from cereal import messaging, log, car, custom +from openpilot.cereal import messaging, log, custom +from opendbc.car.structs import car from openpilot.common.params import Params from openpilot.selfdrive.ui.sunnypilot.layouts.settings.display import OnroadBrightness from openpilot.sunnypilot.sunnylink.sunnylink_state import SunnylinkState diff --git a/openpilot/sunnypilot b/openpilot/sunnypilot deleted file mode 120000 index c4ca692907..0000000000 --- a/openpilot/sunnypilot +++ /dev/null @@ -1 +0,0 @@ -../sunnypilot \ No newline at end of file diff --git a/sunnypilot/SConscript b/openpilot/sunnypilot/SConscript similarity index 100% rename from sunnypilot/SConscript rename to openpilot/sunnypilot/SConscript diff --git a/sunnypilot/__init__.py b/openpilot/sunnypilot/__init__.py similarity index 100% rename from sunnypilot/__init__.py rename to openpilot/sunnypilot/__init__.py diff --git a/sunnypilot/common/transformations/SConscript b/openpilot/sunnypilot/common/transformations/SConscript similarity index 100% rename from sunnypilot/common/transformations/SConscript rename to openpilot/sunnypilot/common/transformations/SConscript diff --git a/sunnypilot/common/transformations/coordinates.cc b/openpilot/sunnypilot/common/transformations/coordinates.cc similarity index 100% rename from sunnypilot/common/transformations/coordinates.cc rename to openpilot/sunnypilot/common/transformations/coordinates.cc diff --git a/sunnypilot/common/transformations/coordinates.hpp b/openpilot/sunnypilot/common/transformations/coordinates.hpp similarity index 100% rename from sunnypilot/common/transformations/coordinates.hpp rename to openpilot/sunnypilot/common/transformations/coordinates.hpp diff --git a/sunnypilot/common/transformations/orientation.cc b/openpilot/sunnypilot/common/transformations/orientation.cc similarity index 100% rename from sunnypilot/common/transformations/orientation.cc rename to openpilot/sunnypilot/common/transformations/orientation.cc diff --git a/sunnypilot/common/transformations/orientation.hpp b/openpilot/sunnypilot/common/transformations/orientation.hpp similarity index 100% rename from sunnypilot/common/transformations/orientation.hpp rename to openpilot/sunnypilot/common/transformations/orientation.hpp diff --git a/sunnypilot/common/version.h b/openpilot/sunnypilot/common/version.h similarity index 100% rename from sunnypilot/common/version.h rename to openpilot/sunnypilot/common/version.h diff --git a/sunnypilot/livedelay/__init__.py b/openpilot/sunnypilot/livedelay/__init__.py similarity index 100% rename from sunnypilot/livedelay/__init__.py rename to openpilot/sunnypilot/livedelay/__init__.py diff --git a/sunnypilot/livedelay/helpers.py b/openpilot/sunnypilot/livedelay/helpers.py similarity index 100% rename from sunnypilot/livedelay/helpers.py rename to openpilot/sunnypilot/livedelay/helpers.py diff --git a/sunnypilot/livedelay/lagd_toggle.py b/openpilot/sunnypilot/livedelay/lagd_toggle.py similarity index 97% rename from sunnypilot/livedelay/lagd_toggle.py rename to openpilot/sunnypilot/livedelay/lagd_toggle.py index 279aa353a3..3926cbebf6 100644 --- a/sunnypilot/livedelay/lagd_toggle.py +++ b/openpilot/sunnypilot/livedelay/lagd_toggle.py @@ -4,7 +4,7 @@ Copyright (c) 2021-, Haibin Wen, sunnypilot, and a number of other contributors. This file is part of sunnypilot and is licensed under the MIT License. See the LICENSE.md file in the root directory for more details. """ -from cereal import log +from openpilot.cereal import log from opendbc.car import structs from openpilot.common.params import Params diff --git a/sunnypilot/mads/helpers.py b/openpilot/sunnypilot/mads/helpers.py similarity index 100% rename from sunnypilot/mads/helpers.py rename to openpilot/sunnypilot/mads/helpers.py diff --git a/sunnypilot/mads/mads.py b/openpilot/sunnypilot/mads/mads.py similarity index 99% rename from sunnypilot/mads/mads.py rename to openpilot/sunnypilot/mads/mads.py index b0a90f82b5..4ae3534b57 100644 --- a/sunnypilot/mads/mads.py +++ b/openpilot/sunnypilot/mads/mads.py @@ -5,7 +5,7 @@ This file is part of sunnypilot and is licensed under the MIT License. See the LICENSE.md file in the root directory for more details. """ -from cereal import log, custom +from openpilot.cereal import log, custom from opendbc.car import structs from opendbc.car.hyundai.values import HyundaiFlags diff --git a/sunnypilot/mads/state.py b/openpilot/sunnypilot/mads/state.py similarity index 99% rename from sunnypilot/mads/state.py rename to openpilot/sunnypilot/mads/state.py index 73240c790c..a8e5e1892f 100644 --- a/sunnypilot/mads/state.py +++ b/openpilot/sunnypilot/mads/state.py @@ -5,7 +5,7 @@ This file is part of sunnypilot and is licensed under the MIT License. See the LICENSE.md file in the root directory for more details. """ -from cereal import log, custom +from openpilot.cereal import log, custom from openpilot.selfdrive.selfdrived.events import ET from openpilot.selfdrive.selfdrived.state import SOFT_DISABLE_TIME from openpilot.common.realtime import DT_CTRL diff --git a/sunnypilot/mads/tests/test_mads_state_machine.py b/openpilot/sunnypilot/mads/tests/test_mads_state_machine.py similarity index 99% rename from sunnypilot/mads/tests/test_mads_state_machine.py rename to openpilot/sunnypilot/mads/tests/test_mads_state_machine.py index 7bc556a0fc..1782d04975 100644 --- a/sunnypilot/mads/tests/test_mads_state_machine.py +++ b/openpilot/sunnypilot/mads/tests/test_mads_state_machine.py @@ -8,7 +8,7 @@ See the LICENSE.md file in the root directory for more details. import pytest from pytest_mock import MockerFixture -from cereal import custom +from openpilot.cereal import custom from openpilot.common.realtime import DT_CTRL from openpilot.sunnypilot.mads.state import StateMachine, SOFT_DISABLE_TIME from openpilot.selfdrive.selfdrived.events import ET, NormalPermanentAlert, Events diff --git a/sunnypilot/mads/tests/test_mads_steering_mode.py b/openpilot/sunnypilot/mads/tests/test_mads_steering_mode.py similarity index 99% rename from sunnypilot/mads/tests/test_mads_steering_mode.py rename to openpilot/sunnypilot/mads/tests/test_mads_steering_mode.py index 8765324cfd..3b7e27a86f 100644 --- a/sunnypilot/mads/tests/test_mads_steering_mode.py +++ b/openpilot/sunnypilot/mads/tests/test_mads_steering_mode.py @@ -7,7 +7,7 @@ See the LICENSE.md file in the root directory for more details. import pytest -from cereal import log, custom +from openpilot.cereal import log, custom from opendbc.car import structs from openpilot.selfdrive.selfdrived.events import Events from openpilot.sunnypilot.selfdrive.selfdrived.events import EventsSP diff --git a/sunnypilot/mapd/__init__.py b/openpilot/sunnypilot/mapd/__init__.py similarity index 56% rename from sunnypilot/mapd/__init__.py rename to openpilot/sunnypilot/mapd/__init__.py index 7ad6f74149..57525254ce 100644 --- a/sunnypilot/mapd/__init__.py +++ b/openpilot/sunnypilot/mapd/__init__.py @@ -1,5 +1,5 @@ import os from openpilot.common.basedir import BASEDIR -MAPD_BIN_DIR = os.path.join(BASEDIR, 'third_party/mapd_pfeiferj') +MAPD_BIN_DIR = os.path.join(BASEDIR, 'openpilot', 'third_party/mapd_pfeiferj') MAPD_PATH = os.path.join(MAPD_BIN_DIR, 'mapd') diff --git a/sunnypilot/mapd/live_map_data/__init__.py b/openpilot/sunnypilot/mapd/live_map_data/__init__.py similarity index 100% rename from sunnypilot/mapd/live_map_data/__init__.py rename to openpilot/sunnypilot/mapd/live_map_data/__init__.py diff --git a/sunnypilot/mapd/live_map_data/base_map_data.py b/openpilot/sunnypilot/mapd/live_map_data/base_map_data.py similarity index 97% rename from sunnypilot/mapd/live_map_data/base_map_data.py rename to openpilot/sunnypilot/mapd/live_map_data/base_map_data.py index 723864dd2a..ca79ce1c6b 100644 --- a/sunnypilot/mapd/live_map_data/base_map_data.py +++ b/openpilot/sunnypilot/mapd/live_map_data/base_map_data.py @@ -6,7 +6,7 @@ See the LICENSE.md file in the root directory for more details. """ from abc import abstractmethod, ABC -import cereal.messaging as messaging +import openpilot.cereal.messaging as messaging from openpilot.common.params import Params from openpilot.common.constants import CV from openpilot.selfdrive.car.cruise import V_CRUISE_UNSET diff --git a/sunnypilot/mapd/live_map_data/debug.py b/openpilot/sunnypilot/mapd/live_map_data/debug.py similarity index 87% rename from sunnypilot/mapd/live_map_data/debug.py rename to openpilot/sunnypilot/mapd/live_map_data/debug.py index 794f2ef8ff..00783d58df 100644 --- a/sunnypilot/mapd/live_map_data/debug.py +++ b/openpilot/sunnypilot/mapd/live_map_data/debug.py @@ -12,12 +12,12 @@ See the LICENSE.md file in the root directory for more details. import threading import traceback -from cereal import messaging +from openpilot.cereal import messaging from openpilot.common.gps import get_gps_location_service from openpilot.common.params import Params from openpilot.common.realtime import config_realtime_process -from openpilot.sunnypilot.selfdrive.controls.lib.speed_limit_controller.common import Policy -from openpilot.sunnypilot.selfdrive.controls.lib.speed_limit_controller.speed_limit_resolver import SpeedLimitResolver +from openpilot.sunnypilot.selfdrive.controls.lib.speed_limit.common import Policy +from openpilot.sunnypilot.selfdrive.controls.lib.speed_limit.speed_limit_resolver import SpeedLimitResolver from openpilot.sunnypilot.mapd.live_map_data import get_debug diff --git a/sunnypilot/mapd/live_map_data/osm_map_data.py b/openpilot/sunnypilot/mapd/live_map_data/osm_map_data.py similarity index 98% rename from sunnypilot/mapd/live_map_data/osm_map_data.py rename to openpilot/sunnypilot/mapd/live_map_data/osm_map_data.py index e2a4ec667f..e6cbce0674 100644 --- a/sunnypilot/mapd/live_map_data/osm_map_data.py +++ b/openpilot/sunnypilot/mapd/live_map_data/osm_map_data.py @@ -8,7 +8,7 @@ import json import math import platform -from cereal import log +from openpilot.cereal import log from openpilot.common.params import Params from openpilot.sunnypilot.mapd.live_map_data.base_map_data import BaseMapData from openpilot.sunnypilot.navd.helpers import Coordinate diff --git a/sunnypilot/mapd/live_map_data/standalone.py b/openpilot/sunnypilot/mapd/live_map_data/standalone.py similarity index 100% rename from sunnypilot/mapd/live_map_data/standalone.py rename to openpilot/sunnypilot/mapd/live_map_data/standalone.py diff --git a/sunnypilot/mapd/mapd_installer.py b/openpilot/sunnypilot/mapd/mapd_installer.py similarity index 98% rename from sunnypilot/mapd/mapd_installer.py rename to openpilot/sunnypilot/mapd/mapd_installer.py index 1e36732dda..9f2e72720a 100755 --- a/sunnypilot/mapd/mapd_installer.py +++ b/openpilot/sunnypilot/mapd/mapd_installer.py @@ -14,11 +14,11 @@ import requests from pathlib import Path from urllib.request import urlopen -from cereal import messaging +from openpilot.cereal import messaging from openpilot.common.params import Params from openpilot.common.hardware.hw import Paths from openpilot.common.spinner import Spinner -from openpilot.system.version import is_prebuilt +from openpilot.common.version import is_prebuilt from openpilot.sunnypilot.mapd import MAPD_PATH, MAPD_BIN_DIR import openpilot.system.sentry as sentry diff --git a/sunnypilot/mapd/mapd_manager.py b/openpilot/sunnypilot/mapd/mapd_manager.py similarity index 100% rename from sunnypilot/mapd/mapd_manager.py rename to openpilot/sunnypilot/mapd/mapd_manager.py diff --git a/sunnypilot/mapd/tests/__init__.py b/openpilot/sunnypilot/mapd/tests/__init__.py similarity index 100% rename from sunnypilot/mapd/tests/__init__.py rename to openpilot/sunnypilot/mapd/tests/__init__.py diff --git a/sunnypilot/mapd/tests/mapd_hash b/openpilot/sunnypilot/mapd/tests/mapd_hash similarity index 100% rename from sunnypilot/mapd/tests/mapd_hash rename to openpilot/sunnypilot/mapd/tests/mapd_hash diff --git a/sunnypilot/mapd/tests/test_mapd_version.py b/openpilot/sunnypilot/mapd/tests/test_mapd_version.py similarity index 100% rename from sunnypilot/mapd/tests/test_mapd_version.py rename to openpilot/sunnypilot/mapd/tests/test_mapd_version.py diff --git a/sunnypilot/mapd/update_version.py b/openpilot/sunnypilot/mapd/update_version.py similarity index 93% rename from sunnypilot/mapd/update_version.py rename to openpilot/sunnypilot/mapd/update_version.py index c5e08b3f8f..b6ca2a757f 100755 --- a/sunnypilot/mapd/update_version.py +++ b/openpilot/sunnypilot/mapd/update_version.py @@ -13,8 +13,8 @@ from openpilot.sunnypilot import get_file_hash from openpilot.common.basedir import BASEDIR from openpilot.sunnypilot.mapd import MAPD_PATH -MAPD_HASH_PATH = os.path.join(BASEDIR, "sunnypilot", "mapd", "tests", "mapd_hash") -MAPD_VERSION_PATH = os.path.join(BASEDIR, "sunnypilot", "mapd", "mapd_installer.py") +MAPD_HASH_PATH = os.path.join(BASEDIR, "openpilot", "sunnypilot", "mapd", "tests", "mapd_hash") +MAPD_VERSION_PATH = os.path.join(BASEDIR, "openpilot", "sunnypilot", "mapd", "mapd_installer.py") def update_mapd_hash(): diff --git a/sunnypilot/mapd/version.py b/openpilot/sunnypilot/mapd/version.py similarity index 100% rename from sunnypilot/mapd/version.py rename to openpilot/sunnypilot/mapd/version.py diff --git a/sunnypilot/modeld_v2/.gitignore b/openpilot/sunnypilot/modeld_v2/.gitignore similarity index 100% rename from sunnypilot/modeld_v2/.gitignore rename to openpilot/sunnypilot/modeld_v2/.gitignore diff --git a/sunnypilot/modeld_v2/SConscript b/openpilot/sunnypilot/modeld_v2/SConscript similarity index 93% rename from sunnypilot/modeld_v2/SConscript rename to openpilot/sunnypilot/modeld_v2/SConscript index 723a1b3408..81affc625a 100644 --- a/sunnypilot/modeld_v2/SConscript +++ b/openpilot/sunnypilot/modeld_v2/SConscript @@ -38,7 +38,7 @@ camera_res_args = ' '.join(f'{cw}x{ch}' for cw, ch in CAMERA_CONFIGS) pythonpath_string = 'PYTHONPATH="${PYTHONPATH}:' + env.Dir("#tinygrad_repo").abspath + ':' + env.Dir("#").abspath + '"' compile_modeld_script = File("compile_modeld.py").abspath -upstream_compile_script = File(Dir("#selfdrive/modeld").File("compile_modeld.py").abspath) +upstream_compile_script = File(Dir("#openpilot/selfdrive/modeld").File("compile_modeld.py").abspath) script_deps = [File("compile_modeld.py"), upstream_compile_script] def compile_combined(model_type, onnx_args, output_name): @@ -84,10 +84,10 @@ if os.path.isfile(supercombo_onnx): 'driving_combined_supercombo_tinygrad.pkl') if PC: - inputs = tinygrad_files + [File(Dir("#sunnypilot/modeld_v2").File("install_models_pc.py").abspath)] + inputs = tinygrad_files + [File(Dir("#openpilot/sunnypilot/modeld_v2").File("install_models_pc.py").abspath)] outputs = [] model_dir = Dir("models").abspath - cmd = f'python3 {Dir("#sunnypilot/modeld_v2").abspath}/install_models_pc.py {model_dir}' + cmd = f'python3 {Dir("#openpilot/sunnypilot/modeld_v2").abspath}/install_models_pc.py {model_dir}' for model_name in ['supercombo', 'driving_vision', 'driving_off_policy', 'driving_on_policy', 'driving_policy']: if File(f"models/{model_name}.onnx").exists(): diff --git a/sunnypilot/modeld_v2/__init__.py b/openpilot/sunnypilot/modeld_v2/__init__.py similarity index 100% rename from sunnypilot/modeld_v2/__init__.py rename to openpilot/sunnypilot/modeld_v2/__init__.py diff --git a/sunnypilot/modeld_v2/camera_offset_helper.py b/openpilot/sunnypilot/modeld_v2/camera_offset_helper.py similarity index 100% rename from sunnypilot/modeld_v2/camera_offset_helper.py rename to openpilot/sunnypilot/modeld_v2/camera_offset_helper.py diff --git a/sunnypilot/modeld_v2/compile_modeld.py b/openpilot/sunnypilot/modeld_v2/compile_modeld.py similarity index 100% rename from sunnypilot/modeld_v2/compile_modeld.py rename to openpilot/sunnypilot/modeld_v2/compile_modeld.py diff --git a/sunnypilot/modeld_v2/constants.py b/openpilot/sunnypilot/modeld_v2/constants.py similarity index 100% rename from sunnypilot/modeld_v2/constants.py rename to openpilot/sunnypilot/modeld_v2/constants.py diff --git a/sunnypilot/modeld_v2/fill_model_msg.py b/openpilot/sunnypilot/modeld_v2/fill_model_msg.py similarity index 99% rename from sunnypilot/modeld_v2/fill_model_msg.py rename to openpilot/sunnypilot/modeld_v2/fill_model_msg.py index 1f281258ba..7d7854be11 100644 --- a/sunnypilot/modeld_v2/fill_model_msg.py +++ b/openpilot/sunnypilot/modeld_v2/fill_model_msg.py @@ -1,7 +1,7 @@ import os import capnp import numpy as np -from cereal import log +from openpilot.cereal import log from openpilot.sunnypilot.modeld_v2.constants import ModelConstants, Plan from openpilot.sunnypilot.models.helpers import plan_x_idxs_helper from openpilot.selfdrive.controls.lib.drive_helpers import get_curvature_from_plan diff --git a/sunnypilot/modeld_v2/get_model_metadata.py b/openpilot/sunnypilot/modeld_v2/get_model_metadata.py similarity index 100% rename from sunnypilot/modeld_v2/get_model_metadata.py rename to openpilot/sunnypilot/modeld_v2/get_model_metadata.py diff --git a/sunnypilot/modeld_v2/install_models_pc.py b/openpilot/sunnypilot/modeld_v2/install_models_pc.py similarity index 94% rename from sunnypilot/modeld_v2/install_models_pc.py rename to openpilot/sunnypilot/modeld_v2/install_models_pc.py index 8000c01cbe..7bc2f4797c 100755 --- a/sunnypilot/modeld_v2/install_models_pc.py +++ b/openpilot/sunnypilot/modeld_v2/install_models_pc.py @@ -6,7 +6,7 @@ import codecs from pathlib import Path from openpilot.common.hardware.hw import Paths -from sunnypilot.modeld_v2.get_model_metadata import MetadataOnnxPBParser, get_name_and_shape, get_metadata_value_by_name +from openpilot.sunnypilot.modeld_v2.get_model_metadata import MetadataOnnxPBParser, get_name_and_shape, get_metadata_value_by_name def generate_metadata_pkl(model_path, output_path): diff --git a/sunnypilot/modeld_v2/meta_20hz.py b/openpilot/sunnypilot/modeld_v2/meta_20hz.py similarity index 100% rename from sunnypilot/modeld_v2/meta_20hz.py rename to openpilot/sunnypilot/modeld_v2/meta_20hz.py diff --git a/sunnypilot/modeld_v2/meta_helper.py b/openpilot/sunnypilot/modeld_v2/meta_helper.py similarity index 96% rename from sunnypilot/modeld_v2/meta_helper.py rename to openpilot/sunnypilot/modeld_v2/meta_helper.py index 3fa10b2415..bcf73adc6f 100644 --- a/sunnypilot/modeld_v2/meta_helper.py +++ b/openpilot/sunnypilot/modeld_v2/meta_helper.py @@ -1,5 +1,5 @@ from openpilot.sunnypilot.modeld_v2.constants import Meta -from cereal import custom +from openpilot.cereal import custom from openpilot.sunnypilot.modeld_v2.meta_20hz import Meta20hz from openpilot.sunnypilot.models.helpers import get_active_bundle diff --git a/sunnypilot/modeld_v2/modeld b/openpilot/sunnypilot/modeld_v2/modeld similarity index 100% rename from sunnypilot/modeld_v2/modeld rename to openpilot/sunnypilot/modeld_v2/modeld diff --git a/sunnypilot/modeld_v2/modeld.py b/openpilot/sunnypilot/modeld_v2/modeld.py similarity index 98% rename from sunnypilot/modeld_v2/modeld.py rename to openpilot/sunnypilot/modeld_v2/modeld.py index 08d3e9d476..86d5b05868 100755 --- a/sunnypilot/modeld_v2/modeld.py +++ b/openpilot/sunnypilot/modeld_v2/modeld.py @@ -16,10 +16,11 @@ if USBGPU: import pickle import time import numpy as np -import cereal.messaging as messaging -from cereal import car, log +import openpilot.cereal.messaging as messaging +from openpilot.cereal import log +from opendbc.car.structs import car from setproctitle import setproctitle -from cereal.messaging import PubMaster, SubMaster +from openpilot.cereal.messaging import PubMaster, SubMaster from msgq.visionipc import VisionIpcClient, VisionStreamType, VisionBuf from opendbc.car.car_helpers import get_demo_car_params from openpilot.common.swaglog import cloudlog @@ -41,7 +42,7 @@ from openpilot.sunnypilot.livedelay.helpers import get_lat_delay from openpilot.sunnypilot.modeld_v2.modeld_base import ModelStateBase from openpilot.sunnypilot.models.helpers import get_active_bundle -PROCESS_NAME = "selfdrive.modeld.modeld_tinygrad" +PROCESS_NAME = "openpilot.selfdrive.modeld.modeld_tinygrad" def _pkl_exists(path): @@ -103,10 +104,10 @@ class ModelState(ModelStateBase): from openpilot.sunnypilot.modeld_v2.compile_modeld import derive_frame_skip, make_split_input_queues from tinygrad.device import Device - from openpilot.common.file_chunker import read_file_chunked + from openpilot.common.file_chunker import open_file_chunked cloudlog.warning(f"loading combined pkl: {pkl_path}") - jits = pickle.loads(read_file_chunked(pkl_path)) + jits = pickle.load(open_file_chunked(pkl_path)) self.DEV = Device.DEFAULT diff --git a/sunnypilot/modeld_v2/modeld_base.py b/openpilot/sunnypilot/modeld_v2/modeld_base.py similarity index 100% rename from sunnypilot/modeld_v2/modeld_base.py rename to openpilot/sunnypilot/modeld_v2/modeld_base.py diff --git a/sunnypilot/modeld_v2/parse_model_outputs.py b/openpilot/sunnypilot/modeld_v2/parse_model_outputs.py similarity index 100% rename from sunnypilot/modeld_v2/parse_model_outputs.py rename to openpilot/sunnypilot/modeld_v2/parse_model_outputs.py diff --git a/sunnypilot/modeld_v2/parse_model_outputs_split.py b/openpilot/sunnypilot/modeld_v2/parse_model_outputs_split.py similarity index 100% rename from sunnypilot/modeld_v2/parse_model_outputs_split.py rename to openpilot/sunnypilot/modeld_v2/parse_model_outputs_split.py diff --git a/sunnypilot/modeld_v2/tests/__init__.py b/openpilot/sunnypilot/modeld_v2/tests/__init__.py similarity index 100% rename from sunnypilot/modeld_v2/tests/__init__.py rename to openpilot/sunnypilot/modeld_v2/tests/__init__.py diff --git a/sunnypilot/modeld_v2/tests/conftest.py b/openpilot/sunnypilot/modeld_v2/tests/conftest.py similarity index 100% rename from sunnypilot/modeld_v2/tests/conftest.py rename to openpilot/sunnypilot/modeld_v2/tests/conftest.py diff --git a/sunnypilot/modeld_v2/tests/test_camera_offset_helper.py b/openpilot/sunnypilot/modeld_v2/tests/test_camera_offset_helper.py similarity index 100% rename from sunnypilot/modeld_v2/tests/test_camera_offset_helper.py rename to openpilot/sunnypilot/modeld_v2/tests/test_camera_offset_helper.py diff --git a/sunnypilot/modeld_v2/tests/test_combined_pkl_loader.py b/openpilot/sunnypilot/modeld_v2/tests/test_combined_pkl_loader.py similarity index 100% rename from sunnypilot/modeld_v2/tests/test_combined_pkl_loader.py rename to openpilot/sunnypilot/modeld_v2/tests/test_combined_pkl_loader.py diff --git a/sunnypilot/modeld_v2/tests/test_compile_modeld.py b/openpilot/sunnypilot/modeld_v2/tests/test_compile_modeld.py similarity index 100% rename from sunnypilot/modeld_v2/tests/test_compile_modeld.py rename to openpilot/sunnypilot/modeld_v2/tests/test_compile_modeld.py diff --git a/sunnypilot/modeld_v2/tests/test_recovery_power.py b/openpilot/sunnypilot/modeld_v2/tests/test_recovery_power.py similarity index 98% rename from sunnypilot/modeld_v2/tests/test_recovery_power.py rename to openpilot/sunnypilot/modeld_v2/tests/test_recovery_power.py index cfa2272386..ac716a5981 100644 --- a/sunnypilot/modeld_v2/tests/test_recovery_power.py +++ b/openpilot/sunnypilot/modeld_v2/tests/test_recovery_power.py @@ -1,6 +1,6 @@ import numpy as np -from cereal import log +from openpilot.cereal import log from openpilot.sunnypilot.modeld_v2.constants import Plan from openpilot.sunnypilot.modeld_v2.modeld import ModelState diff --git a/sunnypilot/modeld_v2/tests/test_warp.py b/openpilot/sunnypilot/modeld_v2/tests/test_warp.py similarity index 100% rename from sunnypilot/modeld_v2/tests/test_warp.py rename to openpilot/sunnypilot/modeld_v2/tests/test_warp.py diff --git a/sunnypilot/modeld_v2/warp.py b/openpilot/sunnypilot/modeld_v2/warp.py similarity index 100% rename from sunnypilot/modeld_v2/warp.py rename to openpilot/sunnypilot/modeld_v2/warp.py diff --git a/sunnypilot/models/README.md b/openpilot/sunnypilot/models/README.md similarity index 100% rename from sunnypilot/models/README.md rename to openpilot/sunnypilot/models/README.md diff --git a/sunnypilot/models/__init__.py b/openpilot/sunnypilot/models/__init__.py similarity index 100% rename from sunnypilot/models/__init__.py rename to openpilot/sunnypilot/models/__init__.py diff --git a/sunnypilot/models/constants.py b/openpilot/sunnypilot/models/constants.py similarity index 100% rename from sunnypilot/models/constants.py rename to openpilot/sunnypilot/models/constants.py diff --git a/sunnypilot/models/default_model.py b/openpilot/sunnypilot/models/default_model.py similarity index 84% rename from sunnypilot/models/default_model.py rename to openpilot/sunnypilot/models/default_model.py index 552f3a5769..62b6831402 100755 --- a/sunnypilot/models/default_model.py +++ b/openpilot/sunnypilot/models/default_model.py @@ -6,9 +6,9 @@ from openpilot.common.basedir import BASEDIR from openpilot.sunnypilot import get_file_hash from openpilot.sunnypilot.models.model_name import DEFAULT_MODEL -DEFAULT_MODEL_NAME_PATH = os.path.join(BASEDIR, "sunnypilot", "models", "model_name.py") -MODEL_HASH_PATH = os.path.join(BASEDIR, "sunnypilot", "models", "tests", "model_hash") -SUPERCOMBO_ONNX_PATH = os.path.join(BASEDIR, "selfdrive", "modeld", "models", "driving_supercombo.onnx") +DEFAULT_MODEL_NAME_PATH = os.path.join(BASEDIR, "openpilot", "sunnypilot", "models", "model_name.py") +MODEL_HASH_PATH = os.path.join(BASEDIR, "openpilot", "sunnypilot", "models", "tests", "model_hash") +SUPERCOMBO_ONNX_PATH = os.path.join(BASEDIR, "openpilot", "selfdrive", "modeld", "models", "driving_supercombo.onnx") def update_model_hash(): diff --git a/sunnypilot/models/fetcher.py b/openpilot/sunnypilot/models/fetcher.py similarity index 99% rename from sunnypilot/models/fetcher.py rename to openpilot/sunnypilot/models/fetcher.py index 6484f2b444..b5197988bb 100644 --- a/sunnypilot/models/fetcher.py +++ b/openpilot/sunnypilot/models/fetcher.py @@ -13,7 +13,7 @@ from openpilot.common.params import Params from openpilot.common.swaglog import cloudlog from openpilot.sunnypilot.models.helpers import is_bundle_version_compatible -from cereal import custom +from openpilot.cereal import custom class ModelParser: diff --git a/sunnypilot/models/helpers.py b/openpilot/sunnypilot/models/helpers.py similarity index 97% rename from sunnypilot/models/helpers.py rename to openpilot/sunnypilot/models/helpers.py index e81c3a5365..a9156ac62e 100644 --- a/sunnypilot/models/helpers.py +++ b/openpilot/sunnypilot/models/helpers.py @@ -11,7 +11,7 @@ import pickle from pathlib import Path import numpy as np -from cereal import custom +from openpilot.cereal import custom from openpilot.common.params import Params from openpilot.common.swaglog import cloudlog from openpilot.sunnypilot.models.constants import Meta, MetaSimPose, MetaTombRaider @@ -27,9 +27,10 @@ _LAST_VALIDATED_RAW = None def _compute_hash(file_path: str) -> str | None: - from openpilot.common.file_chunker import read_file_chunked + from openpilot.common.file_chunker import open_file_chunked try: - return hashlib.sha256(read_file_chunked(file_path)).hexdigest().lower() + with open_file_chunked(file_path) as file: + return hashlib.file_digest(file, "sha256").hexdigest().lower() except FileNotFoundError: return None diff --git a/sunnypilot/models/manager.py b/openpilot/sunnypilot/models/manager.py similarity index 99% rename from sunnypilot/models/manager.py rename to openpilot/sunnypilot/models/manager.py index 02730dd270..405220d2e4 100644 --- a/sunnypilot/models/manager.py +++ b/openpilot/sunnypilot/models/manager.py @@ -15,7 +15,7 @@ from openpilot.common.realtime import Ratekeeper from openpilot.common.swaglog import cloudlog from openpilot.common.hardware.hw import Paths -from cereal import messaging, custom +from openpilot.cereal import messaging, custom from openpilot.sunnypilot.models.fetcher import ModelFetcher from openpilot.sunnypilot.models.helpers import get_active_bundle, validate_active_bundle, verify_file diff --git a/sunnypilot/models/model_name.py b/openpilot/sunnypilot/models/model_name.py similarity index 100% rename from sunnypilot/models/model_name.py rename to openpilot/sunnypilot/models/model_name.py diff --git a/sunnypilot/models/runners/constants.py b/openpilot/sunnypilot/models/runners/constants.py similarity index 91% rename from sunnypilot/models/runners/constants.py rename to openpilot/sunnypilot/models/runners/constants.py index 797a1d04b5..344f8f98cc 100644 --- a/sunnypilot/models/runners/constants.py +++ b/openpilot/sunnypilot/models/runners/constants.py @@ -1,7 +1,7 @@ import os import numpy as np from openpilot.common.hardware.hw import Paths -from cereal import custom +from openpilot.cereal import custom # Type definitions for clarity NumpyDict = dict[str, np.ndarray] diff --git a/sunnypilot/models/runners/helpers.py b/openpilot/sunnypilot/models/runners/helpers.py similarity index 100% rename from sunnypilot/models/runners/helpers.py rename to openpilot/sunnypilot/models/runners/helpers.py diff --git a/sunnypilot/models/runners/model_runner.py b/openpilot/sunnypilot/models/runners/model_runner.py similarity index 100% rename from sunnypilot/models/runners/model_runner.py rename to openpilot/sunnypilot/models/runners/model_runner.py diff --git a/sunnypilot/models/runners/tinygrad/model_types.py b/openpilot/sunnypilot/models/runners/tinygrad/model_types.py similarity index 100% rename from sunnypilot/models/runners/tinygrad/model_types.py rename to openpilot/sunnypilot/models/runners/tinygrad/model_types.py diff --git a/sunnypilot/models/runners/tinygrad/tinygrad_runner.py b/openpilot/sunnypilot/models/runners/tinygrad/tinygrad_runner.py similarity index 100% rename from sunnypilot/models/runners/tinygrad/tinygrad_runner.py rename to openpilot/sunnypilot/models/runners/tinygrad/tinygrad_runner.py diff --git a/sunnypilot/models/split_model_constants.py b/openpilot/sunnypilot/models/split_model_constants.py similarity index 100% rename from sunnypilot/models/split_model_constants.py rename to openpilot/sunnypilot/models/split_model_constants.py diff --git a/sunnypilot/models/tests/__init__.py b/openpilot/sunnypilot/models/tests/__init__.py similarity index 100% rename from sunnypilot/models/tests/__init__.py rename to openpilot/sunnypilot/models/tests/__init__.py diff --git a/sunnypilot/models/tests/model_hash b/openpilot/sunnypilot/models/tests/model_hash similarity index 100% rename from sunnypilot/models/tests/model_hash rename to openpilot/sunnypilot/models/tests/model_hash diff --git a/sunnypilot/models/tests/model_manager_audit.py b/openpilot/sunnypilot/models/tests/model_manager_audit.py similarity index 93% rename from sunnypilot/models/tests/model_manager_audit.py rename to openpilot/sunnypilot/models/tests/model_manager_audit.py index 4cd2b7d78e..2fc8bf5f21 100644 --- a/sunnypilot/models/tests/model_manager_audit.py +++ b/openpilot/sunnypilot/models/tests/model_manager_audit.py @@ -5,7 +5,7 @@ This file is part of sunnypilot and is licensed under the MIT License. See the LICENSE.md file in the root directory for more details. """ -from cereal import messaging, custom +from openpilot.cereal import messaging, custom if __name__ == "__main__": sm = messaging.SubMaster(["modelManagerSP"]) diff --git a/sunnypilot/models/tests/test_default_model.py b/openpilot/sunnypilot/models/tests/test_default_model.py similarity index 100% rename from sunnypilot/models/tests/test_default_model.py rename to openpilot/sunnypilot/models/tests/test_default_model.py diff --git a/sunnypilot/models/tests/test_tinygrad_ref.py b/openpilot/sunnypilot/models/tests/test_tinygrad_ref.py similarity index 100% rename from sunnypilot/models/tests/test_tinygrad_ref.py rename to openpilot/sunnypilot/models/tests/test_tinygrad_ref.py diff --git a/sunnypilot/models/tinygrad_ref.py b/openpilot/sunnypilot/models/tinygrad_ref.py similarity index 100% rename from sunnypilot/models/tinygrad_ref.py rename to openpilot/sunnypilot/models/tinygrad_ref.py diff --git a/sunnypilot/navd/helpers.py b/openpilot/sunnypilot/navd/helpers.py similarity index 100% rename from sunnypilot/navd/helpers.py rename to openpilot/sunnypilot/navd/helpers.py diff --git a/sunnypilot/neural_network_data b/openpilot/sunnypilot/neural_network_data similarity index 100% rename from sunnypilot/neural_network_data rename to openpilot/sunnypilot/neural_network_data diff --git a/sunnypilot/selfdrive/__init__.py b/openpilot/sunnypilot/selfdrive/__init__.py similarity index 100% rename from sunnypilot/selfdrive/__init__.py rename to openpilot/sunnypilot/selfdrive/__init__.py diff --git a/sunnypilot/selfdrive/assets/icons/clock.png b/openpilot/sunnypilot/selfdrive/assets/icons/clock.png similarity index 100% rename from sunnypilot/selfdrive/assets/icons/clock.png rename to openpilot/sunnypilot/selfdrive/assets/icons/clock.png diff --git a/sunnypilot/selfdrive/assets/icons/star-empty.png b/openpilot/sunnypilot/selfdrive/assets/icons/star-empty.png similarity index 100% rename from sunnypilot/selfdrive/assets/icons/star-empty.png rename to openpilot/sunnypilot/selfdrive/assets/icons/star-empty.png diff --git a/sunnypilot/selfdrive/assets/icons/star-filled.png b/openpilot/sunnypilot/selfdrive/assets/icons/star-filled.png similarity index 100% rename from sunnypilot/selfdrive/assets/icons/star-filled.png rename to openpilot/sunnypilot/selfdrive/assets/icons/star-filled.png diff --git a/sunnypilot/selfdrive/assets/icons_mici/always_offroad.png b/openpilot/sunnypilot/selfdrive/assets/icons_mici/always_offroad.png similarity index 100% rename from sunnypilot/selfdrive/assets/icons_mici/always_offroad.png rename to openpilot/sunnypilot/selfdrive/assets/icons_mici/always_offroad.png diff --git a/sunnypilot/selfdrive/assets/icons_mici/disable_offroad.png b/openpilot/sunnypilot/selfdrive/assets/icons_mici/disable_offroad.png similarity index 100% rename from sunnypilot/selfdrive/assets/icons_mici/disable_offroad.png rename to openpilot/sunnypilot/selfdrive/assets/icons_mici/disable_offroad.png diff --git a/sunnypilot/selfdrive/assets/images/green_light.png b/openpilot/sunnypilot/selfdrive/assets/images/green_light.png similarity index 100% rename from sunnypilot/selfdrive/assets/images/green_light.png rename to openpilot/sunnypilot/selfdrive/assets/images/green_light.png diff --git a/sunnypilot/selfdrive/assets/images/lead_depart.png b/openpilot/sunnypilot/selfdrive/assets/images/lead_depart.png similarity index 100% rename from sunnypilot/selfdrive/assets/images/lead_depart.png rename to openpilot/sunnypilot/selfdrive/assets/images/lead_depart.png diff --git a/sunnypilot/selfdrive/assets/images/spinner_sunnypilot.png b/openpilot/sunnypilot/selfdrive/assets/images/spinner_sunnypilot.png similarity index 100% rename from sunnypilot/selfdrive/assets/images/spinner_sunnypilot.png rename to openpilot/sunnypilot/selfdrive/assets/images/spinner_sunnypilot.png diff --git a/sunnypilot/selfdrive/assets/img_minus_arrow_down.png b/openpilot/sunnypilot/selfdrive/assets/img_minus_arrow_down.png similarity index 100% rename from sunnypilot/selfdrive/assets/img_minus_arrow_down.png rename to openpilot/sunnypilot/selfdrive/assets/img_minus_arrow_down.png diff --git a/sunnypilot/selfdrive/assets/img_plus_arrow_up.png b/openpilot/sunnypilot/selfdrive/assets/img_plus_arrow_up.png similarity index 100% rename from sunnypilot/selfdrive/assets/img_plus_arrow_up.png rename to openpilot/sunnypilot/selfdrive/assets/img_plus_arrow_up.png diff --git a/sunnypilot/selfdrive/assets/logo.png b/openpilot/sunnypilot/selfdrive/assets/logo.png similarity index 100% rename from sunnypilot/selfdrive/assets/logo.png rename to openpilot/sunnypilot/selfdrive/assets/logo.png diff --git a/sunnypilot/selfdrive/assets/offroad/icon_display.png b/openpilot/sunnypilot/selfdrive/assets/offroad/icon_display.png similarity index 100% rename from sunnypilot/selfdrive/assets/offroad/icon_display.png rename to openpilot/sunnypilot/selfdrive/assets/offroad/icon_display.png diff --git a/sunnypilot/selfdrive/assets/offroad/icon_exit_offroad.png b/openpilot/sunnypilot/selfdrive/assets/offroad/icon_exit_offroad.png similarity index 100% rename from sunnypilot/selfdrive/assets/offroad/icon_exit_offroad.png rename to openpilot/sunnypilot/selfdrive/assets/offroad/icon_exit_offroad.png diff --git a/sunnypilot/selfdrive/assets/offroad/icon_firehose.png b/openpilot/sunnypilot/selfdrive/assets/offroad/icon_firehose.png similarity index 100% rename from sunnypilot/selfdrive/assets/offroad/icon_firehose.png rename to openpilot/sunnypilot/selfdrive/assets/offroad/icon_firehose.png diff --git a/sunnypilot/selfdrive/assets/offroad/icon_firehose.svg b/openpilot/sunnypilot/selfdrive/assets/offroad/icon_firehose.svg similarity index 100% rename from sunnypilot/selfdrive/assets/offroad/icon_firehose.svg rename to openpilot/sunnypilot/selfdrive/assets/offroad/icon_firehose.svg diff --git a/sunnypilot/selfdrive/assets/offroad/icon_home.png b/openpilot/sunnypilot/selfdrive/assets/offroad/icon_home.png similarity index 100% rename from sunnypilot/selfdrive/assets/offroad/icon_home.png rename to openpilot/sunnypilot/selfdrive/assets/offroad/icon_home.png diff --git a/sunnypilot/selfdrive/assets/offroad/icon_home.svg b/openpilot/sunnypilot/selfdrive/assets/offroad/icon_home.svg similarity index 100% rename from sunnypilot/selfdrive/assets/offroad/icon_home.svg rename to openpilot/sunnypilot/selfdrive/assets/offroad/icon_home.svg diff --git a/sunnypilot/selfdrive/assets/offroad/icon_lateral.png b/openpilot/sunnypilot/selfdrive/assets/offroad/icon_lateral.png similarity index 100% rename from sunnypilot/selfdrive/assets/offroad/icon_lateral.png rename to openpilot/sunnypilot/selfdrive/assets/offroad/icon_lateral.png diff --git a/sunnypilot/selfdrive/assets/offroad/icon_map.png b/openpilot/sunnypilot/selfdrive/assets/offroad/icon_map.png similarity index 100% rename from sunnypilot/selfdrive/assets/offroad/icon_map.png rename to openpilot/sunnypilot/selfdrive/assets/offroad/icon_map.png diff --git a/sunnypilot/selfdrive/assets/offroad/icon_models.png b/openpilot/sunnypilot/selfdrive/assets/offroad/icon_models.png similarity index 100% rename from sunnypilot/selfdrive/assets/offroad/icon_models.png rename to openpilot/sunnypilot/selfdrive/assets/offroad/icon_models.png diff --git a/sunnypilot/selfdrive/assets/offroad/icon_software.png b/openpilot/sunnypilot/selfdrive/assets/offroad/icon_software.png similarity index 100% rename from sunnypilot/selfdrive/assets/offroad/icon_software.png rename to openpilot/sunnypilot/selfdrive/assets/offroad/icon_software.png diff --git a/sunnypilot/selfdrive/assets/offroad/icon_toggle.png b/openpilot/sunnypilot/selfdrive/assets/offroad/icon_toggle.png similarity index 100% rename from sunnypilot/selfdrive/assets/offroad/icon_toggle.png rename to openpilot/sunnypilot/selfdrive/assets/offroad/icon_toggle.png diff --git a/sunnypilot/selfdrive/assets/offroad/icon_trips.png b/openpilot/sunnypilot/selfdrive/assets/offroad/icon_trips.png similarity index 100% rename from sunnypilot/selfdrive/assets/offroad/icon_trips.png rename to openpilot/sunnypilot/selfdrive/assets/offroad/icon_trips.png diff --git a/sunnypilot/selfdrive/assets/offroad/icon_vehicle.png b/openpilot/sunnypilot/selfdrive/assets/offroad/icon_vehicle.png similarity index 100% rename from sunnypilot/selfdrive/assets/offroad/icon_vehicle.png rename to openpilot/sunnypilot/selfdrive/assets/offroad/icon_vehicle.png diff --git a/sunnypilot/selfdrive/assets/offroad/icon_visuals.png b/openpilot/sunnypilot/selfdrive/assets/offroad/icon_visuals.png similarity index 100% rename from sunnypilot/selfdrive/assets/offroad/icon_visuals.png rename to openpilot/sunnypilot/selfdrive/assets/offroad/icon_visuals.png diff --git a/sunnypilot/selfdrive/car/__init__.py b/openpilot/sunnypilot/selfdrive/car/__init__.py similarity index 100% rename from sunnypilot/selfdrive/car/__init__.py rename to openpilot/sunnypilot/selfdrive/car/__init__.py diff --git a/openpilot/sunnypilot/selfdrive/car/car_list.json b/openpilot/sunnypilot/selfdrive/car/car_list.json new file mode 120000 index 0000000000..9bef560d9c --- /dev/null +++ b/openpilot/sunnypilot/selfdrive/car/car_list.json @@ -0,0 +1 @@ +../../../../opendbc_repo/opendbc/sunnypilot/car/car_list.json \ No newline at end of file diff --git a/sunnypilot/selfdrive/car/car_specific.py b/openpilot/sunnypilot/selfdrive/car/car_specific.py similarity index 97% rename from sunnypilot/selfdrive/car/car_specific.py rename to openpilot/sunnypilot/selfdrive/car/car_specific.py index bce496ed28..54fcd34976 100644 --- a/sunnypilot/selfdrive/car/car_specific.py +++ b/openpilot/sunnypilot/selfdrive/car/car_specific.py @@ -5,7 +5,7 @@ This file is part of sunnypilot and is licensed under the MIT License. See the LICENSE.md file in the root directory for more details. """ -from cereal import log, custom +from openpilot.cereal import log, custom from opendbc.car import structs from opendbc.car.chrysler.values import RAM_DT diff --git a/sunnypilot/selfdrive/car/cruise_ext.py b/openpilot/sunnypilot/selfdrive/car/cruise_ext.py similarity index 98% rename from sunnypilot/selfdrive/car/cruise_ext.py rename to openpilot/sunnypilot/selfdrive/car/cruise_ext.py index 3691c35972..61bec477f2 100644 --- a/sunnypilot/selfdrive/car/cruise_ext.py +++ b/openpilot/sunnypilot/selfdrive/car/cruise_ext.py @@ -6,7 +6,8 @@ See the LICENSE.md file in the root directory for more details. """ import numpy as np -from cereal import car, custom +from openpilot.cereal import custom +from opendbc.car.structs import car from opendbc.car import structs from openpilot.common.constants import CV from openpilot.common.params import Params diff --git a/sunnypilot/selfdrive/car/cruise_helpers.py b/openpilot/sunnypilot/selfdrive/car/cruise_helpers.py similarity index 96% rename from sunnypilot/selfdrive/car/cruise_helpers.py rename to openpilot/sunnypilot/selfdrive/car/cruise_helpers.py index 263d6f58cd..aa689ec904 100644 --- a/sunnypilot/selfdrive/car/cruise_helpers.py +++ b/openpilot/sunnypilot/selfdrive/car/cruise_helpers.py @@ -5,7 +5,8 @@ This file is part of sunnypilot and is licensed under the MIT License. See the LICENSE.md file in the root directory for more details. """ -from cereal import car, custom +from openpilot.cereal import custom +from opendbc.car.structs import car from opendbc.car import structs from openpilot.common.params import Params diff --git a/sunnypilot/selfdrive/car/intelligent_cruise_button_management/__init__.py b/openpilot/sunnypilot/selfdrive/car/intelligent_cruise_button_management/__init__.py similarity index 100% rename from sunnypilot/selfdrive/car/intelligent_cruise_button_management/__init__.py rename to openpilot/sunnypilot/selfdrive/car/intelligent_cruise_button_management/__init__.py diff --git a/sunnypilot/selfdrive/car/intelligent_cruise_button_management/controller.py b/openpilot/sunnypilot/selfdrive/car/intelligent_cruise_button_management/controller.py similarity index 98% rename from sunnypilot/selfdrive/car/intelligent_cruise_button_management/controller.py rename to openpilot/sunnypilot/selfdrive/car/intelligent_cruise_button_management/controller.py index 1f491e0f58..ded2c0ab19 100644 --- a/sunnypilot/selfdrive/car/intelligent_cruise_button_management/controller.py +++ b/openpilot/sunnypilot/selfdrive/car/intelligent_cruise_button_management/controller.py @@ -4,7 +4,8 @@ Copyright (c) 2021-, Haibin Wen, sunnypilot, and a number of other contributors. This file is part of sunnypilot and is licensed under the MIT License. See the LICENSE.md file in the root directory for more details. """ -from cereal import car, custom +from openpilot.cereal import custom +from opendbc.car.structs import car from opendbc.car import structs, apply_hysteresis from openpilot.common.constants import CV from openpilot.common.realtime import DT_CTRL diff --git a/sunnypilot/selfdrive/car/intelligent_cruise_button_management/helpers.py b/openpilot/sunnypilot/selfdrive/car/intelligent_cruise_button_management/helpers.py similarity index 100% rename from sunnypilot/selfdrive/car/intelligent_cruise_button_management/helpers.py rename to openpilot/sunnypilot/selfdrive/car/intelligent_cruise_button_management/helpers.py diff --git a/sunnypilot/selfdrive/car/interfaces.py b/openpilot/sunnypilot/selfdrive/car/interfaces.py similarity index 100% rename from sunnypilot/selfdrive/car/interfaces.py rename to openpilot/sunnypilot/selfdrive/car/interfaces.py diff --git a/sunnypilot/selfdrive/car/sync_sunnylink_params.py b/openpilot/sunnypilot/selfdrive/car/sync_sunnylink_params.py similarity index 88% rename from sunnypilot/selfdrive/car/sync_sunnylink_params.py rename to openpilot/sunnypilot/selfdrive/car/sync_sunnylink_params.py index 7539e741c6..6c964710b0 100755 --- a/sunnypilot/selfdrive/car/sync_sunnylink_params.py +++ b/openpilot/sunnypilot/selfdrive/car/sync_sunnylink_params.py @@ -12,7 +12,7 @@ from openpilot.common.basedir import BASEDIR from openpilot.common.params import Params from openpilot.common.swaglog import cloudlog -CAR_LIST_JSON_OUT = os.path.join(BASEDIR, "sunnypilot", "selfdrive", "car", "car_list.json") +CAR_LIST_JSON_OUT = os.path.join(BASEDIR, "openpilot", "sunnypilot", "selfdrive", "car", "car_list.json") def update_car_list_param(): diff --git a/sunnypilot/selfdrive/car/tests/__init__.py b/openpilot/sunnypilot/selfdrive/car/tests/__init__.py similarity index 100% rename from sunnypilot/selfdrive/car/tests/__init__.py rename to openpilot/sunnypilot/selfdrive/car/tests/__init__.py diff --git a/sunnypilot/selfdrive/car/tests/test_cruise_mode.py b/openpilot/sunnypilot/selfdrive/car/tests/test_cruise_mode.py similarity index 98% rename from sunnypilot/selfdrive/car/tests/test_cruise_mode.py rename to openpilot/sunnypilot/selfdrive/car/tests/test_cruise_mode.py index 2fad14a703..3f3701b3ae 100644 --- a/sunnypilot/selfdrive/car/tests/test_cruise_mode.py +++ b/openpilot/sunnypilot/selfdrive/car/tests/test_cruise_mode.py @@ -1,4 +1,4 @@ -from cereal import car +from opendbc.car.structs import car from openpilot.common.parameterized import parameterized_class from openpilot.selfdrive.selfdrived.events import Events from openpilot.sunnypilot.selfdrive.car.cruise_helpers import CruiseHelper, DISTANCE_LONG_PRESS diff --git a/sunnypilot/selfdrive/car/tests/test_custom_cruise.py b/openpilot/sunnypilot/selfdrive/car/tests/test_custom_cruise.py similarity index 99% rename from sunnypilot/selfdrive/car/tests/test_custom_cruise.py rename to openpilot/sunnypilot/selfdrive/car/tests/test_custom_cruise.py index 878bc78b03..ce5d7dc124 100644 --- a/sunnypilot/selfdrive/car/tests/test_custom_cruise.py +++ b/openpilot/sunnypilot/selfdrive/car/tests/test_custom_cruise.py @@ -1,6 +1,6 @@ import pytest -from cereal import car +from opendbc.car.structs import car from openpilot.common.constants import CV from openpilot.common.parameterized import parameterized_class from openpilot.common.params import Params diff --git a/sunnypilot/selfdrive/controls/__init__.py b/openpilot/sunnypilot/selfdrive/controls/__init__.py similarity index 100% rename from sunnypilot/selfdrive/controls/__init__.py rename to openpilot/sunnypilot/selfdrive/controls/__init__.py diff --git a/sunnypilot/selfdrive/controls/controlsd_ext.py b/openpilot/sunnypilot/selfdrive/controls/controlsd_ext.py similarity index 94% rename from sunnypilot/selfdrive/controls/controlsd_ext.py rename to openpilot/sunnypilot/selfdrive/controls/controlsd_ext.py index c8d054243f..33cc9e3ad8 100644 --- a/sunnypilot/selfdrive/controls/controlsd_ext.py +++ b/openpilot/sunnypilot/selfdrive/controls/controlsd_ext.py @@ -6,8 +6,8 @@ See the LICENSE.md file in the root directory for more details. """ import time -import cereal.messaging as messaging -from cereal import log, custom +import openpilot.cereal.messaging as messaging +from openpilot.cereal import log, custom from opendbc.car import structs from openpilot.common.params import Params @@ -72,14 +72,14 @@ class ControlsExt(ModelStateBase): _lead.dRel = src.dRel _lead.yRel = src.yRel _lead.vRel = src.vRel - _lead.aRel = src.aRel + _lead.aRel = src.deprecated.aRel _lead.vLead = src.vLead - _lead.dPath = src.dPath - _lead.vLat = src.vLat + _lead.dPath = src.deprecated.dPath + _lead.vLat = src.deprecated.vLat _lead.vLeadK = src.vLeadK _lead.aLeadK = src.aLeadK - _lead.fcw = src.fcw - _lead.status = src.status + _lead.fcw = src.deprecated.fcw + _lead.status = src.present _lead.aLeadTau = src.aLeadTau _lead.modelProb = src.modelProb _lead.radar = src.radar diff --git a/sunnypilot/selfdrive/controls/lib/__init__.py b/openpilot/sunnypilot/selfdrive/controls/lib/__init__.py similarity index 100% rename from sunnypilot/selfdrive/controls/lib/__init__.py rename to openpilot/sunnypilot/selfdrive/controls/lib/__init__.py diff --git a/sunnypilot/selfdrive/controls/lib/auto_lane_change.py b/openpilot/sunnypilot/selfdrive/controls/lib/auto_lane_change.py similarity index 99% rename from sunnypilot/selfdrive/controls/lib/auto_lane_change.py rename to openpilot/sunnypilot/selfdrive/controls/lib/auto_lane_change.py index cf8de2a1b2..39909ac7b1 100644 --- a/sunnypilot/selfdrive/controls/lib/auto_lane_change.py +++ b/openpilot/sunnypilot/selfdrive/controls/lib/auto_lane_change.py @@ -4,7 +4,7 @@ Copyright (c) 2021-, Haibin Wen, sunnypilot, and a number of other contributors. This file is part of sunnypilot and is licensed under the MIT License. See the LICENSE.md file in the root directory for more details. """ -from cereal import log +from openpilot.cereal import log from openpilot.common.params import Params from openpilot.common.realtime import DT_MDL diff --git a/sunnypilot/selfdrive/controls/lib/blinker_pause_lateral.py b/openpilot/sunnypilot/selfdrive/controls/lib/blinker_pause_lateral.py similarity index 97% rename from sunnypilot/selfdrive/controls/lib/blinker_pause_lateral.py rename to openpilot/sunnypilot/selfdrive/controls/lib/blinker_pause_lateral.py index 98757cd532..e9a6be595e 100644 --- a/sunnypilot/selfdrive/controls/lib/blinker_pause_lateral.py +++ b/openpilot/sunnypilot/selfdrive/controls/lib/blinker_pause_lateral.py @@ -4,7 +4,7 @@ Copyright (c) 2021-, Haibin Wen, sunnypilot, and a number of other contributors. This file is part of sunnypilot and is licensed under the MIT License. See the LICENSE.md file in the root directory for more details. """ -from cereal import car +from opendbc.car.structs import car from openpilot.common.constants import CV from openpilot.common.params import Params diff --git a/sunnypilot/selfdrive/controls/lib/dec/__init__.py b/openpilot/sunnypilot/selfdrive/controls/lib/dec/__init__.py similarity index 100% rename from sunnypilot/selfdrive/controls/lib/dec/__init__.py rename to openpilot/sunnypilot/selfdrive/controls/lib/dec/__init__.py diff --git a/sunnypilot/selfdrive/controls/lib/dec/constants.py b/openpilot/sunnypilot/selfdrive/controls/lib/dec/constants.py similarity index 100% rename from sunnypilot/selfdrive/controls/lib/dec/constants.py rename to openpilot/sunnypilot/selfdrive/controls/lib/dec/constants.py diff --git a/sunnypilot/selfdrive/controls/lib/dec/dec.py b/openpilot/sunnypilot/selfdrive/controls/lib/dec/dec.py similarity index 99% rename from sunnypilot/selfdrive/controls/lib/dec/dec.py rename to openpilot/sunnypilot/selfdrive/controls/lib/dec/dec.py index 46cad1b048..1ba5ab0618 100644 --- a/sunnypilot/selfdrive/controls/lib/dec/dec.py +++ b/openpilot/sunnypilot/selfdrive/controls/lib/dec/dec.py @@ -6,7 +6,7 @@ See the LICENSE.md file in the root directory for more details. """ # Version = 2025-6-30 -from cereal import messaging +from openpilot.cereal import messaging from opendbc.car import structs from numpy import interp from openpilot.common.params import Params @@ -217,7 +217,7 @@ class DynamicExperimentalController: self._standstill_count = max(0, self._standstill_count - 1) # Lead detection - self._lead_filter.add_data(float(lead_one.status)) + self._lead_filter.add_data(float(lead_one.present)) lead_value = self._lead_filter.get_value() or 0.0 self._has_lead_filtered = lead_value > WMACConstants.LEAD_PROB diff --git a/sunnypilot/selfdrive/controls/lib/dec/tests/__init__.py b/openpilot/sunnypilot/selfdrive/controls/lib/dec/tests/__init__.py similarity index 100% rename from sunnypilot/selfdrive/controls/lib/dec/tests/__init__.py rename to openpilot/sunnypilot/selfdrive/controls/lib/dec/tests/__init__.py diff --git a/sunnypilot/selfdrive/controls/lib/dec/tests/pytest_dynamic_controller.py b/openpilot/sunnypilot/selfdrive/controls/lib/dec/tests/pytest_dynamic_controller.py similarity index 100% rename from sunnypilot/selfdrive/controls/lib/dec/tests/pytest_dynamic_controller.py rename to openpilot/sunnypilot/selfdrive/controls/lib/dec/tests/pytest_dynamic_controller.py diff --git a/sunnypilot/selfdrive/controls/lib/e2e_alerts_helper.py b/openpilot/sunnypilot/selfdrive/controls/lib/e2e_alerts_helper.py similarity index 98% rename from sunnypilot/selfdrive/controls/lib/e2e_alerts_helper.py rename to openpilot/sunnypilot/selfdrive/controls/lib/e2e_alerts_helper.py index 944bf617e9..b75bae2461 100644 --- a/sunnypilot/selfdrive/controls/lib/e2e_alerts_helper.py +++ b/openpilot/sunnypilot/selfdrive/controls/lib/e2e_alerts_helper.py @@ -5,7 +5,7 @@ This file is part of sunnypilot and is licensed under the MIT License. See the LICENSE.md file in the root directory for more details. """ -from cereal import messaging, custom +from openpilot.cereal import messaging, custom from openpilot.common.params import Params from openpilot.common.realtime import DT_MDL @@ -61,7 +61,7 @@ class E2EAlertsHelper: model_x = sm['modelV2'].position.x max_idx = len(model_x) - 1 - self.has_lead = sm['radarState'].leadOne.status + self.has_lead = sm['radarState'].leadOne.present lead_dRel = sm['radarState'].leadOne.dRel standstill = CS.standstill diff --git a/sunnypilot/selfdrive/controls/lib/lane_turn_desire.py b/openpilot/sunnypilot/selfdrive/controls/lib/lane_turn_desire.py similarity index 97% rename from sunnypilot/selfdrive/controls/lib/lane_turn_desire.py rename to openpilot/sunnypilot/selfdrive/controls/lib/lane_turn_desire.py index fa35ebb125..ad7e80eda0 100644 --- a/sunnypilot/selfdrive/controls/lib/lane_turn_desire.py +++ b/openpilot/sunnypilot/selfdrive/controls/lib/lane_turn_desire.py @@ -4,7 +4,7 @@ Copyright (c) 2021-, Haibin Wen, sunnypilot, and a number of other contributors. This file is part of sunnypilot and is licensed under the MIT License. See the LICENSE.md file in the root directory for more details. """ -from cereal import custom +from openpilot.cereal import custom from openpilot.common.constants import CV from openpilot.common.params import Params diff --git a/sunnypilot/selfdrive/controls/lib/latcontrol_torque_ext.py b/openpilot/sunnypilot/selfdrive/controls/lib/latcontrol_torque_ext.py similarity index 100% rename from sunnypilot/selfdrive/controls/lib/latcontrol_torque_ext.py rename to openpilot/sunnypilot/selfdrive/controls/lib/latcontrol_torque_ext.py diff --git a/sunnypilot/selfdrive/controls/lib/latcontrol_torque_ext_base.py b/openpilot/sunnypilot/selfdrive/controls/lib/latcontrol_torque_ext_base.py similarity index 100% rename from sunnypilot/selfdrive/controls/lib/latcontrol_torque_ext_base.py rename to openpilot/sunnypilot/selfdrive/controls/lib/latcontrol_torque_ext_base.py diff --git a/sunnypilot/selfdrive/controls/lib/latcontrol_torque_ext_override.py b/openpilot/sunnypilot/selfdrive/controls/lib/latcontrol_torque_ext_override.py similarity index 100% rename from sunnypilot/selfdrive/controls/lib/latcontrol_torque_ext_override.py rename to openpilot/sunnypilot/selfdrive/controls/lib/latcontrol_torque_ext_override.py diff --git a/sunnypilot/selfdrive/controls/lib/latcontrol_torque_v0.py b/openpilot/sunnypilot/selfdrive/controls/lib/latcontrol_torque_v0.py similarity index 99% rename from sunnypilot/selfdrive/controls/lib/latcontrol_torque_v0.py rename to openpilot/sunnypilot/selfdrive/controls/lib/latcontrol_torque_v0.py index f7874cc539..4d9e4492f9 100644 --- a/sunnypilot/selfdrive/controls/lib/latcontrol_torque_v0.py +++ b/openpilot/sunnypilot/selfdrive/controls/lib/latcontrol_torque_v0.py @@ -2,7 +2,7 @@ import math import numpy as np from collections import deque -from cereal import log +from openpilot.cereal import log from opendbc.car.lateral import get_friction from openpilot.common.constants import ACCELERATION_DUE_TO_GRAVITY from openpilot.common.filter_simple import FirstOrderFilter diff --git a/sunnypilot/selfdrive/controls/lib/latcontrol_torque_versions.json b/openpilot/sunnypilot/selfdrive/controls/lib/latcontrol_torque_versions.json similarity index 100% rename from sunnypilot/selfdrive/controls/lib/latcontrol_torque_versions.json rename to openpilot/sunnypilot/selfdrive/controls/lib/latcontrol_torque_versions.json diff --git a/sunnypilot/selfdrive/controls/lib/longitudinal_planner.py b/openpilot/sunnypilot/selfdrive/controls/lib/longitudinal_planner.py similarity index 99% rename from sunnypilot/selfdrive/controls/lib/longitudinal_planner.py rename to openpilot/sunnypilot/selfdrive/controls/lib/longitudinal_planner.py index 6efda4585f..f1e0c36416 100644 --- a/sunnypilot/selfdrive/controls/lib/longitudinal_planner.py +++ b/openpilot/sunnypilot/selfdrive/controls/lib/longitudinal_planner.py @@ -5,7 +5,7 @@ This file is part of sunnypilot and is licensed under the MIT License. See the LICENSE.md file in the root directory for more details. """ -from cereal import messaging, custom +from openpilot.cereal import messaging, custom from opendbc.car import structs from openpilot.common.constants import CV from openpilot.selfdrive.car.cruise import V_CRUISE_MAX diff --git a/sunnypilot/selfdrive/controls/lib/nnlc/__init__.py b/openpilot/sunnypilot/selfdrive/controls/lib/nnlc/__init__.py similarity index 100% rename from sunnypilot/selfdrive/controls/lib/nnlc/__init__.py rename to openpilot/sunnypilot/selfdrive/controls/lib/nnlc/__init__.py diff --git a/sunnypilot/selfdrive/controls/lib/nnlc/helpers.py b/openpilot/sunnypilot/selfdrive/controls/lib/nnlc/helpers.py similarity index 92% rename from sunnypilot/selfdrive/controls/lib/nnlc/helpers.py rename to openpilot/sunnypilot/selfdrive/controls/lib/nnlc/helpers.py index c34fa435c2..a5d56b1ff0 100644 --- a/sunnypilot/selfdrive/controls/lib/nnlc/helpers.py +++ b/openpilot/sunnypilot/selfdrive/controls/lib/nnlc/helpers.py @@ -11,8 +11,8 @@ from difflib import SequenceMatcher from opendbc.car import structs from openpilot.common.basedir import BASEDIR -TORQUE_NN_MODEL_PATH = os.path.join(BASEDIR, "sunnypilot", "neural_network_data", "neural_network_lateral_control") -TORQUE_NN_MODEL_SUBSTITUTE_PATH = os.path.join(BASEDIR, "opendbc", "car", "torque_data/substitute.toml") +TORQUE_NN_MODEL_PATH = os.path.join(BASEDIR, "openpilot", "sunnypilot", "neural_network_data", "neural_network_lateral_control") +TORQUE_NN_MODEL_SUBSTITUTE_PATH = os.path.join(BASEDIR, "opendbc_repo", "opendbc", "car", "torque_data/substitute.toml") MOCK_MODEL_PATH = os.path.join(TORQUE_NN_MODEL_PATH, "MOCK.json") diff --git a/sunnypilot/selfdrive/controls/lib/nnlc/model.py b/openpilot/sunnypilot/selfdrive/controls/lib/nnlc/model.py similarity index 100% rename from sunnypilot/selfdrive/controls/lib/nnlc/model.py rename to openpilot/sunnypilot/selfdrive/controls/lib/nnlc/model.py diff --git a/sunnypilot/selfdrive/controls/lib/nnlc/nnlc.py b/openpilot/sunnypilot/selfdrive/controls/lib/nnlc/nnlc.py similarity index 100% rename from sunnypilot/selfdrive/controls/lib/nnlc/nnlc.py rename to openpilot/sunnypilot/selfdrive/controls/lib/nnlc/nnlc.py diff --git a/sunnypilot/selfdrive/controls/lib/nnlc/tests/__init__.py b/openpilot/sunnypilot/selfdrive/controls/lib/nnlc/tests/__init__.py similarity index 100% rename from sunnypilot/selfdrive/controls/lib/nnlc/tests/__init__.py rename to openpilot/sunnypilot/selfdrive/controls/lib/nnlc/tests/__init__.py diff --git a/sunnypilot/selfdrive/controls/lib/nnlc/tests/test_fingerprint.py b/openpilot/sunnypilot/selfdrive/controls/lib/nnlc/tests/test_fingerprint.py similarity index 100% rename from sunnypilot/selfdrive/controls/lib/nnlc/tests/test_fingerprint.py rename to openpilot/sunnypilot/selfdrive/controls/lib/nnlc/tests/test_fingerprint.py diff --git a/sunnypilot/selfdrive/controls/lib/nnlc/tests/test_load_model.py b/openpilot/sunnypilot/selfdrive/controls/lib/nnlc/tests/test_load_model.py similarity index 100% rename from sunnypilot/selfdrive/controls/lib/nnlc/tests/test_load_model.py rename to openpilot/sunnypilot/selfdrive/controls/lib/nnlc/tests/test_load_model.py diff --git a/sunnypilot/selfdrive/controls/lib/nnlc/tests/test_nnlc.py b/openpilot/sunnypilot/selfdrive/controls/lib/nnlc/tests/test_nnlc.py similarity index 98% rename from sunnypilot/selfdrive/controls/lib/nnlc/tests/test_nnlc.py rename to openpilot/sunnypilot/selfdrive/controls/lib/nnlc/tests/test_nnlc.py index f2009926cf..56fd2f9ce7 100644 --- a/sunnypilot/selfdrive/controls/lib/nnlc/tests/test_nnlc.py +++ b/openpilot/sunnypilot/selfdrive/controls/lib/nnlc/tests/test_nnlc.py @@ -1,6 +1,7 @@ import numpy as np -from cereal import car, log, messaging +from openpilot.cereal import log, messaging +from opendbc.car.structs import car from opendbc.car.car_helpers import interfaces from opendbc.car.gm.values import CAR as GM from opendbc.car.honda.values import CAR as HONDA diff --git a/sunnypilot/selfdrive/controls/lib/smart_cruise_control/__init__.py b/openpilot/sunnypilot/selfdrive/controls/lib/smart_cruise_control/__init__.py similarity index 100% rename from sunnypilot/selfdrive/controls/lib/smart_cruise_control/__init__.py rename to openpilot/sunnypilot/selfdrive/controls/lib/smart_cruise_control/__init__.py diff --git a/sunnypilot/selfdrive/controls/lib/smart_cruise_control/map_controller.py b/openpilot/sunnypilot/selfdrive/controls/lib/smart_cruise_control/map_controller.py similarity index 99% rename from sunnypilot/selfdrive/controls/lib/smart_cruise_control/map_controller.py rename to openpilot/sunnypilot/selfdrive/controls/lib/smart_cruise_control/map_controller.py index c7f11a1bb2..65e157bdbc 100644 --- a/sunnypilot/selfdrive/controls/lib/smart_cruise_control/map_controller.py +++ b/openpilot/sunnypilot/selfdrive/controls/lib/smart_cruise_control/map_controller.py @@ -2,7 +2,7 @@ import json import math import platform -from cereal import custom +from openpilot.cereal import custom from openpilot.common.params import Params from openpilot.common.realtime import DT_MDL from openpilot.selfdrive.car.cruise import V_CRUISE_UNSET diff --git a/sunnypilot/selfdrive/controls/lib/smart_cruise_control/smart_cruise_control.py b/openpilot/sunnypilot/selfdrive/controls/lib/smart_cruise_control/smart_cruise_control.py similarity index 94% rename from sunnypilot/selfdrive/controls/lib/smart_cruise_control/smart_cruise_control.py rename to openpilot/sunnypilot/selfdrive/controls/lib/smart_cruise_control/smart_cruise_control.py index 4ca45202fc..ff6c706634 100644 --- a/sunnypilot/selfdrive/controls/lib/smart_cruise_control/smart_cruise_control.py +++ b/openpilot/sunnypilot/selfdrive/controls/lib/smart_cruise_control/smart_cruise_control.py @@ -4,7 +4,7 @@ Copyright (c) 2021-, Haibin Wen, sunnypilot, and a number of other contributors. This file is part of sunnypilot and is licensed under the MIT License. See the LICENSE.md file in the root directory for more details. """ -import cereal.messaging as messaging +import openpilot.cereal.messaging as messaging from openpilot.sunnypilot.selfdrive.controls.lib.smart_cruise_control.vision_controller import SmartCruiseControlVision from openpilot.sunnypilot.selfdrive.controls.lib.smart_cruise_control.map_controller import SmartCruiseControlMap diff --git a/sunnypilot/selfdrive/controls/lib/smart_cruise_control/tests/test_map_controller.py b/openpilot/sunnypilot/selfdrive/controls/lib/smart_cruise_control/tests/test_map_controller.py similarity index 98% rename from sunnypilot/selfdrive/controls/lib/smart_cruise_control/tests/test_map_controller.py rename to openpilot/sunnypilot/selfdrive/controls/lib/smart_cruise_control/tests/test_map_controller.py index 254e85f573..3b16c59bb5 100644 --- a/sunnypilot/selfdrive/controls/lib/smart_cruise_control/tests/test_map_controller.py +++ b/openpilot/sunnypilot/selfdrive/controls/lib/smart_cruise_control/tests/test_map_controller.py @@ -6,7 +6,7 @@ See the LICENSE.md file in the root directory for more details. """ import platform -from cereal import custom +from openpilot.cereal import custom from openpilot.common.params import Params from openpilot.common.realtime import DT_MDL from openpilot.selfdrive.car.cruise import V_CRUISE_UNSET diff --git a/sunnypilot/selfdrive/controls/lib/smart_cruise_control/tests/test_vision_controller.py b/openpilot/sunnypilot/selfdrive/controls/lib/smart_cruise_control/tests/test_vision_controller.py similarity index 98% rename from sunnypilot/selfdrive/controls/lib/smart_cruise_control/tests/test_vision_controller.py rename to openpilot/sunnypilot/selfdrive/controls/lib/smart_cruise_control/tests/test_vision_controller.py index 2a2c6a6be1..de54a0fdca 100644 --- a/sunnypilot/selfdrive/controls/lib/smart_cruise_control/tests/test_vision_controller.py +++ b/openpilot/sunnypilot/selfdrive/controls/lib/smart_cruise_control/tests/test_vision_controller.py @@ -7,8 +7,8 @@ See the LICENSE.md file in the root directory for more details. import numpy as np import pytest -import cereal.messaging as messaging -from cereal import custom, log +import openpilot.cereal.messaging as messaging +from openpilot.cereal import custom, log from openpilot.common.params import Params from openpilot.common.realtime import DT_MDL from openpilot.selfdrive.car.cruise import V_CRUISE_UNSET diff --git a/sunnypilot/selfdrive/controls/lib/smart_cruise_control/vision_controller.py b/openpilot/sunnypilot/selfdrive/controls/lib/smart_cruise_control/vision_controller.py similarity index 98% rename from sunnypilot/selfdrive/controls/lib/smart_cruise_control/vision_controller.py rename to openpilot/sunnypilot/selfdrive/controls/lib/smart_cruise_control/vision_controller.py index a9d2a66227..fb76f5b546 100644 --- a/sunnypilot/selfdrive/controls/lib/smart_cruise_control/vision_controller.py +++ b/openpilot/sunnypilot/selfdrive/controls/lib/smart_cruise_control/vision_controller.py @@ -6,8 +6,8 @@ See the LICENSE.md file in the root directory for more details. """ import numpy as np -import cereal.messaging as messaging -from cereal import custom +import openpilot.cereal.messaging as messaging +from openpilot.cereal import custom from openpilot.common.params import Params from openpilot.common.realtime import DT_MDL from openpilot.selfdrive.car.cruise import V_CRUISE_UNSET diff --git a/sunnypilot/selfdrive/controls/lib/speed_limit/__init__.py b/openpilot/sunnypilot/selfdrive/controls/lib/speed_limit/__init__.py similarity index 100% rename from sunnypilot/selfdrive/controls/lib/speed_limit/__init__.py rename to openpilot/sunnypilot/selfdrive/controls/lib/speed_limit/__init__.py diff --git a/sunnypilot/selfdrive/controls/lib/speed_limit/common.py b/openpilot/sunnypilot/selfdrive/controls/lib/speed_limit/common.py similarity index 100% rename from sunnypilot/selfdrive/controls/lib/speed_limit/common.py rename to openpilot/sunnypilot/selfdrive/controls/lib/speed_limit/common.py diff --git a/sunnypilot/selfdrive/controls/lib/speed_limit/helpers.py b/openpilot/sunnypilot/selfdrive/controls/lib/speed_limit/helpers.py similarity index 95% rename from sunnypilot/selfdrive/controls/lib/speed_limit/helpers.py rename to openpilot/sunnypilot/selfdrive/controls/lib/speed_limit/helpers.py index 9eddceb820..77d89251e2 100644 --- a/sunnypilot/selfdrive/controls/lib/speed_limit/helpers.py +++ b/openpilot/sunnypilot/selfdrive/controls/lib/speed_limit/helpers.py @@ -5,7 +5,8 @@ This file is part of sunnypilot and is licensed under the MIT License. See the LICENSE.md file in the root directory for more details. """ -from cereal import custom, car +from openpilot.cereal import custom +from opendbc.car.structs import car from openpilot.common.constants import CV from openpilot.common.params import Params from openpilot.sunnypilot.selfdrive.controls.lib.speed_limit.common import Mode as SpeedLimitMode diff --git a/sunnypilot/selfdrive/controls/lib/speed_limit/speed_limit_assist.py b/openpilot/sunnypilot/selfdrive/controls/lib/speed_limit/speed_limit_assist.py similarity index 99% rename from sunnypilot/selfdrive/controls/lib/speed_limit/speed_limit_assist.py rename to openpilot/sunnypilot/selfdrive/controls/lib/speed_limit/speed_limit_assist.py index ff7be8a8be..1ff541167f 100644 --- a/sunnypilot/selfdrive/controls/lib/speed_limit/speed_limit_assist.py +++ b/openpilot/sunnypilot/selfdrive/controls/lib/speed_limit/speed_limit_assist.py @@ -6,7 +6,8 @@ See the LICENSE.md file in the root directory for more details. """ import time -from cereal import custom, car +from openpilot.cereal import custom +from opendbc.car.structs import car from openpilot.common.params import Params from openpilot.common.constants import CV from openpilot.common.realtime import DT_MDL diff --git a/sunnypilot/selfdrive/controls/lib/speed_limit/speed_limit_resolver.py b/openpilot/sunnypilot/selfdrive/controls/lib/speed_limit/speed_limit_resolver.py similarity index 98% rename from sunnypilot/selfdrive/controls/lib/speed_limit/speed_limit_resolver.py rename to openpilot/sunnypilot/selfdrive/controls/lib/speed_limit/speed_limit_resolver.py index 35965c0e18..e46196654c 100644 --- a/sunnypilot/selfdrive/controls/lib/speed_limit/speed_limit_resolver.py +++ b/openpilot/sunnypilot/selfdrive/controls/lib/speed_limit/speed_limit_resolver.py @@ -6,8 +6,8 @@ See the LICENSE.md file in the root directory for more details. """ import time -import cereal.messaging as messaging -from cereal import custom +import openpilot.cereal.messaging as messaging +from openpilot.cereal import custom from openpilot.common.constants import CV from openpilot.common.gps import get_gps_location_service from openpilot.common.params import Params diff --git a/sunnypilot/selfdrive/controls/lib/speed_limit/tests/__init__.py b/openpilot/sunnypilot/selfdrive/controls/lib/speed_limit/tests/__init__.py similarity index 100% rename from sunnypilot/selfdrive/controls/lib/speed_limit/tests/__init__.py rename to openpilot/sunnypilot/selfdrive/controls/lib/speed_limit/tests/__init__.py diff --git a/sunnypilot/selfdrive/controls/lib/speed_limit/tests/test_speed_limit_assist.py b/openpilot/sunnypilot/selfdrive/controls/lib/speed_limit/tests/test_speed_limit_assist.py similarity index 99% rename from sunnypilot/selfdrive/controls/lib/speed_limit/tests/test_speed_limit_assist.py rename to openpilot/sunnypilot/selfdrive/controls/lib/speed_limit/tests/test_speed_limit_assist.py index 6dbe32eaf4..7cd6fef524 100644 --- a/sunnypilot/selfdrive/controls/lib/speed_limit/tests/test_speed_limit_assist.py +++ b/openpilot/sunnypilot/selfdrive/controls/lib/speed_limit/tests/test_speed_limit_assist.py @@ -7,7 +7,7 @@ See the LICENSE.md file in the root directory for more details. import pytest -from cereal import custom +from openpilot.cereal import custom from opendbc.car.car_helpers import interfaces from opendbc.car.rivian.values import CAR as RIVIAN from opendbc.car.tesla.values import CAR as TESLA diff --git a/sunnypilot/selfdrive/controls/lib/speed_limit/tests/test_speed_limit_resolver.py b/openpilot/sunnypilot/selfdrive/controls/lib/speed_limit/tests/test_speed_limit_resolver.py similarity index 99% rename from sunnypilot/selfdrive/controls/lib/speed_limit/tests/test_speed_limit_resolver.py rename to openpilot/sunnypilot/selfdrive/controls/lib/speed_limit/tests/test_speed_limit_resolver.py index c02831d71a..a18880c620 100644 --- a/sunnypilot/selfdrive/controls/lib/speed_limit/tests/test_speed_limit_resolver.py +++ b/openpilot/sunnypilot/selfdrive/controls/lib/speed_limit/tests/test_speed_limit_resolver.py @@ -10,7 +10,7 @@ import time import pytest from pytest_mock import MockerFixture -from cereal import custom +from openpilot.cereal import custom from openpilot.sunnypilot.selfdrive.controls.lib.speed_limit import LIMIT_MAX_MAP_DATA_AGE from openpilot.sunnypilot.selfdrive.controls.lib.speed_limit.speed_limit_resolver import SpeedLimitResolver, ALL_SOURCES diff --git a/sunnypilot/selfdrive/controls/lib/tests/test_auto_lane_change.py b/openpilot/sunnypilot/selfdrive/controls/lib/tests/test_auto_lane_change.py similarity index 100% rename from sunnypilot/selfdrive/controls/lib/tests/test_auto_lane_change.py rename to openpilot/sunnypilot/selfdrive/controls/lib/tests/test_auto_lane_change.py diff --git a/sunnypilot/selfdrive/controls/lib/tests/test_blinker_pause_lateral.py b/openpilot/sunnypilot/selfdrive/controls/lib/tests/test_blinker_pause_lateral.py similarity index 99% rename from sunnypilot/selfdrive/controls/lib/tests/test_blinker_pause_lateral.py rename to openpilot/sunnypilot/selfdrive/controls/lib/tests/test_blinker_pause_lateral.py index b547ea96b6..7a72cfa1f2 100644 --- a/sunnypilot/selfdrive/controls/lib/tests/test_blinker_pause_lateral.py +++ b/openpilot/sunnypilot/selfdrive/controls/lib/tests/test_blinker_pause_lateral.py @@ -4,7 +4,7 @@ Copyright (c) 2021-, Haibin Wen, sunnypilot, and a number of other contributors. This file is part of sunnypilot and is licensed under the MIT License. See the LICENSE.md file in the root directory for more details. """ -from cereal import car +from opendbc.car.structs import car from openpilot.common.constants import CV from openpilot.sunnypilot.selfdrive.controls.lib.blinker_pause_lateral import BlinkerPauseLateral diff --git a/sunnypilot/selfdrive/controls/lib/tests/test_lane_turn_desire.py b/openpilot/sunnypilot/selfdrive/controls/lib/tests/test_lane_turn_desire.py similarity index 99% rename from sunnypilot/selfdrive/controls/lib/tests/test_lane_turn_desire.py rename to openpilot/sunnypilot/selfdrive/controls/lib/tests/test_lane_turn_desire.py index 57fe7b684f..c3e96fd778 100644 --- a/sunnypilot/selfdrive/controls/lib/tests/test_lane_turn_desire.py +++ b/openpilot/sunnypilot/selfdrive/controls/lib/tests/test_lane_turn_desire.py @@ -1,5 +1,5 @@ import pytest -from cereal import log, custom +from openpilot.cereal import log, custom from openpilot.common.params import Params from openpilot.selfdrive.controls.lib.desire_helper import DesireHelper diff --git a/sunnypilot/selfdrive/locationd/.gitignore b/openpilot/sunnypilot/selfdrive/locationd/.gitignore similarity index 100% rename from sunnypilot/selfdrive/locationd/.gitignore rename to openpilot/sunnypilot/selfdrive/locationd/.gitignore diff --git a/sunnypilot/selfdrive/locationd/SConscript b/openpilot/sunnypilot/selfdrive/locationd/SConscript similarity index 100% rename from sunnypilot/selfdrive/locationd/SConscript rename to openpilot/sunnypilot/selfdrive/locationd/SConscript diff --git a/sunnypilot/selfdrive/locationd/__init__.py b/openpilot/sunnypilot/selfdrive/locationd/__init__.py similarity index 100% rename from sunnypilot/selfdrive/locationd/__init__.py rename to openpilot/sunnypilot/selfdrive/locationd/__init__.py diff --git a/sunnypilot/selfdrive/locationd/locationd.cc b/openpilot/sunnypilot/selfdrive/locationd/locationd.cc similarity index 100% rename from sunnypilot/selfdrive/locationd/locationd.cc rename to openpilot/sunnypilot/selfdrive/locationd/locationd.cc diff --git a/sunnypilot/selfdrive/locationd/locationd.h b/openpilot/sunnypilot/selfdrive/locationd/locationd.h similarity index 100% rename from sunnypilot/selfdrive/locationd/locationd.h rename to openpilot/sunnypilot/selfdrive/locationd/locationd.h diff --git a/sunnypilot/selfdrive/locationd/models/.gitignore b/openpilot/sunnypilot/selfdrive/locationd/models/.gitignore similarity index 100% rename from sunnypilot/selfdrive/locationd/models/.gitignore rename to openpilot/sunnypilot/selfdrive/locationd/models/.gitignore diff --git a/sunnypilot/selfdrive/locationd/models/__init__.py b/openpilot/sunnypilot/selfdrive/locationd/models/__init__.py similarity index 100% rename from sunnypilot/selfdrive/locationd/models/__init__.py rename to openpilot/sunnypilot/selfdrive/locationd/models/__init__.py diff --git a/sunnypilot/selfdrive/locationd/models/car_kf.py b/openpilot/sunnypilot/selfdrive/locationd/models/car_kf.py similarity index 100% rename from sunnypilot/selfdrive/locationd/models/car_kf.py rename to openpilot/sunnypilot/selfdrive/locationd/models/car_kf.py diff --git a/sunnypilot/selfdrive/locationd/models/constants.py b/openpilot/sunnypilot/selfdrive/locationd/models/constants.py similarity index 100% rename from sunnypilot/selfdrive/locationd/models/constants.py rename to openpilot/sunnypilot/selfdrive/locationd/models/constants.py diff --git a/sunnypilot/selfdrive/locationd/models/live_kf.cc b/openpilot/sunnypilot/selfdrive/locationd/models/live_kf.cc similarity index 100% rename from sunnypilot/selfdrive/locationd/models/live_kf.cc rename to openpilot/sunnypilot/selfdrive/locationd/models/live_kf.cc diff --git a/sunnypilot/selfdrive/locationd/models/live_kf.h b/openpilot/sunnypilot/selfdrive/locationd/models/live_kf.h similarity index 100% rename from sunnypilot/selfdrive/locationd/models/live_kf.h rename to openpilot/sunnypilot/selfdrive/locationd/models/live_kf.h diff --git a/sunnypilot/selfdrive/locationd/models/live_kf.py b/openpilot/sunnypilot/selfdrive/locationd/models/live_kf.py similarity index 100% rename from sunnypilot/selfdrive/locationd/models/live_kf.py rename to openpilot/sunnypilot/selfdrive/locationd/models/live_kf.py diff --git a/sunnypilot/selfdrive/locationd/tests/.gitignore b/openpilot/sunnypilot/selfdrive/locationd/tests/.gitignore similarity index 100% rename from sunnypilot/selfdrive/locationd/tests/.gitignore rename to openpilot/sunnypilot/selfdrive/locationd/tests/.gitignore diff --git a/sunnypilot/selfdrive/locationd/tests/__init__.py b/openpilot/sunnypilot/selfdrive/locationd/tests/__init__.py similarity index 100% rename from sunnypilot/selfdrive/locationd/tests/__init__.py rename to openpilot/sunnypilot/selfdrive/locationd/tests/__init__.py diff --git a/sunnypilot/selfdrive/locationd/tests/test_locationd.py b/openpilot/sunnypilot/selfdrive/locationd/tests/test_locationd.py similarity index 97% rename from sunnypilot/selfdrive/locationd/tests/test_locationd.py rename to openpilot/sunnypilot/selfdrive/locationd/tests/test_locationd.py index 1f5bfd3b25..551259fa01 100644 --- a/sunnypilot/selfdrive/locationd/tests/test_locationd.py +++ b/openpilot/sunnypilot/selfdrive/locationd/tests/test_locationd.py @@ -5,8 +5,8 @@ import random import time import capnp -import cereal.messaging as messaging -from cereal.services import SERVICE_LIST +import openpilot.cereal.messaging as messaging +from openpilot.cereal.services import SERVICE_LIST from openpilot.common.params import Params from openpilot.common.transformations.coordinates import ecef2geodetic diff --git a/sunnypilot/selfdrive/locationd/torqued_ext.py b/openpilot/sunnypilot/selfdrive/locationd/torqued_ext.py similarity index 98% rename from sunnypilot/selfdrive/locationd/torqued_ext.py rename to openpilot/sunnypilot/selfdrive/locationd/torqued_ext.py index 1e62b7666a..f1f16f58ee 100644 --- a/sunnypilot/selfdrive/locationd/torqued_ext.py +++ b/openpilot/sunnypilot/selfdrive/locationd/torqued_ext.py @@ -6,7 +6,7 @@ See the LICENSE.md file in the root directory for more details. """ import numpy as np -from cereal import car +from opendbc.car.structs import car from openpilot.common.params import Params from openpilot.common.realtime import DT_MDL diff --git a/sunnypilot/selfdrive/pandad/__init__.py b/openpilot/sunnypilot/selfdrive/pandad/__init__.py similarity index 100% rename from sunnypilot/selfdrive/pandad/__init__.py rename to openpilot/sunnypilot/selfdrive/pandad/__init__.py diff --git a/sunnypilot/selfdrive/pandad/rivian_long_flasher.py b/openpilot/sunnypilot/selfdrive/pandad/rivian_long_flasher.py similarity index 97% rename from sunnypilot/selfdrive/pandad/rivian_long_flasher.py rename to openpilot/sunnypilot/selfdrive/pandad/rivian_long_flasher.py index 305b994c78..3be9fb0e4d 100755 --- a/sunnypilot/selfdrive/pandad/rivian_long_flasher.py +++ b/openpilot/sunnypilot/selfdrive/pandad/rivian_long_flasher.py @@ -8,7 +8,8 @@ See the LICENSE.md file in the root directory for more details. import os from itertools import accumulate -from cereal import car, messaging +from openpilot.cereal import messaging +from opendbc.car.structs import car from panda import Panda from openpilot.common.params import Params from openpilot.common.swaglog import cloudlog diff --git a/sunnypilot/selfdrive/pandad/rivian_long_fw.bin.signed b/openpilot/sunnypilot/selfdrive/pandad/rivian_long_fw.bin.signed similarity index 100% rename from sunnypilot/selfdrive/pandad/rivian_long_fw.bin.signed rename to openpilot/sunnypilot/selfdrive/pandad/rivian_long_fw.bin.signed diff --git a/sunnypilot/selfdrive/selfdrived/__init__.py b/openpilot/sunnypilot/selfdrive/selfdrived/__init__.py similarity index 100% rename from sunnypilot/selfdrive/selfdrived/__init__.py rename to openpilot/sunnypilot/selfdrive/selfdrived/__init__.py diff --git a/sunnypilot/selfdrive/selfdrived/events.py b/openpilot/sunnypilot/selfdrive/selfdrived/events.py similarity index 98% rename from sunnypilot/selfdrive/selfdrived/events.py rename to openpilot/sunnypilot/selfdrive/selfdrived/events.py index e9b0e99153..2001d0dbee 100644 --- a/sunnypilot/selfdrive/selfdrived/events.py +++ b/openpilot/sunnypilot/selfdrive/selfdrived/events.py @@ -4,8 +4,9 @@ Copyright (c) 2021-, Haibin Wen, sunnypilot, and a number of other contributors. This file is part of sunnypilot and is licensed under the MIT License. See the LICENSE.md file in the root directory for more details. """ -import cereal.messaging as messaging -from cereal import log, car, custom +import openpilot.cereal.messaging as messaging +from openpilot.cereal import log, custom +from opendbc.car.structs import car from openpilot.common.constants import CV from openpilot.sunnypilot.selfdrive.selfdrived.events_base import EventsBase, Priority, ET, Alert, \ NoEntryAlert, ImmediateDisableAlert, EngagementAlert, NormalPermanentAlert, AlertCallbackType, wrong_car_mode_alert diff --git a/sunnypilot/selfdrive/selfdrived/events_base.py b/openpilot/sunnypilot/selfdrive/selfdrived/events_base.py similarity index 94% rename from sunnypilot/selfdrive/selfdrived/events_base.py rename to openpilot/sunnypilot/selfdrive/selfdrived/events_base.py index 402121f2fe..a392978144 100644 --- a/sunnypilot/selfdrive/selfdrived/events_base.py +++ b/openpilot/sunnypilot/selfdrive/selfdrived/events_base.py @@ -3,15 +3,16 @@ from enum import IntEnum from abc import abstractmethod from collections.abc import Callable -from cereal import log, car -import cereal.messaging as messaging +from openpilot.cereal import log +from opendbc.car.structs import car +import openpilot.cereal.messaging as messaging from openpilot.common.realtime import DT_CTRL from openpilot.common.hardware import HARDWARE AlertSize = log.SelfdriveState.AlertSize AlertStatus = log.SelfdriveState.AlertStatus VisualAlert = car.CarControl.HUDControl.VisualAlert -AudibleAlert = car.CarControl.HUDControl.AudibleAlert +AudibleAlert = log.SelfdriveState.AudibleAlert # Alert priorities @@ -46,7 +47,7 @@ class Alert: alert_size: log.SelfdriveState.AlertSize, priority: Priority, visual_alert: car.CarControl.HUDControl.VisualAlert, - audible_alert: car.CarControl.HUDControl.AudibleAlert, + audible_alert: log.SelfdriveState.AudibleAlert, duration: float, creation_delay: float = 0.): @@ -77,7 +78,7 @@ class AlertBase(Alert): def __init__(self, alert_text_1: str, alert_text_2: str, alert_status: log.SelfdriveState.AlertStatus, alert_size: log.SelfdriveState.AlertSize, priority: Priority, visual_alert: car.CarControl.HUDControl.VisualAlert, - audible_alert: car.CarControl.HUDControl.AudibleAlert, duration: float): + audible_alert: log.SelfdriveState.AudibleAlert, duration: float): super().__init__(alert_text_1, alert_text_2, alert_status, alert_size, priority, visual_alert, audible_alert, duration) @@ -185,11 +186,12 @@ EmptyAlert = Alert("" , "", AlertStatus.normal, AlertSize.none, Priority.LOWEST, class NoEntryAlert(Alert): def __init__(self, alert_text_2: str, alert_text_1: str = "openpilot Unavailable", - visual_alert: car.CarControl.HUDControl.VisualAlert=VisualAlert.none): + visual_alert: car.CarControl.HUDControl.VisualAlert=VisualAlert.none, + priority: Priority = Priority.LOW): if HARDWARE.get_device_type() == 'mici': alert_text_1, alert_text_2 = alert_text_2, alert_text_1 super().__init__(alert_text_1, alert_text_2, AlertStatus.normal, - AlertSize.mid, Priority.LOW, visual_alert, + AlertSize.mid, priority, visual_alert, AudibleAlert.refuse, 3.) @@ -217,7 +219,7 @@ class ImmediateDisableAlert(Alert): class EngagementAlert(Alert): - def __init__(self, audible_alert: car.CarControl.HUDControl.AudibleAlert): + def __init__(self, audible_alert: log.SelfdriveState.AudibleAlert): super().__init__("", "", AlertStatus.normal, AlertSize.none, Priority.MID, VisualAlert.none, diff --git a/sunnypilot/selfdrive/ui/quiet_mode.py b/openpilot/sunnypilot/selfdrive/ui/quiet_mode.py similarity index 96% rename from sunnypilot/selfdrive/ui/quiet_mode.py rename to openpilot/sunnypilot/selfdrive/ui/quiet_mode.py index 739ea1392c..d4dba74d95 100644 --- a/sunnypilot/selfdrive/ui/quiet_mode.py +++ b/openpilot/sunnypilot/selfdrive/ui/quiet_mode.py @@ -4,7 +4,7 @@ Copyright (c) 2021-, Haibin Wen, sunnypilot, and a number of other contributors. This file is part of sunnypilot and is licensed under the MIT License. See the LICENSE.md file in the root directory for more details. """ -from cereal import car +from opendbc.car.structs import car from openpilot.common.params import Params diff --git a/sunnypilot/sunnylink/__init__.py b/openpilot/sunnypilot/sunnylink/__init__.py similarity index 100% rename from sunnypilot/sunnylink/__init__.py rename to openpilot/sunnypilot/sunnylink/__init__.py diff --git a/sunnypilot/sunnylink/api.py b/openpilot/sunnypilot/sunnylink/api.py similarity index 100% rename from sunnypilot/sunnylink/api.py rename to openpilot/sunnypilot/sunnylink/api.py diff --git a/sunnypilot/sunnylink/athena/__init__.py b/openpilot/sunnypilot/sunnylink/athena/__init__.py similarity index 100% rename from sunnypilot/sunnylink/athena/__init__.py rename to openpilot/sunnypilot/sunnylink/athena/__init__.py diff --git a/sunnypilot/sunnylink/athena/manage_sunnylinkd.py b/openpilot/sunnypilot/sunnylink/athena/manage_sunnylinkd.py similarity index 76% rename from sunnypilot/sunnylink/athena/manage_sunnylinkd.py rename to openpilot/sunnypilot/sunnylink/athena/manage_sunnylinkd.py index 377b6990f7..d811fa5dbc 100755 --- a/sunnypilot/sunnylink/athena/manage_sunnylinkd.py +++ b/openpilot/sunnypilot/sunnylink/athena/manage_sunnylinkd.py @@ -2,4 +2,4 @@ from openpilot.system.athena.manage_athenad import manage_athenad if __name__ == '__main__': - manage_athenad("SunnylinkDongleId", "SunnylinkdPid", 'sunnylinkd', 'sunnypilot.sunnylink.athena.sunnylinkd') + manage_athenad("SunnylinkDongleId", "SunnylinkdPid", 'sunnylinkd', 'openpilot.sunnypilot.sunnylink.athena.sunnylinkd') diff --git a/sunnypilot/sunnylink/athena/sunnylinkd.py b/openpilot/sunnypilot/sunnylink/athena/sunnylinkd.py similarity index 99% rename from sunnypilot/sunnylink/athena/sunnylinkd.py rename to openpilot/sunnypilot/sunnylink/athena/sunnylinkd.py index 1a7e69f31c..ac168db7d8 100755 --- a/sunnypilot/sunnylink/athena/sunnylinkd.py +++ b/openpilot/sunnypilot/sunnylink/athena/sunnylinkd.py @@ -16,8 +16,8 @@ import ssl import threading import time -from jsonrpc import dispatcher from functools import partial +from openpilot.system.athena.rpc import dispatcher from openpilot.common.params import Params, ParamKeyType from openpilot.common.realtime import set_core_affinity from openpilot.common.swaglog import cloudlog @@ -27,7 +27,7 @@ from openpilot.system.athena.athenad import ws_send, jsonrpc_handler, \ from websocket import (ABNF, WebSocket, WebSocketException, WebSocketTimeoutException, create_connection, WebSocketConnectionClosedException) -import cereal.messaging as messaging +import openpilot.cereal.messaging as messaging from openpilot.sunnypilot.models.default_model import DEFAULT_MODEL from openpilot.sunnypilot.selfdrive.car.sync_sunnylink_params import update_car_list_param from openpilot.sunnypilot.sunnylink.api import SunnylinkApi diff --git a/sunnypilot/sunnylink/athena/tests/test_sunnylinkd.py b/openpilot/sunnypilot/sunnylink/athena/tests/test_sunnylinkd.py similarity index 100% rename from sunnypilot/sunnylink/athena/tests/test_sunnylinkd.py rename to openpilot/sunnypilot/sunnylink/athena/tests/test_sunnylinkd.py diff --git a/sunnypilot/sunnylink/backups/AESCipher.py b/openpilot/sunnypilot/sunnylink/backups/AESCipher.py similarity index 100% rename from sunnypilot/sunnylink/backups/AESCipher.py rename to openpilot/sunnypilot/sunnylink/backups/AESCipher.py diff --git a/sunnypilot/sunnylink/backups/__init__.py b/openpilot/sunnypilot/sunnylink/backups/__init__.py similarity index 100% rename from sunnypilot/sunnylink/backups/__init__.py rename to openpilot/sunnypilot/sunnylink/backups/__init__.py diff --git a/sunnypilot/sunnylink/backups/manager.py b/openpilot/sunnypilot/sunnylink/backups/manager.py similarity index 99% rename from sunnypilot/sunnylink/backups/manager.py rename to openpilot/sunnypilot/sunnylink/backups/manager.py index 44cdb3bff2..5ac6b8cabc 100644 --- a/sunnypilot/sunnylink/backups/manager.py +++ b/openpilot/sunnypilot/sunnylink/backups/manager.py @@ -16,9 +16,9 @@ from openpilot.common.git import get_branch from openpilot.common.params import Params, ParamKeyFlag from openpilot.common.realtime import Ratekeeper from openpilot.common.swaglog import cloudlog -from openpilot.system.version import get_version +from openpilot.common.version import get_version -from cereal import messaging, custom +from openpilot.cereal import messaging, custom from openpilot.sunnypilot.sunnylink.api import SunnylinkApi from openpilot.sunnypilot.sunnylink.backups.utils import decrypt_compressed_data, encrypt_compressed_data, SnakeCaseEncoder from openpilot.sunnypilot.sunnylink.utils import get_param_as_byte, save_param_from_base64_encoded_string diff --git a/sunnypilot/sunnylink/backups/utils.py b/openpilot/sunnypilot/sunnylink/backups/utils.py similarity index 100% rename from sunnypilot/sunnylink/backups/utils.py rename to openpilot/sunnypilot/sunnylink/backups/utils.py diff --git a/sunnypilot/sunnylink/capabilities.py b/openpilot/sunnypilot/sunnylink/capabilities.py similarity index 98% rename from sunnypilot/sunnylink/capabilities.py rename to openpilot/sunnypilot/sunnylink/capabilities.py index 197e404314..1f12b5b001 100644 --- a/sunnypilot/sunnylink/capabilities.py +++ b/openpilot/sunnypilot/sunnylink/capabilities.py @@ -6,7 +6,8 @@ See the LICENSE.md file in the root directory for more details. """ import json -from cereal import car, custom, messaging +from openpilot.cereal import custom, messaging +from opendbc.car.structs import car from opendbc.car.hyundai.values import CAR as HYUNDAI_CAR, UNSUPPORTED_LONGITUDINAL_CAR from opendbc.car.subaru.values import CAR as SUBARU_CAR, SubaruFlags from opendbc.sunnypilot.car.tesla.values import TeslaFlagsSP diff --git a/sunnypilot/sunnylink/docs/README.md b/openpilot/sunnypilot/sunnylink/docs/README.md similarity index 100% rename from sunnypilot/sunnylink/docs/README.md rename to openpilot/sunnypilot/sunnylink/docs/README.md diff --git a/sunnypilot/sunnylink/registration_manager.py b/openpilot/sunnypilot/sunnylink/registration_manager.py similarity index 95% rename from sunnypilot/sunnylink/registration_manager.py rename to openpilot/sunnypilot/sunnylink/registration_manager.py index 3e00c5c013..cc43dcae87 100755 --- a/sunnypilot/sunnylink/registration_manager.py +++ b/openpilot/sunnypilot/sunnylink/registration_manager.py @@ -5,7 +5,7 @@ from openpilot.common.params import Params from openpilot.common.realtime import Ratekeeper from openpilot.common.swaglog import cloudlog -from cereal import log, messaging +from openpilot.cereal import log, messaging from openpilot.sunnypilot.sunnylink.utils import register_sunnylink NetworkType = log.DeviceState.NetworkType diff --git a/sunnypilot/sunnylink/settings_ui.json b/openpilot/sunnypilot/sunnylink/settings_ui.json similarity index 100% rename from sunnypilot/sunnylink/settings_ui.json rename to openpilot/sunnypilot/sunnylink/settings_ui.json diff --git a/sunnypilot/sunnylink/settings_ui.schema.json b/openpilot/sunnypilot/sunnylink/settings_ui.schema.json similarity index 100% rename from sunnypilot/sunnylink/settings_ui.schema.json rename to openpilot/sunnypilot/sunnylink/settings_ui.schema.json diff --git a/sunnypilot/sunnylink/settings_ui_src/_macros.yaml b/openpilot/sunnypilot/sunnylink/settings_ui_src/_macros.yaml similarity index 100% rename from sunnypilot/sunnylink/settings_ui_src/_macros.yaml rename to openpilot/sunnypilot/sunnylink/settings_ui_src/_macros.yaml diff --git a/sunnypilot/sunnylink/settings_ui_src/_schemas/macros.schema.json b/openpilot/sunnypilot/sunnylink/settings_ui_src/_schemas/macros.schema.json similarity index 100% rename from sunnypilot/sunnylink/settings_ui_src/_schemas/macros.schema.json rename to openpilot/sunnypilot/sunnylink/settings_ui_src/_schemas/macros.schema.json diff --git a/sunnypilot/sunnylink/settings_ui_src/_schemas/page.schema.json b/openpilot/sunnypilot/sunnylink/settings_ui_src/_schemas/page.schema.json similarity index 100% rename from sunnypilot/sunnylink/settings_ui_src/_schemas/page.schema.json rename to openpilot/sunnypilot/sunnylink/settings_ui_src/_schemas/page.schema.json diff --git a/sunnypilot/sunnylink/settings_ui_src/_schemas/rule.schema.json b/openpilot/sunnypilot/sunnylink/settings_ui_src/_schemas/rule.schema.json similarity index 100% rename from sunnypilot/sunnylink/settings_ui_src/_schemas/rule.schema.json rename to openpilot/sunnypilot/sunnylink/settings_ui_src/_schemas/rule.schema.json diff --git a/sunnypilot/sunnylink/settings_ui_src/pages/cruise.yaml b/openpilot/sunnypilot/sunnylink/settings_ui_src/pages/cruise.yaml similarity index 100% rename from sunnypilot/sunnylink/settings_ui_src/pages/cruise.yaml rename to openpilot/sunnypilot/sunnylink/settings_ui_src/pages/cruise.yaml diff --git a/sunnypilot/sunnylink/settings_ui_src/pages/developer.yaml b/openpilot/sunnypilot/sunnylink/settings_ui_src/pages/developer.yaml similarity index 100% rename from sunnypilot/sunnylink/settings_ui_src/pages/developer.yaml rename to openpilot/sunnypilot/sunnylink/settings_ui_src/pages/developer.yaml diff --git a/sunnypilot/sunnylink/settings_ui_src/pages/device.yaml b/openpilot/sunnypilot/sunnylink/settings_ui_src/pages/device.yaml similarity index 100% rename from sunnypilot/sunnylink/settings_ui_src/pages/device.yaml rename to openpilot/sunnypilot/sunnylink/settings_ui_src/pages/device.yaml diff --git a/sunnypilot/sunnylink/settings_ui_src/pages/display.yaml b/openpilot/sunnypilot/sunnylink/settings_ui_src/pages/display.yaml similarity index 100% rename from sunnypilot/sunnylink/settings_ui_src/pages/display.yaml rename to openpilot/sunnypilot/sunnylink/settings_ui_src/pages/display.yaml diff --git a/sunnypilot/sunnylink/settings_ui_src/pages/models.yaml b/openpilot/sunnypilot/sunnylink/settings_ui_src/pages/models.yaml similarity index 100% rename from sunnypilot/sunnylink/settings_ui_src/pages/models.yaml rename to openpilot/sunnypilot/sunnylink/settings_ui_src/pages/models.yaml diff --git a/sunnypilot/sunnylink/settings_ui_src/pages/software.yaml b/openpilot/sunnypilot/sunnylink/settings_ui_src/pages/software.yaml similarity index 100% rename from sunnypilot/sunnylink/settings_ui_src/pages/software.yaml rename to openpilot/sunnypilot/sunnylink/settings_ui_src/pages/software.yaml diff --git a/sunnypilot/sunnylink/settings_ui_src/pages/steering.yaml b/openpilot/sunnypilot/sunnylink/settings_ui_src/pages/steering.yaml similarity index 100% rename from sunnypilot/sunnylink/settings_ui_src/pages/steering.yaml rename to openpilot/sunnypilot/sunnylink/settings_ui_src/pages/steering.yaml diff --git a/sunnypilot/sunnylink/settings_ui_src/pages/toggles.yaml b/openpilot/sunnypilot/sunnylink/settings_ui_src/pages/toggles.yaml similarity index 100% rename from sunnypilot/sunnylink/settings_ui_src/pages/toggles.yaml rename to openpilot/sunnypilot/sunnylink/settings_ui_src/pages/toggles.yaml diff --git a/sunnypilot/sunnylink/settings_ui_src/pages/vehicle.yaml b/openpilot/sunnypilot/sunnylink/settings_ui_src/pages/vehicle.yaml similarity index 100% rename from sunnypilot/sunnylink/settings_ui_src/pages/vehicle.yaml rename to openpilot/sunnypilot/sunnylink/settings_ui_src/pages/vehicle.yaml diff --git a/sunnypilot/sunnylink/settings_ui_src/pages/visuals.yaml b/openpilot/sunnypilot/sunnylink/settings_ui_src/pages/visuals.yaml similarity index 100% rename from sunnypilot/sunnylink/settings_ui_src/pages/visuals.yaml rename to openpilot/sunnypilot/sunnylink/settings_ui_src/pages/visuals.yaml diff --git a/sunnypilot/sunnylink/statsd.py b/openpilot/sunnypilot/sunnylink/statsd.py similarity index 97% rename from sunnypilot/sunnylink/statsd.py rename to openpilot/sunnypilot/sunnylink/statsd.py index f1ee18decd..7e8faf6327 100755 --- a/sunnypilot/sunnylink/statsd.py +++ b/openpilot/sunnypilot/sunnylink/statsd.py @@ -13,14 +13,14 @@ from collections import defaultdict from datetime import datetime, UTC from openpilot.common.params import Params -from cereal.messaging import SubMaster +from openpilot.cereal.messaging import SubMaster from openpilot.common.hardware.hw import Paths from openpilot.common.swaglog import cloudlog from openpilot.common.hardware import HARDWARE from openpilot.common.utils import atomic_write -from openpilot.system.version import get_build_metadata +from openpilot.common.version import get_build_metadata from openpilot.system.loggerd.config import STATS_DIR_FILE_LIMIT, STATS_SOCKET, STATS_FLUSH_TIME_S -from openpilot.system.statsd import METRIC_TYPE, StatLogSP +from openpilot.sunnypilot.system.statsd import METRIC_TYPE, StatLogSP from openpilot.common.realtime import Ratekeeper STATSLOGSP = StatLogSP(intercept=False) diff --git a/sunnypilot/sunnylink/sunnylink_state.py b/openpilot/sunnypilot/sunnylink/sunnylink_state.py similarity index 99% rename from sunnypilot/sunnylink/sunnylink_state.py rename to openpilot/sunnypilot/sunnylink/sunnylink_state.py index a4a3df3a2b..7dc553951e 100644 --- a/sunnypilot/sunnylink/sunnylink_state.py +++ b/openpilot/sunnypilot/sunnylink/sunnylink_state.py @@ -11,7 +11,7 @@ import time import json import pyray as rl -from cereal import messaging +from openpilot.cereal import messaging from openpilot.common.params import Params from openpilot.common.swaglog import cloudlog from openpilot.sunnypilot.sunnylink.api import UNREGISTERED_SUNNYLINK_DONGLE_ID, SunnylinkApi diff --git a/sunnypilot/sunnylink/tests/test_capabilities.py b/openpilot/sunnypilot/sunnylink/tests/test_capabilities.py similarity index 100% rename from sunnypilot/sunnylink/tests/test_capabilities.py rename to openpilot/sunnypilot/sunnylink/tests/test_capabilities.py diff --git a/sunnypilot/sunnylink/tests/test_compile_settings_ui.py b/openpilot/sunnypilot/sunnylink/tests/test_compile_settings_ui.py similarity index 100% rename from sunnypilot/sunnylink/tests/test_compile_settings_ui.py rename to openpilot/sunnypilot/sunnylink/tests/test_compile_settings_ui.py diff --git a/sunnypilot/sunnylink/tests/test_settings_changes.py b/openpilot/sunnypilot/sunnylink/tests/test_settings_changes.py similarity index 100% rename from sunnypilot/sunnylink/tests/test_settings_changes.py rename to openpilot/sunnypilot/sunnylink/tests/test_settings_changes.py diff --git a/sunnypilot/sunnylink/tests/test_settings_schema.py b/openpilot/sunnypilot/sunnylink/tests/test_settings_schema.py similarity index 100% rename from sunnypilot/sunnylink/tests/test_settings_schema.py rename to openpilot/sunnypilot/sunnylink/tests/test_settings_schema.py diff --git a/sunnypilot/sunnylink/tools/apply_macros.py b/openpilot/sunnypilot/sunnylink/tools/apply_macros.py similarity index 100% rename from sunnypilot/sunnylink/tools/apply_macros.py rename to openpilot/sunnypilot/sunnylink/tools/apply_macros.py diff --git a/sunnypilot/sunnylink/tools/compile_settings_ui.py b/openpilot/sunnypilot/sunnylink/tools/compile_settings_ui.py similarity index 100% rename from sunnypilot/sunnylink/tools/compile_settings_ui.py rename to openpilot/sunnypilot/sunnylink/tools/compile_settings_ui.py diff --git a/sunnypilot/sunnylink/tools/extract_settings_ui.py b/openpilot/sunnypilot/sunnylink/tools/extract_settings_ui.py similarity index 100% rename from sunnypilot/sunnylink/tools/extract_settings_ui.py rename to openpilot/sunnypilot/sunnylink/tools/extract_settings_ui.py diff --git a/sunnypilot/sunnylink/tools/generate_settings_schema.py b/openpilot/sunnypilot/sunnylink/tools/generate_settings_schema.py similarity index 100% rename from sunnypilot/sunnylink/tools/generate_settings_schema.py rename to openpilot/sunnypilot/sunnylink/tools/generate_settings_schema.py diff --git a/sunnypilot/sunnylink/tools/validate_settings_ui.py b/openpilot/sunnypilot/sunnylink/tools/validate_settings_ui.py similarity index 100% rename from sunnypilot/sunnylink/tools/validate_settings_ui.py rename to openpilot/sunnypilot/sunnylink/tools/validate_settings_ui.py diff --git a/sunnypilot/sunnylink/uploader.py b/openpilot/sunnypilot/sunnylink/uploader.py similarity index 99% rename from sunnypilot/sunnylink/uploader.py rename to openpilot/sunnypilot/sunnylink/uploader.py index c1da47fa0c..358e3a88e7 100755 --- a/sunnypilot/sunnylink/uploader.py +++ b/openpilot/sunnypilot/sunnylink/uploader.py @@ -9,8 +9,8 @@ import traceback import datetime from collections.abc import Iterator -from cereal import log -import cereal.messaging as messaging +from openpilot.cereal import log +import openpilot.cereal.messaging as messaging from openpilot.sunnypilot.sunnylink.api import SunnylinkApi from openpilot.common.utils import get_upload_stream from openpilot.common.params import Params diff --git a/sunnypilot/sunnylink/utils.py b/openpilot/sunnypilot/sunnylink/utils.py similarity index 98% rename from sunnypilot/sunnylink/utils.py rename to openpilot/sunnypilot/sunnylink/utils.py index 89c3c8a0c8..5588711977 100644 --- a/sunnypilot/sunnylink/utils.py +++ b/openpilot/sunnypilot/sunnylink/utils.py @@ -3,7 +3,7 @@ import gzip import json from openpilot.sunnypilot.sunnylink.api import SunnylinkApi, UNREGISTERED_SUNNYLINK_DONGLE_ID from openpilot.common.params import Params, ParamKeyType -from openpilot.system.version import is_prebuilt +from openpilot.common.version import is_prebuilt def get_sunnylink_status(params=None) -> tuple[bool, bool, bool]: diff --git a/sunnypilot/system/__init__.py b/openpilot/sunnypilot/system/__init__.py similarity index 100% rename from sunnypilot/system/__init__.py rename to openpilot/sunnypilot/system/__init__.py diff --git a/sunnypilot/system/hardware/c3/README.md b/openpilot/sunnypilot/system/hardware/c3/README.md similarity index 100% rename from sunnypilot/system/hardware/c3/README.md rename to openpilot/sunnypilot/system/hardware/c3/README.md diff --git a/sunnypilot/system/hardware/c3/agnos.json b/openpilot/sunnypilot/system/hardware/c3/agnos.json similarity index 100% rename from sunnypilot/system/hardware/c3/agnos.json rename to openpilot/sunnypilot/system/hardware/c3/agnos.json diff --git a/sunnypilot/system/hardware/c3/launch_chffrplus.sh b/openpilot/sunnypilot/system/hardware/c3/launch_chffrplus.sh similarity index 82% rename from sunnypilot/system/hardware/c3/launch_chffrplus.sh rename to openpilot/sunnypilot/system/hardware/c3/launch_chffrplus.sh index 45cc950537..a505e4f1f1 100755 --- a/sunnypilot/system/hardware/c3/launch_chffrplus.sh +++ b/openpilot/sunnypilot/system/hardware/c3/launch_chffrplus.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash SP_C3_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" -DIR="$( cd "$SP_C3_DIR/../../../.." >/dev/null 2>&1 && pwd )" +DIR="$( cd "$SP_C3_DIR/../../../../.." >/dev/null 2>&1 && pwd )" source "$SP_C3_DIR/launch_env.sh" @@ -19,12 +19,12 @@ function agnos_init { if [ $(< /VERSION) != "$AGNOS_VERSION" ]; then - AGNOS_PY="$DIR/system/hardware/tici/agnos.py" + AGNOS_PY="$DIR/openpilot/common/hardware/tici/agnos.py" MANIFEST="$SP_C3_DIR/agnos.json" if $AGNOS_PY --verify $MANIFEST; then sudo reboot fi - $DIR/system/hardware/tici/updater $AGNOS_PY $MANIFEST + $DIR/openpilot/common/hardware/tici/updater $AGNOS_PY $MANIFEST fi } @@ -70,6 +70,14 @@ function launch { ln -sfn $(pwd) /data/pythonpath export PYTHONPATH="$PWD" + # submodule package symlinks for PYTHONPATH imports on device. + # on PC these come from editable installs via pyproject.toml / uv. + ln -sfn msgq_repo/msgq msgq + ln -sfn opendbc_repo/opendbc opendbc + ln -sfn rednose_repo/rednose rednose + ln -sfn teleoprtc_repo/teleoprtc teleoprtc + ln -sfn tinygrad_repo/tinygrad tinygrad + # hardware specific init if [ -f /AGNOS ]; then agnos_init @@ -79,7 +87,7 @@ function launch { tmux capture-pane -pq -S-1000 > /tmp/launch_log # start manager - cd $DIR/system/manager + cd $DIR/openpilot/system/manager if [ ! -f $DIR/prebuilt ]; then ./build.py fi diff --git a/sunnypilot/system/hardware/c3/launch_env.sh b/openpilot/sunnypilot/system/hardware/c3/launch_env.sh similarity index 100% rename from sunnypilot/system/hardware/c3/launch_env.sh rename to openpilot/sunnypilot/system/hardware/c3/launch_env.sh diff --git a/sunnypilot/system/params_migration.py b/openpilot/sunnypilot/system/params_migration.py similarity index 100% rename from sunnypilot/system/params_migration.py rename to openpilot/sunnypilot/system/params_migration.py diff --git a/sunnypilot/system/sensord/.gitignore b/openpilot/sunnypilot/system/sensord/.gitignore similarity index 100% rename from sunnypilot/system/sensord/.gitignore rename to openpilot/sunnypilot/system/sensord/.gitignore diff --git a/sunnypilot/system/sensord/SConscript b/openpilot/sunnypilot/system/sensord/SConscript similarity index 100% rename from sunnypilot/system/sensord/SConscript rename to openpilot/sunnypilot/system/sensord/SConscript diff --git a/sunnypilot/system/sensord/sensors/bmx055_accel.cc b/openpilot/sunnypilot/system/sensord/sensors/bmx055_accel.cc similarity index 100% rename from sunnypilot/system/sensord/sensors/bmx055_accel.cc rename to openpilot/sunnypilot/system/sensord/sensors/bmx055_accel.cc diff --git a/sunnypilot/system/sensord/sensors/bmx055_accel.h b/openpilot/sunnypilot/system/sensord/sensors/bmx055_accel.h similarity index 100% rename from sunnypilot/system/sensord/sensors/bmx055_accel.h rename to openpilot/sunnypilot/system/sensord/sensors/bmx055_accel.h diff --git a/sunnypilot/system/sensord/sensors/bmx055_gyro.cc b/openpilot/sunnypilot/system/sensord/sensors/bmx055_gyro.cc similarity index 100% rename from sunnypilot/system/sensord/sensors/bmx055_gyro.cc rename to openpilot/sunnypilot/system/sensord/sensors/bmx055_gyro.cc diff --git a/sunnypilot/system/sensord/sensors/bmx055_gyro.h b/openpilot/sunnypilot/system/sensord/sensors/bmx055_gyro.h similarity index 100% rename from sunnypilot/system/sensord/sensors/bmx055_gyro.h rename to openpilot/sunnypilot/system/sensord/sensors/bmx055_gyro.h diff --git a/sunnypilot/system/sensord/sensors/bmx055_magn.cc b/openpilot/sunnypilot/system/sensord/sensors/bmx055_magn.cc similarity index 100% rename from sunnypilot/system/sensord/sensors/bmx055_magn.cc rename to openpilot/sunnypilot/system/sensord/sensors/bmx055_magn.cc diff --git a/sunnypilot/system/sensord/sensors/bmx055_magn.h b/openpilot/sunnypilot/system/sensord/sensors/bmx055_magn.h similarity index 100% rename from sunnypilot/system/sensord/sensors/bmx055_magn.h rename to openpilot/sunnypilot/system/sensord/sensors/bmx055_magn.h diff --git a/sunnypilot/system/sensord/sensors/bmx055_temp.cc b/openpilot/sunnypilot/system/sensord/sensors/bmx055_temp.cc similarity index 100% rename from sunnypilot/system/sensord/sensors/bmx055_temp.cc rename to openpilot/sunnypilot/system/sensord/sensors/bmx055_temp.cc diff --git a/sunnypilot/system/sensord/sensors/bmx055_temp.h b/openpilot/sunnypilot/system/sensord/sensors/bmx055_temp.h similarity index 100% rename from sunnypilot/system/sensord/sensors/bmx055_temp.h rename to openpilot/sunnypilot/system/sensord/sensors/bmx055_temp.h diff --git a/sunnypilot/system/sensord/sensors/constants.h b/openpilot/sunnypilot/system/sensord/sensors/constants.h similarity index 100% rename from sunnypilot/system/sensord/sensors/constants.h rename to openpilot/sunnypilot/system/sensord/sensors/constants.h diff --git a/sunnypilot/system/sensord/sensors/i2c_sensor.cc b/openpilot/sunnypilot/system/sensord/sensors/i2c_sensor.cc similarity index 100% rename from sunnypilot/system/sensord/sensors/i2c_sensor.cc rename to openpilot/sunnypilot/system/sensord/sensors/i2c_sensor.cc diff --git a/sunnypilot/system/sensord/sensors/i2c_sensor.h b/openpilot/sunnypilot/system/sensord/sensors/i2c_sensor.h similarity index 100% rename from sunnypilot/system/sensord/sensors/i2c_sensor.h rename to openpilot/sunnypilot/system/sensord/sensors/i2c_sensor.h diff --git a/sunnypilot/system/sensord/sensors/lsm6ds3_accel.cc b/openpilot/sunnypilot/system/sensord/sensors/lsm6ds3_accel.cc similarity index 100% rename from sunnypilot/system/sensord/sensors/lsm6ds3_accel.cc rename to openpilot/sunnypilot/system/sensord/sensors/lsm6ds3_accel.cc diff --git a/sunnypilot/system/sensord/sensors/lsm6ds3_accel.h b/openpilot/sunnypilot/system/sensord/sensors/lsm6ds3_accel.h similarity index 100% rename from sunnypilot/system/sensord/sensors/lsm6ds3_accel.h rename to openpilot/sunnypilot/system/sensord/sensors/lsm6ds3_accel.h diff --git a/sunnypilot/system/sensord/sensors/lsm6ds3_gyro.cc b/openpilot/sunnypilot/system/sensord/sensors/lsm6ds3_gyro.cc similarity index 100% rename from sunnypilot/system/sensord/sensors/lsm6ds3_gyro.cc rename to openpilot/sunnypilot/system/sensord/sensors/lsm6ds3_gyro.cc diff --git a/sunnypilot/system/sensord/sensors/lsm6ds3_gyro.h b/openpilot/sunnypilot/system/sensord/sensors/lsm6ds3_gyro.h similarity index 100% rename from sunnypilot/system/sensord/sensors/lsm6ds3_gyro.h rename to openpilot/sunnypilot/system/sensord/sensors/lsm6ds3_gyro.h diff --git a/sunnypilot/system/sensord/sensors/lsm6ds3_temp.cc b/openpilot/sunnypilot/system/sensord/sensors/lsm6ds3_temp.cc similarity index 100% rename from sunnypilot/system/sensord/sensors/lsm6ds3_temp.cc rename to openpilot/sunnypilot/system/sensord/sensors/lsm6ds3_temp.cc diff --git a/sunnypilot/system/sensord/sensors/lsm6ds3_temp.h b/openpilot/sunnypilot/system/sensord/sensors/lsm6ds3_temp.h similarity index 100% rename from sunnypilot/system/sensord/sensors/lsm6ds3_temp.h rename to openpilot/sunnypilot/system/sensord/sensors/lsm6ds3_temp.h diff --git a/sunnypilot/system/sensord/sensors/mmc5603nj_magn.cc b/openpilot/sunnypilot/system/sensord/sensors/mmc5603nj_magn.cc similarity index 100% rename from sunnypilot/system/sensord/sensors/mmc5603nj_magn.cc rename to openpilot/sunnypilot/system/sensord/sensors/mmc5603nj_magn.cc diff --git a/sunnypilot/system/sensord/sensors/mmc5603nj_magn.h b/openpilot/sunnypilot/system/sensord/sensors/mmc5603nj_magn.h similarity index 100% rename from sunnypilot/system/sensord/sensors/mmc5603nj_magn.h rename to openpilot/sunnypilot/system/sensord/sensors/mmc5603nj_magn.h diff --git a/sunnypilot/system/sensord/sensors/sensor.h b/openpilot/sunnypilot/system/sensord/sensors/sensor.h similarity index 100% rename from sunnypilot/system/sensord/sensors/sensor.h rename to openpilot/sunnypilot/system/sensord/sensors/sensor.h diff --git a/sunnypilot/system/sensord/sensors_qcom2.cc b/openpilot/sunnypilot/system/sensord/sensors_qcom2.cc similarity index 100% rename from sunnypilot/system/sensord/sensors_qcom2.cc rename to openpilot/sunnypilot/system/sensord/sensors_qcom2.cc diff --git a/sunnypilot/system/sensord/tests/test_sensord.py b/openpilot/sunnypilot/system/sensord/tests/test_sensord.py similarity index 97% rename from sunnypilot/system/sensord/tests/test_sensord.py rename to openpilot/sunnypilot/system/sensord/tests/test_sensord.py index 9e09930f0c..98321fb12c 100644 --- a/sunnypilot/system/sensord/tests/test_sensord.py +++ b/openpilot/sunnypilot/system/sensord/tests/test_sensord.py @@ -1,12 +1,13 @@ import os +import subprocess import pytest import time import numpy as np from collections import namedtuple, defaultdict -import cereal.messaging as messaging -from cereal import log -from cereal.services import SERVICE_LIST +import openpilot.cereal.messaging as messaging +from openpilot.cereal import log +from openpilot.cereal.services import SERVICE_LIST from openpilot.common.gpio import get_irqs_for_action from openpilot.common.timeout import Timeout from openpilot.common.hardware import HARDWARE @@ -110,7 +111,7 @@ class TestSensord: os.environ["LSM_SELF_TEST"] = "1" # read initial sensor values every test case can use - os.system("pkill -f \\\\./sensord") + subprocess.run(["pkill", "-f", r"\\./sensord"], check=False) try: managed_processes["sensord"].start() cls.sample_secs = int(os.getenv("SAMPLE_SECS", "10")) diff --git a/sunnypilot/system/sensord/tests/ttff_test.py b/openpilot/sunnypilot/system/sensord/tests/ttff_test.py similarity index 96% rename from sunnypilot/system/sensord/tests/ttff_test.py rename to openpilot/sunnypilot/system/sensord/tests/ttff_test.py index a9cc16d707..cc8408055c 100755 --- a/sunnypilot/system/sensord/tests/ttff_test.py +++ b/openpilot/sunnypilot/system/sensord/tests/ttff_test.py @@ -3,7 +3,7 @@ import time import atexit -from cereal import messaging +from openpilot.cereal import messaging from openpilot.system.manager.process_config import managed_processes TIMEOUT = 10*60 diff --git a/system/statsd.py b/openpilot/sunnypilot/system/statsd.py similarity index 98% rename from system/statsd.py rename to openpilot/sunnypilot/system/statsd.py index 4b2e67caeb..ff77a5a57f 100755 --- a/system/statsd.py +++ b/openpilot/sunnypilot/system/statsd.py @@ -13,12 +13,12 @@ from datetime import datetime, UTC, date from typing import NoReturn from openpilot.common.params import Params -from cereal.messaging import SubMaster +from openpilot.cereal.messaging import SubMaster from openpilot.common.hardware.hw import Paths from openpilot.common.swaglog import cloudlog from openpilot.common.hardware import HARDWARE from openpilot.common.utils import atomic_write -from openpilot.system.version import get_build_metadata +from openpilot.common.version import get_build_metadata from openpilot.system.loggerd.config import STATS_DIR_FILE_LIMIT, STATS_SOCKET, STATS_FLUSH_TIME_S diff --git a/sunnypilot/system/updated/tests/test_sp_branch_migrations.py b/openpilot/sunnypilot/system/updated/tests/test_sp_branch_migrations.py similarity index 100% rename from sunnypilot/system/updated/tests/test_sp_branch_migrations.py rename to openpilot/sunnypilot/system/updated/tests/test_sp_branch_migrations.py diff --git a/sunnypilot/tools/__init__.py b/openpilot/sunnypilot/tools/__init__.py similarity index 100% rename from sunnypilot/tools/__init__.py rename to openpilot/sunnypilot/tools/__init__.py diff --git a/sunnypilot/tools/memory_profiler/__init__.py b/openpilot/sunnypilot/tools/memory_profiler/__init__.py similarity index 100% rename from sunnypilot/tools/memory_profiler/__init__.py rename to openpilot/sunnypilot/tools/memory_profiler/__init__.py diff --git a/sunnypilot/tools/memory_profiler/mem_usage.py b/openpilot/sunnypilot/tools/memory_profiler/mem_usage.py similarity index 100% rename from sunnypilot/tools/memory_profiler/mem_usage.py rename to openpilot/sunnypilot/tools/memory_profiler/mem_usage.py diff --git a/sunnypilot/tools/pull_footage.py b/openpilot/sunnypilot/tools/pull_footage.py similarity index 100% rename from sunnypilot/tools/pull_footage.py rename to openpilot/sunnypilot/tools/pull_footage.py diff --git a/openpilot/system/athena/athenad.py b/openpilot/system/athena/athenad.py index c6508f39fd..292dcdd174 100755 --- a/openpilot/system/athena/athenad.py +++ b/openpilot/system/athena/athenad.py @@ -1,6 +1,7 @@ #!/usr/bin/env python3 from __future__ import annotations +import base64 import hashlib import itertools import json @@ -10,6 +11,7 @@ import random import select import socket import sys +import tempfile import threading import time import gzip @@ -38,7 +40,7 @@ from openpilot.system.loggerd.xattr_cache import getxattr, setxattr from openpilot.common.swaglog import cloudlog from openpilot.common.version import get_build_metadata from openpilot.common.hardware.hw import Paths -from openpilot.system.athena.rpc import dispatcher, dumps_call, handle, is_call, is_response, loads +from openpilot.system.athena.rpc import dispatcher, handle, is_call, is_response, loads ATHENA_HOST = os.getenv('ATHENA_HOST', 'wss://athena.comma.ai') @@ -624,24 +626,6 @@ def startStream(sdp: str, enabled: bool) -> dict: return post_stream_request(StreamRequestBody(sdp, "wideRoad", enabled, bridge_services_in, ["carState", "deviceState"])) -@dispatcher.add_method -def takeSnapshot() -> str | dict[str, str] | None: - from openpilot.system.camerad.snapshot import jpeg_write, snapshot - ret = snapshot() - if ret is not None: - def b64jpeg(x): - if x is not None: - f = io.BytesIO() - jpeg_write(f, x) - return base64.b64encode(f.getvalue()).decode("utf-8") - else: - return None - return {'jpegBack': b64jpeg(ret[0]), - 'jpegFront': b64jpeg(ret[1])} - else: - raise Exception("not available while camerad is started") - - def get_logs_to_send_sorted(log_attr_name=LOG_ATTR_NAME) -> list[str]: # TODO: scan once then use inotify to detect file creation/deletion curr_time = int(time.time()) # noqa: TID251 diff --git a/openpilot/system/athena/manage_athenad.py b/openpilot/system/athena/manage_athenad.py index 7ab88fb67e..3f0d6adcd3 100755 --- a/openpilot/system/athena/manage_athenad.py +++ b/openpilot/system/athena/manage_athenad.py @@ -13,7 +13,7 @@ ATHENA_MGR_PID_PARAM = "AthenadPid" def main(): - manage_athenad("DongleId", ATHENA_MGR_PID_PARAM, 'athenad', 'system.athena.athenad') + manage_athenad("DongleId", ATHENA_MGR_PID_PARAM, 'athenad', 'openpilot.system.athena.athenad') def manage_athenad(dongle_id_param, pid_param, process_name, target): diff --git a/openpilot/system/hardware/hardwared.py b/openpilot/system/hardware/hardwared.py index 165bdd6d16..e5b3d8020c 100755 --- a/openpilot/system/hardware/hardwared.py +++ b/openpilot/system/hardware/hardwared.py @@ -15,15 +15,16 @@ from openpilot.common.filter_simple import FirstOrderFilter from openpilot.common.params import Params from openpilot.common.realtime import DT_HW from openpilot.selfdrive.selfdrived.alertmanager import set_offroad_alert -from openpilot.common.hardware import HARDWARE, TICI, PC +from openpilot.common.hardware import HARDWARE, TICI from openpilot.common.hardware.usb import get_usb_state, set_usb_state from openpilot.common.linux import LinuxSystemStats from openpilot.system.loggerd.config import get_available_percent from openpilot.common.swaglog import cloudlog +from openpilot.sunnypilot.system.statsd import statlog from openpilot.system.hardware.power_monitoring import PowerMonitoring from openpilot.system.hardware.fan_controller import FanController from openpilot.common.version import terms_version, training_version, get_build_metadata, terms_version_sp -from openpilot.system.athena.registration import UNREGISTERED_DONGLE_ID + ThermalStatus = log.DeviceState.ThermalStatus NetworkType = log.DeviceState.NetworkType @@ -379,9 +380,11 @@ def hardware_thread(end_event, hw_queue) -> None: msg.deviceState.offroadPowerUsageUwh = power_monitor.get_power_used() msg.deviceState.carBatteryCapacityUwh = max(0, power_monitor.get_car_battery_capacity()) current_power_draw = HARDWARE.get_current_power_draw() + statlog.sample("power_draw", current_power_draw) msg.deviceState.powerDrawW = current_power_draw som_power_draw = HARDWARE.get_som_power_draw() + statlog.sample("som_power_draw", som_power_draw) msg.deviceState.somPowerDrawW = som_power_draw # Check if we need to shut down @@ -399,6 +402,23 @@ def hardware_thread(end_event, hw_queue) -> None: msg.deviceState.thermalStatus = thermal_status pm.send("deviceState", msg) + statlog.gauge("free_space_percent", msg.deviceState.freeSpacePercent) + statlog.gauge("gpu_usage_percent", msg.deviceState.gpuUsagePercent) + statlog.gauge("memory_usage_percent", msg.deviceState.memoryUsagePercent) + for i, usage in enumerate(msg.deviceState.cpuUsagePercent): + statlog.gauge(f"cpu{i}_usage_percent", usage) + for i, temp in enumerate(msg.deviceState.cpuTempC): + statlog.gauge(f"cpu{i}_temperature", temp) + for i, temp in enumerate(msg.deviceState.gpuTempC): + statlog.gauge(f"gpu{i}_temperature", temp) + statlog.gauge("memory_temperature", msg.deviceState.memoryTempC) + for i, temp in enumerate(msg.deviceState.pmicTempC): + statlog.gauge(f"pmic{i}_temperature", temp) + for i, temp in enumerate(last_hw_state.modem_temps): + statlog.gauge(f"modem_temperature{i}", temp) + statlog.gauge("fan_speed_percent_desired", msg.deviceState.fanSpeedPercentDesired) + statlog.gauge("screen_brightness_percent", msg.deviceState.screenBrightnessPercent) + # report to server once every 10 minutes, or every 1s when thermally blocked rising_edge_started = should_start and not should_start_prev status_packet_interval = 1. if show_alert else 600. diff --git a/openpilot/system/hardware/power_monitoring.py b/openpilot/system/hardware/power_monitoring.py index 0c26569731..ca3390b8f0 100644 --- a/openpilot/system/hardware/power_monitoring.py +++ b/openpilot/system/hardware/power_monitoring.py @@ -4,6 +4,7 @@ import threading from openpilot.common.params import Params from openpilot.common.hardware import HARDWARE from openpilot.common.swaglog import cloudlog +from openpilot.sunnypilot.system.statsd import statlog CAR_VOLTAGE_LOW_PASS_K = 0.011 # LPF gain for 45s tau (dt/tau / (dt/tau + 1)) @@ -49,6 +50,7 @@ class PowerMonitoring: # Low-pass battery voltage self.car_voltage_instant_mV = voltage self.car_voltage_mV = ((voltage * CAR_VOLTAGE_LOW_PASS_K) + (self.car_voltage_mV * (1 - CAR_VOLTAGE_LOW_PASS_K))) + statlog.gauge("car_voltage", self.car_voltage_mV / 1e3) # Cap the car battery power and save it in a param every 10-ish seconds self.car_battery_capacity_uWh = max(self.car_battery_capacity_uWh, 0) diff --git a/openpilot/system/manager/process_config.py b/openpilot/system/manager/process_config.py index 655d1c4e29..a72675385d 100644 --- a/openpilot/system/manager/process_config.py +++ b/openpilot/system/manager/process_config.py @@ -3,9 +3,16 @@ import operator import platform from opendbc.car.structs import car +from openpilot.cereal import custom from openpilot.common.params import Params from openpilot.common.hardware import PC, TICI from openpilot.system.manager.process import PythonProcess, NativeProcess, DaemonProcess +from openpilot.common.hardware.hw import Paths + +from openpilot.sunnypilot.mapd.mapd_manager import MAPD_PATH + +from openpilot.sunnypilot.models.helpers import get_active_model_runner +from openpilot.sunnypilot.sunnylink.utils import sunnylink_need_register, sunnylink_ready, use_sunnylink_uploader WEBCAM = os.getenv("USE_WEBCAM") is not None @@ -61,6 +68,42 @@ def only_offroad(started: bool, params: Params, CP: car.CarParams) -> bool: def livestream(started: bool, params: Params, CP: car.CarParams) -> bool: return params.get_bool("IsLiveStreaming") +def use_github_runner(started, params, CP: car.CarParams) -> bool: + return not PC and params.get_bool("EnableGithubRunner") and ( + not params.get_bool("NetworkMetered") and not params.get_bool("GithubRunnerSufficientVoltage")) + +def use_copyparty(started, params, CP: car.CarParams) -> bool: + return bool(params.get_bool("EnableCopyparty")) + +def sunnylink_ready_shim(started, params, CP: car.CarParams) -> bool: + """Shim for sunnylink_ready to match the process manager signature.""" + return sunnylink_ready(params) + +def sunnylink_need_register_shim(started, params, CP: car.CarParams) -> bool: + """Shim for sunnylink_need_register to match the process manager signature.""" + return sunnylink_need_register(params) + +def use_sunnylink_uploader_shim(started, params, CP: car.CarParams) -> bool: + """Shim for use_sunnylink_uploader to match the process manager signature.""" + return use_sunnylink_uploader(params) + +def is_tinygrad_model(started, params, CP: car.CarParams) -> bool: + """Check if the active model runner is SNPE.""" + return bool(get_active_model_runner(params, not started) == custom.ModelManagerSP.Runner.tinygrad) + +def is_stock_model(started, params, CP: car.CarParams) -> bool: + """Check if the active model runner is stock.""" + return bool(get_active_model_runner(params, not started) == custom.ModelManagerSP.Runner.stock) + +def mapd_ready(started: bool, params: Params, CP: car.CarParams) -> bool: + return bool(os.path.exists(Paths.mapd_root())) + +def uploader_ready(started: bool, params: Params, CP: car.CarParams) -> bool: + if not params.get_bool("OnroadUploads"): + return only_offroad(started, params, CP) + + return always_run(started, params, CP) + def or_(*fns): return lambda *args: operator.or_(*(fn(*args) for fn in fns)) @@ -85,7 +128,7 @@ procs = [ PythonProcess("micd", "openpilot.system.micd", iscar), PythonProcess("timed", "openpilot.system.timed", always_run, enabled=not PC), - PythonProcess("modeld", "openpilot.selfdrive.modeld.modeld", only_onroad), + PythonProcess("modeld", "openpilot.selfdrive.modeld.modeld", and_(only_onroad, is_stock_model)), PythonProcess("dmonitoringmodeld", "openpilot.selfdrive.modeld.dmonitoringmodeld", driverview, enabled=(WEBCAM or not PC)), PythonProcess("sensord", "openpilot.system.sensord.sensord", only_onroad, enabled=not PC), @@ -115,13 +158,54 @@ procs = [ PythonProcess("modem", "openpilot.common.hardware.tici.modem", always_run, enabled=TICI), PythonProcess("tombstoned", "openpilot.system.tombstoned", always_run, enabled=not PC), PythonProcess("updated", "openpilot.system.updated.updated", only_offroad, enabled=not PC), - PythonProcess("uploader", "openpilot.system.loggerd.uploader", always_run), + PythonProcess("uploader", "openpilot.system.loggerd.uploader", uploader_ready), + PythonProcess("statsd", "openpilot.sunnypilot.system.statsd", always_run), PythonProcess("feedbackd", "openpilot.selfdrive.ui.feedback.feedbackd", only_onroad), # debug procs NativeProcess("bridge", "openpilot/cereal/messaging", ["./bridge"], notcar), PythonProcess("webrtcd", "openpilot.system.webrtc.webrtcd", or_(and_(livestream, not_(iscar)), notcar)), PythonProcess("joystick", "openpilot.tools.joystick.joystick_control", and_(joystick, iscar)), + + # sunnylink <3 + DaemonProcess("manage_sunnylinkd", "openpilot.sunnypilot.sunnylink.athena.manage_sunnylinkd", "SunnylinkdPid"), + PythonProcess("sunnylink_registration_manager", "openpilot.sunnypilot.sunnylink.registration_manager", sunnylink_need_register_shim), + PythonProcess("statsd_sp", "openpilot.sunnypilot.sunnylink.statsd", and_(always_run, sunnylink_ready_shim)), ] +# sunnypilot +procs += [ + # Models + PythonProcess("models_manager", "openpilot.sunnypilot.models.manager", only_offroad), + NativeProcess("modeld_tinygrad", "openpilot/sunnypilot/modeld_v2", ["./modeld"], and_(only_onroad, is_tinygrad_model)), + + # Backup + PythonProcess("backup_manager", "openpilot.sunnypilot.sunnylink.backups.manager", and_(only_offroad, sunnylink_ready_shim)), + + # mapd + NativeProcess("mapd", Paths.mapd_root(), ["bash", "-c", f"{MAPD_PATH} > /dev/null 2>&1"], mapd_ready), + PythonProcess("mapd_manager", "openpilot.sunnypilot.mapd.mapd_manager", always_run), + + # locationd + NativeProcess("locationd_llk", "openpilot/sunnypilot/selfdrive/locationd", ["./locationd"], only_onroad), +] + +if os.path.exists("./github_runner.sh"): + procs += [NativeProcess("github_runner_start", "openpilot/system/manager", + ["./github_runner.sh", "start"], and_(only_offroad, use_github_runner), sigkill=False)] + +if os.path.exists("../../sunnypilot/sunnylink/uploader.py"): + procs += [PythonProcess("sunnylink_uploader", "openpilot.sunnypilot.sunnylink.uploader", use_sunnylink_uploader_shim)] + +if os.path.exists("../../third_party/copyparty/copyparty-sfx.py"): + sunnypilot_root = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..")) + copyparty_args = [f"-v{Paths.crash_log_root()}:/swaglogs:r"] + copyparty_args += [f"-v{Paths.log_root()}:/routes:r"] + copyparty_args += [f"-v{Paths.model_root()}:/models:rw"] + copyparty_args += [f"-v{sunnypilot_root}:/sunnypilot:rw"] + copyparty_args += ["-p8080"] + copyparty_args += ["-z"] + copyparty_args += ["-q"] + procs += [NativeProcess("copyparty-sfx", "openpilot/third_party/copyparty", ["./copyparty-sfx.py", *copyparty_args], and_(only_offroad, use_copyparty))] + managed_processes = {p.name: p for p in procs} diff --git a/system/ui/sunnypilot/lib/application.py b/openpilot/system/ui/sunnypilot/lib/application.py similarity index 100% rename from system/ui/sunnypilot/lib/application.py rename to openpilot/system/ui/sunnypilot/lib/application.py diff --git a/system/ui/sunnypilot/lib/styles.py b/openpilot/system/ui/sunnypilot/lib/styles.py similarity index 100% rename from system/ui/sunnypilot/lib/styles.py rename to openpilot/system/ui/sunnypilot/lib/styles.py diff --git a/system/ui/sunnypilot/lib/utils.py b/openpilot/system/ui/sunnypilot/lib/utils.py similarity index 100% rename from system/ui/sunnypilot/lib/utils.py rename to openpilot/system/ui/sunnypilot/lib/utils.py diff --git a/system/ui/sunnypilot/widgets/__init__.py b/openpilot/system/ui/sunnypilot/widgets/__init__.py similarity index 100% rename from system/ui/sunnypilot/widgets/__init__.py rename to openpilot/system/ui/sunnypilot/widgets/__init__.py diff --git a/system/ui/sunnypilot/widgets/helpers/__init__.py b/openpilot/system/ui/sunnypilot/widgets/helpers/__init__.py similarity index 100% rename from system/ui/sunnypilot/widgets/helpers/__init__.py rename to openpilot/system/ui/sunnypilot/widgets/helpers/__init__.py diff --git a/system/ui/sunnypilot/widgets/helpers/fuzzy_search.py b/openpilot/system/ui/sunnypilot/widgets/helpers/fuzzy_search.py similarity index 100% rename from system/ui/sunnypilot/widgets/helpers/fuzzy_search.py rename to openpilot/system/ui/sunnypilot/widgets/helpers/fuzzy_search.py diff --git a/system/ui/sunnypilot/widgets/helpers/star_icon.py b/openpilot/system/ui/sunnypilot/widgets/helpers/star_icon.py similarity index 100% rename from system/ui/sunnypilot/widgets/helpers/star_icon.py rename to openpilot/system/ui/sunnypilot/widgets/helpers/star_icon.py diff --git a/system/ui/sunnypilot/widgets/html_render.py b/openpilot/system/ui/sunnypilot/widgets/html_render.py similarity index 100% rename from system/ui/sunnypilot/widgets/html_render.py rename to openpilot/system/ui/sunnypilot/widgets/html_render.py diff --git a/system/ui/sunnypilot/widgets/input_dialog.py b/openpilot/system/ui/sunnypilot/widgets/input_dialog.py similarity index 100% rename from system/ui/sunnypilot/widgets/input_dialog.py rename to openpilot/system/ui/sunnypilot/widgets/input_dialog.py diff --git a/system/ui/sunnypilot/widgets/list_view.py b/openpilot/system/ui/sunnypilot/widgets/list_view.py similarity index 100% rename from system/ui/sunnypilot/widgets/list_view.py rename to openpilot/system/ui/sunnypilot/widgets/list_view.py diff --git a/system/ui/sunnypilot/widgets/option_control.py b/openpilot/system/ui/sunnypilot/widgets/option_control.py similarity index 100% rename from system/ui/sunnypilot/widgets/option_control.py rename to openpilot/system/ui/sunnypilot/widgets/option_control.py diff --git a/system/ui/sunnypilot/widgets/progress_bar.py b/openpilot/system/ui/sunnypilot/widgets/progress_bar.py similarity index 100% rename from system/ui/sunnypilot/widgets/progress_bar.py rename to openpilot/system/ui/sunnypilot/widgets/progress_bar.py diff --git a/system/ui/sunnypilot/widgets/sunnylink_pairing_dialog.py b/openpilot/system/ui/sunnypilot/widgets/sunnylink_pairing_dialog.py similarity index 100% rename from system/ui/sunnypilot/widgets/sunnylink_pairing_dialog.py rename to openpilot/system/ui/sunnypilot/widgets/sunnylink_pairing_dialog.py diff --git a/system/ui/sunnypilot/widgets/toggle.py b/openpilot/system/ui/sunnypilot/widgets/toggle.py similarity index 100% rename from system/ui/sunnypilot/widgets/toggle.py rename to openpilot/system/ui/sunnypilot/widgets/toggle.py diff --git a/system/ui/sunnypilot/widgets/tree_dialog.py b/openpilot/system/ui/sunnypilot/widgets/tree_dialog.py similarity index 100% rename from system/ui/sunnypilot/widgets/tree_dialog.py rename to openpilot/system/ui/sunnypilot/widgets/tree_dialog.py diff --git a/third_party/copyparty/copyparty-sfx.py b/openpilot/third_party/copyparty/copyparty-sfx.py similarity index 100% rename from third_party/copyparty/copyparty-sfx.py rename to openpilot/third_party/copyparty/copyparty-sfx.py diff --git a/third_party/mapd_pfeiferj/README.md b/openpilot/third_party/mapd_pfeiferj/README.md similarity index 100% rename from third_party/mapd_pfeiferj/README.md rename to openpilot/third_party/mapd_pfeiferj/README.md diff --git a/third_party/mapd_pfeiferj/mapd b/openpilot/third_party/mapd_pfeiferj/mapd similarity index 100% rename from third_party/mapd_pfeiferj/mapd rename to openpilot/third_party/mapd_pfeiferj/mapd diff --git a/panda b/panda index d994e8e800..61b050f1bd 160000 --- a/panda +++ b/panda @@ -1 +1 @@ -Subproject commit d994e8e8009d934a94c3a94c863b559118353bdd +Subproject commit 61b050f1bd36fad04d4ceccca8a72c92ee1422df diff --git a/release/ci/publish.sh b/release/ci/publish.sh index 315ae22bfe..27904caf5d 100755 --- a/release/ci/publish.sh +++ b/release/ci/publish.sh @@ -30,7 +30,7 @@ if [ -z "$GIT_ORIGIN" ]; then fi # "Tagging" -echo "#define SUNNYPILOT_VERSION \"$VERSION\"" > ${OUTPUT_DIR}/sunnypilot/common/version.h +echo "#define SUNNYPILOT_VERSION \"$VERSION\"" > ${OUTPUT_DIR}/openpilot/sunnypilot/common/version.h ## set git identity #source $DIR/identity.sh @@ -55,7 +55,7 @@ git add -f . # include source commit hash and build date in commit GIT_HASH=$(git --git-dir=$SOURCE_DIR/.git rev-parse HEAD) DATETIME=$(date '+%Y-%m-%dT%H:%M:%S') -SP_VERSION=$(awk -F\" '{print $2}' $SOURCE_DIR/sunnypilot/common/version.h) +SP_VERSION=$(awk -F\" '{print $2}' $SOURCE_DIR/openpilot/sunnypilot/common/version.h) # Commit with detailed message git commit -a -m "sunnypilot v$VERSION diff --git a/scripts/lint/lint.sh b/scripts/lint/lint.sh index 920cdd2c77..024a743912 100755 --- a/scripts/lint/lint.sh +++ b/scripts/lint/lint.sh @@ -102,7 +102,8 @@ done RUN=$([ -z "$RUN" ] && echo "" || echo "!($(echo $RUN | sed 's/ /|/g'))") SKIP="@($(echo $SKIP | sed 's/ /|/g'))" -GIT_FILES="$(git ls-files openpilot)" +IGNORED_DIRS="^openpilot/third_party/.*" +GIT_FILES="$(git ls-files openpilot | grep -vE "$IGNORED_DIRS")" ALL_FILES="" for f in $GIT_FILES; do if [[ -f $f ]]; then diff --git a/sunnypilot/selfdrive/car/car_list.json b/sunnypilot/selfdrive/car/car_list.json deleted file mode 120000 index a4ae7b75f9..0000000000 --- a/sunnypilot/selfdrive/car/car_list.json +++ /dev/null @@ -1 +0,0 @@ -../../../opendbc_repo/opendbc/sunnypilot/car/car_list.json \ No newline at end of file diff --git a/system/manager/process_config.py b/system/manager/process_config.py deleted file mode 100644 index 510395b93b..0000000000 --- a/system/manager/process_config.py +++ /dev/null @@ -1,209 +0,0 @@ -import os -import operator -import platform - -from cereal import car, custom -from openpilot.common.params import Params -from openpilot.common.hardware import PC, TICI -from openpilot.system.manager.process import PythonProcess, NativeProcess, DaemonProcess -from openpilot.common.hardware.hw import Paths - -from openpilot.sunnypilot.mapd.mapd_manager import MAPD_PATH - -from openpilot.sunnypilot.models.helpers import get_active_model_runner -from openpilot.sunnypilot.sunnylink.utils import sunnylink_need_register, sunnylink_ready, use_sunnylink_uploader - -WEBCAM = os.getenv("USE_WEBCAM") is not None - -def driverview(started: bool, params: Params, CP: car.CarParams) -> bool: - return started or params.get_bool("IsDriverViewEnabled") - -def notcar(started: bool, params: Params, CP: car.CarParams) -> bool: - return started and CP.notCar - -def iscar(started: bool, params: Params, CP: car.CarParams) -> bool: - return started and not CP.notCar - -def logging(started: bool, params: Params, CP: car.CarParams) -> bool: - run = (not CP.notCar) or not params.get_bool("DisableLogging") - return started and run - -def ublox_available() -> bool: - return os.path.exists('/dev/ttyHS0') and not os.path.exists('/persist/comma/use-quectel-gps') - -def ublox(started: bool, params: Params, CP: car.CarParams) -> bool: - use_ublox = ublox_available() - if use_ublox != params.get_bool("UbloxAvailable"): - params.put_bool("UbloxAvailable", use_ublox, block=True) - return started and use_ublox - -def joystick(started: bool, params: Params, CP: car.CarParams) -> bool: - return started and params.get_bool("JoystickDebugMode") - -def not_joystick(started: bool, params: Params, CP: car.CarParams) -> bool: - return started and not params.get_bool("JoystickDebugMode") - -def long_maneuver(started: bool, params: Params, CP: car.CarParams) -> bool: - return started and params.get_bool("LongitudinalManeuverMode") - -def lat_maneuver(started: bool, params: Params, CP: car.CarParams) -> bool: - return started and params.get_bool("LateralManeuverMode") - -def not_long_maneuver(started: bool, params: Params, CP: car.CarParams) -> bool: - return started and not params.get_bool("LongitudinalManeuverMode") - -def qcomgps(started: bool, params: Params, CP: car.CarParams) -> bool: - return started and not ublox_available() - -def always_run(started: bool, params: Params, CP: car.CarParams) -> bool: - return True - -def only_onroad(started: bool, params: Params, CP: car.CarParams) -> bool: - return started - -def only_offroad(started: bool, params: Params, CP: car.CarParams) -> bool: - return not started - -def livestream(started: bool, params: Params, CP: car.CarParams) -> bool: - return params.get_bool("IsLiveStreaming") - -def use_github_runner(started, params, CP: car.CarParams) -> bool: - return not PC and params.get_bool("EnableGithubRunner") and ( - not params.get_bool("NetworkMetered") and not params.get_bool("GithubRunnerSufficientVoltage")) - -def use_copyparty(started, params, CP: car.CarParams) -> bool: - return bool(params.get_bool("EnableCopyparty")) - -def sunnylink_ready_shim(started, params, CP: car.CarParams) -> bool: - """Shim for sunnylink_ready to match the process manager signature.""" - return sunnylink_ready(params) - -def sunnylink_need_register_shim(started, params, CP: car.CarParams) -> bool: - """Shim for sunnylink_need_register to match the process manager signature.""" - return sunnylink_need_register(params) - -def use_sunnylink_uploader_shim(started, params, CP: car.CarParams) -> bool: - """Shim for use_sunnylink_uploader to match the process manager signature.""" - return use_sunnylink_uploader(params) - -def is_tinygrad_model(started, params, CP: car.CarParams) -> bool: - """Check if the active model runner is SNPE.""" - return bool(get_active_model_runner(params, not started) == custom.ModelManagerSP.Runner.tinygrad) - -def is_stock_model(started, params, CP: car.CarParams) -> bool: - """Check if the active model runner is stock.""" - return bool(get_active_model_runner(params, not started) == custom.ModelManagerSP.Runner.stock) - -def mapd_ready(started: bool, params: Params, CP: car.CarParams) -> bool: - return bool(os.path.exists(Paths.mapd_root())) - -def uploader_ready(started: bool, params: Params, CP: car.CarParams) -> bool: - if not params.get_bool("OnroadUploads"): - return only_offroad(started, params, CP) - - return always_run(started, params, CP) - -def or_(*fns): - return lambda *args: operator.or_(*(fn(*args) for fn in fns)) - -def and_(*fns): - return lambda *args: operator.and_(*(fn(*args) for fn in fns)) - -def not_(*fns): - return lambda *args: operator.not_(*(fn(*args) for fn in fns)) - -procs = [ - DaemonProcess("manage_athenad", "system.athena.manage_athenad", "AthenadPid"), - - NativeProcess("loggerd", "system/loggerd", ["./loggerd"], logging), - NativeProcess("encoderd", "system/loggerd", ["./encoderd"], only_onroad), - NativeProcess("stream_encoderd", "system/loggerd", ["./encoderd", "--stream"], or_(and_(livestream, not_(iscar)), notcar)), - PythonProcess("logmessaged", "system.logmessaged", always_run), - - NativeProcess("camerad", "system/camerad", ["./camerad"], or_(driverview, livestream), enabled=not WEBCAM), - PythonProcess("webcamerad", "system.camerad.webcam.camerad", driverview, enabled=WEBCAM), - PythonProcess("proclogd", "system.proclogd", only_onroad, enabled=platform.system() != "Darwin"), - PythonProcess("journald", "system.journald", only_onroad, platform.system() != "Darwin"), - PythonProcess("micd", "system.micd", iscar), - PythonProcess("timed", "system.timed", always_run, enabled=not PC), - - PythonProcess("modeld", "selfdrive.modeld.modeld", and_(only_onroad, is_stock_model)), - PythonProcess("dmonitoringmodeld", "selfdrive.modeld.dmonitoringmodeld", driverview, enabled=(WEBCAM or not PC)), - - PythonProcess("sensord", "system.sensord.sensord", only_onroad, enabled=not PC), - PythonProcess("ui", "selfdrive.ui.ui", always_run, restart_if_crash=True), - PythonProcess("soundd", "selfdrive.ui.soundd", driverview), - PythonProcess("locationd", "selfdrive.locationd.locationd", only_onroad), - NativeProcess("_pandad", "selfdrive/pandad", ["./pandad"], always_run, enabled=False), - PythonProcess("calibrationd", "selfdrive.locationd.calibrationd", only_onroad), - PythonProcess("torqued", "selfdrive.locationd.torqued", only_onroad), - PythonProcess("controlsd", "selfdrive.controls.controlsd", and_(not_joystick, iscar)), - PythonProcess("joystickd", "tools.joystick.joystickd", or_(joystick, notcar)), - PythonProcess("selfdrived", "selfdrive.selfdrived.selfdrived", only_onroad), - PythonProcess("card", "selfdrive.car.card", only_onroad), - PythonProcess("deleter", "system.loggerd.deleter", always_run), - PythonProcess("dmonitoringd", "selfdrive.monitoring.dmonitoringd", driverview, enabled=(WEBCAM or not PC)), - PythonProcess("qcomgpsd", "system.qcomgpsd.qcomgpsd", qcomgps, enabled=TICI), - PythonProcess("pandad", "selfdrive.pandad.pandad", always_run), - PythonProcess("paramsd", "selfdrive.locationd.paramsd", only_onroad), - PythonProcess("lagd", "selfdrive.locationd.lagd", only_onroad), - PythonProcess("ubloxd", "system.ubloxd.ubloxd", ublox, enabled=TICI), - PythonProcess("pigeond", "system.ubloxd.pigeond", ublox, enabled=TICI), - PythonProcess("plannerd", "selfdrive.controls.plannerd", not_long_maneuver), - PythonProcess("maneuversd", "tools.longitudinal_maneuvers.maneuversd", long_maneuver), - PythonProcess("lateral_maneuversd", "tools.lateral_maneuvers.lateral_maneuversd", lat_maneuver), - PythonProcess("radard", "selfdrive.controls.radard", only_onroad), - PythonProcess("hardwared", "system.hardware.hardwared", always_run), - PythonProcess("modem", "common.hardware.tici.modem", always_run, enabled=TICI), - PythonProcess("tombstoned", "system.tombstoned", always_run, enabled=not PC), - PythonProcess("updated", "system.updated.updated", only_offroad, enabled=not PC), - PythonProcess("uploader", "system.loggerd.uploader", uploader_ready), - PythonProcess("statsd", "system.statsd", always_run), - PythonProcess("feedbackd", "selfdrive.ui.feedback.feedbackd", only_onroad), - - # debug procs - NativeProcess("bridge", "cereal/messaging", ["./bridge"], notcar), - PythonProcess("webrtcd", "system.webrtc.webrtcd", or_(and_(livestream, not_(iscar)), notcar)), - PythonProcess("joystick", "tools.joystick.joystick_control", and_(joystick, iscar)), - - # sunnylink <3 - DaemonProcess("manage_sunnylinkd", "sunnypilot.sunnylink.athena.manage_sunnylinkd", "SunnylinkdPid"), - PythonProcess("sunnylink_registration_manager", "sunnypilot.sunnylink.registration_manager", sunnylink_need_register_shim), - PythonProcess("statsd_sp", "sunnypilot.sunnylink.statsd", and_(always_run, sunnylink_ready_shim)), -] - -# sunnypilot -procs += [ - # Models - PythonProcess("models_manager", "sunnypilot.models.manager", only_offroad), - NativeProcess("modeld_tinygrad", "sunnypilot/modeld_v2", ["./modeld"], and_(only_onroad, is_tinygrad_model)), - - # Backup - PythonProcess("backup_manager", "sunnypilot.sunnylink.backups.manager", and_(only_offroad, sunnylink_ready_shim)), - - # mapd - NativeProcess("mapd", Paths.mapd_root(), ["bash", "-c", f"{MAPD_PATH} > /dev/null 2>&1"], mapd_ready), - PythonProcess("mapd_manager", "sunnypilot.mapd.mapd_manager", always_run), - - # locationd - NativeProcess("locationd_llk", "sunnypilot/selfdrive/locationd", ["./locationd"], only_onroad), -] - -if os.path.exists("./github_runner.sh"): - procs += [NativeProcess("github_runner_start", "system/manager", ["./github_runner.sh", "start"], and_(only_offroad, use_github_runner), sigkill=False)] - -if os.path.exists("../../sunnypilot/sunnylink/uploader.py"): - procs += [PythonProcess("sunnylink_uploader", "sunnypilot.sunnylink.uploader", use_sunnylink_uploader_shim)] - -if os.path.exists("../../third_party/copyparty/copyparty-sfx.py"): - sunnypilot_root = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..")) - copyparty_args = [f"-v{Paths.crash_log_root()}:/swaglogs:r"] - copyparty_args += [f"-v{Paths.log_root()}:/routes:r"] - copyparty_args += [f"-v{Paths.model_root()}:/models:rw"] - copyparty_args += [f"-v{sunnypilot_root}:/sunnypilot:rw"] - copyparty_args += ["-p8080"] - copyparty_args += ["-z"] - copyparty_args += ["-q"] - procs += [NativeProcess("copyparty-sfx", "third_party/copyparty", ["./copyparty-sfx.py", *copyparty_args], and_(only_offroad, use_copyparty))] - -managed_processes = {p.name: p for p in procs} diff --git a/uv.lock b/uv.lock index 2284243b55..d9adb09f0b 100644 --- a/uv.lock +++ b/uv.lock @@ -1032,7 +1032,6 @@ dependencies = [ { name = "libusb-package" }, { name = "libusb1" }, { name = "opendbc" }, - { name = "spidev", marker = "sys_platform == 'linux'" }, ] [package.metadata] @@ -1043,7 +1042,7 @@ requires-dist = [ { name = "gcc-arm-none-eabi", marker = "extra == 'dev'", git = "https://github.com/commaai/dependencies.git?subdirectory=gcc-arm-none-eabi&rev=release-gcc-arm-none-eabi" }, { name = "libusb-package" }, { name = "libusb1" }, - { name = "opendbc", git = "https://github.com/commaai/opendbc.git?rev=master" }, + { name = "opendbc", git = "https://github.com/sunnypilot/opendbc.git?rev=master" }, { name = "pycryptodome", marker = "extra == 'dev'", specifier = ">=3.9.8" }, { name = "pytest", marker = "extra == 'dev'" }, { name = "pytest-mock", marker = "extra == 'dev'" }, @@ -1052,7 +1051,6 @@ requires-dist = [ { name = "ruff", marker = "extra == 'dev'" }, { name = "scons", marker = "extra == 'dev'" }, { name = "setuptools", marker = "extra == 'dev'" }, - { name = "spidev", marker = "sys_platform == 'linux'" }, ] provides-extras = ["dev"] @@ -1310,7 +1308,7 @@ wheels = [ [[package]] name = "pytest-xdist" -version = "3.7.1.dev24+g2b4372bd6" +version = "3.7.1.dev24+g2b4372b" source = { git = "https://github.com/sshane/pytest-xdist?rev=2b4372bd62699fb412c4fe2f95bf9f01bd2018da#2b4372bd62699fb412c4fe2f95bf9f01bd2018da" } dependencies = [ { name = "execnet" }, @@ -1541,12 +1539,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/4e/39/a61d4b83a7746b70d23d9173be688c0c6bfc7173772344b7442c2c155497/sounddevice-0.5.5-py3-none-win_arm64.whl", hash = "sha256:3861901ddd8230d2e0e8ae62ac320cdd4c688d81df89da036dcb812f757bb3e6", size = 317115, upload-time = "2026-01-23T18:36:42.235Z" }, ] -[[package]] -name = "spidev" -version = "3.8" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/67/87/039b6eeea781598015b538691bc174cc0bf77df9d4d2d3b8bf9245c0de8c/spidev-3.8.tar.gz", hash = "sha256:2bc02fb8c6312d519ebf1f4331067427c0921d3f77b8bcaf05189a2e8b8382c0", size = 13893, upload-time = "2025-09-15T18:56:20.672Z" } - [[package]] name = "sympy" version = "1.14.0" @@ -1586,7 +1578,7 @@ provides-extras = ["dev"] [[package]] name = "tinygrad" -version = "0.13.0" +version = "0.12.0" source = { editable = "tinygrad_repo" } [package.metadata] @@ -1633,7 +1625,6 @@ requires-dist = [ { name = "tiktoken", marker = "extra == 'testing'" }, { name = "tinygrad", extras = ["testing-minimal"], marker = "extra == 'testing-unit'" }, { name = "tinygrad", extras = ["testing-unit"], marker = "extra == 'testing'" }, - { name = "tinymesa", marker = "extra == 'mesa'", specifier = "==25.2.7.2" }, { name = "torch", marker = "extra == 'testing-minimal'", specifier = "==2.9.1" }, { name = "tqdm", marker = "extra == 'testing-unit'" }, { name = "transformers", marker = "extra == 'testing'" }, @@ -1641,7 +1632,7 @@ requires-dist = [ { name = "typing-extensions", marker = "extra == 'linting'" }, { name = "z3-solver", marker = "extra == 'testing-minimal'", specifier = "<4.15.4" }, ] -provides-extras = ["linting", "testing-minimal", "testing-unit", "testing", "docs", "mesa"] +provides-extras = ["linting", "testing-minimal", "testing-unit", "testing", "docs"] [[package]] name = "tomli" From bf1b93f757065fe687a536a0aaeeec35ebcfc197 Mon Sep 17 00:00:00 2001 From: Jason Wen Date: Mon, 20 Jul 2026 09:25:49 -0400 Subject: [PATCH 151/151] Revert "agnos: split launch for c3 and c3x to support custom agnos" (#1879) Revert "agnos: split launch for c3 and c3x to support custom agnos (#1186)" This reverts commit 54174d1e --- launch_openpilot.sh | 17 --- .../sunnypilot/system/hardware/c3/README.md | 3 - .../sunnypilot/system/hardware/c3/agnos.json | 84 --------------- .../system/hardware/c3/launch_chffrplus.sh | 100 ------------------ .../system/hardware/c3/launch_env.sh | 13 --- 5 files changed, 217 deletions(-) delete mode 100644 openpilot/sunnypilot/system/hardware/c3/README.md delete mode 100644 openpilot/sunnypilot/system/hardware/c3/agnos.json delete mode 100755 openpilot/sunnypilot/system/hardware/c3/launch_chffrplus.sh delete mode 100755 openpilot/sunnypilot/system/hardware/c3/launch_env.sh diff --git a/launch_openpilot.sh b/launch_openpilot.sh index 0b3550aba8..d6e3424c34 100755 --- a/launch_openpilot.sh +++ b/launch_openpilot.sh @@ -1,20 +1,3 @@ #!/usr/bin/env bash -set -euo pipefail -IFS=$'\n\t' - -# On any failure, run the fallback launcher -trap 'exec ./launch_chffrplus.sh' ERR -C3_LAUNCH_SH="./openpilot/sunnypilot/system/hardware/c3/launch_chffrplus.sh" - -MODEL="$(tr -d '\0' < "/sys/firmware/devicetree/base/model")" -export MODEL - -if [ "$MODEL" = "comma tici" ]; then - # Force a failure if the launcher doesn't exist - [ -x "$C3_LAUNCH_SH" ] || false - - # If it exists, run it - exec "$C3_LAUNCH_SH" -fi exec ./launch_chffrplus.sh diff --git a/openpilot/sunnypilot/system/hardware/c3/README.md b/openpilot/sunnypilot/system/hardware/c3/README.md deleted file mode 100644 index f74a210191..0000000000 --- a/openpilot/sunnypilot/system/hardware/c3/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# C3 specific hardware code - -`c3` is known as `tici` and comma three by comma. Not to confuse it with `c3x` which is known as `tizi`. \ No newline at end of file diff --git a/openpilot/sunnypilot/system/hardware/c3/agnos.json b/openpilot/sunnypilot/system/hardware/c3/agnos.json deleted file mode 100644 index 941a4956bf..0000000000 --- a/openpilot/sunnypilot/system/hardware/c3/agnos.json +++ /dev/null @@ -1,84 +0,0 @@ -[ - { - "name": "xbl", - "url": "https://commadist.azureedge.net/agnosupdate/xbl-effa23294138e2297b85a5b482a885184c437b5ab25d74f2a62d4fce4e68f63b.img.xz", - "hash": "effa23294138e2297b85a5b482a885184c437b5ab25d74f2a62d4fce4e68f63b", - "hash_raw": "effa23294138e2297b85a5b482a885184c437b5ab25d74f2a62d4fce4e68f63b", - "size": 3282256, - "sparse": false, - "full_check": true, - "has_ab": true, - "ondevice_hash": "ed61a650bea0c56652dd0fc68465d8fc722a4e6489dc8f257630c42c6adcdc89" - }, - { - "name": "xbl_config", - "url": "https://commadist.azureedge.net/agnosupdate/xbl_config-63d019efed684601f145ef37628e62c8da73f5053a8e51d7de09e72b8b11f97c.img.xz", - "hash": "63d019efed684601f145ef37628e62c8da73f5053a8e51d7de09e72b8b11f97c", - "hash_raw": "63d019efed684601f145ef37628e62c8da73f5053a8e51d7de09e72b8b11f97c", - "size": 98124, - "sparse": false, - "full_check": true, - "has_ab": true, - "ondevice_hash": "b12801ffaa81e58e3cef914488d3b447e35483ba549b28c6cd9deb4814c3265f" - }, - { - "name": "abl", - "url": "https://commadist.azureedge.net/agnosupdate/abl-32a2174b5f764e95dfc54cf358ba01752943b1b3b90e626149c3da7d5f1830b6.img.xz", - "hash": "32a2174b5f764e95dfc54cf358ba01752943b1b3b90e626149c3da7d5f1830b6", - "hash_raw": "32a2174b5f764e95dfc54cf358ba01752943b1b3b90e626149c3da7d5f1830b6", - "size": 274432, - "sparse": false, - "full_check": true, - "has_ab": true, - "ondevice_hash": "32a2174b5f764e95dfc54cf358ba01752943b1b3b90e626149c3da7d5f1830b6" - }, - { - "name": "aop", - "url": "https://commadist.azureedge.net/agnosupdate/aop-21370172e590bd4ea907a558bcd6df20dc7a6c7d38b8e62fdde18f4a512ba9e9.img.xz", - "hash": "21370172e590bd4ea907a558bcd6df20dc7a6c7d38b8e62fdde18f4a512ba9e9", - "hash_raw": "21370172e590bd4ea907a558bcd6df20dc7a6c7d38b8e62fdde18f4a512ba9e9", - "size": 184364, - "sparse": false, - "full_check": true, - "has_ab": true, - "ondevice_hash": "c1be2f4aac5b3af49b904b027faec418d05efd7bd5144eb4fdfcba602bcf2180" - }, - { - "name": "devcfg", - "url": "https://commadist.azureedge.net/agnosupdate/devcfg-d7d7e52963bbedbbf8a7e66847579ca106a0a729ce2cf60f4b8d8ea4b535d620.img.xz", - "hash": "d7d7e52963bbedbbf8a7e66847579ca106a0a729ce2cf60f4b8d8ea4b535d620", - "hash_raw": "d7d7e52963bbedbbf8a7e66847579ca106a0a729ce2cf60f4b8d8ea4b535d620", - "size": 40336, - "sparse": false, - "full_check": true, - "has_ab": true, - "ondevice_hash": "17b229668b20305ff8fa3cd5f94716a3aaa1e5bf9d1c24117eff7f2f81ae719f" - }, - { - "name": "boot", - "url": "https://commadist.azureedge.net/agnosupdate/boot-0191529aa97d90d1fa04b472d80230b777606459e1e1e9e2323c9519839827b4.img.xz", - "hash": "0191529aa97d90d1fa04b472d80230b777606459e1e1e9e2323c9519839827b4", - "hash_raw": "0191529aa97d90d1fa04b472d80230b777606459e1e1e9e2323c9519839827b4", - "size": 18515968, - "sparse": false, - "full_check": true, - "has_ab": true, - "ondevice_hash": "492ae27f569e8db457c79d0e358a7a6297d1a1c685c2b1ae6deba7315d3a6cb0" - }, - { - "name": "system", - "url": "https://commadist.azureedge.net/agnosupdate/system-e0007afa5d1026671c1943d44bb7f7ad26259f673392dd00a03073a2870df087.img.xz", - "hash": "1468d50b7ad0fda0f04074755d21e786e3b1b6ca5dd5b17eb2608202025e6126", - "hash_raw": "e0007afa5d1026671c1943d44bb7f7ad26259f673392dd00a03073a2870df087", - "size": 5368709120, - "sparse": true, - "full_check": false, - "has_ab": true, - "ondevice_hash": "242aa5adad1c04e1398e00e2440d1babf962022eb12b89adf2e60ee3068946e7", - "alt": { - "hash": "e0007afa5d1026671c1943d44bb7f7ad26259f673392dd00a03073a2870df087", - "url": "https://commadist.azureedge.net/agnosupdate/system-e0007afa5d1026671c1943d44bb7f7ad26259f673392dd00a03073a2870df087.img", - "size": 5368709120 - } - } -] \ No newline at end of file diff --git a/openpilot/sunnypilot/system/hardware/c3/launch_chffrplus.sh b/openpilot/sunnypilot/system/hardware/c3/launch_chffrplus.sh deleted file mode 100755 index a505e4f1f1..0000000000 --- a/openpilot/sunnypilot/system/hardware/c3/launch_chffrplus.sh +++ /dev/null @@ -1,100 +0,0 @@ -#!/usr/bin/env bash - -SP_C3_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" -DIR="$( cd "$SP_C3_DIR/../../../../.." >/dev/null 2>&1 && pwd )" - -source "$SP_C3_DIR/launch_env.sh" - -function agnos_init { - # TODO: move this to agnos - sudo rm -f /data/etc/NetworkManager/system-connections/*.nmmeta - - # set success flag for current boot slot - sudo abctl --set_success - - # TODO: do this without udev in AGNOS - # udev does this, but sometimes we startup faster - sudo chgrp gpu /dev/adsprpc-smd /dev/ion /dev/kgsl-3d0 - sudo chmod 660 /dev/adsprpc-smd /dev/ion /dev/kgsl-3d0 - - - if [ $(< /VERSION) != "$AGNOS_VERSION" ]; then - AGNOS_PY="$DIR/openpilot/common/hardware/tici/agnos.py" - MANIFEST="$SP_C3_DIR/agnos.json" - if $AGNOS_PY --verify $MANIFEST; then - sudo reboot - fi - $DIR/openpilot/common/hardware/tici/updater $AGNOS_PY $MANIFEST - fi -} - -function launch { - # Remove orphaned git lock if it exists on boot - [ -f "$DIR/.git/index.lock" ] && rm -f $DIR/.git/index.lock - - # Check to see if there's a valid overlay-based update available. Conditions - # are as follows: - # - # 1. The DIR init file has to exist, with a newer modtime than anything in - # the DIR Git repo. This checks for local development work or the user - # switching branches/forks, which should not be overwritten. - # 2. The FINALIZED consistent file has to exist, indicating there's an update - # that completed successfully and synced to disk. - - if [ -f "${DIR}/.overlay_init" ]; then - find ${DIR}/.git -newer ${DIR}/.overlay_init | grep -q '.' 2> /dev/null - if [ $? -eq 0 ]; then - echo "${DIR} has been modified, skipping overlay update installation" - else - if [ -f "${STAGING_ROOT}/finalized/.overlay_consistent" ]; then - if [ ! -d /data/safe_staging/old_openpilot ]; then - echo "Valid overlay update found, installing" - LAUNCHER_LOCATION="${BASH_SOURCE[0]}" - - mv $DIR /data/safe_staging/old_openpilot - mv "${STAGING_ROOT}/finalized" $DIR - cd $DIR - - echo "Restarting launch script ${LAUNCHER_LOCATION}" - unset AGNOS_VERSION - exec "${LAUNCHER_LOCATION}" - else - echo "openpilot backup found, not updating" - # TODO: restore backup? This means the updater didn't start after swapping - fi - fi - fi - fi - - # handle pythonpath - ln -sfn $(pwd) /data/pythonpath - export PYTHONPATH="$PWD" - - # submodule package symlinks for PYTHONPATH imports on device. - # on PC these come from editable installs via pyproject.toml / uv. - ln -sfn msgq_repo/msgq msgq - ln -sfn opendbc_repo/opendbc opendbc - ln -sfn rednose_repo/rednose rednose - ln -sfn teleoprtc_repo/teleoprtc teleoprtc - ln -sfn tinygrad_repo/tinygrad tinygrad - - # hardware specific init - if [ -f /AGNOS ]; then - agnos_init - fi - - # write tmux scrollback to a file - tmux capture-pane -pq -S-1000 > /tmp/launch_log - - # start manager - cd $DIR/openpilot/system/manager - if [ ! -f $DIR/prebuilt ]; then - ./build.py - fi - ./manager.py - - # if broken, keep on screen error - while true; do sleep 1; done -} - -launch diff --git a/openpilot/sunnypilot/system/hardware/c3/launch_env.sh b/openpilot/sunnypilot/system/hardware/c3/launch_env.sh deleted file mode 100755 index 4c011c6ac0..0000000000 --- a/openpilot/sunnypilot/system/hardware/c3/launch_env.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/env bash - -export OMP_NUM_THREADS=1 -export MKL_NUM_THREADS=1 -export NUMEXPR_NUM_THREADS=1 -export OPENBLAS_NUM_THREADS=1 -export VECLIB_MAXIMUM_THREADS=1 - -if [ -z "$AGNOS_VERSION" ]; then - export AGNOS_VERSION="12.8" -fi - -export STAGING_ROOT="/data/safe_staging"