diff --git a/openpilot/common/file_chunker.py b/openpilot/common/file_chunker.py index 2d080c3fff..3baa618fb1 100755 --- a/openpilot/common/file_chunker.py +++ b/openpilot/common/file_chunker.py @@ -40,9 +40,13 @@ def get_existing_chunks(path): raise FileNotFoundError(path) class ChunkStream(io.RawIOBase): - def __init__(self, paths): + def __init__(self, paths, total=0, progress_cb=None): self._paths = iter(paths) self._f = None + self._total = total + self._progress_cb = progress_cb + self._read = 0 + self._last_pct = -1 def readable(self): return True @@ -62,9 +66,15 @@ class ChunkStream(io.RawIOBase): self._f = None continue n += count + self._read += n + if self._progress_cb and self._total: + pct = min(100, self._read * 100 // self._total) + if pct != self._last_pct: + self._last_pct = pct + self._progress_cb(pct) return n -def open_file_chunked(path): +def open_file_chunked(path, progress_cb=None): manifest_path = get_manifest_path(path) if os.path.isfile(manifest_path): num_chunks = int(Path(manifest_path).read_text().strip()) @@ -73,7 +83,8 @@ def open_file_chunked(path): paths = [path] else: raise FileNotFoundError(path) - return io.BufferedReader(ChunkStream(paths)) + total = sum(os.path.getsize(p) for p in paths) + return io.BufferedReader(ChunkStream(paths, total, progress_cb)) if __name__ == "__main__": diff --git a/openpilot/common/params_keys.h b/openpilot/common/params_keys.h index be4a4dc4a2..4a29e58555 100644 --- a/openpilot/common/params_keys.h +++ b/openpilot/common/params_keys.h @@ -132,6 +132,7 @@ inline static std::unordered_map keys = { {"UptimeOnroad", {PERSISTENT, FLOAT, "0.0"}}, {"UsbGpuActive", {CLEAR_ON_MANAGER_START | CLEAR_ON_OFFROAD_TRANSITION | CLEAR_ON_IGNITION_ON, BOOL}}, {"UsbGpuLoading", {CLEAR_ON_MANAGER_START | CLEAR_ON_OFFROAD_TRANSITION | CLEAR_ON_IGNITION_ON, BOOL}}, + {"UsbGpuLoadProgress", {CLEAR_ON_MANAGER_START | CLEAR_ON_OFFROAD_TRANSITION | CLEAR_ON_IGNITION_ON, INT, "0"}}, {"Version", {PERSISTENT, STRING}}, // --- sunnypilot params --- // diff --git a/openpilot/selfdrive/ui/mici/onroad/hud_renderer.py b/openpilot/selfdrive/ui/mici/onroad/hud_renderer.py index 26b43370c7..495f6e1e0c 100644 --- a/openpilot/selfdrive/ui/mici/onroad/hud_renderer.py +++ b/openpilot/selfdrive/ui/mici/onroad/hud_renderer.py @@ -232,6 +232,13 @@ class HudRenderer(Widget): rect.y + rect.height - 14 - (self._txt_wheel.height + icon.height) / 2) rl.draw_texture_ex(icon, pos, 0.0, 1.0, rl.Color(255, 255, 255, int(255 * opacity * alpha))) + if loading: + pct_text = f"{ui_state.usbgpu_load_progress}%" + pct_size = measure_text_cached(self._font_bold, pct_text, FONT_SIZES.max_speed) + pct_pos = rl.Vector2(pos.x - 8 - pct_size.x, pos.y + (icon.height - pct_size.y) / 2) + rl.draw_text_ex(self._font_bold, pct_text, pct_pos, FONT_SIZES.max_speed, 0, + rl.Color(255, 255, 255, int(255 * opacity * alpha))) + def _draw_steering_wheel(self, rect: rl.Rectangle) -> None: wheel_txt = self._txt_wheel_critical if self._show_wheel_critical else self._txt_wheel diff --git a/openpilot/selfdrive/ui/ui_state.py b/openpilot/selfdrive/ui/ui_state.py index e0aca74ff2..12732aeab5 100644 --- a/openpilot/selfdrive/ui/ui_state.py +++ b/openpilot/selfdrive/ui/ui_state.py @@ -86,6 +86,7 @@ class UIState(UIStateSP): self.usbgpu_compiled: bool = usbgpu_compiled() self.usbgpu_active: bool | None = self.params.get("UsbGpuActive") self.usbgpu_loading: bool = self.params.get_bool("UsbGpuLoading") + self.usbgpu_load_progress: int = self.params.get("UsbGpuLoadProgress", return_default=True) self.started: bool = False self.ignition: bool = False self.recording_audio: bool = False @@ -222,6 +223,7 @@ class UIState(UIStateSP): self.usbgpu_compiled = usbgpu_compiled() self.usbgpu_active = self.params.get("UsbGpuActive") self.usbgpu_loading = self.params.get_bool("UsbGpuLoading") + self.usbgpu_load_progress = self.params.get("UsbGpuLoadProgress", return_default=True) UIStateSP.update_params(self) diff --git a/openpilot/sunnypilot/modeld_v2/modeld.py b/openpilot/sunnypilot/modeld_v2/modeld.py index 9f3d709537..f31a25771d 100755 --- a/openpilot/sunnypilot/modeld_v2/modeld.py +++ b/openpilot/sunnypilot/modeld_v2/modeld.py @@ -107,7 +107,8 @@ class ModelState(ModelStateBase): def _init_combined(self, pkl_path, cam_w, cam_h, bundle): cloudlog.warning(f"loading combined pkl: {pkl_path}") - jits = load_oob(open_file_chunked(pkl_path)) + progress_cb = (lambda pct: Params().put("UsbGpuLoadProgress", pct)) if self.usbgpu else None + jits = load_oob(open_file_chunked(pkl_path, progress_cb)) self.WARP_DEV = 'QCOM' if COMMA_HARDWARE else 'CPU' self.DEV = 'AMD' if self.usbgpu else self.WARP_DEV @@ -333,6 +334,7 @@ def main(demo=False): params = Params() params.put_bool("UsbGpuLoading", USBGPU) + params.put("UsbGpuLoadProgress", 0) params.remove("UsbGpuActive") # visionipc clients