Skip to content

Commit d1da3e1

Browse files
committed
first commit that adds ilayn's default time for step code
1 parent 15e5cba commit d1da3e1

File tree

5 files changed

+211
-93
lines changed

5 files changed

+211
-93
lines changed

control/statesp.py

+4
Original file line numberDiff line numberDiff line change
@@ -930,6 +930,10 @@ def dcgain(self):
930930
gain = np.tile(np.nan, (self.outputs, self.inputs))
931931
return np.squeeze(gain)
932932

933+
def is_static_gain(self):
934+
"""True if and only if the system has no dynamics, that is,
935+
if A and B are zero. """
936+
return not np.any(self.A) and not np.any(self.B)
933937

934938
# TODO: add discrete time check
935939
def _convertToStateSpace(sys, **kw):

control/tests/sisotool_test.py

+10-4
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,12 @@ def test_sisotool(self):
3232
initial_point_2, 4)
3333

3434
# Check the step response before moving the point
35+
# new array needed because change in compute step response default time
3536
step_response_original = np.array(
36-
[0., 0.0217, 0.1281, 0.3237, 0.5797, 0.8566, 1.116,
37-
1.3261, 1.4659, 1.526])
37+
[0. , 0.0069, 0.0448, 0.124 , 0.2427, 0.3933, 0.5653, 0.7473,
38+
0.928 , 1.0969])
39+
#old: np.array([0., 0.0217, 0.1281, 0.3237, 0.5797, 0.8566, 1.116,
40+
# 1.3261, 1.4659, 1.526])
3841
assert_array_almost_equal(
3942
ax_step.lines[0].get_data()[1][:10], step_response_original, 4)
4043

@@ -77,9 +80,12 @@ def test_sisotool(self):
7780
bode_mag_moved, 4)
7881

7982
# Check if the step response has changed
83+
# new array needed because change in compute step response default time
8084
step_response_moved = np.array(
81-
[0., 0.0239, 0.161 , 0.4547, 0.8903, 1.407,
82-
1.9121, 2.2989, 2.4686, 2.353])
85+
[0. , 0.0072, 0.0516, 0.1554, 0.3281, 0.5681, 0.8646, 1.1987,
86+
1.5452, 1.875 ])
87+
#old: array([0., 0.0239, 0.161 , 0.4547, 0.8903, 1.407,
88+
# 1.9121, 2.2989, 2.4686, 2.353])
8389
assert_array_almost_equal(
8490
ax_step.lines[0].get_data()[1][:10], step_response_moved, 4)
8591

control/tests/timeresp_test.py

+41-24
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,12 @@ def setUp(self):
2929
# Create some transfer functions
3030
self.siso_tf1 = TransferFunction([1], [1, 2, 1])
3131
self.siso_tf2 = _convert_to_transfer_function(self.siso_ss1)
32+
33+
# tests for pole cancellation
34+
self.pole_cancellation = TransferFunction([1.067e+05, 5.791e+04],
35+
[10.67, 1.067e+05, 5.791e+04])
36+
self.no_pole_cancellation = TransferFunction([1.881e+06],
37+
[188.1, 1.881e+06])
3238

3339
# Create MIMO system, contains ``siso_ss1`` twice
3440
A = np.matrix("1. -2. 0. 0.;"
@@ -167,6 +173,14 @@ def test_step_info(self):
167173
2.50,
168174
rtol=rtol)
169175

176+
# confirm that pole-zero cancellation doesn't perturb results
177+
# https://github.com/python-control/python-control/issues/440
178+
step_info_no_cancellation = step_info(self.no_pole_cancellation)
179+
step_info_cancellation = step_info(self.pole_cancellation)
180+
for key in step_info_no_cancellation:
181+
np.testing.assert_allclose(step_info_no_cancellation[key],
182+
step_info_cancellation[key], rtol=1e-4)
183+
170184
def test_impulse_response(self):
171185
# Test SISO system
172186
sys = self.siso_ss1
@@ -348,33 +362,41 @@ def test_step_robustness(self):
348362
sys2 = TransferFunction(num, den2)
349363

350364
# Compute step response from input 1 to output 1, 2
351-
t1, y1 = step_response(sys1, input=0, T_num=100)
352-
t2, y2 = step_response(sys2, input=0, T_num=100)
365+
t1, y1 = step_response(sys1, input=0, T=2, T_num=100)
366+
t2, y2 = step_response(sys2, input=0, T=2, T_num=100)
353367
np.testing.assert_array_almost_equal(y1, y2)
354368

355369
def test_auto_generated_time_vector(self):
356-
# confirm a TF with a pole at p simulates for 7.0/p seconds
370+
# confirm a TF with a pole at p simulates for ratio/p seconds
357371
p = 0.5
372+
ratio = 9.21034*p # taken from code
373+
ratio2 = 25*p
358374
np.testing.assert_array_almost_equal(
359375
_ideal_tfinal_and_dt(TransferFunction(1, [1, .5]))[0],
360-
(7/p))
376+
(ratio/p))
361377
np.testing.assert_array_almost_equal(
362378
_ideal_tfinal_and_dt(TransferFunction(1, [1, .5]).sample(.1))[0],
363-
(7/p))
364-
# confirm a TF with poles at 0 and p simulates for 7.0/p seconds
379+
(ratio2/p))
380+
# confirm a TF with poles at 0 and p simulates for ratio/p seconds
365381
np.testing.assert_array_almost_equal(
366382
_ideal_tfinal_and_dt(TransferFunction(1, [1, .5, 0]))[0],
367-
(7/p))
383+
(ratio2/p))
384+
368385
# confirm a TF with a natural frequency of wn rad/s gets a
369-
# dt of 1/(7.0*wn)
386+
# dt of 1/(ratio*wn)
370387
wn = 10
388+
ratio_dt = 1/(0.025133 * ratio * wn)
371389
np.testing.assert_array_almost_equal(
372390
_ideal_tfinal_and_dt(TransferFunction(1, [1, 0, wn**2]))[1],
373-
1/(7.0*wn))
391+
1/(ratio_dt*ratio*wn))
392+
wn = 100
393+
np.testing.assert_array_almost_equal(
394+
_ideal_tfinal_and_dt(TransferFunction(1, [1, 0, wn**2]))[1],
395+
1/(ratio_dt*ratio*wn))
374396
zeta = .1
375397
np.testing.assert_array_almost_equal(
376398
_ideal_tfinal_and_dt(TransferFunction(1, [1, 2*zeta*wn, wn**2]))[1],
377-
1/(7.0*wn))
399+
1/(ratio_dt*ratio*wn))
378400
# but a smapled one keeps its dt
379401
np.testing.assert_array_almost_equal(
380402
_ideal_tfinal_and_dt(TransferFunction(1, [1, 2*zeta*wn, wn**2]).sample(.1))[1],
@@ -384,37 +406,32 @@ def test_auto_generated_time_vector(self):
384406
.1)
385407
np.testing.assert_array_almost_equal(
386408
_ideal_tfinal_and_dt(TransferFunction(1, [1, 2*zeta*wn, wn**2]))[1],
387-
1/(7.0*wn))
409+
1/(ratio_dt*ratio*wn))
410+
411+
388412
# TF with fast oscillations simulates only 5000 time steps even with long tfinal
389413
self.assertEqual(5000,
390414
len(_default_time_vector(TransferFunction(1, [1, 0, wn**2]),tfinal=100)))
391-
# and simulates for 7.0/dt time steps
392-
self.assertEqual(
393-
len(_default_time_vector(TransferFunction(1, [1, 0, wn**2]))),
394-
int(7.0/(1/(7.0*wn))))
395415

396416
sys = TransferFunction(1, [1, .5, 0])
397417
sysdt = TransferFunction(1, [1, .5, 0], .1)
398418
# test impose number of time steps
399419
self.assertEqual(10, len(step_response(sys, T_num=10)[0]))
400-
self.assertEqual(10, len(step_response(sysdt, T_num=10)[0]))
420+
# test that discrete ignores T_num
421+
self.assertNotEqual(15, len(step_response(sysdt, T_num=15)[0]))
401422
# test impose final time
402423
np.testing.assert_array_almost_equal(
403424
100,
404-
step_response(sys, 100)[0][-1],
405-
decimal=.5)
425+
np.ceil(step_response(sys, 100)[0][-1]))
406426
np.testing.assert_array_almost_equal(
407427
100,
408-
step_response(sysdt, 100)[0][-1],
409-
decimal=.5)
428+
np.ceil(step_response(sysdt, 100)[0][-1]))
410429
np.testing.assert_array_almost_equal(
411430
100,
412-
impulse_response(sys, 100)[0][-1],
413-
decimal=.5)
431+
np.ceil(impulse_response(sys, 100)[0][-1]))
414432
np.testing.assert_array_almost_equal(
415433
100,
416-
initial_response(sys, 100)[0][-1],
417-
decimal=.5)
434+
np.ceil(initial_response(sys, 100)[0][-1]))
418435

419436

420437
def test_time_vector(self):

0 commit comments

Comments
 (0)