From dc6e64435974192572fd8a51381ddd1673aacd8c Mon Sep 17 00:00:00 2001 From: ZwX1616 Date: Sun, 26 Apr 2026 17:49:21 -0700 Subject: [PATCH] ui: DM icon turns orange briefly after awareness drops (#37826) * change icon after 1s * match * timinng * speed up * tint * cleanup --- .../onroad/driver_monitoring/dm_cone.png | 4 ++-- selfdrive/ui/mici/onroad/driver_state.py | 15 ++++++++++++++- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/selfdrive/assets/icons_mici/onroad/driver_monitoring/dm_cone.png b/selfdrive/assets/icons_mici/onroad/driver_monitoring/dm_cone.png index ec2f94899..6974b6d8e 100644 --- a/selfdrive/assets/icons_mici/onroad/driver_monitoring/dm_cone.png +++ b/selfdrive/assets/icons_mici/onroad/driver_monitoring/dm_cone.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:26b3660dbd1e60b0ba98914afa7cb3a67151bb6990d218f55c901f243e38ff3e -size 3631 +oid sha256:5f5d4b7bd406114945e53f4d56089102ee83ba7d0a4590a371f7acab90c7ad53 +size 1862 diff --git a/selfdrive/ui/mici/onroad/driver_state.py b/selfdrive/ui/mici/onroad/driver_state.py index 69ada3dae..37306ce0d 100644 --- a/selfdrive/ui/mici/onroad/driver_state.py +++ b/selfdrive/ui/mici/onroad/driver_state.py @@ -16,11 +16,15 @@ DEBUG = False LOOKING_CENTER_THRESHOLD_UPPER = math.radians(6) LOOKING_CENTER_THRESHOLD_LOWER = math.radians(3) +CONE_COLOR_GREEN = (0, 255, 64) +CONE_COLOR_ORANGE = (255, 115, 0) + class DriverStateRenderer(Widget): BASE_SIZE = 60 LINES_ANGLE_INCREMENT = 5 LINES_STALE_ANGLES = 3.0 # seconds + AWARENESS_UNFULL_PERCENT = 95 # ~0.5s def __init__(self, lines: bool = False, inset: bool = False): super().__init__() @@ -40,8 +44,10 @@ class DriverStateRenderer(Widget): self._should_draw = False self._force_active = False self._looking_center = False + self._awareness_unfull = False self._fade_filter = FirstOrderFilter(0.0, 0.05, 1 / gui_app.target_fps) + self._color_fade_filter = FirstOrderFilter(1.0, 0.05, 1 / gui_app.target_fps) # 1.0 = full green, 0.0 = full orange self._pitch_filter = FirstOrderFilter(0.0, 0.05, 1 / gui_app.target_fps, initialized=False) self._yaw_filter = FirstOrderFilter(0.0, 0.05, 1 / gui_app.target_fps, initialized=False) self._rotation_filter = FirstOrderFilter(0.0, 0.1, 1 / gui_app.target_fps, initialized=False) @@ -100,6 +106,12 @@ class DriverStateRenderer(Widget): rl.Color(255, 255, 255, int(255 * 0.9 * self._fade_filter.x))) if self.effective_active: + self._color_fade_filter.update(0.0 if self._awareness_unfull else 1.0) + t = self._color_fade_filter.x + r = int(round(CONE_COLOR_GREEN[0] * t + CONE_COLOR_ORANGE[0] * (1 - t))) + g = int(round(CONE_COLOR_GREEN[1] * t + CONE_COLOR_ORANGE[1] * (1 - t))) + b = int(round(CONE_COLOR_GREEN[2] * t + CONE_COLOR_ORANGE[2] * (1 - t))) + source_rect = rl.Rectangle(0, 0, self._dm_cone.width, self._dm_cone.height) dest_rect = rl.Rectangle( self._rect.x + self._rect.width / 2, @@ -115,7 +127,7 @@ class DriverStateRenderer(Widget): dest_rect, rl.Vector2(dest_rect.width / 2, dest_rect.height / 2), self._rotation_filter.x - 90, - rl.Color(255, 255, 255, int(255 * self._fade_filter.x)), + rl.Color(r, g, b, int(255 * self._fade_filter.x)), ) else: @@ -158,6 +170,7 @@ class DriverStateRenderer(Widget): self._is_active = dm_state.activePolicy == log.DriverMonitoringState.MonitoringPolicy.vision self._is_rhd = dm_state.isRHD self._face_detected = dm_state.visionPolicyState.faceDetected + self._awareness_unfull = self._is_active and dm_state.visionPolicyState.awarenessPercent < self.AWARENESS_UNFULL_PERCENT self._face_pitch = dm_state.visionPolicyState.pose.pitch + math.radians(6) # calib or DM pose is not accurate, add a fake upward pitch to bias forward self._face_yaw = -dm_state.visionPolicyState.pose.yaw # undo sign flip in face_orientation_from_model to match UI convention