diff --git a/selfdrive/ui/sunnypilot/layouts/settings/models.py b/selfdrive/ui/sunnypilot/layouts/settings/models.py
index 3b6326d37a..4a1db72d82 100644
--- a/selfdrive/ui/sunnypilot/layouts/settings/models.py
+++ b/selfdrive/ui/sunnypilot/layouts/settings/models.py
@@ -4,6 +4,7 @@ import pyray as rl
from cereal import messaging, car, custom
from openpilot.common.params import Params
+from openpilot.common.constants import CV
from openpilot.system.ui.lib.multilang import tr
from openpilot.system.ui.lib.application import gui_app
from openpilot.system.ui.widgets import DialogResult, Widget
@@ -41,37 +42,27 @@ class ModelsLayout(Widget):
self.navigation_label = progress_item(tr("Navigation Model"))
self.vision_label = progress_item(tr("Vision Model"))
self.policy_label = progress_item(tr("Policy Model"))
- self.lane_turn_desire_toggle = toggle_item_sp(tr("Use Lane Turn Desires"),
- tr("If you're driving at 20 mph (32 km/h) or below and have your blinker on, " +
- "the car will plan a turn in that direction at the nearest drivable path. " +
- "This prevents situations (like at red lights) where the car might plan the wrong turn direction."),
- callback=self._on_lane_turn_desire_changed, param="LaneTurnDesire")
- max_value_mph = 20
- is_metric = self._params.get_bool("IsMetric")
- per_value_change = 100 if not is_metric else int(round(100 / 1.609344))
- self.lane_turn_value_control = option_item_sp(tr("Adjust Lane Turn Speed"), "LaneTurnValue", 5 * 100, max_value_mph * 100,
- tr("Set the maximum speed for lane turn desires. Default is 19 mph."),
- per_value_change, None, True, "", style.BUTTON_WIDTH, None, True,
- lambda v: self._format_lane_turn_label(v / 100))
- self.lagd_toggle = toggle_item_sp(tr("Live Learning Steer Delay"), "", callback=self._on_lagd_changed, param="LagdToggle")
- self.delay_control = option_item_sp(tr("Adjust Software Delay"), "LagdToggleDelay", 5, 50,
- tr("Adjust the software delay when Live Learning Steer Delay is toggled off. " +
- "The default software delay value is 0.2"),
- 1, None, True, "", style.BUTTON_WIDTH, None, True,
- lambda v: f"{v/100:.2f}s")
- self.items = [
- self.current_model_item,
- self.refresh_item,
- self.clear_cache_item,
- self.supercombo_label,
- self.vision_label,
- self.policy_label,
- self.lane_turn_desire_toggle,
- self.lane_turn_value_control,
- self.lagd_toggle,
- self.delay_control,
- ]
+ self.lane_turn_desire_toggle = toggle_item_sp(tr("Use Lane Turn Desires"),
+ tr("If you're driving at 20 mph (32 km/h) or below and have your blinker on, the car will plan a turn in that direction at the nearest drivable path. " +
+ "This prevents situations (like at red lights) where the car might plan the wrong turn direction."),
+ callback=lambda s: self.lane_turn_value_control.set_visible(s), param="LaneTurnDesire")
+
+ self.lane_turn_value_control = option_item_sp(tr("Adjust Lane Turn Speed"), "LaneTurnValue", 500, 2000,
+ tr("Set the maximum speed for lane turn desires. Default is 19 mph."),
+ int(round(100 / CV.MPH_TO_KPH)), None, True, "", style.BUTTON_WIDTH, None, True,
+ lambda v: self._format_lane_turn_label(v / 100))
+
+ self.lagd_toggle = toggle_item_sp(tr("Live Learning Steer Delay"), "",
+ callback=lambda s: (self.delay_control.set_visible(not s), self._update_lagd_description()), param="LagdToggle")
+
+ self.delay_control = option_item_sp(tr("Adjust Software Delay"), "LagdToggleDelay", 5, 50,
+ tr("Adjust the software delay when Live Learning Steer Delay is toggled off. The default software delay value is 0.2"),
+ 1, None, True, "", style.BUTTON_WIDTH, None, True, lambda v: f"{v/100:.2f}s")
+
+ self.items = [self.current_model_item, self.refresh_item, self.clear_cache_item, self.supercombo_label,
+ self.vision_label, self.policy_label, self.lane_turn_desire_toggle, self.lane_turn_value_control,
+ self.lagd_toggle, self.delay_control]
def _render(self, rect):
self._scroller.render(rect)
@@ -82,98 +73,71 @@ class ModelsLayout(Widget):
self.update_labels()
def update_labels(self):
+ self._update_lane_turn_step()
self.update_model_manager_state()
self.handle_bundle_download_progress()
self.current_model_item.action_item.set_value(self.get_active_model_internal_name())
self.clear_cache_item.action_item.set_value(f"{self.calculate_cache_size():.2f} MB")
self._update_lagd_description()
+ def _update_lane_turn_step(self):
+ new_step = int(round(100 / CV.MPH_TO_KPH)) if self._params.get_bool("IsMetric") else 100
+ if self.lane_turn_value_control.action_item.option_control.value_change_step != new_step:
+ self.lane_turn_value_control.action_item.option_control.value_change_step = new_step
+
def _update_lagd_description(self):
- desc = tr("Enable this for the car to learn and adapt its steering response time. " +
- "Disable to use a fixed steering response time. Keeping this on provides the stock openpilot experience.")
+ desc = tr("Enable this for the car to learn and adapt its steering response time. Disable to use a fixed steering response time. " +
+ "Keeping this on provides the stock openpilot experience.")
if self._params.get_bool("LagdToggle"):
- live_delay = ui_state.sm["liveDelay"].lateralDelay
- desc += f"
{tr('Live Steer Delay:')} {live_delay:.3f} s"
- else:
- car_params_bytes = self._params.get("CarParamsPersistent")
- if car_params_bytes:
- carparams = messaging.log_from_bytes(car_params_bytes, car.CarParams)
- steer_delay = carparams.steerActuatorDelay
- software_delay = float(self._params.get("LagdToggleDelay", "0.2"))
- total_lag = steer_delay + software_delay
- desc += (f"
{tr('Actuator Delay:')} {steer_delay:.2f} s + " +
- f"{tr('Software Delay:')} {software_delay:.2f} s = " +
- f"{tr('Total Delay:')} {total_lag:.2f} s")
+ desc += f"
{tr('Live Steer Delay:')} {ui_state.sm['liveDelay'].lateralDelay:.3f} s"
+ elif (cp := self._params.get("CarParamsPersistent")):
+ cp = messaging.log_from_bytes(cp, car.CarParams)
+ sw_delay = float(self._params.get("LagdToggleDelay", "0.2"))
+ desc += (f"
{tr('Actuator Delay:')} {cp.steerActuatorDelay:.2f} s + {tr('Software Delay:')} {sw_delay:.2f} s = " +
+ f"{tr('Total Delay:')} {cp.steerActuatorDelay + sw_delay:.2f} s")
self.lagd_toggle.set_description(desc)
- def _on_lane_turn_desire_changed(self, state):
- self.lane_turn_value_control.set_visible(state)
-
- def _on_lagd_changed(self, state):
- self.delay_control.set_visible(not state)
- self._update_lagd_description()
-
def _format_lane_turn_label(self, mph):
is_metric = self._params.get_bool("IsMetric")
- unit = "km/h" if is_metric else "mph"
- display_value = mph
- if is_metric:
- display_value *= 1.609344
- return f"{int(round(display_value))} {unit}"
+ return f"{int(round(mph * (CV.MPH_TO_KPH if is_metric else 1)))} {'km/h' if is_metric else 'mph'}"
def update_model_manager_state(self):
self.model_manager = ui_state.sm["modelManagerSP"]
def handle_bundle_download_progress(self):
- labels = {
- custom.ModelManagerSP.Model.Type.supercombo: self.supercombo_label,
- custom.ModelManagerSP.Model.Type.vision: self.vision_label,
- custom.ModelManagerSP.Model.Type.policy: self.policy_label,
- }
-
- for label in labels.values():
- label.set_visible(False)
+ labels = {custom.ModelManagerSP.Model.Type.supercombo: self.supercombo_label,
+ custom.ModelManagerSP.Model.Type.vision: self.vision_label,
+ custom.ModelManagerSP.Model.Type.policy: self.policy_label}
+ for l in labels.values():
+ l.set_visible(False)
if not self.model_manager or (not self.model_manager.selectedBundle and not self.model_manager.activeBundle):
return
- show_selected = (self.model_manager.selectedBundle and
- (self.is_downloading() or
- self.model_manager.selectedBundle.status == custom.ModelManagerSP.DownloadStatus.failed))
- bundle = self.model_manager.selectedBundle if show_selected else self.model_manager.activeBundle
- models = bundle.models
+ bundle = self.model_manager.activeBundle
+ if (sb := self.model_manager.selectedBundle) and (self.is_downloading() or sb.status == custom.ModelManagerSP.DownloadStatus.failed):
+ bundle = sb
+
self.download_status = bundle.status
- download_status_changed = self.prev_download_status != self.download_status
+ status_changed = self.prev_download_status != self.download_status
- for model in models:
- model_name = bundle.displayName
- model_type = model.type.raw if hasattr(model.type, 'raw') else model.type
- label = labels.get(model_type)
- if label:
+ for model in bundle.models:
+ if label := labels.get(model.type.raw if hasattr(model.type, 'raw') else model.type):
label.set_visible(True)
- progress = model.artifact.downloadProgress
+ p = model.artifact.downloadProgress
+ name = bundle.displayName
- text_color = rl.BLACK
- show_progress = False
+ text, show, color = f"pending - {name}", False, rl.BLACK
+ if p.status == custom.ModelManagerSP.DownloadStatus.downloading:
+ text, show = f"{int(p.progress)}% - {name}", True
+ elif p.status == custom.ModelManagerSP.DownloadStatus.downloaded:
+ text, color = f"{name} - {tr('downloaded') if status_changed else tr('ready')}", rl.Color(51, 171, 76, 255)
+ elif p.status == custom.ModelManagerSP.DownloadStatus.cached:
+ text, color = f"{name} - {tr('from cache') if status_changed else tr('ready')}", rl.Color(51, 171, 76, 255)
+ elif p.status == custom.ModelManagerSP.DownloadStatus.failed:
+ text, color = f"download failed - {name}", rl.RED
- if progress.status == custom.ModelManagerSP.DownloadStatus.downloading:
- text = f"{int(progress.progress)}% - {model_name}"
- show_progress = True
- elif progress.status == custom.ModelManagerSP.DownloadStatus.downloaded:
- status = tr("downloaded") if download_status_changed else tr("ready")
- text = f"{model_name} - {status}"
- text_color = rl.Color(51, 171, 76, 255)
- elif progress.status == custom.ModelManagerSP.DownloadStatus.cached:
- status = tr("from cache") if download_status_changed else tr("ready")
- text = f"{model_name} - {status}"
- text_color = rl.Color(51, 171, 76, 255)
- elif progress.status == custom.ModelManagerSP.DownloadStatus.failed:
- text = f"download failed - {model_name}"
- text_color = rl.RED
- else:
- text = f"pending - {model_name}"
-
- label.action_item.update(progress.progress, text, show_progress, text_color)
+ label.action_item.update(p.progress, text, show, color)
self.prev_download_status = self.download_status