mirror of
https://github.com/sunnypilot/sunnypilot.git
synced 2026-11-12 20:03:43 +08:00
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| cbd0c6721a | |||
| 43dac61e64 | |||
| 57245fbb29 | |||
| a88abfda2f | |||
| 956bbcf3c0 |
@@ -141,6 +141,7 @@ inline static std::unordered_map<std::string, ParamKeyAttributes> keys = {
|
||||
{"BlinkerLateralReengageDelay", {PERSISTENT | BACKUP, INT, "0"}}, // seconds
|
||||
{"BlinkerMinLateralControlSpeed", {PERSISTENT | BACKUP, INT, "20"}}, // MPH or km/h
|
||||
{"BlinkerPauseLateralControl", {PERSISTENT | BACKUP, INT, "0"}},
|
||||
{"BranchEolAck", {CLEAR_ON_MANAGER_START | CLEAR_ON_OFFROAD_TRANSITION, BOOL}},
|
||||
{"Brightness", {PERSISTENT | BACKUP, INT, "0"}},
|
||||
{"CarList", {PERSISTENT, JSON}},
|
||||
{"CarParamsSP", {CLEAR_ON_MANAGER_START | CLEAR_ON_ONROAD_TRANSITION, BYTES}},
|
||||
@@ -169,6 +170,7 @@ inline static std::unordered_map<std::string, ParamKeyAttributes> keys = {
|
||||
{"MaxTimeOffroad", {PERSISTENT | BACKUP, INT, "1800"}},
|
||||
{"ModelRunnerTypeCache", {CLEAR_ON_ONROAD_TRANSITION, INT}},
|
||||
{"OffroadMode", {CLEAR_ON_MANAGER_START, BOOL}},
|
||||
{"Offroad_BranchEol", {CLEAR_ON_MANAGER_START, JSON}},
|
||||
{"Offroad_TiciSupport", {CLEAR_ON_MANAGER_START, JSON}},
|
||||
{"OnroadScreenOffBrightness", {PERSISTENT | BACKUP, INT, "0"}},
|
||||
{"OnroadScreenOffBrightnessMigrated", {PERSISTENT | BACKUP, STRING, "0.0"}},
|
||||
|
||||
+1
-1
Submodule opendbc_repo updated: df807f8be3...1c2d90dfd2
@@ -1,4 +1,8 @@
|
||||
{
|
||||
"Offroad_BranchEol": {
|
||||
"text": "This branch will not receive any more functional updates. Switch to hkg-angle-steering-2025. See the angle steering topic on community.sunnypilot.ai for what you need to do.",
|
||||
"severity": 1
|
||||
},
|
||||
"Offroad_TemperatureTooHigh": {
|
||||
"text": "Device temperature too high. System cooling down before starting. Current internal component temperature: %1",
|
||||
"severity": 0
|
||||
|
||||
@@ -9,6 +9,7 @@ from openpilot.selfdrive.ui.onroad.augmented_road_view import AugmentedRoadView
|
||||
from openpilot.selfdrive.ui.ui_state import device, ui_state
|
||||
from openpilot.system.ui.widgets import Widget
|
||||
from openpilot.selfdrive.ui.layouts.onboarding import OnboardingWindow
|
||||
from openpilot.selfdrive.ui.sunnypilot.layouts.branch_eol import BranchEolGate, BranchEolNotice
|
||||
|
||||
if gui_app.sunnypilot_ui():
|
||||
from openpilot.selfdrive.ui.sunnypilot.layouts.settings.settings import SettingsLayoutSP as SettingsLayout
|
||||
@@ -46,6 +47,8 @@ class MainLayout(Widget):
|
||||
if not self._onboarding_window.completed:
|
||||
gui_app.push_widget(self._onboarding_window)
|
||||
|
||||
self._branch_eol = BranchEolGate(self, BranchEolNotice)
|
||||
|
||||
def _render(self, _):
|
||||
self._handle_onroad_transition()
|
||||
self._render_main_content()
|
||||
|
||||
@@ -6,6 +6,8 @@ from openpilot.selfdrive.ui.mici.layouts.offroad_alerts import MiciOffroadAlerts
|
||||
from openpilot.selfdrive.ui.mici.onroad.augmented_road_view import AugmentedRoadView
|
||||
from openpilot.selfdrive.ui.ui_state import device, ui_state
|
||||
from openpilot.selfdrive.ui.mici.layouts.onboarding import OnboardingWindow
|
||||
from openpilot.selfdrive.ui.sunnypilot.layouts.branch_eol import BranchEolGate
|
||||
from openpilot.selfdrive.ui.sunnypilot.mici.layouts.branch_eol import MiciBranchEolNotice
|
||||
from openpilot.system.ui.widgets import Widget
|
||||
from openpilot.system.ui.widgets.scroller import Scroller
|
||||
from openpilot.system.ui.lib.application import gui_app
|
||||
@@ -59,6 +61,8 @@ class MiciMainLayout(Scroller):
|
||||
if not self._onboarding_window.completed:
|
||||
gui_app.push_widget(self._onboarding_window)
|
||||
|
||||
self._branch_eol = BranchEolGate(self, MiciBranchEolNotice)
|
||||
|
||||
def _setup_callbacks(self):
|
||||
self._home_layout.set_callbacks(
|
||||
on_settings=lambda: gui_app.push_widget(self._settings_layout),
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
"""
|
||||
Copyright (c) 2021-, sunnypilot, and a number of other contributors.
|
||||
|
||||
This file is part of sunnypilot and is licensed under the MIT License.
|
||||
See the LICENSE.md file in the root directory for more details.
|
||||
"""
|
||||
from collections.abc import Callable
|
||||
|
||||
import numpy as np
|
||||
import pyray as rl
|
||||
import qrcode
|
||||
from openpilot.selfdrive.ui.ui_state import ui_state
|
||||
from openpilot.system.ui.lib.application import FontWeight, gui_app
|
||||
from openpilot.system.ui.lib.multilang import tr
|
||||
from openpilot.system.ui.widgets import Widget
|
||||
from openpilot.system.ui.widgets.button import Button, ButtonStyle
|
||||
from openpilot.system.ui.widgets.label import Label
|
||||
|
||||
BRANCH_EOL_URL = "https://community.sunnypilot.ai/t/support-for-newer-vehicles-equipped-with-angle-steering-lfa2/22/751?u=sunnyhaibin"
|
||||
BRANCH_EOL_TEXT = "hkg-angle-steering-2025-hda1 will not receive any more functional updates. Switch to hkg-angle-steering-2025."
|
||||
|
||||
|
||||
class BranchEolGate:
|
||||
# The ack param clears on boot and on every offroad transition, so the notice is shown again after each drive.
|
||||
def __init__(self, main: Widget, notice_cls: Callable[[Callable[[], None]], Widget]):
|
||||
self._main = main
|
||||
self._notice = notice_cls(self._on_ack)
|
||||
self._acked = False
|
||||
gui_app.add_nav_stack_tick(self._tick)
|
||||
|
||||
def _tick(self):
|
||||
if ui_state.started:
|
||||
self._acked = False
|
||||
elif not self._acked and gui_app.get_active_widget() is self._main:
|
||||
gui_app.push_widget(self._notice)
|
||||
|
||||
def _on_ack(self):
|
||||
self._acked = True
|
||||
ui_state.params.put_bool("BranchEolAck", True)
|
||||
gui_app.pop_widgets_to(self._main, instant=True)
|
||||
|
||||
|
||||
class BranchEolNotice(Widget):
|
||||
def __init__(self, on_ack: Callable[[], None]):
|
||||
super().__init__()
|
||||
self._title = Label(tr("This branch is no longer updated"), font_size=75, font_weight=FontWeight.BOLD,
|
||||
text_alignment=rl.GuiTextAlignment.TEXT_ALIGN_LEFT,
|
||||
text_alignment_vertical=rl.GuiTextAlignmentVertical.TEXT_ALIGN_TOP)
|
||||
self._desc = Label(tr(BRANCH_EOL_TEXT + "\n\nScan the QR code to see what you need to do."),
|
||||
font_size=55, font_weight=FontWeight.MEDIUM,
|
||||
text_alignment=rl.GuiTextAlignment.TEXT_ALIGN_LEFT,
|
||||
text_alignment_vertical=rl.GuiTextAlignmentVertical.TEXT_ALIGN_TOP)
|
||||
self._ack_btn = Button(tr("I understand"), button_style=ButtonStyle.PRIMARY, click_callback=on_ack)
|
||||
|
||||
qr = qrcode.QRCode(error_correction=qrcode.constants.ERROR_CORRECT_L, box_size=10, border=4)
|
||||
qr.add_data(BRANCH_EOL_URL)
|
||||
qr.make(fit=True)
|
||||
pil_img = qr.make_image(fill_color="black", back_color="white").convert('RGBA')
|
||||
img_array = np.array(pil_img, dtype=np.uint8)
|
||||
rl_image = rl.Image()
|
||||
rl_image.data = rl.ffi.cast("void *", img_array.ctypes.data)
|
||||
rl_image.width = pil_img.width
|
||||
rl_image.height = pil_img.height
|
||||
rl_image.mipmaps = 1
|
||||
rl_image.format = rl.PixelFormat.PIXELFORMAT_UNCOMPRESSED_R8G8B8A8
|
||||
self._qr_texture = rl.load_texture_from_image(rl_image)
|
||||
|
||||
def _render(self, rect: rl.Rectangle):
|
||||
rl.draw_rectangle_rec(rect, rl.BLACK)
|
||||
|
||||
qr_size = 560
|
||||
qr_x = rect.x + rect.width - qr_size - 90
|
||||
text_x = rect.x + 90
|
||||
text_w = qr_x - text_x - 60
|
||||
self._title.render(rl.Rectangle(text_x, rect.y + 90, text_w, 200))
|
||||
self._desc.render(rl.Rectangle(text_x, rect.y + 300, text_w, 450))
|
||||
|
||||
src = rl.Rectangle(0, 0, self._qr_texture.width, self._qr_texture.height)
|
||||
rl.draw_texture_pro(self._qr_texture, src, rl.Rectangle(qr_x, rect.y + 90, qr_size, qr_size), rl.Vector2(0, 0), 0, rl.WHITE)
|
||||
|
||||
self._ack_btn.render(rl.Rectangle(rect.x + 45, rect.y + rect.height - 160 - 45, rect.width - 90, 160))
|
||||
|
||||
def __del__(self):
|
||||
if self._qr_texture.id != 0:
|
||||
rl.unload_texture(self._qr_texture)
|
||||
@@ -0,0 +1,33 @@
|
||||
"""
|
||||
Copyright (c) 2021-, sunnypilot, and a number of other contributors.
|
||||
|
||||
This file is part of sunnypilot and is licensed under the MIT License.
|
||||
See the LICENSE.md file in the root directory for more details.
|
||||
"""
|
||||
from collections.abc import Callable
|
||||
|
||||
import pyray as rl
|
||||
from openpilot.selfdrive.ui.mici.layouts.onboarding import QRCodeWidget
|
||||
from openpilot.selfdrive.ui.mici.widgets.dialog import BigConfirmationCircleButton
|
||||
from openpilot.selfdrive.ui.sunnypilot.layouts.branch_eol import BRANCH_EOL_URL
|
||||
from openpilot.system.ui.lib.application import gui_app
|
||||
from openpilot.system.ui.mici_setup import GreyBigButton
|
||||
from openpilot.system.ui.widgets.scroller import Scroller
|
||||
|
||||
|
||||
class MiciBranchEolNotice(Scroller):
|
||||
def __init__(self, on_ack: Callable[[], None]):
|
||||
super().__init__()
|
||||
self._scroller.add_widgets([
|
||||
GreyBigButton("no longer\nupdated", "scroll to continue",
|
||||
gui_app.texture("icons_mici/setup/green_info.png", 64, 64)),
|
||||
GreyBigButton("", "This branch will not receive any more functional updates."),
|
||||
GreyBigButton("switch to", "hkg-angle-steering-2025"),
|
||||
GreyBigButton("scan the QR code", "to see what to do"),
|
||||
QRCodeWidget(BRANCH_EOL_URL),
|
||||
BigConfirmationCircleButton("I\nunderstand", gui_app.texture("icons_mici/setup/driver_monitoring/dm_check.png", 64, 64), on_ack),
|
||||
])
|
||||
|
||||
def _render(self, _):
|
||||
rl.draw_rectangle_rec(self._rect, rl.BLACK)
|
||||
super()._render(_)
|
||||
@@ -210,6 +210,7 @@ def hardware_thread(end_event, hw_queue) -> None:
|
||||
thermal_config = HARDWARE.get_thermal_config()
|
||||
|
||||
fan_controller = FanController(int(1./DT_HW))
|
||||
set_offroad_alert("Offroad_BranchEol", True)
|
||||
|
||||
while not end_event.is_set():
|
||||
sm.update(PANDA_STATES_TIMEOUT)
|
||||
@@ -301,6 +302,7 @@ def hardware_thread(end_event, hw_queue) -> None:
|
||||
|
||||
startup_conditions["up_to_date"] = params.get("Offroad_ConnectivityNeeded") is None or params.get_bool("DisableUpdates") or params.get_bool("SnoozeUpdate")
|
||||
startup_conditions["no_excessive_actuation"] = params.get("Offroad_ExcessiveActuation") is None
|
||||
startup_conditions["branch_eol_ack"] = params.get_bool("BranchEolAck")
|
||||
startup_conditions["not_uninstalling"] = not params.get_bool("DoUninstall")
|
||||
startup_conditions["accepted_terms"] = params.get("HasAcceptedTerms") == terms_version
|
||||
startup_conditions["accepted_terms_sp"] = params.get("HasAcceptedTermsSP") == terms_version_sp
|
||||
|
||||
Reference in New Issue
Block a user