diff --git a/selfdrive/ui/layouts/settings/starpilot/vehicle.py b/selfdrive/ui/layouts/settings/starpilot/vehicle.py index a7e71cb48..42a1f6037 100644 --- a/selfdrive/ui/layouts/settings/starpilot/vehicle.py +++ b/selfdrive/ui/layouts/settings/starpilot/vehicle.py @@ -35,7 +35,7 @@ from openpilot.selfdrive.ui.layouts.settings.starpilot.aethergrid import ( draw_status_badges, ) from openpilot.selfdrive.ui.lib.starpilot_state import starpilot_state -from openpilot.selfdrive.ui.mici.layouts.settings.fingerprint_catalog import ( +from openpilot.selfdrive.ui.lib.fingerprint_catalog import ( FingerprintModelOption, get_fingerprint_catalog, shorten_model_label, @@ -605,20 +605,24 @@ class StarPilotVehicleSettingsLayout(_SettingsPage): def on_confirm(res): if res == DialogResult.CONFIRM: self._params.put_bool("DisableOpenpilotLongitudinal", True) + starpilot_state.update(force=True) if starpilot_state.started: HARDWARE.reboot() gui_app.push_widget(ConfirmDialog(tr("Disable openpilot longitudinal control?"), tr("Disable"), callback=on_confirm)) else: self._params.put_bool("DisableOpenpilotLongitudinal", False) + starpilot_state.update(force=True) return if param_key == "RemapCancelToDistance": new_state = not self._params.get_bool("RemapCancelToDistance") self._params.put_bool("RemapCancelToDistance", new_state) if new_state: migrate_cancel_button_controls(self._params) + starpilot_state.update(force=True) return current = self._params.get_bool(param_key) if self._params.get(param_key) is not None else False self._params.put_bool(param_key, not current) + starpilot_state.update(force=True) def _on_select(self, key: str): if key == "CarMake": @@ -648,7 +652,7 @@ class StarPilotVehicleSettingsLayout(_SettingsPage): if current_model not in available: self._params.remove("CarModel") self._params.remove("CarModelName") - starpilot_state.update() + starpilot_state.update(force=True) dialog = MultiOptionDialog(tr("Select Make"), makes, default_make, callback=on_select) gui_app.push_widget(dialog) @@ -676,7 +680,7 @@ class StarPilotVehicleSettingsLayout(_SettingsPage): self._params.put("CarModel", opt.value) self._params.put("CarModelName", opt.label) self._params.put("CarMake", make) - starpilot_state.update() + starpilot_state.update(force=True) dialog = MultiOptionDialog(tr("Select Model"), option_labels, default_option, callback=on_select) gui_app.push_widget(dialog) diff --git a/selfdrive/ui/mici/layouts/settings/fingerprint_catalog.py b/selfdrive/ui/lib/fingerprint_catalog.py similarity index 100% rename from selfdrive/ui/mici/layouts/settings/fingerprint_catalog.py rename to selfdrive/ui/lib/fingerprint_catalog.py diff --git a/selfdrive/ui/lib/starpilot_state.py b/selfdrive/ui/lib/starpilot_state.py index ce2854857..714aa5145 100644 --- a/selfdrive/ui/lib/starpilot_state.py +++ b/selfdrive/ui/lib/starpilot_state.py @@ -76,21 +76,35 @@ class StarPilotState: self._param_update_time = 0.0 self.update() - def _apply_desktop_fallback(self, starpilot_toggles: dict): + def _apply_manual_fingerprint(self, starpilot_toggles: dict): fallback_make = starpilot_toggles.get("car_make") or self.params.get("CarMake") or "gm" fallback_model = starpilot_toggles.get("car_model") or self.params.get("CarModel") or "CHEVROLET_BOLT_ACC_2022_2023" + from openpilot.selfdrive.ui.lib.fingerprint_catalog import FINGERPRINT_MAKE_TO_VALUES_DIR + fallback_make_lower = fallback_make.lower() + brand = FINGERPRINT_MAKE_TO_VALUES_DIR.get(fallback_make_lower, fallback_make_lower) + + self.car_state.isBolt = fallback_model.startswith("CHEVROLET_BOLT") + self.car_state.isGM = brand == "gm" + self.car_state.isHKG = brand == "hyundai" + self.car_state.isSubaru = brand == "subaru" + self.car_state.isToyota = brand == "toyota" + self.car_state.isVolt = fallback_model.startswith("CHEVROLET_VOLT") + + # Determine isHKGCanFd for manual selection + is_canfd = False + try: + from opendbc.car.hyundai.values import CANFD_CAR + is_canfd = any(fallback_model == getattr(c, "value", str(c)) for c in CANFD_CAR) + except Exception: + pass + self.car_state.isHKGCanFd = self.car_state.isHKG and is_canfd + self.car_state.hasModeStarButtons = self.car_state.isHKGCanFd self.car_state.hasPedal = starpilot_toggles.get("has_pedal", True) self.car_state.hasSASCM = starpilot_toggles.get("has_sascm", False) self.car_state.hasSDSU = starpilot_toggles.get("has_sdsu", False) self.car_state.hasZSS = starpilot_toggles.get("has_zss", False) - self.car_state.isBolt = fallback_model.startswith("CHEVROLET_BOLT") - self.car_state.isGM = fallback_make == "gm" - self.car_state.isHKG = fallback_make == "hyundai" - self.car_state.isSubaru = fallback_make == "subaru" - self.car_state.isToyota = fallback_make == "toyota" - self.car_state.isVolt = fallback_model.startswith("CHEVROLET_VOLT") self.car_state.canUsePedal = self.car_state.hasPedal or self.car_state.isBolt self.car_state.canUseSDSU = self.car_state.hasSDSU @@ -100,15 +114,16 @@ class StarPilotState: except Exception: return default - def update(self) -> None: + def update(self, force: bool = False) -> None: # Throttle heavy param parsing to avoid slowing down UI current_time = time.monotonic() - if current_time - self._param_update_time < 2.0: + if not force and current_time - self._param_update_time < 2.0: return self._param_update_time = current_time self.tuning_level = self.params.get_int("TuningLevel") + force_fingerprint = self.params.get_bool("ForceFingerprint") # Read starpilot_toggles from params memory or scene try: @@ -171,13 +186,13 @@ class StarPilotState: self.car_state.vEgoStarting = float(self._safe_get(CP, "vEgoStarting", self.car_state.vEgoStarting)) self.car_state.vEgoStopping = float(self._safe_get(CP, "vEgoStopping", self.car_state.vEgoStopping)) - if PC and (car_make == "mock" or car_fingerprint == "MOCK"): - self._apply_desktop_fallback(starpilot_toggles) - elif PC: - self._apply_desktop_fallback(starpilot_toggles) + if (PC or force_fingerprint) and (car_make == "mock" or car_fingerprint == "MOCK"): + self._apply_manual_fingerprint(starpilot_toggles) + elif PC or force_fingerprint: + self._apply_manual_fingerprint(starpilot_toggles) - elif PC: - self._apply_desktop_fallback(starpilot_toggles) + elif PC or force_fingerprint: + self._apply_manual_fingerprint(starpilot_toggles) # 2. Parse StarPilotCarParamsPersistent fpcp_bytes = self.params.get("StarPilotCarParamsPersistent") diff --git a/selfdrive/ui/mici/layouts/settings/vehicle.py b/selfdrive/ui/mici/layouts/settings/vehicle.py index 7825aecb6..769897844 100644 --- a/selfdrive/ui/mici/layouts/settings/vehicle.py +++ b/selfdrive/ui/mici/layouts/settings/vehicle.py @@ -2,7 +2,7 @@ from openpilot.common.params import Params from openpilot.system.ui.widgets.scroller import NavScroller from openpilot.selfdrive.ui.mici.widgets.button import BigButton, BigParamControl from openpilot.selfdrive.ui.mici.widgets.dialog import BigDialog, BigMultiOptionDialog -from openpilot.selfdrive.ui.mici.layouts.settings.fingerprint_catalog import ( +from openpilot.selfdrive.ui.lib.fingerprint_catalog import ( FingerprintModelOption, format_fingerprint_value, get_fingerprint_catalog,