A complete, plain-language field guide to every argument and tunable parameter of the
real-time Online Stability Indicator (fable_osi_runtime.m) and its authority law,
as deployed on the Speedgoat target.
fable_auth)The OSI (Online Stability Indicator) watches the servo-hydraulic control loop
in real time and answers one question every 0.125 s:
how close is the loop to going unstable right now? It answers with a single number, the
margin b — large means safe, small means near the edge.
It does not just observe. It also acts: an authority law turns the margin into a
gain factor auth (called a internally, range a_min…a_max)
that multiplies the command going to the actuator. When the loop is healthy the OSI runs the loop at
full authority (auth = 1); when the margin drops toward the target it
sheds authority to pull the loop back from the edge, then recovers it once the margin returns.
target (default 0.55).
The law regulates the margin b onto this value. A healthy loop sits above it and runs at full authority;
a degrading loop is held right at it. target is also reused as the detection
threshold. Change this one number and the whole system's conservatism moves with it.
The Simulink / Speedgoat block calls one function once per base-rate sample
(the base rate is fs = 2048 Hz, so every dt = 1/2048 s):
The loop command (drive) signal, in mm. This is the input u of the plant. In the
spectral estimates it produces the auto-spectrum Suu.
The measured displacement (response) signal, in mm. This is the output y of the
plant. It produces Syy and, together with dd, the cross-spectrum Suy.
The mode switch. It combines a base mode with an optional +2 pause bit:
en = 0 — shadow: the estimator runs and logs, but the published authority is forced to a_init (the loop does not feel the OSI). Counters and latches still evolve.en = 1 — active: the authority the law computes is published to the “Apply OSI gain” product.+2 (i.e. 2 or 3) — pause: the raw data rings and transient statistics reset, but the calibrated baseline, regime memory and authority state are kept. Same contract as osi_gain_runtime.The remaining six inputs are compile-time constant arrays built once by
prepare_fable_runtime.m. They carry all configuration — the block never takes a live
parameter. They are the subject of most of this document.
| Argument | Shape | What it carries |
|---|---|---|
| fbls | 57×1 | Scalar OSI config vector (segment sizes, gates, calibration, fast-path knobs). Index map in §5–§8 and the master table. |
| fblw | segment_n×1 | The slow-path Hann window (2048 points) applied to each 1 s segment before its FFT. |
| fblbins | nf×5 | Per-slow-bin table: [freq_hz, fft_bin, keep, res_keep, nominal_curve] — which FFT bins are analysed, which survive line-rejection, which are in the residual hazard band, and the prior-model margin curve. |
| fblfw | fast_segment_n×1 | The fast-path Hann window (512 points) for the 0.25 s fast segments. |
| fblfbins | nf_fast×6 | Per-fast-bin table: [freq_hz, fft_bin, keep, cell_lo, cell_hi, band_id] — the fast grid plus the map that projects slow bins onto fast bins and the burst sub-band id of each bin. |
| fblag | n_alpha×1 | The authority-prediction gain grid alpha_grid (25 log-spaced loop-gain multipliers, 0.05–20). Used to predict the margin at other authority levels. |
| fbla | 31×1 | The authority-law parameter vector (target, rates, gates, trip response). Index map in §8 and the master table. |
All outputs are held constant between the internal 0.125 s steps (they refresh once per step, published on tick T0+56).
| Output | Meaning |
|---|---|
| auth | The authority factor a for the “Apply OSI gain” product. In shadow mode (en_act=0) it is pinned to a_init. |
| b_osi | The selected margin (the headline number). NaN = no evidence yet / warm-up (never a fabricated value). |
| b_st | The slow coherent-branch margin (NaN when the band is unobservable). |
| b_res | The residual-branch margin (equals the cap 1/√2 when the branch is not engaged). |
| b_fast | The fast short-memory margin (NaN when unavailable). |
| trip_reason | 0 none, 1 quiet-band burst trip, 2 fast FRF-collapse trip. |
| valid | 1 when b_osi is real evidence (post warm-up, non-NaN). |
| decision | Authority-law action this step: 0 hold, 1 down, 2 severe down, 3 up, 4 fast trip. |
The indicator runs on two clocks so it can be both accurate and fast:
| Scale | Cadence | Segment | Memory | Purpose |
|---|---|---|---|---|
| SLOW path | hop_s = 0.25 s | 1 s Hann (segment_s) | 5 s ring, 17 segments (window_s) | Accurate margin level and the recovery authority. It can only be trusted slowly because good spectra need averaging. |
| FAST path (“quick dip”) | step_s = 0.125 s | 0.25 s Hann (fast_segment_s) | ~0.6 s ring, 3 segments (fast_ring_n) | Catches a sudden collapse in ≤ 0.5 s. Fast trips may only ever reduce authority; increases always require the slow, accurate margin. |
Five detection/decision branches run on top of those two clocks. They are the organizing principle for every parameter in this document:
dd, dm rings→
detrend + Hann + FFT→
Suu, Syy, Suy (median over ring)→
FRF M, coherence g2, residual res→
excited / quiet gates→
ST + residual margins→
combine → b→
authority law → auth
The runtime time-slices this pipeline across 56 base-rate ticks (one bounded phase per tick) so the Speedgoat never does the whole burst in a single 488 µs slot — but the arithmetic is bit-identical to doing it all at once. That scheduling is an implementation detail; it does not change any parameter's meaning.
These are the quantities the branches are built from. Understanding them makes the parameters obvious.
From the windowed FFTs U (of dd) and Y (of dm), aggregated by
median across the ring of segments:
The empirical frequency response (FRF, the transfer from command to response at each bin):
M
M = SuySuu
The raw magnitude-squared coherence measures how linearly related dm is to
dd at a bin (1 = perfectly driven, 0 = noise). It is bias-corrected
using the effective number of independent averages k_eff:
k_eff and the coherence gate gamma_gate are derived from the window overlap, not tuned directly:
Here K = n_segment (17), ρm is the window's overlap correlation at lag m·hop.
The gate formula comes from the null hypothesis “no true relation”, under which
P(γ² > z) = (1−z)k−1. So gamma_alpha (§7) is a false-pass probability, not a raw coherence value.
The project’s stability margin is the chordal / NCF-style distance of the Nyquist locus from the
critical point. With the sensitivity S and complementary sensitivity T:
In the estimator, L is not known directly; instead the chordal margin is computed from the FRF
M via the intermediate st, and capped at the mathematical ceiling cap = 1/√2 ≈ 0.7071:
The min is taken over the excited bins only (bins the command actually drives), after a
frequency-median smoothing of width freq_medfilt_n. The reported b is the temporal
median of the two slow branches, min(b_st, b_res), over margin_filter_n hops.
A bin with high coherence (g2→1) has almost no residual; a bin whose energy is not explained
by the command (an emerging self-excitation) keeps a large residual. The residual branch (§6) watches this in the
undriven “quiet” bins.
A bin is excited (used by the ST branch) if it passes line-rejection (keep), the coherence
gate (g2raw > gamma_gate), the input-power gate and the sidelobe gate. A bin is
quiet (used by the residual branch) if it is in the residual band, has no input, and has low
coherence (g2raw < gamma_quiet).
The fast guards do not threshold a single reading; they accumulate evidence with a one-sided CUSUM (cumulative sum) so that sustained moderate shifts trip within a few steps while isolated spikes decay:
where z is a calibrated log z-score, ν (nu) is the drift the accumulator ignores,
and h is the trip level. Each branch has its own nu/h pair (§7).
To size sheds and cap recovery, the OSI predicts the margin at other loop-gain multipliers alpha
(the alpha_grid). Freezing the plant FRF and scaling the open loop by alpha:
The loop running at multiplier alpha has authority alpha·a. The authority law walks the
contiguous safe interval of this curve around alpha = 1 to floor a shed and cap a recovery.
This is the branch that produces the accurate margin level b_st and the recovery
authority. It runs every hop_s = 0.25 s on the 5 s ring. Its parameters trade smoothness/lag against
reactivity.
Length of one analysis segment (the FFT window). Sets frequency resolution: 1 s → 1 Hz bins.
Derived count segment_n = round(segment_s·fs) = 2048. do not go below 1 s shorter kills the 1 Hz resolution the margins need.
Total span averaged. Longer ↑ = smoother, laggier margin; shorter = jumpier, faster to move.
Derived: n_segment = round((window_s−segment_s)/hop_s)+1 = 17 (the ring depth).
The slow refresh cadence — one new segment FFT per hop. Must be an integer multiple of step_s
(steps_per_hop = 2). It is the time unit for every “per hop” counter below.
Temporal median over this many distinct slow updates before b is reported. Bigger ↑ =
smoother, more constant selected OSI, but adds (n−1)·hop_s/2 of lag.
Median smoothing across neighboring frequency bins before the min is taken. Bigger ↑ = fewer single-bin dips counted as the margin. must be odd the runtime's hand-coded median filters assume odd, centered windows.
EMA weight of the slow-margin tracker b_slow_filt that the fast path uses as its direction reference.
Lower ↓ = steadier reference, slower to follow a real level change.
b_slow_filt ← (1−α)·b_slow_filt + α·b_slow.
False-pass probability of the coherence gate (see §4). Smaller ↓ = stricter gate,
fewer bins accepted, less noise in the margin but more “no evidence”. Enters the runtime already baked into
gamma_gate (fbls[8]).
Coherence ceiling for a bin to count as “quiet” (undriven). Bins above this are related to the command and are excluded from the residual branch.
Bins more than this far below the in-band input peak are treated as unexcited. Smaller (e.g. 30) ↓ =
stricter, margin computed on fewer, stronger bins. Feeds the has_input gate (§4).
Bins more than this far below a ±3 Hz neighbor are window leakage, not real excitation, and are excluded. The Hann first sidelobe is −31 dB and leaks coherently, so without this gate a low-band margin can read 0.45 instead of the true 0.7.
Minimum number of excited bins for the slow ST margin to be considered observable. Below it, b_st = NaN
(reported as no evidence rather than a guess).
The mathematical ceiling of the margin. Every branch caps its output here; it is a constant, not really a tuning knob.
Detection / fast-trip margin level. fable_osi.m's own default is 0.30, but
prepare_fable_runtime overrides it to target_outer_ncf (0.55) so detection and
regulation share one level. Used by the fast-ST trip (b_fast < threshold + fast_babs_offset).
Slow updates that must pass before any margin is reported (fills the ring first). During warm-up b_osi = NaN.
The ST branch only sees frequencies the command drives. A loop can go unstable at a frequency the command is
not exciting — a growing self-oscillation. The residual branch watches the undriven (quiet) bins
inside a hazard band for energy growth that the model cannot explain (§4, res). It engages with hysteresis
and persistence so it does not false-alarm on harmonic distortion.
The detection statistic is a per-bin log z-score of the self-normalized residual ratio against its calibrated baseline:
The hazard band the branch guards. Keep it where the loop can actually go unstable; widening it down into
harmonic-distortion territory (2–28 Hz distortion of a strong 2–7 Hz command) causes false engagement.
Enters as the res_keep column of fblbins.
The z threshold to engage the branch. Raise ↑ to make engagement rarer (fewer false alarms, later detection).
The z threshold to disengage. The gap z_on − z_off is the hysteresis band that stops the
branch chattering on/off.
Consecutive slow hops above z_on (at the same frequency) required to engage. More ↑ =
needs more sustained evidence, smoother but slower.
How long an unconfirmed engagement may persist inside the hysteresis zone before it expires. Prevents a
stale engagement from depressing the margin forever. Stored as res_hold_hops = round(res_hold_s/hop_s) = 20.
Minimum absolute growth (on top of the z threshold) needed to engage. Raise ↑ to ignore small quiet-band changes entirely. This is what makes the defendable quiet-band level absolute (~0.40), not target-relative.
Same-frequency persistence tolerance: successive exceedances must be within this many Hz to count as the same event.
Floor of the calibrated ln-ratio spread σ0. Raise ↑ to desensitize the z-score
globally (a large σ0 shrinks every z).
Lower clamp on 1 − g2 when forming res, so a perfectly-coherent bin still carries a tiny,
well-defined residual instead of exactly zero.
The fast path runs every step (0.125 s) on a short ~0.6 s ring of 0.25 s segments. It exists to catch a sudden dip in the margin within 0.25–0.5 s — far faster than the 5 s slow ring could react. It contains two CUSUM detectors (§4) that can only ever reduce authority:
trip_reason = 2.trip_reason = 1.Fast segment length → 4 Hz bins (fast_segment_n = 512). Short so it reacts quickly; too short to resolve fine structure, which is why it only trips, never sets the level.
Number of fast segments aggregated (~0.5 s memory). The fast margin uses the median over this ring.
Minimum excited fast bins for a fast statistic to be computed at all.
CUSUM drift ν for the FRF-change z. Higher ↑ = calmer (more evidence ignored per step).
CUSUM trip level h. The main speed-vs-false-alarm knob: each unit of h adds roughly one extra
0.125 s step of sustained evidence before a trip. Lower ↓ = faster, riskier trips.
A fast-ST trip also requires b_fast < threshold + fast_babs_offset. Raise ↑ to allow
trips further above target (more protective); toward 0 = trip only once the fast margin is already at target.
The FRF-change statistic watches the total loop, which includes the authority factor. If the committed
authority moves more than this (relative) the statistic is disarmed for one full analysis window
(amove_hold = round(window_s/step_s) = 40 steps) so the law's own moves never read as a plant change. In
replays where authority does not act on the plant, a_cmd = NaN leaves the detector always armed.
Floor of the calibrated ln FRF-change spread σ_d. Raise to desensitize the fast-ST z-score. With too few
calibration samples σ_d is set to 1e6 — the guard disarms itself rather than false-trip.
CUSUM drift for the burst z. Same trade as fast_st_nu.
Burst CUSUM trip level. Can sit high because a diverging loop produces a huge z: a 1–2 segment ring-down after a command step gains ~4, but sustained growth still crosses in 3–6 steps.
The guarded quiet sub-bands (rows of [lo hi] Hz), 5 bands by default. Each is a separate CUSUM. Fewer
rows = cheaper and less sensitive. Enters as per-bin band_id in fblfbins.
Floor of the calibrated ln burst-power spread. Raise to desensitize all burst bands. Bands with <8 calibration
samples get σ = 1e6 and are disarmed.
The newest fast segment's input power must stay within [lo, hi]× its ~3 s EMA for the FRF-change
statistic to be trusted. A fading or bursting command mimics a plant change; this window rejects that artifact.
EMA update rate (per 0.125 s step) of that input-power reference p_in_ema.
Every statistic above is measured against a calibrated healthy baseline. This branch builds that baseline at startup and rebuilds it whenever the excitation regime changes (a new test phase drives a different set of frequencies) — because baselines do not transfer across excitation regimes, and the excited-set change is the one exogenous signal that an instability cannot fake. These rarely need touching.
Sustained hops of excited-set change before a rebaseline is triggered. Larger ↑ = more tolerant of
slowly wandering excitation, slower to re-adapt. A change is declared when ndiff > max(6, 0.5·nref) bins differ.
Startup blackout — ignore this much data before collecting calibration windows (lets transients settle).
Number of accepted calibration windows (slow hops) that define a full baseline.
Minimum acceptable calibration length if the timeout is hit before cal_windows accumulate.
Give up waiting for a full calibration after this many hops and finalize with what is accepted (≥ cal_min_windows).
Reject a candidate window if its broadband residual differs from the running reference by more than this factor (guards against calibrating on a transient).
This many consecutive rejects means the reference itself was bad — discard and restart calibration collection.
Time constant of the gated, ultra-slow baseline drift tracking (only while healthy). Enters the runtime as
bl_alpha = hop_s/bl_adapt_tau_s = 0.0025.
Hard cap on how far baseline drift may move from the original calibration. never raise this far a large cap lets real, slow degradation be absorbed into the baseline and go undetected.
Also in fbls and derived, not user-tuned: k_eff [7] (≈9.1), gamma_gate [8],
n_alpha [50] (=25), pred_denom_floor [51] (1e-3, numerical guard on 1−M),
nf [53], nf_fast [54], pred_enable [55] (see §9), and the sizes
dt [1], fs [2], step_n [3], steps_per_hop [4], segment_n [5], n_segment [6].
fable_auth decisionThis is the actuator. Every 0.125 s it turns the margin b (and the fast trips) into the published
authority auth. Its parameters live in fbla (index in brackets). The contract:
b ≥ target → authority recovers toward a_max and stays there (healthy loop = full authority).b < target → authority sheds multiplicatively a ← a·(b/target)down_power, rate-limited.b << target (severe) → immediate shed, no confirmation, no commit gate.The OSI level to defend/track. Raising ↑ makes the system more conservative (sheds earlier).
must stay below the healthy-loop margin at full authority or the law permanently detunes chasing an
unreachable margin. Shared with the detection threshold.
EMA time constant applied to b before it sizes sheds and gates recovery. Larger ↑ = smoother,
more constant authority; 0 disables it. Severe-drop detection always also watches raw b, so smoothing never
delays catching a genuine collapse by more than down_confirm_n updates. Stored as
filt_alpha = 1 − exp(−dt_update/b_filt_tau_s).
Margin must fall below target − down_deadband to count as a deficit. Widen to ignore tiny grazes (less flicker).
Consecutive low updates before a (non-severe) shed starts. More ↑ = fewer false sheds on noise,
but adds n·dt_update of reaction delay.
Exponent of the multiplicative shed a·(b/target)down_power. Higher ↑ = deeper
correction per update; 1 = proportional.
Max shed speed (authority units/s) for a confirmed deficit. The main “catch drops fast” knob.
The key anti-compounding knob. The margin estimate lags the loop by its analysis-window flush, so each
shed is sized once and then held for down_settle_s before being re-sized. Without this, re-deriving a
multiplicative shed from the same stale reading every step compounds one dip into a slam to the floor. Higher (toward the
OSI window length) = gentler, staircase-like sheds.
A margin reading this much below the one that sized the active shed re-sizes it immediately (fresh evidence of continued decline bypasses the settle hold). Lower ↓ = more reactive to genuine decline.
Raw b < sev_frac·target is treated as severe: immediate shed, bypassing confirmation, the
commit gate, and the ordinary rate limit.
Shed speed for severe deficits (units/s). The emergency path — keep high.
Margin must exceed target + up_deadband before recovery is considered (hysteresis). Widen to kill
target-hugging oscillation; narrow for faster reclaim.
The margin must hold above the recovery threshold this long before authority moves up. Longer ↑ = more constant authority, later recovery.
Base recovery speed (units/s) when the margin is model-verified (coherent input present, valid_up true).
Recovery speed with no coherent input (“probe and verify”): the loop feels its way up while the burst guard
and residual branch stand watch. Kept several times slower than up_rate.
Surplus-proportional recovery boost: effective rate = up_rate·(1 + up_prop·(b_filt − target − up_deadband)/target).
0 = constant rate; higher = sprint back when the margin is comfortably high, creep when barely above target.
The committed authority (what the loop sees) only moves when the internally-regulated value has drifted at
least this far. Bigger ↑ = steppier, more constant authority (fewer, larger moves); 0 = continuous.
Severe sheds and fast trips bypass it. The internal value keeps integrating, so the gate never deadlocks recovery — it
just quantizes it into min_step-sized steps.
1 = use the prediction curve (§4) to floor sheds and cap recovery; 0 = pure power-law regulation
(cheaper, more shed overshoot). Tie to pred_enable (below).
Predicted margin must clear target + pred_guard to count as safe. This is also the recovery standoff:
authority may climb up to (not past) the interpolated boundary where the predicted margin crosses that level. Widen if the
prediction proves optimistic on your rig.
Shed floor as a fraction of the predicted-safe authority (0.90 = a confirmed shed stops 10% below the predicted-safe point instead of slamming to the power-law floor). DOWN path only.
OSI-side switch that actually computes the prediction grid. Set to 0 (via hs.fable_pred_enable) to drop that
pipeline phase for CPU relief; the law then regulates by power law alone. Should be turned off together with
use_pred.
Multiplicative drop on a trip (0.60 = shed 40% instantly). Burst trips (trip_reason = 1) compound this every
step while the divergence evidence persists.
A fast-ST trip (trip_reason = 2) is sized a·(b_fast/target)trip_power, never milder than
trip_drop allows. Higher ↑ = deeper drop for a given fast-margin reading.
Cooldown after a trip during which recovery is blocked and the trip re-arms.
A trip followed within this window by a confirmed excitation-regime recalibration is undone — the “trip” was the test phase changing, not the plant.
A fast-ST trip is honored only when the committed authority has been steady — moved less than
self_move_frac (relative) per update — for the last self_move_gate_s. The estimator watches the
total loop including the authority, so the law's own moves would otherwise self-trip. Real damage arrives while
a is static, so the gate costs nothing there; burst trips are never gated.
After a trip or a residual-driven (invisible-band) shed, recovery is capped at latch_relax× the post-shed
authority: hard evidence of a plant change is not re-probed immediately.
How slowly that latched ceiling is forgotten (seconds). Raise ↑ for more caution after events; lower to let a healed plant recover sooner. (Was 200 s in an earlier draft; the current tracking law uses 1 s.)
Authority floor. The most detuned the loop can get.
Authority ceiling — also the value held whenever b ≥ target and nothing is latched.
Startup authority and the shadow-mode pin. Recommended 1.0: the law defends the margin, so starting detuned is not needed.
Seconds between law calls (the OSI step cadence). Every “/s” rate and “_s” time above is converted to update counts with this.
The knobs that control OSI behavior, grouped by the branch they belong to. Derived / structural
constants (sizes, k_eff, gamma_gate, indices) are omitted — they are computed, not chosen.
Columns: the exact code name, where it lands in the runtime arrays, its default, and which way to turn it.
| Parameter | Array idx | Default | Effect — turn up (↑) |
|---|---|---|---|
| window_s | fbls→n_segment | 5.0 s | Smoother, laggier margin; more averaging. |
| hop_s | fbls[52] | 0.25 s | Slower slow-refresh; coarser cadence for all “per hop” counters. |
| segment_s | fbls→segment_n | 1.0 s | Finer frequency resolution (do not drop below 1 s). |
| margin_filter_n | fbls[14] | 3 | Smoother selected OSI, adds lag. |
| freq_medfilt_n | fbls[13] | 3 (odd) | Fewer single-bin dips counted; smoother across frequency. |
| slow_filt_alpha | fbls[15] | 0.2 | (↓) steadier fast-path reference, slower to follow level change. |
| gamma_alpha | fbls→gamma_gate[8] | 0.01 | (↓) stricter coherence gate, fewer bins, more “no evidence”. |
| gamma_quiet | fbls[9] | 0.15 | More bins allowed into “quiet” set for the residual branch. |
| input_power_range_db | fbls[10] | 35 dB | (↓) stricter; margin on fewer, stronger bins. |
| sidelobe_db | fbls[11] | 25 dB | Stricter leakage rejection. |
| min_bins | fbls[12] | 5 | Needs more excited bins before reporting a margin. |
| threshold | fbls[17] | =target 0.55 | Higher detection/fast-trip level (more protective). |
| warm_updates | fbls[35] | 4 | Longer warm-up before any margin is published. |
| residual_floor | fbls[18] | 0.03 | Higher floor on 1−g2 in the residual. |
| Parameter | Array idx | Default | Effect — turn up (↑) |
|---|---|---|---|
| residual_band_hz | fblbins(res_keep) | [28 100] Hz | Wider hazard band watched (risk of harmonic-distortion false alarms if widened down). |
| z_on | fbls[25] | 4.0 | Rarer engagement (fewer false alarms, later detection). |
| z_off | fbls[26] | 2.0 | Narrower hysteresis (disengages sooner). |
| res_on_n | fbls[27] | 4 | More sustained evidence to engage; smoother, slower. |
| res_hold_s | fbls[28] | 5 s | Unconfirmed engagement persists longer before expiring. |
| res_min_growth_db | fbls[29] | 3 dB | Ignores larger quiet-band changes (higher absolute defend level). |
| res_match_hz | fbls[30] | 3 Hz | Looser same-frequency persistence tolerance. |
| sigma0_floor | fbls[31] | 0.15 | Globally desensitizes the residual z-score. |
| Parameter | Array idx | Default | Effect — turn up (↑) |
|---|---|---|---|
| fast_segment_s | fbls→fast_segment_n[36] | 0.25 s | Coarser fast bins; slightly slower reaction. |
| fast_ring_n | fbls[37] | 3 | Longer fast memory (~more smoothing, more lag). |
| fast_min_bins | fbls[38] | 3 | Needs more excited fast bins to compute a statistic. |
| fast_st_nu | fbls[39] | 1.25 | Calmer FRF-change CUSUM (ignores more per step). |
| fast_st_h | fbls[40] | 4.5 | Later FRF-change trip (~+1 step/unit); fewer false trips. |
| fast_babs_offset | fbls[43] | 0.10 | Allows fast-ST trips further above target (more protective). |
| fast_amove_frac | fbls[56] | 0.02 | Tolerates larger authority moves before disarming the FRF-change stat. |
| fast_d_sig_floor | fbls[48] | 0.30 | Desensitizes the fast-ST z-score. |
| fast_burst_nu | fbls[41] | 1.0 | Calmer burst CUSUM. |
| fast_burst_h | fbls[42] | 6.0 | Later burst trip; fewer false trips. |
| fast_burst_bands | fblfbins(band_id) | 5 bands | More/other guarded sub-bands (cost & sensitivity). |
| fast_sig_floor | fbls[47] | 0.20 | Desensitizes all burst bands. |
| fast_pin_lo / _hi | fbls[44]/[45] | 0.25 / 4.0 | Widen the accepted input-power window (fewer artifacts rejected). |
| fast_pin_alpha | fbls[46] | 0.04 | Faster input-power reference tracking. |
| Parameter | Array idx | Default | Effect — turn up (↑) |
|---|---|---|---|
| regime_hops | fbls[34] | 8 | More tolerant of wandering excitation; slower rebaseline. |
| cal_skip_s | fbls[19] | 10 s | Longer startup blackout before calibrating. |
| cal_windows | fbls[20] | 80 | Longer, more robust baseline; slower first-ready. |
| cal_min_windows | fbls[24] | 24 | Requires more windows on the timeout path. |
| cal_timeout_hops | fbls[23] | 600 | Waits longer for a full calibration. |
| cal_reject_factor | fbls[21] | 4 | More permissive window acceptance. |
| cal_restart_rejects | fbls[22] | 12 | Slower to abandon a bad reference. |
| bl_adapt_tau_s | fbls→bl_alpha[32] | 100 s | Slower healthy-baseline drift tracking. |
| bl_adapt_max_db | fbls[33] | 3 dB | Larger drift cap (danger: can absorb real degradation). |
fable_auth → fbla)Sub-grouped by role. This is the branch that turns the margin into the published gain auth.
| Role | Parameter | fbla idx | Default | Effect — turn up (↑) |
|---|---|---|---|---|
| Setpoint / smoothing | target | [1] | 0.55 | More conservative (sheds earlier). Must stay below healthy margin. |
| b_filt_tau_s | [6] | 0.4 s | Smoother, more constant authority. | |
| Drop / shed | down_deadband | [7] | 0.01 | Ignores tinier target grazes (less flicker). |
| down_confirm_n | [8] | 2 | Fewer false sheds; more reaction delay. | |
| down_power | [9] | 1.5 | Deeper shed per update. | |
| down_rate | [10] | 2.0 /s | Sheds faster (main “catch drops” knob). | |
| down_settle_s | [28] | 1.25 s | Gentler, staircase sheds (anti-compounding). | |
| re_shed_delta | [29] | 0.02 | Less reactive to continued decline (↓ for more reactive). | |
| sev_frac | [11] | 0.60 | Severe path triggers at a higher margin (more emergencies). | |
| Severe | sev_down_rate | [12] | 8.0 /s | Faster emergency shed. |
| Recovery | up_deadband | [13] | 0.02 | More cautious recovery; kills target-hugging oscillation. |
| up_hold_s | [14] | 1.5 s | Later recovery; more constant authority. | |
| up_rate | [15] | 0.08 /s | Faster model-verified recovery. | |
| up_rate_blind | [16] | 0.02 /s | Faster blind (probe) recovery (keep < up_rate). | |
| up_prop | [17] | 3.0 | Sprints back harder when margin is comfortably high. | |
| Anti-flicker | min_step | [18] | 0.02 | Steppier, more constant authority (fewer, larger moves). |
| Prediction | use_pred | [19] | 1 | On = floor sheds / cap recovery with the model (with pred_enable). |
| pred_guard | [20] | 0.03 | Larger safety standoff on the predicted-safe boundary. | |
| pred_floor_frac | [21] | 0.90 | Shed stops closer to predicted-safe (less overshoot). | |
| Fast-trip response | trip_drop | [22] | 0.60 | Milder instant drop on a trip (↓ for deeper). |
| trip_power | [23] | 1.5 | Deeper fast-ST drop for a given b_fast. | |
| trip_cool_s | [24] | 5.0 s | Longer post-trip recovery lockout. | |
| trip_undo_s | [25] | 2.5 s | Wider window to undo a trip on a regime recal. | |
| self_move_gate_s / _frac | [30]/[31] | 1.5 s / 0.02 | Requires authority steadier/longer before honoring a fast-ST trip. | |
| Post-event latch | latch_relax | [26] | 1.15 | Higher recovery ceiling right after an event (less caution). |
| latch_decay_tau_s | [27] | 1 s | Slower forgetting of the latched ceiling (more caution). | |
| Bounds / cadence | a_min | [2] | 0.08 | Higher authority floor (less detuning allowed). |
| a_max | [3] | 1.00 | Higher ceiling (rarely changed). | |
| a_init | [4] | 1.00 | Higher startup / shadow-pin authority. | |
| dt_update | [5] | 0.125 s | Slower law cadence (tied to step_s). |
How to change these in practice. You do not edit fbls/fbla by hand. You pass an
override struct through the hs config that prepare_fable_runtime reads:
hs.fable_osi_override for Categories A–D (fields = the fable_osi config names above) and
hs.fable_auth_override for Category E (fields = the fable_auth param names). Top-level shortcuts
hs.target_outer_ncf, hs.osi_gain_min, hs.osi_gain_initial and
hs.fable_pred_enable set target/threshold, a_min, a_init and
pred_enable directly. After any change, re-run
OSI_tests/fable/test_fable_runtime_equivalence.m to confirm the runtime still matches the desktop model.
Generated from a read of the runtime source on the current branch. Notation matches the code exactly; defaults are the
validated RTHS-column values from makeConfig / makeParams.