BigUI StarPilot Layer + AOL + Personality Buttons

This commit is contained in:
firestarsdog
2026-03-31 01:39:27 -04:00
committed by firestar5683
parent 23a7fd7d81
commit f9131e4f02
4 changed files with 126 additions and 2 deletions
+2 -2
View File
@@ -6,7 +6,7 @@ from openpilot.system.ui.lib.application import gui_app
from openpilot.selfdrive.ui.layouts.sidebar import Sidebar, SIDEBAR_WIDTH
from openpilot.selfdrive.ui.layouts.home import HomeLayout
from openpilot.selfdrive.ui.layouts.settings.settings import SettingsLayout, PanelType
from openpilot.selfdrive.ui.onroad.augmented_road_view import AugmentedRoadView
from openpilot.selfdrive.ui.onroad.starpilot.starpilot_onroad_view import StarPilotOnroadView
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
@@ -29,7 +29,7 @@ class MainLayout(Widget):
self._prev_onroad = False
# Initialize layouts
self._layouts = {MainState.HOME: HomeLayout(), MainState.SETTINGS: SettingsLayout(), MainState.ONROAD: AugmentedRoadView()}
self._layouts = {MainState.HOME: HomeLayout(), MainState.SETTINGS: SettingsLayout(), MainState.ONROAD: StarPilotOnroadView()}
self._sidebar_rect = rl.Rectangle(0, 0, 0, 0)
self._content_rect = rl.Rectangle(0, 0, 0, 0)
@@ -0,0 +1,63 @@
import pyray as rl
from cereal import log
from openpilot.common.params import Params
from openpilot.selfdrive.ui.ui_state import ui_state
from openpilot.system.ui.lib.application import gui_app
from openpilot.system.ui.widgets import Widget
BTN_SIZE = 192
ICON_SIZE = 144
PERSONALITY_TO_INT = log.LongitudinalPersonality.schema.enumerants
class PersonalityButton(Widget):
def __init__(self):
super().__init__()
self._params_memory = Params(memory=True)
self._personality: int = 1 # default: standard
self._traffic_mode: bool = False
# 0=traffic, 1=aggressive, 2=standard, 3=relaxed
self._icons = [
gui_app.starpilot_texture("stock_theme/distance_icons/traffic.png", ICON_SIZE, ICON_SIZE),
gui_app.starpilot_texture("stock_theme/distance_icons/aggressive.png", ICON_SIZE, ICON_SIZE),
gui_app.starpilot_texture("stock_theme/distance_icons/standard.png", ICON_SIZE, ICON_SIZE),
gui_app.starpilot_texture("stock_theme/distance_icons/relaxed.png", ICON_SIZE, ICON_SIZE),
]
self._rect = rl.Rectangle(0, 0, BTN_SIZE, BTN_SIZE)
self._black_bg = rl.Color(0, 0, 0, 0)
self._white = rl.Color(255, 255, 255, 255)
self.set_visible(lambda: ui_state.started and ui_state.has_longitudinal_control)
@property
def is_interacting(self) -> bool:
return self.is_pressed
def _update_state(self):
sm = ui_state.sm
if sm.valid.get("selfdriveState", False):
self._personality = PERSONALITY_TO_INT[sm["selfdriveState"].personality]
self._traffic_mode = ui_state.traffic_mode_enabled
def _handle_mouse_press(self, _):
self._params_memory.put_bool("OnroadDistanceButtonPressed", True)
def _handle_mouse_release(self, _):
self._params_memory.put_bool("OnroadDistanceButtonPressed", False)
def _render(self, rect: rl.Rectangle):
center_x = int(self._rect.x + self._rect.width / 2)
center_y = int(self._rect.y + self._rect.height / 2)
opacity = 180 if self.is_pressed else 255
self._white.a = opacity
icon_idx = 0 if self._traffic_mode else min(self._personality + 1, len(self._icons) - 1)
icon = self._icons[icon_idx]
rl.draw_circle(center_x, center_y, self._rect.width / 2, self._black_bg)
rl.draw_texture(icon, center_x - icon.width // 2, center_y - icon.height // 2, self._white)
@@ -0,0 +1,61 @@
import pyray as rl
from msgq.visionipc import VisionStreamType
from openpilot.common.params import Params
from openpilot.selfdrive.ui import UI_BORDER_SIZE
from openpilot.selfdrive.ui.onroad.augmented_road_view import AugmentedRoadView, BORDER_COLORS
from openpilot.selfdrive.ui.onroad.starpilot.personality_button import PersonalityButton, BTN_SIZE
from openpilot.selfdrive.ui.ui_state import ui_state, UIStatus
AOL_COLOR = rl.Color(10, 186, 181, 255)
class StarPilotOnroadView(AugmentedRoadView):
def __init__(self, stream_type: VisionStreamType = VisionStreamType.VISION_STREAM_ROAD):
super().__init__(stream_type)
self._params = Params()
self._personality_button = PersonalityButton()
def _render(self, rect: rl.Rectangle):
super()._render(rect)
if not ui_state.started:
return
self._render_overlays()
def _render_overlays(self):
self._position_personality_button()
self._personality_button.render()
def _position_personality_button(self):
dm = self.driver_state_renderer
toggle_on = self._params.get_bool("OnroadDistanceButton")
if not dm.is_visible or not toggle_on:
self._personality_button.set_visible(False)
return
self._personality_button.set_visible(
lambda: ui_state.started and ui_state.has_longitudinal_control
)
y = dm.position_y - BTN_SIZE / 2
if dm.is_rhd:
x = dm.position_x - BTN_SIZE * 2
else:
x = dm.position_x + BTN_SIZE
self._personality_button.set_position(x, y)
def _draw_border(self, rect: rl.Rectangle):
rl.draw_rectangle_lines_ex(rect, UI_BORDER_SIZE, rl.BLACK)
border_rect = rl.Rectangle(rect.x + UI_BORDER_SIZE, rect.y + UI_BORDER_SIZE,
rect.width - 2 * UI_BORDER_SIZE, rect.height - 2 * UI_BORDER_SIZE)
border_color = AOL_COLOR if ui_state.always_on_lateral_active else BORDER_COLORS.get(ui_state.status, BORDER_COLORS[UIStatus.DISENGAGED])
rl.draw_rectangle_rounded_lines_ex(border_rect, 0.12, 10, UI_BORDER_SIZE, border_color)
def _handle_mouse_press(self, _):
if self._personality_button.is_interacting:
return
super()._handle_mouse_press(_)