|
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