UAV Systems Engineering · Module 5
M5-T16: Disturbance rejection and wind compensation
Wind is an unmeasured force. You can reject it with integrators, cancel it with an observer, or estimate it from the vehicle’s own motion.
A multirotor in wind is a controller with an unmodelled external force. Integral action eventually removes constant offsets, but gusts need faster action. A disturbance observer treats the force as an extra state and cancels it; the same idea in an EKF turns the vehicle into a crude anemometer.
Learning objectives
After this lesson, you should be able to:
- Model wind as a constant plus gust disturbance entering the translational dynamics.
- Compare integral action with a disturbance observer for rejection speed and noise sensitivity.
- Estimate wind from airspeed-like quantities using a drag model and state the assumptions.
- List what limits the wind speed in which a vehicle can hold position.
Conceptual explanation
Established Integral action and disturbance observers are standard control methods. Wind estimation from drag depends on a calibrated drag model for the specific vehicle: the coefficients below are illustrative, not measured values for any real aircraft.
Wind enters a multirotor mainly through aerodynamic drag, which depends on the velocity relative to the air, and through changes in rotor thrust. For small speeds a linear model is often used: the drag force is proportional to the relative velocity, so the vehicle in a steady wind experiences a force that tilts it into the wind and needs a steady lean to hold position.
Approaches to rejection, in order of complexity:
- Integral action in the velocity or position loop removes steady offsets, at the cost of lag and windup risk.
- Disturbance observer (DOB): estimate the lumped disturbance from the difference between the measured acceleration and the model-predicted acceleration, and subtract it in the command.
- Wind estimation in the EKF: augment the state with the wind velocity and use the drag model so that the horizontal acceleration measured by the IMU makes the wind observable (PX4’s EKF2 can estimate wind this way and also uses airspeed if present; check the documentation for your version).
- Robust or adaptive control (for example L1 adaptive control) which adapts the compensation online.

Engineering intuition
Integral action is a person slowly leaning on a door until it stops moving: it works, but only after the door has already moved. A disturbance observer is a person who feels the push immediately and pushes back with the same force: faster, but if the person misjudges the push, the door still moves.
The limit is always physical. Holding position in wind requires tilting enough that the horizontal thrust component equals the drag. For a given drag coefficient the maximum tilt (set by thrust margin) fixes the maximum wind. No controller beats that; it can only avoid wasting margin. In gusts, remaining thrust margin is what lets the vehicle recover, so flying close to the thrust limit in strong wind is the dangerous regime.
Mathematical formulation
Translational dynamics with a lumped disturbance acceleration (including wind-induced drag): , where is the commanded acceleration from the controller. A disturbance observer with gain (first-order) estimates it as:
In practice is not measured directly; the equivalent form uses an auxiliary variable : , , which needs only and . The error of the estimate obeys , so a constant disturbance is estimated with time constant 1/L and a ramp with a steady error ḋ/L: a larger gives a faster estimate and more noise gain.
With a linear drag model (per unit mass, in 1/s), holding position in wind needs a horizontal acceleration , so the lean angle is for small vertical acceleration. The maximum holdable wind for a tilt limit is
For example with an illustrative and , : a vehicle-specific measurement is required to know the real value.
- lumped disturbance acceleration .
- observer bandwidth (1/s).
- linear drag coefficient per unit mass (1/s).
- wind velocity (m/s).
Architecture and data flow
IMU and position/velocity estimate → disturbance observer or EKF wind states → feed-forward added to the commanded acceleration → position controller. With an airspeed sensor, the relative airspeed directly supplies , which makes the estimate faster and observable in steady flight. Alongside, a monitor checks the lean angle and thrust margin against the vehicle’s wind limit and triggers return or landing when the margin is exhausted.
Real-world UAV applications
- Position hold and precision landing in wind.
- Inspection close to structures where wind is turbulent.
- Ship deck landing with gusts and air-wake.
- Estimating wind for meteorological data or for planning energy use.
Implementation example
This runs as shown. A point mass with a PD position controller faces a constant acceleration disturbance of that switches on at . The test compares: PD only (steady offset), PD with integral action (slow recovery), and PD with a disturbance observer (fast recovery), and confirms the ordering of the peak and settling errors. It also reproduces the maximum holdable wind arithmetic.
import numpy as np
def run(mode, dt=0.002, T=20.0, Kp=4.0, Kd=3.5, Ki=2.5, L=8.0, dist=1.5):
p = v = I = z = 0.0; peak = 0.0; late = []
for k in range(int(T / dt)):
t = k * dt; d = dist if t >= 5.0 else 0.0
dhat = z + L * v if mode == 'dob' else 0.0
u = -Kp * p - Kd * v - (I if mode == 'int' else 0.0) - dhat
if mode == 'int': I += Ki * p * dt
if mode == 'dob': z += -L * (z + L * v + u) * dt # observer: dhat = z + L v, estimate of the disturbance acceleration
v += (u + d) * dt; p += v * dt
if t >= 5.0: peak = max(peak, abs(p))
if t >= 15.0: late.append(abs(p))
return peak, np.mean(late)
res = {m: run(m) for m in ('pd', 'int', 'dob')}
for m, (pk, ss) in res.items(): print(f"{m:>3}: peak {pk:.3f} m, error at 15-20 s {ss:.4f} m")
assert res['pd'][1] > 0.3 and res['int'][1] < 0.01 and res['dob'][1] < 0.01 and res['dob'][0] < res['int'][0] < res['pd'][0] + 1e-9
g, kd, th = 9.81, 0.5, np.radians(25); print(f"w_max = {g * np.tan(th) / kd:.1f} m/s (illustrative k_d)")
assert abs(g * np.tan(th) / kd - 9.15) < 0.1Common engineering mistakes
Integral action with no anti-windup
Windup in saturation produces large overshoot after a gust.
Observer bandwidth too high
Noise on the velocity estimate is amplified into the command.
Using a drag model from another vehicle
The wind estimate is biased by the wrong coefficient.
No margin check
In strong wind the thrust margin vanishes and recovery from a gust is impossible.
Treating gusts as constants
A gust has dynamics faster than the integrator; the integrator lags and the DOB bandwidth must be chosen accordingly.
Failure modes
| Failure mode | How it shows up | Likely cause |
|---|---|---|
| Vehicle drifts downwind | Gradual offset in position hold | No integral action or too weak; wind beyond the lean limit |
| Oscillation after a gust | Overshoot and ringing | Integrator windup or an over-aggressive observer |
| Bad wind estimate | Estimate wanders or is biased | Wrong drag model, poor excitation, or vibration in the accelerometer |
| Loss of altitude in a gust | Sudden sink | Thrust saturated by the combined lean and gust demand |
Debugging approach
- Plot the commanded lean angle and the estimated wind against time and compare with a reference anemometer.
- Check the thrust margin and saturation flags.
- Replay a recorded gust through the controller in simulation.
- Test the response to a step disturbance (tethered pull or simulated wind) and measure the recovery time.
Practical exercises
- Sweep the observer bandwidth from 1 to 40 and plot the peak error and the sensitivity to velocity noise (add 0.05 m/s noise).
- Replace the constant disturbance with a 1 Hz sinusoid and compare the three controllers.
- Compute the maximum holdable wind for and tilt.
- Add actuator saturation and anti-windup to the integrator.
Interview questions
Write an answer in your own words, then reveal the model answer. Nothing is sent anywhere.
Question 1
Compare integral action with a disturbance observer.
Model answer
Integral action removes constant offsets slowly and risks windup; a disturbance observer estimates the disturbance from model mismatch and cancels it quickly, but its noise gain grows with bandwidth and it relies on the model.
Question 2
How can a multirotor estimate wind?
Model answer
By modelling drag as a function of velocity relative to the air and augmenting the EKF with wind states, so that the measured acceleration and the vehicle’s motion make wind observable (airspeed measurements make it more direct).
Question 3
What limits the wind in which a vehicle can hold position?
Model answer
The lean angle needed to balance drag against the tilt and thrust margin available. When the margin is exhausted the vehicle drifts and cannot recover from gusts.
References and further reading
Primary papers, official documentation and standards. Each claim above that is specific to a tool or version points here.