Files
sunnypilot-byd/openpilot/selfdrive/ui/sunnypilot/onroad/rainbow_path.py
T
github-actions[bot] de77c89cf6 sunnypilot v2026.002.000
version: sunnypilot v2026.002.000 (staging)
date: 2026-07-21T07:44:02
master commit: 2c334ede443d7391d27575af8c854a095ba702a8
2026-07-21 07:44:02 +00:00

80 lines
2.3 KiB
Python

"""
Copyright (c) 2021-, Haibin Wen, sunnypilot, and a number of other contributors.
This file is part of sunnypilot and is licensed under the MIT License.
See the LICENSE.md file in the root directory for more details.
"""
import time
import colorsys
import pyray as rl
from openpilot.system.ui.lib.shader_polygon import draw_polygon, Gradient
class RainbowPath:
DEFAULT_NUM_SEGMENTS = 8
DEFAULT_SPEED = 50.0 # degrees per second
DEFAULT_SATURATION = 0.9
DEFAULT_LIGHTNESS = 0.6
BASE_ALPHA = 0.8
ALPHA_FADE = 0.3 # Alpha reduction from bottom to top
def __init__(self, num_segments: int = DEFAULT_NUM_SEGMENTS, speed: float = DEFAULT_SPEED,
saturation: float = DEFAULT_SATURATION, lightness: float = DEFAULT_LIGHTNESS):
self.num_segments = num_segments
self.speed = speed
self.saturation = saturation
self.lightness = lightness
def set_speed(self, speed: float):
self.speed = speed
def set_num_segments(self, num_segments: int):
self.num_segments = num_segments
def set_saturation(self, saturation: float):
self.saturation = max(0.0, min(1.0, saturation))
def set_lightness(self, lightness: float):
self.lightness = max(0.0, min(1.0, lightness))
def get_gradient(self) -> Gradient:
time_offset = time.monotonic()
hue_offset = (time_offset * self.speed) % 360.0
segment_colors = []
gradient_stops = []
for i in range(self.num_segments):
position = i / (self.num_segments - 1)
hue = (hue_offset + position * 360.0) % 360.0
alpha = self.BASE_ALPHA * (1.0 - position * self.ALPHA_FADE)
color = self._hsla_to_color(
hue / 360.0,
self.saturation,
self.lightness,
alpha
)
gradient_stops.append(position)
segment_colors.append(color)
return Gradient(
start=(0.0, 1.0), # Bottom of path
end=(0.0, 0.0), # Top of path
colors=segment_colors,
stops=gradient_stops,
)
@staticmethod
def _hsla_to_color(h: float, s: float, l: float, a: float) -> rl.Color:
rgb = colorsys.hls_to_rgb(h, l, s)
return rl.Color(
int(rgb[0] * 255),
int(rgb[1] * 255),
int(rgb[2] * 255),
int(a * 255)
)
def draw_rainbow_path(self, rect, path):
gradient = self.get_gradient()
draw_polygon(rect, path.projected_points, gradient=gradient)