fixes and Themes

This commit is contained in:
firestar5683
2026-04-19 19:03:54 -05:00
parent 392d38c589
commit 174bb9f31f
49 changed files with 250 additions and 43 deletions
Binary file not shown.
+4
View File
@@ -316,11 +316,13 @@ inline static std::unordered_map<std::string, ParamKeyAttributes> keys = {
{"LaneChanges", {PERSISTENT, BOOL, "1", "1", 0}},
{"LaneChangeTime", {PERSISTENT, FLOAT, "1.0", "0.0", 1}},
{"LaneDetectionWidth", {PERSISTENT, FLOAT, "0.0", "0.0", 1}},
{"LaneLinesColor", {PERSISTENT, STRING, "", "", 2}},
{"LaneLinesWidth", {PERSISTENT, FLOAT, "4.0", "2.0", 2}},
{"LastMapsUpdate", {PERSISTENT, STRING, "", ""}},
{"LateralTune", {PERSISTENT, BOOL, "1", "0", 1}},
{"LeadDepartingAlert", {PERSISTENT, BOOL, "0", "0", 0}},
{"LeadDetectionThreshold", {PERSISTENT, INT, "35", "50", 3}},
{"LeadIndicator", {PERSISTENT, BOOL, "1", "1", 2}},
{"LeadInfo", {PERSISTENT, BOOL, "1", "0", 3}},
{"LKASButtonControl", {PERSISTENT, INT, "5", "0", 2}},
{"LockDoors", {PERSISTENT, BOOL, "1", "0", 0}},
@@ -383,6 +385,8 @@ inline static std::unordered_map<std::string, ParamKeyAttributes> keys = {
{"OnroadDistanceButtonPressed", {CLEAR_ON_MANAGER_START, BOOL, "0", "0"}},
{"openpilotMinutes", {PERSISTENT, INT, "0", "0", 0}},
{"OverpassRequests", {PERSISTENT, JSON, "{}", "{}"}},
{"PathColor", {PERSISTENT, STRING, "", "", 2}},
{"PathEdgesColor", {PERSISTENT, STRING, "", "", 2}},
{"PathEdgeWidth", {PERSISTENT, FLOAT, "20.0", "0.0", 2}},
{"PathWidth", {PERSISTENT, FLOAT, "6.1", "5.9", 2}},
{"PauseAOLOnBrake", {PERSISTENT, BOOL, "0", "0", 1}},
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+1 -1
View File
@@ -1,2 +1,2 @@
extern const uint8_t gitversion[19];
const uint8_t gitversion[19] = "DEV-ee3f32ad-DEBUG";
const uint8_t gitversion[19] = "DEV-392d38c5-DEBUG";
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+1 -1
View File
@@ -1 +1 @@
DEV-ee3f32ad-DEBUG
DEV-392d38c5-DEBUG
Binary file not shown.
+60 -2
View File
@@ -26,6 +26,30 @@ _THEME_COLOR_CACHE: dict[str, object] = {
}
def _as_color(value: object, fallback: tuple[int, int, int, int] = (255, 255, 255, 255)) -> rl.Color:
if all(hasattr(value, channel) for channel in ("r", "g", "b", "a")):
return rl.Color(
_clamp_channel(getattr(value, "r"), fallback[0]),
_clamp_channel(getattr(value, "g"), fallback[1]),
_clamp_channel(getattr(value, "b"), fallback[2]),
_clamp_channel(getattr(value, "a"), fallback[3]),
)
if isinstance(value, (tuple, list)):
items = list(value)
if len(items) == 3:
items.append(fallback[3])
if len(items) >= 4:
return rl.Color(
_clamp_channel(items[0], fallback[0]),
_clamp_channel(items[1], fallback[1]),
_clamp_channel(items[2], fallback[2]),
_clamp_channel(items[3], fallback[3]),
)
return rl.Color(*fallback)
def _file_stamp(path: Path) -> tuple[str, int | None, int | None]:
try:
stat = path.stat()
@@ -84,9 +108,43 @@ def _load_theme_colors() -> dict[str, rl.Color]:
def get_theme_color(key: str, fallback: rl.Color | None = None) -> rl.Color:
color = _load_theme_colors().get(key)
if color is not None:
return color
return fallback if fallback is not None else rl.WHITE
return _as_color(color)
return _as_color(fallback if fallback is not None else rl.WHITE)
def get_param_color(params, key: str, fallback_alpha: int = 255) -> rl.Color | None:
value = params.get(key, encoding="utf-8") if params is not None else None
if not value:
return None
color = value.strip()
if not color or color.lower() == "stock":
return None
if color.startswith("#"):
color = color[1:]
if len(color) not in (6, 8):
return None
try:
red = int(color[0:2], 16)
green = int(color[2:4], 16)
blue = int(color[4:6], 16)
alpha = int(color[6:8], 16) if len(color) == 8 else fallback_alpha
except ValueError:
return None
return rl.Color(red, green, blue, alpha)
def get_visual_color(params, param_key: str, theme_key: str, fallback: rl.Color | None = None) -> rl.Color:
base = _as_color(fallback if fallback is not None else rl.WHITE)
override = get_param_color(params, param_key, base.a)
if override is not None:
return override
return get_theme_color(theme_key, base)
def with_alpha(color: rl.Color, alpha: int) -> rl.Color:
color = _as_color(color)
return rl.Color(color.r, color.g, color.b, max(0, min(255, int(alpha))))
+10
View File
@@ -14,3 +14,13 @@ def get_border_width(base_width: int, params: Params | None = None) -> int:
scale = min(250.0, max(25.0, scale))
return max(1, int(round(base_width * scale / 100.0)))
def lead_indicator_enabled(params: Params | None = None) -> bool:
active_params = params if params is not None else Params()
enabled = not active_params.get_bool("HideLeadMarker", default=False)
if active_params.get("LeadIndicator") is not None:
enabled = enabled and active_params.get_bool("LeadIndicator", default=True)
return enabled
+22 -1
View File
@@ -1,5 +1,6 @@
from openpilot.common.params import Params
from openpilot.selfdrive.ui.mici.widgets.button import BigButton, BigParamControl
from openpilot.selfdrive.ui.lib.starpilot_visuals import lead_indicator_enabled
from openpilot.selfdrive.ui.mici.widgets.button import BigButton, BigParamControl, BigToggle
from openpilot.selfdrive.ui.mici.widgets.dialog import BigDialog, BigMultiOptionDialog
from openpilot.system.ui.lib.application import gui_app
from openpilot.system.ui.widgets.scroller import NavScroller
@@ -38,12 +39,29 @@ class CameraViewBigButton(BigButton):
gui_app.push_widget(dialog)
class LeadIndicatorBigButton(BigToggle):
def __init__(self):
super().__init__("lead indicator")
self.params = Params()
self.refresh()
def _handle_mouse_release(self, mouse_pos):
super()._handle_mouse_release(mouse_pos)
self.params.put_bool("LeadIndicator", self._checked)
self.params.put_bool("HideLeadMarker", not self._checked)
def refresh(self):
self.set_checked(lead_indicator_enabled(self.params))
class VisualsLayoutMici(NavScroller):
def __init__(self):
super().__init__()
self._camera_view_btn = CameraViewBigButton()
self._driver_camera_btn = BigParamControl("driver camera on reverse", "DriverCamera")
self._stopped_timer_btn = BigParamControl("stopped timer", "StoppedTimer")
self._rainbow_path_btn = BigParamControl("rainbow road", "RainbowPath")
self._lead_indicator_btn = LeadIndicatorBigButton()
self._speed_limit_signs_btn = BigParamControl("speed limit signs", "ShowSpeedLimits")
self._slc_confirmation_btn = BigParamControl("confirm new speed limits", "SLCConfirmation")
self._slc_confirmation_lower_btn = BigParamControl("confirm lower limits", "SLCConfirmationLower")
@@ -53,6 +71,8 @@ class VisualsLayoutMici(NavScroller):
self._camera_view_btn,
self._driver_camera_btn,
self._stopped_timer_btn,
self._rainbow_path_btn,
self._lead_indicator_btn,
self._speed_limit_signs_btn,
self._slc_confirmation_btn,
self._slc_confirmation_lower_btn,
@@ -69,6 +89,7 @@ class VisualsLayoutMici(NavScroller):
def _refresh(self):
self._camera_view_btn.refresh()
self._lead_indicator_btn.refresh()
confirmation_enabled = self._slc_confirmation_btn.params.get_bool("SLCConfirmation")
self._slc_confirmation_lower_btn.set_visible(confirmation_enabled)
self._slc_confirmation_higher_btn.set_visible(confirmation_enabled)
+77 -12
View File
@@ -7,7 +7,8 @@ from openpilot.common.params import Params
from openpilot.common.constants import CV
from openpilot.common.filter_simple import FirstOrderFilter
from openpilot.selfdrive.locationd.calibrationd import HEIGHT_INIT
from openpilot.selfdrive.ui.lib.starpilot_theme import get_theme_color, with_alpha
from openpilot.selfdrive.ui.lib.starpilot_theme import get_param_color, get_theme_color, get_visual_color, with_alpha
from openpilot.selfdrive.ui.lib.starpilot_visuals import lead_indicator_enabled
from openpilot.selfdrive.ui.ui_state import ui_state, UIStatus
from openpilot.selfdrive.ui.mici.onroad import blend_colors
from openpilot.selfdrive.ui.mici.onroad.starpilot_status import get_border_color, get_path_edge_color
@@ -18,6 +19,8 @@ from openpilot.system.ui.widgets import Widget
CLIP_MARGIN = 500
MIN_DRAW_DISTANCE = 10.0
MAX_DRAW_DISTANCE = 100.0
RAINBOW_GRADIENT_COLOR_COUNT = 19
RAINBOW_SCROLL_SPEED_DEG_PER_SEC = 60.0
THROTTLE_COLORS = [
rl.Color(13, 248, 122, 102), # HSLF(148/360, 0.94, 0.51, 0.4)
@@ -117,7 +120,7 @@ class ModelRenderer(Widget):
model = sm['modelV2']
radar_state = sm['radarState'] if sm.valid['radarState'] else None
lead_one = radar_state.leadOne if radar_state else None
render_lead_indicator = self._longitudinal_control and radar_state is not None
render_lead_indicator = self._longitudinal_control and radar_state is not None and lead_indicator_enabled(self._params)
# Update model data when needed
model_updated = sm.updated['modelV2']
@@ -137,8 +140,8 @@ class ModelRenderer(Widget):
self._draw_lane_lines()
self._draw_path(sm)
# if render_lead_indicator and radar_state:
# self._draw_lead_indicator()
if render_lead_indicator and radar_state:
self._draw_lead_indicator()
def _update_raw_points(self, model):
"""Update raw 3D points from model data"""
@@ -243,10 +246,22 @@ class ModelRenderer(Widget):
def _update_experimental_gradient(self):
"""Pre-calculate experimental mode gradient colors"""
if not (self._experimental_mode or self._params.get_bool("AccelerationPath", default=True)):
use_rainbow = self._params.get_bool("RainbowPath", default=False)
use_acceleration = not use_rainbow and (self._experimental_mode or self._params.get_bool("AccelerationPath", default=True))
if not (use_rainbow or use_acceleration):
return
max_len = min(len(self._path.projected_points) // 2, len(self._acceleration_x))
if use_rainbow:
gradient_bottom, gradient_top = self._get_visible_gradient_bounds()
self._exp_gradient = self._build_rainbow_gradient(gradient_bottom, gradient_top)
return
custom_theme_selected = (self._params.get("ColorScheme", encoding="utf-8", default="stock") or "stock").lower() != "stock"
path_color = None
if custom_theme_selected or get_param_color(self._params, "PathColor", 255) is not None:
path_color = get_visual_color(self._params, "PathColor", "Path", rl.Color(48, 255, 156, 255))
segment_colors = []
gradient_stops = []
@@ -262,6 +277,14 @@ class ModelRenderer(Widget):
# Calculate color based on acceleration (0 is bottom, 1 is top)
lin_grad_point = 1 - (track_y - self._rect.y) / self._rect.height
if path_color is not None and abs(self._acceleration_x[i]) < 0.25:
alpha = np.interp(lin_grad_point, [0.0, 1.0], [path_color.a, path_color.a * 0.10])
color = with_alpha(path_color, int(alpha))
gradient_stops.append(lin_grad_point)
segment_colors.append(color)
i += 1 + (1 if (i + 2) < max_len else 0)
continue
# speed up: 120, slow down: 0
path_hue = np.clip(60 + self._acceleration_x[i] * 35, 0, 120)
@@ -281,6 +304,40 @@ class ModelRenderer(Widget):
# Store the gradient in the path object
self._exp_gradient.colors = segment_colors
self._exp_gradient.stops = gradient_stops
self._exp_gradient.start = (0.0, 1.0)
self._exp_gradient.end = (0.0, 0.0)
def _get_visible_gradient_bounds(self) -> tuple[float, float]:
if self._path.projected_points.size == 0:
return 1.0, 0.0
polygon_y = self._path.projected_points[:, 1]
visible_track_y = polygon_y[(polygon_y >= self._rect.y) & (polygon_y <= (self._rect.y + self._rect.height))]
if visible_track_y.size == 0:
return 1.0, 0.0
gradient_bottom = np.clip((float(np.max(visible_track_y)) - self._rect.y) / self._rect.height, 0.0, 1.0)
gradient_top = np.clip((float(np.min(visible_track_y)) - self._rect.y) / self._rect.height, 0.0, 1.0)
return float(gradient_bottom), float(gradient_top)
def _build_rainbow_gradient(self, gradient_bottom: float, gradient_top: float) -> Gradient:
hue_offset = (rl.get_time() * RAINBOW_SCROLL_SPEED_DEG_PER_SEC) % 360.0
stops = [i / (RAINBOW_GRADIENT_COLOR_COUNT - 1) for i in range(RAINBOW_GRADIENT_COLOR_COUNT)]
colors = []
for i, stop in enumerate(stops):
hue_progress = i / RAINBOW_GRADIENT_COLOR_COUNT
path_hue = (hue_progress * 360.0 - hue_offset) % 360.0
alpha = np.interp(stop, [0.0, 1.0], [0.48, 0.18])
colors.append(self._hsla_to_color(path_hue / 360.0, 1.0, 0.5, alpha))
return Gradient(
start=(0.0, gradient_bottom),
end=(0.0, gradient_top),
colors=colors,
stops=stops,
)
def _update_lead_vehicle(self, d_rel, v_rel, point, rect):
speed_buff, lead_buff = 10.0, 40.0
@@ -309,8 +366,12 @@ class ModelRenderer(Widget):
def _get_ll_color(self, prob: float, adjacent: bool, left: bool):
alpha = np.clip(prob, 0.0, 0.7)
if adjacent:
_base_color = get_path_edge_color(ui_state)
color = rl.Color(_base_color.r, _base_color.g, _base_color.b, int(alpha * 255))
override = get_param_color(self._params, "PathEdgesColor", 255)
if override is not None:
color = with_alpha(override, int(alpha * override.a))
else:
_base_color = get_path_edge_color(ui_state)
color = rl.Color(_base_color.r, _base_color.g, _base_color.b, int(alpha * 255))
# turn adjacent lls orange if torque is high
torque = self._torque_filter.x
@@ -322,7 +383,7 @@ class ModelRenderer(Widget):
np.interp(abs(torque), [0.6, 0.8], [0.0, 1.0])
)
else:
lane_lines_color = get_theme_color("LaneLines", rl.WHITE)
lane_lines_color = get_visual_color(self._params, "LaneLinesColor", "LaneLines", rl.WHITE)
color = with_alpha(lane_lines_color, int(alpha * lane_lines_color.a))
return color
@@ -353,17 +414,20 @@ class ModelRenderer(Widget):
lateral_ui_active = ui_state.status == UIStatus.ENGAGED or ui_state.always_on_lateral_active
allow_throttle = sm['longitudinalPlan'].allowThrottle or not self._longitudinal_control or ui_state.always_on_lateral_active
self._blend_filter.update(int(allow_throttle))
use_rainbow = self._params.get_bool("RainbowPath", default=False)
use_accel_path = not use_rainbow and self._params.get_bool("AccelerationPath", default=True)
path_override = get_param_color(self._params, "PathColor", 255)
custom_theme_selected = (self._params.get("ColorScheme", encoding="utf-8", default="stock") or "stock").lower() != "stock"
if self._experimental_mode or self._params.get_bool("AccelerationPath", default=True):
if use_rainbow or self._experimental_mode or use_accel_path:
# Draw with acceleration coloring
if len(self._exp_gradient.colors) > 1:
draw_polygon(self._rect, self._path.projected_points, gradient=self._exp_gradient)
else:
fallback = get_border_color(ui_state)
draw_polygon(self._rect, self._path.projected_points, rl.Color(fallback.r, fallback.g, fallback.b, 90))
elif custom_theme_selected:
path_color = get_theme_color("Path", rl.Color(48, 255, 156, 255))
elif path_override is not None or custom_theme_selected:
path_color = get_visual_color(self._params, "PathColor", "Path", rl.Color(48, 255, 156, 255))
gradient = Gradient(
start=(0.0, 1.0),
end=(0.0, 0.0),
@@ -391,12 +455,13 @@ class ModelRenderer(Widget):
def _draw_lead_indicator(self):
# Draw lead vehicles if available
lead_color = get_theme_color("LeadMarker", rl.Color(201, 34, 49, 255))
for lead in self._lead_vehicles:
if not lead.glow or not lead.chevron:
continue
rl.draw_triangle_fan(lead.glow, len(lead.glow), rl.Color(218, 202, 37, 255))
rl.draw_triangle_fan(lead.chevron, len(lead.chevron), rl.Color(201, 34, 49, lead.fill_alpha))
rl.draw_triangle_fan(lead.chevron, len(lead.chevron), with_alpha(lead_color, lead.fill_alpha))
@staticmethod
def _get_path_length_idx(pos_x_array: np.ndarray, path_height: float) -> int:
+58 -24
View File
@@ -7,7 +7,8 @@ from openpilot.common.filter_simple import FirstOrderFilter
from openpilot.common.params import Params
from openpilot.common.constants import CV
from openpilot.selfdrive.locationd.calibrationd import HEIGHT_INIT
from openpilot.selfdrive.ui.lib.starpilot_theme import get_theme_color, with_alpha
from openpilot.selfdrive.ui.lib.starpilot_theme import get_param_color, get_theme_color, get_visual_color, with_alpha
from openpilot.selfdrive.ui.lib.starpilot_visuals import lead_indicator_enabled
from openpilot.selfdrive.ui.ui_state import ui_state, UIStatus
from openpilot.system.ui.lib.application import gui_app
from openpilot.system.ui.lib.shader_polygon import draw_polygon, Gradient
@@ -16,6 +17,8 @@ from openpilot.system.ui.widgets import Widget
CLIP_MARGIN = 500
MIN_DRAW_DISTANCE = 10.0
MAX_DRAW_DISTANCE = 100.0
RAINBOW_GRADIENT_COLOR_COUNT = 19
RAINBOW_SCROLL_SPEED_DEG_PER_SEC = 60.0
THROTTLE_COLORS = [
rl.Color(13, 248, 122, 102), # HSLF(148/360, 0.94, 0.51, 0.4)
@@ -59,10 +62,6 @@ class ModelRenderer(Widget):
self._adjacent_path_vertices = [np.empty((0, 2), dtype=np.float32), np.empty((0, 2), dtype=np.float32)]
# Outer path polygon for edge rendering
self._track_edge_vertices = np.empty((0, 2), dtype=np.float32)
# Rainbow animation state
self._rainbow_hue_offset = 0.0
# Cached speed for rainbow animation
self._speed = 0.0
# Initialize ModelPoints objects
self._path = ModelPoints()
@@ -107,7 +106,6 @@ class ModelRenderer(Widget):
# Update state
self._experimental_mode = sm['selfdriveState'].experimentalMode
self._speed = sm['carState'].vEgo
live_calib = sm['liveCalibration']
self._path_offset_z = live_calib.height[0] if live_calib.height else HEIGHT_INIT[0]
@@ -118,7 +116,7 @@ class ModelRenderer(Widget):
model = sm['modelV2']
radar_state = sm['radarState'] if sm.valid['radarState'] else None
lead_one = radar_state.leadOne if radar_state else None
render_lead_indicator = self._longitudinal_control and radar_state is not None
render_lead_indicator = self._longitudinal_control and radar_state is not None and lead_indicator_enabled(self._params)
# Update model data when needed
model_updated = sm.updated['modelV2']
@@ -244,13 +242,22 @@ class ModelRenderer(Widget):
def _update_experimental_gradient(self):
"""Pre-calculate experimental mode gradient colors"""
use_acceleration = self._experimental_mode or self._params.get_bool('AccelerationPath', default=True)
use_rainbow = self._params.get_bool('RainbowPath') and not use_acceleration
use_rainbow = self._params.get_bool('RainbowPath', default=False)
use_acceleration = not use_rainbow and (self._experimental_mode or self._params.get_bool('AccelerationPath', default=True))
if not use_acceleration and not use_rainbow:
return
max_len = min(len(self._path.projected_points) // 2, len(self._acceleration_x))
if use_rainbow:
gradient_bottom, gradient_top = self._get_visible_gradient_bounds()
self._exp_gradient = self._build_rainbow_gradient(gradient_bottom, gradient_top)
return
custom_theme_selected = (self._params.get('ColorScheme', encoding='utf-8', default='stock') or 'stock').lower() != 'stock'
path_color = None
if custom_theme_selected or get_param_color(self._params, 'PathColor', 255) is not None:
path_color = get_visual_color(self._params, 'PathColor', 'Path', rl.Color(48, 255, 156, 255))
segment_colors = []
gradient_stops = []
@@ -266,16 +273,9 @@ class ModelRenderer(Widget):
# Calculate color based on acceleration (0 is bottom, 1 is top)
lin_grad_point = 1 - (track_y - self._rect.y) / self._rect.height
if use_rainbow:
# Rainbow: hue based on gradient position + animated offset
self._rainbow_hue_offset += self._speed * 0.02
if self._rainbow_hue_offset >= 360.0:
self._rainbow_hue_offset = self._rainbow_hue_offset % 360.0
path_hue = (lin_grad_point * 120.0 + self._rainbow_hue_offset) % 360.0
saturation = 1.0
lightness = 0.5
alpha = np.interp(lin_grad_point, [0.0, 1.0], [0.5, 0.1])
color = self._hsla_to_color(path_hue / 360.0, saturation, lightness, alpha)
if path_color is not None and abs(self._acceleration_x[i]) < 0.25:
alpha = np.interp(lin_grad_point, [0.0, 1.0], [path_color.a, path_color.a * 0.10])
color = with_alpha(path_color, int(alpha))
gradient_stops.append(lin_grad_point)
segment_colors.append(color)
i += 1 + (1 if (i + 2) < max_len else 0)
@@ -305,6 +305,38 @@ class ModelRenderer(Widget):
stops=gradient_stops,
)
def _get_visible_gradient_bounds(self) -> tuple[float, float]:
if self._path.projected_points.size == 0:
return 1.0, 0.0
polygon_y = self._path.projected_points[:, 1]
visible_track_y = polygon_y[(polygon_y >= self._rect.y) & (polygon_y <= (self._rect.y + self._rect.height))]
if visible_track_y.size == 0:
return 1.0, 0.0
gradient_bottom = np.clip((float(np.max(visible_track_y)) - self._rect.y) / self._rect.height, 0.0, 1.0)
gradient_top = np.clip((float(np.min(visible_track_y)) - self._rect.y) / self._rect.height, 0.0, 1.0)
return float(gradient_bottom), float(gradient_top)
def _build_rainbow_gradient(self, gradient_bottom: float, gradient_top: float) -> Gradient:
hue_offset = (rl.get_time() * RAINBOW_SCROLL_SPEED_DEG_PER_SEC) % 360.0
stops = [i / (RAINBOW_GRADIENT_COLOR_COUNT - 1) for i in range(RAINBOW_GRADIENT_COLOR_COUNT)]
colors = []
for i, stop in enumerate(stops):
hue_progress = i / RAINBOW_GRADIENT_COLOR_COUNT
path_hue = (hue_progress * 360.0 - hue_offset) % 360.0
alpha = np.interp(stop, [0.0, 1.0], [0.48, 0.18])
colors.append(self._hsla_to_color(path_hue / 360.0, 1.0, 0.5, alpha))
return Gradient(
start=(0.0, gradient_bottom),
end=(0.0, gradient_top),
colors=colors,
stops=stops,
)
def _update_lead_vehicle(self, d_rel, v_rel, point, rect):
speed_buff, lead_buff = 10.0, 40.0
@@ -331,7 +363,7 @@ class ModelRenderer(Widget):
def _draw_lane_lines(self):
"""Draw lane lines and road edges"""
lane_lines_color = get_theme_color("LaneLines", rl.WHITE)
lane_lines_color = get_visual_color(self._params, "LaneLinesColor", "LaneLines", rl.WHITE)
for i, lane_line in enumerate(self._lane_lines):
if lane_line.projected_points.size == 0:
@@ -357,15 +389,17 @@ class ModelRenderer(Widget):
allow_throttle = sm['longitudinalPlan'].allowThrottle or not self._longitudinal_control
self._blend_filter.update(int(allow_throttle))
use_accel_path = self._params.get_bool('AccelerationPath', default=True)
use_rainbow = self._params.get_bool('RainbowPath', default=False)
use_accel_path = not use_rainbow and self._params.get_bool('AccelerationPath', default=True)
path_override = get_param_color(self._params, 'PathColor', 255)
custom_theme_selected = (self._params.get('ColorScheme', encoding='utf-8', default='stock') or 'stock').lower() != 'stock'
if self._experimental_mode or use_accel_path:
if use_rainbow or self._experimental_mode or use_accel_path:
if len(self._exp_gradient.colors) > 1:
draw_polygon(self._rect, self._path.projected_points, gradient=self._exp_gradient)
else:
draw_polygon(self._rect, self._path.projected_points, rl.Color(255, 255, 255, 30))
elif custom_theme_selected:
path_color = get_theme_color("Path", rl.Color(48, 255, 156, 255))
elif path_override is not None or custom_theme_selected:
path_color = get_visual_color(self._params, "PathColor", "Path", rl.Color(48, 255, 156, 255))
gradient = Gradient(
start=(0.0, 1.0),
end=(0.0, 0.0),
+5 -2
View File
@@ -6,7 +6,7 @@ import numpy as np
import pyray as rl
from openpilot.selfdrive.ui.lib.starpilot_state import starpilot_state
from openpilot.selfdrive.ui.lib.starpilot_theme import get_theme_color, with_alpha
from openpilot.selfdrive.ui.lib.starpilot_theme import get_param_color, get_theme_color, with_alpha
from openpilot.selfdrive.ui.ui_state import ui_state
from openpilot.system.ui.lib.shader_polygon import draw_polygon, Gradient
@@ -177,8 +177,11 @@ def render_path_edges(renderer) -> None:
elif ui_state.traffic_mode_enabled:
base_color = rl.Color(201, 34, 49, 241)
else:
override = get_param_color(renderer._params, "PathEdgesColor", 241)
color_scheme = renderer._params.get("ColorScheme", encoding="utf-8", default="stock")
if color_scheme != "stock":
if override is not None:
base_color = rl.Color(override.r, override.g, override.b, 241)
elif color_scheme != "stock":
theme_color = get_theme_color("PathEdge", rl.Color(23, 134, 68, 241))
base_color = rl.Color(theme_color.r, theme_color.g, theme_color.b, 241)
else:
BIN
View File
Binary file not shown.
@@ -1608,6 +1608,14 @@
"ui_type": "toggle",
"parent_key": "CustomUI"
},
{
"key": "RainbowPath",
"label": "Rainbow Road",
"description": "Color the driving path like a rainbow road.\n\nOn the Python UIs this overrides acceleration and braking path coloring.",
"data_type": "bool",
"ui_type": "toggle",
"parent_key": "CustomUI"
},
{
"key": "AdjacentPath",
"label": "Adjacent Lanes",
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+4
View File
@@ -142,11 +142,13 @@ LKASButtonControl
LaneChangeTime
LaneChanges
LaneDetectionWidth
LaneLinesColor
LaneLinesWidth
LanguageSetting
LateralTune
LeadDepartingAlert
LeadDetectionThreshold
LeadIndicator
LeadInfo
LiveDelay
LiveParameters
@@ -197,6 +199,8 @@ OneLaneChange
OnroadDistanceButton
OpenpilotEnabledToggle
OverpassRequests
PathColor
PathEdgesColor
PathEdgeWidth
PathWidth
PauseAOLOnBrake