Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
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
  • Loading branch information
juanodecc committed Mar 12, 2021
commit 12635500e42d89cb4abfbb0fed88d2d6b5594e72
105 changes: 104 additions & 1 deletion control/tests/timeresp_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,35 @@ def pole_cancellation(self):
def no_pole_cancellation(self):
return TransferFunction([1.881e+06],
[188.1, 1.881e+06])

@pytest.fixture
def siso_tf_type1(self):
# System Type 1 - Step response not stationary: G(s)=1/s(s+1)
return TransferFunction(1, [1, 1, 0])

@pytest.fixture
def siso_tf_kpos(self):
# SISO under shoot response and positive final value G(s)=(-s+1)/(s²+s+1)
return TransferFunction([-1, 1], [1, 1, 1])

@pytest.fixture
def siso_tf_kneg(self):
# SISO under shoot response and negative final value k=-1 G(s)=-(-s+1)/(s²+s+1)
return TransferFunction([1, -1], [1, 1, 1])

@pytest.fixture
def tf1_matlab_help(self):
# example from matlab online help https://www.mathworks.com/help/control/ref/stepinfo.html
return TransferFunction([1, 5, 5], [1, 1.65, 5, 6.5, 2])

@pytest.fixture
def tf2_matlab_help(self):
A = [[0.68, - 0.34], [0.34, 0.68]]
B = [[0.18], [0.04]]
C = [-1.12, - 1.10]
D = [0.06]
sys = StateSpace(A, B, C, D, 0.2)
return sys

@pytest.fixture
def tsystem(self,
Expand All @@ -202,7 +231,9 @@ def tsystem(self,
siso_dtf0, siso_dtf1, siso_dtf2,
siso_dss1, siso_dss2,
mimo_dss1, mimo_dss2, mimo_dtf1,
pole_cancellation, no_pole_cancellation):
pole_cancellation, no_pole_cancellation, siso_tf_type1,
siso_tf_kpos, siso_tf_kneg, tf1_matlab_help,
tf2_matlab_help):
systems = {"siso_ss1": siso_ss1,
"siso_ss2": siso_ss2,
"siso_tf1": siso_tf1,
Expand All @@ -220,6 +251,11 @@ def tsystem(self,
"mimo_dtf1": mimo_dtf1,
"pole_cancellation": pole_cancellation,
"no_pole_cancellation": no_pole_cancellation,
"siso_tf_type1": siso_tf_type1,
"siso_tf_kpos": siso_tf_kpos,
"siso_tf_kneg": siso_tf_kneg,
"tf1_matlab_help": tf1_matlab_help,
"tf2_matlab_help": tf2_matlab_help,
}
return systems[request.param]

Expand Down Expand Up @@ -303,6 +339,73 @@ def test_step_info(self):
[Strue[k] for k in Sktrue],
rtol=rtol)

# tolerance for all parameters could be wrong for some systems ej: discrete systems time parameters tolerance
# could be +/-dt
Comment thread
bnavigator marked this conversation as resolved.
Outdated
@pytest.mark.parametrize(
"tsystem, info_true, tolerance",
[("tf1_matlab_help", {
'RiseTime': 3.8456,
'SettlingTime': 27.9762,
'SettlingMin': 2.0689,
'SettlingMax': 2.6873,
'Overshoot': 7.4915,
'Undershoot': 0,
'Peak': 2.6873,
'PeakTime': 8.0530,
'SteadyStateValue': 2.5}, 2e-2),
("tf2_matlab_help", {
'RiseTime': 0.4000,
'SettlingTime': 2.8000,
'SettlingMin': -0.6724,
'SettlingMax': -0.5188,
'Overshoot': 24.6476,
'Undershoot': 11.1224,
'Peak': 0.6724,
'PeakTime': 1,
'SteadyStateValue': -0.5394}, .2),
("siso_tf_kpos", {
'RiseTime': 1.242,
'SettlingTime': 9.110,
'SettlingMin': 0.950,
'SettlingMax': 1.208,
'Overshoot': 20.840,
'Undershoot': 27.840,
'Peak': 1.208,
'PeakTime': 4.282,
'SteadyStateValue': 1.0}, 2e-2),
("siso_tf_kneg", {
'RiseTime': 1.242,
'SettlingTime': 9.110,
'SettlingMin': -1.208,
'SettlingMax': -0.950,
'Overshoot': 20.840,
'Undershoot': 27.840,
'Peak': 1.208,
'PeakTime': 4.282,
'SteadyStateValue': -1.0}, 2e-2),
("siso_tf_type1", {'RiseTime': np.NaN,
'SettlingTime': np.NaN,
'SettlingMin': np.NaN,
'SettlingMax': np.NaN,
'Overshoot': np.NaN,
'Undershoot': np.NaN,
'Peak': np.Inf,
'PeakTime': np.Inf,
'SteadyStateValue': np.NaN}, 2e-2)],
indirect=["tsystem"])
def test_step_info(self, tsystem, info_true, tolerance):
""" """
info = step_info(tsystem)

info_true_sorted = sorted(info_true.keys())
info_sorted = sorted(info.keys())

assert info_sorted == info_true_sorted

np.testing.assert_allclose([info_true[k] for k in info_true_sorted],
[info[k] for k in info_sorted],
rtol=tolerance)

def test_step_pole_cancellation(self, pole_cancellation,
no_pole_cancellation):
# confirm that pole-zero cancellation doesn't perturb results
Expand Down