ADRC quickstart guide

Setting up and tuning active disturbance rejection control as an alternative to PID control.

Experimental

This is an experimental feature. It replaces the PID loop with a fundamentally different control algorithm.

TL;DR: I just want to get flying

1. What is ADRC, and why use it?

ADRC is an experimental, optional, complete replacement for PID. Instead of relying on static parameters or complicated aerodynamic models, it continuously estimates everything that is pushing on your quad and cancels it out in real time. External forces include things like wind, drag, and prop wash, while internal dynamics include things like frame flex, battery voltage sag, a shifting center of gravity, and unexpected propeller damage. ADRC lumps all of these into a single fictitious force called “disturbance” rather than trying to model each one separately. Because the controller is always adjusting for these forces, there are a few practical benefits:

Simpler tuning. The tuning parameters are also a little easier to understand than PID’s. The main one is a physical value specific to your drone, essentially its acceleration on each axis. The other two simply control how fast you want the drone to respond.

Coming from PID?

Early ADRC research describes it as an extension of PID, and you can think of it as a PID controller that constantly re-tunes itself. That is a simplification, but it is a somewhat reasonable way to think about how ADRC works.

A note on filters. ADRC can interact in unexpected ways with some of the default filters. It is recommended to disable any filters that are not directly related to something physical on the drone: disable everything in the filters setting tab other than the gyro RPM filter and any notch filters that have been previously set to account for a frame resonance.

2. The control parameters

b0 — nominal control gain

Set per axis.

This is the most important parameter, as it gives the controller an estimate of how each axis responds for a given input. Think of this as how much the controller expects the drone to accelerate for a given amount of motor power. A drone with a high thrust-to-weight ratio will have a higher b0 than one with a low thrust-to-weight ratio.

This parameter only needs to be a reasonably close ballpark estimate, as a gap between the drone's actual gain (b) and the control gain is lumped into the disturbance estimate. However, if b0 is too far off the actual b, the mismatch can exceed what the controller is able to correct, and result in motor oscillations, tracking lag, and instability. This value can be determined using the included code that fits a blackbox log.

wo — observer bandwidth

Set per axis. Units: rad/s.

This governs how fast the observer is able to detect and estimate disturbances. This is limited by gyro noise and frame vibrations; setting this too high will eventually cause the observer to pick up sensor noise and normal drone vibrations. This leads to excessive erroneous corrections, resulting in wasted battery, motor heating, and oscillations. If this is too low the drone will respond slowly to disturbances. As a rule of thumb, this parameter should be set as high as the drone's noise floor allows.

wc — controller bandwidth

Set per axis. Units: rad/s.

This governs how fast the controller attempts to adjust the drone. If this is too low, the drone will be sluggish and respond slowly to inputs. If this is too high the drone will feel twitchy and can overshoot commanded movements. This is similar but not exactly the same as the P gain in a PID controller. This must always be lower than the observer bandwidth, or the controller will attempt adjustments before it can see disturbances and create instabilities.

adrc_b0_law — scaling for b0

Accepted values: QUADRATIC, LINEAR, SQRT, FIXED. Default: SQRT.

This scales the nominal control gain (b0) based on the throttle. Because thrust is slightly nonlinear with throttle, the drone's actual gain varies based on throttle position. The optimal scaling law varies depending on the specific hardware configuration. For most tested hardware configurations, either SQRT or LINEAR perform well. FIXED disables this function.

adrc_hover_throttle — throttle % at which the drone hovers

Default: 35%. This is the throttle % at which the b0 scaling law kicks in. Does nothing if adrc_b0_law is FIXED.

Important

The wc/wo ratio represents a trade-off between disturbance rejection and responsiveness. Setting wc much lower than wo (around 30–50%) will result in a slower response to control inputs, but will better reject disturbances. A higher wc/wo ratio (around 90%) will result in a faster response, but it will reject disturbances slower and may overshoot more. A wc/wo ratio of 0.9 (low disturbance rejection) on a 5″ drone is still able to fly with missing propeller blades.

3. Quick start tuning procedure

Because the gain of a particular drone is specific to the hardware configuration (mostly the motors and propellers) there is not a universal setting that works reasonably well across all hardware configurations, unlike the stock PID settings. The easiest way to determine these values is from a blackbox log recorded during a test flight while using the stock PID settings.

Record baseline PID flight & gather data

Fly the drone using standard PID controls. Note the throttle percentage required to maintain a hover. During the flight execute a chirp command used for the PID auto tune on each axis, or fly around with a fair number of movements on each axis. The baseline flight should basically be a hover with some wobbles commanded on each axis.

Calculate b0 values from the recorded baseline flight

Run the recorded blackbox log through the plant-fitting script to determine the nominal control gain (b0). Before dropping in the log, set Proposed wc to the controller bandwidth you plan to fly (80 if you’re following this guide). The output of the fitting script includes several plots that show the points used for the fit along with the fit. Shown below is an example of a fit performed on the baseline flight from a 5″ drone.

Plant fitting output for roll, pitch and yaw: recovered gain against frequency, with the controller-free fit band, controller-free fit and eRPM path.
Example plant-fitting output from a 5″ drone baseline flight.

Make sure that the fit output looks reasonable (the fit curves should overlap reasonably with the points used for the fit). Also check that the calculated ctrl-free and eRPM values are reasonably close to each other. If the fits on the plot do not line up well, or the ctrl-free and eRPM values are very far apart, redo the baseline PID flight with more movement on each axis. The fitter reports b0 matched to the wc you entered, so the output values can be used directly as your initial b0 values with no further adjustment. If you later change wc, rerun the fit with the new value to get a matching b0.

The fitter also outputs a motor lag value. Set this as adrc_motor_tau_ms in the CLI.

Fit warnings

Occasionally there will be an output warning that says something like:

[WARNING: yaw] 2nd pole above the excited band

This most frequently occurs with the yaw axis. It means that the axis was not excited enough for a proper fit — in the example plots, the controller-free and eRPM fits diverge slightly at lower frequency. This may be corrected by adjusting the chirp parameters or including more yaw movements in the test flight. Because b0 does not need to be exact, in most cases this parameter can be used and the baseline flight does not need to be repeated. This has not been found to matter so far in testing.

Disable unnecessary filters (optional)

Filters used by PID control can interact in unexpected ways, because they introduce a slight delay to what the observer sees and can cause the controller to attempt to correct for disturbances too slowly. Navigate to the PID Tuning > Filter Settings tab in Betaflight and disable all PID filters (lowpass filters, dynamic notch, D-term filters). Keep only physical hardware-related filters enabled, such as the motor / gyro RPM filter and any manual notch filters tuned for known structural frame resonances.

Switch controller and apply parameters

Open the Betaflight CLI and run the following commands. Substitute in your calculated b0 values, fitted motor lag, and measured hover throttle:

Betaflight CLI

set PID_TYPE = ADRC
set adrc_hover_throttle = <your_hover_throttle_value>
set adrc_b0_roll = <calculated_roll_b0>
set adrc_b0_pitch = <calculated_pitch_b0>
set adrc_b0_yaw = <calculated_yaw_b0>
set adrc_wc_roll = 80
set adrc_wc_pitch = 80
set adrc_wc_yaw = 80
set adrc_wo_roll = 90
set adrc_wo_pitch = 90
set adrc_wo_yaw = 90
set adrc_motor_tau_ms = <fitted_motor_lag>
save

The wc/wo values of 80/90 provide fairly responsive controls and are a good starting place for further tuning if desired.

Perform ground arm tap test

This is only necessary if the control loop is active on the ground (Betaflight default). If pid_at_min_throttle = OFF this process is not necessary.

If the control loop is active on the ground, the drone can lift or hop by itself right after arming in airmode. This mostly occurs on smaller drones. It shows up as the drone bouncing or hopping on the ground and then abruptly flying away when no throttle is commanded. The parameter adrc_ground_wc sets the controller bandwidth to a low value while on the ground. It prevents unintended lifting or hopping on arm in airmode, which can lead to a flyaway while the control loop is still closed through ground contact. By default adrc_ground_wc = 10, which should prevent this from occurring.

To ensure this is not possible on your drone, arm the drone and, when no throttle is commanded, physically tap on the drone a couple of times using a stick. Lifting the back of the drone slightly and letting it drop down also works. If the drone starts bouncing on the ground during this test, reduce the adrc_ground_wc value until it stops occurring.

Danger

Setting adrc_ground_wc to 0 disables this protection. Do not set this value to 0 if the drone bounces on the ground during this test, as this will cause it to unpredictably fly away when armed.

Done

Initial ADRC setup is now complete.

4. Parameter tuning table

SettingWhat it doesIf it's too highIf it's too lowRule of thumb
Observer bandwidth (wo) How quickly the drone notices things like wind gusts or extra weight. The drone overreacts to tiny vibrations. The motors buzz and twitch, run hot, and drain the battery faster. The drone is slow to notice wind or changes, so it drifts and wobbles before correcting. Increase it until the motors start sounding rough, then turn it back down a bit.
Controller bandwidth (wc) How quickly and firmly the drone responds to commands and corrections. The drone is twitchy and overshoots its target. It can start oscillating and potentially lose stability. The drone feels sluggish to respond to commanded movements and hold position. Start low and increase gradually until the drone feels crisp but not twitchy.
Nominal control gain (b0) The controller's guess of how strongly the drone responds to motor changes. The controller doesn't request motor power quickly enough, so the drone feels sluggish and soft. The controller requests motor power too quickly, so the drone overshoots or oscillates. This causes instability. If unsure, guess a little high. Sluggish and stable is safer than twitchy and unstable.

Bandwidth ratio

State / rangeRatio value (wc / wo)Flight behavior & primary effectPotential risks / downsides
Too low< 0.30 Highly damped and sluggish stick response; observer runs much faster than control action. The drone feels unresponsive and delayed on stick inputs.
High rejection (conservative)≈ 0.30 – 0.50 Prioritizes rejecting external forces, wind, prop wash, and frame anomalies. Slower response to pilot control inputs.
High responsiveness (aggressive)≈ 0.80 – 0.90 Fast tracking to stick inputs with minimal lag. Slower disturbance rejection (though a 0.9 ratio on a 5″ drone can still fly with damaged or missing prop blades).
Too high (marginal)> 0.90 – 0.95 Extremely reactive, twitchy feel; can feel over-sensitive to stick inputs. Prone to overshoot on aggressive maneuvers; disturbance rejection becomes sluggish.
Critical limit / instability≥ 1.0 (wc ≥ wo) Controller attempts to make physical adjustments before the observer can detect and estimate disturbances. Control instability, potential for rapid self-excited oscillations.
Try it

The interactive tuning sandbox lets you drag wc, wo and b0 on a simulated rate loop and watch the step response and disturbance recovery change.