From c2572f50a4f9208843af7efb3da7bd8d38cafcba Mon Sep 17 00:00:00 2001 From: firestar5683 <168790843+firestar5683@users.noreply.github.com> Date: Sat, 28 Mar 2026 23:03:51 -0500 Subject: [PATCH] galaxy --- .../ui/layouts/settings/starpilot/vehicle.py | 1 + selfdrive/ui/lib/starpilot_state.py | 4 + starpilot/common/starpilot_variables.py | 1 + .../assets/components/tools/troubleshoot.css | 16 +++- .../assets/components/tools/troubleshoot.js | 18 ++++- starpilot/system/the_pond/the_pond.py | 74 ++++++++++++++++++- 6 files changed, 107 insertions(+), 7 deletions(-) diff --git a/selfdrive/ui/layouts/settings/starpilot/vehicle.py b/selfdrive/ui/layouts/settings/starpilot/vehicle.py index af1122bc..d88bfe6d 100644 --- a/selfdrive/ui/layouts/settings/starpilot/vehicle.py +++ b/selfdrive/ui/layouts/settings/starpilot/vehicle.py @@ -489,6 +489,7 @@ class StarPilotVehicleInfoLayout(StarPilotPanel): None, [ tr("Pedal") if starpilot_state.car_state.canUsePedal else "", + tr("SASCM") if starpilot_state.car_state.hasSASCM else "", tr("SDSU") if starpilot_state.car_state.canUseSDSU else "", tr("ZSS") if starpilot_state.car_state.hasZSS else "", ], diff --git a/selfdrive/ui/lib/starpilot_state.py b/selfdrive/ui/lib/starpilot_state.py index 0b907432..98b6f1d8 100644 --- a/selfdrive/ui/lib/starpilot_state.py +++ b/selfdrive/ui/lib/starpilot_state.py @@ -6,6 +6,7 @@ from openpilot.common.params import Params from openpilot.system.hardware import HARDWARE, PC from openpilot.selfdrive.ui.ui_state import ui_state from cereal import car, log, custom, messaging +from opendbc.car.gm.values import GMFlags @dataclass class StarPilotCarState: @@ -25,6 +26,7 @@ class StarPilotCarState: hasBSM: bool = False hasRadar: bool = True hasPedal: bool = False + hasSASCM: bool = False hasSNG: bool = False hasNNFFLog: bool = True hasAutoTune: bool = True @@ -81,6 +83,7 @@ class StarPilotState: fallback_model = "CHEVROLET_BOLT_ACC_2022_2023" 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") @@ -139,6 +142,7 @@ class StarPilotState: self.car_state.hasOpenpilotLongitudinal = bool(self._safe_get(CP, "openpilotLongitudinalControl", False)) self.car_state.hasPCMCruise = bool(self._safe_get(CP, "pcmCruise", False)) self.car_state.hasPedal = bool(self._safe_get(CP, "enableGasInterceptorDEPRECATED", False)) + self.car_state.hasSASCM = car_make == "gm" and bool(self._safe_get(CP, "flags", 0) & GMFlags.SASCM.value) self.car_state.hasRadar = not bool(self._safe_get(CP, "radarUnavailable", False)) self.car_state.hasSDSU = starpilot_toggles.get("has_sdsu", False) self.car_state.hasSNG = bool(self._safe_get(CP, "autoResumeSng", False)) diff --git a/starpilot/common/starpilot_variables.py b/starpilot/common/starpilot_variables.py index 6b75bad9..ea4f3419 100644 --- a/starpilot/common/starpilot_variables.py +++ b/starpilot/common/starpilot_variables.py @@ -451,6 +451,7 @@ class StarPilotVariables: friction = CP.lateralTuning.torque.friction has_bsm = CP.enableBsm toggle.has_cc_long = toggle.car_make == "gm" and bool(CP.flags & GMFlags.CC_LONG.value) + toggle.has_sascm = toggle.car_make == "gm" and bool(CP.flags & GMFlags.SASCM.value) has_nnff = nnff_supported(toggle.car_model) toggle.has_pedal = CP.enableGasInterceptorDEPRECATED has_radar = not CP.radarUnavailable diff --git a/starpilot/system/the_pond/assets/components/tools/troubleshoot.css b/starpilot/system/the_pond/assets/components/tools/troubleshoot.css index bb3a7e62..0bdb14c1 100644 --- a/starpilot/system/the_pond/assets/components/tools/troubleshoot.css +++ b/starpilot/system/the_pond/assets/components/tools/troubleshoot.css @@ -83,6 +83,10 @@ grid-template-columns: 2fr 1fr 1fr; } +.troubleshootHeaderRowLearned { + grid-template-columns: 2fr 1fr 1fr 1.3fr; +} + .troubleshootHeaderRowSnapshot { grid-template-columns: 2fr 2fr; } @@ -95,12 +99,17 @@ grid-template-columns: 2fr 1fr 1fr; } +.troubleshootItemRowLearned { + grid-template-columns: 2fr 1fr 1fr 1.3fr; +} + .troubleshootItemLabel { font-weight: 600; } .troubleshootItemValue, -.troubleshootItemDefault { +.troubleshootItemDefault, +.troubleshootItemLearned { font-family: "Open Sans", sans-serif; word-break: break-word; } @@ -112,6 +121,11 @@ font-size: 0.9rem; } + .troubleshootHeaderRowLearned, + .troubleshootItemRowLearned { + grid-template-columns: 1.3fr 0.95fr 0.95fr 1.2fr; + } + .troubleshootSnapshotRow { grid-template-columns: 1fr; gap: 4px; diff --git a/starpilot/system/the_pond/assets/components/tools/troubleshoot.js b/starpilot/system/the_pond/assets/components/tools/troubleshoot.js index 8562ba58..76e05e64 100644 --- a/starpilot/system/the_pond/assets/components/tools/troubleshoot.js +++ b/starpilot/system/the_pond/assets/components/tools/troubleshoot.js @@ -23,6 +23,12 @@ function formatValue(value) { return text || "(empty)" } +function formatLearnedValue(value) { + if (value === null || value === undefined) return "" + const text = String(value).trim() + return text ? formatValue(value) : "" +} + function buildReportText() { const lines = [] lines.push("StarPilot Troubleshoot Report") @@ -38,7 +44,10 @@ function buildReportText() { lines.push("") lines.push(section.title) for (const item of section.items || []) { - lines.push(`- ${item.label}: ${formatValue(item.value)} (default: ${formatValue(item.defaultValue)})`) + const learnedSuffix = formatLearnedValue(item.learnedValue) + ? `, learned: ${formatLearnedValue(item.learnedValue)}` + : "" + lines.push(`- ${item.label}: ${formatValue(item.value)} (default: ${formatValue(item.defaultValue)}${learnedSuffix})`) } } @@ -132,11 +141,13 @@ function initialize() { function itemRows(section) { const items = Array.isArray(section?.items) ? section.items : [] + const rowClassName = section?.hasLearnedColumn ? "troubleshootItemRow troubleshootItemRowLearned" : "troubleshootItemRow" return items.map((item) => html` -
+
${item.label}
${formatValue(item.value)}
${formatValue(item.defaultValue)}
+ ${section?.hasLearnedColumn ? html`
${formatLearnedValue(item.learnedValue)}
` : ""}
`) } @@ -192,10 +203,11 @@ export function Troubleshoot() { ` : ""}
-
+
Setting Current Default + ${section?.hasLearnedColumn ? html`Learned` : ""}
${itemRows(section)}
diff --git a/starpilot/system/the_pond/the_pond.py b/starpilot/system/the_pond/the_pond.py index d1e72e4c..118c1efe 100644 --- a/starpilot/system/the_pond/the_pond.py +++ b/starpilot/system/the_pond/the_pond.py @@ -26,8 +26,9 @@ import time import traceback from urllib.parse import quote -from cereal import car, messaging +from cereal import car, log, messaging from opendbc.can.parser import CANParser +from opendbc.car.gm.values import GMFlags from opendbc.car.toyota.carcontroller import LOCK_CMD, UNLOCK_CMD from openpilot.common.params import ParamKeyType, Params from openpilot.common.realtime import DT_HW @@ -1956,6 +1957,63 @@ def _resolve_troubleshoot_default_value(key, value_type, default_values): return _coerce_param_value(default_raw_value, safe_type) +def _normalize_live_delay_status(status): + status_text = str(status or "").strip().lower() + if status_text in {"estimated", "unestimated", "invalid"}: + return status_text + + try: + if status == log.LiveDelayData.Status.estimated: + return "estimated" + if status == log.LiveDelayData.Status.unestimated: + return "unestimated" + if status == log.LiveDelayData.Status.invalid: + return "invalid" + except Exception: + pass + + return status_text + +def _get_steer_delay_learned_text(): + live_delay_bytes = _safe_params_get_live_raw("LiveDelay") + if not live_delay_bytes: + return "Unavailable" + + current_cp_bytes = _safe_params_get_live_raw("CarParamsPersistent") + previous_cp_bytes = _safe_params_get_live_raw("CarParamsPrevRoute") + if current_cp_bytes and previous_cp_bytes: + try: + with car.CarParams.from_bytes(current_cp_bytes) as current_cp, car.CarParams.from_bytes(previous_cp_bytes) as previous_cp: + current_fingerprint = str(getattr(current_cp, "carFingerprint", "") or "") + previous_fingerprint = str(getattr(previous_cp, "carFingerprint", "") or "") + if current_fingerprint and previous_fingerprint and current_fingerprint != previous_fingerprint: + return "Unavailable" + except Exception: + pass + + try: + live_delay = messaging.log_from_bytes(live_delay_bytes, log.Event).liveDelay + except Exception: + return "Unavailable" + + estimate = _safe_float(getattr(live_delay, "lateralDelayEstimate", 0.0), 0.0) + cal_perc = int(max(0, min(100, _safe_float(getattr(live_delay, "calPerc", 0), 0)))) + status = _normalize_live_delay_status(getattr(live_delay, "status", "")) + + if status == "estimated": + return f"Complete ({estimate:.2f}s)" + if status == "invalid": + return f"Invalid ({estimate:.2f}s)" + if status == "unestimated": + return f"Learning {cal_perc}% ({estimate:.2f}s)" + + return f"{estimate:.2f}s" + +def _get_troubleshoot_learned_values(): + return { + "SteerDelay": _get_steer_delay_learned_text(), + } + def _get_safety_snapshot_text(): cp_bytes = params.get("CarParamsPersistent") if not cp_bytes: @@ -2026,6 +2084,7 @@ def _get_hardware_snapshot_items(): has_bsm = None has_openpilot_longitudinal = None has_pedal = False + has_sascm = bool(starpilot_toggles.get("has_sascm", False)) has_radar = None has_sdsu = bool(starpilot_toggles.get("has_sdsu", False)) has_sng = None @@ -2044,6 +2103,7 @@ def _get_hardware_snapshot_items(): has_bsm = bool(getattr(cp, "enableBsm", False)) has_openpilot_longitudinal = bool(getattr(cp, "openpilotLongitudinalControl", False)) has_pedal = bool(getattr(cp, "enableGasInterceptorDEPRECATED", False)) + has_sascm = car_make == "gm" and bool(getattr(cp, "flags", 0) & GMFlags.SASCM.value) has_radar = not bool(getattr(cp, "radarUnavailable", False)) has_sdsu = bool(starpilot_toggles.get("has_sdsu", has_sdsu)) has_sng = bool(getattr(cp, "autoResumeSng", False)) @@ -2054,6 +2114,7 @@ def _get_hardware_snapshot_items(): fallback_make = str(starpilot_toggles.get("car_make", "") or "gm") fallback_model = str(starpilot_toggles.get("car_model", "") or "CHEVROLET_BOLT_ACC_2022_2023") has_pedal = bool(starpilot_toggles.get("has_pedal", True)) + has_sascm = bool(starpilot_toggles.get("has_sascm", has_sascm)) has_sdsu = bool(starpilot_toggles.get("has_sdsu", has_sdsu)) has_zss = bool(starpilot_toggles.get("has_zss", has_zss)) is_bolt = fallback_model.startswith("CHEVROLET_BOLT") @@ -2064,6 +2125,7 @@ def _get_hardware_snapshot_items(): elif PC: fallback_model = str(starpilot_toggles.get("car_model", "") or "CHEVROLET_BOLT_ACC_2022_2023") has_pedal = bool(starpilot_toggles.get("has_pedal", True)) + has_sascm = bool(starpilot_toggles.get("has_sascm", has_sascm)) has_sdsu = bool(starpilot_toggles.get("has_sdsu", has_sdsu)) has_zss = bool(starpilot_toggles.get("has_zss", has_zss)) is_bolt = fallback_model.startswith("CHEVROLET_BOLT") @@ -2085,6 +2147,8 @@ def _get_hardware_snapshot_items(): detected = [] if has_pedal: detected.append("comma Pedal") + if has_sascm: + detected.append("SASCM") if has_sdsu: detected.append("SDSU") if has_zss: @@ -2093,6 +2157,7 @@ def _get_hardware_snapshot_items(): return [ {"id": "hardware_detected", "label": "Hardware Detected", "value": ", ".join(detected) if detected else "None", "resettable": False}, {"id": "pedal_detected", "label": "Pedal Detected", "value": _snapshot_bool_text(has_pedal), "resettable": False}, + {"id": "sascm_detected", "label": "SASCM Detected", "value": _snapshot_bool_text(has_sascm), "resettable": False}, {"id": "sdsu_detected", "label": "SDSU Detected", "value": _snapshot_bool_text(has_sdsu), "resettable": False}, {"id": "zss_detected", "label": "ZSS Detected", "value": _snapshot_bool_text(has_zss), "resettable": False}, {"id": "blind_spot_support", "label": "Blind Spot Support", "value": _snapshot_bool_text(has_bsm), "resettable": False}, @@ -2103,7 +2168,7 @@ def _get_hardware_snapshot_items(): {"id": "sng_support", "label": "Stop-and-Go Support", "value": _snapshot_bool_text(has_sng), "resettable": False}, ] -def _build_troubleshoot_section_payload(section_definition, value_types, default_values, layout_metadata): +def _build_troubleshoot_section_payload(section_definition, value_types, default_values, layout_metadata, learned_values): section_keys = [str(key).strip() for key in section_definition.get("keys", []) if str(key).strip()] items = [] @@ -2131,18 +2196,21 @@ def _build_troubleshoot_section_payload(section_definition, value_types, default "label": label, "value": current_value, "defaultValue": default_value, + "learnedValue": learned_values.get(key), }) return { "id": section_definition["id"], "title": section_definition["title"], "resettable": True, + "hasLearnedColumn": any(item.get("learnedValue") not in (None, "") for item in items), "items": items, } def _build_troubleshoot_payload(): _, value_types = _get_param_type_info() default_values = _get_default_param_values() + learned_values = _get_troubleshoot_learned_values() layout_metadata = _get_layout_param_metadata() longitudinal_personality_raw = _safe_params_get("LongitudinalPersonality", encoding="utf-8", default="") or "" @@ -2175,7 +2243,7 @@ def _build_troubleshoot_payload(): ] sections = [ - _build_troubleshoot_section_payload(section_definition, value_types, default_values, layout_metadata) + _build_troubleshoot_section_payload(section_definition, value_types, default_values, layout_metadata, learned_values) for section_definition in _TROUBLESHOOT_SECTION_DEFINITIONS ]