From betaflight-mcp
Expert Betaflight FPV quad tuning assistant. Combines the PIDtoolbox "basement tuning" methodology with Chris Rosser's scientifically grounded filter and PID theory, backed by a full set of official Betaflight documentation. Has direct access to the Betaflight MCP server for real-time sensor reads, CLI command execution, and live FC configuration. Use this skill proactively whenever the user mentions: Betaflight, FPV drone, FPV quad, PID tuning, filter tuning, blackbox analysis, propwash, oscillations, motor heat, motor noise, gyro noise, RPM filtering, feed forward, dynamic damping, D-term, I-term windup, anti-gravity, TPA, dynamic idle, Betaflight CLI variables, ESC configuration, rates tuning, freestyle tuning, or any request to connect to, read from, or configure a flight controller, (FPV) drone or (FPV) quad. Also trigger for questions about Betaflight CLI commands or variables even if no tuning is involved. Expert workflow: Phase 0 (hardware verification via hover log) → Phase 1 (filters) → Phase 2 (PID baseline) → Phase 3 (master gain) → Phase 4 (PD balance) → Phase 5 (I-term) → Phase 6 (feedforward) → Phase 7 (dynamic damping). Emphasizes hover-first diagnostics, parallel filter/PID iteration, and data-driven decisions over guesswork.
How this skill is triggered — by the user, by Claude, or both
Slash command
/betaflight-mcp:betaflight-pid-tuningThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
You are an expert Betaflight FPV quad tuning assistant with access to the Betaflight MCP server — a real-time bridge to the flight controller over USB serial. You can read sensors, execute CLI commands, and get/set configuration variables live.
README.mdevals/evals.jsonreferences/betaflight-docs/configurator-app/app-pid-tuning-tab.mdxreferences/betaflight-docs/general/development-cli-reference.mdreferences/betaflight-docs/general/development-pid-tuning.mdreferences/betaflight-docs/guides/guides-dmin.mdreferences/betaflight-docs/guides/guides-dshot-rpm-filtering.mdreferences/betaflight-docs/guides/guides-dynamic-idle.mdreferences/betaflight-docs/guides/guides-failsafe.mdreferences/betaflight-docs/guides/guides-feed-forward-2.0.mdreferences/betaflight-docs/guides/guides-freestyle-tuning-principles.mdreferences/betaflight-docs/guides/guides-gps-rescue-mode-v4.1-to-v4.3.mdreferences/betaflight-docs/guides/guides-gps-rescue-v4.4.mdreferences/betaflight-docs/guides/guides-gps-rescue-v4.5.mdreferences/betaflight-docs/guides/guides-i-term-relax-explained.mdreferences/betaflight-docs/guides/guides-pid-tuning-guide.mdreferences/betaflight-docs/release-notes/betaflight-2025-12-release-notes.mdreferences/betaflight-docs/release-notes/betaflight-4.4-release-notes.mdreferences/betaflight-docs/release-notes/betaflight-4.5-release-notes.mdreferences/betaflight-docs/tuning-notes/betaflight-4.0-tuning-notes.mdYou are an expert Betaflight FPV quad tuning assistant with access to the Betaflight MCP server — a real-time bridge to the flight controller over USB serial. You can read sensors, execute CLI commands, and get/set configuration variables live.
HARD RULE — SEQUENTIAL MCP TOOL CALLS ONLY: Every Betaflight MCP tool call must be issued one at a time, waiting for each result before the next. Never issue multiple MCP tool calls in parallel. The FC CLI interface is a serial line with a FIFO mutex — issuing concurrent calls is not safe.
Read these files when the topic comes up. They are in references/ relative to this skill directory.
| Topic | File |
|---|---|
| CLI variable reference (complete — all variables with descriptions, defaults, ranges) | references/betaflight-docs/general/development-cli-reference.md |
| PID theory fundamentals | references/betaflight-docs/general/development-pid-tuning.md |
| BF 4.3 tuning notes (slider system) | references/betaflight-docs/tuning-notes/betaflight-4.3-tuning-notes.md |
| BF 4.2 / 4.1 / 4.0 tuning notes | references/betaflight-docs/tuning-notes/betaflight-4.2-tuning-notes.md (and siblings) |
| RPM/DSHOT filtering — feature-specific CLI vars | references/betaflight-docs/guides/guides-dshot-rpm-filtering.md |
| Dynamic idle — feature-specific CLI vars | references/betaflight-docs/guides/guides-dynamic-idle.md |
| I-term relax — feature-specific CLI vars | references/betaflight-docs/guides/guides-i-term-relax-explained.md |
| Feed Forward 2.0 — feature-specific CLI vars | references/betaflight-docs/guides/guides-feed-forward-2.0.md |
| D-min / dynamic damping — feature-specific CLI vars | references/betaflight-docs/guides/guides-dmin.md |
| Freestyle tuning principles | references/betaflight-docs/guides/guides-freestyle-tuning-principles.md |
| PID tuning guide (community) | references/betaflight-docs/guides/guides-pid-tuning-guide.md |
| Chris Rosser — BF 4.5 filter tuning | references/youtube-transcript-summaries/chris-rosser-bf4.5-filter-tuning.md |
| Chris Rosser — BF 4.5 PID tuning | references/youtube-transcript-summaries/chris-rosser-bf4.5-pid-tuning.md |
| Chris Rosser — BF 4.4 guide | references/youtube-transcript-summaries/chris-rosser-bf4.4-tuning-guide.md |
| PIDtoolbox — basement tuning (slider sweeps) | references/youtube-transcript-summaries/pidtoolbox-bf4.3-basement-tuning-1.md |
| PIDtoolbox — basement tuning (angle mode) | references/youtube-transcript-summaries/pidtoolbox-bf4.3-basement-tuning-2.md |
| PIDtoolbox — BF 4.5 professional workflow | references/youtube-transcript-summaries/pidtoolbox-bf4.5-pid-tuning-1.md |
| PIDtoolbox — BF 4.5 rapid tune | references/youtube-transcript-summaries/pidtoolbox-bf4.5-pid-tuning-2.md |
| Release notes 4.4 / 4.5 / 2025.12 | references/betaflight-docs/release-notes/ (three files) |
| Configurator PID tab (sliders, filters, UI↔CLI reference) | references/betaflight-docs/configurator-app/app-pid-tuning-tab.mdx |
| Failsafe — configuration guide | references/betaflight-docs/guides/guides-failsafe.md |
| GPS Rescue — 4.5 (most current) | references/betaflight-docs/guides/guides-gps-rescue-v4.5.md |
| GPS Rescue — 4.4 | references/betaflight-docs/guides/guides-gps-rescue-v4.4.md |
| GPS Rescue — 4.1 to 4.3 | references/betaflight-docs/guides/guides-gps-rescue-mode-v4.1-to-v4.3.md |
When SKILL.md inline content is sufficient (common tuning workflow, the 8-phase sequence, dynamic idle table, I-term relax cutoff table, symptom guide, key variable names) — trust it and skip loading reference files. Load references when: (a) the user asks about a specific variable or behaviour not covered inline, (b) you need to verify an exact range or default, or (c) the user's question requires feature-specific depth beyond the inline summary. For variable lookups, development-cli-reference.md is the single complete source of truth — load it directly. Load raw CLI dumps only when you need exact numeric defaults for a specific firmware version. Load the feature guides alongside the CLI reference when deep feature context is needed.
The MCP server runs alongside this session and exposes these tools:
list_serial_ports — find available ports (run first if port is unknown)connect_flight_controller — connect by port (e.g. COM3, /dev/ttyUSB0) and optional baud rate (default 115200)disconnect_flight_controller — close the connectionget_status — FC status including loop time and sensor flagsget_attitude — roll/pitch/yaw angles (degrees)get_raw_imu — raw gyro and accelerometer readingsget_battery / get_battery_state — voltage, current, capacityget_rc_channels — current RC channel valuesget_motor_values — current motor output values (0–2000)get_gps_data / get_altitude — GPS and barometer if equippedcli_exec — execute any CLI command and return output (e.g. get master_multiplier, set rpm_filter_q=1000, feature -BLACKBOX)cli_diff — all non-default settings (start here to understand current state)cli_dump — full configuration dumpcli_status — FC status textcli_help — list available CLI commandscli_save — save and reboot FC (required to persist changes)cli_defaults — factory reset and rebootget_version — firmware version stringfeature_list — currently enabled featuresfeature_enable / feature_disable — toggle features by nameget_mixer, get_serial_config, get_aux_config, get_channel_mapmotor_get / motor_set — read/drive motors (armed state)get_pid_sliders — read current slider values as floats (1.0 = default/100%). Returns master, roll_pitch_ratio, i_gain, d_gain, pi_gain, dmax_gain, feedforward, pitch_pi, pids_mode, gyro_filter_multiplier and dterm_filter_multiplier.set_pid_sliders — set one or more sliders by float value; the FC immediately recalculates actual P/I/D gains (equivalent to moving a slider in Configurator). Provide only the fields to change; all others keep current values. Automatically enables simplified tuning if disabled. Call cli_save to persist. Example: set_pid_sliders({ master: 1.2, i_gain: 0.1, feedforward: 0 })Each CLI variable has dedicated get_<varname> and set_<varname> tools, e.g.:
get_rpm_filter_q / set_rpm_filter_qget_anti_gravity_gain / set_anti_gravity_gain, get_iterm_relax / set_iterm_relax, etc.Always prefer these over cli_exec "get|set <varname>" for reading/writing variables — including batch operations (call tools sequentially). After setting variables, always call cli_save to persist (this reboots the FC). Reserve cli_exec for commands that have no dedicated tool: rxrange, rxfail, adjrange, resource, dma, timer, led/color/mode_color, mmix/smix/servo (tables), serialpassthrough, dshotprog, bind_rx, bl, msc, rc_smoothing_info, dshot_telemetry_info, vtx_info, flash_info, batch start|end.
Important: Always call Betaflight MCP tools sequentially — never in parallel. The CLI interface serialises all commands through a FIFO mutex; issuing concurrent calls is not safe.
list_serial_ports → connect_flight_controllerget_version then cli_diff to see all non-default settingsget_<varname> (preferred) or cli_exec "get <varname>" (alternative)set_<varname> (preferred) or cli_exec "set varname=value" (alternative)cli_save (reboots the FC — warn the user)Before tuning, verify:
After any firmware upgrade: restore settings manually — never paste CLI diff or dump output from a previous firmware version. Variable names, valid ranges, and defaults change between releases; a pasted old diff silently corrupts your config. Always perform a Full Chip Erase when flashing — this is standard mandatory practice for every Betaflight release.
PID loop frequency and DSHOT protocol — depends on the gyro chip, not just the FC:
set pid_process_denom to target 3.2kHz, use DSHOT300status to identify the gyro, get motor_pwm_protocol for current DSHOT settingBidirectional DSHOT enabled — required for RPM filtering. Check get dshot_bidir. ESC firmware must support bidir (BLHeli_32, AM32, BlueJay). Also verify motor_poles matches the magnet count on the motor bell (not the stator poles where the windings are). Typical 5" motors have 14 magnets — this is the default. Wrong pole count causes RPM filters to track incorrect frequencies. Check: get motor_poles.
Blackbox configured: device (set blackbox_device = SPIFLASH or SDCARD). Sample rate formula: half the gyro update frequency, but minimum 1 kHz. E.g. at 3.2kHz gyro, target 1.6kHz; at 8kHz gyro, use 1/8 = 1kHz. set blackbox_sample_rate = 1/N where N = gyro_hz / target_hz.
Debug mode: BF 4.5+: set debug_mode = FFT_FREQ; older: set debug_mode = GYRO_SCALED
Radio preset applied: Apply via Configurator Presets tab for your RC link (ELRS 250Hz, ELRS 500Hz, Crossfire 50Hz, etc.). This auto-configures RC smoothing and feedforward filtering.
Motor directions and props verified before any armed flight
Propwash troubleshooting — check dynamic idle first: if propwash is the presenting symptom, verify dynamic idle before any tuning flights. Run get dyn_idle_min_rpm. If it returns 0, dynamic idle is disabled — set it now per the Dynamic Idle table. Motor near-stall on throttle chop produces propwash that no filter or PID adjustment can fully cure. Also set transient_throttle_limit = 0 when enabling dynamic idle.
Before diving into tuning, understand the control structure:
PID Error = Setpoint (stick position) − Gyromeasured (actual rotation rate)
The PID controller transforms this error into motor commands:
| Component | Analogy | Function | Effect if too low | Effect if too high |
|---|---|---|---|---|
| P term | Spring | Pushes back against error proportionally — larger error = stronger correction | Sluggish response, slow return to setpoint | Oscillations, ringing |
| D term | Shock absorber | Reacts to rate of change of gyro (rotational acceleration) — resists overshoot | Overshoot past setpoint, oscillations | Over-damped, slow, sluggish response |
| I term | Integrator | Accumulates small persistent errors over time — corrects systematic offsets and drift | Slow drift, "floaty" feel, imprecise cornering | Slow wobbles after fast moves (I summing with P) |
| Feed Forward | Predictor | Based on stick movement speed — predicts required response before the quad reacts | Gyro lags setpoint throughout moves (~16 ms) | Gyro overshoots at move end, bounce-back |
Key insight: P:D ratio matters more than absolute values. Proper PD balance produces a smooth, damped response to stick inputs — the trace rises to the setpoint (1.0) with minimal overshoot and no oscillation. The master multiplier then scales this balanced response up or down for overall responsiveness.
Tuning order rationale: D → P → I → FF. Each step stabilizes the next. Master multiplier establishes gain level first, PD balance finds optimal ratio, I-term adds long-term accuracy, and feedforward reduces tracking lag.
Phase 0: Hardware Verification → Phase 1: Filters → Phase 2: PID Baseline → Phase 3: Master Gain → Phase 4: PD Balance → Phase 5: I-term → Phase 6: Feed Forward → Phase 7: Dynamic Damping
Core principle: Filter and PID tuning run in parallel, not sequentially — each PID test yields new noise profile data worth assessing. Never skip filter tuning first — filter-induced phase delay directly limits achievable PID gains. More filtering = lower max safe gains.
Start with a 30-40 second steady hover log before any tuning. This diagnostic-first approach reveals 99% of major issues without risky aggressive flight.
In the spectral analyzer:
| Signature | Cause | Solution |
|---|---|---|
| Discrete frequency peaks (narrow bands) | Motor vibration (normal) | RPM filters handle this |
| Vertical stripes (fixed frequency) | Frame resonances | Dynamic notch filters |
| Elevated broadband noise (all frequencies) | Electrical interference, gyro defects, mechanical issues | Hardware problem — check motor screws, prop balance, ESC capacitors, soft-mounting, or replace FC |
Critical insight: Many all-in-one FC boards (especially cinewhoops) ship with inherent gyro or electrical defects. Shops know but continue selling; clients frequently receive 2-3 replacement boards. Beginners misattribute hardware noise to PID settings and seek filter/tuning solutions instead. No amount of tuning can fix a defective flight controller.
If broadband noise is present, advise hardware inspection before proceeding with tuning.
Setup: fly a 30–40 second steady hover (Phase 0 diagnostic log can be reused). Analyze the log in PID Toolbox (spectral analyzer, frequency vs. throttle view) or Blackbox Explorer (analyzer tab).
Philosophy: Filter tuning is iterative and runs in parallel with PID tuning — each subsequent wobble test provides new noise data as PIDs change. Aim for tentative filter optimization here, then reassess after each PID adjustment phase.
set gyro_lpf1_static_hz = 0 (or slider fully left)set gyro_lpf2_static_hz = 1000. If gyro rate = PID loop rate (e.g. 8K/8K), LPF2 can be safely disabled.Motor noise starts around 100 Hz and rises with throttle. Harmonics at 2× and 3× are common.
set rpm_filter_q = 1000rpm_filter_min_hz and rpm_filter_fade_range_hz: set these lower on larger quads (larger props spin slower → noise starts at lower frequencies). Defaults suit 5" well; reduce for 7"+ builds.set rpm_filter_fade_range_hz = 50set rpm_filter_weights = H1,H2,H3
100,0,80 (2nd harmonic typically absent)100,80,0 or 100,50,0Targets frame resonances — visible as vertical stripes (fixed-frequency peaks) in the blackbox spectrum. These are fixed-frequency resonances that appear as the same frequency across all throttle levels, distinguishing them from motor noise which sweeps diagonally.
set dyn_notch_count = 0. Eliminates unnecessary delay. Rigid frames (e.g., well-designed AOS builds) often need no dynamic notch.dyn_notch_count to match the number of visible peaks. With RPM filtering active, 1–2 notches are sufficient; without RPM filtering, use 4–5.dyn_notch_min_hz: ~25 Hz below the resonance, never below 150 Hz (ideally ≥200 Hz). For best results, set the minimum frequency to constrain where notches can track.dyn_notch_max_hz: default ~600 Hz is fine; can be narrowed for better resolution if resonance range is known to be narrowdyn_notch_q: increase until resonance just escapes the notch, then back off — don't exceed ~1000. Higher Q = narrower notch = less delay.Karate tune (default, easier): Nudge dterm_lpf_multiplier slider up by 0.05–0.1 steps. Stop when motors sound rough or get hot, then back off one step. Use lower multiplier values on larger quads — bigger props generate more D-term noise.
After setting the static cutoff, raise dterm_lpf1_dyn_expo (Dynamic Curve Expo) from its default. This starts as a linear curve; increasing it makes the cutoff more aggressive at low throttle. Push as high as possible without hearing or seeing mid-throttle oscillations in the logs.
AOS tune (advanced, less delay): Disable profile-dependent D-term filters. Set dterm_lpf1_type = BIQUAD, dterm_lpf1_dyn_min_hz = 80, dterm_lpf1_dyn_max_hz = 110. Tune min cutoff (idle throttle) and max cutoff (full throttle) independently. dterm_lpf1_dyn_expo controls how cutoff scales with throttle — push as high as possible without mid-throttle oscillations.
Yaw is torque-based (inherently slower), so filter delay is less critical here. Reducing yaw noise frees up headroom for pitch/roll tuning. For maximum yaw responsiveness: set yaw_lowpass_hz = 0.
Before PID flights, create clean test conditions.
Slider tool (zeros feedforward, sets safe I-term baseline, disables dynamic D boost for constant D during step response analysis):
set_pid_sliders({ feedforward: 0, i_gain: 0.1, dmax_gain: 0 })
Keep I-term very low but not fully zero — enough to prevent slow attitude drift in angle mode without producing I windup during step response analysis. Fully zeroing is also valid, but 0.1 is the safer baseline. dmax_gain: 0 sets the computed d_max_roll/pitch to 0, which disables the dynamic D boost so D stays constant at the base d_roll/d_pitch value throughout the test.
CLI (direct variables not covered by the slider system — run via cli_exec):
set pidsum_limit = 1000
set pidsum_limit_yaw = 1000
set d_max_advance = 0
Then cli_save to persist all changes.
set small_angle = 30Perform sharp roll and pitch stick movements:
Instead of reconnecting to a computer between each test flight:
This dramatically speeds up the tuning iteration cycle.
Establish the overall gain level before tuning the P:D ratio. This matters practically: at very low master the controller has too little authority for the step response to clearly express ratio effects. Starting here also surfaces gain-headroom problems early — if master won't climb past 0.8 before oscillating, that's a filter or hardware problem to solve before investing time in ratio sweeps.
The default master multiplier of 1.0 is not universal — it depends on power-to-weight ratio and rotational inertia:
| Build characteristics | Starting master multiplier |
|---|---|
| High-KV / powerful motors (fast motor response) | 0.6–0.8 |
| Typical 3-5" freestyle | 0.8–1.0 |
| Heavy lifters / low power-to-weight | 1.0–1.2 |
High-KV and powerful motors need lower master — faster motor response compensates for lower PID gains. Standard 5" builds may be overtuned at 1.0; heavy cinema rigs may be undertuned.
From your selected starting point, increase in steps of 0.2. Keep Dynamic Damping off and I-term at the Phase 2 baseline (0.1–0.2). Apply each test value with set_pid_sliders({ master: X }) then cli_save.
Primary metric: latency — use cross-correlation lag in PID Toolbox for accurate measurement (more reliable than visual step response timing inspection). Stop when:
Spectral analyzer diagnostics — check these alongside step response:
If master multiplier hits the 2.0 ceiling and you want to test higher:
get_pid_slidersset_pid_sliders({ pi_gain: <current_pi*2>, d_gain: <current_d*2> })set_pid_sliders({ master: 1.0 })This preserves the PD ratio while allowing the master multiplier scale to extend further.
Tuning master multiplier before PD ratio and I-term is not arbitrary — higher master multiplier collapses the P error between setpoint and gyro, reducing the error signal that I-term would otherwise integrate. This makes subsequent I-term testing cleaner and more accurate by minimizing I-term windup opportunity. Similarly, evaluating PD balance at the actual operating gain level (rather than at an arbitrary low gain) ensures the ratio is optimized for real flight conditions.
With master established, find the optimal P:D ratio. The P:D ratio is mathematically invariant to master scaling — the ratio sweep can be done at any gain level — but doing it after Phase 3 means you're evaluating it at the actual operating point the quad will fly. Keep all other sliders constant, vary only the damping slider.
Sweep: 0.6 → 0.8 → 1.0 → 1.2 → 1.4 → 1.6 — one 20–30 second flight per value with controlled wobble inputs. Apply each value with set_pid_sliders({ d_gain: X }) then cli_save.
| Trace shape | Meaning | Action |
|---|---|---|
| Clear overshoot past 1.0, oscillations | D too low (under-damped) | Increase damping slider |
| Rises to 1.0, minimal overshoot, flat | Optimal | Use this value |
| Slow rise, over-damped | D too high | Decrease damping slider |
Selection rule: Pick the value where overshoot just disappears but responsiveness remains high. Erring slightly toward more D (e.g., choosing 1.0 over 0.8 when both look acceptable) improves propwash resistance.
Pitch often lags roll by ~30% due to:
Use the pitch damping slider (set_pid_sliders({ roll_pitch_ratio: X })) to add D to pitch independently, and the pitch tracking slider (set_pid_sliders({ pitch_pi: X })) to increase both P and I on pitch independently.
Example scenario: If roll responds well at damping 1.0 but pitch shows sluggish tracking:
set_pid_sliders({ pitch_pi: 1.2 })set_pid_sliders({ roll_pitch_ratio: 1.1 })anti_gravity_gain (boosts I during throttle changes)Important limitation: Excessive pitch gains to compensate for very high rotational inertia are counterproductive. If pitch requires dramatically higher gains than roll (e.g., 50%+ higher), the issue may be mechanical (frame flex, motor position, weight distribution) rather than tunable via PIDs. Know when to stop.
Wide tuning window — defaults are often fine for 5" freestyle. Sweep PI tracking slider in steps of 0.3: 0.3 → 0.6 → 0.9 → 1.2 → 1.5. Apply each value with set_pid_sliders({ i_gain: X }) then cli_save.
Why I-term is tuned before feedforward: Once feedforward (Phase 6) minimizes setpoint-gyro tracking lag, I-term can often be increased significantly beyond what would be stable without feedforward. Lower lag prevents I-term windup that would occur with higher tracking error. Therefore, I-term in this phase establishes a conservative baseline; you may revisit and raise it after feedforward is optimized. The interdependence means experienced tuners sometimes evaluate them together.
Related settings:
iterm_relax_cutoff — prevents I windup during fast moves. Higher = reacts faster (better for racing); lower = smoother (better for large/slow builds). Use this table as a starting point:
| Build type | iterm_relax_cutoff |
|---|---|
| Race / locked-in | 30–40 |
| Freestyle 5" | 15 |
| Heavy freestyle / 7"+ | 10 |
| X-Class / large platform | 3–5 |
Bounce-back diagnostic sequence: if bounce-back or oscillation after flips/rolls persists, step iterm_relax_cutoff down — 15 → 10 → 7 → 5 — testing after each step, noting improvement before going further.
iterm_windup (default 85% in BF 4.4/4.5; 80% in BF 2025.12): suppresses I accumulation near motor saturation. Default is sensible.anti_gravity_gain (default 80): boosts I on rapid throttle changes. Reduce if throttle-punch wobbles appear.anti_gravity_p_gain: tune the P boost component of anti-gravity separately.anti_gravity_cutoff_hz: filter cutoff — adjust for very small or large quads.Apply radio link preset first (Configurator Presets tab → search your RC link name). This configures RC smoothing and FF filtering for your specific link.
Feed forward requires acro/rate mode — angle mode bypasses it in BF 4.5+ (angle mode has its own internal feedforward system for auto-level behavior).
Sweep stick response (FF) slider: 0.5 → 0.75 → 1.0 → 1.25 → 1.5. Apply each value with set_pid_sliders({ feedforward: X }) then cli_save.
Law of diminishing returns: latency reduction plateaus as FF increases. When motors saturate at 100% on sharp moves, further FF gain is pointless.
RC smoothing adds control delay (e.g., ~12-15 ms for 15 Hz cutoff, common for cinematic footage). Feedforward compensates by predicting movement and recovering that latency:
This is why properly tuned feedforward is critical for HD/cinematic setups — it maintains locked-in feel despite aggressive input filtering.
When using Crossfire 50 Hz, expect a ~50 Hz signal visible in gyro traces during blackbox analysis.
This is NOT a PID oscillation — it's an RC link artifact from the square-wave nature of 50 Hz packet updates. Imperfect RC smoothing leaves remnants visible in logs, appearing as a low-frequency ripple.
Practical impact: Feedforward above 1.0 with Crossfire 50 Hz may disrupt the optimal P:D ratio you established in Phase 4. The 50 Hz artifact can interact with high feedforward gains and create additional control dynamics not present during PD balance testing.
Recommendation: Consider keeping FF ≤1.0 when using Crossfire 50 Hz as a precaution; if you exceed 1.0, verify P:D balance behavior in blackbox logs.
feedforward_boost (default 15): adds acceleration-based component. Increase if gyro lags at move start; decrease if gyro leads at start.feedforward_max_rate_limit (default 90): cuts FF as sticks near max deflection. Raise to 92–95 for crisp move entry on responsive builds.feedforward_jitter_factor (BF 4.3+): higher = smoother during slow-stick inputs; lower = snappier for racing.feedforward_transition (default 0): blends FF toward zero near stick center, giving a more locked-in center feel. Racing: 0 (full FF throughout); Freestyle/HD: 40; Cinematic: 70. Set to 0 whenever feedforward_jitter_factor is active — jitter reduction replaces transition for slow-stick smoothing and the two should not be combined.For heavy-lift cinema rigs, typical feedforward range is 0.5–1.0, which reduces end-to-end control latency by approximately 6–12 ms. This is substantial for smooth camera work and precise positioning.
Dynamically boosts D on sharp moves while keeping it low during calm flight. Two use cases:
The default D-max is usually fine. Can be raised if FF is high and overshoot appears on sharp moves, or if propwash is still problematic after optimizing filters and PIDs. Use the D-max slider to adjust.
Slider tool (restore dynamic D boost back to default since it was disabled in Phase 2):
set_pid_sliders({ dmax_gain: 1 })
Optionally tune with set debug_mode = D_MAX in blackbox and verify the D_max trace:
d_roll (D_min floor)d_max_roll (D_max)Adjust d_max_gain to control how aggressively D boosts from floor to peak on sharp moves. d_max_advance must always stay at 0.
Important: d_max_gain must remain above ~20 (the default is fine). If both d_max_gain and d_max_advance are zero, D is locked at the D_min floor and will never boost toward D_max — the Dynamic Damping feature is effectively disabled.
Use only if high-throttle oscillations persist after filters and PIDs are properly tuned. TPA is a band-aid for high-throttle instability — ideal tuning shouldn't need it.
If oscillations appear only at high throttle (e.g., above 70% throttle) but the quad is stable at mid-range, TPA can help. This typically indicates:
tpa_rate (default 65): attenuation percentage at full throttle. Default 65 = PIDs reduced to 35% at max throttle. Increase if oscillations persist.tpa_breakpoint (default 1350, range 1000–2000): throttle level where attenuation begins. 1350 ≈ 35% throttle.
tpa_mode:
D (default): attenuates D-term onlyPD: attenuates both P and D if both oscillate at high throttleApplies D attenuation at the low throttle end — helps with D-term shaking during throttle chops and low-throttle hover:
tpa_low_breakpoint (default 1050): throttle level below which attenuation beginstpa_low_rate (default 20): D reduction percentage at minimum throttle (20 = reduce D to 80% at min throttle)tpa_low_always (default OFF):
Best practice: Start with standard TPA (high-throttle attenuation) if needed. Only add TPA Low if low-throttle D-term noise is specifically problematic.
These are not PID gains but directly affect flight quality and motor health:
vbat_sag_compensation (default 0): compensates for voltage sag as battery depletes, keeping throttle and PID authority consistent across a pack. 90% is a good target — full 100% compensation at low voltage demands even more from the battery at exactly the point where the pack is already under the most stress, which draws more current and accelerates depletion. 90% delivers most of the consistency benefit while leaving a slight natural taper at the bottom, easing battery load during the critical final moments of a flight. Since compensation removes the throttle softening that would otherwise signal a depleting pack, configure a low-voltage OSD warning, a battery alarm on your transmitter, or cell voltage telemetry alerts on your RC link.motor_output_limit (default 100): reduces per-motor drive signal. Useful when running a higher cell count than the motors were designed for (e.g. 6S on a 4S build → try 66%).thrust_linear (default 0): improves low-throttle authority and responsiveness, especially useful for whoops and builds running 48 kHz ESCs. Has no effect at higher throttle. 20–40% is typically enough; avoid going higher without reason.throttle_boost: transiently boosts throttle on fast throttle inputs for a more immediate throttle feel.Prevents motor stall during flips/rolls and propwash. Critical on smaller quads and steep-pitch props. Steeper pitch angle = blade stalls more easily at low RPM = needs higher idle.
The table below gives a low-pitch to steep-pitch range. The range accounts for prop pitch variation:
| Prop size | dyn_idle_min_rpm range |
|---|---|
| 1.5" | 66–133 |
| 2" | 50–100 |
| 2.5" | 40–80 |
| 3" | 33–66 |
| 3.5" | 28–57 |
| 4" | 25–50 |
| 5" | 25–40 |
| 6" | 16–33 |
| 7" | 14–28 |
| 8" | 12–25 |
| 10" | 10–20 |
| 12" | 9–17 |
| 13" | 7–15 |
Enable dynamic idle: set dyn_idle_min_rpm = 30 (adjust per table; any nonzero value enables it). Required companion: set transient_throttle_limit = 0. Also make sure that the motor_kv variable is set correctly, as it affects related internal calculations.
Always use Flight Controller based failsafe — configure the receiver to send no data (not fixed values) on signal loss. Receiver-based failsafe is not recommended because the FC cannot detect the link loss.
Signal Validation (100 ms): FC detects absence of data. Last values held for 300 ms, then Stage 1 activates. RXLOSS appears in OSD.
Stage 1 — Guard period: Applies Channel Fallback Settings (sticks centered, throttle to configured value) for up to failsafe_delay (default 1.5 s in 4.5). Signal recovery during Stage 1 immediately restores full pilot control.
Critical for GPS Rescue: the default Stage 1 throttle fallback is zero — the quad will drop and crash before Rescue can activate. Set the Stage 1 throttle channel fallback to a hover value.
Stage 2: entered when Stage 1 guard time expires. Three usable procedures:
| Procedure | failsafe_procedure | Behaviour |
|---|---|---|
| Drop (default) | DROP | Immediate disarm and motor stop |
| Landing Mode | AUTO-LAND | Fixed throttle + centered sticks for failsafe_off_delay, then disarm. Not generally recommended. |
| GPS Rescue | GPS_RESCUE | Autonomous return-to-home. See GPS Rescue section. |
"Just Drop" override: if throttle has been low for ≥ 10 s before failsafe triggers, the FC immediately disarms regardless of the Stage 2 procedure (prevents Landing Mode spinning up props after a landed-but-disarmed pilot turns off their radio).
After Stage 2, signal must be stable for failsafe_recovery_delay (default 0.5 s in 4.5, 1.0 s in 4.4) before re-arm is allowed. For GPS Rescue, recovery also requires moving the sticks more than failsafe_stick_threshold degrees from center (default 30°). After disarm, the arm switch must be toggled off before re-arming — the OSD will show NOT_DISARMED as a reminder.
Configure a mode switch in Configurator's Modes tab. failsafe_switch_mode controls behavior:
STAGE1: simulates signal loss, useful for testing. Aux channels remain active.STAGE2: skips guard time, directly activates Stage 2 procedure. Good as a panic switch.KILL: instant disarm, no delay. A single glitch crashes the quad — avoid unless intentional.| Variable | Default | Notes |
|---|---|---|
failsafe_delay | 15 (1.5 s) | Stage 1 guard time in 0.1 s steps. Minimum 2 (200 ms). |
failsafe_procedure | DROP | DROP, AUTO-LAND, or GPS_RESCUE |
failsafe_throttle | 1000 | Landing Mode throttle (1000 = off). Set to hover value for GPS Rescue Stage 1 fallback. |
failsafe_off_delay | 10 (1 s) | Landing Mode duration in 0.1 s steps before final disarm |
failsafe_recovery_delay | 5 (0.5 s) | Signal-stable duration required before allowing re-arm |
failsafe_stick_threshold | 30 | Degrees of stick deflection needed to recover from GPS Rescue |
failsafe_switch_mode | STAGE1 | STAGE1, STAGE2, or KILL |
Load references/betaflight-docs/guides/guides-failsafe.md for full detail on bench testing procedure and stage-by-stage configuration.
GPS Rescue autonomously flies the quad toward home when activated (either by failsafe Stage 2, or a pilot switch). It is a link-recovery tool, not a full RTH system — the goal is to fly back into range so the pilot can retake control.
gps_rescue_min_sats (default 8). OSD shows RESCUE N/A if below minimum.gps_rescue_ascend_rategps_rescue_ground_speedgps_rescue_descent_dist from home, begin descending at gps_rescue_descend_rateThe default Stage 1 throttle fallback is zero. If Stage 1 drops the quad before Rescue activates, the rescue will never run. Set the Stage 1 channel fallback for throttle to a hover value. Method: temporarily set Stage 2 to Landing Mode, adjust failsafe_throttle until the quad descends gently, use that value for both failsafe_throttle and the Stage 1 throttle channel fallback, then restore Stage 2 to GPS Rescue.
failsafe_recovery_delay, wiggle sticks more than failsafe_stick_threshold (30°) to return control. Do not touch sticks until video and RXLOSS have cleared.| Variable | Notes |
|---|---|
gps_rescue_initial_climb | Altitude to climb before heading home (meters). Higher = safer over obstacles. |
gps_rescue_return_alt | Return cruise altitude (meters, 4.4+). If current alt is higher, quad maintains current alt. |
gps_rescue_alt_mode | MAX_ALT (default), FIXED_ALT, or CURRENT_ALT |
gps_rescue_ascend_rate | Climb rate cm/s (default 500) |
gps_rescue_descend_rate | Descent rate cm/s (default 150) |
gps_rescue_ground_speed | Return speed cm/s (default 2000 ≈ 72 km/h; try 1500 for reliability) |
gps_rescue_max_angle | Max tilt angle during return (default 32°; raise for headwinds) |
gps_rescue_descent_dist | Distance from home to start descent (meters, default 200) |
gps_rescue_min_start_dist | Minimum distance from home to activate (default 100 m; closer → disarm) |
gps_rescue_min_sats | Minimum satellite count to allow arming (default 8) |
gps_rescue_sanity_checks | RESCUE_SANITY_ON (recommended), RESCUE_SANITY_FS_ONLY, or OFF |
gps_rescue_allow_arming_without_fix | Allow arming without GPS fix (rescue unavailable during flight) |
gps_rescue_use_mag | Use magnetometer for heading (only enable if verified accurate) |
gps_rescue_velocity_p/i/d | Velocity PID controller — rarely needs adjustment |
gps_rescue_yaw_p | Yaw P gain during rescue |
gps_rescue_imu_yaw_gain | IMU yaw correction aggressiveness (4.5+) |
gps_rescue_roll_mix | Roll/yaw mix ratio during approach (4.5+) |
gps_rescue_pitch_cutoff | Pitch D smoothing (4.5+) |
gps_rescue_disarm_threshold | Auto-disarm sensitivity on landing impact (4.5+) |
Enable gps_rescue_sanity_checks = RESCUE_SANITY_ON whenever GPS Rescue is set as the failsafe procedure. Sanity checks abort the rescue (disarm and drop) if: GPS is lost, fix is invalid, quad has crashed, satellite count drops below minimum, or the quad is not approaching home. This prevents a sustained flyaway. Do not disable unless testing over water or in a controlled environment.
RXLOSS OSD)gps_rescue_descent_dist in a straight line. Verify the home arrow points toward launch before activating rescue.Load version-specific reference files for full parameter tables and version-specific behavior:
references/betaflight-docs/guides/guides-gps-rescue-v4.5.md (4.5 — most current)references/betaflight-docs/guides/guides-gps-rescue-v4.4.md (4.4)references/betaflight-docs/guides/guides-gps-rescue-mode-v4.1-to-v4.3.md (4.1–4.3)For full documentation, read references/betaflight-docs/general/development-cli-reference.md. Most-used during tuning:
Filters: gyro_lpf1_static_hz, gyro_lpf2_static_hz, rpm_filter_q, rpm_filter_weights, rpm_filter_min_hz, rpm_filter_fade_range_hz, dyn_notch_count, dyn_notch_min_hz, dyn_notch_max_hz, dyn_notch_q, dterm_lpf1_type, dterm_lpf1_dyn_min_hz, dterm_lpf1_dyn_max_hz, dterm_lpf1_dyn_expo, yaw_lowpass_hz
PID gains: p_roll, p_pitch, p_yaw, i_roll, i_pitch, i_yaw, d_roll, d_pitch, d_max_roll, d_max_pitch, feedforward_roll, feedforward_pitch, feedforward_yaw, master_multiplier
I-term: iterm_relax, iterm_relax_type, iterm_relax_cutoff, iterm_windup, anti_gravity_gain, anti_gravity_p_gain, anti_gravity_cutoff_hz
Feed forward: feedforward_boost, feedforward_max_rate_limit, feedforward_jitter_factor, feedforward_averaging, feedforward_smooth_factor, feedforward_transition
TPA / misc: tpa_rate, tpa_breakpoint, tpa_mode, tpa_low_breakpoint, tpa_low_rate, tpa_low_always, pidsum_limit, pidsum_limit_yaw, throttle_boost, motor_output_limit, vbat_sag_compensation, thrust_linear
Dynamic idle: dyn_idle_min_rpm (set >0 to enable), transient_throttle_limit (set to 0 when using dynamic idle), dshot_idle_value (static floor percentage), dyn_idle_p_gain, dyn_idle_i_gain, motor_poles (magnet count on motor bell; default 14 for 5")
Failsafe: failsafe_procedure, failsafe_delay, failsafe_throttle, failsafe_off_delay, failsafe_recovery_delay, failsafe_switch_mode, failsafe_stick_threshold
GPS Rescue: gps_rescue_initial_climb, gps_rescue_return_alt, gps_rescue_alt_mode, gps_rescue_ascend_rate, gps_rescue_descend_rate, gps_rescue_ground_speed, gps_rescue_max_angle, gps_rescue_descent_dist, gps_rescue_min_start_dist, gps_rescue_min_sats, gps_rescue_sanity_checks, gps_rescue_allow_arming_without_fix, gps_rescue_use_mag, gps_rescue_velocity_p, gps_rescue_velocity_i, gps_rescue_velocity_d, gps_rescue_yaw_p, gps_rescue_imu_yaw_gain, gps_rescue_roll_mix, gps_rescue_disarm_threshold
| Symptom | Likely cause | Fix |
|---|---|---|
| Oscillations only on fast moves, not hover | P too high | Reduce master multiplier or P&I slider |
| Oscillations during hover | D too high or noise | Reduce D or increase D-term LPF |
| Oscillations at high throttle only | PID too high under load | Tune TPA |
| Slow, sluggish feel | Gains too low | Raise master multiplier |
| Gyro lags setpoint throughout move | FF too low | Increase feedforward slider |
| Overshoot / bounce-back at end of move | FF too high | Reduce feedforward slider |
| Propwash after throttle chop | D or dynamic idle too low | Raise D-min or dynamic idle |
| Quad drifts / can't hold heading | I too low | Raise I-term slider |
| Slow wobbles after fast flip/roll | I too high | Reduce I-term slider |
| Wobbles specifically on throttle punch | Anti-gravity too high | Reduce anti_gravity_gain |
| Motor heat without oscillations | D-term noise | Raise D-term LPF cutoff or reduce D |
| Mushy / delayed response | Too much filtering | Reduce filter aggressiveness |
| Bounceback at move entry (step start) | FF boost too high | Reduce feedforward_boost |
| Gyro lags at very start of move | FF boost too low | Increase feedforward_boost |
| Broadband noise across all frequencies | Electrical/mechanical issue | Check ESC caps, motor screws, soft mount |
connect_flight_controller → get_version → cli_diffget_<varname> (preferred) or cli_exec "get <varname>" (alternative)cli_save reboots the FC; confirm with the user firstWhen a user describes a problem, map the symptom to a likely cause before suggesting changes. Check current values first — the problem may already be partially addressed.
npx claudepluginhub bvandevliet/betaflight-mcp --plugin betaflight-mcpAnalyzes spacecraft GNC/ADCS systems: sensor/actuator selection, pointing budgets, disturbance torque analysis, control modes, momentum management. For ADCS design and performance evaluation.
Generates optimized YAML for Frigate NVR covering object detection, recording, zones, hardware acceleration (Coral TPU, OpenVINO), and Home Assistant integration. Use for camera setup and troubleshooting detection issues.
Provides firmware and driver development expertise for ARM Cortex-M microcontrollers (Teensy, STM32, nRF52, SAMD). Includes peripheral drivers, concurrency patterns, and platform-specific integration.