eGPU Temp Overlay MICI (#25)

* eGPU temperature Mici UI

* positioning, state of display overlay, transparency, no dynamic on/off
This commit is contained in:
infiniteCable2
2026-08-28 21:53:35 +02:00
committed by GitHub
parent d51b23665e
commit 0f11b3a9b4
5 changed files with 99 additions and 3 deletions
+1
View File
@@ -151,6 +151,7 @@ inline static std::unordered_map<std::string, ParamKeyAttributes> keys = {
{"ForceRHDForBSM", {PERSISTENT, BOOL}},
{"DisableCarSteerAlerts", {PERSISTENT, BOOL}},
{"ShowAccelBar", {PERSISTENT, BOOL}},
{"ICShowEgpuTemperatures", {PERSISTENT, BOOL}},
{"LiveCurvatureParameters", {PERSISTENT | DONT_LOG, BYTES}},
// --- sunnypilot params --- //
@@ -22,6 +22,7 @@ class ICTogglesLayoutMici(NavScroller):
enable_dark_mode = BigParamControl("Dark Mode", "DarkMode")
enable_onroad_screen_timer = BigParamControl("Onroad Screen Timeout", "DisableScreenTimer")
enable_accel_bar = BigParamControl("Enable Accel Bar", "ShowAccelBar")
show_egpu_temperatures = BigParamControl("Show eGPU Temperatures", "ICShowEgpuTemperatures")
enable_curvatured = BigParamControl("Enable Dynamic Steering Learner", "EnableCurvatureD")
show_curvatured_graph = BigParamControl("Show Dynamic Steering Learner Graph", "ShowDynamicSteeringLearnerGraph")
@@ -42,6 +43,7 @@ class ICTogglesLayoutMici(NavScroller):
enable_dark_mode,
enable_onroad_screen_timer,
enable_accel_bar,
show_egpu_temperatures,
enable_curvatured,
show_curvatured_graph,
])
@@ -60,6 +62,7 @@ class ICTogglesLayoutMici(NavScroller):
("DarkMode", enable_dark_mode),
("DisableScreenTimer", enable_onroad_screen_timer),
("ShowAccelBar", enable_accel_bar),
("ICShowEgpuTemperatures", show_egpu_temperatures),
("EnableCurvatureD", enable_curvatured),
("ShowDynamicSteeringLearnerGraph", show_curvatured_graph),
)
@@ -7,6 +7,7 @@ from openpilot.selfdrive.ui.ui_state import ui_state, UIStatus
from openpilot.selfdrive.ui.mici.onroad import SIDE_PANEL_WIDTH
from openpilot.selfdrive.ui.mici.onroad.alert_renderer import AlertRenderer
from openpilot.selfdrive.ui.mici.onroad.driver_state import DriverStateRenderer
from openpilot.selfdrive.ui.mici.onroad.egpu_temperature_overlay import EgpuTemperatureOverlay
from openpilot.selfdrive.ui.mici.onroad.hud_renderer import HudRenderer
from openpilot.selfdrive.ui.mici.onroad.model_renderer import ModelRenderer
from openpilot.selfdrive.ui.mici.onroad.confidence_ball import ConfidenceBall
@@ -152,6 +153,7 @@ class AugmentedRoadView(CameraView):
self._bookmark_icon = BookmarkIcon(bookmark_callback)
self._model_renderer = ModelRenderer()
self._egpu_temperature_overlay = EgpuTemperatureOverlay()
self._hud_renderer = HudRenderer()
self._alert_renderer = AlertRenderer()
self._driver_state_renderer = DriverStateRenderer()
@@ -221,6 +223,9 @@ class AugmentedRoadView(CameraView):
# Fade out bottom of overlays for looks
rl.draw_texture_ex(self._fade_texture, rl.Vector2(self._content_rect.x, self._content_rect.y), 0.0, 1.0, rl.WHITE)
# Render custom data overlays before alerts and the HUD so safety-critical elements stay on top.
self._egpu_temperature_overlay.render(self._content_rect)
alert_to_render, not_animating_out = self._alert_renderer.will_render()
# Hide DMoji when disengaged unless AlwaysOnDM is enabled
@@ -0,0 +1,84 @@
import pyray as rl
from openpilot.selfdrive.ui.mici.onroad.dynamic_steering_learner_graph import CONFIG as STEERING_GRAPH_CONFIG
from openpilot.selfdrive.ui.ui_state import ui_state, UIStatus
from openpilot.system.ui.lib.application import FontWeight, gui_app
from openpilot.system.ui.lib.text_measure import measure_text_cached
from openpilot.system.ui.widgets import Widget
class EgpuTemperatureOverlay(Widget):
PANEL_WIDTH = 145
PANEL_HEIGHT = 86
GAP_TO_STEERING_GRAPH = 8
HORIZONTAL_PADDING = 12
BACKGROUND_ALPHA = 108
TITLE_FONT_SIZE = 20
ROW_FONT_SIZE = 18
def __init__(self):
super().__init__()
self._font_title = gui_app.font(FontWeight.SEMI_BOLD)
self._font_label = gui_app.font(FontWeight.MEDIUM)
self._font_value = gui_app.font(FontWeight.SEMI_BOLD)
self._core_temp: float | None = None
self._vram_temp: float | None = None
self._available = False
self._shown_this_drive = False
self._started_frame = -1
def _update_state(self) -> None:
sm = ui_state.sm
if ui_state.started_frame != self._started_frame:
self._started_frame = ui_state.started_frame
self._shown_this_drive = False
self._core_temp = None
self._vram_temp = None
self._available = (sm.seen["chestnutState"] and sm.alive["chestnutState"] and sm.valid["chestnutState"] and
sm.recv_frame["chestnutState"] >= ui_state.started_frame)
if self._available and (sm.updated["chestnutState"] or self._core_temp is None or self._vram_temp is None):
self._core_temp = float(sm["chestnutState"].tempC)
self._vram_temp = float(sm["chestnutState"].memoryTempC)
if self._available and ui_state.status != UIStatus.DISENGAGED:
self._shown_this_drive = True
@staticmethod
def _format_temperature(temperature: float | None) -> str:
return "" if temperature is None else f"{temperature:.0f}°C"
def _draw_row(self, panel: rl.Rectangle, y: float, label: str, value: str) -> None:
label_pos = rl.Vector2(panel.x + self.HORIZONTAL_PADDING, y)
rl.draw_text_ex(self._font_label, label, label_pos, self.ROW_FONT_SIZE, 0, rl.Color(205, 205, 205, 255))
value_size = measure_text_cached(self._font_value, value, self.ROW_FONT_SIZE)
value_pos = rl.Vector2(panel.x + panel.width - self.HORIZONTAL_PADDING - value_size.x, y)
value_color = rl.WHITE if self._available else rl.Color(166, 166, 166, 255)
rl.draw_text_ex(self._font_value, value, value_pos, self.ROW_FONT_SIZE, 0, value_color)
def _render(self, rect: rl.Rectangle) -> None:
if not ui_state.ic_show_egpu_temperatures or not ui_state.usbgpu or not self._shown_this_drive:
return
graph_top = rect.y + rect.height * STEERING_GRAPH_CONFIG.zero_line_screen_y_frac - STEERING_GRAPH_CONFIG.height * 0.5
panel = rl.Rectangle(
rect.x + rect.width - STEERING_GRAPH_CONFIG.right_margin - self.PANEL_WIDTH,
graph_top - self.GAP_TO_STEERING_GRAPH - self.PANEL_HEIGHT,
self.PANEL_WIDTH,
self.PANEL_HEIGHT,
)
rl.draw_rectangle_rounded(panel, 0.18, 10, rl.Color(0, 0, 0, self.BACKGROUND_ALPHA))
rl.draw_rectangle_rounded_lines_ex(panel, 0.18, 10, 1, rl.Color(255, 255, 255, 45))
title_pos = rl.Vector2(panel.x + self.HORIZONTAL_PADDING, panel.y + 7)
rl.draw_text_ex(self._font_title, "eGPU", title_pos, self.TITLE_FONT_SIZE, 0, rl.WHITE)
core = self._format_temperature(self._core_temp if self._available else None)
vram = self._format_temperature(self._vram_temp if self._available else None)
self._draw_row(panel, panel.y + 34, "CORE", core)
self._draw_row(panel, panel.y + 58, "VRAM", vram)
+6 -3
View File
@@ -70,9 +70,10 @@ class UIState(UIStateSP):
"carOutput",
"carControl",
"vehicleParameters",
"testJoystick",
"rawAudioData",
] + ic_services + self.sm_services_ext
"testJoystick",
"rawAudioData",
"chestnutState",
] + ic_services + self.sm_services_ext
)
self.prime_state = PrimeState()
@@ -107,6 +108,7 @@ class UIState(UIStateSP):
self.dark_mode: bool = False
self.onroad_screen_timeout: bool = False
self.enable_accel_bar: bool = False
self.ic_show_egpu_temperatures: bool = False
self.has_alert: bool = False
self.has_status_change: bool = False
self._status_prev: UIStatus = self.status
@@ -259,6 +261,7 @@ class UIState(UIStateSP):
self.dark_mode = self.params.get_bool("DarkMode")
self.onroad_screen_timeout = self.params.get_bool("DisableScreenTimer")
self.enable_accel_bar = self.params.get_bool("ShowAccelBar")
self.ic_show_egpu_temperatures = self.params.get_bool("ICShowEgpuTemperatures")
class Device(DeviceSP):