Skip to content

Commit 1263550

Browse files
committed
Added 5 test for step_info:
1) System Type 1 - Step response not stationary:  G(s)=1/s(s+1) 2) SISO system with under shoot response and positive final value G(s)=(-s+1)/(s²+s+1) 3) Same system that 2) with k=-1 4) example from matlab online help https://www.mathworks.com/help/control/ref/stepinfo.html G(s)=(s²+5s+5)/(s^4+1.65s^3+6.5s+2) with stepinfo output:         RiseTime: 3.8456     SettlingTime: 27.9762      SettlingMin: 2.0689      SettlingMax: 2.6873        Overshoot: 7.4915       Undershoot: 0             Peak: 2.6873         PeakTime: 8.0530 5) example from matlab online help https://www.mathworks.com/help/control/ref/stepinfo.html A = [0.68 -0.34; 0.34 0.68]; B = [0.18 -0.05; 0.04 0.11]; C = [0 -1.53; -1.12 -1.10]; D = [0 0; 0.06 -0.37]; sys = StateSpace(A,B,C,D,0.2); examine the response characteristics for the response from the first input to the second output of sys. with stepinfo output:         RiseTime: 0.4000     SettlingTime: 2.8000      SettlingMin: -0.6724      SettlingMax: -0.5188        Overshoot: 24.6476       Undershoot: 11.1224             Peak: 0.6724         PeakTime: 1
1 parent 92de12d commit 1263550

1 file changed

Lines changed: 104 additions & 1 deletion

File tree

control/tests/timeresp_test.py

Lines changed: 104 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,35 @@ def pole_cancellation(self):
193193
def no_pole_cancellation(self):
194194
return TransferFunction([1.881e+06],
195195
[188.1, 1.881e+06])
196+
197+
@pytest.fixture
198+
def siso_tf_type1(self):
199+
# System Type 1 - Step response not stationary: G(s)=1/s(s+1)
200+
return TransferFunction(1, [1, 1, 0])
201+
202+
@pytest.fixture
203+
def siso_tf_kpos(self):
204+
# SISO under shoot response and positive final value G(s)=(-s+1)/(s²+s+1)
205+
return TransferFunction([-1, 1], [1, 1, 1])
206+
207+
@pytest.fixture
208+
def siso_tf_kneg(self):
209+
# SISO under shoot response and negative final value k=-1 G(s)=-(-s+1)/(s²+s+1)
210+
return TransferFunction([1, -1], [1, 1, 1])
211+
212+
@pytest.fixture
213+
def tf1_matlab_help(self):
214+
# example from matlab online help https://www.mathworks.com/help/control/ref/stepinfo.html
215+
return TransferFunction([1, 5, 5], [1, 1.65, 5, 6.5, 2])
216+
217+
@pytest.fixture
218+
def tf2_matlab_help(self):
219+
A = [[0.68, - 0.34], [0.34, 0.68]]
220+
B = [[0.18], [0.04]]
221+
C = [-1.12, - 1.10]
222+
D = [0.06]
223+
sys = StateSpace(A, B, C, D, 0.2)
224+
return sys
196225

197226
@pytest.fixture
198227
def tsystem(self,
@@ -202,7 +231,9 @@ def tsystem(self,
202231
siso_dtf0, siso_dtf1, siso_dtf2,
203232
siso_dss1, siso_dss2,
204233
mimo_dss1, mimo_dss2, mimo_dtf1,
205-
pole_cancellation, no_pole_cancellation):
234+
pole_cancellation, no_pole_cancellation, siso_tf_type1,
235+
siso_tf_kpos, siso_tf_kneg, tf1_matlab_help,
236+
tf2_matlab_help):
206237
systems = {"siso_ss1": siso_ss1,
207238
"siso_ss2": siso_ss2,
208239
"siso_tf1": siso_tf1,
@@ -220,6 +251,11 @@ def tsystem(self,
220251
"mimo_dtf1": mimo_dtf1,
221252
"pole_cancellation": pole_cancellation,
222253
"no_pole_cancellation": no_pole_cancellation,
254+
"siso_tf_type1": siso_tf_type1,
255+
"siso_tf_kpos": siso_tf_kpos,
256+
"siso_tf_kneg": siso_tf_kneg,
257+
"tf1_matlab_help": tf1_matlab_help,
258+
"tf2_matlab_help": tf2_matlab_help,
223259
}
224260
return systems[request.param]
225261

@@ -303,6 +339,73 @@ def test_step_info(self):
303339
[Strue[k] for k in Sktrue],
304340
rtol=rtol)
305341

342+
# tolerance for all parameters could be wrong for some systems ej: discrete systems time parameters tolerance
343+
# could be +/-dt
344+
@pytest.mark.parametrize(
345+
"tsystem, info_true, tolerance",
346+
[("tf1_matlab_help", {
347+
'RiseTime': 3.8456,
348+
'SettlingTime': 27.9762,
349+
'SettlingMin': 2.0689,
350+
'SettlingMax': 2.6873,
351+
'Overshoot': 7.4915,
352+
'Undershoot': 0,
353+
'Peak': 2.6873,
354+
'PeakTime': 8.0530,
355+
'SteadyStateValue': 2.5}, 2e-2),
356+
("tf2_matlab_help", {
357+
'RiseTime': 0.4000,
358+
'SettlingTime': 2.8000,
359+
'SettlingMin': -0.6724,
360+
'SettlingMax': -0.5188,
361+
'Overshoot': 24.6476,
362+
'Undershoot': 11.1224,
363+
'Peak': 0.6724,
364+
'PeakTime': 1,
365+
'SteadyStateValue': -0.5394}, .2),
366+
("siso_tf_kpos", {
367+
'RiseTime': 1.242,
368+
'SettlingTime': 9.110,
369+
'SettlingMin': 0.950,
370+
'SettlingMax': 1.208,
371+
'Overshoot': 20.840,
372+
'Undershoot': 27.840,
373+
'Peak': 1.208,
374+
'PeakTime': 4.282,
375+
'SteadyStateValue': 1.0}, 2e-2),
376+
("siso_tf_kneg", {
377+
'RiseTime': 1.242,
378+
'SettlingTime': 9.110,
379+
'SettlingMin': -1.208,
380+
'SettlingMax': -0.950,
381+
'Overshoot': 20.840,
382+
'Undershoot': 27.840,
383+
'Peak': 1.208,
384+
'PeakTime': 4.282,
385+
'SteadyStateValue': -1.0}, 2e-2),
386+
("siso_tf_type1", {'RiseTime': np.NaN,
387+
'SettlingTime': np.NaN,
388+
'SettlingMin': np.NaN,
389+
'SettlingMax': np.NaN,
390+
'Overshoot': np.NaN,
391+
'Undershoot': np.NaN,
392+
'Peak': np.Inf,
393+
'PeakTime': np.Inf,
394+
'SteadyStateValue': np.NaN}, 2e-2)],
395+
indirect=["tsystem"])
396+
def test_step_info(self, tsystem, info_true, tolerance):
397+
""" """
398+
info = step_info(tsystem)
399+
400+
info_true_sorted = sorted(info_true.keys())
401+
info_sorted = sorted(info.keys())
402+
403+
assert info_sorted == info_true_sorted
404+
405+
np.testing.assert_allclose([info_true[k] for k in info_true_sorted],
406+
[info[k] for k in info_sorted],
407+
rtol=tolerance)
408+
306409
def test_step_pole_cancellation(self, pole_cancellation,
307410
no_pole_cancellation):
308411
# confirm that pole-zero cancellation doesn't perturb results

0 commit comments

Comments
 (0)