mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-11-12 23:43:44 +08:00
db1c5a7445
Release inherited Params locks correctly across fork and exec. Preserve qualified lateral armed intent through temporary faults, restore the Big UI CEM gauge, improve speed typography, and hide unavailable CEM initialization text. Include matching device artifacts and focused regression coverage.
64 lines
3.2 KiB
Python
64 lines
3.2 KiB
Python
"""Short, source-bound labels for accepted conditional mode receipts."""
|
|
|
|
import pyray as rl
|
|
|
|
from openpilot.starpilot.conditional_mode.policy import ModeChoice, Reason
|
|
from openpilot.starpilot.ui.onroad_state import AlertSize
|
|
from openpilot.starpilot.ui.onroad_state import OnroadState
|
|
|
|
|
|
_CEM_HOLD_REASONS = {3: "cem_curve", 4: "cem_lead", 5: "cem_signal", 6: "cem_speed",
|
|
7: "cem_speed_limit", 8: "cem_stop"}
|
|
_CCM_HOLD_REASONS = {4: "ccm_lead", 6: "ccm_speed"}
|
|
|
|
|
|
_REASONS = {reason.value: (reason.name[4:] if reason.name.startswith(('CEM_', 'CCM_')) else reason.name).replace('_', ' ')
|
|
for reason in Reason}
|
|
_HIDDEN_REASONS = frozenset((Reason.SCENE_UNAVAILABLE.value, Reason.UNAVAILABLE.value))
|
|
|
|
|
|
def reason(state: OnroadState) -> str | None:
|
|
"""Resolve the accepted planner reason, including its authoritative held status."""
|
|
preview = state.visual_preview
|
|
if preview is not None and preview.cem_reason in ('CURVE', 'LEAD', 'STOP LIGHT', 'SPEED'):
|
|
return {'CURVE': 'cem_curve', 'LEAD': 'cem_lead', 'STOP LIGHT': 'cem_stop', 'SPEED': 'cem_speed'}[preview.cem_reason]
|
|
value = (state.conditional_effective if state.longitudinal_active else None) or getattr(state, 'conditional_perception', None)
|
|
if value is None or value.choice not in (ModeChoice.CEM, ModeChoice.CCM) or value.reason in _HIDDEN_REASONS:
|
|
return None
|
|
if value.reason == 'cem_hold' and value.choice is ModeChoice.CEM:
|
|
return _CEM_HOLD_REASONS.get(getattr(value, 'status_code', 0))
|
|
if value.reason == 'ccm_hold' and value.choice is ModeChoice.CCM:
|
|
return _CCM_HOLD_REASONS.get(getattr(value, 'status_code', 0))
|
|
return value.reason
|
|
|
|
|
|
def stop_active(state: OnroadState) -> bool:
|
|
"""One accepted stop state for the light icon and the conditional orange border."""
|
|
if state.alert.size == AlertSize.FULL or state.longitudinal_overridden:
|
|
return False
|
|
value = state.conditional_effective
|
|
preview = state.visual_preview
|
|
return bool(reason(state) == 'cem_stop' and
|
|
(preview is not None and preview.cem_reason == 'STOP LIGHT' or
|
|
state.longitudinal_active and value is not None and value.choice is ModeChoice.CEM and value.effective_experimental))
|
|
|
|
|
|
def status(state: OnroadState) -> tuple[str, str, rl.Color] | None:
|
|
preview = state.visual_preview
|
|
if preview is not None and preview.cem_reason in ('CURVE', 'LEAD', 'STOP LIGHT', 'SPEED'):
|
|
if state.alert.size == AlertSize.FULL:
|
|
return None
|
|
return 'CEM', f'PREVIEW {preview.cem_reason}', rl.Color(112, 192, 216, 255)
|
|
value = (state.conditional_effective if state.longitudinal_active else None) or getattr(state, 'conditional_perception', None)
|
|
if value is None or value.choice not in (ModeChoice.CEM, ModeChoice.CCM):
|
|
return None
|
|
if value.reason in _HIDDEN_REASONS or value.reason in ('no_trigger', 'manual_chill', 'manual_experimental', 'ccm_veto'):
|
|
return None
|
|
# The text is selected from known policy reasons, never rendered from wire text.
|
|
detail = _REASONS.get(reason(state))
|
|
if detail is None:
|
|
return None
|
|
family = 'CEM' if value.choice is ModeChoice.CEM else 'CCM'
|
|
color = rl.Color(112, 192, 216, 255) if value.effective_experimental else rl.Color(255, 155, 63, 255)
|
|
return family, detail, color
|