# 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);


$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);