@@ -80,7 +80,7 @@ def _polysqr(pol):
8080# idea for the frequency data solution copied/adapted from
8181# https://github.com/alchemyst/Skogestad-Python/blob/master/BODE.py
8282# 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 ):
8484 """Calculate gain, phase and stability margins and associated
8585 crossover frequencies.
8686
@@ -101,6 +101,9 @@ def stability_margins(sysdata, deg=True, returnall=False):
101101 returnall=False: boolean
102102 If true, return all margins found. Note that for frequency data or
103103 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.
104107
105108 Returns
106109 -------
@@ -113,7 +116,7 @@ def stability_margins(sysdata, deg=True, returnall=False):
113116 When requesting all margins, the return values are array_like,
114117 and all margins are returns for linear systems not equal to FRD
115118 """
116-
119+
117120 try :
118121 if isinstance (sysdata , frdata .FRD ):
119122 sys = frdata .FRD (sysdata , smooth = True )
@@ -143,14 +146,14 @@ def stability_margins(sysdata, deg=True, returnall=False):
143146 # test imaginary part of tf == 0, for phase crossover/gain margins
144147 test_w_180 = np .polyadd (np .polymul (inum , rden ), np .polymul (rnum , - iden ))
145148 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 )])
147150 w_180 .sort ()
148151
149152 # test magnitude is 1 for gain crossover/phase margins
150153 test_wc = np .polysub (np .polyadd (_polysqr (rnum ), _polysqr (inum )),
151154 np .polyadd (_polysqr (rden ), _polysqr (iden )))
152155 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 )])
154157 wc .sort ()
155158
156159 # stability margin was a bitch to elaborate, relies on magnitude to
@@ -168,7 +171,7 @@ def stability_margins(sysdata, deg=True, returnall=False):
168171
169172 # and find the value of the 2nd derivative there, needs to be positive
170173 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 ) *
172175 (np .abs (wstabplus ) > 0. )])
173176 wstab .sort ()
174177
0 commit comments