Tuning algorithms: Phase 0 + Phase 1 — calibrated power spectrum, DSP correctness, coherence, verify coverage - #434
Merged
Conversation
Deep audit of src/main/analysis DSP and tuning logic, KB/apply/verify flow review, and 2026 market benchmark (PIDtoolbox PRO, Plasmatree, Blackbox Explorer 2025.12, FPVtune). Key findings: amplitude-domain spectrum averaging (uncalibrated PSD), per-step response measurement without deconvolution, dead coherence plumbing, hardcoded frame-resonance band, missing BF 4.5/4.6 version-conditional recommendations, unverified CLI-applied settings. Roadmap: Phase 0 golden-output harness, Phase 1 DSP correctness (single dB-scale recalibration event), Phase 2 SOTA parity (single time-domain recalibration event), Phase 3 differentiators (what-if simulation, explainable recommendations, filter placement optimizer). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EJhhk2frYDDnpNbSHRxGdv
Runs FilterAnalyzer/PIDAnalyzer/TransferFunction pipelines over seeded demo BBLs and a real VX3.5 BBL fixture, snapshotting stable summaries (recommendations, noise floors, peaks, step/TF metrics) into JSON fixtures. Any behavioral change in analysis now shows up as a golden diff. Regenerate with UPDATE_GOLDEN=1; only the two planned recalibration PRs may regenerate wholesale. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EJhhk2frYDDnpNbSHRxGdv
FFTCompute now produces a calibrated one-sided power spectrum (SPECTRUM_SCALE_VERSION = 2): segments are detrended, Hanning-windowed, normalized by coherent window gain ((Σw)²), Welch-averaged in the POWER domain (was amplitude domain), and reported as 10·log10(power). A sine of amplitude A reads exactly 10·log10(A²/2) independent of FFT size and sample rate; white-noise floors depend only on FFT size. New calibration unit tests assert the theoretical values. All absolute dB thresholds shift +10 dB to the new scale in the same commit (NOISE_LEVEL_BY_SIZE, noise-target anchors, LPF2 disable thresholds, propwash floor bypass, mechanical-health extreme noise, flight-quality noise-floor anchors). Relative dB thresholds (prominence, deltas, convergence) are scale-invariant and unchanged. Empirical offset verified on demo (+10.0 dB) and real VX3.5 (+10.5-11.2 dB) logs; golden fixtures regenerated — recommendation directions unchanged. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EJhhk2frYDDnpNbSHRxGdv
Severity ratio now divides event band energy by a CLEAN baseline — the 20-90 Hz band energy of contiguous runs outside every drop + post-drop window, each run FFT'd separately (no concatenation artifacts) and length-weighted. The previous whole-flight baseline included the prop-wash oscillation itself, compressing severity on aggressive flights and saturating the ratio when oscillation dominated total energy (strong and weak oscillation scored identically). Falls back to the whole flight when no clean run is at least 1024 samples. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EJhhk2frYDDnpNbSHRxGdv
… P1.3) Peak detection in NoiseAnalyzer now handles flat-topped peaks (plateau runs count once, at their center), enforces a 15 Hz minimum spacing so a broad resonance hump reports as one peak instead of several adjacent bins, and refines peak frequency/magnitude with 3-point parabolic interpolation for sub-bin accuracy. Frame-resonance classification is size-aware via FRAME_RESONANCE_BY_SIZE (1"/2.5": 150-350 Hz ... 7": 60-150 Hz) instead of a fixed 80-200 Hz band — a micro frame resonating at 300 Hz is no longer misclassified as electrical noise. droneSize threads from FilterAnalyzer options through analyzeAxisNoise to classifyPeak; 5" band remains the fallback. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EJhhk2frYDDnpNbSHRxGdv
…te (P1.4) TransferFunctionEstimator now computes magnitude-squared coherence γ²(f) = |S_xy|²/(S_xx·S_yy) per axis (the cross/auto spectra were already accumulated; S_yy is new) and summarizes it as coherenceMean over the 1-30 Hz stick-input band. Coherence is omitted when only one Welch window fits (trivially 1). Wiring that was dead until now comes alive: PIDAnalyzer passes coherenceMean into scoreWienerDataQuality, so the axis-coverage sub-score uses real data instead of a constant 50 and low_coherence warnings fire. New TF_COHERENCE_GATE (0.5): TF-1..TF-4 gain recommendations are skipped for any axis whose transfer function is not coherence-trustworthy — verified on the real VX3.5 log where a spurious TF-2 yaw P cut is now correctly suppressed. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EJhhk2frYDDnpNbSHRxGdv
…max advisory, TF margin sentinels (P1.5) - normalizeThrottle deduplicated into src/main/analysis/throttleUtils.ts (was triplicated in SegmentSelector, ThrottleSpectrogramAnalyzer, PropWashDetector with drift risk). - FeedforwardAnalyzer small/large step split now uses the max stick rate actually flown (deriveMaxStickRate from setpoint traces, floored at 300 deg/s) instead of assuming the BF default 670 deg/s rate profile. - simplified_dmax_gain=0 recommendation for <=5" quads is now informational — auto-applying silently flipped a simplified-tuning slider off without the pilot's consent. - TF gain/phase margins report crossingFound flags instead of silently passing their 60 dB/90° caps as measurements; the flight-quality Phase Margin component skips axes without a measured gain crossover, so an unmeasured margin no longer scores as 'very stable'. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EJhhk2frYDDnpNbSHRxGdv
Throttle-binned analyses no longer FFT concatenations of non-contiguous samples (which create phantom spectral content at splice discontinuities). ThrottleSpectrogramAnalyzer computes per-band spectra from contiguous runs only — per-run Welch FFT, length-weighted power average; bands whose samples are only short scattered chunks report no spectrum instead of an artifact-ridden one. ThrottleTFAnalyzer estimates the per-band transfer function from the longest contiguous run (min 2048 samples) since cross-spectra require an unbroken time series. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EJhhk2frYDDnpNbSHRxGdv
…tion (P1.8) Steady-segment detection now also checks yaw gyro variance with a relaxed 1.5x threshold (YAW_STEADY_MULTIPLIER) — a segment with an active yaw spin is not a steady hover and polluted noise statistics. FilterRecommender gains rule F-YAW-RES: a strong yaw-only peak (>=12 dB) that the dynamic notch does not cover and that has no roll/pitch counterpart is surfaced as an informational observation (loose stack / motor mount / frame flex indicator). Yaw still never drives LPF cutoffs by design — documented in the KB. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EJhhk2frYDDnpNbSHRxGdv
…read-back (P1.9) getFeedforwardConfiguration now parses the fields that were always present in mspLayouts.ts but never read: feedforward_averaging, dyn_idle_min_rpm (base layout), and vbat_sag_compensation, thrust_linear, anti_gravity_gain, tpa_mode/rate/breakpoint (extended API 1.45+ layout, gated by response length so a short pre-1.45 response never misreads offset 21). verifyAppliedConfig moves those settings from the skip-list into the verified set — previously TPA, anti-gravity, thrust linearization, dynamic idle and vbat sag changes were applied and saved with zero read-back verification. On old firmware they degrade to 'unchecked' (verified=false) instead of being silently skipped. Genuinely CLI-only settings (tpa_low_always, pidsum_limit*, rc_smoothing_auto_factor, simplified_dmax_gain, dterm_lpf1_dyn_expo) remain skipped. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EJhhk2frYDDnpNbSHRxGdv
Major 1: informational recommendations now pass through deduplication unmerged — the F-YAW-RES no-op observation could previously replace an actionable F-DN-COUNT reduction sharing the setting name and inherit 'high' confidence. Major 2: SPECTRUM_SCALE_VERSION moved to shared constants and stamped into FilterMetricsSummary at write time. ConvergenceDetector refuses to compare noise floors across scale versions (a v1-stored flight vs a v2 measurement carries a phantom ~+10 dB shift that read as a huge regression); flash convergence also skips the cross-scale noise check. Major 3: verifyAppliedConfig silently skips advanced settings whose fields are absent from the firmware's (pre-1.45, short) MSP_PID_ADVANCED layout instead of marking them unchecked — previously every apply on BF 4.3/4.4 flipped verified=false and fired a false-positive auto diagnostic report. Minor 4: flash convergence ignores 90-degree phase-margin placeholders (phaseMarginCrossingFound=false) instead of diffing them as measurements. Nits: stale extreme-noise comment, ENBW-corrected white-noise floor formula in docs, POWER_FLOOR/DB_SENTINEL exported from FFTCompute and reused, propwash severity cross-version caveat in the KB. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EJhhk2frYDDnpNbSHRxGdv
/doc-sync audit across README, TESTING, ARCHITECTURE, SPEC, subdirectory CLAUDE.md files, and design docs. Decision tables updated to the v2 power-spectrum scale (size-aware noise levels, 0/-60 dB targeting anchors, -35 dB LPF2 disable), size-aware frame-resonance bands, F-YAW-RES row, coherence gate for TF rules, clean-segment propwash baseline, and the extended MSP_PID_ADVANCED verification. TESTING.md inventory recounted per file (3243 tests / 147 files, incl. 32 pre-existing stale rows fixed). TUNING_ALGORITHMS_AUDIT.md marked Active with Phase 0/1 implemented. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EJhhk2frYDDnpNbSHRxGdv
There was a problem hiding this comment.
Pull request overview
Implements Phase 0 (golden-output regression harness) and Phase 1 of the tuning-algorithms audit roadmap across the analysis pipeline, with a calibrated v2 power-spectrum scale, coherence computation + TF gating, contiguity-safe throttle-binned FFT/TF, prop-wash baseline fixes, size-aware resonance/noise thresholds, and extended apply verification coverage.
Changes:
- Recalibrates FFT/PSD computation to a v2 calibrated one-sided power spectrum and updates all dependent thresholds, scoring anchors, and docs/fixtures accordingly.
- Improves analysis robustness: peak detection (plateaus/spacing/interpolation), size-aware resonance bands, coherence-based data-quality integration + TF rule gating, contiguity-safe throttle band processing, and clean-baseline prop-wash severity.
- Extends MSP_PID_ADVANCED parsing and post-apply verification read-back coverage, adds golden-output fixtures/tests, and updates documentation inventories/status.
Reviewed changes
Copilot reviewed 60 out of 60 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| src/shared/utils/tuneQualityScore.ts | Updates noise-floor scoring anchors for v2 spectrum scale; adjusts phase-margin scoring to ignore unmeasured margins. |
| src/shared/utils/tuneQualityScore.test.ts | Updates quality-score tests to match v2 noise-floor anchors and new scoring behavior. |
| src/shared/utils/metricsExtract.ts | Stamps filter summaries with spectrumScaleVersion; plumbs phaseMarginCrossingFound into TF summaries. |
| src/shared/utils/metricsExtract.test.ts | Adjusts rounding assertions for newly added boolean fields. |
| src/shared/types/tuning-history.types.ts | Adds spectrumScaleVersion to stored filter metrics and phaseMarginCrossingFound to TF summaries. |
| src/shared/types/pid.types.ts | Extends FeedforwardConfiguration to include additional MSP-readable advanced fields (TPA, anti-gravity gain, etc.). |
| src/shared/types/analysis.types.ts | Refactors TF metrics typing; adds coherence and crossingFound flags to TF metric shape. |
| src/shared/constants.ts | Adds SPECTRUM_SCALE_VERSION constant and documents v2 scale semantics. |
| src/main/utils/verifyAppliedConfig.ts | Expands which feedforward-stage settings are verified via MSP read-back; avoids false negatives on older firmware layouts. |
| src/main/utils/verifyAppliedConfig.test.ts | Adds tests for extended advanced-setting verification, mismatch behavior, and old-firmware silent skips. |
| src/main/msp/test/mspResponseFactory.ts | Adds support for generating both short and full MSP_PID_ADVANCED layouts in tests. |
| src/main/msp/MSPClient.ts | Parses extended MSP_PID_ADVANCED fields using length-gated layout handling. |
| src/main/msp/MSPClient.test.ts | Adds test coverage for 61-byte (API 1.45+) parsing and 55-byte omission behavior. |
| src/main/msp/CLAUDE.md | Documents MSP_PID_ADVANCED parsing/verification behavior. |
| src/main/CLAUDE.md | Updates main-process architecture docs for scale-version stamping and extended apply verification coverage. |
| src/main/analysis/TransferFunctionEstimator.ts | Adds magnitude-squared coherence computation, coherenceMean summary, and margin crossingFound flags. |
| src/main/analysis/TransferFunctionEstimator.test.ts | Adds unit tests for coherence behavior and metric plumbing. |
| src/main/analysis/throttleUtils.ts | Introduces shared throttle normalization utility for analysis modules. |
| src/main/analysis/throttleUtils.test.ts | Adds unit tests for throttle normalization heuristics. |
| src/main/analysis/ThrottleTFAnalyzer.ts | Makes throttle-band TF estimation contiguous-run safe (longest run per band) and introduces minimum run length. |
| src/main/analysis/ThrottleSpectrogramAnalyzer.ts | Makes per-band spectra contiguous-run safe; introduces contiguous-run extraction + run-weighted power averaging. |
| src/main/analysis/ThrottleSpectrogramAnalyzer.test.ts | Adds tests for contiguous-run extraction and contiguity-safe spectrogram behavior. |
| src/main/analysis/SegmentSelector.ts | Adds yaw steadiness gating with relaxed threshold multiplier; deduplicates throttle normalization. |
| src/main/analysis/SegmentSelector.test.ts | Adds tests for yaw steadiness inclusion and relaxed threshold behavior. |
| src/main/analysis/PropWashDetector.ts | Reworks prop-wash severity baseline to use clean (non-event) contiguous runs; exports clean-run computation. |
| src/main/analysis/PropWashDetector.test.ts | Adds tests validating clean-run baseline behavior and non-saturated severity discrimination. |
| src/main/analysis/PIDRecommender.ts | Adds coherence gate for TF rules; marks simplified D-max disable as informational; clarifies advisory semantics. |
| src/main/analysis/PIDRecommender.test.ts | Adds tests for coherence gating and informational D-max recommendation behavior. |
| src/main/analysis/PIDAnalyzer.ts | Plumbs coherenceMean into Wiener data-quality scoring; derives max stick rate from setpoint for FF analysis. |
| src/main/analysis/NoiseAnalyzer.ts | Updates peak detection (plateaus/spacing/interpolation), size-aware resonance classification, and power-domain averaging. |
| src/main/analysis/NoiseAnalyzer.test.ts | Adds tests for new peak detection behaviors and size-aware resonance bands; updates noise-tier thresholds. |
| src/main/analysis/MechanicalHealthChecker.ts | Updates extreme-noise thresholding for v2 spectrum scale and size-aware rationale. |
| src/main/analysis/MechanicalHealthChecker.test.ts | Updates tests to reflect v2-scale thresholds and size-aware extreme-noise behavior. |
| src/main/analysis/goldenOutputs.test.ts | Adds golden-output regression harness (demo + real BBL) with deterministic RNG and JSON fixture comparison. |
| src/main/analysis/FilterRecommender.ts | Adds yaw-only resonance informational rule; ensures informational recs don’t collide with actionable deduplication. |
| src/main/analysis/FilterAnalyzer.ts | Threads drone size through axis noise analysis for size-aware peak classification. |
| src/main/analysis/FFTCompute.ts | Implements calibrated v2 one-sided power spectrum (detrend + coherent-gain normalization + power-domain Welch averaging). |
| src/main/analysis/FFTCompute.test.ts | Adds calibration tests validating theoretical PSD levels and detrending behavior. |
| src/main/analysis/FeedforwardAnalyzer.ts | Derives max stick rate from setpoint traces with floor/fallback; uses it for small/large step split. |
| src/main/analysis/FeedforwardAnalyzer.test.ts | Adds unit tests for derived max stick rate behavior. |
| src/main/analysis/ConvergenceDetector.ts | Adds cross-spectrum-scale guard; avoids phase-margin placeholder deltas; skips cross-scale noise comparisons. |
| src/main/analysis/ConvergenceDetector.test.ts | Adds tests for cross-scale guard and phase-margin sentinel handling. |
| src/main/analysis/constants.ts | Recalibrates absolute dB thresholds to v2 scale; adds size-aware resonance bands and peak spacing constant; re-exports spectrum scale version. |
| src/main/analysis/CLAUDE.md | Updates analysis architecture docs to reflect v2 spectrum, coherence, contiguity-safe processing, and golden-output harness. |
| src/main/analysis/fixtures/golden/real-vx35-tf.json | Adds/updates golden TF analysis summary fixture for real VX3.5 log. |
| src/main/analysis/fixtures/golden/real-vx35-pid.json | Adds/updates golden PID analysis summary fixture for real VX3.5 log. |
| src/main/analysis/fixtures/golden/real-vx35-filter.json | Adds/updates golden filter analysis summary fixture for real VX3.5 log. |
| src/main/analysis/fixtures/golden/demo-pid-cycle0.json | Adds/updates golden PID demo-cycle fixture. |
| src/main/analysis/fixtures/golden/demo-flash-cycle0.json | Adds/updates golden Flash/Wiener demo-cycle fixture. |
| src/main/analysis/fixtures/golden/demo-filter-cycle2.json | Adds/updates golden Filter demo-cycle fixture (cleaner). |
| src/main/analysis/fixtures/golden/demo-filter-cycle0.json | Adds/updates golden Filter demo-cycle fixture (noisier). |
| SPEC.md | Updates test inventory counts and progress summary metadata for the new coverage/harness. |
| README.md | Updates feature descriptions, module count, test counts, and tuning-methodology documentation for v2 spectrum/coherence/contiguity changes. |
| docs/TUNING_SESSION_EVALUATION.md | Updates evaluation criteria to v2 spectrum scale and new scoring/convergence guards. |
| docs/TUNING_ALGORITHMS_AUDIT.md | Adds the audit/roadmap design doc as Active with Phase 0/1 marked implemented. |
| docs/README.md | Adds the audit doc to the docs index. |
| docs/PID_TUNING_KNOWLEDGE.md | Updates the tuning knowledge base to reflect v2 spectrum scale, coherence, contiguity-safe FFT/TF, and verification coverage changes. |
| ARCHITECTURE.md | Updates architecture/testing inventories and analysis-engine docs for v2 spectrum, coherence, contiguity, and golden-output harness. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
276
to
280
| │ │ │ ├── MechanicalHealthChecker.ts # Frame/motor health diagnostics | ||
| │ │ │ ├── WindDisturbanceDetector.ts # Wind/disturbance detection | ||
| │ │ │ ├── headerValidation.ts # BB header diagnostics | ||
| │ │ │ ├── throttleUtils.ts # Shared throttle normalization + contiguous run finder | ||
| │ │ │ └── constants.ts # Tunable thresholds |
Comment on lines
+303
to
+306
| | `DataQualityScorer.ts` | 403 | 39 | Flight data quality scoring (0-100), confidence adjustment, low coherence warning | | ||
| | `headerValidation.ts` | 300 | 45 | BB header diagnostics, version-aware debug mode, RPM enrichment, preset gap analysis fields | | ||
| | `throttleUtils.ts` | 24 | 4 | Shared throttle normalization + contiguous-run finder | | ||
| | `constants.ts` | 927 | 11 | All tunable thresholds (validated by `constants.test.ts`) | |
Comment on lines
+62
to
+64
| - `getFeedforwardConfiguration()` parses the base layout (FF boost/smooth/jitter/max-rate-limit, d_min per axis + gain/advance, iterm_relax type/cutoff, `feedforward_averaging`, `dyn_idle_min_rpm`) plus length-gated extended fields: `vbat_sag_compensation` and `thrust_linear` when the response reaches their offsets, and `anti_gravity_gain`/`tpa_mode`/`tpa_rate`/`tpa_breakpoint` from the 61-byte API 1.45+ layout (a response long enough for TPA also guarantees the ≥1.45 meaning of anti_gravity_gain @21) | ||
| - These parsed fields feed `verifyAppliedConfig()` post-apply read-back — on older firmware without the extended layout the settings land in `unchecked` instead of failing verification | ||
|
|
Comment on lines
+155
to
+157
| // Only axes with a measured gain crossover count — a capped 90° | ||
| // placeholder (no crossing found) must not read as "very stable". | ||
| const axes = [tf.roll, tf.pitch, tf.yaw].filter((a) => a.phaseMarginCrossingFound !== false); |
- throttleUtils.ts descriptions no longer claim it contains the contiguous-run finder (that lives in ThrottleSpectrogramAnalyzer) - msp/CLAUDE.md: pre-1.45 firmware fields are silently skipped during verification, not marked unchecked - tuneQualityScore: phase-margin filter comment documents the backward-compatibility treatment of legacy records without the flag Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EJhhk2frYDDnpNbSHRxGdv
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements Phase 0 and all of Phase 1 of the tuning-algorithms audit roadmap (
docs/TUNING_ALGORITHMS_AUDIT.md, included here and marked Active).What's in here
P0.1 — Golden-output regression harness: full analysis pipelines run over seeded demo BBLs + a real VX3.5 BBL; stable summaries snapshotted to JSON fixtures (
src/main/analysis/__fixtures__/golden/). Regenerate withUPDATE_GOLDEN=1; only designated recalibration PRs may regenerate wholesale.P1.1 — Calibrated power spectrum (v2 scale, the dB recalibration event): detrended + Hanning, (Σw)² coherent-gain normalization, power-domain Welch averaging,
10·log10. A sine of amplitude A reads exactly10·log10(A²/2)independent of FFT size/sample rate (unit-tested against theory). All absolute dB thresholds shifted +10 in the same commit; relative dB thresholds untouched (scale-invariant).SPECTRUM_SCALE_VERSION = 2is stamped into stored metrics; convergence detection refuses cross-scale comparisons.P1.2/P1.3 — Robust peak detection + size-aware frame resonance: plateau handling, 15 Hz minimum spacing, parabolic sub-bin interpolation;
FRAME_RESONANCE_BY_SIZE(micros resonate up to 350 Hz) replaces the fixed 80–200 Hz band.P1.4 — Coherence: magnitude-squared coherence γ²(f) computed per axis; feeds the Wiener data-quality axis-coverage sub-score (previously a dead constant 50) and gates TF-1..TF-4 gain recommendations per axis (
TF_COHERENCE_GATE = 0.5) — verified on a real log where a spurious TF yaw P-cut is now suppressed.P1.5 — Quick wins:
normalizeThrottlededuplicated; FF small/large-step split uses the max stick rate actually flown;simplified_dmax_gain=0is advisory (never auto-applied); TF gain/phase margins carrycrossingFoundflags so 60 dB/90° caps stop scoring as "very stable".P1.6 — Contiguity-safe throttle-binned FFT/TF: per-band spectra from contiguous runs only (no splice artifacts); per-band TF from the longest contiguous run.
P1.7 — Prop-wash clean baseline: severity = event energy vs clean (non-event) segments — the whole-flight baseline saturated the ratio on aggressive flights (strong and weak oscillation scored identically).
P1.8 — Yaw coverage: steadiness gating includes yaw at a relaxed 1.5× threshold; new informational rule F-YAW-RES for strong yaw-only peaks the notch doesn't cover.
P1.9 — Extended apply verification:
MSP_PID_ADVANCEDparsing now covers averaging, dyn idle, vbat sag, thrust linearization, anti-gravity gain, and TPA (length-gated 61-byte API 1.45+ layout) — settings that were previously applied and saved with zero read-back verification are now verified; on older firmware they degrade to silent skip (no false-positive diagnostic reports).Review gates
/tuning-advisor reviewran on the full diff — 3 major findings fixed in1efac19(informational-rec dedup collision, cross-scale metric comparison guard + version stamping, false verification failures on pre-1.45 firmware), plus minors/nits./doc-syncran — README decision tables, TESTING.md inventory (3243 tests / 147 files), ARCHITECTURE.md, SPEC.md, subdirectory CLAUDE.md files and design docs synced; KB (docs/PID_TUNING_KNOWLEDGE.md) updated with every rule change.Validation
tsc --noEmitclean.🤖 Generated with Claude Code
https://claude.ai/code/session_01EJhhk2frYDDnpNbSHRxGdv
Generated by Claude Code