Skip to content

Commit bde60f5

Browse files
committed
Added display of GM and PM in bode plot. Fixed Hz bug support. Fixed phase limit bug.
1 parent 72ffb63 commit bde60f5

3 files changed

Lines changed: 23 additions & 7 deletions

File tree

control/freqplot.py

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ def bode_plot(syslist, omega=None, dB=None, Hz=None, deg=None,
8686
omega_num: int
8787
number of samples
8888
margins : boolean
89-
if True, plot gain and phase margin
89+
If True, plot gain and phase margin
9090
*args, **kwargs:
9191
Additional options to matplotlib (color, linestyle, etc)
9292
@@ -233,10 +233,14 @@ def bode_plot(syslist, omega=None, dB=None, Hz=None, deg=None,
233233
if margins:
234234
margin = stability_margins(sys)
235235
gm, pm, Wcg, Wcp = margin[0], margin[1], margin[3], margin[4]
236-
if pm >= 0.:
237-
phase_limit = -180.
238-
else:
236+
phase_at_cp = phases[0][(np.abs(omegas[0] - Wcp)).argmin()]
237+
if phase_at_cp >= 0.:
239238
phase_limit = 180.
239+
else:
240+
phase_limit = -180.
241+
242+
if Hz:
243+
Wcg, Wcp = Wcg/(2*math.pi),Wcp/(2*math.pi)
240244

241245
ax_mag.axhline(y=0 if dB else 1, color='k', linestyle=':')
242246
ax_phase.axhline(y=phase_limit if deg else math.radians(phase_limit), color='k', linestyle=':')
@@ -271,7 +275,14 @@ def bode_plot(syslist, omega=None, dB=None, Hz=None, deg=None,
271275

272276
ax_mag.set_ylim(mag_ylim)
273277
ax_phase.set_ylim(phase_ylim)
274-
plt.suptitle('Gm = %.2f %s(at %.2f rad/s), Pm = %.2f %s (at %.2f rad/s)'%(20*np.log10(gm) if dB else gm,'dB ' if dB else '\b',Wcg,pm if deg else math.radians(pm),'deg' if deg else 'rad',Wcp))
278+
279+
if sisotool:
280+
ax_mag.text(0.04, 0.06, 'G.M.: %.2f %s\nFreq: %.2f %s'%(20*np.log10(gm) if dB else gm,'dB ' if dB else '\b',Wcg,'Hz' if Hz else 'rad/s'), horizontalalignment='left', verticalalignment='bottom',
281+
transform=ax_mag.transAxes,fontsize=10)
282+
ax_phase.text(0.04, 0.06, 'P.M.: %.2f %s\nFreq: %.2f %s'%(pm if deg else math.radians(pm),'deg' if deg else 'rad',Wcp,'Hz' if Hz else 'rad/s'), horizontalalignment='left', verticalalignment='bottom',
283+
transform=ax_phase.transAxes,fontsize=10)
284+
else:
285+
plt.suptitle('Gm = %.2f %s(at %.2f %s), Pm = %.2f %s (at %.2f %s)'%(20*np.log10(gm) if dB else gm,'dB ' if dB else '\b','Hz' if Hz else 'rad/s',Wcg,pm if deg else math.radians(pm),'deg' if deg else 'rad',Wcp,'Hz' if Hz else 'rad/s'))
275286

276287
if nyquistfrq_plot:
277288
ax_phase.axvline(nyquistfrq_plot, color=pltline[0].get_color())
@@ -644,6 +655,11 @@ def gen_prefix(pow1000):
644655
'z', # zepto (10^-21)
645656
'y'][8 - pow1000] # yocto (10^-24)
646657

658+
def find_nearest_omega(omega_list, omega):
659+
omega_list = np.asarray(omega_list)
660+
idx = (np.abs(omega_list - omega)).argmin()
661+
return omega_list[(np.abs(omega_list - omega)).argmin()]
662+
647663
# Function aliases
648664
bode = bode_plot
649665
nyquist = nyquist_plot

control/rlocus.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -382,7 +382,6 @@ def _RLFeedbackClicksPoint(event,sys,fig,ax_rlocus=None,sisotool=False):
382382
(nump, denp) = _systopoly1d(sys)
383383
s = complex(event.xdata, event.ydata)
384384
K = -1. / sys.horner(s)
385-
print(K)
386385
if abs(K.real) > 1e-8 and abs(K.imag / K.real) < 0.04 and event.inaxes == ax_rlocus.axes:
387386

388387
# Display the parameters in the output window and figure

control/sisotool.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from .lti import issiso
66
import matplotlib.pyplot as plt
77

8-
def sisotool(sys, kvect = None, xlim = None, ylim = None, plotstr_rlocus = '-',rlocus_grid = False, omega = None, dB = None, Hz = None, deg = None, omega_limits = None, omega_num = None, tvect=None):
8+
def sisotool(sys, kvect = None, xlim = None, ylim = None, plotstr_rlocus = '-',rlocus_grid = False, omega = None, dB = None, Hz = None, deg = None, omega_limits = None, omega_num = None,margins = True, tvect=None):
99

1010
from .rlocus import root_locus
1111

@@ -29,6 +29,7 @@ def sisotool(sys, kvect = None, xlim = None, ylim = None, plotstr_rlocus = '-',r
2929
'omega_num' : omega_num,
3030
'sisotool': True,
3131
'fig': fig,
32+
'margins': margins,
3233
}
3334

3435
# First time call to setup the bode and step response plots

0 commit comments

Comments
 (0)