forked from alchemyst/Skogestad-Python
/
BODE.py
79 lines (57 loc) · 1.93 KB
/
BODE.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
import numpy as np
import scipy as sc
import scipy.signal as scs
import matplotlib.pyplot as plt
from utils import phase, tf
G = tf(8, [1, 8]) * tf(1, [1, 1])
# freq(G) returns a frequency response function given a Laplace function
def freq(G):
def Gw(w):
return G(1j*w)
return Gw
def margins(G):
""" Calculate the gain margin and phase margin of a system.
Input: G - a function of s
Outputs:
GM Gain margin
PM Phase margin
wc Gain crossover frequency
w_180 Phase Crossover frequency
"""
Gw = freq(G)
def mod(x):
"""to give the function to calculate |G(jw)| = 1"""
return np.abs(Gw(x)) - 1
# how to calculate the freqeuncy at which |G(jw)| = 1
wc = sc.optimize.fsolve(mod, 0.1)
def arg(w):
"""function to calculate the phase angle at -180 deg"""
return np.angle(Gw(w)) + np.pi
# where the freqeuncy is calculated where arg G(jw) = -180 deg
w_180 = sc.optimize.fsolve(arg, -1)
PM = np.angle(Gw(wc), deg=True) + 180
GM = 1/(np.abs(Gw(w_180)))
return GM, PM, wc, w_180
def Bode(G):
"""give the Bode plot along with GM and PM"""
GM, PM, wc, w_180 = margins(G)
# plotting of Bode plot and with corresponding freqeuncies for PM and GM
w = np.logspace(-5, np.log(w_180), 1000)
s = 1j*w
plt.subplot(211)
gains = np.abs(G(s))
plt.loglog(w, gains)
plt.loglog(wc*np.ones(2), [np.max(gains), np.min(gains)])
plt.text(w_180, np.average([np.max(gains), np.min(gains)]), '<G(jw) = -180 Deg')
plt.loglog(w_180*np.ones(2), [np.max(gains), np.min(gains)])
plt.loglog(w, 1*np.ones(len(w)))
# argument of G
plt.subplot(212)
phaseangle = phase(G(s), deg=True)
plt.semilogx(w, phaseangle)
plt.semilogx(wc*np.ones(2), [np.max(phaseangle), np.min(phaseangle)])
plt.semilogx(w_180*np.ones(2), [-180, 0])
plt.show()
return GM, PM
[GM, PM] = Bode(G)
print GM, PM