Betaflight PID Tuning From Blackbox: Fix the Cause, Not the Symptom
Your quad overshoots after a flip. The forum answer is "drop P" or "add D". The catch: the same overshoot has three possible causes, and two of them need opposite fixes. If feedforward is behind it, lowering P makes it worse. If the loop lacks damping, lowering FF changes nothing. The log tells you which case you have. Below is how bbdoctor reads it, checked on six real logs from Betaflight 3.1.5 to 2026.6.
Order of work: mechanics → noise → PID
- Mechanics. Good props, motors without play, a tight frame, a battery that doesn't shift. No PID fixes a bent prop.
- Noise and filters. RPM filter (bidirectional DShot), sensible filtering, cool motors after a flight. See the noise and filters guide.
- PID. Roll and pitch first (P/D and feedforward), then I, TPA and anti-gravity.
Why: D is the derivative of the gyro, so it amplifies high-frequency noise and sends it straight to the motors. bbdoctor won't suggest more D when high-frequency motor noise exceeds 2.5% of motor range, when the PID noise comes mainly from the D-term, or when raw gyro noise above 80 Hz reaches 10 deg/s. In the 4.2.5 case below the loop needed more D, but raw gyro noise of 35.8 deg/s turned the advice into P −10% (p_roll 42 → 38) and mechanics first.
The log you need
- ACRO. 30–60 seconds of sharp rolls and flips on each axis, snapping the stick back to centre. In ANGLE and HORIZON on Betaflight and INAV the setpoint comes from the angle loop, not your stick; if more than half the flight is self-levelled, the response isn't computed. ArduPilot and PX4 log the rate controller's target (
RATE.RDes,vehicle_rates_setpoint), so the response is valid in any mode. - Logging rate. The step response works from 200 Hz; 1 kHz is the practical minimum. Below 500 Hz bbdoctor can't measure how far D really rises and caps the ringing verdict at "info".
- How many moves. The flight is cut into 1-second windows every 1/8 s, keeping those where the stick asked for at least 20 deg/s. Any verdict on an axis needs 10 usable windows (and at least a quarter of all of them); a "critical" verdict and the cause analysis need 50. Windows overlap, so 65 windows is roughly 8 seconds of active flying.
- Log the setpoint field; setup details in blackbox setup.
Reading the step response
A step response shows how the quad would rotate if you moved the stick to a given rate instantly. 1.0 is the requested rate. A good curve rises fast, goes slightly past 1.0 and settles right away.
Overshoot
How far the peak goes above 1.0; up to 15% is normal. The verdict uses the 90% interval, not a single number:
- warn when the lower bound is above 15%, crit above 35% (with at least 50 windows);
- fine when the estimate is up to 15% and the upper bound up to 25%;
- borderline when the estimate is a little over 15% with a narrow interval: change nothing yet, compare with the next log;
- uncertain when the interval is wider than 15 points: add 5–6 more moves on that axis next time.
Damping ζ
bbdoctor fits a second-order model to the curve and takes its damping ratio ζ, which tells you how much overshoot the P/D loop produces on its own:
| ζ | Overshoot from the loop | What it looks like |
|---|---|---|
| 0.36 | ~30% | Deep dip after the peak, several swings |
| 0.5 | ~16% | Clear dip, one or two swings |
| 0.6 | ~9% | Small bump, barely any dip |
| 0.7–0.9 | 5% or less | A bump, then a flat line — what you want |
bbdoctor calls it ringing only when two signs agree: ζ at most 0.5 and a dip below the target of at least 4% (at least 2% with 90% confidence). It's a warn at ζ up to 0.40 or a dip of 15% or more. If the model fits poorly, ζ isn't shown and the dip alone decides, at info level at most. Ringing below 6 Hz on a 5-inch points to the I-term or a heavy craft rather than D.
Speed
- t50 is the time to half the requested rate: 7–12 ms on the responsive logs in this guide.
- Setpoint-to-rotation delay runs from a setpoint change to the peak of the reaction, through the whole loop: PID, FF, filters, motors, props. Normal is 4–12 ms with feedforward, up to 15 ms without. From 20 ms the axis counts as slow, and bbdoctor won't tell you to lower P on it. The radio path comes on top (12 ms in the GEPRC case below).
How the curve is built
Nobody moves the stick in perfect steps, so the response is recovered backwards (deconvolution): for every 1-second window, what reaction to an instant step turns this stick input into this gyro trace? Two traps:
- High frequencies. Above roughly 25 Hz stick movements carry no energy, so deconvolution there computes only noise. PID-Analyzer chops it off with a steep cutoff around 25 Hz, but a steep cutoff draws its own ripple (the Gibbs effect): about 10% of overshoot on a response that has none. bbdoctor suppresses everything above 80 Hz and smooths with a 30 Hz Gaussian, which has no negative lobes and doesn't invent a bump.
- The method's own bias. Windowing and smoothing still leave a small bump, so the same calculation runs on a perfect response, the setpoint delayed by the same t50, and its overshoot (1–5% on our logs) is subtracted. On synthetic data a pure delay comes out at 0% and a ζ 0.5 system at 15% against a true 16%.
The curve is the median across windows; the interval comes from a bootstrap (200 random reshuffles of the windows), hence "47% (90%: 44–53%)" in the report. So 10% of "overshoot" in a tool with a steep cutoff can be pure artefact.
One overshoot, three causes
| Cause | What the log shows | What to do | What not to do |
|---|---|---|---|
| Feedforward (on 3.x, the D setpoint weight) | FF does 45% or more of the work on sharp stick moves, P adds almost nothing, and the gyro keeps up with or gets ahead of the setpoint | Lower f_roll/f_pitch by 15% (on 3.x, dterm_setpoint_weight). Safe first step: it doesn't heat the motors | Don't touch P and D |
| Underdamped loop | FF does less than 45%, the quad doesn't get ahead of the stick, ζ below 0.5, a dip after the peak and ringing | Raise the base D by 15% (with its ceiling) if the motors are cool; if they're noisy, lower P by 10% | Don't lower FF — it won't help. Don't lower P if the axis is already slow (20 ms or more) |
| Lead | The loop is well damped (ζ ≥ 0.6, no dip), yet the overshoot is more than twice what such a loop gives; FF does 35% or more of the work | Lower FF. If nothing changes, put it back: then it's the I-term pushing | Don't lower P: with less P the loop pulls back more weakly and the overshoot grows |
Three more patterns, checked separately:
- overshoot grows at high throttle: that's TPA, see TPA and anti-gravity;
- gentle moves overshoot more than sharp ones: base D too low, the boost only works on sharp moves, see D Max vs D Min;
- sharp moves overshoot more than gentle ones: feedforward boost, see feedforward and RC smoothing.

Five real cases
The reference: 2% at ζ 0.73
The plasmatree_good_tune log (Betaflight 3.1.5) is the reference good tune among the logs bbdoctor's thresholds were calibrated on. Roll 2% (90%: 1–3%), pitch 5%, no overshoot on yaw. Roll ζ 0.73, no dip, t50 9 ms, setpoint-to-rotation delay 10 ms. Don't copy its P 19, I 12, D 18 to 4.x: filtering, D and feedforward work differently there.
Stock 3.1.5 tune: 87% from the setpoint weight
The 18_stock_tune log, 7.9 kHz. Roll 87% (79–93%), pitch 65%. 3.x doesn't log the setpoint, so it's rebuilt from the sticks and rates. On the sharpest moves the gyro gets ahead of the setpoint, which a loop without a push from the stick can't do; the push comes from dterm_setpoint_weight = 190, 3.x's stand-in for feedforward. The advice is 190 → 100, one setting for all axes. Roll also rings (ζ 0.36), but D is only the next step here: d_roll 20 → 23 if the ringing stays.
A 3.5-inch on 4.5.2: 47%, almost all of it FF
The vx35_18-23 log. Roll 47% (44–53%), t50 7 ms. Feedforward does 60% of the work, with near-zero tracking error on the sharpest moves. At ζ 0.62 the loop alone would overshoot about 9%; FF adds the rest. Pitch: 27%, FF doing 59%. The advice touches FF only:
set f_roll = 102
set f_pitch = 106
set simplified_pids_mode = OFF
save
The slider line is needed because this log's PIDs no longer match the sliders and would be overwritten on save. Also, the D boost only rises to ×1.15 of the configured ×1.67, so the quad mostly flies on d_min_roll = 30, not on 50.
Betaflight 2026.6: 35% from the loop itself
A GEPRC F405 log recorded at 247 Hz. Roll 35% (33–38%). FF does only 29% of the work and the quad doesn't get ahead of the stick, so it isn't feedforward. After the peak the response dips 5% below the target and rings at ~9 Hz, ζ 0.49 (likely 0.42–0.50). Pitch looks the same (ζ 0.50), so both axes get one fix: base D +15%.
set d_roll = 39
set d_max_roll = 46
set d_pitch = 53
set d_max_pitch = 63
set simplified_pids_mode = OFF
save
Lowering P is off the table: roll already takes 24 ms and pitch 28 ms, plus ~12 ms from the 50 packet/s radio link before the stick even reaches the setpoint. At 247 Hz the log can't show D noise, so touch the motors after a first 1–2 minute flight.

Betaflight 4.2.5: gentle moves 32%, sharp ones 1%
The v0002 log, 2 kHz. Roll 23%, from the loop. Split by stick size, gentle moves (up to 101 deg/s) overshoot 32%, sharp ones (from 800 deg/s) 1%. D hits its ceiling of ×1.52 on sharp moves (d_min_roll 23 → d_roll 35), while gentle moves fly on the base 23. The textbook fix is more base D, but this gyro is noisy (see the first section), so the advice is P −10%.
P, I and D one by one
- P is stiffness. Too little D for your P means overshoot and ringing; too little P means a mushy response, a long delay and a quad that holds its line worse in propwash. Lower P against overshoot only when the loop is the cause and the axis isn't slow.
- I holds the quad against steady forces: an off-centre CG, wind, long manoeuvres. Too much I relative to P gives a slow 1.5–10 Hz wobble in calm flight. bbdoctor looks for a narrow peak in the tracking error with the stick within ±40 deg/s and checks whether the I-term drives it (coherence with the error ≥ 0.5, I/P at that frequency ≥ 1); then the advice is I −15%. Otherwise it's play (battery strap, GPS mast) or wind, and the gains stay put. If I sits at its limit for long stretches (checked on 2025.12+), something keeps pulling the quad: the CG, a tilted motor or a prop. Bounce-back after flips is often I too, see bounce-back after flips.
- D is damping and the main reason motors get hot. bbdoctor measures the D that actually works in flight, not just the configured one. Base D and the boost: D Max vs D Min.
When roll and pitch respond differently
On the same VX3.5 log the roll delay is 3.8 ms (90%: 2.9–5.0) and pitch is 9.5 ms (8.5–10.6). The intervals don't overlap, so the difference is real, and the gains explain it: pitch P 42, roll P 59. When the slower axis has P below 85% of the faster one, bbdoctor says that alone explains the gap. Finish the overshoot steps first, then bring roll P down towards ~50 rather than raise pitch, which already overshoots. With no P gap, a common cause is weight distribution: a battery far from the centre adds pitch inertia.
D names by version and the slider trap
| Version | Base D | Boost ceiling |
|---|---|---|
| 4.0–4.2 | d_min_roll | d_roll |
| 4.3–4.5 | d_min_roll ("Derivative") | d_roll ("D Max") |
| 4.6 / 2025.12+ | d_roll ("Derivative") | d_max_roll ("D Max") |
The same advice, "raise d_roll", raises the base D on 2025.12 but only the ceiling on 4.5, which the quad may rarely reach. Example for 4.5 (base 30, ceiling 50), +10% roll damping:
set d_min_roll = 33
set d_roll = 55
set simplified_pids_mode = OFF
save
Sliders. Until simplified_pids_mode is OFF, the Configurator recalculates the PIDs from the sliders on save and wipes manual changes. Never run simplified_tuning apply over a hand tune: it rebuilds the PIDs from the slider multipliers on the stock defaults.
INAV, ArduPilot, PX4
- INAV:
mc_p_roll,mc_i_roll,mc_d_roll,mc_cd_roll(CD is feedforward), and the same for pitch and yaw. TPA istpa_rateandtpa_breakpoint. More in INAV blackbox analysis. - ArduPilot:
ATC_RAT_RLL_P/_I/_D/_FF, and the same for PIT and YAW. On ArduCopter start with the built-in AUTOTUNE and use the log to check the result. You need fast logging (the ATTITUDE_FAST bit inLOG_BITMASK). More in ArduPilot log analysis. - PX4:
MC_ROLLRATE_P/_I/_D/_FF.MC_ROLLRATE_Kmultiplies P, I and D together, so factor it in. Autotune:MC_AT_EN = 1, then start it from QGroundControl (PID Tuning). Log with the High rate bit inSDLOG_PROFILE. See PX4 ULog analysis.
Safety
- Props off whenever you're in the CLI with the battery plugged in.
- One change per flight, 10–15% per step, or you won't know what worked.
- Keep the first flight after a change short and low, with a finger on disarm.
- After a minute in the air, touch the motors. Clearly warmer means put it back.
- Don't chase zero: 5–12% overshoot with a flat line after the peak is a good tune, not a problem.
- Shaking on throttle chops is a separate story: see propwash.
Check your own log
Upload your log to bbdoctor, free. The report shows per-axis overshoot with its interval, ζ, the dip, FF's share of the work, the delay and the axis gap, plus CLI commands built from your current values with the right names for your version. See one in the example report, and check your settings without a flight from a diff all on the config check page.
FAQ
How do I tell feedforward overshoot from P overshoot?
Look at who does the work during sharp stick moves. If feedforward carries 45% or more and on the sharpest moves the gyro keeps up with or gets ahead of the setpoint, the overshoot is from FF: lower f_roll and f_pitch by 15% and leave P and D alone. If FF does less than 45% and the response dips below the target after the peak and rings (ζ below 0.5), it's the P/D loop.
Which D do I change on Betaflight 4.5 and on 2025.12?
The base D you fly on most of the time. On 4.3–4.5 that's d_min_roll (the Derivative column) and d_roll is only the boost ceiling (D Max). From 4.6/2025.12 the names match the columns: base d_roll, ceiling d_max_roll. Change both by the same ratio, like the slider does.
How much should I change PIDs at once?
One parameter per flight, 10–15% per step. After the first minute in the air, touch the motors: if they're clearly warmer than before the change, put it back. A 10–15% step is big enough to show in the log above the measurement spread of a few percent, and small enough not to jump past the sweet spot.
What does ζ (damping) mean in the report?
It's how quickly the oscillation after the peak dies out. At ζ 0.5 the loop alone overshoots about 16% and visibly rings; at 0.7 it's about 5% with almost no ringing. A good tune sits at 0.6–0.9. Below 0.5 with a dip after the peak means there's too little damping (D) for the current P.
Updated: