Skip to content

longTauGnssCoupling: coast-cap + graded-taper primitives (unit layer)#80

Closed
bobvan wants to merge 2 commits into
mainfrom
bravo/longtau-coast-cap
Closed

longTauGnssCoupling: coast-cap + graded-taper primitives (unit layer)#80
bobvan wants to merge 2 commits into
mainfrom
bravo/longtau-coast-cap

Conversation

@bobvan
Copy link
Copy Markdown
Owner

@bobvan bobvan commented May 29, 2026

Summary

The unit layer for longTauGnssCoupling — four pure policy functions in discipline.py, not yet wired into DisciplineScheduler. Reviewing the API shape + math now (both the engine wiring and Charlie's closedLoopServoSim will consume these signatures).

The bug they target: the scheduler's τ = √(2·T/D) budgets only the deterministic drift. A quiet DO (D≈0) gets τ→max_interval (120 s), but its stochastic phase wander keeps growing over the coast — the tau~64–256 s TDEV hump in the 2026-05-29 overnight runs (PiFace 6.4 ns @ 64 s, MadHat 3.6 ns @ 256 s), exactly where GNSS is at its best.

function what it does
coast_cap_from_tdev invert a power-law freerun TDEV → largest τ with k·TDEV(τ) ≤ budget. DO-class: ~138 s for an 85 ps OCXO, <1 s for a 1.17 ns TCXO. slope≤0 ⇒ no constraint.
coast_cap_from_p22 largest int τ with k·√(P22(τ)) ≤ budget; P22 from a caller closure over the filter's predict-only growth.
normalized_convergence map √(P22)/σ_total → [0,1] — the single derived signal every policy reads (disciplineModeFsm reframe).
graded_interval geometric taper replacing the binary 1 if converging else interval latch (and its 1→120 s actuation cliff). Continuous + monotone ⇒ cannot chatter.

Connections to the rest of the redesign

  • Depends on qFromCharPerActuator (Main): the √(P22) cap is only honest in the characterized small-Q regime — with an inflated Q it's spuriously tight. Per Main's take, qFromCharPerActuator lands first; this layer is reviewable independently but wires after it.
  • Main's growth-law correction: coast P-growth is dominated by the frequency random-walk integrated into phase (Var ≈ q_f·τ³/3, σ ∝ τ^1.5), not the phase term. coast_cap_from_p22 is agnostic (callable); a test pins the cubic-variance shape.
  • graded_interval is the continuous converging→tracking transition (Bob's emergent-not-latched preference); it's also a candidate fix for pifaceShortTauGlitches candidate (a), the coast-end actuation cliff.

Test plan

  • 28 unit tests (TDEV inversion incl. OCXO/TCXO/RW-FM, P22 cap incl. freq-RW cubic + exact boundary, normalized ramp, taper monotonicity + no-cliff, composition)
  • Wire into compute_adaptive_interval (behind params, default-off) after qFromCharPerActuator
  • Closed-loop A/B in closedLoopServoSim: confirm the tau~64–256 s hump drops

🤖 Generated with Claude Code

… layer)

The deterministic drift budget (tau = sqrt(2*T/D)) bounds only the
signed aging/thermal ramp.  A quiet DO (D~0) gets tau -> max_interval
(120s), but its STOCHASTIC phase wander keeps accumulating over the
long coast -- the tau~64-256s TDEV hump in the 2026-05-29 overnight
runs (PiFace 6.4ns@64s, MadHat 3.6ns@256s), exactly where the GNSS
reference is at its best.

Four pure functions (no DisciplineScheduler state, not yet wired --
integration + closed-loop A/B is deferred to closedLoopServoSim):

  coast_cap_from_tdev   -- invert a power-law freerun TDEV model for
                           the largest tau with k*TDEV(tau) <= budget.
                           DO-class property: long for an OCXO, sub-1s
                           for a TCXO.  slope<=0 (white/flicker-PM) =>
                           no constraint.
  coast_cap_from_p22    -- largest integer tau with k*sqrt(P22(tau)) <=
                           budget, P22 from a caller closure over the
                           filter's predict-only growth.  Per Main's
                           qFromCharPerActuator note the dominant growth
                           is the FREQUENCY random-walk integrated into
                           phase (Var ~ q_f*tau^3/3); the function is
                           agnostic to the law (callable) -- a test
                           pins the cubic-variance shape.
  normalized_convergence-- map sqrt(P22)/sigma_total (ns) to a [0,1]
                           convergence metric: the single derived signal
                           every policy reads (disciplineModeFsm
                           reframe -- continuous, not a latched state).
  graded_interval       -- geometric taper replacing the binary
                           "1 if converging else interval" latch (and
                           the 1->120s actuation cliff it creates):
                           m=0 -> full coast, m=1 -> min_interval,
                           continuous + monotone so it cannot chatter.

DEPENDENCY (Main, qFromCharPerActuator): the sqrt(P22) path is only
honest in the characterized small-Q regime -- with an inflated Q the
cap is spuriously tight.  qFromCharPerActuator is the prerequisite and
should land first; this unit layer can be reviewed independently.

28 tests (TDEV inversion incl. OCXO/TCXO/RW-FM, P22 cap incl. freq-RW
cubic growth + boundary, normalized ramp, taper monotonicity +
no-cliff, composition).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@bobvan
Copy link
Copy Markdown
Owner Author

bobvan commented May 29, 2026

REVIEW (charlie) — LGTM. Math verified on all four primitives + 28 tests pass; full review on the dayplan (longTauGnssCoupling thread, 2026-05-28). Two minor non-blocking nits: (1) normalized_convergence reads inverted vs its name (returns 1.0 when least-converged — naming-honesty); (2) coast_cap_from_p22 scans O(max_tau) closure calls (negligible at 1Hz). Design is sim-friendly — I'll consume coast_cap_from_p22 in closedLoopServoSim's coast gate once qFromCharPerActuator lands honest Q[3,3]. Ship the unit layer.

Naming-honesty fix (charlie PR #80 review, docs/misnomers.md): the
function returns 1.0 when LEAST converged (far from lock), which reads
inverted against "convergence".  Renamed to normalized_distance_to_lock
(0 = locked, 1 = far) so the value matches the name; graded_interval's
param follows (convergence_metric -> distance_to_lock).  No behavior
change.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@bobvan
Copy link
Copy Markdown
Owner Author

bobvan commented May 29, 2026

Superseded by #86 (longTau stack squashed into one PR per Bob, 2026-05-29). The primitives (Charlie-approved here) + scheduler wiring + engine wiring all live in #86. Thanks @charlie for the review — the normalized_distance_to_lock rename + the 4-primitive math all carried into #86 unchanged.

@bobvan bobvan closed this May 29, 2026
@bobvan bobvan deleted the bravo/longtau-coast-cap branch May 29, 2026 19:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant