bbdoctor
Drone diagnostics from logs: Betaflight, INAV, ArduPilot, PX4
RUENESPTUA

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

  1. Mechanics. Good props, motors without play, a tight frame, a battery that doesn't shift. No PID fixes a bent prop.
  2. Noise and filters. RPM filter (bidirectional DShot), sensible filtering, cool motors after a flight. See the noise and filters guide.
  3. 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

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:

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 loopWhat 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.95% or lessA 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

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:

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

CauseWhat the log showsWhat to doWhat 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 setpointLower f_roll/f_pitch by 15% (on 3.x, dterm_setpoint_weight). Safe first step: it doesn't heat the motorsDon't touch P and D
Underdamped loopFF does less than 45%, the quad doesn't get ahead of the stick, ζ below 0.5, a dip after the peak and ringingRaise 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)
LeadThe 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 workLower FF. If nothing changes, put it back: then it's the I-term pushingDon't lower P: with less P the loop pulls back more weakly and the overshoot grows

Three more patterns, checked separately:

Three roll step responses: a good tune with 2% overshoot, the stock Betaflight 3.1.5 tune with 87% and a 4.5.2 quad with 47% from feedforward
Roll response of three quads, normalised to the settled level. A: the reference tune (Betaflight 3.1.5), peak 1.05, 2% after subtracting the method's bias. B: the stock 3.1.5 tune (7.9 kHz log), peak near 1.9, a dip to 0.8 and ringing: 87%, from the D setpoint weight. C: a 3.5-inch on 4.5.2, peak 1.49 (47%) and a shallow dip: feedforward does 60% of the work.

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.

Two roll step responses: an underdamped loop that dips and rings, and a healthy response; dashed, the perfect response run through the same method
A: Betaflight 2026.6, 247 Hz log: peak 1.39 at ~50 ms, a dip to 0.95 and ringing at ~9 Hz, ζ 0.49. B: Betaflight 4.5.1, 1 kHz: peak 1.16, 12% on both roll and pitch, t50 10–12 ms; nothing to touch. Dashed: what the method draws for a perfect response with the same delay; its 4% bump is subtracted from the overshoot. Shading: the spread between single windows, hence the median and interval.

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

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

VersionBase DBoost ceiling
4.0–4.2d_min_rolld_roll
4.3–4.5d_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

Safety

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:

More guides