Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitdf6b352

Browse files
authored
Merge pull request#688 from bnavigator/omega_default_round
Round to nearest integer decade for default omega vector
2 parentsa111b03 +021372f commitdf6b352

File tree

3 files changed

+46
-28
lines changed

3 files changed

+46
-28
lines changed

‎control/freqplot.py

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ def bode_plot(syslist, omega=None,
209209
syslist= (syslist,)
210210

211211
omega,omega_range_given=_determine_omega_vector(
212-
syslist,omega,omega_limits,omega_num)
212+
syslist,omega,omega_limits,omega_num,Hz=Hz)
213213

214214
ifplot:
215215
# Set up the axes with labels so that multiple calls to
@@ -965,7 +965,7 @@ def gangof4_plot(P, C, omega=None, **kwargs):
965965
# Select a default range if none is provided
966966
# TODO: This needs to be made more intelligent
967967
ifomegaisNone:
968-
omega=_default_frequency_range((P,C,S))
968+
omega=_default_frequency_range((P,C,S),Hz=Hz)
969969

970970
# Set up the axes with labels so that multiple calls to
971971
# gangof4_plot will superimpose the data. See details in bode_plot.
@@ -1115,7 +1115,7 @@ def singular_values_plot(syslist, omega=None,
11151115
syslist= (syslist,)
11161116

11171117
omega,omega_range_given=_determine_omega_vector(
1118-
syslist,omega,omega_limits,omega_num)
1118+
syslist,omega,omega_limits,omega_num,Hz=Hz)
11191119

11201120
omega=np.atleast_1d(omega)
11211121

@@ -1210,7 +1210,8 @@ def singular_values_plot(syslist, omega=None,
12101210

12111211

12121212
# Determine the frequency range to be used
1213-
def_determine_omega_vector(syslist,omega_in,omega_limits,omega_num):
1213+
def_determine_omega_vector(syslist,omega_in,omega_limits,omega_num,
1214+
Hz=None):
12141215
"""Determine the frequency range for a frequency-domain plot
12151216
according to a standard logic.
12161217
@@ -1236,6 +1237,10 @@ def _determine_omega_vector(syslist, omega_in, omega_limits, omega_num):
12361237
omega_num : int
12371238
Number of points to be used for the frequency
12381239
range (if the frequency range is not user-specified)
1240+
Hz : bool, optional
1241+
If True, the limits (first and last value) of the frequencies
1242+
are set to full decades in Hz so it fits plotting with logarithmic
1243+
scale in Hz otherwise in rad/s. Omega is always returned in rad/sec.
12391244
12401245
Returns
12411246
-------
@@ -1253,7 +1258,8 @@ def _determine_omega_vector(syslist, omega_in, omega_limits, omega_num):
12531258
omega_range_given=False
12541259
# Select a default range if none is provided
12551260
omega_out=_default_frequency_range(syslist,
1256-
number_of_samples=omega_num)
1261+
number_of_samples=omega_num,
1262+
Hz=Hz)
12571263
else:
12581264
omega_limits=np.asarray(omega_limits)
12591265
iflen(omega_limits)!=2:
@@ -1280,7 +1286,7 @@ def _default_frequency_range(syslist, Hz=None, number_of_samples=None,
12801286
----------
12811287
syslist : list of LTI
12821288
List of linear input/output systems (single system is OK)
1283-
Hz : bool
1289+
Hz : bool, optional
12841290
If True, the limits (first and last value) of the frequencies
12851291
are set to full decades in Hz so it fits plotting with logarithmic
12861292
scale in Hz otherwise in rad/s. Omega is always returned in rad/sec.
@@ -1326,7 +1332,7 @@ def _default_frequency_range(syslist, Hz=None, number_of_samples=None,
13261332
features_=np.concatenate((np.abs(sys.pole()),
13271333
np.abs(sys.zero())))
13281334
# Get rid of poles and zeros at the origin
1329-
toreplace=features_==0.0
1335+
toreplace=np.isclose(features_,0.0)
13301336
ifnp.any(toreplace):
13311337
features_=features_[~toreplace]
13321338
elifsys.isdtime(strict=True):
@@ -1339,7 +1345,7 @@ def _default_frequency_range(syslist, Hz=None, number_of_samples=None,
13391345
# Get rid of poles and zeros on the real axis (imag==0)
13401346
# * origin and real < 0
13411347
# * at 1.: would result in omega=0. (logaritmic plot!)
1342-
toreplace= (features_.imag==0.0)& (
1348+
toreplace=np.isclose(features_.imag,0.0)& (
13431349
(features_.real<=0.)|
13441350
(np.abs(features_.real-1.0)<1.e-10))
13451351
ifnp.any(toreplace):
@@ -1360,15 +1366,13 @@ def _default_frequency_range(syslist, Hz=None, number_of_samples=None,
13601366

13611367
ifHz:
13621368
features/=2.*math.pi
1363-
features=np.log10(features)
1364-
lsp_min=np.floor(np.min(features)-feature_periphery_decades)
1365-
lsp_max=np.ceil(np.max(features)+feature_periphery_decades)
1369+
features=np.log10(features)
1370+
lsp_min=np.rint(np.min(features)-feature_periphery_decades)
1371+
lsp_max=np.rint(np.max(features)+feature_periphery_decades)
1372+
ifHz:
13661373
lsp_min+=np.log10(2.*math.pi)
13671374
lsp_max+=np.log10(2.*math.pi)
1368-
else:
1369-
features=np.log10(features)
1370-
lsp_min=np.floor(np.min(features)-feature_periphery_decades)
1371-
lsp_max=np.ceil(np.max(features)+feature_periphery_decades)
1375+
13721376
iffreq_interesting:
13731377
lsp_min=min(lsp_min,np.log10(min(freq_interesting)))
13741378
lsp_max=max(lsp_max,np.log10(max(freq_interesting)))

‎control/tests/nyquist_test.py

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -182,42 +182,56 @@ def test_nyquist_encirclements():
182182
assert_Z(sys)==count+_P(sys)
183183

184184

185-
deftest_nyquist_indent():
185+
@pytest.fixture
186+
defindentsys():
186187
# FBS Figure 10.10
187-
s=ct.tf('s')
188-
sys=3* (s+6)**2/ (s* (s+1)**2)
189188
# poles: [-1, -1, 0]
189+
s=ct.tf('s')
190+
return3* (s+6)**2/ (s* (s+1)**2)
190191

192+
193+
deftest_nyquist_indent_default(indentsys):
191194
plt.figure();
192-
count=ct.nyquist_plot(sys)
195+
count=ct.nyquist_plot(indentsys)
193196
plt.title("Pole at origin; indent_radius=default")
194-
assert_Z(sys)==count+_P(sys)
197+
assert_Z(indentsys)==count+_P(indentsys)
195198

199+
200+
deftest_nyquist_indent_dont(indentsys):
196201
# first value of default omega vector was 0.1, replaced by 0. for contour
197202
# indent_radius is larger than 0.1 -> no extra quater circle around origin
198-
count,contour=ct.nyquist_plot(sys,plot=False,indent_radius=.1007,
203+
count,contour=ct.nyquist_plot(indentsys,
204+
plot=False,
205+
indent_radius=.1007,
199206
return_contour=True)
200207
np.testing.assert_allclose(contour[0],.1007+0.j)
201208
# second value of omega_vector is larger than indent_radius: not indented
202209
assertnp.all(contour.real[2:]==0.)
203210

211+
212+
deftest_nyquist_indent_do(indentsys):
204213
plt.figure();
205-
count,contour=ct.nyquist_plot(sys,indent_radius=0.01,
214+
count,contour=ct.nyquist_plot(indentsys,
215+
indent_radius=0.01,
206216
return_contour=True)
207217
plt.title("Pole at origin; indent_radius=0.01; encirclements = %d"%count)
208-
assert_Z(sys)==count+_P(sys)
218+
assert_Z(indentsys)==count+_P(indentsys)
209219
# indent radius is smaller than the start of the default omega vector
210220
# check that a quarter circle around the pole at origin has been added.
211221
np.testing.assert_allclose(contour[:50].real**2+contour[:50].imag**2,
212222
0.01**2)
213223

224+
225+
deftest_nyquist_indent_left(indentsys):
214226
plt.figure();
215-
count=ct.nyquist_plot(sys,indent_direction='left')
227+
count=ct.nyquist_plot(indentsys,indent_direction='left')
216228
plt.title(
217229
"Pole at origin; indent_direction='left'; encirclements = %d"%count)
218-
assert_Z(sys)==count+_P(sys,indent='left')
230+
assert_Z(indentsys)==count+_P(indentsys,indent='left')
231+
219232

220-
# System with poles on the imaginary axis
233+
deftest_nyquist_indent_im():
234+
"""Test system with poles on the imaginary axis."""
221235
sys=ct.tf([1,1], [1,0,1])
222236

223237
# Imaginary poles with standard indentation

‎control/tests/sisotool_test.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,8 @@ def test_sisotool(self, tsys):
102102

103103
# Check if the bode_mag line has moved
104104
bode_mag_moved=np.array(
105-
[674.0242,667.8354,661.7033,655.6275,649.6074,643.6426,
106-
637.7324,631.8765,626.0742,620.3252])
105+
[69.0065,68.6749,68.3448,68.0161,67.6889,67.3631,67.0388,
106+
66.7159,66.3944,66.0743])
107107
assert_array_almost_equal(ax_mag.lines[0].get_data()[1][10:20],
108108
bode_mag_moved,4)
109109

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp