mirror of
https://github.com/sunnypilot/sunnypilot.git
synced 2026-07-23 18:42:10 +08:00
Merge branch 'master' into ccnc-port
This commit is contained in:
@@ -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}},
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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]]
|
||||
|
||||
Reference in New Issue
Block a user