diff --git a/launch_chffrplus.sh b/launch_chffrplus.sh index 6bea0c8ac8..2aeed7b5ac 100755 --- a/launch_chffrplus.sh +++ b/launch_chffrplus.sh @@ -133,101 +133,10 @@ function launch { while true; do sleep 1; done fi - function prebuilt_runtime_compatible { - python3 - <<'PY' -import importlib -import os -from pathlib import Path -import sys -import time - -from openpilot.common.file_chunker import get_existing_chunks - -start = time.monotonic() -last = start -log_path = os.environ.get("SP_BOOT_TIMING_LOG") - -def emit(line): - print(line, flush=True) - if log_path: - try: - with open(log_path, "a") as f: - f.write(line + "\n") - except OSError: - pass - -def log_step(label): - global last - now = time.monotonic() - emit(f"SP_BOOT_TIMING prebuilt_compat {label} +{now - last:.3f}s total={now - start:.3f}s") - last = now - -mods = [ - "openpilot.common.params_pyx", - "msgq.ipc_pyx", - "msgq.visionipc.visionipc_pyx", - "openpilot.common.transformations.transformations", - "openpilot.selfdrive.pandad.pandad_api_impl", - "openpilot.selfdrive.controls.lib.lateral_mpc_lib.c_generated_code.acados_ocp_solver_pyx", - "openpilot.selfdrive.controls.lib.longitudinal_mpc_lib.c_generated_code.acados_ocp_solver_pyx", -] - -for mod in mods: - try: - importlib.import_module(mod) - except Exception as e: - print(f"Prebuilt compatibility failure in {mod}: {e}", file=sys.stderr) - raise - log_step(f"import:{mod}") - -repo_root = Path.cwd().parents[1] -required_model_artifacts = [ - repo_root / "selfdrive/modeld/models/driving_tinygrad.pkl", - repo_root / "selfdrive/modeld/models/dmonitoring_model_metadata.pkl", - repo_root / "selfdrive/modeld/models/dmonitoring_model_tinygrad.pkl", - repo_root / "selfdrive/modeld/models/dm_warp_1928x1208_tinygrad.pkl", - repo_root / "selfdrive/modeld/models/dm_warp_1344x760_tinygrad.pkl", -] -required_files = [ - repo_root / "selfdrive/pandad/pandad_api_impl.so", - repo_root / "selfdrive/controls/lib/lateral_mpc_lib/c_generated_code/acados_ocp_solver_pyx.so", - repo_root / "selfdrive/controls/lib/lateral_mpc_lib/c_generated_code/libacados_ocp_solver_lat.so", - repo_root / "selfdrive/controls/lib/longitudinal_mpc_lib/c_generated_code/acados_ocp_solver_pyx.so", - repo_root / "selfdrive/controls/lib/longitudinal_mpc_lib/c_generated_code/libacados_ocp_solver_long.so", - repo_root / "opendbc_repo/opendbc/dbc/gm_global_a_powertrain_generated.dbc", -] - -for path in required_model_artifacts: - try: - artifact_paths = [Path(p) for p in get_existing_chunks(path)] - except Exception as e: - raise FileNotFoundError(f"Missing prebuilt runtime artifact: {path}") from e - missing_chunks = [p for p in artifact_paths if not p.is_file()] - if missing_chunks: - missing = ", ".join(str(p) for p in missing_chunks) - raise FileNotFoundError(f"Missing prebuilt runtime artifact chunks for {path}: {missing}") -log_step("required_model_artifacts") - -for path in required_files: - if not path.is_file(): - raise FileNotFoundError(f"Missing prebuilt runtime artifact: {path}") -log_step("required_files") -PY - } - - USE_PREBUILT=1 - if [ -f /data/params/d/UsePrebuilt ]; then - USE_PREBUILT=$(tr -d '\n' < /data/params/d/UsePrebuilt) - fi - sp_launch_timing "prebuilt_decision_done" - if [ "$USE_PREBUILT" = "1" ] && [ -f $DIR/prebuilt ] && ! prebuilt_runtime_compatible; then - echo "Prebuilt runtime artifacts are incompatible on this device; rebuilding locally." - USE_PREBUILT=0 - fi - sp_launch_timing "prebuilt_compat_done" - - if [ "$USE_PREBUILT" != "1" ] || [ ! -f $DIR/prebuilt ]; then + # Published trees carry this marker and must never compile on-device. + # Developers can remove it explicitly when working from a source tree. + if [ ! -f "$DIR/prebuilt" ]; then sp_launch_timing "build_start" ./build.py sp_launch_timing "build_done" diff --git a/selfdrive/ui/layouts/settings/developer.py b/selfdrive/ui/layouts/settings/developer.py index 437376d949..2e817bef22 100644 --- a/selfdrive/ui/layouts/settings/developer.py +++ b/selfdrive/ui/layouts/settings/developer.py @@ -25,10 +25,6 @@ DESCRIPTIONS = { "Enable this to switch to openpilot longitudinal control. Enabling Experimental mode is recommended when enabling openpilot longitudinal control alpha. " + "Changing this setting will restart openpilot if the car is powered on." ), - 'use_prebuilt': tr_noop( - "When enabled (default), openpilot uses prebuilt binaries at startup and skips source compilation. " + - "Disable this if you intend to edit code and compile directly on-device." - ), } @@ -46,14 +42,6 @@ class DeveloperLayout(Widget): enabled=ui_state.is_offroad, ) - self._use_prebuilt_toggle = toggle_item( - lambda: tr("Use Prebuilt Binaries"), - description=lambda: tr(DESCRIPTIONS["use_prebuilt"]), - initial_state=self._params.get_bool("UsePrebuilt"), - callback=self._on_use_prebuilt, - enabled=ui_state.is_offroad, - ) - # SSH enable toggle + SSH key management self._ssh_toggle = toggle_item( lambda: tr("Enable SSH"), @@ -96,7 +84,6 @@ class DeveloperLayout(Widget): self._scroller = Scroller([ self._adb_toggle, - self._use_prebuilt_toggle, self._ssh_toggle, self._ssh_keys, self._joystick_toggle, @@ -140,7 +127,6 @@ class DeveloperLayout(Widget): # refresh toggles from params to mirror external changes for key, item in ( ("AdbEnabled", self._adb_toggle), - ("UsePrebuilt", self._use_prebuilt_toggle), ("SshEnabled", self._ssh_toggle), ("JoystickDebugMode", self._joystick_toggle), ("LongitudinalManeuverMode", self._long_maneuver_toggle), @@ -160,9 +146,6 @@ class DeveloperLayout(Widget): def _on_enable_ssh(self, state: bool): self._params.put_bool("SshEnabled", state) - def _on_use_prebuilt(self, state: bool): - self._params.put_bool("UsePrebuilt", state) - def _on_joystick_debug_mode(self, state: bool): self._params.put_bool("JoystickDebugMode", state) self._params.put_bool("LongitudinalManeuverMode", False) diff --git a/selfdrive/ui/mici/layouts/settings/developer.py b/selfdrive/ui/mici/layouts/settings/developer.py index 1a396a7ed0..5c33d0b7af 100644 --- a/selfdrive/ui/mici/layouts/settings/developer.py +++ b/selfdrive/ui/mici/layouts/settings/developer.py @@ -49,7 +49,6 @@ class DeveloperLayoutMici(NavScroller): # ******** Main Scroller ******** self._adb_toggle = BigCircleParamControl(gui_app.texture("icons_mici/adb_short.png", 82, 82), "AdbEnabled", icon_offset=(0, 12)) self._ssh_toggle = BigCircleParamControl(gui_app.texture("icons_mici/ssh_short.png", 82, 82), "SshEnabled", icon_offset=(0, 12)) - self._use_prebuilt_toggle = BigParamControl("use prebuilt binaries", "UsePrebuilt") self._disable_wide_road_toggle = BigParamControl("disable wide road camera", "DisableWideRoad", toggle_callback=restart_needed_callback) self._joystick_toggle = BigToggle("joystick debug mode", initial_state=ui_state.params.get_bool("JoystickDebugMode"), @@ -71,7 +70,6 @@ class DeveloperLayoutMici(NavScroller): self._adb_toggle, self._ssh_toggle, self._ssh_keys_btn, - self._use_prebuilt_toggle, self._disable_wide_road_toggle, self._joystick_toggle, self._long_maneuver_toggle, @@ -84,7 +82,6 @@ class DeveloperLayoutMici(NavScroller): self._refresh_toggles = ( ("AdbEnabled", self._adb_toggle), ("SshEnabled", self._ssh_toggle), - ("UsePrebuilt", self._use_prebuilt_toggle), ("DisableWideRoad", self._disable_wide_road_toggle), ("JoystickDebugMode", self._joystick_toggle), ("LongitudinalManeuverMode", self._long_maneuver_toggle), @@ -94,7 +91,6 @@ class DeveloperLayoutMici(NavScroller): ) onroad_blocked_toggles = ( self._adb_toggle, - self._use_prebuilt_toggle, self._disable_wide_road_toggle, self._joystick_toggle, ) diff --git a/system/manager/launch_param_migrations.py b/system/manager/launch_param_migrations.py index 5504a4d8fd..adf09a0021 100644 --- a/system/manager/launch_param_migrations.py +++ b/system/manager/launch_param_migrations.py @@ -187,11 +187,6 @@ def _apply_legacy_launch_param_migrations(params: ParamsLike, marker: Path) -> N _approx_equal(steer_kp_stock, LEGACY_STEER_KP_STOCK_PLACEHOLDER)): params.put_float(STEER_KP_STOCK_KEY, DEFAULT_STEER_KP) - # Initialize UsePrebuilt to True if never explicitly set, so the UI default - # matches the shell script's default of USE_PREBUILT=1. - if not Path(params.get_param_path("UsePrebuilt")).exists(): - params.put_bool("UsePrebuilt", True) - marker.touch() diff --git a/system/manager/test/test_launch_param_migrations.py b/system/manager/test/test_launch_param_migrations.py index 45205715e6..d8624d6dfd 100644 --- a/system/manager/test/test_launch_param_migrations.py +++ b/system/manager/test/test_launch_param_migrations.py @@ -84,23 +84,6 @@ def test_apply_launch_param_migrations_sets_branch_defaults_once(tmp_path): assert marker_path(tmp_path, LAUNCH_PARAM_MIGRATION_MARKER).is_file() -def test_apply_launch_param_migrations_initializes_use_prebuilt(tmp_path): - params = FileBackedFakeParams(tmp_path / "params") - - apply_launch_param_migrations(params) - - assert params.get_bool("UsePrebuilt") - - -def test_apply_launch_param_migrations_does_not_overwrite_use_prebuilt(tmp_path): - params = FileBackedFakeParams(tmp_path / "params") - params.put_bool("UsePrebuilt", False) - - apply_launch_param_migrations(params) - - assert not params.get_bool("UsePrebuilt") - - def test_apply_launch_param_migrations_does_not_reapply_after_marker(tmp_path): params = FileBackedFakeParams(tmp_path / "params") marker = marker_path(tmp_path, LAUNCH_PARAM_MIGRATION_MARKER) diff --git a/system/manager/test/test_launch_prebuilt_policy.py b/system/manager/test/test_launch_prebuilt_policy.py new file mode 100644 index 0000000000..e4506acd03 --- /dev/null +++ b/system/manager/test/test_launch_prebuilt_policy.py @@ -0,0 +1,14 @@ +from pathlib import Path +import re + + +LAUNCH_SCRIPT = Path(__file__).parents[3] / "launch_chffrplus.sh" + + +def test_prebuilt_marker_is_the_only_build_gate(): + script = LAUNCH_SCRIPT.read_text() + + assert "UsePrebuilt" not in script + assert "prebuilt_runtime_compatible" not in script + assert len(re.findall(r"\./build\.py", script)) == 1 + assert re.search(r'if \[ ! -f "\$DIR/prebuilt" \]; then\s+sp_launch_timing "build_start"\s+\./build\.py', script)