Output-only marginality · method 7
In a real-time hybrid simulation the loop can lose stability at a single sharp resonance near 37 Hz. M7 hears that resonance in the measured displacement dm and rescales the model's known margin into a live reading — no input excitation, no dither. Precisely: not a from-scratch output-only margin, but a model-anchored NCF, tracked by the output.
Drag damage or let it sweep. As the 37 Hz peak grows, Spk rises and the margin b falls toward the 0.40 alarm — the entire method, in one panel.
The premise
Near the stability edge the loop grows a tall sensitivity peak at about 37 Hz. The closed loop amplifies its own internal noise — servo hum, friction, quantization — right there, so the resonance shows up in the measured displacement dm even when the test input never visits 37 Hz.
That growth is the incipient instability. So the output carries a warning the input physically cannot deliver — which is exactly why M7 can stay blind to the command and still see trouble coming.
The measurement
Take a short window of dm. Compare the energy in the resonance band to a quiet reference band off to the side:
A flat spectrum gives Spk ≈ 1. A sharpening 37 Hz peak drives it up. The floor band sits above the 60 Hz line so the ratio tracks the resonance, not the overall noise level.
The conversion
When the dominant internal noise is output- or sensor-side, the output PSD near resonance is |S(jω)|² times that noise, so the peak/floor ratio is the height of the sensitivity peak. For actuator-side noise it is only proportional (an extra plant-gain factor) — which is exactly why the constant gets calibrated in step 3.
‖S‖∞ is the inverse of the closest the loop comes to the −1 instability point. The NCF margin is that distance, normalized — so the margin is inversely proportional to the peak.
Assume the model is right at the beginning. Take the median Spk over the first 7.5 s as the reference and the model's binding-band margin bnom = 0.588. Healthy reads bnom; as the peak grows, b falls.
Because the constant is calibrated, M7 is a relative reading — it needs the healthy reference. That is the price of being output-only. A companion method that estimates b straight from the closed-loop S and T reads it absolutely, but needs the band excited.
Why output-only
FRF methods
Under a low-frequency input, the open-loop FRF dm/dc collapses to the tautology −1/C at 37 Hz — it reports a near-zero margin even when the loop is perfectly healthy.
Method 7
M7 ignores the input, so the lock can't fool it. It reads the 37 Hz resonance in dm — and is the only indicator that still detects when the input has no energy up there.
What it can miss
The peak band is a built-in assumption that the instability will appear near 37 Hz. Where it does, M7 is sharp and sensitive. But a marginality whose sensitivity peak lands outside that band is under-read or missed entirely — and that is not hypothetical. Verified on the real model:
| scenario | peak ends up at | true margin b | M7 reports |
|---|---|---|---|
| too much integral gain (low-PM mode) | ~20 Hz | 0.087 (near unstable) | 0.40 — misses the severity |
| phase-delay instability | migrates to ~4 Hz | falling | blind (peak below the band) |
| gain-type damage (the design case) | 35 → 40 Hz, stays in band | 0.34 | 0.38 — handled |
Calibration & robustification
The reading is only as honest as its healthy reference. Four things are fit once, on the calibration window (the first seconds, assumed healthy); three guards keep a noisy spectrum from lying.
58–62 Hz mains line; runs out to 100 Hz.Robustness is three knobs, none tuned to the damage: averaging inside the window (more Welch segments lower per-bin variance), a 3-bin median on the spectrum before the peak (kills single-bin spikes without flattening a ~6-bin resonance), and the quiet-shelf floor.
Making it sharp
A first attempt scanned the spectrum relative to baseline, max|S/S0|², and read the real damage as a blunt 0.42 — the resonance moves and broadens, so the ratio dilutes. The fix: read the absolute sensitivity peak the way M7 does (peak over floor), but with the peak found anywhere in the band instead of a fixed window. With one steady input it is sharp again:
| steady test | true b | sharp scan (peak anywhere) | M7 (fixed band) |
|---|---|---|---|
| healthy | 0.588 | 0.58 ±0.04 | 0.59 ±0.06 |
| damage at 37 Hz | 0.344 | 0.36 — sharp now | 0.37 |
| low-PM mode at 20 Hz | 0.087 | 0.16 — caught | 0.36 — misses |
The test battery
To score any indicator honestly you need cases that isolate distinct failure mechanisms. These five do — three keep the binding mode in M7's band, two migrate it out (one by integral action, one by pure phase lag with the gain unchanged). Every number below is from the verified battery (run_osi_test_cases.m); "detect" uses the relative alarm b < 0.8·b_nom ≈ 0.47.
| case — what changes | binding f | band | true b | M7 | PP scan | M9.1 (codex) |
|---|---|---|---|---|---|---|
| C1 healthy (reference) | 35 Hz | in | 0.59 | 0.62 ok | 0.64 ok | 0.54 ok |
| C2 gain damage ×2.4 (measured 7000→5000) | 39 Hz | in | 0.34 | 0.42 detect | 0.41 detect | 0.44 detect |
| C3 excess gain ×3.8 (extrapolated) | 36 Hz | in | 0.25 | 0.31 detect | 0.32 detect | 0.37 detect |
| C4 integral action ×10 (I 20→200) | 20 Hz | OUT | 0.09 | 0.45 — blind (5× over-read) | 0.17 detect | 0.14 detect |
| C5 phase lag, +160-sample delay (gain unchanged) | 2.3 Hz | OUT | 0.31 | 0.67 miss | 0.56 miss | 0.52 miss |
The 3-case reality check
Run the healthy→damaged jump (at t = 10 s) under three input characters, 8 disturbance seeds each. M7's peak and floor bands are adjacent, so a broadband input cancels in the ratio. The wide scan takes the tallest peak anywhere — and under broadband input that peak is often input-driven, not the sensitivity resonance, so it locks onto the wrong thing and misses the damage. The seeds tell the story:
Strictly backward-looking. Every point uses only the 4 s of data ending at that time (timestamped at the window end, not its center), a trailing median, and a calibration fit on the pre-jump phase only — so nothing peeks ahead. Verified by a truncation test: zeroing all future samples leaves every past value unchanged to 0 (a centered median, by contrast, shifts them by ~4e-3 — and is not used).
The verdict. No output-only scan beat M7 across the three inputs — there is a real tension between looking everywhere (catches surprises, but a broadband input contaminates it) and input-robustness (M7's adjacent bands, which assume the location). So the honest moves, each verified, are:
| instead of… | do this (verified) |
|---|---|
| hard-coding 37 Hz ("cheating") | place M7's band at the model-predicted instability frequency — the −180° crossing of C·H₀ — and re-derive it if the model updates |
| an output-only wide scan as primary | keep it only as a side watchdog for clean (internal-noise) excitation; it is contaminated by broadband input |
| guessing an unknown location | use an input-aware, coherence-gated margin over a wide band — coherence is what rejects the input contamination |
M9.1 is that fusion (the violet curve above, from the codex folder, run here unchanged). It uses the phase-aware closed-loop S, T branch on coherent excited bins and a coherence-gated residual-output branch where the band is quiet — and it is the only one that detects in all three cases: damaged 0.34 / 0.41 / 0.34 (true 0.344), and earliest (≈10.5 s high/mixed vs M7's 13.5 s). It is the input-aware, coherence-gated answer the table points to. (One caveat, unchanged from its source: M9.1 smooths with a centered 3-tap median, a mild ±0.5 s acausal step.)
Speed
M7's resolution comes from a multi-second PSD buffer, so the reading lags by roughly half the buffer, and the resonance itself takes a few cycles to build. That is a configuration choice, not a law.
Swap the block PSD for a recursive narrowband tracker — a bandpass at 37 Hz plus an exponential power estimate — and Spk updates every sample with ~0.2–0.5 s of memory instead of seconds. The real floor is physics: telling a 37 Hz tone from noise needs only a few of its cycles, about 0.1 s.