diff --git a/openpilot/selfdrive/modeld/models/driving_tinygrad.pkl.chunk01of02 b/openpilot/selfdrive/modeld/models/driving_tinygrad.pkl.chunk01of02 index 6782bba16..f5ff3d5d3 100644 Binary files a/openpilot/selfdrive/modeld/models/driving_tinygrad.pkl.chunk01of02 and b/openpilot/selfdrive/modeld/models/driving_tinygrad.pkl.chunk01of02 differ diff --git a/openpilot/selfdrive/modeld/models/driving_tinygrad.pkl.chunk02of02 b/openpilot/selfdrive/modeld/models/driving_tinygrad.pkl.chunk02of02 index 2959a0c45..0b17418f5 100644 Binary files a/openpilot/selfdrive/modeld/models/driving_tinygrad.pkl.chunk02of02 and b/openpilot/selfdrive/modeld/models/driving_tinygrad.pkl.chunk02of02 differ diff --git a/openpilot/sunnypilot/modeld_v2/modeld.py b/openpilot/sunnypilot/modeld_v2/modeld.py index 6584ee4c9..e9469478b 100755 --- a/openpilot/sunnypilot/modeld_v2/modeld.py +++ b/openpilot/sunnypilot/modeld_v2/modeld.py @@ -75,10 +75,18 @@ def _pkl_exists(path): return all(os.path.exists(get_chunk_name(path, i, num_chunks)) for i in range(num_chunks)) -def _find_driving_pkl(bundle): +def _find_driving_pkl(bundle, chestnut: bool = False): if (override := os.environ.get('COMBINED_MODEL_PKL')) and _pkl_exists(override): return override - if bundle is None or not bundle.models: + if bundle is None: + # no active bundle: use the bundled default pkl (CD210) so a fresh install + # works immediately without downloading a model + from openpilot.selfdrive.modeld.helpers import modeld_pkl_path + bundled = str(modeld_pkl_path(chestnut)) + if _pkl_exists(bundled): + return bundled + return None + if not bundle.models: return None from openpilot.common.hardware.hw import Paths model_root = Paths.model_root() @@ -121,7 +129,7 @@ class ModelState(ModelStateBase): self.PLANPLUS_CONTROL: float = 1.0 self.chestnut = chestnut - pkl_path = _find_driving_pkl(model_bundle) + pkl_path = _find_driving_pkl(model_bundle, chestnut=chestnut) assert pkl_path is not None, f"No driving pkl found for {'chestnut' if chestnut else 'small model'} — all models must be compiled with compile_modeld.py" self._init_combined(pkl_path, cam_w, cam_h, model_bundle) diff --git a/openpilot/sunnypilot/models/helpers.py b/openpilot/sunnypilot/models/helpers.py index a1a392c5e..842595cec 100644 --- a/openpilot/sunnypilot/models/helpers.py +++ b/openpilot/sunnypilot/models/helpers.py @@ -175,6 +175,24 @@ def validate_active_bundles(params: Params, source_bundles: dict[str, list[custo get_active_model_runner(params, force_check=True) +def _bundled_default_pkl_available() -> bool: + # the repo ships the default model (CD210) as driving_tinygrad.pkl chunks; only + # a real pkl or all chunk files count (a bare chunkmanifest does not) + from openpilot.common.file_chunker import get_chunk_name, get_manifest_path + from openpilot.selfdrive.modeld.helpers import modeld_pkl_path + path = str(modeld_pkl_path(chestnut=False)) + if os.path.exists(path): + return True + manifest_path = get_manifest_path(path) + if not os.path.exists(manifest_path): + return False + try: + num_chunks = int(open(manifest_path).read().strip()) + except Exception: + return False + return all(os.path.exists(get_chunk_name(path, i, num_chunks)) for i in range(num_chunks)) + + def get_active_model_runner(params: Params | None = None, force_check: bool = False) -> int: params = params or Params() cached_runner_type = params.get("ModelRunnerTypeCache") @@ -183,6 +201,10 @@ def get_active_model_runner(params: Params | None = None, force_check: bool = Fa runner_type = custom.ModelManagerSP.Runner.stock if active_bundle := get_active_bundle(params): runner_type = active_bundle.runner.raw + elif _bundled_default_pkl_available(): + # no bundle selected: modeld_v2 runs the bundled default pkl (CD210), so it + # must not fall back to stock modeld (which expects a run_model-format pkl) + runner_type = custom.ModelManagerSP.Runner.tinygrad if cached_runner_type != runner_type: params.put("ModelRunnerTypeCache", int(runner_type), block=True)