|
17 | 17 | from .exception import ControlMIMONotImplemented |
18 | 18 | from .iosys import issiso |
19 | 19 | from . import ss |
| 20 | +from .ctrlutil import mag2db |
20 | 21 | try: |
21 | 22 | from slycot import ab13md |
22 | 23 | except ImportError: |
23 | 24 | ab13md = None |
24 | | -try: |
25 | | - from . import mag2db |
26 | | -except ImportError: |
27 | | - # Likely due the following circular import issue: |
28 | | - # |
29 | | - # ImportError: cannot import name 'mag2db' from partially initialized module |
30 | | - # 'control' (most likely due to a circular import) (control/__init__.py) |
31 | | - # |
32 | | - def mag2db(mag): |
33 | | - return 20*np.log10(mag) |
34 | 25 |
|
35 | 26 | __all__ = ['stability_margins', 'phase_crossover_frequencies', 'margin', 'disk_margins', 'disk_margin_plot'] |
36 | 27 |
|
@@ -567,52 +558,20 @@ def disk_margins(L, omega, skew = 0.0, returnall = False): |
567 | 558 |
|
568 | 559 | Examples |
569 | 560 | -------- |
570 | | - >> import control |
571 | | - >> import numpy as np |
572 | | - >> import matplotlib |
573 | | - >> import matplotlib.pyplot as plt |
574 | | - >> |
575 | | - >> omega = np.logspace(-1, 3, 1001) |
| 561 | + >> omega = np.logspace(-1, 3, 1001) # frequencies of interest (rad/s) |
| 562 | + >> P = control.ss([[0,10],[-10,0]],np.eye(2),[[1,10],[-10,1]],[[0,0],[0,0]]) # plant |
| 563 | + >> K = control.ss([],[],[],[[1,-2],[0,1]]) # controller |
| 564 | + >> L = P*K # output loop gain |
576 | 565 | >> |
577 | | - >> P = control.ss([[0, 10],[-10, 0]], np.eye(2), [[1, 10], [-10, 1]], [[0, 0],[0, 0]]) |
578 | | - >> K = control.ss([],[],[], [[1, -2], [0, 1]]) |
579 | | - >> L = P*K |
| 566 | + >> DM, GM, PM = control.disk_margins(L, omega, skew = 0.0, returnall = False) |
| 567 | + >> print(f"DM = {DM}") |
| 568 | + >> print(f"GM = {GM} dB") |
| 569 | + >> print(f"PM = {PM} deg\n") |
580 | 570 | >> |
581 | | - >> DM, GM, PM = control.disk_margins(L, omega, skew = 0.0, returnall = True) # balanced (S - T) |
| 571 | + >> DM, GM, PM = control.disk_margins(L, omega, skew = 0.0, returnall = True) |
582 | 572 | >> print(f"min(DM) = {min(DM)} (omega = {omega[np.argmin(DM)]})") |
583 | 573 | >> print(f"GM = {GM[np.argmin(DM)]} dB") |
584 | 574 | >> print(f"PM = {PM[np.argmin(DM)]} deg\n") |
585 | | - >> |
586 | | - >> plt.figure(1) |
587 | | - >> plt.subplot(3,1,1) |
588 | | - >> plt.semilogx(omega, DM, label='$\\alpha$') |
589 | | - >> plt.legend() |
590 | | - >> plt.title('Disk Margin') |
591 | | - >> plt.grid() |
592 | | - >> plt.tight_layout() |
593 | | - >> plt.xlim([omega[0], omega[-1]]) |
594 | | - >> |
595 | | - >> plt.figure(1) |
596 | | - >> plt.subplot(3,1,2) |
597 | | - >> plt.semilogx(omega, GM, label='$\\gamma_{m}$') |
598 | | - >> plt.ylabel('Gain Margin (dB)') |
599 | | - >> plt.legend() |
600 | | - >> plt.title('Disk-Based Gain Margin') |
601 | | - >> plt.grid() |
602 | | - >> plt.ylim([0, 40]) |
603 | | - >> plt.tight_layout() |
604 | | - >> plt.xlim([omega[0], omega[-1]]) |
605 | | - >> |
606 | | - >> plt.figure(1) |
607 | | - >> plt.subplot(3,1,3) |
608 | | - >> plt.semilogx(omega, PM, label='$\\phi_{m}$') |
609 | | - >> plt.ylabel('Phase Margin (deg)') |
610 | | - >> plt.legend() |
611 | | - >> plt.title('Disk-Based Phase Margin') |
612 | | - >> plt.grid() |
613 | | - >> plt.ylim([0, 90]) |
614 | | - >> plt.tight_layout() |
615 | | - >> plt.xlim([omega[0], omega[-1]]) |
616 | 575 |
|
617 | 576 | References |
618 | 577 | ---------- |
|
0 commit comments