Bode Plots

In [1]:
import control
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['figure.figsize'] = (5, 5)
s = control.tf([1, 0], [0, 1])

Derivative Terms

$ G(s) = s$

In [2]:
G_D = s
control.bode(G_D, dB=True);
G_D
Out[2]:
$$\frac{s}{1}$$

Integral Terms

$ G(s) = \dfrac{1}{s}$

In [3]:
G_I = 1/s
control.bode(G_I, dB=True);
G_I
Out[3]:
$$\frac{1}{s}$$

First Order Zeros

$ G(s) = \dfrac{s + \omega}{\omega}$

In [4]:
G_FZ = (s+1)/1
control.bode(G_FZ, dB=True);
G_FZ
Out[4]:
$$\frac{s + 1}{1}$$

First Order Poles

$ G(s) = \dfrac{\omega}{s + \omega}$

In [5]:
G_FP = 1/(s+1)
control.bode(G_FZ, dB=True);
G_FP
Out[5]:
$$\frac{1}{s + 1}$$

Second Order Poles: Case 1, Real Poles

$G(s) = \dfrac{\omega}{s^2 + 2 \zeta \omega s + \omega_n^2}$

$\zeta >= 1$

Factor into two first order poles.

In [6]:
zeta = 10
wn = 1

G_SR = 1/(s**2 + 2*zeta*wn*s + wn**2)
control.bode(G_SR, dB=True);
print('roots', np.roots([1, 2*zeta*wn, wn**2]))
G_SR
roots [-19.94987437  -0.05012563]
Out[6]:
$$\frac{1}{s^2 + 20 s + 1}$$

Second Order Poles: Case 2, Imaginary Poles

$G(s) = \dfrac{\omega}{s^2 + 2 \zeta \omega s + \omega_n^2}$

$\zeta < 1$

In [7]:
zeta = 0.1
wn = 1

G_SR = 1/(s**2 + 2*zeta*wn*s + wn**2)
G_damp = [1/(s**2 + 2*zeta*wn*s + wn**2) for zeta in np.arange(0.01, 0.9, 0.2)]
control.bode(G_damp, dB=True, omega=np.logspace(-2, 2, 1000));
G_SR
Out[7]:
$$\frac{1}{s^2 + 0.2 s + 1}$$

Unstable Poles and Zeros

  • Same magnitude
  • Oppositive slope

$G(s) = \dfrac{1}{s + 1}$

vs.

$G(s) = \dfrac{1}{s - 1}$

In [8]:
control.bode([1/(s+1), 1/(s-1)], dB=True);
ax = plt.gca()

$G(s) = s + 1$

vs.

$G(s) = s = 1$

In [9]:
control.bode([(s+1), (s-1)], dB=True);

Leading Negative

  • Add 180 deg phase.

$G(s) = -\dfrac{1}{s + 1}$

In [10]:
control.bode([1/(s+1), -1/(s+1)], dB=True);

Bode Plot Rules Summary

  1. Find $|G(0)|$, where your magnitude plot starts and $|G(\infty)|$, where it ends.
  2. Find $\angle G(0)$, where your phase plot starts and $\angle G(\infty)$, where it ends.
  3. Make table of slope and phase contribution for each factor. If you have a second order pole or zero if it has real roots, treat as two first order sytems. If it has complex roots, find the natural frequency and the damping ratio. The damping ratio determines the size of the resonant peak, and the natural frequency is the corner frequency.
  4. Draw asymptotes using $|G(0)|$ to start the magnitude plot and $\angle G(0)$ to start the phase plot.
  5. Interpolate between asymptotes for magnitude and phase.

Zeros:

factor corner freq. (rad/s) phase (deg) slope (dB/dec)
$s$ 0 +90 +20
$(s+\omega)$ $\omega$ +90 +20
$(s-\omega)$ $\omega$ -90 +20
$(s^2 + 2\zeta \omega_n s + \omega_n^2)$ $\omega_n$ +180 +40

Poles:

factor corner freq. (rad/s) phase (deg) slope (dB/dec)
$1/s$ 0 -90 -20
$1/(s+\omega)$ $\omega$ -90 -20
$1/(s-\omega)$ $\omega$ +90 -20
$1/(s^2 + 2\zeta \omega_n s + \omega_n^2)$ $\omega_n$ -180 -40

Combining Factors

$G(s) = \dfrac{-1}{(s-1)(s-2)}$

$|G(0)| = |-1/2| = 1/2 \approx -6 dB$

$\angle G(0) = \angle -1/2 = -180 deg$

factor corner freq. (rad/s) phase (deg) slope (dB/dec)
$1/(s-1)$ 1 +90 -20
$1/(s-2)$ 2 +90 -20

Notice phase contribution of the pole is now positive, since it is an unstable pole.

In [11]:
import control
s = control.tf([1, 0], [0, 1])
control.bode(-1/((s-1)*(s-2)), dB=True);