mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-11-08 13:33:42 +08:00
a82935f326
Integrate onroad views, configurable widgets, local settings, steering-profile contracts, Bluetooth and Android Auto with their device and runtime services. Co-authored-by: Adeeb Shihadeh <adeebshihadeh@gmail.com> Co-authored-by: Daniel Koepping <elkoled@gmail.com> Co-authored-by: Danny <dannyirwin31@yahoo.com> Co-authored-by: DimitriChrysafis <Dimitri.chrysafis@gmail.com> Co-authored-by: Dom <168790843+firestar5683@users.noreply.github.com> Co-authored-by: Harald Schäfer <harald.the.engineer@gmail.com> Co-authored-by: Prabhaav Pillai <prabhaav@msu.edu> Co-authored-by: Shane Smiskol <shane@smiskol.com> Co-authored-by: dirwin31 <83434411+dirwin31@users.noreply.github.com> Co-authored-by: firestarsdog <229254897+firestarsdog@users.noreply.github.com> Co-authored-by: stef <19478336+stefpi@users.noreply.github.com> Co-authored-by: whoisdomi <dcantu83@gmail.com> Co-authored-by: Intelli <contact@intelli.software> Co-authored-by: pharmacomaniac <blittle65@gmail.com> Co-authored-by: prabhaavp <prabhaav@msu.edu>
105 lines
4.3 KiB
Python
105 lines
4.3 KiB
Python
"""Positioned native cone/person monitoring artwork with observed visibility."""
|
|
|
|
import math
|
|
|
|
import pyray as rl
|
|
|
|
from openpilot.selfdrive.ui.mici.onroad.driver_state import DriverStateRenderer
|
|
from openpilot.selfdrive.ui.ui_state import ui_state
|
|
from openpilot.starpilot.ui.onroad_customization import PROFILES, placement, widget_size
|
|
from openpilot.starpilot.ui.onroad_state import AlertSize
|
|
from openpilot.starpilot.ui.onroad_widget_style import draw_widget_frame
|
|
from openpilot.starpilot.ui.presentation import Profile
|
|
|
|
|
|
def valid_observation(monitor, driver):
|
|
try:
|
|
vision = monitor.visionPolicyState
|
|
return (type(monitor.isRHD) is bool and type(vision.faceDetected) is bool and
|
|
all(math.isfinite(float(number)) for number in (vision.pose.pitch, vision.pose.yaw, vision.awarenessPercent)) and
|
|
0 <= vision.awarenessPercent <= 100 and
|
|
getattr(driver, 'rightDriverData' if monitor.isRHD else 'leftDriverData') is not None)
|
|
except (AttributeError, TypeError, ValueError, OverflowError):
|
|
return False
|
|
|
|
|
|
def monitor_bounds(document, profile, is_rhd):
|
|
position = placement(document, profile, 'driver_monitor')
|
|
widget = PROFILES[str(profile)]['widgets']['driver_monitor']
|
|
width, height = widget_size(document, profile, 'driver_monitor')
|
|
x, y = position['x'], position['y']
|
|
if profile == Profile.LARGE and is_rhd and (x, y) == (widget['default']['x'], widget['default']['y']):
|
|
bounds = PROFILES['large']['bounds']
|
|
x = 2 * bounds['x'] + bounds['width'] - x - width
|
|
return rl.Rectangle(x, y, width, height)
|
|
|
|
|
|
def draw_monitor_art(renderer, bounds, profile):
|
|
"""Scale the native icon and cone together inside the saved square."""
|
|
base = 128 if profile == Profile.LARGE else 60
|
|
renderer._rect = rl.Rectangle(bounds.x, bounds.y, base, base)
|
|
rl.rl_push_matrix()
|
|
try:
|
|
rl.rl_translatef(bounds.x, bounds.y, 0)
|
|
rl.rl_scalef(bounds.width / base, bounds.height / base, 1)
|
|
rl.rl_translatef(-bounds.x, -bounds.y, 0)
|
|
renderer._render(renderer._rect)
|
|
finally:
|
|
rl.rl_pop_matrix()
|
|
|
|
|
|
def monitor_visible(profile, state, *, fresh, onroad, top_icons):
|
|
occluded = False
|
|
if profile == Profile.COMPACT and top_icons:
|
|
monitor = monitor_bounds(state.customization, profile, False)
|
|
speed = placement(state.customization, profile, 'max_speed')
|
|
widget = PROFILES['compact']['widgets']['max_speed']
|
|
occluded = rl.check_collision_recs(monitor, rl.Rectangle(speed['x'], speed['y'], widget['width'], widget['height']))
|
|
return bool(onroad and state.alert.size != AlertSize.FULL and not state.alert.critical and
|
|
not occluded and
|
|
placement(state.customization, profile, 'driver_monitor')['enabled'])
|
|
|
|
|
|
class StableDriverStateRenderer(DriverStateRenderer):
|
|
@property
|
|
def should_draw(self):
|
|
return self._should_draw
|
|
|
|
def _update_state(self):
|
|
super()._update_state()
|
|
if self.should_draw:
|
|
self._fade_filter.x = 1.0 if self._face_detected else min(self._fade_filter.x, 0.35)
|
|
|
|
|
|
class LargeDriverStateRenderer(StableDriverStateRenderer):
|
|
def get_driver_data(self):
|
|
result = super().get_driver_data()
|
|
self._face_yaw = -ui_state.sm['driverMonitoringState'].visionPolicyState.pose.yaw
|
|
return result
|
|
|
|
|
|
class DriverMonitorLayer:
|
|
def __init__(self, profile):
|
|
self.profile = profile
|
|
self.renderer = LargeDriverStateRenderer() if profile == Profile.LARGE else StableDriverStateRenderer()
|
|
if profile == Profile.LARGE:
|
|
self.renderer.set_rect(rl.Rectangle(0, 0, 128, 128))
|
|
self.renderer.load_icons()
|
|
|
|
def render(self, state, *, monitor, driver, fresh, onroad, top_icons=False):
|
|
ready = fresh and valid_observation(monitor, driver)
|
|
visible = monitor_visible(self.profile, state, fresh=ready, onroad=onroad, top_icons=top_icons)
|
|
self.renderer.set_should_draw(visible)
|
|
is_rhd = monitor.isRHD if ready else getattr(self.renderer, '_is_rhd', False)
|
|
bounds = monitor_bounds(state.customization, self.profile, is_rhd)
|
|
self.renderer.set_position(bounds.x, bounds.y)
|
|
if ready:
|
|
self.renderer._update_state()
|
|
else:
|
|
self.renderer._is_active = False
|
|
self.renderer._awareness_unfull = False
|
|
self.renderer._fade_filter.update(0.35 if visible else 0.0)
|
|
if visible:
|
|
draw_widget_frame(bounds, state.customization, self.profile, "driver_monitor")
|
|
draw_monitor_art(self.renderer, bounds, self.profile)
|