9
9
# specific unit tests will do that.
10
10
11
11
import unittest
12
+ from distutils .version import StrictVersion
13
+
12
14
import numpy as np
15
+ import pytest
16
+ import scipy as sp
17
+
13
18
from control .timeresp import *
14
19
from control .timeresp import _ideal_tfinal_and_dt , _default_time_vector
15
20
from control .statesp import *
@@ -29,11 +34,11 @@ def setUp(self):
29
34
# Create some transfer functions
30
35
self .siso_tf1 = TransferFunction ([1 ], [1 , 2 , 1 ])
31
36
self .siso_tf2 = _convert_to_transfer_function (self .siso_ss1 )
32
-
37
+
33
38
# tests for pole cancellation
34
- self .pole_cancellation = TransferFunction ([1.067e+05 , 5.791e+04 ],
39
+ self .pole_cancellation = TransferFunction ([1.067e+05 , 5.791e+04 ],
35
40
[10.67 , 1.067e+05 , 5.791e+04 ])
36
- self .no_pole_cancellation = TransferFunction ([1.881e+06 ],
41
+ self .no_pole_cancellation = TransferFunction ([1.881e+06 ],
37
42
[188.1 , 1.881e+06 ])
38
43
39
44
# Create MIMO system, contains ``siso_ss1`` twice
@@ -177,8 +182,8 @@ def test_step_info(self):
177
182
# https://github.com/python-control/python-control/issues/440
178
183
step_info_no_cancellation = step_info (self .no_pole_cancellation )
179
184
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 ],
185
+ for key in step_info_no_cancellation :
186
+ np .testing .assert_allclose (step_info_no_cancellation [key ],
182
187
step_info_cancellation [key ], rtol = 1e-4 )
183
188
184
189
def test_impulse_response (self ):
@@ -218,6 +223,8 @@ def test_impulse_response(self):
218
223
np .testing .assert_array_almost_equal (
219
224
yy , np .vstack ((youttrue , np .zeros_like (youttrue ))), decimal = 4 )
220
225
226
+ @pytest .mark .skipif (StrictVersion (sp .__version__ ) < "1.3.0" ,
227
+ reason = "requires SciPy 1.3.0 or greater" )
221
228
def test_discrete_time_impulse (self ):
222
229
# discrete time impulse sampled version should match cont time
223
230
dt = 0.1
@@ -226,7 +233,7 @@ def test_discrete_time_impulse(self):
226
233
sysdt = sys .sample (dt , 'impulse' )
227
234
np .testing .assert_array_almost_equal (impulse_response (sys , t )[1 ],
228
235
impulse_response (sysdt , t )[1 ])
229
-
236
+
230
237
def test_initial_response (self ):
231
238
# Test SISO system
232
239
sys = self .siso_ss1
@@ -363,7 +370,7 @@ def test_step_robustness(self):
363
370
"Unit test: https://github.com/python-control/python-control/issues/240"
364
371
# Create 2 input, 2 output system
365
372
num = [ [[0 ], [1 ]], [[1 ], [0 ]] ]
366
-
373
+
367
374
den1 = [ [[1 ], [1 ,1 ]], [[1 ,4 ], [1 ]] ]
368
375
sys1 = TransferFunction (num , den1 )
369
376
@@ -381,47 +388,47 @@ def test_auto_generated_time_vector(self):
381
388
ratio = 9.21034 * p # taken from code
382
389
ratio2 = 25 * p
383
390
np .testing .assert_array_almost_equal (
384
- _ideal_tfinal_and_dt (TransferFunction (1 , [1 , .5 ]))[0 ],
391
+ _ideal_tfinal_and_dt (TransferFunction (1 , [1 , .5 ]))[0 ],
385
392
(ratio / p ))
386
393
np .testing .assert_array_almost_equal (
387
- _ideal_tfinal_and_dt (TransferFunction (1 , [1 , .5 ]).sample (.1 ))[0 ],
394
+ _ideal_tfinal_and_dt (TransferFunction (1 , [1 , .5 ]).sample (.1 ))[0 ],
388
395
(ratio2 / p ))
389
396
# confirm a TF with poles at 0 and p simulates for ratio/p seconds
390
397
np .testing .assert_array_almost_equal (
391
- _ideal_tfinal_and_dt (TransferFunction (1 , [1 , .5 , 0 ]))[0 ],
398
+ _ideal_tfinal_and_dt (TransferFunction (1 , [1 , .5 , 0 ]))[0 ],
392
399
(ratio2 / p ))
393
400
394
- # confirm a TF with a natural frequency of wn rad/s gets a
401
+ # confirm a TF with a natural frequency of wn rad/s gets a
395
402
# dt of 1/(ratio*wn)
396
403
wn = 10
397
404
ratio_dt = 1 / (0.025133 * ratio * wn )
398
405
np .testing .assert_array_almost_equal (
399
- _ideal_tfinal_and_dt (TransferFunction (1 , [1 , 0 , wn ** 2 ]))[1 ],
406
+ _ideal_tfinal_and_dt (TransferFunction (1 , [1 , 0 , wn ** 2 ]))[1 ],
400
407
1 / (ratio_dt * ratio * wn ))
401
408
wn = 100
402
409
np .testing .assert_array_almost_equal (
403
- _ideal_tfinal_and_dt (TransferFunction (1 , [1 , 0 , wn ** 2 ]))[1 ],
410
+ _ideal_tfinal_and_dt (TransferFunction (1 , [1 , 0 , wn ** 2 ]))[1 ],
404
411
1 / (ratio_dt * ratio * wn ))
405
412
zeta = .1
406
413
np .testing .assert_array_almost_equal (
407
- _ideal_tfinal_and_dt (TransferFunction (1 , [1 , 2 * zeta * wn , wn ** 2 ]))[1 ],
414
+ _ideal_tfinal_and_dt (TransferFunction (1 , [1 , 2 * zeta * wn , wn ** 2 ]))[1 ],
408
415
1 / (ratio_dt * ratio * wn ))
409
416
# but a smapled one keeps its dt
410
417
np .testing .assert_array_almost_equal (
411
- _ideal_tfinal_and_dt (TransferFunction (1 , [1 , 2 * zeta * wn , wn ** 2 ]).sample (.1 ))[1 ],
418
+ _ideal_tfinal_and_dt (TransferFunction (1 , [1 , 2 * zeta * wn , wn ** 2 ]).sample (.1 ))[1 ],
412
419
.1 )
413
420
np .testing .assert_array_almost_equal (
414
- np .diff (initial_response (TransferFunction (1 , [1 , 2 * zeta * wn , wn ** 2 ]).sample (.1 ))[0 ][0 :2 ]),
421
+ np .diff (initial_response (TransferFunction (1 , [1 , 2 * zeta * wn , wn ** 2 ]).sample (.1 ))[0 ][0 :2 ]),
415
422
.1 )
416
423
np .testing .assert_array_almost_equal (
417
- _ideal_tfinal_and_dt (TransferFunction (1 , [1 , 2 * zeta * wn , wn ** 2 ]))[1 ],
424
+ _ideal_tfinal_and_dt (TransferFunction (1 , [1 , 2 * zeta * wn , wn ** 2 ]))[1 ],
418
425
1 / (ratio_dt * ratio * wn ))
419
-
420
-
426
+
427
+
421
428
# TF with fast oscillations simulates only 5000 time steps even with long tfinal
422
- self .assertEqual (5000 ,
429
+ self .assertEqual (5000 ,
423
430
len (_default_time_vector (TransferFunction (1 , [1 , 0 , wn ** 2 ]),tfinal = 100 )))
424
-
431
+
425
432
sys = TransferFunction (1 , [1 , .5 , 0 ])
426
433
sysdt = TransferFunction (1 , [1 , .5 , 0 ], .1 )
427
434
# test impose number of time steps
@@ -430,16 +437,16 @@ def test_auto_generated_time_vector(self):
430
437
self .assertNotEqual (15 , len (step_response (sysdt , T_num = 15 )[0 ]))
431
438
# test impose final time
432
439
np .testing .assert_array_almost_equal (
433
- 100 ,
440
+ 100 ,
434
441
np .ceil (step_response (sys , 100 )[0 ][- 1 ]))
435
442
np .testing .assert_array_almost_equal (
436
- 100 ,
443
+ 100 ,
437
444
np .ceil (step_response (sysdt , 100 )[0 ][- 1 ]))
438
445
np .testing .assert_array_almost_equal (
439
- 100 ,
446
+ 100 ,
440
447
np .ceil (impulse_response (sys , 100 )[0 ][- 1 ]))
441
448
np .testing .assert_array_almost_equal (
442
- 100 ,
449
+ 100 ,
443
450
np .ceil (initial_response (sys , 100 )[0 ][- 1 ]))
444
451
445
452
@@ -490,7 +497,7 @@ def test_time_vector(self):
490
497
np .testing .assert_array_equal (tout , Tin1 )
491
498
492
499
# MIMO forced response
493
- tout , yout , xout = forced_response (self .mimo_dss1 , Tin1 ,
500
+ tout , yout , xout = forced_response (self .mimo_dss1 , Tin1 ,
494
501
(np .sin (Tin1 ), np .cos (Tin1 )),
495
502
mimo_x0 )
496
503
self .assertEqual (np .shape (tout ), np .shape (yout [0 ,:]))
0 commit comments