Adaptive Control, when the plant refuses to hold still.
The art of tuning controllers while they run — what it buys you, what it costs you, and the ideas you need to keep your adaptation from destabilizing the very system you are trying to stabilize.
§ 01Why adapt?
A fixed-gain controller is a promise: "the plant I tuned against is the plant I will meet in the field." Violate that promise and you get degraded performance, limit cycles, or instability. Classical robust control handles the violation by leaving performance on the table — big phase margins, slow loops. Adaptive control handles it by learning.
Use adaptive methods when one or more of these is true:
- Plant parameters drift slowly (temperature, wear, aging, saturation).
- Operating point changes dramatically (flight envelope, motor speed/torque, battery SoC).
- You can't identify the plant cheaply offline (production tolerance, unit-to-unit variation).
- A disturbance you cannot measure enters the loop as an unknown additive or multiplicative term.
Adaptation is a second feedback loop wrapped around your first one. Everything that made the inner loop fragile — noise, un-modeled dynamics, saturation, finite word length — now feeds the adaptation law too. A naïve adaptive controller is usually less robust than the fixed-gain design it replaced. Section §08 exists for this reason.
§ 02The taxonomy in one page
Every adaptive controller you will meet falls into one of these four boxes. Knowing which box you're in tells you what stability theorem to invoke, what signals to filter, and what goes wrong first.
Direct MRAC
Update controller parameters θ directly from the tracking error e = y − y_m. Plant parameters never appear explicitly. Lyapunov or MIT rule.
Indirect adaptive (STR)
First estimate plant parameters online (â, b̂), then design the controller from those estimates every cycle. "Certainty equivalence."
Gain scheduling
Pre-compute a family of controllers indexed by a measured scheduling variable (Mach, RPM, temperature). Interpolate online. Not technically "adaptive" — no learning — but solves the same problem.
L1 / robust-adaptive
Modern architectures that decouple adaptation speed from robustness via a low-pass filter on the adaptation signal. Fast transient without the high-frequency fragility of classical MRAC.
Direct methods adapt the medicine. Indirect methods adapt the diagnosis, then re-prescribe. Gain scheduling keeps a cabinet of pre-filled prescriptions. L1 adapts the diagnosis fast but only prescribes what's been filtered through the pharmacist.
§ 03Core terminology
Hover the dotted terms anywhere in this document for a reminder. The full list, for when an equation suddenly assumes you remember what a "regressor" is:
- Reference model y_m, G_m(s)
- The behavior you want. Drives the tracking error
e = y − y_mthat the adaptation minimizes. Must be stable and achievable by the plant class you assume. - Regressor φ(t)
- Vector of measured/filtered signals that multiply the unknown parameters in the plant model:
y = φᵀθ. Good regressors are bounded, persistently exciting, and known exactly. - Persistence of excitation PE
- A condition on the regressor: its autocorrelation matrix is uniformly positive-definite over every window. PE ⇒ parameter convergence. Without it you get tracking convergence but drifting estimates.
- Adaptation gain γ, Γ
- How aggressively the parameter estimate chases the error. Too small: slow learning. Too large: high-frequency parameter oscillation that couples into the plant. The single most-tuned knob in MRAC.
- Certainty equivalence
- The design philosophy of indirect adaptive control: use the current estimate as if it were the truth. Works when estimation error is small and slow; fails spectacularly when estimate jumps.
- Forgetting factor λ
- In recursive least squares, the exponential weight on old data.
λ=1: infinite memory (good for constant parameters).λ<1: tracks drift but amplifies noise. - Covariance wind-up
- When the regressor is not PE, the RLS covariance matrix
Pgrows without bound. The estimator becomes infinitely sensitive and a tiny disturbance throws the estimate off a cliff. - σ-modification / e-modification
- Leakage terms added to the parameter update law so estimates stay bounded even without PE. σ: constant leak. e-mod: leak scaled by error magnitude. Both trade parameter-error accuracy for robustness.
- Projection operator Proj(·)
- Clamps the parameter estimate to a known-safe convex set. Non-negotiable in production code: it is the difference between a bounded controller and one that commands infinity.
- Dead zone
- Turn off adaptation when the tracking error is smaller than a noise/disturbance floor. Stops the adaptation from chasing measurement noise forever.
- Relative degree r
- Difference between numerator and denominator orders of the plant. Governs which MRAC variant you need (for
r=1: SPR-based Lyapunov design. Forr>1: augmented error or backstepping). - Minimum-phase
- No right-half-plane zeros. Essentially every classical MRAC stability proof assumes this, because the ideal controller inverts the plant zeros. Non-min-phase plants need careful output redefinition.
§ 04MRAC, in the flesh
Model Reference Adaptive Control is the canonical direct method. You pick a reference model with the dynamics you want, wrap a controller around the real plant, and let an adaptation law bend the controller gains until plant output matches model output.
Consider a first-order scalar plant with unknown parameters a and b:
and a reference model you get to choose:
Parameterize the controller as u = θ₁ r − θ₂ xp. If we knew the plant, the matching gains would be θ₁* = b_m / b and θ₂* = (a_m − a) / b. We don't know them, so we update them online. Two classic laws:
| Law | Update | What it guarantees |
|---|---|---|
| MIT rule (gradient) | θ̇ = −γ e (∂e/∂θ) |
Decreases a local error-squared cost. Not globally stable for large γ. |
| Lyapunov (normalized) | θ̇₁ = −γ e r, θ̇₂ = +γ e xp |
Globally bounded signals, e → 0, via a Lyapunov function with parameter-error terms. Requires sign(b) known. |
Watch them fight in the lab below. Change the true plant parameters, the adaptation gain, and the reference signal, then watch both the tracking error and the parameter estimate drift toward (or away from) the matching values.
In discrete time you will integrate θ̂ with your outer-loop rate. Either use a tight Euler step and verify step size against the highest adaptation bandwidth, or use a trapezoidal/Tustin integrator. Always apply projection on every integration step, not just at the output.
§ 05Persistence of excitation, visually
You have two reasonable goals when adapting: track the reference, and learn the true parameters. It is a hard truth that tracking converges under weaker conditions than parameter convergence. The condition you need for the second is persistence of excitation — there must be enough frequency content in the regressor to separately identify each parameter.
Rule of thumb: to identify n parameters you need at least n/2 independent sinusoids in your excitation. A step has one frequency (DC) — it will never identify two parameters. Try it in the MRAC lab above by switching the reference to "square" and watching θ̂₁ and θ̂₂ drift indefinitely even while tracking error goes to zero.
§ 06Self-tuning regulators & online identification
The indirect approach: identify the plant first, then redesign the controller from the identified model. The workhorse identifier is Recursive Least Squares:
Watch how λ trades memory for agility. λ=1 gives you the classical batch least-squares answer in the limit (good for truly constant parameters). λ<1 exponentially forgets old data: essential for drifting parameters, ruinous if the regressor isn't PE.
Set λ<1 and switch the excitation to "step" above. Watch tr(P) climb without bound — the estimator "forgets" without "learning anything new." The moment a disturbance hits, your estimates fly off. In production: add a directional forgetting or constant-trace algorithm, or switch to λ=1 with a reset on event detection.
λ so that the effective memory window N_eff ≈ 1/(1−λ) is 5–10× the longest time constant you want to track. Initialize P(0) = α·I with α large (1e3–1e6) only if you have no prior; otherwise seed with a smaller α and a good initial θ̂(0) — it robustifies the first second.
§ 07Gain scheduling — the pragmatist's adaptive control
Before you reach for MRAC, ask: is there a measurable variable that explains most of my plant's variation? If yes, gain scheduling is almost always simpler, safer, and more certifiable. Pre-compute a family of fixed-gain controllers at representative operating points, interpolate between them online.
The catch: gain scheduling is open-loop in the parameter. If your scheduling variable is wrong, lagged, or noisy, no error signal tells the controller to correct. This is why modern designs often combine the two: gain schedule for known operating-point variation, narrow adaptive term for the residual.
Design workflow
- Select the scheduling variable s. It must be measurable, slowly varying, and causally related to plant variation.
- Identify the plant at N operating points spanning the envelope of s.
- Design N controllers, one per point, using your favorite fixed-gain technique.
- Interpolate — linearly, bilinearly, or via a smooth basis — between stored gain sets.
- Verify stability at the interpolated points, not just the design points. LPV analysis gives you rigorous bounds.
Interpolating between two individually stable controllers can produce an intermediate controller that is unstable on the intermediate plant. This is the same pathology as "hidden modes" in switched systems. Always gridded-sim your full envelope.
§ 08Robustness modifications
A pure Lyapunov-based MRAC guarantees e → 0 for the ideal plant. The word "ideal" is doing a lot of work. The real plant has un-modeled high-frequency dynamics, bounded disturbances, and measurement noise. Any of these three can cause the parameter estimate to drift without bound even while tracking looks fine — until the drift excites the un-modeled dynamics and everything explodes. This is parameter drift / bursting.
The fix is always the same shape: add a stabilizing term to the parameter update law that keeps θ̂ bounded. Four standard patches:
| Modification | Update law | When to use | Cost |
|---|---|---|---|
| σ-modification | θ̂̇ = −γeφ − σ θ̂ |
Always on; cheapest insurance. | Biases θ̂ toward zero; small residual tracking error. |
| e-modification | θ̂̇ = −γeφ − σ·|e|·θ̂ |
When you want leakage only during poor tracking. | Ineffective once e is small; won't catch slow drift. |
| Dead zone | θ̂̇ = 0 if |e| < δ |
Known disturbance/noise floor. | Must know δ; misestimate and you lose tracking. |
| Projection | θ̂̇ = Proj(−γeφ, Θ) |
Always on. Non-negotiable in safety-critical code. | Requires known bounds on θ*. Usually cheap to get. |
Ship with all four. Projection for hard bounds, σ-mod for drift insurance, dead zone sized to your measurement noise 3σ, and a supervisor that can blend back to a safe fixed-gain controller if ‖θ̂‖ hits the projection boundary for more than a few seconds (that means your assumed plant class was wrong).
1/σ is about 10× your expected parameter-change time scale. Too small: drift still wins. Too large: σ biases θ̂ toward zero and kills steady-state tracking accuracy.
§ 09L1 adaptive control, briefly
Classical MRAC's trade-off between adaptation speed and robustness is fundamental: crank γ up for fast learning and the same update law pumps high-frequency noise into the parameter — which then modulates u through the controller. L1 adaptive control's insight: decouple the two. Adapt as fast as you like on an internal signal path; only let the filtered version reach the actuator.
The low-pass filter C(s) is the crucial block. Its bandwidth sets a hard ceiling on how much of your adaptation ends up in u. You design C(s) for robustness (like a traditional loop shape), and pick γ to be as fast as numerical stability allows. The resulting transient performance is bounded in the L∞ (uniform) sense — predictable, not just asymptotic.
Flight control, missile autopilots, fast electromechanical systems where transient overshoot matters more than asymptotic perfection. If your MRAC keeps hitting a speed/robustness wall, this is the next architecture to study.
§ 10Implementation notes
Discretization
Almost everything in the literature is written in continuous time. You will run on a micro at 1–20 kHz. Three rules:
- Sample the adaptation law at the same rate as the control law. If the outer loop runs slower (e.g. 1 kHz control, 100 Hz estimator), you are adapting to a stale error signal. Tune γ against the slower rate.
- Use Euler for prototyping, Tustin for production. Euler's one-step phase lag is fine while you're debugging; it becomes part of your stability margin in shipped code.
- Check against γ·Ts < 2/‖φ‖² at every operating point. This is the discrete-time stability bound for the normalized gradient update and is often violated silently when φ grows.
Fixed-point considerations
Parameter estimates are the scariest quantity to fixed-point — they can drift over orders of magnitude and they multiply signals that saturate asymmetrically. Recommendations:
- Use a Q-format with at least 2× the expected θ-range as headroom. Projection is what keeps you from ever exercising that headroom, but the compiler-inserted saturation semantics differ across toolchains.
- In TargetLink/AUTOSAR environments: enforce the type on the parameter state explicitly, don't rely on inference. A silent
float32→uint16conversion on an update path is a multi-hour root-cause hunt. - Keep regressors normalized:
φ_n = φ / (1 + φᵀφ). This bounds the update step and is what most proofs silently assume anyway.
Sensor-hostile environments
- Pre-filter the same signal going into the regressor and the tracking error with the same filter. Any mismatch introduces a bias the estimator will happily absorb into θ̂.
- Anti-alias, anti-alias, anti-alias. An under-filtered φ at Nyquist will alias into a DC bias that looks exactly like a true plant change.
- A/D quantization couples into the update as an effective disturbance of magnitude
γ · q · ‖φ‖. Scale γ against the bit depth.
Initialization
- Seed θ̂(0) from an offline ID pass or a nominal-parameter table. Never start at zero unless your Lyapunov proof explicitly accommodates the transient.
- Start with adaptation off for the first 100–1000 ms. Let filters settle, initial transients decay, then freeze-release the update law.
- Log every boundary hit of your projection operator. Sustained projection contact is the earliest warning that your assumed plant class is wrong.
Saturation & anti-windup
Saturation is the single most common cause of adaptive-control accidents. When u saturates, the plant is not actually responding to your commanded u; the tracking error accumulates; the adaptation law concludes "I must push harder" and drives θ̂ further into saturation. Three mitigations, in order of effectiveness:
- Freeze adaptation when u is saturated. Simplest, most widely used. Just check the saturation flag and gate the update.
- Use the actual applied u (post-saturation) in the regressor, not the commanded u. The estimator sees the truth.
- Hedging-based MRAC — explicitly model the saturation in the reference model so the model slows down with the plant. Research-grade, increasingly seen in aerospace.
§ 11Rules of thumb — one card per decision
λ = 1 − Ts/τ_drift where τ_drift is how fast you expect true parameters to change. Never go below 0.90 without a covariance-bounded RLS variant. Never use λ<1 without PE monitoring.
§ 12The ten failure modes
Every adaptive controller that has ever destabilized a real system did so through one of these. Memorize them.
- Parameter drift / bursting. Non-PE regressor + small disturbance + no σ-mod/projection. Symptom: tracking looks fine for minutes, then a burst. Fix: §08.
- Saturation coupling. Actuator saturates, error grows, estimator concludes "more gain!", commanded u grows further into saturation. Fix: gate adaptation on saturation flag.
- Un-modeled high-frequency dynamics. Adaptation excites a resonance the reference model didn't know about. Fix: low-pass φ below the first un-modeled resonance, shrink γ.
- Sign-of-gain assumption violated. Lyapunov-MRAC assumes sign(b) is known. In some plants (e.g. motor reversal, surface reversal in flight), it isn't. Fix: Nussbaum-gain techniques or switch-on-sign detection.
- Reference model not achievable. You asked for bandwidth the actuator cannot produce. Adaptation tries forever. Fix: relax the reference model, or add hedging.
- Covariance wind-up in RLS. λ<1 with persistent non-PE. Fix: bounded-trace RLS, directional forgetting, or switch λ→1 on PE loss.
- Regressor noise absorbed as bias. Measured signals enter φ with noise; noise correlates with error; estimator explains the noise with wrong θ̂. Fix: identical filtering on error and regressor, or instrumental-variable methods.
- Slow estimator in a fast loop. Controller redesigns before estimator has converged → intermittent performance. Fix: separate the two time scales by 5× minimum, or add a hold on the controller redesign.
- Projection whiplash. Tight bounds + aggressive γ → estimate pinned to a face, chattering. Fix: widen bounds, smooth projection operator.
- Cold-start transients. θ̂(0) far from θ*; initial u huge; actuator saturates; see failure #2. Fix: seed θ̂(0) from nominal, adaptation-off warm-up period.