|
2 | 2 | Demonstrate disk-based stability margin calculations.
|
3 | 3 | """
|
4 | 4 |
|
5 |
| -import os, sys, math |
6 |
| -import numpy as np |
7 |
| -import control |
8 |
| - |
| 5 | +import os |
9 | 6 | import math
|
10 |
| -import matplotlib as mpl |
| 7 | +import control |
| 8 | +import matplotlib |
11 | 9 | import matplotlib.pyplot as plt
|
12 |
| -from warnings import warn |
13 |
| - |
14 | 10 | import numpy as np
|
15 |
| -import scipy as sp |
16 | 11 |
|
17 | 12 | def plot_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")
|
|
0 commit comments