diff --git a/cereal/custom.capnp b/cereal/custom.capnp index b2575256d8..5007d06752 100644 --- a/cereal/custom.capnp +++ b/cereal/custom.capnp @@ -64,6 +64,11 @@ struct ModelManagerSP @0xaedffd8f31e7b55d { progress @1 :Float32; eta @2 :UInt32; } + + enum Runner { + snpe @0; + tinygrad @1; + } struct ModelBundle { index @0 :UInt32; diff --git a/sunnypilot/models/helpers.py b/sunnypilot/models/helpers.py index fe6ac2133c..71d93dff75 100644 --- a/sunnypilot/models/helpers.py +++ b/sunnypilot/models/helpers.py @@ -30,3 +30,21 @@ def get_active_bundle(params: Params) -> custom.ModelManagerSP.ModelBundle: return messaging.log_from_bytes(active_bundle, custom.ModelManagerSP.ModelBundle) return None + +def get_model_runner_by_filename(filename: str) -> custom.ModelManagerSP.Runner: + if filename.endswith(".thneed"): + return custom.ModelManagerSP.Runner.snpe + + if filename.endswith("_tinygrad.pkl"): + return custom.ModelManagerSP.Runner.tinygrad + +def get_active_model_runner(params: Params) -> custom.ModelManagerSP.Runner: + """Gets the model runner from the active model bundle. If no active bundle, returns tinygrad""" + if params is None: + params = Params() + + if active_bundle := get_active_bundle(params): + drive_model = next(model for model in active_bundle.models if model.type == custom.ModelManagerSP.Type.drive) + return get_model_runner_by_filename(drive_model.fileName) + + return custom.ModelManagerSP.Runner.tinygrad diff --git a/system/manager/process_config.py b/system/manager/process_config.py index 905a74e7c1..6530c752f1 100644 --- a/system/manager/process_config.py +++ b/system/manager/process_config.py @@ -1,10 +1,12 @@ import os import operator -from cereal import car +from cereal import car, custom from openpilot.common.params import Params from openpilot.system.hardware import PC, TICI from openpilot.system.manager.process import PythonProcess, NativeProcess, DaemonProcess + +from sunnypilot.models.helpers import get_active_model_runner from sunnypilot.sunnylink.utils import sunnylink_need_register, sunnylink_ready, use_sunnylink_uploader WEBCAM = os.getenv("USE_WEBCAM") is not None @@ -70,6 +72,11 @@ 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_snpe_model(started, params, CP: car.CarParams) -> bool: + """Check if the active model runner is SNPE.""" + # TODO-SP: I want to do a little more optimization here to only check this once when we've transitioned from offroad to onroad. + return get_active_model_runner(params) == custom.ModelManagerSP.Runner.snpe + def or_(*fns): return lambda *args: operator.or_(*(fn(*args) for fn in fns)) @@ -92,7 +99,7 @@ procs = [ NativeProcess("stream_encoderd", "system/loggerd", ["./encoderd", "--stream"], notcar), NativeProcess("loggerd", "system/loggerd", ["./loggerd"], logging), # TODO Make python process once TG allows opening QCOM from child proc - #NativeProcess("modeld", "selfdrive/modeld", ["./modeld"], only_onroad), + NativeProcess("modeld", "selfdrive/modeld", ["./modeld"], and_(only_onroad, not is_snpe_model)), NativeProcess("sensord", "system/sensord", ["./sensord"], only_onroad, enabled=not PC), NativeProcess("ui", "selfdrive/ui", ["./ui"], always_run, watchdog_max_dt=(5 if not PC else None)), PythonProcess("soundd", "selfdrive.ui.soundd", only_onroad), @@ -134,7 +141,7 @@ procs = [ # sunnypilot procs += [ PythonProcess("models_manager", "sunnypilot.models.manager", only_offroad), - NativeProcess("modeld", "sunnypilot/modeld", ["./modeld"], only_onroad), + NativeProcess("modeld", "sunnypilot/modeld", ["./modeld"], and_(only_onroad, is_snpe_model)), ] if os.path.exists("./github_runner.sh"):