Skip to content

Commit 73ce1a6

Browse files
committed
allow specified frequency range to exceed nyquist frequency if desired
1 parent 24d57e1 commit 73ce1a6

File tree

1 file changed

+48
-36
lines changed

1 file changed

+48
-36
lines changed

control/freqplot.py

Lines changed: 48 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -194,28 +194,25 @@ def bode_plot(syslist, omega=None,
194194
if not hasattr(syslist, '__iter__'):
195195
syslist = (syslist,)
196196

197+
# decide whether to go above nyquist. freq
198+
omega_range_given = True if omega is not None else False
197199

198200
if omega is None:
199-
omega_was_given = False # used do decide whether to include nyq. freq
201+
omega_num = config._get_param('freqplot','number_of_samples', omega_num)
200202
if omega_limits is None:
201203
# Select a default range if none is provided
202-
omega = _default_frequency_range(syslist, Hz=Hz,
203-
number_of_samples=omega_num)
204+
omega = _default_frequency_range(syslist,
205+
number_of_samples=omega_num)
204206
else:
207+
omega_range_given = True
205208
omega_limits = np.asarray(omega_limits)
206209
if len(omega_limits) != 2:
207210
raise ValueError("len(omega_limits) must be 2")
208211
if Hz:
209212
omega_limits *= 2. * math.pi
210-
if omega_num:
211-
num = omega_num
212-
else:
213-
num = config.defaults['freqplot.number_of_samples']
214213
omega = np.logspace(np.log10(omega_limits[0]),
215-
np.log10(omega_limits[1]), num=num,
214+
np.log10(omega_limits[1]), num=omega_num,
216215
endpoint=True)
217-
else:
218-
omega_was_given = True
219216

220217
if plot:
221218
# Set up the axes with labels so that multiple calls to
@@ -264,12 +261,11 @@ def bode_plot(syslist, omega=None,
264261
else:
265262
omega_sys = np.asarray(omega)
266263
if sys.isdtime(strict=True):
267-
nyquistfrq = 2. * math.pi * 1. / sys.dt / 2.
268-
if not omega_was_given:
269-
# include nyquist frequency
264+
nyquistfrq = math.pi / sys.dt
265+
if not omega_range_given:
266+
# limit up to and including nyquist frequency
270267
omega_sys = np.hstack((
271-
omega_sys[omega_sys < nyquistfrq],
272-
nyquistfrq))
268+
omega_sys[omega_sys < nyquistfrq], nyquistfrq))
273269
else:
274270
nyquistfrq = None
275271

@@ -332,21 +328,27 @@ def bode_plot(syslist, omega=None,
332328
nyquistfrq_plot = nyquistfrq
333329
phase_plot = phase * 180. / math.pi if deg else phase
334330
mag_plot = mag
335-
#
336-
# Magnitude plot
337-
#
338331

339332
if nyquistfrq_plot:
340-
# add data for vertical nyquist freq indicator line
341-
# so it is a single plot action. This preserves line
342-
# order when creating legend eg. legend('sys1', 'sys2)
343-
omega_plot = np.hstack((omega_plot, nyquistfrq,nyquistfrq))
344-
mag_plot = np.hstack((mag_plot,
345-
0.7*min(mag_plot),1.3*max(mag_plot)))
333+
# append data for vertical nyquist freq indicator line.
334+
# if this extra nyquist lime is is plotted in a single plot
335+
# command then line order is preserved when
336+
# creating a legend eg. legend(('sys1', 'sys2'))
337+
omega_nyq_line = np.array((np.nan, nyquistfrq, nyquistfrq))
338+
omega_plot = np.hstack((omega_plot, omega_nyq_line))
339+
mag_nyq_line = np.array((
340+
np.nan, 0.7*min(mag_plot), 1.3*max(mag_plot)))
341+
mag_plot = np.hstack((mag_plot, mag_nyq_line))
346342
phase_range = max(phase_plot) - min(phase_plot)
347-
phase_plot = np.hstack((phase_plot,
343+
phase_nyq_line = np.array((np.nan,
348344
min(phase_plot) - 0.2 * phase_range,
349345
max(phase_plot) + 0.2 * phase_range))
346+
phase_plot = np.hstack((phase_plot, phase_nyq_line))
347+
348+
#
349+
# Magnitude plot
350+
#
351+
350352
if dB:
351353
ax_mag.semilogx(omega_plot, 20 * np.log10(mag_plot),
352354
*args, **kwargs)
@@ -535,8 +537,8 @@ def nyquist_plot(syslist, omega=None, plot=True, omega_limits=None,
535537
omega : array_like
536538
Set of frequencies to be evaluated in rad/sec.
537539
omega_limits : array_like of two values
538-
Limits to the range of frequencies. Ignored if omega
539-
is provided, and auto-generated if omitted.
540+
Limits to the range of frequencies. Ignored if omega
541+
is provided, and auto-generated if omitted.
540542
omega_num : int
541543
Number of samples to plot. Defaults to
542544
config.defaults['freqplot.number_of_samples'].
@@ -588,33 +590,43 @@ def nyquist_plot(syslist, omega=None, plot=True, omega_limits=None,
588590
if not hasattr(syslist, '__iter__'):
589591
syslist = (syslist,)
590592

591-
# Select a default range if none is provided
593+
# decide whether to go above nyquist. freq
594+
omega_range_given = True if omega is not None else False
595+
592596
if omega is None:
597+
omega_num = config._get_param('freqplot','number_of_samples',omega_num)
593598
if omega_limits is None:
594599
# Select a default range if none is provided
595-
omega = _default_frequency_range(syslist, Hz=False,
596-
number_of_samples=omega_num)
600+
omega = _default_frequency_range(syslist,
601+
number_of_samples=omega_num)
597602
else:
603+
omega_range_given = True
598604
omega_limits = np.asarray(omega_limits)
599605
if len(omega_limits) != 2:
600606
raise ValueError("len(omega_limits) must be 2")
601-
num = \
602-
ct.config._get_param('freqplot','number_of_samples', omega_num)
603607
omega = np.logspace(np.log10(omega_limits[0]),
604-
np.log10(omega_limits[1]), num=num,
608+
np.log10(omega_limits[1]), num=omega_num,
605609
endpoint=True)
606610

607611
xs, ys, omegas = [], [], []
608612
for sys in syslist:
609-
mag, phase, omega = sys.frequency_response(omega)
613+
omega_sys = np.asarray(omega)
614+
if sys.isdtime(strict=True):
615+
nyquistfrq = math.pi / sys.dt
616+
if not omega_range_given:
617+
# limit up to and including nyquist frequency
618+
omega_sys = np.hstack((
619+
omega_sys[omega_sys < nyquistfrq], nyquistfrq))
620+
621+
mag, phase, omega_sys = sys.frequency_response(omega_sys)
610622

611623
# Compute the primary curve
612624
x = mag * np.cos(phase)
613625
y = mag * np.sin(phase)
614626

615627
xs.append(x)
616628
ys.append(y)
617-
omegas.append(omega)
629+
omegas.append(omega_sys)
618630

619631
if plot:
620632
if not sys.issiso():
@@ -642,7 +654,7 @@ def nyquist_plot(syslist, omega=None, plot=True, omega_limits=None,
642654
# Label the frequencies of the points
643655
if label_freq:
644656
ind = slice(None, None, label_freq)
645-
for xpt, ypt, omegapt in zip(x[ind], y[ind], omega[ind]):
657+
for xpt, ypt, omegapt in zip(x[ind], y[ind], omega_sys[ind]):
646658
# Convert to Hz
647659
f = omegapt / (2 * np.pi)
648660

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy