mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-10-28 09:03:46 +08:00
60 lines
3.0 KiB
Python
60 lines
3.0 KiB
Python
"""Bounded optional learner observations; never admission or publisher proof."""
|
|
|
|
_SERVICES = ('deviceMotion', 'extrinsicsCalibration', 'carState', 'driverMonitoringState')
|
|
|
|
|
|
def _snapshot(collector, sm, now_ns, reason):
|
|
ready = collector.ready
|
|
command, output = ready[-1] if ready else (None, None)
|
|
return {
|
|
'reason': reason, 'observedMonoTime': now_ns, 'readyPairs': len(ready),
|
|
'currentNative': bool(getattr(collector, '_learning_current_native_allowed', False)),
|
|
'controlMonoTime': None if command is None else command.control_ns,
|
|
'applyMonoTime': None if output is None else output.apply_ns,
|
|
'originalNativeObservedMonoTime': None if command is None else command.native_observed_ns,
|
|
'originalNativeValidUntilMonoTime': None if command is None else command.native_expires_ns,
|
|
'receiver': {
|
|
service: {
|
|
'seen': bool(sm.seen[service]), 'alive': bool(sm.alive[service]),
|
|
'valid': bool(sm.valid[service]), 'freqOk': bool(sm.freq_ok[service]),
|
|
'sourceEventMonoTime': int(sm.logMonoTime[service]),
|
|
'receivedMonoTime': int(sm.recv_time[service] * 1e9),
|
|
} for service in _SERVICES
|
|
},
|
|
}
|
|
|
|
|
|
def record_refusal(collector, sm, now_ns, reason, *, error=None):
|
|
"""Existing rejected branches only; at most two snapshots per collector."""
|
|
try:
|
|
counts = getattr(collector, '_source_observation_refusals', None)
|
|
if counts is None:
|
|
counts = collector._source_observation_refusals = {}
|
|
if reason in counts or len(counts) < 24:
|
|
counts[reason] = counts.get(reason, 0) + 1
|
|
collector._source_observation_current_refusal = (reason, now_ns)
|
|
if error is not None:
|
|
collector._source_observation_exception = {'observedMonoTime': now_ns, 'type': type(error).__name__, 'message': str(error)[:192]}
|
|
if not getattr(collector, '_source_observation_first_attempted', False):
|
|
collector._source_observation_first_attempted = True
|
|
collector._source_observation_first_refusal = _snapshot(collector, sm, now_ns, reason)
|
|
if collector.ready and not getattr(collector, '_source_observation_ready_attempted', False):
|
|
collector._source_observation_ready_attempted = True
|
|
collector._source_observation_ready_refusal = _snapshot(collector, sm, now_ns, reason)
|
|
except Exception:
|
|
# Observability must not alter rejection, reset, clock or driving behavior.
|
|
pass
|
|
|
|
|
|
def refusal_report(collector):
|
|
current = getattr(collector, '_source_observation_current_refusal', None)
|
|
return {
|
|
'publisherRefusal': 'unknown_not_transmitted',
|
|
'scope': 'learner receiver only; not the Controls publisher admission reason',
|
|
'counts': dict(getattr(collector, '_source_observation_refusals', {})),
|
|
'lastRefusal': None if current is None else {'reason': current[0], 'observedMonoTime': current[1]},
|
|
'lastException': getattr(collector, '_source_observation_exception', None),
|
|
'firstRefusal': getattr(collector, '_source_observation_first_refusal', None),
|
|
'firstReadyPairRefusal': getattr(collector, '_source_observation_ready_refusal', None),
|
|
}
|