Files
StarPilot/openpilot/starpilot/ui/rainbow_path.py
T
firestar5683 a82935f326 User interfaces and Android Auto
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>
2026-10-14 20:02:39 -05:00

53 lines
1.7 KiB
Python

"""Speed-scrolling gradient for the onroad path."""
import colorsys
import math
import pyray as rl
from openpilot.system.ui.lib.shader_polygon import Gradient
HUE_RANGE = 120.0
SCROLL_DEG_PER_SEC_PER_MPS = 5.0
NUM_STOPS = 12
MAX_SAMPLE_AGE_NS = 500_000_000
MAX_FRAME_GAP_NS = 250_000_000
class RainbowPath:
def __init__(self) -> None:
self.phase_deg = 0.0
self.last_ns: int | None = None
self.sample_ns: int | None = None
self.speed_mps = 0.0
def update(self, now_ns: int, speed_mps: float | None, *, source_alive: bool) -> None:
if now_ns < 0 or self.last_ns is not None and now_ns < self.last_ns:
self.sample_ns = None
self.last_ns = now_ns
return
if not source_alive:
self.sample_ns = None
elif speed_mps is not None:
if math.isfinite(speed_mps) and 0.0 <= speed_mps <= 80.0:
self.speed_mps = speed_mps
self.sample_ns = now_ns
else:
self.sample_ns = None
dt_ns = 0 if self.last_ns is None else now_ns - self.last_ns
self.last_ns = now_ns
if (self.sample_ns is not None and now_ns - self.sample_ns <= MAX_SAMPLE_AGE_NS and
0 < dt_ns <= MAX_FRAME_GAP_NS):
self.phase_deg = (self.phase_deg + self.speed_mps * SCROLL_DEG_PER_SEC_PER_MPS * dt_ns / 1e9) % 360.0
def gradient(self) -> Gradient:
stops = [index / (NUM_STOPS - 1) for index in range(NUM_STOPS)]
colors = []
for stop in stops:
hue = ((stop * HUE_RANGE + self.phase_deg) % 360.0) / 360.0
red, green, blue = colorsys.hls_to_rgb(hue, 0.5, 1.0)
alpha = 0.5 + (0.1 - 0.5) * stop
colors.append(rl.Color(int(red * 255), int(green * 255), int(blue * 255), int(alpha * 255)))
return Gradient(start=(0.0, 0.0), end=(0.0, 1.0), colors=colors, stops=stops)