This commit is contained in:
whoisdomi
2026-09-16 06:44:08 -05:00
parent 5059dae1a2
commit 2267f2dce2
3 changed files with 29 additions and 26 deletions
+3 -4
View File
@@ -532,10 +532,9 @@ EVENTS: dict[int, dict[str, Alert | AlertCallbackType]] = {
"Ensure road ahead is clear"),
},
EventName.bigModelLoading: {
ET.PERMANENT: NormalPermanentAlert("Big Model Loading",
"Driving on the small model"),
},
# bigModelLoading and bigModelPending carry no alerts on purpose: the blinking eGPU icon
# already says the big model is loading, and its absence says it is ready.
EventName.bigModelLoading: {},
# bigModelPending carries no alert on purpose: the eGPU icon clearing, and then turning
# green on the next engage, is the driver's cue. A banner here announced the model before
+7 -10
View File
@@ -64,9 +64,6 @@ StarPilotEventName = custom.StarPilotOnroadEvent.EventName
IGNORED_SAFETY_MODES = (SafetyModel.silent, SafetyModel.noOutput)
VALID_ONLY_COMM_ISSUE_GRACE_FRAMES = max(1, round(0.5 / DT_CTRL))
# How long the "driving on the small model" banner shows before the blinking eGPU icon
# takes over as the indication that the big model is still loading.
BIG_MODEL_LOADING_ALERT_SECONDS = 3.0
def evaluate_comm_issue(all_checks: bool, all_alive: bool, all_freq_ok: bool,
@@ -259,7 +256,6 @@ class SelfdriveD:
self.big_model_active = False
self.big_model_failed = False
self.big_model_swap_t = 0.
self.big_model_loading_t = 0.
self.experimental_mode = False
self.ecu_disable_failed = False
self.ecu_disable_failed_checked = not (
@@ -398,12 +394,10 @@ class SelfdriveD:
loading = self.params.get_bool("UsbGpuLoading")
if loading:
self.big_model_attempted = True
if not self.big_model_loading:
self.big_model_loading_t = time.monotonic()
self.big_model_loading = loading
# Announce the small-model handover briefly; the blinking eGPU icon carries the
# "still loading" state from there so the banner does not sit on screen for minutes.
if loading and time.monotonic() < self.big_model_loading_t + BIG_MODEL_LOADING_ALERT_SECONDS:
# No alert while loading: the blinking eGPU icon already carries that state, and the
# small model is driving normally. big_model_loading still gates the frame-drop warning.
if loading:
self.events.add(EventName.bigModelLoading)
# The big model loads in the background while the small model drives, so it sits
@@ -817,7 +811,10 @@ class SelfdriveD:
# TODO: fix simulator
if not SIMULATION or REPLAY:
if self.sm['modelV2'].frameDropPerc > 20:
# Loading the big model realizes its graph on the same QCOM GPU the small model is
# driving on, which costs real frames for part of the load. The small model keeps
# publishing throughout, so warn about the drops only once the load is out of the way.
if self.sm['modelV2'].frameDropPerc > 20 and not self.big_model_loading:
self.events.add(EventName.modeldLagging)
# Decrement personality on configured steering-wheel button presses
@@ -13,7 +13,6 @@ def test_big_model_loading_does_not_block_engagement():
# The big model loads in the background while the small model drives, so waiting for it
# must never keep the driver from engaging.
assert ET.NO_ENTRY not in EVENTS[EventName.bigModelLoading]
assert ET.PERMANENT in EVENTS[EventName.bigModelLoading]
def test_big_model_pending_raises_no_alert():
@@ -63,22 +62,30 @@ def test_pending_is_raised_before_loading_is_cleared():
"UsbGpuPending must be raised before UsbGpuLoading is cleared"
def test_loading_banner_is_brief_and_hands_over_to_the_icon():
# The load can run for minutes; the banner announces the handover to the small model and
# then gets out of the way, leaving the blinking eGPU icon as the "still loading" cue.
def test_big_model_loading_raises_no_alert():
# The blinking eGPU icon already says the big model is loading, so the banner was noise
# sitting on screen for the whole load.
assert EVENTS[EventName.bigModelLoading] == {}
def test_frame_drop_warning_is_suppressed_while_the_big_model_loads():
"""Loading realizes the big model's graph on QCOM, the GPU the small model drives on.
Measured on drive 00000ab7: the small model's own modelExecutionTime p95 went 37 ms ->
126 ms for a stretch of the load, which pushed frameDropPerc past the modeldLagging
threshold. The small model keeps publishing and driving correctly throughout, so the
warning is noise until the load is done.
"""
from openpilot.selfdrive.selfdrived import selfdrived
assert selfdrived.BIG_MODEL_LOADING_ALERT_SECONDS == 3.0
source = (Path(selfdrived.__file__)).read_text(encoding="utf-8")
tree = ast.parse(source)
guard = next(
node for node in ast.walk(tree)
if isinstance(node, ast.If) and "bigModelLoading" in ast.dump(node)
and "BIG_MODEL_LOADING_ALERT_SECONDS" in ast.dump(node.test)
node for node in ast.walk(ast.parse(source))
if isinstance(node, ast.If) and "modeldLagging" in ast.dump(node)
and "frameDropPerc" in ast.dump(node.test)
)
# The alert must be gated on elapsed time, not added unconditionally every frame.
assert "big_model_loading_t" in ast.dump(guard.test)
assert "big_model_loading" in ast.dump(guard.test), \
"modeldLagging must not fire for frames the big-model load is costing"
def _big_failed(*, attempted, loading, pending, big_active, model_unavailable=False):