mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-11-06 20:43:46 +08:00
Show retained Auto Learn study progress
This commit is contained in:
@@ -1484,10 +1484,17 @@ class LiveTrackingOptimizer:
|
||||
and 0 <= now_ns - self.last_ack[-1] <= 100_000_000
|
||||
)
|
||||
status, reason = self.status, self.reason
|
||||
paused = self.paused_intent
|
||||
if (self.paused_demand_context != (self.binding, self.certificate, self.domain)
|
||||
or paused is None or paused[0]['baseline'] != self.accepted or type(now_ns) is not int or now_ns >= paused[0]['deadline_ns']):
|
||||
paused = None
|
||||
before, future = (self.before, self.future) if paused is None else paused[1:]
|
||||
if state is not None and state.get('accepted', False):
|
||||
if acknowledged:
|
||||
status = state['phase']
|
||||
reason = 'accepted_target_currently_acknowledged' if status == 'confirmed' else 'prior_accepted_baseline_restored'
|
||||
if status == 'rollback' and paused is not None and self.paused_baseline_ns > 0:
|
||||
reason = 'original_input_regime_after_baseline_ack_required'
|
||||
else:
|
||||
state = None
|
||||
|
||||
@@ -1503,14 +1510,14 @@ class LiveTrackingOptimizer:
|
||||
'trialId': None if state is None else state['trial_id'],
|
||||
'phase': None if state is None else state['phase'],
|
||||
'requiredEpisodes': None if state is None else state['required_episodes'],
|
||||
'beforeEpisodes': len(self.before),
|
||||
'futureEpisodes': len(self.future),
|
||||
'beforeEpisodes': len(before),
|
||||
'futureEpisodes': len(future),
|
||||
'modelStatus': self.model_status if current else 'stale',
|
||||
'lagMs': self.lag_ns / 1e6,
|
||||
'baselineErrorRms': mean(self.before, 'error_rms'),
|
||||
'futureErrorRms': mean(self.future, 'error_rms'),
|
||||
'baselineReversalHz': mean(self.before, 'reversal_hz'),
|
||||
'futureReversalHz': mean(self.future, 'reversal_hz'),
|
||||
'baselineErrorRms': mean(before, 'error_rms'),
|
||||
'futureErrorRms': mean(future, 'error_rms'),
|
||||
'baselineReversalHz': mean(before, 'reversal_hz'),
|
||||
'futureReversalHz': mean(future, 'reversal_hz'),
|
||||
'applicationAcknowledged': acknowledged,
|
||||
'applicationSettledMonoTime': self.last_ack[-1] if acknowledged and self.last_ack is not None else self.settled_ns,
|
||||
'lastCorrectionMonoTime': self.last_correction or None,
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
"""Retained numerical progress must not become current target authority."""
|
||||
|
||||
from dataclasses import replace
|
||||
|
||||
from openpilot.starpilot.flm.tests.test_staged_source_study import pause, baseline_ack
|
||||
|
||||
|
||||
def test_held_progress_does_not_claim_target_or_confirmed_application():
|
||||
o, _original, scores, incoming = pause()
|
||||
report = o.report(incoming.end_ns)
|
||||
assert report['phase'] == 'rollback' and not report['applicationAcknowledged']
|
||||
assert (report['beforeEpisodes'], report['futureEpisodes'], report['requiredEpisodes']) == (3, 2, 3)
|
||||
assert report['reason'] == 'trial_input_regime_ended' and not any(o.accepted.values())
|
||||
ack = baseline_ack(o, incoming.end_ns + 10_000_000)
|
||||
report = o.report(ack)
|
||||
assert report['status'] == report['phase'] == 'rollback'
|
||||
assert report['applicationAcknowledged'] and report['reason'] == 'original_input_regime_after_baseline_ack_required'
|
||||
assert (report['beforeEpisodes'], report['futureEpisodes']) == (len(scores[0]), len(scores[1]))
|
||||
assert report['lastCorrectionMonoTime'] is None and not any(o.accepted.values())
|
||||
|
||||
|
||||
def test_stale_baseline_does_not_report_current_restoration():
|
||||
o, _original, _scores, incoming = pause()
|
||||
ack = baseline_ack(o, incoming.end_ns + 10_000_000)
|
||||
report = o.report(ack + 100_000_001)
|
||||
assert not report['applicationAcknowledged'] and not report['bindingCurrent']
|
||||
assert report['phase'] is None and report['modelStatus'] == 'stale'
|
||||
|
||||
|
||||
def test_expired_changed_or_discarded_study_has_no_retained_progress():
|
||||
for change in ('expiry', 'certificate', 'baseline', 'manual'):
|
||||
o, original, _scores, incoming = pause()
|
||||
now = baseline_ack(o, incoming.end_ns + 10_000_000)
|
||||
if change == 'expiry':
|
||||
now = original['deadline_ns']
|
||||
elif change == 'certificate':
|
||||
o.certificate = replace(o.certificate, model_revision='9' * 64)
|
||||
elif change == 'baseline':
|
||||
o.accepted['ff_gain_left'] = 0.001
|
||||
else:
|
||||
o.interrupt('manual_override')
|
||||
report = o.report(now)
|
||||
assert report['beforeEpisodes'] == report['futureEpisodes'] == 0
|
||||
for invalid_now in (None, True, 'now', float('nan')):
|
||||
o, _original, _scores, incoming = pause()
|
||||
baseline_ack(o, incoming.end_ns + 10_000_000)
|
||||
report = o.report(invalid_now)
|
||||
assert report['beforeEpisodes'] == report['futureEpisodes'] == 0
|
||||
assert not report['applicationAcknowledged'] and not report['bindingCurrent']
|
||||
@@ -1,7 +1,7 @@
|
||||
import assert from 'node:assert/strict'
|
||||
import { compile } from '../web/vendor/vue/vue.esm-browser.js'
|
||||
import { FlmPage } from '../web/js/flm.js'
|
||||
import { SURFACE_NAMES, PID_UNSUPPORTED, validTrainingResults, validTrackingResults, trackingView, surfaceRows, measurementText, validTrackingValues, trackingCoordinates, validTrackingPlot, trackingPlotView, sourceSeconds } from '../web/js/flm-training-results.js'
|
||||
import { SURFACE_NAMES, PID_UNSUPPORTED, validTrainingResults, validTrackingResults, trackingView, surfaceRows, measurementText, validTrackingValues, trackingCoordinates, validTrackingPlot, trackingPlotView, sourceSeconds, tunerStatus } from '../web/js/flm-training-results.js'
|
||||
|
||||
const coordinates = amount => SURFACE_NAMES.map((name, i) => [name, i === 0 ? amount : 0])
|
||||
const tracking = () => ({ version: 1, status: 'trial_active', reason: 'scoring_future_tracking', group: 'feedforward',
|
||||
@@ -60,6 +60,24 @@ const neutralRollback = report(); neutralRollback.current.tracking.status = 'rol
|
||||
neutralRollback.current.application.applied = false
|
||||
neutralRollback.current.details['Actual full surface coordinates'] = coordinates(0)
|
||||
assert.equal(trackingView(neutralRollback, true).label, 'Correction rollback acknowledged')
|
||||
const held = structuredClone(neutralRollback)
|
||||
held.current.tracking.reason = 'original_input_regime_after_baseline_ack_required'
|
||||
held.current.tracking.futureEpisodes = 2
|
||||
assert.equal(trackingView(held, true).label, 'Baseline restored; waiting for matching road')
|
||||
assert.equal(tunerStatus(held, true).title, 'Waiting for matching road')
|
||||
assert.equal(trackingView(held, true).futureEpisodes, 2)
|
||||
assert.equal(trackingView(held, true).requiredEpisodes, 3)
|
||||
assert(!/confirmed|saved|correction applied/i.test(tunerStatus(held, true).title))
|
||||
for (const mutate of [value => value.current.tracking.applicationAcknowledged = false,
|
||||
value => value.current.tracking.bindingCurrent = false,
|
||||
value => value.current.fresh = false,
|
||||
value => value.current.tracking.phase = 'trial',
|
||||
value => delete value.current.details['Actual full surface coordinates']]) {
|
||||
const noProof = structuredClone(held); mutate(noProof)
|
||||
assert.equal(trackingView(noProof, true).acknowledged, false)
|
||||
assert.notEqual(tunerStatus(noProof, true).title, 'Waiting for matching road')
|
||||
}
|
||||
assert.notEqual(tunerStatus(held, false).title, 'Waiting for matching road')
|
||||
for (const mutate of [value => value.current.tracking.applicationAcknowledged = false,
|
||||
value => value.current.tracking.bindingCurrent = false,
|
||||
value => value.current.tracking.applicationSettledMonoTime = null,
|
||||
|
||||
@@ -175,6 +175,7 @@ const REASONS = {
|
||||
trial_oscillation_batch_worse: "Comparable trial windows showed more oscillation, so the correction was rolled back.",
|
||||
predeclared_independent_future_look_required: "Collecting the next planned set of comparison windows.",
|
||||
prior_accepted_baseline_restored: "The controller returned to its prior baseline.",
|
||||
original_input_regime_after_baseline_ack_required: "The baseline is restored. Completed comparison samples are kept while waiting for the same driving conditions.",
|
||||
scoring_later_matched_whole_episodes: "Comparing new steering windows with the baseline.",
|
||||
accepted_target_currently_acknowledged: "The controller acknowledged the accepted correction.",
|
||||
}
|
||||
@@ -204,10 +205,12 @@ export function tunerStatus(report, live = false, choiceLive = false, error = ""
|
||||
if ((tracking?.reason || current.reason) === "controller_collection_required")
|
||||
return { key: "waiting", tone: "muted", title: "Waiting for active steering", description: learningReason("controller_collection_required") }
|
||||
if (tracking && !tracking.bindingCurrent)
|
||||
return { key: "paused", tone: "warning", title: "Learning paused", description: "The steering context changed. A fresh qualified window is required." }
|
||||
return { key: "paused", tone: "warning", title: "Learning paused", description: "Current steering evidence is unavailable. A fresh qualified window is required." }
|
||||
if (tracking?.acknowledged && tracking.status === "confirmed") return { key: "confirmed", tone: "success", title: "Correction applied", description: "The comparison passed and the controller acknowledged this correction. Disk saving is a separate result." }
|
||||
if (tracking?.acknowledged && tracking.status === "trial_active") return { key: "testing", tone: "active", title: "Testing a small correction", description: "The controller acknowledged the trial. Comparable new driving windows decide whether to keep it." }
|
||||
if (tracking?.status === "trial_pending") return { key: "pending", tone: "active", title: "Waiting for the controller", description: "A trial was offered. It has not yet been acknowledged as applied." }
|
||||
if (tracking?.status === "rollback" && tracking.acknowledged && tracking.reason === "original_input_regime_after_baseline_ack_required")
|
||||
return { key: "waiting", tone: "ready", title: "Waiting for matching road", description: learningReason(tracking.reason) }
|
||||
if (tracking?.status === "rollback") return { key: "rollback", tone: "warning", title: "Returning to the baseline", description: tracking.acknowledged ? "The controller acknowledged the rollback." : "A rollback was requested. Current application is not yet acknowledged." }
|
||||
if (tracking?.status === "paused" || current.status === "unavailable") return { key: "paused", tone: "warning", title: "Learning paused", description: learningReason(tracking?.reason || current.reason) }
|
||||
return { key: "collecting", tone: "active", title: tracking?.status === "calibrating" ? "Measuring steering response" : "Collecting driving samples", description: learningReason(tracking?.reason || current.reason) }
|
||||
@@ -256,8 +259,9 @@ export function trackingView(report, live = false) {
|
||||
if (value.status === 'trial_active' && acknowledged) label = 'Evaluating correction'
|
||||
if (value.status === 'confirmed' && acknowledged) label = 'Confirmed correction acknowledged'
|
||||
if (value.status === 'rollback' && acknowledged) label = 'Correction rollback acknowledged'
|
||||
if (value.status === 'rollback' && acknowledged && value.reason === 'original_input_regime_after_baseline_ack_required') label = 'Baseline restored; waiting for matching road'
|
||||
if (value.status !== 'paused' && (value.phase !== null && !matchingPhase || expectedPhase !== undefined && !matchingPhase)) label = 'Learning state reported; trial application unknown'
|
||||
if (live && !value.bindingCurrent) label = 'Learning paused; steering context changed'
|
||||
if (live && !value.bindingCurrent) label = 'Learning paused; current steering evidence unavailable'
|
||||
if (!live) label = 'Earlier learning report; current application unknown'
|
||||
return { ...value, label, acknowledged, changedParameters: value.names.map(readable).join(', '),
|
||||
measurements: [
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
{"protected_inventory_sha256": "9653f67cf25c7e37488533864943c5949cca94b4c7dadbe1ad1af400eb36d88d", "schema_version": 1}
|
||||
{"protected_inventory_sha256": "a65a390042e7d02f1180f79f6ad3e95c80ce96be9f44cc1230ff7afe2fad885c", "schema_version": 1}
|
||||
|
||||
Reference in New Issue
Block a user