|
2 | 2 | Demonstrate disk-based stability margin calculations.
|
3 | 3 | """
|
4 | 4 |
|
5 |
| -importos,sys,math |
6 |
| -importnumpyasnp |
7 |
| -importcontrol |
8 |
| - |
| 5 | +importos |
9 | 6 | importmath
|
10 |
| -importmatplotlibasmpl |
| 7 | +importcontrol |
| 8 | +importmatplotlib |
11 | 9 | importmatplotlib.pyplotasplt
|
12 |
| -fromwarningsimportwarn |
13 |
| - |
14 | 10 | importnumpyasnp
|
15 |
| -importscipyassp |
16 | 11 |
|
17 | 12 | defplot_allowable_region(alpha_max,skew,ax=None):
|
18 | 13 | """Plot region of allowable gain/phase variation, given worst-case disk margin.
|
@@ -122,19 +117,16 @@ def test_siso1():
|
122 | 117 | # Frequencies of interest
|
123 | 118 | omega=np.logspace(-1,2,1001)
|
124 | 119 |
|
125 |
| -# Laplace variable |
126 |
| -s=control.tf('s') |
127 |
| - |
128 | 120 | # Loop transfer gain
|
129 | 121 | L=control.tf(25, [1,10,10,10])
|
130 | 122 |
|
131 |
| -print(f"------------- Python control built-in (S) -------------") |
| 123 | +print("------------- Python control built-in (S) -------------") |
132 | 124 | GM_,PM_,SM_=control.stability_margins(L)[:3]# python-control default (S-based...?)
|
133 | 125 | print(f"SM_ ={SM_}")
|
134 | 126 | print(f"GM_ ={GM_} dB")
|
135 | 127 | print(f"PM_ ={PM_} deg\n")
|
136 | 128 |
|
137 |
| -print(f"------------- Sensitivity function (S) -------------") |
| 129 | +print("------------- Sensitivity function (S) -------------") |
138 | 130 | DM,GM,PM=control.disk_margins(L,omega,skew=1.0,returnall=True)# S-based (S)
|
139 | 131 | print(f"min(DM) ={min(DM)} (omega ={omega[np.argmin(DM)]})")
|
140 | 132 | print(f"GM ={GM[np.argmin(DM)]} dB")
|
@@ -173,7 +165,7 @@ def test_siso1():
|
173 | 165 | plt.ylim([0,90])
|
174 | 166 | plt.xlabel('Frequency (rad/s)')
|
175 | 167 |
|
176 |
| -print(f"------------- Complementary sensitivity function (T) -------------") |
| 168 | +print("------------- Complementary sensitivity function (T) -------------") |
177 | 169 | DM,GM,PM=control.disk_margins(L,omega,skew=-1.0,returnall=True)# T-based (T)
|
178 | 170 | print(f"min(DM) ={min(DM)} (omega ={omega[np.argmin(DM)]})")
|
179 | 171 | print(f"GM ={GM[np.argmin(DM)]} dB")
|
@@ -212,7 +204,7 @@ def test_siso1():
|
212 | 204 | plt.ylim([0,90])
|
213 | 205 | plt.xlabel('Frequency (rad/s)')
|
214 | 206 |
|
215 |
| -print(f"------------- Balanced sensitivity function (S - T) -------------") |
| 207 | +print("------------- Balanced sensitivity function (S - T) -------------") |
216 | 208 | DM,GM,PM=control.disk_margins(L,omega,skew=0.0,returnall=True)# balanced (S - T)
|
217 | 209 | print(f"min(DM) ={min(DM)} (omega ={omega[np.argmin(DM)]})")
|
218 | 210 | print(f"GM ={GM[np.argmin(DM)]} dB")
|
@@ -276,13 +268,13 @@ def test_siso2():
|
276 | 268 | # Loop transfer gain
|
277 | 269 | L= (6.25*(s+3)*(s+5))/(s*(s+1)**2*(s**2+0.18*s+100))
|
278 | 270 |
|
279 |
| -print(f"------------- Python control built-in (S) -------------") |
| 271 | +print("------------- Python control built-in (S) -------------") |
280 | 272 | GM_,PM_,SM_=control.stability_margins(L)[:3]# python-control default (S-based...?)
|
281 | 273 | print(f"SM_ ={SM_}")
|
282 | 274 | print(f"GM_ ={GM_} dB")
|
283 | 275 | print(f"PM_ ={PM_} deg\n")
|
284 | 276 |
|
285 |
| -print(f"------------- Sensitivity function (S) -------------") |
| 277 | +print("------------- Sensitivity function (S) -------------") |
286 | 278 | DM,GM,PM=control.disk_margins(L,omega,skew=1.0,returnall=True)# S-based (S)
|
287 | 279 | print(f"min(DM) ={min(DM)} (omega ={omega[np.argmin(DM)]})")
|
288 | 280 | print(f"GM ={GM[np.argmin(DM)]} dB")
|
@@ -321,7 +313,7 @@ def test_siso2():
|
321 | 313 | plt.ylim([0,90])
|
322 | 314 | plt.xlabel('Frequency (rad/s)')
|
323 | 315 |
|
324 |
| -print(f"------------- Complementary sensitivity function (T) -------------") |
| 316 | +print("------------- Complementary sensitivity function (T) -------------") |
325 | 317 | DM,GM,PM=control.disk_margins(L,omega,skew=-1.0,returnall=True)# T-based (T)
|
326 | 318 | print(f"min(DM) ={min(DM)} (omega ={omega[np.argmin(DM)]})")
|
327 | 319 | print(f"GM ={GM[np.argmin(DM)]} dB")
|
@@ -360,7 +352,7 @@ def test_siso2():
|
360 | 352 | plt.ylim([0,90])
|
361 | 353 | plt.xlabel('Frequency (rad/s)')
|
362 | 354 |
|
363 |
| -print(f"------------- Balanced sensitivity function (S - T) -------------") |
| 355 | +print("------------- Balanced sensitivity function (S - T) -------------") |
364 | 356 | DM,GM,PM=control.disk_margins(L,omega,skew=0.0,returnall=True)# balanced (S - T)
|
365 | 357 | print(f"min(DM) ={min(DM)} (omega ={omega[np.argmin(DM)]})")
|
366 | 358 | print(f"GM ={GM[np.argmin(DM)]} dB")
|
@@ -419,15 +411,12 @@ def test_mimo():
|
419 | 411 | # Frequencies of interest
|
420 | 412 | omega=np.logspace(-1,3,1001)
|
421 | 413 |
|
422 |
| -# Laplace variable |
423 |
| -s=control.tf('s') |
424 |
| - |
425 | 414 | # Loop transfer gain
|
426 | 415 | P=control.ss([[0,10],[-10,0]],np.eye(2), [[1,10], [-10,1]], [[0,0],[0,0]])# plant
|
427 | 416 | K=control.ss([],[],[], [[1,-2], [0,1]])# controller
|
428 | 417 | L=P*K# loop gain
|
429 | 418 |
|
430 |
| -print(f"------------- Sensitivity function (S) -------------") |
| 419 | +print("------------- Sensitivity function (S) -------------") |
431 | 420 | DM,GM,PM=control.disk_margins(L,omega,skew=1.0,returnall=True)# S-based (S)
|
432 | 421 | print(f"min(DM) ={min(DM)} (omega ={omega[np.argmin(DM)]})")
|
433 | 422 | print(f"GM ={GM[np.argmin(DM)]} dB")
|
@@ -466,7 +455,7 @@ def test_mimo():
|
466 | 455 | plt.ylim([0,90])
|
467 | 456 | plt.xlabel('Frequency (rad/s)')
|
468 | 457 |
|
469 |
| -print(f"------------- Complementary sensitivity function (T) -------------") |
| 458 | +print("------------- Complementary sensitivity function (T) -------------") |
470 | 459 | DM,GM,PM=control.disk_margins(L,omega,skew=-1.0,returnall=True)# T-based (T)
|
471 | 460 | print(f"min(DM) ={min(DM)} (omega ={omega[np.argmin(DM)]})")
|
472 | 461 | print(f"GM ={GM[np.argmin(DM)]} dB")
|
@@ -505,7 +494,7 @@ def test_mimo():
|
505 | 494 | plt.ylim([0,90])
|
506 | 495 | plt.xlabel('Frequency (rad/s)')
|
507 | 496 |
|
508 |
| -print(f"------------- Balanced sensitivity function (S - T) -------------") |
| 497 | +print("------------- Balanced sensitivity function (S - T) -------------") |
509 | 498 | DM,GM,PM=control.disk_margins(L,omega,skew=0.0,returnall=True)# balanced (S - T)
|
510 | 499 | print(f"min(DM) ={min(DM)} (omega ={omega[np.argmin(DM)]})")
|
511 | 500 | print(f"GM ={GM[np.argmin(DM)]} dB")
|
|