Stability Analysis
A system is stable if its output stays bounded for any bounded input (BIBO stability). In practice: does the output settle to a steady value, or does it oscillate and grow? Stability analysis tools — Routh-Hurwitz, root locus, Bode plots — answer this question without simulation.
Why It Matters
An unstable control loop is dangerous — oscillations grow until something saturates, breaks, or crashes (literally, for a quadcopter). Before deploying any controller, you need to verify stability and know how much margin you have. Phase margin tells you “how close to instability are we?”
Pole-Based Stability
A linear system is stable iff all poles of the closed-loop transfer function have negative real parts (lie in the left half of the s-plane).
jω
↑
│ ✗ unstable ✓ stable (underdamped)
│ (growing osc) (decaying osc)
──────┼──────────────────→ σ
│ ✗ unstable ✓ stable (underdamped)
│
LEFT HALF = stable RIGHT HALF = unstable
On jω axis = marginally stable (constant oscillation)
- Real poles on negative real axis → exponential decay (no oscillation)
- Complex conjugate poles with negative real part → decaying oscillation
- Poles further left → faster decay
Routh-Hurwitz Criterion
Determines if any poles are in the right half plane without computing them. Build a table from the characteristic polynomial coefficients.
For s³ + 3s² + 3s + 1 = 0:
s³ │ 1 3
s² │ 3 1
s¹ │ (3·3-1·1)/3 = 8/3 0
s⁰ │ 1
Rule: if all entries in the first column are positive, all poles are in the left half plane → stable. Any sign change in the first column = one unstable pole.
Bode Plot Analysis
Plot magnitude and phase of the open-loop transfer function G(jω)H(jω) vs frequency:
import numpy as np
import matplotlib.pyplot as plt
w = np.logspace(-2, 3, 1000)
s = 1j * w
# G(s) = 10 / ((s + 1)(s + 10))
G = 10 / ((s + 1) * (s + 10))
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(8, 6))
ax1.semilogx(w, 20 * np.log10(np.abs(G)))
ax1.set_ylabel('Magnitude (dB)')
ax1.grid(True, which='both')
ax2.semilogx(w, np.angle(G, deg=True))
ax2.set_ylabel('Phase (deg)')
ax2.set_xlabel('Frequency (rad/s)')
ax2.grid(True, which='both')
plt.tight_layout(); plt.show()Stability Margins
| Margin | Definition | Rule of Thumb |
|---|---|---|
| Gain margin | How much gain increase before | G(jω) |
| Phase margin | How much phase lag before phase = -180° at the gain-crossover frequency (where | G |
Magnitude (dB)
│
0dB├──────────────╱──── gain crossover frequency (ωgc)
│ ╱ ↓ phase margin read here
│
Phase (deg)
│
-180°├────────────────╱── phase crossover frequency (ωpc)
│ ╱ ↑ gain margin read here
Phase margin ≈ damping: 45° ≈ ζ = 0.42 (good), 60° ≈ ζ = 0.58 (better), 30° ≈ ζ = 0.3 (oscillatory but stable).
Root Locus
Plots how closed-loop poles move as a gain parameter K varies from 0 to ∞. Useful for tuning controller gain.
As K increases:
× poles start at open-loop pole locations (K=0)
× poles move along locus paths
× poles may cross into right half plane → instability at critical K
○ poles end at zero locations or at infinity (K→∞)
Root locus tells you the maximum gain before instability. In Python:
from scipy import signal
import control # pip install control
# Open-loop: G(s) = 1 / (s(s+1)(s+2))
sys = control.tf([1], [1, 3, 2, 0])
control.root_locus(sys)
plt.show()Stability in Discrete Systems
For digital control (z-domain), stability requires all poles inside the unit circle |z| < 1 (instead of left half plane).
z-plane:
Continuous s-plane left half ↔ inside unit circle
jω axis ↔ unit circle boundary
Right half plane ↔ outside unit circle
Mapping: z = e^(sT) where T is the sampling period. A pole at s = -a maps to z = e^(-aT). As long as a > 0, |z| < 1.
Nyquist Criterion (Brief)
For systems where Bode analysis is ambiguous (open-loop unstable, non-minimum phase), Nyquist plots the full frequency response as a curve in the complex plane. The number of clockwise encirclements of the point (-1, 0) determines closed-loop stability. More advanced than Bode, but handles all linear cases.
Related
- Transfer Functions — poles and zeros determine stability
- PID Controller — stability margins guide PID tuning
- Open Loop vs Closed Loop — closed loop can stabilize unstable plants
- Digital Control — unit circle stability criterion
- State Space Representation — eigenvalues of A are the poles