@@ -80,7 +80,7 @@ def _polysqr(pol):
80
80
# idea for the frequency data solution copied/adapted from
81
81
# https://github.com/alchemyst/Skogestad-Python/blob/master/BODE.py
82
82
# Rene van Paassen <rene.vanpaassen@gmail.com>
83
- def stability_margins (sysdata , deg = True , returnall = False ):
83
+ def stability_margins (sysdata , deg = True , returnall = False , epsw = 1e-12 ):
84
84
"""Calculate gain, phase and stability margins and associated
85
85
crossover frequencies.
86
86
@@ -101,6 +101,9 @@ def stability_margins(sysdata, deg=True, returnall=False):
101
101
returnall=False: boolean
102
102
If true, return all margins found. Note that for frequency data or
103
103
FRD systems, only one margin is found and returned.
104
+ epsw=1e-12: float
105
+ frequencies below this value are considered static gain, and not
106
+ returned as margin.
104
107
105
108
Returns
106
109
-------
@@ -113,7 +116,7 @@ def stability_margins(sysdata, deg=True, returnall=False):
113
116
When requesting all margins, the return values are array_like,
114
117
and all margins are returns for linear systems not equal to FRD
115
118
"""
116
-
119
+
117
120
try :
118
121
if isinstance (sysdata , frdata .FRD ):
119
122
sys = frdata .FRD (sysdata , smooth = True )
@@ -143,14 +146,14 @@ def stability_margins(sysdata, deg=True, returnall=False):
143
146
# test imaginary part of tf == 0, for phase crossover/gain margins
144
147
test_w_180 = np .polyadd (np .polymul (inum , rden ), np .polymul (rnum , - iden ))
145
148
w_180 = np .roots (test_w_180 )
146
- w_180 = np .real (w_180 [(np .imag (w_180 ) == 0 ) * (w_180 > 0. )])
149
+ w_180 = np .real (w_180 [(np .imag (w_180 ) == 0 ) * (w_180 > epsw )])
147
150
w_180 .sort ()
148
151
149
152
# test magnitude is 1 for gain crossover/phase margins
150
153
test_wc = np .polysub (np .polyadd (_polysqr (rnum ), _polysqr (inum )),
151
154
np .polyadd (_polysqr (rden ), _polysqr (iden )))
152
155
wc = np .roots (test_wc )
153
- wc = np .real (wc [(np .imag (wc ) == 0 ) * (wc > 0. )])
156
+ wc = np .real (wc [(np .imag (wc ) == 0 ) * (wc > epsw )])
154
157
wc .sort ()
155
158
156
159
# stability margin was a bitch to elaborate, relies on magnitude to
@@ -168,7 +171,7 @@ def stability_margins(sysdata, deg=True, returnall=False):
168
171
169
172
# and find the value of the 2nd derivative there, needs to be positive
170
173
wstabplus = np .polyval (np .polyder (test_wstab ), wstab )
171
- wstab = np .real (wstab [(np .imag (wstab ) == 0 ) * (wstab > 0. ) *
174
+ wstab = np .real (wstab [(np .imag (wstab ) == 0 ) * (wstab > epsw ) *
172
175
(np .abs (wstabplus ) > 0. )])
173
176
wstab .sort ()
174
177
0 commit comments