Merge branch 'master' into ccnc-port

This commit is contained in:
royjr
2026-02-24 14:12:12 -05:00
7 changed files with 65 additions and 66 deletions
+1 -1
View File
@@ -190,7 +190,7 @@ inline static std::unordered_map<std::string, ParamKeyAttributes> keys = {
// Model Manager params
{"ModelManager_ActiveBundle", {PERSISTENT, JSON}},
{"ModelManager_ClearCache", {CLEAR_ON_MANAGER_START, BOOL}},
{"ModelManager_DownloadIndex", {CLEAR_ON_MANAGER_START | CLEAR_ON_ONROAD_TRANSITION, INT, "0"}},
{"ModelManager_DownloadIndex", {CLEAR_ON_MANAGER_START | CLEAR_ON_ONROAD_TRANSITION, INT}},
{"ModelManager_Favs", {PERSISTENT | BACKUP, STRING}},
{"ModelManager_LastSyncTime", {CLEAR_ON_MANAGER_START | CLEAR_ON_OFFROAD_TRANSITION, INT, "0"}},
{"ModelManager_ModelsCache", {PERSISTENT | BACKUP, JSON}},
+5 -2
View File
@@ -48,14 +48,14 @@ class VCruiseHelper(VCruiseHelperSP):
self.get_minimum_set_speed(is_metric)
_enabled = self.update_enabled_state(CS, enabled)
if CS.cruiseState.available:
_enabled = self.update_enabled_state(CS, enabled)
if not self.CP.pcmCruise or (not self.CP_SP.pcmCruiseSpeed and _enabled):
# if stock cruise is completely disabled, then we can use our own set speed logic
self._update_v_cruise_non_pcm(CS, _enabled, is_metric)
self.update_speed_limit_assist_v_cruise_non_pcm()
self.v_cruise_cluster_kph = self.v_cruise_kph
self.update_button_timers(CS, enabled)
else:
self.v_cruise_kph = CS.cruiseState.speed * CV.MS_TO_KPH
self.v_cruise_cluster_kph = CS.cruiseState.speedCluster * CV.MS_TO_KPH
@@ -69,6 +69,9 @@ class VCruiseHelper(VCruiseHelperSP):
self.v_cruise_kph = V_CRUISE_UNSET
self.v_cruise_cluster_kph = V_CRUISE_UNSET
if not self.CP.pcmCruise or not self.CP_SP.pcmCruiseSpeed:
self.update_button_timers(CS, enabled)
def _update_v_cruise_non_pcm(self, CS, enabled, is_metric):
# handle button presses. TODO: this should be in state_control, but a decelCruise press
# would have the effect of both enabling and changing speed is checked after the state transition
@@ -25,7 +25,6 @@ class SmartCruiseControlRenderer(Widget):
self.long_override = False
self.font = gui_app.font(FontWeight.BOLD)
self.scc_tex = rl.load_render_texture(256, 128)
def update(self):
sm = ui_state.sm
@@ -65,44 +64,24 @@ class SmartCruiseControlRenderer(Widget):
sz = measure_text_cached(self.font, text, font_size)
box_height = int(sz.y + padding_v * 2)
texture_width = 256
texture_height = 128
rl.begin_texture_mode(self.scc_tex)
rl.clear_background(rl.Color(0, 0, 0, 0))
if self.long_override:
box_color = COLORS.OVERRIDE
else:
box_color = rl.Color(0, 255, 0, 255)
# Center box in texture
box_x = (texture_width - box_width) // 2
box_y = (texture_height - box_height) // 2
screen_y = rect_height / 4 + y_offset
box_x = rect_center_x + x_offset - box_width / 2
box_y = screen_y - box_height / 2
# Draw rounded background box
rl.draw_rectangle_rounded(rl.Rectangle(box_x, box_y, box_width, box_height), 0.2, 10, box_color)
# Draw text with custom blend mode to punch hole
rl.rl_set_blend_factors(rl.RL_ZERO, rl.RL_ONE_MINUS_SRC_ALPHA, 0x8006)
rl.rl_set_blend_mode(rl.BLEND_CUSTOM)
# Draw text centered in the box (black color for contrast against bright green/grey)
text_pos_x = box_x + (box_width - sz.x) / 2
text_pos_y = box_y + (box_height - sz.y) / 2
rl.draw_text_ex(self.font, text, rl.Vector2(text_pos_x, text_pos_y), font_size, 0, rl.WHITE)
rl.rl_set_blend_mode(rl.BLEND_ALPHA) # Reset
rl.end_texture_mode()
screen_y = rect_height / 4 + y_offset
dest_x = rect_center_x + x_offset - texture_width / 2
dest_y = screen_y - texture_height / 2
src_rect = rl.Rectangle(0, 0, texture_width, -texture_height)
dst_rect = rl.Rectangle(dest_x, dest_y, texture_width, texture_height)
rl.draw_texture_pro(self.scc_tex.texture, src_rect, dst_rect, rl.Vector2(0, 0), 0, rl.WHITE)
rl.draw_text_ex(self.font, text, rl.Vector2(text_pos_x, text_pos_y), font_size, 0, rl.BLACK)
def _render(self, rect: rl.Rectangle):
x_offset = -260
+46 -30
View File
@@ -4,6 +4,7 @@ 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.
"""
from dataclasses import dataclass
import math
import pyray as rl
@@ -22,6 +23,8 @@ from openpilot.system.ui.widgets import Widget
METER_TO_FOOT = 3.28084
METER_TO_MILE = 0.000621371
AHEAD_THRESHOLD = 5
SET_SPEED_NA = 255
KM_TO_MILE = 0.621371
AssistState = custom.LongitudinalPlanSP.SpeedLimit.AssistState
SpeedLimitSource = custom.LongitudinalPlanSP.SpeedLimit.Source
@@ -31,7 +34,7 @@ SpeedLimitSource = custom.LongitudinalPlanSP.SpeedLimit.Source
class Colors:
WHITE = rl.WHITE
BLACK = rl.BLACK
RED = rl.RED
RED = rl.Color(235, 32, 32, 255)
GREY = rl.Color(145, 155, 149, 255)
DARK_GREY = rl.Color(77, 77, 77, 255)
SUB_BG = rl.Color(0, 0, 0, 180)
@@ -58,8 +61,11 @@ class SpeedLimitRenderer(Widget):
self.speed_limit_ahead_frame = 0
self.assist_frame = 0
self.speed = 0.0
self.set_speed = 0.0
self.is_cruise_set: bool = False
self.is_cruise_available: bool = True
self.set_speed: float = SET_SPEED_NA
self.speed: float = 0.0
self.v_ego_cluster_seen: bool = False
self.font_bold = gui_app.font(FontWeight.BOLD)
self.font_demi = gui_app.font(FontWeight.SEMI_BOLD)
@@ -77,6 +83,8 @@ class SpeedLimitRenderer(Widget):
def update(self):
sm = ui_state.sm
if sm.recv_frame["carState"] < ui_state.started_frame:
self.set_speed = SET_SPEED_NA
self.speed = 0.0
return
if sm.updated["longitudinalPlanSP"]:
@@ -106,9 +114,21 @@ class SpeedLimitRenderer(Widget):
self.speed_limit_ahead_dist_prev = self.speed_limit_ahead_dist
cs = sm["carState"]
self.set_speed = cs.cruiseState.speed * self.speed_conv
v_ego = cs.vEgoCluster if cs.vEgoCluster != 0.0 else cs.vEgo
controls_state = sm['controlsState']
car_state = sm["carState"]
v_cruise_cluster = car_state.vCruiseCluster
self.set_speed = (
controls_state.vCruiseDEPRECATED if v_cruise_cluster == 0.0 else v_cruise_cluster
)
self.is_cruise_set = 0 < self.set_speed < SET_SPEED_NA
self.is_cruise_available = self.set_speed != -1
if self.is_cruise_set and not ui_state.is_metric:
self.set_speed *= KM_TO_MILE
self.v_ego_cluster_seen = self.v_ego_cluster_seen or car_state.vEgoCluster != 0.0
v_ego = car_state.vEgoCluster if self.v_ego_cluster_seen else car_state.vEgo
self.speed = max(0.0, v_ego * self.speed_conv)
@staticmethod
@@ -182,22 +202,17 @@ class SpeedLimitRenderer(Widget):
center = rl.Vector2(rect.x + rect.width / 2, rect.y + rect.height / 2)
radius = (rect.width + 18) / 2
white = rl.Color(255, 255, 255, int(255 * alpha))
red = rl.Color(255, 0, 0, int(255 * alpha))
if hasattr(color, 'r'):
text_color = rl.Color(color.r, color.g, color.b, int(255 * alpha))
else:
text_color = rl.Color(color[0], color[1], color[2], int(255 * alpha))
black = rl.Color(0, 0, 0, int(255 * alpha))
dark_grey = rl.Color(77, 77, 77, int(255 * alpha))
white = rl.color_alpha(Colors.WHITE, alpha)
red = rl.color_alpha(Colors.RED, alpha)
black = rl.color_alpha(Colors.BLACK, alpha)
dark_grey = rl.color_alpha(Colors.DARK_GREY, alpha)
text_color = rl.color_alpha(color, alpha)
rl.draw_circle_v(center, radius, white)
rl.draw_ring(center, radius * 0.80, radius, 0, 360, 36, red)
rl.draw_ring(center, radius * 0.75, radius, 0, 360, 36, red)
f_size = 70 if len(val) >= 3 else 85
self._draw_text_centered(self.font_bold, val, f_size, center, text_color)
font_size = 70 if len(val) >= 3 else 85
self._draw_text_centered(self.font_bold, val, font_size, center, text_color)
if sub and has_limit:
s_radius = radius * 0.4
@@ -206,22 +221,23 @@ class SpeedLimitRenderer(Widget):
rl.draw_circle_v(s_center, s_radius, black)
rl.draw_ring(s_center, s_radius - 3, s_radius, 0, 360, 36, dark_grey)
f_scale = 0.5 if len(sub) < 3 else 0.45
self._draw_text_centered(self.font_bold, sub, int(s_radius * 2 * f_scale), s_center, white)
font_scale = 0.5 if len(sub) < 3 else 0.45
self._draw_text_centered(self.font_bold, sub, int(s_radius * 2 * font_scale), s_center, white)
def _render_mutcd(self, rect, val, sub, color, has_limit, alpha=1.0):
white = rl.Color(255, 255, 255, int(255 * alpha))
black = rl.Color(0, 0, 0, int(255 * alpha))
dark_grey = rl.Color(77, 77, 77, int(255 * alpha))
if hasattr(color, 'r'):
text_color = rl.Color(color.r, color.g, color.b, int(255 * alpha))
else:
text_color = rl.Color(color[0], color[1], color[2], int(255 * alpha))
white = rl.color_alpha(Colors.WHITE, alpha)
black = rl.color_alpha(Colors.BLACK, alpha)
dark_grey = rl.color_alpha(Colors.DARK_GREY, alpha)
text_color = rl.color_alpha(color, alpha)
rl.draw_rectangle_rounded(rect, 0.35, 10, white)
inner = rl.Rectangle(rect.x + 10, rect.y + 10, rect.width - 20, rect.height - 20)
rl.draw_rectangle_rounded_lines_ex(inner, 0.35, 10, 4, black)
outer_radius = 0.35 * rect.width / 2.0
inner_radius = outer_radius - 10.0
inner_roundness = inner_radius / (inner.width / 2.0)
rl.draw_rectangle_rounded_lines_ex(inner, inner_roundness, 10, 4, black)
self._draw_text_centered(self.font_demi, "SPEED", 40, rl.Vector2(rect.x + rect.width / 2, rect.y + 40), black)
self._draw_text_centered(self.font_demi, "LIMIT", 40, rl.Vector2(rect.x + rect.width / 2, rect.y + 80), black)
+1 -1
View File
@@ -171,7 +171,7 @@ class ModelManagerSP:
self.available_models = self.model_fetcher.get_available_bundles()
self.active_bundle = get_active_bundle(self.params)
if index_to_download := self.params.get("ModelManager_DownloadIndex"):
if (index_to_download := self.params.get("ModelManager_DownloadIndex")) is not None:
if model_to_download := next((model for model in self.available_models if model.index == index_to_download), None):
try:
self.download(model_to_download, Paths.model_root())
@@ -44,7 +44,8 @@ class OptionControlSP(ItemAction):
self.current_value = int(key)
break
else:
self.current_value = int(self.params.get(self.param_key, return_default=True))
value = self.params.get(self.param_key, return_default=True)
self.current_value = int(float(value) * 100.0) if self.use_float_scaling else int(value)
# Initialize font and button styles
self._font = gui_app.font(FontWeight.MEDIUM)
Generated
+3 -3
View File
@@ -414,11 +414,11 @@ wheels = [
[[package]]
name = "filelock"
version = "3.24.2"
version = "3.24.3"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/02/a8/dae62680be63cbb3ff87cfa2f51cf766269514ea5488479d42fec5aa6f3a/filelock-3.24.2.tar.gz", hash = "sha256:c22803117490f156e59fafce621f0550a7a853e2bbf4f87f112b11d469b6c81b", size = 37601, upload-time = "2026-02-16T02:50:45.614Z" }
sdist = { url = "https://files.pythonhosted.org/packages/73/92/a8e2479937ff39185d20dd6a851c1a63e55849e447a55e798cc2e1f49c65/filelock-3.24.3.tar.gz", hash = "sha256:011a5644dc937c22699943ebbfc46e969cdde3e171470a6e40b9533e5a72affa", size = 37935, upload-time = "2026-02-19T00:48:20.543Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/e7/04/a94ebfb4eaaa08db56725a40de2887e95de4e8641b9e902c311bfa00aa39/filelock-3.24.2-py3-none-any.whl", hash = "sha256:667d7dc0b7d1e1064dd5f8f8e80bdac157a6482e8d2e02cd16fd3b6b33bd6556", size = 24152, upload-time = "2026-02-16T02:50:44Z" },
{ url = "https://files.pythonhosted.org/packages/9c/0f/5d0c71a1aefeb08efff26272149e07ab922b64f46c63363756224bd6872e/filelock-3.24.3-py3-none-any.whl", hash = "sha256:426e9a4660391f7f8a810d71b0555bce9008b0a1cc342ab1f6947d37639e002d", size = 24331, upload-time = "2026-02-19T00:48:18.465Z" },
]
[[package]]