diff --git a/panda/board/obj/body_h7.bin.signed b/panda/board/obj/body_h7.bin.signed index f5ee65ce6..e52fd2c9e 100644 Binary files a/panda/board/obj/body_h7.bin.signed and b/panda/board/obj/body_h7.bin.signed differ diff --git a/panda/board/obj/body_h7/bootstub.elf b/panda/board/obj/body_h7/bootstub.elf index efcabbb2e..73c328644 100755 Binary files a/panda/board/obj/body_h7/bootstub.elf and b/panda/board/obj/body_h7/bootstub.elf differ diff --git a/panda/board/obj/body_h7/main.bin b/panda/board/obj/body_h7/main.bin index 565a907d6..e89c5228e 100755 Binary files a/panda/board/obj/body_h7/main.bin and b/panda/board/obj/body_h7/main.bin differ diff --git a/panda/board/obj/body_h7/main.elf b/panda/board/obj/body_h7/main.elf index c381a42b8..940ee36a5 100755 Binary files a/panda/board/obj/body_h7/main.elf and b/panda/board/obj/body_h7/main.elf differ diff --git a/panda/board/obj/bootstub.body_h7.bin b/panda/board/obj/bootstub.body_h7.bin index b12510e34..b9ae1e6eb 100755 Binary files a/panda/board/obj/bootstub.body_h7.bin and b/panda/board/obj/bootstub.body_h7.bin differ diff --git a/panda/board/obj/bootstub.panda.bin b/panda/board/obj/bootstub.panda.bin index 81f65efd3..dfe4a7cad 100755 Binary files a/panda/board/obj/bootstub.panda.bin and b/panda/board/obj/bootstub.panda.bin differ diff --git a/panda/board/obj/bootstub.panda_h7.bin b/panda/board/obj/bootstub.panda_h7.bin index 584eaf301..a35aee732 100755 Binary files a/panda/board/obj/bootstub.panda_h7.bin and b/panda/board/obj/bootstub.panda_h7.bin differ diff --git a/panda/board/obj/bootstub.panda_h7_remote.bin b/panda/board/obj/bootstub.panda_h7_remote.bin index 584eaf301..a35aee732 100755 Binary files a/panda/board/obj/bootstub.panda_h7_remote.bin and b/panda/board/obj/bootstub.panda_h7_remote.bin differ diff --git a/panda/board/obj/bootstub.panda_jungle_h7.bin b/panda/board/obj/bootstub.panda_jungle_h7.bin index 838481de5..d1a40e846 100755 Binary files a/panda/board/obj/bootstub.panda_jungle_h7.bin and b/panda/board/obj/bootstub.panda_jungle_h7.bin differ diff --git a/panda/board/obj/bootstub.panda_remote.bin b/panda/board/obj/bootstub.panda_remote.bin index 81f65efd3..dfe4a7cad 100755 Binary files a/panda/board/obj/bootstub.panda_remote.bin and b/panda/board/obj/bootstub.panda_remote.bin differ diff --git a/panda/board/obj/gitversion.h b/panda/board/obj/gitversion.h index f10ee4cc5..79320e7ba 100644 --- a/panda/board/obj/gitversion.h +++ b/panda/board/obj/gitversion.h @@ -1,2 +1,2 @@ extern const uint8_t gitversion[19]; -const uint8_t gitversion[19] = "DEV-82619bd7-DEBUG"; +const uint8_t gitversion[19] = "DEV-277b2255-DEBUG"; diff --git a/panda/board/obj/panda.bin.signed b/panda/board/obj/panda.bin.signed index a833d4dee..095883775 100644 Binary files a/panda/board/obj/panda.bin.signed and b/panda/board/obj/panda.bin.signed differ diff --git a/panda/board/obj/panda/bootstub.elf b/panda/board/obj/panda/bootstub.elf index 7253eecc3..83d4547f0 100755 Binary files a/panda/board/obj/panda/bootstub.elf and b/panda/board/obj/panda/bootstub.elf differ diff --git a/panda/board/obj/panda/main.bin b/panda/board/obj/panda/main.bin index e141ed98d..0f1a54458 100755 Binary files a/panda/board/obj/panda/main.bin and b/panda/board/obj/panda/main.bin differ diff --git a/panda/board/obj/panda/main.elf b/panda/board/obj/panda/main.elf index 2ec1b4558..0b724e2c5 100755 Binary files a/panda/board/obj/panda/main.elf and b/panda/board/obj/panda/main.elf differ diff --git a/panda/board/obj/panda_h7.bin.signed b/panda/board/obj/panda_h7.bin.signed index 03b251481..3007ab6fb 100644 Binary files a/panda/board/obj/panda_h7.bin.signed and b/panda/board/obj/panda_h7.bin.signed differ diff --git a/panda/board/obj/panda_h7/bootstub.elf b/panda/board/obj/panda_h7/bootstub.elf index a3265a685..280fcf29c 100755 Binary files a/panda/board/obj/panda_h7/bootstub.elf and b/panda/board/obj/panda_h7/bootstub.elf differ diff --git a/panda/board/obj/panda_h7/main.bin b/panda/board/obj/panda_h7/main.bin index 0529b1413..730439eb7 100755 Binary files a/panda/board/obj/panda_h7/main.bin and b/panda/board/obj/panda_h7/main.bin differ diff --git a/panda/board/obj/panda_h7/main.elf b/panda/board/obj/panda_h7/main.elf index cdc135157..53294827e 100755 Binary files a/panda/board/obj/panda_h7/main.elf and b/panda/board/obj/panda_h7/main.elf differ diff --git a/panda/board/obj/panda_h7_remote.bin.signed b/panda/board/obj/panda_h7_remote.bin.signed index a1817cb3e..1fba3aa66 100644 Binary files a/panda/board/obj/panda_h7_remote.bin.signed and b/panda/board/obj/panda_h7_remote.bin.signed differ diff --git a/panda/board/obj/panda_h7_remote/bootstub.elf b/panda/board/obj/panda_h7_remote/bootstub.elf index fb354cf92..d0245dbd9 100755 Binary files a/panda/board/obj/panda_h7_remote/bootstub.elf and b/panda/board/obj/panda_h7_remote/bootstub.elf differ diff --git a/panda/board/obj/panda_h7_remote/main.bin b/panda/board/obj/panda_h7_remote/main.bin index a1a841736..4525df840 100755 Binary files a/panda/board/obj/panda_h7_remote/main.bin and b/panda/board/obj/panda_h7_remote/main.bin differ diff --git a/panda/board/obj/panda_h7_remote/main.elf b/panda/board/obj/panda_h7_remote/main.elf index 6eea34670..d25cc91c7 100755 Binary files a/panda/board/obj/panda_h7_remote/main.elf and b/panda/board/obj/panda_h7_remote/main.elf differ diff --git a/panda/board/obj/panda_jungle_h7.bin.signed b/panda/board/obj/panda_jungle_h7.bin.signed index 89ac3f97b..68b3c5560 100644 Binary files a/panda/board/obj/panda_jungle_h7.bin.signed and b/panda/board/obj/panda_jungle_h7.bin.signed differ diff --git a/panda/board/obj/panda_jungle_h7/bootstub.elf b/panda/board/obj/panda_jungle_h7/bootstub.elf index b1fd91369..52d626beb 100755 Binary files a/panda/board/obj/panda_jungle_h7/bootstub.elf and b/panda/board/obj/panda_jungle_h7/bootstub.elf differ diff --git a/panda/board/obj/panda_jungle_h7/main.bin b/panda/board/obj/panda_jungle_h7/main.bin index f239891b6..7e9a04074 100755 Binary files a/panda/board/obj/panda_jungle_h7/main.bin and b/panda/board/obj/panda_jungle_h7/main.bin differ diff --git a/panda/board/obj/panda_jungle_h7/main.elf b/panda/board/obj/panda_jungle_h7/main.elf index 32f43489e..cc1fdbf42 100755 Binary files a/panda/board/obj/panda_jungle_h7/main.elf and b/panda/board/obj/panda_jungle_h7/main.elf differ diff --git a/panda/board/obj/panda_remote.bin.signed b/panda/board/obj/panda_remote.bin.signed index aa6d1b6c0..5ad16f1d7 100644 Binary files a/panda/board/obj/panda_remote.bin.signed and b/panda/board/obj/panda_remote.bin.signed differ diff --git a/panda/board/obj/panda_remote/bootstub.elf b/panda/board/obj/panda_remote/bootstub.elf index 0a6cba7df..a48c14ae6 100755 Binary files a/panda/board/obj/panda_remote/bootstub.elf and b/panda/board/obj/panda_remote/bootstub.elf differ diff --git a/panda/board/obj/panda_remote/main.bin b/panda/board/obj/panda_remote/main.bin index bdd2a5915..7fb59ef0b 100755 Binary files a/panda/board/obj/panda_remote/main.bin and b/panda/board/obj/panda_remote/main.bin differ diff --git a/panda/board/obj/panda_remote/main.elf b/panda/board/obj/panda_remote/main.elf index ef0590bdc..5fa18e4f4 100755 Binary files a/panda/board/obj/panda_remote/main.elf and b/panda/board/obj/panda_remote/main.elf differ diff --git a/panda/board/obj/version b/panda/board/obj/version index 382bc80eb..7d2e710b5 100644 --- a/panda/board/obj/version +++ b/panda/board/obj/version @@ -1 +1 @@ -DEV-82619bd7-DEBUG \ No newline at end of file +DEV-277b2255-DEBUG \ No newline at end of file diff --git a/selfdrive/ui/layouts/settings/starpilot/metro.py b/selfdrive/ui/layouts/settings/starpilot/metro.py index f38c87ce7..3302805c8 100644 --- a/selfdrive/ui/layouts/settings/starpilot/metro.py +++ b/selfdrive/ui/layouts/settings/starpilot/metro.py @@ -128,17 +128,38 @@ class ToggleTile(MetroTile): class ValueTile(MetroTile): - def __init__(self, title: str, get_value: Callable[[], str], on_click: Callable, icon_path: str | None = None, bg_color: rl.Color | str | None = None): + def __init__(self, title: str, get_value: Callable[[], str], on_click: Callable, icon_path: str | None = None, + bg_color: rl.Color | str | None = None, is_enabled: Callable[[], bool] | None = None): super().__init__(bg_color=bg_color, on_click=on_click) self.title = title self.get_value = get_value + self.is_enabled = is_enabled or (lambda: True) self._icon = gui_app.starpilot_texture(icon_path, 80, 80) if icon_path else None self._font = gui_app.font(FontWeight.BOLD) + self._active_color = self.bg_color + self._disabled_color = rl.Color(120, 120, 120, 255) + + def _enabled(self) -> bool: + return self.is_enabled() if callable(self.is_enabled) else bool(self.is_enabled) + + def _handle_mouse_press(self, mouse_pos: MousePos): + if not self._enabled(): + self._is_pressed = False + return + super()._handle_mouse_press(mouse_pos) + + def _handle_mouse_release(self, mouse_pos: MousePos): + if not self._enabled(): + self._is_pressed = False + return + super()._handle_mouse_release(mouse_pos) def _render(self, rect: rl.Rectangle): self.set_rect(rect) - r, g, b = max(0, self.bg_color.r - 20), max(0, self.bg_color.g - 20), max(0, self.bg_color.b - 20) - color = rl.Color(r, g, b, 255) if self._is_pressed else self.bg_color + enabled = self._enabled() + base_color = self._active_color if enabled else self._disabled_color + r, g, b = max(0, base_color.r - 20), max(0, base_color.g - 20), max(0, base_color.b - 20) + color = rl.Color(r, g, b, 255) if self._is_pressed and enabled else base_color rl.draw_rectangle_rounded(rect, 0.15, 10, color) self._draw_watermark(rect, self._icon) padding = 25 diff --git a/selfdrive/ui/layouts/settings/starpilot/wheel.py b/selfdrive/ui/layouts/settings/starpilot/wheel.py index 1055a8135..25f730845 100644 --- a/selfdrive/ui/layouts/settings/starpilot/wheel.py +++ b/selfdrive/ui/layouts/settings/starpilot/wheel.py @@ -29,7 +29,7 @@ class StarPilotWheelLayout(StarPilotPanel): "title": tr_noop("Remap Cancel Button"), "type": "toggle", "get_state": lambda: self._params.get_bool("RemapCancelToDistance"), - "set_state": lambda s: self._params.put_bool("RemapCancelToDistance", s), + "set_state": self._set_cancel_remap_state, "color": "#FFC40D", }, { @@ -58,17 +58,39 @@ class StarPilotWheelLayout(StarPilotPanel): "type": "value", "get_value": lambda: self._get_action_name("LKASButtonControl"), "on_click": lambda: self._show_action_picker("LKASButtonControl"), + "is_enabled": lambda: not self._lkas_locked(), "key": "LKASButtonControl", "color": "#FFC40D", }, ] self._rebuild_grid() + def _lkas_locked(self): + return self._params.get_bool("RemapCancelToDistance") + + def _force_lkas_no_action(self): + if self._params.get_int("LKASButtonControl") != 0: + self._params.put_int("LKASButtonControl", 0) + self._params_memory.put_bool("StarPilotTogglesUpdated", True) + + def _set_cancel_remap_state(self, state): + self._params.put_bool("RemapCancelToDistance", state) + if state: + self._force_lkas_no_action() + self._rebuild_grid() + def _get_action_name(self, key): + if key == "LKASButtonControl" and self._lkas_locked(): + self._force_lkas_no_action() + return ACTION_NAME_BY_ID[0] + idx = self._params.get_int(key) return ACTION_NAME_BY_ID.get(idx, ACTION_NAMES[0]) - def _get_available_actions(self): + def _get_available_actions(self, key=None): + if key == "LKASButtonControl" and self._lkas_locked(): + return [ACTION_NAME_BY_ID[0]] + cs = starpilot_state.car_state return [ option["name"] for option in ACTION_OPTIONS @@ -76,7 +98,12 @@ class StarPilotWheelLayout(StarPilotPanel): ] def _show_action_picker(self, key): - actions = self._get_available_actions() + if key == "LKASButtonControl" and self._lkas_locked(): + self._force_lkas_no_action() + self._rebuild_grid() + return + + actions = self._get_available_actions(key) current = self._get_action_name(key) if current not in actions: current = actions[0] @@ -84,6 +111,7 @@ class StarPilotWheelLayout(StarPilotPanel): def on_select(res, val): if res == DialogResult.CONFIRM: self._params.put_int(key, ACTION_IDS.get(val, 0)) + self._params_memory.put_bool("StarPilotTogglesUpdated", True) self._rebuild_grid() gui_app.set_modal_overlay(SelectionDialog(tr(key), actions, current, on_close=on_select)) @@ -91,6 +119,8 @@ class StarPilotWheelLayout(StarPilotPanel): def _rebuild_grid(self): if not self.CATEGORIES: return + if self._lkas_locked(): + self._force_lkas_no_action() if self._tile_grid is None: self._tile_grid = __import__('openpilot.selfdrive.ui.layouts.settings.starpilot.metro', fromlist=['TileGrid']).TileGrid(columns=None, padding=20) self._tile_grid.clear() @@ -110,7 +140,7 @@ class StarPilotWheelLayout(StarPilotPanel): elif tile_type == "value": from openpilot.selfdrive.ui.layouts.settings.starpilot.metro import ValueTile - tile = ValueTile(title=tr(cat["title"]), get_value=cat["get_value"], on_click=cat["on_click"], bg_color=cat.get("color")) + tile = ValueTile(title=tr(cat["title"]), get_value=cat["get_value"], on_click=cat["on_click"], bg_color=cat.get("color"), is_enabled=cat.get("is_enabled")) else: continue self._tile_grid.add_tile(tile) diff --git a/selfdrive/ui/ui b/selfdrive/ui/ui index ba6e54549..87f7f44ff 100755 Binary files a/selfdrive/ui/ui and b/selfdrive/ui/ui differ diff --git a/starpilot/system/the_pond/assets/components/tools/device_settings.js b/starpilot/system/the_pond/assets/components/tools/device_settings.js index c70ecc89a..8148f05bb 100644 --- a/starpilot/system/the_pond/assets/components/tools/device_settings.js +++ b/starpilot/system/the_pond/assets/components/tools/device_settings.js @@ -565,6 +565,13 @@ function clearSearchFilter() { scheduleSyncInputs() } +function getSettingLockReason(param) { + if (param?.key === "LKASButtonControl" && !!state.values.RemapCancelToDistance) { + return "Cancel remap requires the LKAS button to stay on No Action." + } + return "" +} + function handleSectionTabClick(sectionSlug, event) { if (!sectionSlug || sectionSlug === state.activeSectionSlug) return @@ -590,6 +597,8 @@ function renderSettingRow(p) { const isNumeric = p.ui_type === "numeric" const isChild = p.parent_key ? "ds-child-modifier" : "" + const lockReason = getSettingLockReason(p) + const isLocked = lockReason !== "" return html`
Error: ${state.error}
` : ""} ${state.live?.lastError ? html`Source Error: ${state.live.lastError}
` : ""}- Match rating uses a 30-second rolling window. Lateral prefers true steering-demand moments, and longitudinal also checks how much of the window stays above error limits so brief spikes are less likely to mark "Poor." + Match rating uses a 30-second rolling window. Strong steering or accel moments are preferred, but gentler windows can still earn a rating so normal driving does not sit at N/A. Longitudinal also checks how much of the window stays above error limits so brief spikes are less likely to mark "Poor."
diff --git a/starpilot/system/the_pond/the_pond.py b/starpilot/system/the_pond/the_pond.py index 54d3096f1..20e510e63 100644 --- a/starpilot/system/the_pond/the_pond.py +++ b/starpilot/system/the_pond/the_pond.py @@ -674,6 +674,26 @@ def _safe_float(value, default=0.0): except Exception: return float(default) +def _get_param_int_value(key, default=0): + try: + raw_value = params.get(key) + if isinstance(raw_value, bytes): + raw_value = raw_value.decode("utf-8", errors="replace") + return int(float(str(raw_value or default))) + except Exception: + return int(default) + +def _enforce_cancel_remap_lkas_lock(): + if not params.get_bool("RemapCancelToDistance"): + return False + + if _get_param_int_value("LKASButtonControl", 0) == 0: + return False + + params.put("LKASButtonControl", "0") + update_starpilot_toggles() + return True + def _get_system_uptime_seconds(): try: with open("/proc/uptime", "r", encoding="utf-8") as uptime_file: @@ -2803,15 +2823,30 @@ def setup(app): metered_enabled = str_val.strip() in ("1", "true", "True") gsm_metered_apply_result = _apply_cellular_metered_setting(metered_enabled) + locked_lkas = _enforce_cancel_remap_lkas_lock() update_starpilot_toggles() response = {"message": f"Parameter '{key}' updated successfully."} + updated = {} + if key == "RemapCancelToDistance" and params.get_bool("RemapCancelToDistance"): + updated["RemapCancelToDistance"] = True + updated["LKASButtonControl"] = 0 + response["message"] = "Remap Cancel To Distance enabled. LKAS Button has been locked to No Action." + elif key == "LKASButtonControl" and params.get_bool("RemapCancelToDistance"): + updated["LKASButtonControl"] = 0 + updated["RemapCancelToDistance"] = True + response["message"] = "LKAS Button is locked to No Action while Remap Cancel To Distance is enabled." + elif locked_lkas: + updated["LKASButtonControl"] = 0 + if gsm_metered_apply_result is not None: - response["updated"] = {"GsmMetered": str_val.strip() in ("1", "true", "True")} + updated["GsmMetered"] = str_val.strip() in ("1", "true", "True") response["networkProfilesUpdated"] = gsm_metered_apply_result.get("profiles", []) warnings = gsm_metered_apply_result.get("warnings", []) if warnings: response["warning"] = " ".join(warnings) + if updated: + response["updated"] = updated return jsonify(response), 200 @@ -2819,6 +2854,7 @@ def setup(app): @app.route("/api/params/all", methods=["GET"]) def get_all_params(): + _enforce_cancel_remap_lkas_lock() allowed_keys, types = _get_param_type_info() result = {} diff --git a/starpilot/ui/qt/offroad/vehicle_settings.cc b/starpilot/ui/qt/offroad/vehicle_settings.cc index 12a43c5dd..75cd2ffed 100644 --- a/starpilot/ui/qt/offroad/vehicle_settings.cc +++ b/starpilot/ui/qt/offroad/vehicle_settings.cc @@ -305,6 +305,11 @@ StarPilotVehiclesPanel::StarPilotVehiclesPanel(StarPilotSettingsWindow *parent, QSet