From 9c0b1f9fa98ccd4b1b87cb8e0596e2fcda3855ff Mon Sep 17 00:00:00 2001 From: nayan Date: Thu, 20 Aug 2026 18:35:23 -0400 Subject: [PATCH] device --- .../ui/sunnypilot/layouts/settings/models.py | 6 +- .../ui/sunnypilot/mici/layouts/models.py | 8 +- openpilot/sunnypilot/models/default_model.py | 94 +++++++++++++------ openpilot/sunnypilot/models/model_name.py | 1 + .../sunnypilot/models/tests/model_hash_big | 1 + .../models/tests/test_default_model.py | 19 +++- 6 files changed, 87 insertions(+), 42 deletions(-) create mode 100644 openpilot/sunnypilot/models/tests/model_hash_big diff --git a/openpilot/selfdrive/ui/sunnypilot/layouts/settings/models.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/models.py index aa5700fe28..85438f4de8 100644 --- a/openpilot/selfdrive/ui/sunnypilot/layouts/settings/models.py +++ b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/models.py @@ -10,7 +10,7 @@ import time import pyray as rl from openpilot.cereal import custom -from openpilot.sunnypilot.models.default_model import DEFAULT_MODEL +from openpilot.sunnypilot.models.default_model import get_default_model from openpilot.common.constants import CV from openpilot.selfdrive.ui.ui_state import device, ui_state from openpilot.system.ui.lib.multilang import tr @@ -211,7 +211,7 @@ class ModelsLayout(Widget): for bundle in bundles: folders.setdefault(next((ov_ride.value for ov_ride in bundle.overrides if ov_ride.key == "folder"), ""), []).append(bundle) - folders_list = [TreeFolder("", [TreeNode("Default", {'display_name': f"{DEFAULT_MODEL} (Default)", 'short_name': "Default"})])] + folders_list = [TreeFolder("", [TreeNode("Default", {'display_name': f"{get_default_model()} (Default)", 'short_name': "Default"})])] for folder, folder_bundles in sorted(folders.items(), key=lambda x: max((bundle.index for bundle in x[1]), default=-1), reverse=True): folder_bundles.sort(key=lambda bundle: bundle.index, reverse=True) name = folder + (f" - (Updated: {m.group(1)})" if folder_bundles and (m := re.search(r'\(([^)]*)\)[^(]*$', folder_bundles[0].displayName)) else "") @@ -249,7 +249,7 @@ class ModelsLayout(Widget): self._update_lagd_description(live_delay) self.model_manager = ui_state.sm["modelManagerSP"] self._handle_bundle_download_progress() - active_name = self.model_manager.activeBundle.displayName if self.model_manager and self.model_manager.activeBundle.ref else f"{DEFAULT_MODEL} (Default)" + active_name = self.model_manager.activeBundle.displayName if self.model_manager and self.model_manager.activeBundle.ref else f"{get_default_model()} (Default)" self.current_model_item.action_item.set_value(active_name) if not ui_state.is_offroad(): diff --git a/openpilot/selfdrive/ui/sunnypilot/mici/layouts/models.py b/openpilot/selfdrive/ui/sunnypilot/mici/layouts/models.py index af8f348f72..01f8d1fe4d 100644 --- a/openpilot/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. import pyray as rl from openpilot.cereal import custom -from openpilot.sunnypilot.models.default_model import DEFAULT_MODEL +from openpilot.sunnypilot.models.default_model import get_default_model from openpilot.selfdrive.ui.mici.widgets.button import BigButton from openpilot.selfdrive.ui.sunnypilot.layouts.settings.models import ModelsLayout from openpilot.selfdrive.ui.ui_state import ui_state, device @@ -27,7 +27,7 @@ class CurrentModelInfo(Widget): subheader_color = rl.Color(255, 255, 255, int(255 * 0.9 * 0.65)) max_width = int(self._rect.width - 20) self.current_model_header = UnifiedLabel(tr("active model"), 48, max_width=max_width, text_color=header_color, font_weight=FontWeight.DISPLAY) - default_text = f"{DEFAULT_MODEL} (Default)".lower() + default_text = f"{get_default_model()} (Default)".lower() self.current_model_text = UnifiedLabel(default_text, 32, max_width=max_width, text_color=subheader_color, font_weight=FontWeight.ROMAN, scroll=True) self.info_header = UnifiedLabel("cache size", 48, max_width=max_width, text_color=header_color, font_weight=FontWeight.DISPLAY) @@ -95,7 +95,7 @@ class ModelsLayoutMici(NavScroller): folders = self._get_grouped_bundles(favorites) folder_buttons = [] - default_btn = BigButton(f"{DEFAULT_MODEL} (Default)".lower()) + default_btn = BigButton(f"{get_default_model()} (Default)".lower()) default_btn.set_click_callback(self._select_default) folder_buttons.append(default_btn) @@ -162,7 +162,7 @@ class ModelsLayoutMici(NavScroller): self._was_downloading = is_downloading self.current_model_info.current_model_header.set_text(tr("active model")) - model_text = manager.activeBundle.displayName.lower() if manager.activeBundle.ref else f"{DEFAULT_MODEL} (Default)".lower() + model_text = manager.activeBundle.displayName.lower() if manager.activeBundle.ref else f"{get_default_model()} (Default)".lower() self.current_model_info.current_model_text.set_text(model_text) self.current_model_info.info_header.set_text(tr("cache size")) self.current_model_info.info_text.set_text(f"{ModelsLayout.calculate_cache_size():.2f} MB") diff --git a/openpilot/sunnypilot/models/default_model.py b/openpilot/sunnypilot/models/default_model.py index 62b6831402..fc5c2704fa 100755 --- a/openpilot/sunnypilot/models/default_model.py +++ b/openpilot/sunnypilot/models/default_model.py @@ -4,58 +4,90 @@ import hashlib from openpilot.common.basedir import BASEDIR from openpilot.sunnypilot import get_file_hash -from openpilot.sunnypilot.models.model_name import DEFAULT_MODEL +from openpilot.sunnypilot.models.model_name import DEFAULT_MODEL, DEFAULT_BIG_MODEL +from openpilot.selfdrive.modeld.helpers import usbgpu_present 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") +BIG_MODEL_HASH_PATH = os.path.join(BASEDIR, "openpilot", "sunnypilot", "models", "tests", "model_hash_big") SUPERCOMBO_ONNX_PATH = os.path.join(BASEDIR, "openpilot", "selfdrive", "modeld", "models", "driving_supercombo.onnx") +BIG_SUPERCOMBO_ONNX_PATH = os.path.join(BASEDIR, "openpilot", "selfdrive", "modeld", "models", "big_driving_supercombo.onnx") + + +def _model_hash(path: str) -> str: + return hashlib.sha256(get_file_hash(path).encode()).hexdigest() def update_model_hash(): - supercombo_hash = get_file_hash(SUPERCOMBO_ONNX_PATH) - - combined_hash = hashlib.sha256(supercombo_hash.encode()).hexdigest() - with open(MODEL_HASH_PATH, "w") as f: - f.write(combined_hash) + f.write(_model_hash(SUPERCOMBO_ONNX_PATH)) + with open(BIG_MODEL_HASH_PATH, "w") as f: + f.write(_model_hash(BIG_SUPERCOMBO_ONNX_PATH)) - print(f"Generated and updated new combined model hash to {MODEL_HASH_PATH}") + print(f"Generated and updated new model hashes to {MODEL_HASH_PATH} and {BIG_MODEL_HASH_PATH}") -def get_current_default_model_name(): - print("[GET DEFAULT MODEL NAME]") - name = DEFAULT_MODEL - print(f'Current default model name: "{name}"') - - return name +def get_default_model() -> str: + return DEFAULT_BIG_MODEL if usbgpu_present() else DEFAULT_MODEL -def update_default_model_name(name: str): - print("[CHANGE DEFAULT MODEL NAME]") +def update_default_model_names(default_model_name: str, default_big_model_name: str): + print("[CHANGE DEFAULT MODEL NAMES]") with open(DEFAULT_MODEL_NAME_PATH, "w") as f: - f.write(f'DEFAULT_MODEL = "{name}"\n') - print(f'New default model name: "{name}"') + f.write(f'DEFAULT_MODEL = "{default_model_name}"\n') + f.write(f'DEFAULT_BIG_MODEL = "{default_big_model_name}"\n') + + print(f'New default small model name: "{default_model_name}"') + print(f'New default big model name: "{default_big_model_name}"') print("[DONE]") if __name__ == "__main__": - parser = argparse.ArgumentParser(description="Update default model name and hash") - parser.add_argument("--new_name", type=str, help="New default model name") + parser = argparse.ArgumentParser(description="Update default model names and hash") + parser.add_argument("--new_small_model_name", type=str, help="New default model name") + parser.add_argument("--new_big_model_name", type=str, help="New default big model name") args = parser.parse_args() - if not args.new_name: - print("Warning: No new default model name provided. Use --new_name to specify") - print("Default model name and hash will not be updated! (aborted)") + current_name = DEFAULT_MODEL + current_big_model_name = DEFAULT_BIG_MODEL + + new_name = args.new_small_model_name if args.new_small_model_name is not None else input( + f'Enter new default small model name (current: "{current_name}", leave empty to keep): ').strip() + new_big_model_name = args.new_big_model_name if args.new_big_model_name is not None else input( + f'Enter new default big model name (current: "{current_big_model_name}", leave empty to keep): ').strip() + + if not new_name and not new_big_model_name: + print("No new default model names provided. Default model names and hash will not be updated! (aborted)") exit(0) - current_name = get_current_default_model_name() - new_name = args.new_name - if current_name == new_name: - print(f'Proposed default model name: "{new_name}"') - confirm = input("Proposed default model name is the same as the current default model name. Confirm? (y/n): ").upper().strip() - if confirm != "Y": - print("Default model name and hash will not be updated! (aborted)") - exit(0) + final_name = current_name + final_big_model_name = current_big_model_name - update_default_model_name(new_name) + if new_name: + if current_name == new_name: + print(f'Proposed default model name: "{new_name}" is the same as the current default model name.') + confirm = input("Confirm? (y/n): ").upper().strip() + if confirm != "Y": + print(f'Default model name will not be updated: "{new_name}"') + else: + final_name = new_name + else: + final_name = new_name + + if new_big_model_name: + if current_big_model_name == new_big_model_name: + print(f'Proposed default big model name: "{new_big_model_name}" is the same as the current default big model name.') + confirm = input("Confirm? (y/n): ").upper().strip() + if confirm != "Y": + print(f'Default big model name will not be updated: "{new_big_model_name}"') + else: + final_big_model_name = new_big_model_name + else: + final_big_model_name = new_big_model_name + + if final_name == current_name and final_big_model_name == current_big_model_name: + print("No changes made. Default model names and hash will not be updated! (aborted)") + exit(0) + + update_default_model_names(final_name, final_big_model_name) update_model_hash() diff --git a/openpilot/sunnypilot/models/model_name.py b/openpilot/sunnypilot/models/model_name.py index 02a6c2bac2..374e8473df 100644 --- a/openpilot/sunnypilot/models/model_name.py +++ b/openpilot/sunnypilot/models/model_name.py @@ -1 +1,2 @@ DEFAULT_MODEL = "CD210" +DEFAULT_BIG_MODEL = "Lebowski" diff --git a/openpilot/sunnypilot/models/tests/model_hash_big b/openpilot/sunnypilot/models/tests/model_hash_big new file mode 100644 index 0000000000..e957940fdd --- /dev/null +++ b/openpilot/sunnypilot/models/tests/model_hash_big @@ -0,0 +1 @@ +8bba37156aa17d49210cad028744c839ea9ed7b1f19428a8ecfafdc1e07a73b6 \ No newline at end of file diff --git a/openpilot/sunnypilot/models/tests/test_default_model.py b/openpilot/sunnypilot/models/tests/test_default_model.py index 450237e0e9..a7fa4394a1 100644 --- a/openpilot/sunnypilot/models/tests/test_default_model.py +++ b/openpilot/sunnypilot/models/tests/test_default_model.py @@ -6,18 +6,29 @@ See the LICENSE.md file in the root directory for more details. """ from openpilot.sunnypilot import get_file_hash -from openpilot.sunnypilot.models.default_model import MODEL_HASH_PATH, SUPERCOMBO_ONNX_PATH +from openpilot.sunnypilot.models.default_model import (MODEL_HASH_PATH, BIG_MODEL_HASH_PATH, + SUPERCOMBO_ONNX_PATH, BIG_SUPERCOMBO_ONNX_PATH) import hashlib from openpilot.common.test import OpenpilotTestCase class TestDefaultModel(OpenpilotTestCase): - def test_compare_onnx_hashes(self): + def test_compare_onnx_hash(self): supercombo_hash = get_file_hash(SUPERCOMBO_ONNX_PATH) - combined_hash = hashlib.sha256(supercombo_hash.encode()).hexdigest() + expected_hash = hashlib.sha256(supercombo_hash.encode()).hexdigest() with open(MODEL_HASH_PATH) as f: current_hash = f.read().strip() - assert combined_hash == current_hash, "Run sunnypilot/models/default_model.py to update the default model name and hash" + assert expected_hash == current_hash, "Run sunnypilot/models/default_model.py to update the default model name and hash" + + def test_compare_big_onnx_hash(self): + big_supercombo_hash = get_file_hash(BIG_SUPERCOMBO_ONNX_PATH) + + expected_hash = hashlib.sha256(big_supercombo_hash.encode()).hexdigest() + + with open(BIG_MODEL_HASH_PATH) as f: + current_hash = f.read().strip() + + assert expected_hash == current_hash, "Run sunnypilot/models/default_model.py to update the default big model name and hash"