diff --git a/openpilot/common/pid.py b/openpilot/common/pid.py
index b5bb0e00b..f2765fdd7 100644
--- a/openpilot/common/pid.py
+++ b/openpilot/common/pid.py
@@ -60,16 +60,11 @@ class PIDController:
class MultiplicativeUnwindPID:
- def __init__(self, k_p, k_i, k_f=0., k_d=0., pos_limit=1e308, neg_limit=-1e308, rate=100, min_cmd=1e-10, ki_red_time=1.0):
- if isinstance(k_p, Number):
- k_p = [[0], [k_p]]
- if isinstance(k_i, Number):
- k_i = [[0], [k_i]]
- if isinstance(k_d, Number):
- k_d = [[0], [k_d]]
- self._k_p = k_p
- self._k_i = k_i
- self._k_d = k_d
+ def __init__(self, k_p: Gain, k_i: Gain, k_f=0., k_d: Gain = 0., pos_limit=1e308, neg_limit=-1e308,
+ rate=100, min_cmd=1e-10, ki_red_time=1.0):
+ self._k_p = ([0], [k_p]) if isinstance(k_p, (int, float)) else k_p
+ self._k_i = ([0], [k_i]) if isinstance(k_i, (int, float)) else k_i
+ self._k_d = ([0], [k_d]) if isinstance(k_d, (int, float)) else k_d
self.k_f = float(k_f)
self.pos_limit = pos_limit
self.neg_limit = neg_limit
diff --git a/openpilot/common/pt2.py b/openpilot/common/pt2.py
index 14270619f..070586835 100644
--- a/openpilot/common/pt2.py
+++ b/openpilot/common/pt2.py
@@ -34,7 +34,7 @@ class PT2Filter:
=> Zeitbereich: y[k] = -a1*y[k-1] - a2*y[k-2] + b0*u[k] + b1*u[k-1] + b2*u[k-2].
"""
-
+
Ts = dt
wd = w0
alpha = 2.0 / Ts
@@ -66,14 +66,14 @@ class PT2Filter:
return (a1d, a2d, b0d, b1d, b2d)
def sync(self, target: float):
- steps = compute_saturation_steps(self.w0, self.zeta, self.dt)
- for i in range(1, steps + 1):
- update(target)
+ steps = self.compute_saturation_steps(self.w0, self.zeta, self.dt)
+ for _ in range(steps):
+ self.update(target)
def compute_saturation_steps(self, w0: float, zeta: float, dt: float) -> int:
"""
Berechnet eine Abschätzung der Schritte, bis der Filter (95% des Endwerts) erreicht ist.
-
+
Wir nutzen hier die Abschätzung:
T_s = 4 / (zeta * w0)
und setzen N = T_s / dt.
@@ -103,10 +103,10 @@ class PT2Filter:
+ self.b1 * self.u1
+ self.b2 * self.u2
)
-
+
self.y2 = self.y1
self.y1 = y
self.u2 = self.u1
self.u1 = u
-
+
return y
diff --git a/openpilot/selfdrive/controls/controlsd.py b/openpilot/selfdrive/controls/controlsd.py
index 62755531e..ac2e0dea9 100644
--- a/openpilot/selfdrive/controls/controlsd.py
+++ b/openpilot/selfdrive/controls/controlsd.py
@@ -19,13 +19,11 @@ from openpilot.selfdrive.controls.lib.latcontrol_pid import LatControlPID
from openpilot.selfdrive.controls.lib.latcontrol_angle import LatControlAngle, STEER_ANGLE_SATURATION_THRESHOLD
from openpilot.selfdrive.controls.lib.latcontrol_curvature import LatControlCurvature
from openpilot.selfdrive.controls.lib.latcontrol_torque import LatControlTorque
-from openpilot.selfdrive.controls.lib.latcontrol_curvature import LatControlCurvature
from openpilot.selfdrive.controls.lib.longcontrol import LongControl
from openpilot.selfdrive.modeld.modeld import LAT_SMOOTH_SECONDS
from openpilot.selfdrive.locationd.helpers import PoseCalibrator, Pose
from openpilot.selfdrive.controls.lib.longitudinal_mpc_lib.long_mpc import get_T_FOLLOW
from openpilot.common.pt2 import PT2Filter
-from openpilot.common.realtime import DT_CTRL
from openpilot.sunnypilot.selfdrive.controls.controlsd_ext import ControlsExt
@@ -119,7 +117,7 @@ class Controls(ControlsExt):
self.force_rhd_for_bsm = self.params.get_bool("ForceRHDForBSM")
self.enable_long_comfort_mode = self.params.get_bool("EnableLongComfortMode")
self.disable_car_steer_alerts = self.params.get_bool("DisableCarSteerAlerts")
-
+
def state_control(self):
CS = self.sm['carState']
diff --git a/openpilot/selfdrive/controls/lib/latcontrol_curvature.py b/openpilot/selfdrive/controls/lib/latcontrol_curvature.py
index 05c40a130..5ea185c87 100644
--- a/openpilot/selfdrive/controls/lib/latcontrol_curvature.py
+++ b/openpilot/selfdrive/controls/lib/latcontrol_curvature.py
@@ -1,5 +1,4 @@
import math
-import numpy as np
from openpilot.cereal import log
from openpilot.common.pid import MultiplicativeUnwindPID
@@ -25,7 +24,7 @@ class LatControlCurvature(LatControl):
else:
self.pid = None
self.kf = 1.
-
+
def set_pid_enabled(self, enabled: bool) -> None:
self.enable_pid = enabled
diff --git a/openpilot/selfdrive/controls/lib/latcontrol_curvature_pid_backup.py b/openpilot/selfdrive/controls/lib/latcontrol_curvature_pid_backup.py
index 50eb23bf5..9dfeb4239 100644
--- a/openpilot/selfdrive/controls/lib/latcontrol_curvature_pid_backup.py
+++ b/openpilot/selfdrive/controls/lib/latcontrol_curvature_pid_backup.py
@@ -19,7 +19,7 @@
# def reset(self):
# super().reset()
# self.pid.reset()
-#
+#
# def update(self, active, CS, VM, params, steer_limited_by_safety, desired_curvature, calibrated_pose, curvature_limited):
# pid_log = log.ControlsState.LateralCurvatureState.new_message()
# if not active:
@@ -35,10 +35,10 @@
# actual_curvature = np.interp(CS.vEgo, [2.0, 5.0], [actual_curvature_vm, actual_curvature_pose])
#
# desired_curvature_corr = desired_curvature - roll_compensation
-#
+#
# pid_log.error = float(desired_curvature - actual_curvature)
# freeze_integrator = steer_limited_by_safety or CS.vEgo < 5 or CS.steeringPressed
-#
+#
# pid_curvature = self.pid.update(pid_log.error, feedforward=desired_curvature_corr, speed=CS.vEgo,
# freeze_integrator=freeze_integrator, override=CS.steeringPressed)
#
diff --git a/openpilot/selfdrive/controls/lib/longitudinal_planner.py b/openpilot/selfdrive/controls/lib/longitudinal_planner.py
index 19caae7a8..d2454103c 100644
--- a/openpilot/selfdrive/controls/lib/longitudinal_planner.py
+++ b/openpilot/selfdrive/controls/lib/longitudinal_planner.py
@@ -32,7 +32,7 @@ def get_max_accel(v_ego):
def get_coast_accel(pitch):
return np.sin(pitch) * -5.65 - 0.3 # fitted from data using xx/projects/allow_throttle/compute_coast_accel.py
-
+
def get_lead_distance(radarState):
if radarState.leadOne.present and (not radarState.leadTwo.present or radarState.leadOne.dRel < radarState.leadTwo.dRel):
@@ -40,7 +40,7 @@ def get_lead_distance(radarState):
if radarState.leadTwo.present:
return radarState.leadTwo.dRel
return 0
-
+
def limit_accel_in_turns(v_ego, angle_steers, a_target, CP):
"""
diff --git a/openpilot/selfdrive/controls/tests/test_curvatured.py b/openpilot/selfdrive/controls/tests/test_curvatured.py
index d0f86509b..cbea511b6 100644
--- a/openpilot/selfdrive/controls/tests/test_curvatured.py
+++ b/openpilot/selfdrive/controls/tests/test_curvatured.py
@@ -232,7 +232,7 @@ class TestCurvatureDController:
def counting(*args, **kwargs):
call_count["n"] += 1
return original(*args, **kwargs)
- CurvatureDLookup.interp_curve_value = counting
+ CurvatureDLookup.interp_curve_value = counting # ty: ignore[invalid-assignment]
try:
# First call: cache miss, calls interp_curve_value once
first = controller.get_correction(32e-6, v_ego)
diff --git a/openpilot/selfdrive/locationd/curvatured.py b/openpilot/selfdrive/locationd/curvatured.py
index 4d0f2b724..f96fb9c8e 100644
--- a/openpilot/selfdrive/locationd/curvatured.py
+++ b/openpilot/selfdrive/locationd/curvatured.py
@@ -550,7 +550,7 @@ class CurvatureEstimator(CurvatureDLookup):
self._restore_cached_params()
self.update_use_params(force=True)
- cloudlog.info(f"curvatured init brand={self.CP.brand} fingerprint={self.CP.carFingerprint} "
+ cloudlog.info(f"curvatured init brand={self.CP.brand} fingerprint={self.CP.carFingerprint} " +
f"steerControlType={self.CP.steerControlType} history={HISTORY:.2f}s")
@staticmethod
@@ -596,8 +596,8 @@ class CurvatureEstimator(CurvatureDLookup):
self.use_params = self.enable_curvatured and self.CP.brand in ALLOWED_CARS and \
self.CP.steerControlType == car.CarParams.SteerControlType.curvature
if self.prev_use_params != self.use_params:
- cloudlog.info(f"curvatured use_params={self.use_params} toggle={self.enable_curvatured} "
- f"brand={self.CP.brand} allowed={self.CP.brand in ALLOWED_CARS} "
+ cloudlog.info(f"curvatured use_params={self.use_params} toggle={self.enable_curvatured} " +
+ f"brand={self.CP.brand} allowed={self.CP.brand in ALLOWED_CARS} " +
f"steerControlType={self.CP.steerControlType}")
self.prev_use_params = self.use_params
if not self.use_params:
@@ -960,10 +960,10 @@ class CurvatureEstimator(CurvatureDLookup):
self.last_status_log_t = t
checks = sm.all_checks(tracked_services) if valid is None else valid
- cloudlog.info(f"curvatured status use_params={self.use_params} checks={checks} "
- f"lag={self.lag:.3f} total_points={int(round(float(self.counts.sum())))} "
- f"bucket={self.current_bucket} bucket_points={self.current_bucket_points} "
- f"corr={self.current_correction:.8f} cal={self.calibration_percent(self.counts)} "
+ cloudlog.info(f"curvatured status use_params={self.use_params} checks={checks} " +
+ f"lag={self.lag:.3f} total_points={int(round(float(self.counts.sum())))} " +
+ f"bucket={self.current_bucket} bucket_points={self.current_bucket_points} " +
+ f"corr={self.current_correction:.8f} cal={self.calibration_percent(self.counts)} " +
f"invalid={invalid} not_alive={not_alive}")
diff --git a/openpilot/selfdrive/locationd/paramsd.py b/openpilot/selfdrive/locationd/paramsd.py
index e6c1ff7b4..c1088a818 100755
--- a/openpilot/selfdrive/locationd/paramsd.py
+++ b/openpilot/selfdrive/locationd/paramsd.py
@@ -276,4 +276,4 @@ def main():
if __name__ == "__main__":
- main()
\ No newline at end of file
+ main()
diff --git a/openpilot/selfdrive/locationd/test/test_curvatured.py b/openpilot/selfdrive/locationd/test/test_curvatured.py
index 62145f20d..bc40ea0bb 100644
--- a/openpilot/selfdrive/locationd/test/test_curvatured.py
+++ b/openpilot/selfdrive/locationd/test/test_curvatured.py
@@ -1,5 +1,6 @@
import numpy as np
+from openpilot.cereal import custom
from opendbc.car.structs import car
from opendbc.car.volkswagen.values import CAR
@@ -233,7 +234,7 @@ class TestCurvatureEstimator:
speed_idx = len(CurvatureDLookup.SPEED_ANCHORS) - 1
v_ego = float(CurvatureDLookup.SPEED_ANCHORS[speed_idx])
required = CurvatureDLookup.required_support_bucket_count(speed_idx)
- selected_indices = list(range(0, required - 1)) + [required]
+ selected_indices = list(range(required - 1)) + [required]
for bucket_idx in selected_indices:
desired_curvature = float(CurvatureDLookup.CURVATURE_BUCKET_CENTERS[bucket_idx])
@@ -262,7 +263,6 @@ class TestCurvatureEstimator:
def test_outer_learned_buckets_stay_invalid_for_apply(self):
speed_idx = len(CurvatureDLookup.SPEED_ANCHORS) - 1
- v_ego = float(CurvatureDLookup.SPEED_ANCHORS[speed_idx])
outer_idx = len(CurvatureDLookup.CURVATURE_BUCKET_CENTERS) - 1
counts = np.zeros(CurvatureDLookup.bucket_shape(), dtype=np.float32)
bias = np.zeros(CurvatureDLookup.bucket_shape(), dtype=np.float32)
diff --git a/openpilot/selfdrive/locationd/torqued.py b/openpilot/selfdrive/locationd/torqued.py
index a1010ca55..1d4aa8bc3 100755
--- a/openpilot/selfdrive/locationd/torqued.py
+++ b/openpilot/selfdrive/locationd/torqued.py
@@ -289,4 +289,4 @@ if __name__ == "__main__":
parser = argparse.ArgumentParser(description='Process the --demo argument.')
parser.add_argument('--demo', action='store_true', help='A boolean for demo mode.')
args = parser.parse_args()
- main(demo=args.demo)
\ No newline at end of file
+ main(demo=args.demo)
diff --git a/openpilot/selfdrive/ui/layouts/settings/ictoggles.py b/openpilot/selfdrive/ui/layouts/settings/ictoggles.py
index b8d9566fa..bb8159ddd 100644
--- a/openpilot/selfdrive/ui/layouts/settings/ictoggles.py
+++ b/openpilot/selfdrive/ui/layouts/settings/ictoggles.py
@@ -1,4 +1,3 @@
-from openpilot.cereal import log
from openpilot.common.params import Params, UnknownKeyName
from openpilot.system.ui.widgets import Widget
from openpilot.system.ui.widgets.list_view import toggle_item
@@ -16,7 +15,8 @@ DESCRIPTIONS = {
"Enables curvature PID post-processing additionally to QFK curvature offset"
),
"EnableCurvatureD": tr_noop(
- "Learns speed- and curvature-dependent steering corrections around center for dynamic steering behavior. Experimental and only used on curvature-based steering paths."
+ "Learns speed- and curvature-dependent steering corrections around center for dynamic steering behavior. " +
+ "Experimental and only used on curvature-based steering paths."
),
"ShowDynamicSteeringLearnerGraph": tr_noop(
"Display the current dynamic steering learner fit, marker, and status information in the onroad UI."
diff --git a/openpilot/selfdrive/ui/layouts/settings/software.py b/openpilot/selfdrive/ui/layouts/settings/software.py
index 41badce55..ab8cf6fb4 100644
--- a/openpilot/selfdrive/ui/layouts/settings/software.py
+++ b/openpilot/selfdrive/ui/layouts/settings/software.py
@@ -100,15 +100,15 @@ class SoftwareLayout(Widget):
self._version_item.action_item.set_text(current_desc)
self._version_item.set_description(current_release_notes)
- # Update download button visibility and state
- self._download_btn.set_visible(ui_state.is_offroad())
- self._force_download_btn.set_visible(ui_state.is_offroad())
-
updater_state = ui_state.params.get("UpdaterState") or "idle"
failed_count = ui_state.params.get("UpdateFailedCount") or 0
fetch_available = ui_state.params.get_bool("UpdaterFetchAvailable")
update_available = ui_state.params.get_bool("UpdateAvailable")
+ # Update download button visibility and state
+ self._download_btn.set_visible(ui_state.is_offroad())
+ self._force_download_btn.set_visible(ui_state.is_offroad() and not update_available)
+
if updater_state != "idle":
# Updater responded
self._waiting_for_updater = False
@@ -189,7 +189,7 @@ class SoftwareLayout(Widget):
self._force_download_btn.action_item.set_enabled(False)
self._waiting_for_updater = True
self._waiting_start_ts = time.monotonic()
- os.system("pkill -SIGUSR2 -f system.updated.updated")
+ subprocess.run("pkill -SIGUSR2 -f openpilot.system.updated.updated", shell=True)
def _on_select_branch(self):
# Get available branches and order
diff --git a/openpilot/selfdrive/ui/mici/layouts/settings/ictoggles.py b/openpilot/selfdrive/ui/mici/layouts/settings/ictoggles.py
index 0bd78042a..a2ad07d01 100644
--- a/openpilot/selfdrive/ui/mici/layouts/settings/ictoggles.py
+++ b/openpilot/selfdrive/ui/mici/layouts/settings/ictoggles.py
@@ -1,9 +1,6 @@
-from openpilot.cereal import log
-
from openpilot.system.ui.widgets.scroller import NavScroller
-from openpilot.selfdrive.ui.mici.widgets.button import BigParamControl, BigMultiParamToggle
+from openpilot.selfdrive.ui.mici.widgets.button import BigParamControl
from openpilot.system.ui.lib.application import gui_app
-from openpilot.selfdrive.ui.layouts.settings.common import restart_needed_callback
from openpilot.selfdrive.ui.ui_state import ui_state
@@ -25,7 +22,7 @@ class ICTogglesLayoutMici(NavScroller):
enable_accel_bar = BigParamControl("Enable Accel Bar", "ShowAccelBar")
enable_curvatured = BigParamControl("Enable Dynamic Steering Learner", "EnableCurvatureD")
show_curvatured_graph = BigParamControl("Show Dynamic Steering Learner Graph", "ShowDynamicSteeringLearnerGraph")
-
+
self._scroller.add_widgets([
enable_curvature_correction,
enable_long_comfort_mode,
diff --git a/openpilot/selfdrive/ui/mici/layouts/settings/settings.py b/openpilot/selfdrive/ui/mici/layouts/settings/settings.py
index c27a89fd5..c0e00e449 100644
--- a/openpilot/selfdrive/ui/mici/layouts/settings/settings.py
+++ b/openpilot/selfdrive/ui/mici/layouts/settings/settings.py
@@ -24,11 +24,11 @@ class SettingsLayout(NavScroller):
toggles_panel = TogglesLayoutMici()
toggles_btn = SettingsBigButton("toggles", "", gui_app.texture("icons_mici/settings.png", 64, 64))
toggles_btn.set_click_callback(lambda: gui_app.push_widget(toggles_panel))
-
+
ictoggles_panel = ICTogglesLayoutMici()
ictoggles_btn = SettingsBigButton("ictoggles", "", gui_app.texture("icons_mici/settings.png", 64, 64))
ictoggles_btn.set_click_callback(lambda: gui_app.push_widget(ictoggles_panel))
-
+
network_panel = NetworkLayoutMici()
network_btn = SettingsBigButton("network", "", gui_app.texture("icons_mici/settings/network/wifi_strength_full.png", 76, 56))
network_btn.set_click_callback(lambda: gui_app.push_widget(network_panel))
diff --git a/openpilot/selfdrive/ui/mici/onroad/dynamic_steering_learner_graph.py b/openpilot/selfdrive/ui/mici/onroad/dynamic_steering_learner_graph.py
index 2bc312d8c..074c2711c 100644
--- a/openpilot/selfdrive/ui/mici/onroad/dynamic_steering_learner_graph.py
+++ b/openpilot/selfdrive/ui/mici/onroad/dynamic_steering_learner_graph.py
@@ -124,7 +124,6 @@ class DynamicSteeringLearnerGraphMici(Widget):
lcp = sm["liveCurvatureParameters"]
lcp_frame = sm.recv_frame["liveCurvatureParameters"]
car_state = sm["carState"]
- controls_state = sm["controlsState"]
fit_corrections = np.zeros(CurvatureDLookup.bucket_shape(), dtype=np.float32)
fit_valid = np.zeros(CurvatureDLookup.bucket_shape(), dtype=bool)
@@ -194,7 +193,8 @@ class DynamicSteeringLearnerGraphMici(Widget):
0.0, 1.0,
))
marker_x = plot_rect.x + marker_alpha * plot_rect.width
- marker_correction = float(np.interp(abs(desired_curvature), np.abs(self._plot_x), self._cached_fit_curve))
+ center_idx = len(self._plot_x) // 2
+ marker_correction = float(np.interp(abs(desired_curvature), self._plot_x[center_idx:], corrections[center_idx:]))
marker_y = self._map_y(plot_rect, marker_correction, min_y, max_y)
rl.draw_circle(int(marker_x), int(marker_y), 5, self._marker_glow_color)
rl.draw_circle(int(marker_x), int(marker_y), 3, self._marker_color)
diff --git a/openpilot/selfdrive/ui/onroad/battery_details.py b/openpilot/selfdrive/ui/onroad/battery_details.py
index 8b936c6b4..ebdebde69 100644
--- a/openpilot/selfdrive/ui/onroad/battery_details.py
+++ b/openpilot/selfdrive/ui/onroad/battery_details.py
@@ -1,7 +1,8 @@
-import pyray as rl
import time
-
from dataclasses import dataclass
+
+import pyray as rl
+
from openpilot.common.params import Params
from openpilot.selfdrive.ui.ui_state import ui_state
from openpilot.system.ui.lib.application import gui_app, FontWeight
@@ -16,19 +17,21 @@ class BatteryPanelConfig:
line_height: int = 48 # Basis-Zeilenhöhe
label_width: int = 320
text_margin: int = 25 # Abstand Label → Wert
-
+
+
CONFIG = BatteryPanelConfig()
+
class BatteryDetails(Widget):
def __init__(self) -> None:
super().__init__()
self._params = Params()
-
+
self._capacity: float = 0.0
self._charge: float = 0.0
self._soc: float = 0.0
self._temperature: float = 0.0
- self._heaterActive: bool = False
+ self._heater_active: bool = False
self._voltage: float = 0.0
self._current: float = 0.0
self._power: float = 0.0
@@ -37,21 +40,23 @@ class BatteryDetails(Widget):
self._panel_bg: rl.Color = rl.Color(0, 0, 0, 128)
self._label_color: rl.Color = rl.Color(220, 220, 220, 255)
self._value_color: rl.Color = rl.Color(255, 255, 255, 255)
-
+
self._display_enabled: bool = False
+ self._data_valid: bool = False
self._param_update_time: float = 0.0
-
+
self._update_params()
def _update_state(self) -> None:
if time.monotonic() - self._param_update_time > 2.0:
self._update_params()
-
+
if not self._display_enabled:
return
-
+
sm = ui_state.sm
- if sm.recv_frame["carState"] < ui_state.started_frame:
+ if (sm.recv_frame["carStateIC"] < ui_state.started_frame or
+ not sm.valid["carStateIC"] or not sm.alive["carStateIC"]):
self._reset_values()
return
@@ -66,11 +71,12 @@ class BatteryDetails(Widget):
self._voltage = float(battery_data.voltage)
self._current = float(battery_data.current)
self._power = float(battery_data.power)
-
+ self._data_valid = True
+
def _update_params(self) -> None:
self._param_update_time = time.monotonic()
self._display_enabled = self._params.get_bool("BatteryDetails")
-
+
def _reset_values(self) -> None:
self._capacity = 0.0
self._charge = 0.0
@@ -80,9 +86,10 @@ class BatteryDetails(Widget):
self._voltage = 0.0
self._current = 0.0
self._power = 0.0
+ self._data_valid = False
def _render(self, rect: rl.Rectangle) -> None:
- if not self._display_enabled:
+ if not self._display_enabled or not self._data_valid:
return
scale = CONFIG.scale_factor
@@ -103,7 +110,6 @@ class BatteryDetails(Widget):
label_width = CONFIG.label_width
text_margin = CONFIG.text_margin
column_spacing = panel_width // 2 - 40
- value_width = column_spacing - label_width - text_margin
labels = [
"Capacity:", "Charge:", "SoC:", "Temperature:",
@@ -121,9 +127,7 @@ class BatteryDetails(Widget):
f"{self._power:.2f} kW",
]
- rl.draw_text_ex
-
- for i, (label, value) in enumerate(zip(labels, values)):
+ for i, (label, value) in enumerate(zip(labels, values, strict=True)):
column = i // 4
row = i % 4
diff --git a/openpilot/selfdrive/ui/onroad/dynamic_steering_learner_graph.py b/openpilot/selfdrive/ui/onroad/dynamic_steering_learner_graph.py
index 2055d8019..36b84b1ab 100644
--- a/openpilot/selfdrive/ui/onroad/dynamic_steering_learner_graph.py
+++ b/openpilot/selfdrive/ui/onroad/dynamic_steering_learner_graph.py
@@ -133,7 +133,6 @@ class DynamicSteeringLearnerGraph(Widget):
rl.draw_rectangle_rounded(graph_rect, 0.08, 8, self._panel_bg)
lcp_frame = sm.recv_frame["liveCurvatureParameters"]
- controls_state = sm["controlsState"]
car_state = sm["carState"]
fit_corrections = np.zeros(CurvatureDLookup.bucket_shape(), dtype=np.float32)
@@ -276,17 +275,17 @@ class DynamicSteeringLearnerGraph(Widget):
rl.draw_text_ex(self._font_bold, title, rl.Vector2(text_x, title_y), title_size, 0, self._text_color)
status_text = (
- f"live={payload_valid} transport={transport_valid} cal={int(getattr(lcp, 'calPerc', 0))}% "
+ f"live={payload_valid} transport={transport_valid} cal={int(getattr(lcp, 'calPerc', 0))}% " +
f"points={int(getattr(lcp, 'totalBucketPoints', 0))}"
)
rl.draw_text_ex(self._font_medium, status_text, rl.Vector2(text_x, status_y), status_size, 0, self._muted_text_color)
speed_mix = (
- f"v={v_ego * 3.6:.0f} km/h mix={CurvatureDLookup.SPEED_ANCHORS[low_idx] * 3.6:.0f}/"
+ f"v={v_ego * 3.6:.0f} km/h mix={CurvatureDLookup.SPEED_ANCHORS[low_idx] * 3.6:.0f}/" +
f"{CurvatureDLookup.SPEED_ANCHORS[high_idx] * 3.6:.0f} alpha={alpha:.2f}"
)
marker_info = (
- f"k={desired_curvature:.2e} corr={display_correction:.2e} "
+ f"k={desired_curvature:.2e} corr={display_correction:.2e} " +
f"bucket=({int(getattr(lcp, 'bucketSpeed', -1))}, {int(getattr(lcp, 'bucketCurvature', -1))})"
)
rl.draw_text_ex(self._font_medium, speed_mix, rl.Vector2(text_x, footer_y1), footer_size, 0, self._muted_text_color)
diff --git a/openpilot/selfdrive/ui/sunnypilot/layouts/settings/steering.py b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/steering.py
index 008d8c791..796196962 100644
--- a/openpilot/selfdrive/ui/sunnypilot/layouts/settings/steering.py
+++ b/openpilot/selfdrive/ui/sunnypilot/layouts/settings/steering.py
@@ -120,7 +120,9 @@ class SteeringLayout(Widget):
def _update_state(self):
super()._update_state()
- torque_allowed = ui_state.CP is not None and ui_state.CP.steerControlType not in (car.CarParams.SteerControlType.angle, car.CarParams.SteerControlType.curvature)
+ torque_allowed = (ui_state.CP is not None and
+ ui_state.CP.steerControlType not in (car.CarParams.SteerControlType.angle,
+ car.CarParams.SteerControlType.curvature))
if ui_state.CP is not None:
mads_main_desc = self._mads_limited_desc if self._mads_settings_layout._mads_limited_settings() else self._mads_full_desc
self._mads_toggle.set_description(f"{mads_main_desc}
{self._mads_base_desc}")
diff --git a/openpilot/selfdrive/ui/tests/diff/replay_script.py b/openpilot/selfdrive/ui/tests/diff/replay_script.py
index 109f32e47..ebfb6d5f7 100644
--- a/openpilot/selfdrive/ui/tests/diff/replay_script.py
+++ b/openpilot/selfdrive/ui/tests/diff/replay_script.py
@@ -381,6 +381,14 @@ def build_mici_script(pm: PubMaster, main_layout, script: Script) -> None:
def build_tizi_script(pm: PubMaster, main_layout, script: Script) -> None:
"""Build the replay script for the tizi layout."""
+ def select_settings_panel(panel_name: str) -> None:
+ """Select a settings panel without relying on stock or sunnypilot sidebar coordinates."""
+ from openpilot.selfdrive.ui.layouts.main import MainState
+
+ settings_layout = main_layout._layouts[MainState.SETTINGS]
+ panel_type = next(panel_type for panel_type in settings_layout._panels if panel_type.name == panel_name)
+ settings_layout.set_current_panel(panel_type)
+
def make_home_refresh_setup(fn: Callable) -> Callable:
"""Return setup function that calls the given function to modify state and forces an immediate refresh on the home layout."""
from openpilot.selfdrive.ui.layouts.main import MainState
@@ -457,7 +465,7 @@ def build_tizi_script(pm: PubMaster, main_layout, script: Script) -> None:
script.click(2000, 970) # OK
# === Settings - Network ===
- script.click(278, 450)
+ script.setup(lambda: select_settings_panel("NETWORK"))
# TODO: mock networks
script.click(1880, 100) # advanced network settings
@@ -473,12 +481,12 @@ def build_tizi_script(pm: PubMaster, main_layout, script: Script) -> None:
script.click(630, 80) # back from advanced network
# === Settings - Toggles ===
- script.click(278, 600)
+ script.setup(lambda: select_settings_panel("TOGGLES"))
script.click(1200, 280) # expand experimental mode description
# === Settings - Software ===
script.setup(lambda: setup_update_available(False), wait_after=0) # start with no update available
- script.click(278, 720) # software
+ script.setup(lambda: select_settings_panel("SOFTWARE"))
for _ in range(2):
script.click(720, 120) # toggle current release notes
script.setup(setup_update_available) # set update available
@@ -491,11 +499,11 @@ def build_tizi_script(pm: PubMaster, main_layout, script: Script) -> None:
script.click(650, 750) # cancel uninstall
# === Settings - Firehose ===
- script.click(278, 845)
+ script.setup(lambda: select_settings_panel("FIREHOSE"))
# === Settings - Developer (set CarParamsPersistent first) ===
script.setup(setup_developer_params, wait_after=0)
- script.click(278, 950)
+ script.setup(lambda: select_settings_panel("DEVELOPER"))
script.click(1930, 470) # SSH keys (keyboard)
script.click(1930, 115) # click cancel on keyboard
script.click(2000, 960) # toggle alpha long
diff --git a/openpilot/selfdrive/ui/ui_state.py b/openpilot/selfdrive/ui/ui_state.py
index db1f6d17e..5221af953 100644
--- a/openpilot/selfdrive/ui/ui_state.py
+++ b/openpilot/selfdrive/ui/ui_state.py
@@ -99,7 +99,7 @@ class UIState(UIStateSP):
self.is_body: bool | None = None
self.CP: car.CarParams | None = None
self.light_sensor: float = -1.0
-
+
self.dark_mode: bool = False
self.onroad_screen_timeout: bool = False
self.enable_accel_bar: bool = False
@@ -190,11 +190,11 @@ class UIState(UIStateSP):
self.status = UIStatus.OVERRIDE
else:
self.status = UIStatus.ENGAGED if ss.enabled else UIStatus.DISENGAGED
-
+
# detect status change
self.has_status_change = True if self.status != self._status_prev else False
self._status_prev = self.status
-
+
# check for alert
self.has_alert = True if ss.alertSize != 0 else False