python ui: Implement FPS monitor (#34605)

monitor fps
pull/34607/head
Dean Lee 2 months ago committed by GitHub
parent d2c0bcf7b9
commit ca05c25ba2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 30
      system/ui/lib/application.py

@ -1,14 +1,21 @@
import atexit import atexit
import os import os
import time
import pyray as rl import pyray as rl
from enum import IntEnum from enum import IntEnum
from openpilot.common.basedir import BASEDIR from openpilot.common.basedir import BASEDIR
from openpilot.common.swaglog import cloudlog
DEFAULT_TEXT_SIZE = 60
DEFAULT_FPS = 60 DEFAULT_FPS = 60
FONT_DIR = os.path.join(BASEDIR, "selfdrive/assets/fonts") FPS_LOG_INTERVAL = 5 # Seconds between logging FPS drops
FPS_DROP_THRESHOLD = 0.9 # FPS drop threshold for triggering a warning
FPS_CRITICAL_THRESHOLD = 0.5 # Critical threshold for triggering strict actions
DEBUG_FPS = os.getenv("DEBUG_FPS") == '1' DEBUG_FPS = os.getenv("DEBUG_FPS") == '1'
STRICT_MODE = os.getenv("STRICT_MODE") == '1'
DEFAULT_TEXT_SIZE = 60
FONT_DIR = os.path.join(BASEDIR, "selfdrive/assets/fonts")
class FontWeight(IntEnum): class FontWeight(IntEnum):
@ -28,6 +35,8 @@ class GuiApplication:
self._width = width self._width = width
self._height = height self._height = height
self._textures: list[rl.Texture] = [] self._textures: list[rl.Texture] = []
self._target_fps: int = DEFAULT_FPS
self._last_fps_log_time: float = time.monotonic()
def init_window(self, title: str, fps: int=DEFAULT_FPS): def init_window(self, title: str, fps: int=DEFAULT_FPS):
atexit.register(self.close) # Automatically call close() on exit atexit.register(self.close) # Automatically call close() on exit
@ -36,6 +45,7 @@ class GuiApplication:
rl.init_window(self._width, self._height, title) rl.init_window(self._width, self._height, title)
rl.set_target_fps(fps) rl.set_target_fps(fps)
self._target_fps = fps
self._set_styles() self._set_styles()
self._load_fonts() self._load_fonts()
@ -72,6 +82,7 @@ class GuiApplication:
rl.draw_fps(10, 10) rl.draw_fps(10, 10)
rl.end_drawing() rl.end_drawing()
self._monitor_fps()
def font(self, font_wight: FontWeight=FontWeight.NORMAL): def font(self, font_wight: FontWeight=FontWeight.NORMAL):
return self._fonts[font_wight] return self._fonts[font_wight]
@ -111,5 +122,20 @@ class GuiApplication:
rl.gui_set_style(rl.GuiControl.DEFAULT, rl.GuiDefaultProperty.BACKGROUND_COLOR, rl.color_to_int(rl.Color(30, 30, 30, 255))) rl.gui_set_style(rl.GuiControl.DEFAULT, rl.GuiDefaultProperty.BACKGROUND_COLOR, rl.color_to_int(rl.Color(30, 30, 30, 255)))
rl.gui_set_style(rl.GuiControl.DEFAULT, rl.GuiControlProperty.BASE_COLOR_NORMAL, rl.color_to_int(rl.Color(50, 50, 50, 255))) rl.gui_set_style(rl.GuiControl.DEFAULT, rl.GuiControlProperty.BASE_COLOR_NORMAL, rl.color_to_int(rl.Color(50, 50, 50, 255)))
def _monitor_fps(self):
fps = rl.get_fps()
# Log FPS drop below threshold at regular intervals
if fps < self._target_fps * FPS_DROP_THRESHOLD:
current_time = time.monotonic()
if current_time - self._last_fps_log_time >= FPS_LOG_INTERVAL:
cloudlog.warning(f"FPS dropped below {self._target_fps}: {fps}")
self._last_fps_log_time = current_time
# Strict mode: terminate UI if FPS drops too much
if STRICT_MODE and fps < self._target_fps * FPS_CRITICAL_THRESHOLD:
cloudlog.error(f"FPS dropped critically below {fps}. Shutting down UI.")
os._exit(1)
gui_app = GuiApplication(2160, 1080) gui_app = GuiApplication(2160, 1080)

Loading…
Cancel
Save