Skip to the lesson
FixTheRobot Explore Robotics / Guidance, Navigation and Control / M5 Nonlinear, Scheduled and Adaptive Control / M5-T7

Guidance, Navigation and Control · Theory · M5

M5-T7 — Robustness Beyond Gain and Phase Margin

Gain margin and phase margin each move one thing at a time. A real loop is wrong in gain and phase together, and one number can say how much of both it tolerates.

  • Lesson 7 of 7
  • Intermediate
  • Module 5: Nonlinear, Scheduled and Adaptive Control
  • Theory
  • About 13 minutes to read

The classical margins ask how much gain, or how much phase, can be added to a loop before it goes unstable. They test two directions of a plane. This lesson computes the disk margin, which tests a whole disk of simultaneous gain and phase variations from the peaks of two frequency responses, states the small-gain theorem that underlies it, and shows on Hopper that a loop with a comfortable gain range and phase margin can still fail for a modest combination, and that the observer-based loop of module 4 has a disk margin one fifth that of the regulator.

Learning objectives

After this lesson, you should be able to:

  • Compute the disk margin of a loop from its sensitivity and complementary sensitivity.
  • Convert the disk margin to a guaranteed gain interval and a guaranteed phase variation.
  • State the small-gain theorem and apply it to a multiplicative uncertainty.
  • Show an example in which gain and phase margins hold separately but the loop fails for a combination.

The intuition

Lab: Build a CBF Safety Filter guarded a vehicle from leaving a safe set. Margins guard a loop from leaving the set of stable ones. The classical measures of how far a loop is from that edge are limited in a way that matters on real vehicles.

Two directions in a plane

Multiply the loop gain at the plant input by a complex number f=k e−jϕf = k\,e^{-j\phi}: its magnitude is a gain change, its angle a phase lag. The nominal loop is f=1f = 1. The gain margin asks how far along the real axis ff can move before the loop goes unstable. The phase margin asks how far around the unit circle. These are two radial lines in the plane of ff, and the loop can be perfectly safe on both and unstable between them.

A disk of safe variations

The disk margin replaces the two lines by a disk. The loop is stable for every ff inside a disk whose size is set by one number, α\alpha, found from the peak of ∣T−S∣|T - S|, a difference of the complementary sensitivity TT and the sensitivity SS of module 3. It is a guarantee: no test of individual points is needed, because the theorem covers them all. For Hopper's pitch loop with servo and delay α=0.83\alpha = 0.83: the loop is stable for any gain from 0.415 to 2.41 and any phase lag up to 45° together, in the sense of the disk.

What the classical margins miss

The same loop has a gain range from 0.03 to 5.96 and a phase margin of 44°, much wider on the gain axis. A gain of 0.5 and a lag of 40° are each inside those ranges, and together they destabilize the loop. For the observer-based loop of the last lesson the classical gain range was ×0.69 to ×1.5; the disk margin is 0.215, a gain interval of ×0.81 to ×1.24 and ±12° at the same time. A designer who looks at gain and phase margins separately sees a loop that is more robust than it is.

The disk margin of a loop and Nyquist tests of combined gain and phase errorsThe complex plane of a factor that multiplies the loop gain. The circle centred at 1.41 with radius 1.00 is the region in which the loop is guaranteed stable, from its disk margin. The point at 1 is the nominal loop. Tested factors are marked, filled for stable and open for unstable: those inside the circle are all stable, two outside it are stable too, and two outside it are unstable, at a gain of 0.5 with 40 degrees of lag and a gain of 0.6 with 45 degrees.-0.500.511.522.53-1.75-1.25-0.75-0.250.250.751.251.75real part of the factor on the loop gainimaginary partguaranteed disk nominal filled: stable open: unstable
The plane of the factor on the loop gain. The disk of the disk margin is a region that is guaranteed stable. Points outside may be stable (the guarantee is sufficient) or unstable, as the tests show.

One disk margin says how much gain and phase variation the loop tolerates together. Its guarantee is for the whole disk, and it is conservative outside it.

Definitions

Sensitivity SS
S=1/(1+L)S = 1/(1 + L): the response of the error to a disturbance at the output.
Complementary sensitivity TT
T=L/(1+L)=1−ST = L/(1 + L) = 1 - S: the response of the output to the command and the sensitivity to noise and to multiplicative uncertainty.
Disk margin α\alpha
The largest α\alpha such that the loop stays stable for every complex factor in the disk D(α)D(\alpha), defined below.
Small-gain theorem
A loop of two stable systems is stable if the product of their gains is below 1: ∥G1∥∞∥G2∥∞<1\|G_1\|_\infty\|G_2\|_\infty < 1.
Multiplicative uncertainty
A perturbation of the loop that multiplies it by 1+Δ1 + \Delta, as an error in the effectiveness bb or an unmodelled lag does.
The disk margin (skew 0)
αmax⁡=2sup⁡ω ∣T(jω)−S(jω)∣=2sup⁡ω ∣1−2S(jω)∣\alpha_{\max} = \dfrac{2}{\sup_\omega\,|T(j\omega) - S(j\omega)|} = \dfrac{2}{\sup_\omega\,|1 - 2S(j\omega)|}
The supremum is over all frequencies. The expression is computed from the loop gain at the plant input. The nominal loop must be stable.
The disk and what it guarantees
D(α): the disk with diameter on the real axis from 2−α2+α to 2+α2−αD(\alpha) : \ \text{the disk with diameter on the real axis from } \dfrac{2 - \alpha}{2 + \alpha} \text{ to } \dfrac{2 + \alpha}{2 - \alpha}
A loop with disk margin α tolerates every gain factor between those two values (a gain interval) and every phase lag up to 2arctan⁡(α/2)2\arctan(\alpha/2), and all the combinations whose factor lies in the disk.

Derivation: the small-gain theorem and the disk margin

The loop gain is perturbed to fLf L with ff a complex constant.

  1. f=1+(α/2)δ1−(α/2)δ,∣δ∣≤1f = \dfrac{1 + (\alpha/2)\delta}{1 - (\alpha/2)\delta}, \quad |\delta| \le 1

    A parametrization of the disk D(α): δ = ±1 gives its two real-axis ends and the whole unit disk of δ fills it. Stability for every factor in D(α) means stability for every such δ.

  2. 1+fL=(1+L)+(α/2)δ (L−1)1−(α/2)δ=(1+L) (1+(α/2)δ (T−S))1−(α/2)δ1 + fL = \dfrac{(1 + L) + (\alpha/2)\delta\,(L - 1)}{1 - (\alpha/2)\delta} = \dfrac{(1 + L)\,\bigl(1 + (\alpha/2)\delta\,(T - S)\bigr)}{1 - (\alpha/2)\delta}

    Substitute and divide by 1+L1 + L, using (L−1)/(1+L)=T−S(L - 1)/(1 + L) = T - S. The nominal loop is stable, so a change of stability can come only from the second factor.

  3. no zero of 1+(α/2)δ (T−S) on the imaginary axis for any ∣δ∣≤1\text{no zero of } 1 + (\alpha/2)\delta\,(T - S) \text{ on the imaginary axis for any } |\delta| \le 1

    This is the small-gain condition for the stable loop T−ST - S with the perturbation (α/2)δ(\alpha/2)\delta: the product of their gains must stay below 1.

  4. α2 sup⁡ω∣T−S∣<1  ⇒  α<2sup⁡ω∣T−S∣\dfrac{\alpha}{2}\,\sup_\omega|T - S| < 1 \;\Rightarrow\; \alpha < \dfrac{2}{\sup_\omega|T - S|}

    Solve for the size of the disk. The largest safe disk is the disk margin. It is sufficient and may be conservative.

The gain and phase it implies

  1. fmin⁡=2−α2+α,fmax⁡=2+α2−αf_{\min} = \dfrac{2 - \alpha}{2 + \alpha}, \qquad f_{\max} = \dfrac{2 + \alpha}{2 - \alpha}

    Where the disk meets the real axis: the guaranteed gain interval. For α = 0.827 it is (0.415, 2.41).

  2. sin⁡ϕmax⁡=fmax⁡−fmin⁡fmax⁡+fmin⁡=4α4+α2,ϕmax⁡=2arctan⁡α2\sin\phi_{\max} = \dfrac{f_{\max} - f_{\min}}{f_{\max} + f_{\min}} = \dfrac{4\alpha}{4 + \alpha^2}, \quad \phi_{\max} = 2\arctan\dfrac{\alpha}{2}

    The largest angle subtended by a point of the disk at the origin: the tangent from the origin to the circle. For α = 0.827 it is 44.9°.

The disk margin is the small-gain condition for a perturbation of the loop gain by a complex factor: it guarantees stability for a whole disk of gain and phase errors from a single peak of the frequency response.

A worked example

Hopper's pitch loop with PD gains (Kp=0.8405, Kd=0.2854K_p = 0.8405,\ K_d = 0.2854), the 40 rad/s servo and a 30 ms delay, then the lateral loops of module 4.

  1. The peak. The peak of ∣S∣|S| is 1.437 and the peak of ∣T−S∣|T - S| gives α=0.827\alpha = 0.827: a guaranteed gain interval of (0.415, 2.41) and a phase lag of up to 44.9°, together.
  2. One at a time. By Nyquist tests the loop is stable for gains from 0.03 to 5.96 with the phase unchanged and for lags up to 44° with the gain unchanged. The phase margin is 45.1°, the same as the disk gives; the gain range is much wider.
  3. Together. A gain of 0.6 with a lag of 30° is stable and inside the disk. A gain of 0.6 with 45° is unstable (outside the disk). A gain of 0.5 with 40° is unstable, although 0.5 alone and 40° alone are both inside the one-at-a-time ranges. A gain of 2 with 40° is stable though outside the disk: the guarantee is sufficient, not necessary.
  4. The lateral loops. The LQR alone has α=1.148\alpha = 1.148: gain ×0.27 to ×3.69 and ±60° (the guaranteed 60° of the LQR lesson). The LQG with the Kalman observer has α=0.215\alpha = 0.215: ×0.81 to ×1.24 and ±12°. Recovery with ρ=10\rho = 10 has α=0.962\alpha = 0.962: ×0.35 to ×2.85 and ±51°.
  5. Reading. The disk margin ranks the three lateral designs on one scale and shows the observer-based loop to be five times less robust than the regulator it was built from, which the gain range alone (×0.69 to ×1.5) understated.
import math, cmath
import gnckit as g

lam2, b = 0.49, 19.62
kp, kd = 0.8405, 0.2854
wserv, tau = 40.0, 0.03

# loop gain at the plant input: PD controller, gimbal servo 40 rad/s, pure delay 30 ms, rigid pitch plant b/(s^2 - lam2)
def Lf(w, extra=1.0):
    s = 1j * w
    C = kp + kd * s
    return extra * C * wserv / (s + wserv) * cmath.exp(-s * tau) * b / (s * s - lam2)

ws = g.logspace(-2, 3, 20000)
def disk(Lfun):
    peak = max(abs(1 - 2 / (1 + Lfun(w))) for w in ws)       # |T - S| with S = 1/(1+L), T = 1 - S
    alpha = 2 / peak
    gmax = (2 + alpha) / (2 - alpha) if alpha < 2 else float('inf')
    return alpha, (2 - alpha) / (2 + alpha), gmax, math.degrees(2 * math.atan(alpha / 2))

def classical(Lfun):
    # lowest gain crossover and phase margin; gain margin by scanning for phase = -180
    prev = None; pm = None; gm_lo = gm_hi = None
    ph = 0.0; last = None
    for w in ws:
        v = Lfun(w)
        a = math.degrees(cmath.phase(v))
        if last is not None:
            d = a - last
            while d > 180: d -= 360
            while d < -180: d += 360
            ph += d
        else:
            ph = a
        if prev is not None and abs(prev[1]) > 1 >= abs(v) and pm is None:
            pm = 180 + ph
            wc = w
        last = a; prev = (w, v)
    return pm

print('Hopper pitch loop (PD, servo 40 rad/s, 30 ms delay):')
alpha, glo, ghi, ph = disk(Lf)
print(f'  disk margin alpha = {alpha:.3f}: gain from x{glo:.3f} to x{ghi:.3f} and phase +-{ph:.1f} deg, together')
print(f'  loop-at-a-time phase margin {classical(Lf):.1f} deg')
sens = max(abs(1 / (1 + Lf(w))) for w in ws)
print(f'  peak |S| = {sens:.3f}')


class Pert:
    def __init__(self, f):
        self.f = f
    def __call__(self, s):
        C = kp + kd * s
        return self.f * C * wserv / (s + wserv) * cmath.exp(-s * tau) * b / (s * s - lam2)

def stable_with(f):
    # the open loop has one right half-plane pole (+0.7), so stability needs N + 1 = 0 (Z = N + P)
    return g.nyquist_encirclements(Pert(f), w_max=1e3, n=20000) + 1 == 0

ks = [10 ** (i / 40) for i in range(-80, 80)]
okk = [k for k in ks if stable_with(k)]
print(f'loop-at-a-time gain: stable for k from {min(okk):.2f} to {max(okk):.2f} (phase unchanged)')
okp = [p for p in range(0, 120, 2) if stable_with(cmath.exp(-1j * math.radians(p)))]
print(f'loop-at-a-time phase: stable for lags up to {max(okp)} degrees (gain unchanged)')
print('both at once (gain k, phase lag phi):')
for k, phi in ((0.6, 0), (0.6, 30), (0.6, 45), (1.0, 40), (2.0, 40), (2.0, 20), (0.5, 40), (0.7, 40), (0.7, 20), (0.7, 10)):
    f = k * cmath.exp(-1j * math.radians(phi))
    inside = abs(f - (glo + ghi) / 2) <= (ghi - glo) / 2
    print(f'  k = {k:3.1f}, phi = {phi:2.0f} deg: ' + ('stable  ' if stable_with(f) else 'UNSTABLE') + ('  (inside the disk)' if inside else '  (outside the disk)'))

# the observer-based LQG loop of the previous lesson: disk margin from its sensitivity functions
gr = 9.81
A4 = [[0, 1, 0, 0], [0, 0, gr, 0], [0, 0, 0, 1], [0, 0, lam2, 0]]
B4 = [0, gr, 0, b]
C4 = [1, 0, 0, 0]
K4 = g.lqr(A4, [[v] for v in B4], [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 25, 0], [0, 0, 0, 4]], [[1 / 0.15 ** 2]])[0][0]
W0 = [[0, 0, 0, 0], [0, 0.01, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0.01]]
def lqg_loop(Lg):
    Acc = [[A4[i][j] - B4[i] * K4[j] - Lg[i] * C4[j] for j in range(4)] for i in range(4)]
    return lambda w: g.ss_freq(Acc, Lg, K4, 0.0, w) * g.ss_freq(A4, B4, C4, 0.0, w)
print('disk margins of Hopper lateral loops (same weights as the previous lesson):')
Lq = lambda w: g.ss_freq(A4, B4, K4, 0.0, w)
Lk = [row[0] for row in g.kalman_gain(A4, [C4], W0, [[5e-4]])[0]]
rho = 10
Wr = [[W0[i][j] + rho ** 2 * B4[i] * B4[j] for j in range(4)] for i in range(4)]
Lr = [row[0] for row in g.kalman_gain(A4, [C4], Wr, [[5e-4]])[0]]
for name, Lf2 in (('LQR alone', Lq), ('LQG, Kalman observer', lqg_loop(Lk)), ('LQG, recovery rho = 10', lqg_loop(Lr))):
    peak = max(abs(1 - 2 / (1 + Lf2(w))) for w in ws)
    al = 2 / peak
    lo_, hi_ = (2 - al) / (2 + al), ((2 + al) / (2 - al) if al < 2 else float('inf'))
    print(f'  {name:24s} alpha = {al:.3f}, gain x{lo_:.2f} to x{hi_:.2f}, phase +-{math.degrees(2 * math.atan(al / 2)):.0f} deg')
Hopper pitch loop (PD, servo 40 rad/s, 30 ms delay):
  disk margin alpha = 0.827: gain from x0.415 to x2.410 and phase +-44.9 deg, together
  loop-at-a-time phase margin 45.1 deg
  peak |S| = 1.437
loop-at-a-time gain: stable for k from 0.03 to 5.96 (phase unchanged)
loop-at-a-time phase: stable for lags up to 44 degrees (gain unchanged)
both at once (gain k, phase lag phi):
  k = 0.6, phi =  0 deg: stable    (inside the disk)
  k = 0.6, phi = 30 deg: stable    (inside the disk)
  k = 0.6, phi = 45 deg: UNSTABLE  (outside the disk)
  k = 1.0, phi = 40 deg: stable    (inside the disk)
  k = 2.0, phi = 40 deg: stable    (outside the disk)
  k = 2.0, phi = 20 deg: stable    (inside the disk)
  k = 0.5, phi = 40 deg: UNSTABLE  (outside the disk)
  k = 0.7, phi = 40 deg: stable    (inside the disk)
  k = 0.7, phi = 20 deg: stable    (inside the disk)
  k = 0.7, phi = 10 deg: stable    (inside the disk)
disk margins of Hopper lateral loops (same weights as the previous lesson):
  LQR alone                alpha = 1.148, gain x0.27 to x3.69, phase +-60 deg
  LQG, Kalman observer     alpha = 0.215, gain x0.81 to x1.24, phase +-12 deg
  LQG, recovery rho = 10   alpha = 0.962, gain x0.35 to x2.85, phase +-51 deg
The disk margin comes from the peak of |1 - 2S| over a frequency grid; stability of a perturbed loop is tested by counting encirclements with nyquist_encirclements, with one right half-plane open-loop pole.

In robotics

Disk margins are the preferred robustness number in current flight-control practice.

  • Requirements. A requirement such as "a gain variation of ±6 dB and a phase variation of ±45° simultaneously" is a disk margin: it is the standard way, in flight-control specifications, to ask for combined margins instead of two separate numbers.
  • Comparing designs. One number ranks a regulator, an observer-based loop and a schedule on the same scale, as above. It is also the right metric for a tuning search.
  • Multiple loops. For a vehicle with several channels, margins measured one loop at a time can miss variations in two loops at once. The disk margin extends to the multivariable case by treating all channels together, and this is where the single-loop reading fails worst.
  • Uncertainty models. Multiplicative uncertainty 1+Δ1 + \Delta with a bound on ∣Δ(jω)∣|\Delta(j\omega)| that grows with frequency (unmodelled lag, delay, flexible modes) gives a robust-stability test ∣T(jω)∣<1/∣Δ(jω)∣|T(j\omega)| < 1/|\Delta(j\omega)|: the small-gain theorem again.
  • Conservatism. The disk is a sufficient region. A structured analysis (μ-analysis) keeps more of the structure of the uncertainty and is less conservative, at the cost of more computation, and is covered in the references.

The lab M5-L1: Schedule the Gains Through the Burn reports the disk margin of the scheduled loop at several masses, and the delay margin of module 3 remains a good complement for pure delay.

Common misconceptions

“If the gain margin and the phase margin are both good, the loop is robust.”

They check the two axes only. In the example a gain of 0.5 and a lag of 40° are each inside the margins and together unstable. The disk margin tests the combinations.

“The disk margin is the exact boundary of stability.”

It is a sufficient condition. Outside the disk the loop can still be stable (a gain of 2 with 40° is), so the margin is conservative, though safe.

“A large peak of the sensitivity is only a matter of noise amplification.”

It is also the inverse of the distance from the Nyquist curve to −1: the disk margin is bounded by it. A peak of 4.8 (the plain Kalman observer of the last lesson) means a small margin to every kind of variation.

“The disk margin of the LQG loop is that of the LQR.”

The regulator alone has 1.148; the observer-based loop 0.215. The guarantee of the regulator does not pass to the combination, which is the lesson of module 4 stated in one number.

“Margins are about the model being wrong.”

They are about the loop being unable to tolerate any change of gain or phase, whatever its source: a model error, an aged actuator, a changed delay, a sensor with a different lag.

Key takeaways

  1. The disk margin α=2/sup⁡∣T−S∣\alpha = 2/\sup|T - S| guarantees stability for every gain-and-phase variation in a disk.
  2. It gives a gain interval [(2−α)/(2+α), (2+α)/(2−α)][(2-\alpha)/(2+\alpha),\ (2+\alpha)/(2-\alpha)] and a phase variation ±2arctan⁡(α/2)\pm 2\arctan(\alpha/2), together.
  3. It comes from the small-gain theorem: a stable loop with a stable perturbation is stable if the gains multiply to less than the bound.
  4. For Hopper's pitch loop α = 0.83: ×0.415 to ×2.41 and ±45°, while the one-at-a-time ranges are ×0.03 to ×5.96 and 44°.
  5. A gain of 0.5 with 40° is unstable, though each is inside its own margin.
  6. The lateral disk margins are 1.148 (LQR), 0.215 (Kalman LQG) and 0.962 (recovery with ρ = 10).

References and further reading

Each source is marked free or paid. Free to read does not mean free to reuse: the course resources page lists every source with its licence.

  • MathWorks documentation, disk margins , a clear statement of the definition and skew parameter. Free to read; the documentation is copyrighted.
  • K. J. Åström and R. M. Murray, Feedback Systems, 2nd edition, Princeton University Press, 2021 , the chapters on robust performance and the small-gain theorem. Free to read as the authors' PDF; the book is copyrighted.
  • P. Seiler, A. Packard and P. Gahinet, "An introduction to disk margins", IEEE Control Systems Magazine 40(5), 2020, the derivation with skew. Paid (IEEE); the authors' pre-print is on arXiv.
  • S. Skogestad and I. Postlethwaite, Multivariable Feedback Control, 2nd edition, Wiley, 2005, the chapters on uncertainty and robust stability. Paid.

Knowledge check

Three questions. Write an answer, then reveal the explanation. Your answers stay in your browser.

Question 1

A loop has a gain margin of 6 dB each way and a phase margin of 45°. Does that guarantee stability for a gain 4 dB too high and a lag 30° at once?

Explanation

No. The margins test the real axis and the unit circle separately. A gain of +4 dB is a factor of 1.58 and a lag of 30° moves it off the real axis, and the point 1.58·e^(−j30°) is not covered by either test. For Hopper's loop a gain of 0.5 with 40° was unstable though each alone was inside its margin. A disk margin that covers the combination, or a direct test of the point, is needed.

Question 2

The disk margin of Hopper's pitch loop is α = 0.827. What gain interval and phase variation does it guarantee?

Explanation

The gain interval is from (2 − α)/(2 + α) = 1.173/2.827 = 0.415 to (2 + α)/(2 − α) = 2.827/1.173 = 2.41. The phase variation is 2·arctan(α/2) = 2·arctan(0.4135) = 2 · 22.5° = 44.9°. These are guaranteed together: every factor in the disk, not just the points on the axes, leaves the loop stable. Outside the disk the loop may still be stable, since the condition is sufficient.

Question 3

Why does the peak of the sensitivity, 4.76, of the plain Kalman observer loop of module 4 imply a poor disk margin?

Explanation

The sensitivity is 1/(1 + L), the inverse of the distance from the Nyquist curve to −1, so a peak of 4.76 means the curve comes within 0.21 of the critical point. Any perturbation that moves the curve by more than that can destabilize the loop, in any direction, which bounds the disk margin by the same distance: the computed α is 0.215. A large sensitivity peak is a small margin to everything, not only to noise.

What’s next

Next lesson

M6-T1 — What Inertial Sensors Measure

Explain specific force and angular rate, write the sensor error model (bias, scale factor, misalignment, noise), and relate sensor grades to their error sizes.

Nothing below is required to finish this lesson.

  • Before
    M5-T6: Control Allocation

    Distribute a commanded force and moment over more effectors than degrees of freedom, with position and rate limits, and reallocate after one fails.

Other courses on this site treat neighbouring topics from their own angle:

This course leaves the following to the pages that already teach them: