mirror of
https://github.com/sunnypilot/sunnypilot.git
synced 2026-06-09 01:25:11 +08:00
Compare commits
21 Commits
henc
...
visuals-hi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0491242b4a | ||
|
|
37ac33fbcc | ||
|
|
0376660023 | ||
|
|
2e82908c07 | ||
|
|
b71914e006 | ||
|
|
a9d5c9e23a | ||
|
|
c01719bb99 | ||
|
|
1b89608ccc | ||
|
|
53a24655d2 | ||
|
|
c9f92a8c76 | ||
|
|
10b1d673c9 | ||
|
|
7080167daf | ||
|
|
c7a1c70504 | ||
|
|
c6a6caf6ff | ||
|
|
8d49a44f52 | ||
|
|
3434ca9d3e | ||
|
|
e4f8a5edd1 | ||
|
|
1f4f9bd4bd | ||
|
|
455e730c4c | ||
|
|
b243d4e356 | ||
|
|
de0550d47b |
@@ -34,10 +34,10 @@ jobs:
|
||||
echo "tinygrad_ref=$ref" >> $GITHUB_OUTPUT
|
||||
echo "tinygrad_ref is $ref"
|
||||
|
||||
- name: Checkout docs repo (sunnypilot-docs, gh-pages)
|
||||
- name: Checkout docs repo (sunnypilot-models, gh-pages)
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: sunnypilot/sunnypilot-docs
|
||||
repository: sunnypilot/sunnypilot-models
|
||||
ref: gh-pages
|
||||
path: docs
|
||||
ssh-key: ${{ secrets.CI_SUNNYPILOT_DOCS_PRIVATE_KEY }}
|
||||
@@ -202,7 +202,7 @@ jobs:
|
||||
- name: Checkout docs repo
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: sunnypilot/sunnypilot-docs
|
||||
repository: sunnypilot/sunnypilot-models
|
||||
ref: gh-pages
|
||||
path: docs
|
||||
ssh-key: ${{ secrets.CI_SUNNYPILOT_DOCS_PRIVATE_KEY }}
|
||||
|
||||
@@ -119,7 +119,7 @@ jobs:
|
||||
- name: Checkout docs repo
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: sunnypilot/sunnypilot-docs
|
||||
repository: sunnypilot/sunnypilot-models
|
||||
ref: gh-pages
|
||||
path: docs
|
||||
ssh-key: ${{ secrets.CI_SUNNYPILOT_DOCS_PRIVATE_KEY }}
|
||||
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -101,6 +101,8 @@ Pipfile
|
||||
.context/
|
||||
PLAN.md
|
||||
TASK.md
|
||||
CLAUDE.md
|
||||
SKILL.md
|
||||
|
||||
### JetBrains ###
|
||||
!.idea/customTargets.xml
|
||||
|
||||
@@ -54,6 +54,7 @@ inline static std::unordered_map<std::string, ParamKeyAttributes> keys = {
|
||||
{"GsmRoaming", {PERSISTENT | BACKUP, BOOL}},
|
||||
{"HardwareSerial", {PERSISTENT, STRING}},
|
||||
{"HasAcceptedTerms", {PERSISTENT, STRING, "0"}},
|
||||
{"HideCamera", {PERSISTENT | BACKUP, BOOL, "0"}},
|
||||
{"InstallDate", {PERSISTENT, TIME}},
|
||||
{"IsDriverViewEnabled", {CLEAR_ON_MANAGER_START, BOOL}},
|
||||
{"IsEngaged", {PERSISTENT, BOOL}},
|
||||
@@ -172,6 +173,7 @@ inline static std::unordered_map<std::string, ParamKeyAttributes> keys = {
|
||||
{"OnroadScreenOffBrightness", {PERSISTENT | BACKUP, INT, "0"}},
|
||||
{"OnroadScreenOffBrightnessMigrated", {PERSISTENT | BACKUP, STRING, "0.0"}},
|
||||
{"OnroadScreenOffTimer", {PERSISTENT | BACKUP, INT, "15"}},
|
||||
{"OnroadScreenOffTimerMigrated", {PERSISTENT | BACKUP, STRING, "0.0"}},
|
||||
{"OnroadUploads", {PERSISTENT | BACKUP, BOOL, "1"}},
|
||||
{"QuickBootToggle", {PERSISTENT | BACKUP, BOOL, "0"}},
|
||||
{"QuietMode", {PERSISTENT | BACKUP, BOOL, "0"}},
|
||||
|
||||
Submodule opendbc_repo updated: 5269f659d2...96a96b80da
@@ -68,21 +68,20 @@ def flash_panda(panda_serial: str) -> Panda:
|
||||
return panda
|
||||
|
||||
|
||||
def check_panda_support(panda_serials: list[str]) -> bool:
|
||||
unsupported = []
|
||||
def check_panda_support(panda_serials: list[str]) -> list[str]:
|
||||
spi_serials = set(Panda.spi_list())
|
||||
for serial in panda_serials:
|
||||
if serial in spi_serials:
|
||||
return [serial]
|
||||
|
||||
for serial in panda_serials:
|
||||
panda = Panda(serial)
|
||||
hw_type = panda.get_type()
|
||||
is_internal = panda.is_internal()
|
||||
panda.close()
|
||||
if hw_type in Panda.SUPPORTED_DEVICES:
|
||||
return True
|
||||
if is_internal:
|
||||
return [serial]
|
||||
|
||||
unsupported.append((serial, hw_type))
|
||||
|
||||
for serial, hw_type in unsupported:
|
||||
cloudlog.warning(f"Panda {serial} is not supported (hw_type: {hw_type}), skipping...")
|
||||
|
||||
return False
|
||||
return []
|
||||
|
||||
|
||||
def main() -> None:
|
||||
@@ -137,8 +136,9 @@ def main() -> None:
|
||||
# custom flasher for xnor's Rivian Longitudinal Upgrade Kit
|
||||
flash_rivian_long(panda_serials)
|
||||
|
||||
# skip flashing and health check if no supported panda is detected
|
||||
if not check_panda_support(panda_serials):
|
||||
# find the internal supported panda (e.g. skip external Black Panda)
|
||||
panda_serials = check_panda_support(panda_serials)
|
||||
if len(panda_serials) == 0:
|
||||
continue
|
||||
|
||||
# Flash the first panda
|
||||
|
||||
@@ -69,7 +69,6 @@ class SoftwareLayout(Widget):
|
||||
|
||||
# Branch switcher
|
||||
self._branch_btn = button_item(lambda: tr("Target Branch"), lambda: tr("SELECT"), callback=self._on_select_branch)
|
||||
self._branch_btn.set_visible(not ui_state.params.get_bool("IsTestedBranch"))
|
||||
self._branch_btn.action_item.set_value(ui_state.params.get("UpdaterTargetBranch") or "")
|
||||
self._branch_dialog: MultiOptionDialog | None = None
|
||||
|
||||
|
||||
@@ -231,7 +231,7 @@ class AlertRenderer(Widget, SpeedLimitAlertRenderer):
|
||||
self._alpha_filter.update(0 if alert is None else 1)
|
||||
|
||||
if gui_app.sunnypilot_ui():
|
||||
ui_state.onroad_brightness_handle_alerts(ui_state.started, alert)
|
||||
ui_state.onroad_brightness_handle_alerts(ui_state, alert)
|
||||
|
||||
if alert is None:
|
||||
# If still animating out, keep the previous alert
|
||||
|
||||
@@ -212,6 +212,8 @@ class AugmentedRoadView(CameraView):
|
||||
|
||||
# Render the base camera view
|
||||
super()._render(self._content_rect)
|
||||
if ui_state.hide_camera:
|
||||
rl.draw_rectangle_rec(self._content_rect, rl.BLACK)
|
||||
|
||||
# Draw all UI overlays
|
||||
self._model_renderer.render(self._content_rect)
|
||||
|
||||
@@ -118,7 +118,7 @@ class AlertRenderer(Widget):
|
||||
alert = self.get_alert(ui_state.sm)
|
||||
|
||||
if gui_app.sunnypilot_ui():
|
||||
ui_state.onroad_brightness_handle_alerts(ui_state.started, alert)
|
||||
ui_state.onroad_brightness_handle_alerts(ui_state, alert)
|
||||
|
||||
if not alert:
|
||||
return
|
||||
|
||||
@@ -91,6 +91,8 @@ class AugmentedRoadView(CameraView, AugmentedRoadViewSP):
|
||||
|
||||
# Render the base camera view
|
||||
super()._render(rect)
|
||||
if ui_state.hide_camera:
|
||||
rl.draw_rectangle_rec(self._content_rect, rl.BLACK)
|
||||
|
||||
# Draw all UI overlays
|
||||
self.model_renderer.render(self._content_rect)
|
||||
|
||||
@@ -12,8 +12,7 @@ from openpilot.system.ui.widgets import Widget
|
||||
from openpilot.system.ui.lib.multilang import tr
|
||||
from openpilot.system.ui.widgets.scroller_tici import Scroller
|
||||
from openpilot.system.ui.sunnypilot.widgets.list_view import option_item_sp, ToggleActionSP
|
||||
|
||||
ONROAD_BRIGHTNESS_TIMER_VALUES = {0: 15, 1: 30, **{i: (i - 1) * 60 for i in range(2, 12)}}
|
||||
from openpilot.sunnypilot.system.params_migration import ONROAD_BRIGHTNESS_TIMER_VALUES
|
||||
|
||||
|
||||
class OnroadBrightness(IntEnum):
|
||||
@@ -46,7 +45,7 @@ class DisplayLayout(Widget):
|
||||
title=lambda: tr("Onroad Brightness Delay"),
|
||||
description="",
|
||||
min_value=0,
|
||||
max_value=11,
|
||||
max_value=15,
|
||||
value_change_step=1,
|
||||
value_map=ONROAD_BRIGHTNESS_TIMER_VALUES,
|
||||
label_callback=lambda value: f"{value} s" if value < 60 else f"{int(value/60)} m",
|
||||
@@ -92,7 +91,11 @@ class DisplayLayout(Widget):
|
||||
if isinstance(_item.action_item, ToggleActionSP) and _item.action_item.toggle.param_key is not None:
|
||||
_item.action_item.set_state(self._params.get_bool(_item.action_item.toggle.param_key))
|
||||
elif isinstance(_item.action_item, OptionControlSP) and _item.action_item.param_key is not None:
|
||||
_item.action_item.set_value(self._params.get(_item.action_item.param_key, return_default=True))
|
||||
raw_value = self._params.get(_item.action_item.param_key, return_default=True)
|
||||
if _item.action_item.value_map:
|
||||
reverse_map = {v: k for k, v in _item.action_item.value_map.items()}
|
||||
raw_value = reverse_map.get(raw_value, _item.action_item.current_value)
|
||||
_item.action_item.set_value(raw_value)
|
||||
|
||||
brightness_val = self._params.get("OnroadScreenOffBrightness", return_default=True)
|
||||
self._onroad_brightness_timer.action_item.set_enabled(brightness_val not in (OnroadBrightness.AUTO, OnroadBrightness.AUTO_DARK))
|
||||
|
||||
@@ -93,6 +93,11 @@ class VisualsLayout(Widget):
|
||||
"This displays what the car is currently doing, not what the planner is requesting."),
|
||||
None,
|
||||
),
|
||||
"HideCamera": (
|
||||
lambda: tr("Hide Camera"),
|
||||
tr("Hide the camera live view from the driving screen."),
|
||||
None,
|
||||
),
|
||||
}
|
||||
self._toggles = {}
|
||||
for param, (title, desc, callback) in self._toggle_defs.items():
|
||||
|
||||
@@ -49,8 +49,11 @@ class UIStateSP:
|
||||
else:
|
||||
self.sunnylink_state.stop()
|
||||
|
||||
def onroad_brightness_handle_alerts(self, started: bool, alert):
|
||||
has_alert = started and self.onroad_brightness != OnroadBrightness.AUTO and alert is not None
|
||||
def onroad_brightness_handle_alerts(self, _ui_state, alert):
|
||||
if _ui_state.sm.recv_frame["carState"] < _ui_state.started_frame:
|
||||
return
|
||||
|
||||
has_alert = _ui_state.started and self.onroad_brightness != OnroadBrightness.AUTO and alert is not None
|
||||
|
||||
self.update_onroad_brightness(has_alert)
|
||||
if has_alert:
|
||||
@@ -130,6 +133,7 @@ class UIStateSP:
|
||||
self.chevron_metrics = self.params.get("ChevronInfo")
|
||||
self.custom_interactive_timeout = self.params.get("InteractivityTimeout", return_default=True)
|
||||
self.developer_ui = self.params.get("DevUIInfo")
|
||||
self.hide_camera = self.params.get_bool("HideCamera")
|
||||
self.hide_v_ego_ui = self.params.get_bool("HideVEgoUI")
|
||||
self.onroad_brightness = int(float(self.params.get("OnroadScreenOffBrightness", return_default=True)))
|
||||
self.onroad_brightness_timer_param = self.params.get("OnroadScreenOffTimer", return_default=True)
|
||||
|
||||
@@ -116,7 +116,7 @@ class ModelCache:
|
||||
|
||||
class ModelFetcher:
|
||||
"""Handles fetching and caching of model data from remote source"""
|
||||
MODEL_URL = "https://raw.githubusercontent.com/sunnypilot/sunnypilot-docs/refs/heads/gh-pages/docs/driving_models_v15.json"
|
||||
MODEL_URL = "https://raw.githubusercontent.com/sunnypilot/sunnypilot-models/refs/heads/gh-pages/docs/driving_models_v15.json"
|
||||
|
||||
def __init__(self, params: Params):
|
||||
self.params = params
|
||||
|
||||
@@ -84,7 +84,11 @@ def flash_rivian_long(panda_serials: list[str]) -> None:
|
||||
cloudlog.info("Not a Rivian, skipping longitudinal upgrade...")
|
||||
return
|
||||
|
||||
# only check USB connected pandas, internal panda uses SPI and is never an external panda
|
||||
usb_serials = set(Panda.usb_list())
|
||||
for serial in panda_serials:
|
||||
if serial not in usb_serials:
|
||||
continue
|
||||
panda = Panda(serial)
|
||||
# only flash external black pandas (HW_TYPE_BLACK = 0x03)
|
||||
if panda.get_type() == b'\x03' and not panda.is_internal():
|
||||
|
||||
@@ -370,6 +370,10 @@
|
||||
"title": "Has Accepted sunnypilot Terms",
|
||||
"description": ""
|
||||
},
|
||||
"HideCamera": {
|
||||
"title": "Hide Camera",
|
||||
"description": "Hide the camera live view from the driving screen."
|
||||
},
|
||||
"HideVEgoUI": {
|
||||
"title": "[TIZI/TICI only] Speedometer: Hide from Onroad Screen",
|
||||
"description": "When enabled, the speedometer on the onroad screen is not displayed."
|
||||
@@ -941,6 +945,22 @@
|
||||
"title": "Onroad Brightness Delay",
|
||||
"description": "",
|
||||
"options": [
|
||||
{
|
||||
"value": 3,
|
||||
"label": "3s"
|
||||
},
|
||||
{
|
||||
"value": 5,
|
||||
"label": "5s"
|
||||
},
|
||||
{
|
||||
"value": 7,
|
||||
"label": "7s"
|
||||
},
|
||||
{
|
||||
"value": 10,
|
||||
"label": "10s"
|
||||
},
|
||||
{
|
||||
"value": 15,
|
||||
"label": "15s"
|
||||
@@ -991,6 +1011,10 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"OnroadScreenOffTimerMigrated": {
|
||||
"title": "Onroad Brightness Delay Migration Version",
|
||||
"description": "This param is to track whether OnroadScreenOffTimer needs to be migrated."
|
||||
},
|
||||
"OnroadUploads": {
|
||||
"title": "Onroad Uploads",
|
||||
"description": ""
|
||||
@@ -1290,7 +1314,7 @@
|
||||
"min": 0.1,
|
||||
"max": 5.0,
|
||||
"step": 0.1,
|
||||
"unit": "m/s²"
|
||||
"unit": "m/s\u00b2"
|
||||
},
|
||||
"ToyotaEnforceStockLongitudinal": {
|
||||
"title": "Toyota: Enforce Factory Longitudinal Control",
|
||||
|
||||
@@ -10,6 +10,7 @@ import os
|
||||
|
||||
from openpilot.common.basedir import BASEDIR
|
||||
from openpilot.common.params import Params
|
||||
from openpilot.sunnypilot.system.params_migration import ONROAD_BRIGHTNESS_TIMER_VALUES
|
||||
|
||||
METADATA_PATH = os.path.join(os.path.dirname(__file__), "../params_metadata.json")
|
||||
TORQUE_VERSIONS_JSON = os.path.join(BASEDIR, "sunnypilot", "selfdrive", "controls", "lib", "latcontrol_torque_versions.json")
|
||||
@@ -56,6 +57,9 @@ def main():
|
||||
# update onroad screen brightness params
|
||||
update_onroad_brightness_param()
|
||||
|
||||
# update onroad screen brightness timer params
|
||||
update_onroad_brightness_timer_param()
|
||||
|
||||
# update torque versions param
|
||||
update_torque_versions_param()
|
||||
|
||||
@@ -81,6 +85,24 @@ def update_onroad_brightness_param():
|
||||
print(f"Failed to update OnroadScreenOffBrightness versions in params_metadata.json: {e}")
|
||||
|
||||
|
||||
def update_onroad_brightness_timer_param():
|
||||
try:
|
||||
with open(METADATA_PATH) as f:
|
||||
params_metadata = json.load(f)
|
||||
if "OnroadScreenOffTimer" in params_metadata:
|
||||
options = []
|
||||
for _index, seconds in sorted(ONROAD_BRIGHTNESS_TIMER_VALUES.items()):
|
||||
label = f"{seconds}s" if seconds < 60 else f"{seconds // 60}m"
|
||||
options.append({"value": seconds, "label": label})
|
||||
params_metadata["OnroadScreenOffTimer"]["options"] = options
|
||||
with open(METADATA_PATH, 'w') as f:
|
||||
json.dump(params_metadata, f, indent=2)
|
||||
f.write('\n')
|
||||
print(f"Updated OnroadScreenOffTimer options in params_metadata.json with {len(options)} options.")
|
||||
except Exception as e:
|
||||
print(f"Failed to update OnroadScreenOffTimer options in params_metadata.json: {e}")
|
||||
|
||||
|
||||
def update_torque_versions_param():
|
||||
with open(TORQUE_VERSIONS_JSON) as f:
|
||||
current_versions = json.load(f)
|
||||
|
||||
@@ -7,13 +7,18 @@ See the LICENSE.md file in the root directory for more details.
|
||||
from openpilot.common.swaglog import cloudlog
|
||||
|
||||
ONROAD_BRIGHTNESS_MIGRATION_VERSION: str = "1.0"
|
||||
ONROAD_BRIGHTNESS_TIMER_MIGRATION_VERSION: str = "1.0"
|
||||
|
||||
# index → seconds mapping for OnroadScreenOffTimer (SSoT)
|
||||
ONROAD_BRIGHTNESS_TIMER_VALUES = {0: 3, 1: 5, 2: 7, 3: 10, 4: 15, 5: 30, **{i: (i - 5) * 60 for i in range(6, 16)}}
|
||||
VALID_TIMER_VALUES = set(ONROAD_BRIGHTNESS_TIMER_VALUES.values())
|
||||
|
||||
|
||||
def run_migration(_params):
|
||||
# migrate OnroadScreenOffBrightness
|
||||
if _params.get("OnroadScreenOffBrightnessMigrated") != ONROAD_BRIGHTNESS_MIGRATION_VERSION:
|
||||
try:
|
||||
val = _params.get("OnroadScreenOffBrightness")
|
||||
val = _params.get("OnroadScreenOffBrightness", return_default=True)
|
||||
if val >= 2: # old: 5%, new: Screen Off
|
||||
new_val = val + 1
|
||||
_params.put("OnroadScreenOffBrightness", new_val)
|
||||
@@ -25,3 +30,18 @@ def run_migration(_params):
|
||||
cloudlog.info(log_str + f" Setting OnroadScreenOffBrightnessMigrated to {ONROAD_BRIGHTNESS_MIGRATION_VERSION}")
|
||||
except Exception as e:
|
||||
cloudlog.exception(f"Error migrating OnroadScreenOffBrightness: {e}")
|
||||
|
||||
# migrate OnroadScreenOffTimer
|
||||
if _params.get("OnroadScreenOffTimerMigrated") != ONROAD_BRIGHTNESS_TIMER_MIGRATION_VERSION:
|
||||
try:
|
||||
val = _params.get("OnroadScreenOffTimer", return_default=True)
|
||||
if val not in VALID_TIMER_VALUES:
|
||||
_params.put("OnroadScreenOffTimer", 15)
|
||||
log_str = f"Successfully migrated OnroadScreenOffTimer from {val} to 15 (default)."
|
||||
else:
|
||||
log_str = "Migration not required for OnroadScreenOffTimer."
|
||||
|
||||
_params.put("OnroadScreenOffTimerMigrated", ONROAD_BRIGHTNESS_TIMER_MIGRATION_VERSION)
|
||||
cloudlog.info(log_str + f" Setting OnroadScreenOffTimerMigrated to {ONROAD_BRIGHTNESS_TIMER_MIGRATION_VERSION}")
|
||||
except Exception as e:
|
||||
cloudlog.exception(f"Error migrating OnroadScreenOffTimer: {e}")
|
||||
|
||||
@@ -51,7 +51,8 @@ def manager_init() -> None:
|
||||
if params.get_bool("RecordFrontLock"):
|
||||
params.put_bool("RecordFront", True)
|
||||
|
||||
run_migration(params)
|
||||
if not PC:
|
||||
run_migration(params)
|
||||
|
||||
# set unset params to their default value
|
||||
for k in params.all_keys():
|
||||
|
||||
Reference in New Issue
Block a user