Closed
Description
The SettlingMin or SettlingMax or/and Peak values calculus depend on span time selección when the system is asymptotic system:
step_info test broke with this test (In this case Fail SettingMax):
@pytest.fixture
def siso_tf_peak1(self):
# Peak_value = Undershoot = y_final(y(t=inf))
# step info time values depend on time vector discretization
# use T=linspace(0,50,10000)
T = TSys(TransferFunction([-1, 1],[1, 1]))
T.step_info = {
'RiseTime': 2.2002,
'SettlingTime': 4.6104,
'SettlingMin': 0.9004,
'SettlingMax': 0.9999,
'Overshoot': 0,
'Undershoot': 100.0,
'Peak': 1.0,
'PeakTime': 0.0,
'SteadyStateValue': 1.0}
return T
the problem is with SettlingMax using T by deafault
========================================================================== FAILURES ===========================================================================
__________________________________________________ TestTimeresp.test_step_info[siso_tf_peak1-ltisys-yfinal] ___________________________________________________
self = <control.tests.timeresp_test.TestTimeresp object at 0x7f443b7aebb0>, tsystem = TransferFunction(array([-1, 1]), array([1, 1])), systype = 'ltisys'
time_2d = False, yfinal = True
@pytest.mark.parametrize(
"yfinal", [True, False], ids=["yfinal", "no yfinal"])
@pytest.mark.parametrize(
"systype, time_2d",
[("ltisys", False),
("time response", False),
("time response", True),
],
ids=["ltisys", "time response (n,)", "time response (1,n)"])
@pytest.mark.parametrize(
"tsystem",
["siso_tf_step_matlab",
"siso_ss_step_matlab",
"siso_tf_kpos",
"siso_tf_kneg",
"siso_tf_type1",
"siso_tf_peak1"],
indirect=["tsystem"])
def test_step_info(self, tsystem, systype, time_2d, yfinal):
"""Test step info for SISO systems."""
step_info_kwargs = tsystem.kwargs.get('step_info', {})
if systype == "time response":
# simulate long enough for steady state value
tfinal = 3 * tsystem.step_info['SettlingTime']
if np.isnan(tfinal):
pytest.skip("test system does not settle")
t, y = step_response(tsystem.sys, T=tfinal, T_num=5000)
sysdata = y
step_info_kwargs['T'] = t[np.newaxis, :] if time_2d else t
else:
sysdata = tsystem.sys
if yfinal:
step_info_kwargs['yfinal'] = tsystem.step_info['SteadyStateValue']
info = step_info(sysdata, **step_info_kwargs)
> self.assert_step_info_match(tsystem.sys, info, tsystem.step_info)
control/tests/timeresp_test.py:509:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <control.tests.timeresp_test.TestTimeresp object at 0x7f443b7aebb0>, sys = TransferFunction(array([-1, 1]), array([1, 1]))
info = {'Overshoot': 0, 'Peak': 1.0, 'PeakTime': 0.0, 'RiseTime': 2.1630344812974367, ...}
info_ref = {'Overshoot': 0, 'Peak': 1.0, 'PeakTime': 0.0, 'RiseTime': 2.2002, ...}
def assert_step_info_match(self, sys, info, info_ref):
"""Assert reasonable step_info accuracy."""
if sys.isdtime(strict=True):
dt = sys.dt
else:
_, dt = _ideal_tfinal_and_dt(sys, is_step=True)
for k in ['RiseTime', 'SettlingTime', 'PeakTime']:
np.testing.assert_allclose(info[k], info_ref[k], atol=dt,
err_msg=f"{k} does not match")
for k in ['Overshoot', 'Undershoot', 'Peak', 'SteadyStateValue']:
np.testing.assert_allclose(info[k], info_ref[k], rtol=5e-3,
err_msg=f"{k} does not match")
# steep gradient right after RiseTime
absrefinf = np.abs(info_ref['SteadyStateValue'])
if info_ref['RiseTime'] > 0:
y_next_sample_max = 0.8*absrefinf/info_ref['RiseTime']*dt
else:
y_next_sample_max = 0
for k in ['SettlingMin', 'SettlingMax']:
if (np.abs(info_ref[k]) - 0.9 * absrefinf) > y_next_sample_max:
# local min/max peak well after signal has risen
> np.testing.assert_allclose(info[k], info_ref[k], rtol=1e-3)
E AssertionError:
E Not equal to tolerance rtol=0.001, atol=0
E
E Mismatched elements: 1 / 1 (100%)
E Max absolute difference: 0.0019
E Max relative difference: 0.00190019
E x: array(0.998)
E y: array(0.9999)
control/tests/timeresp_test.py:471: AssertionError
_________________________________________________ TestTimeresp.test_step_info[siso_tf_peak1-ltisys-no yfinal] _________________________________________________
self = <control.tests.timeresp_test.TestTimeresp object at 0x7f44b0132df0>, tsystem = TransferFunction(array([-1, 1]), array([1, 1])), systype = 'ltisys'
time_2d = False, yfinal = False
@pytest.mark.parametrize(
"yfinal", [True, False], ids=["yfinal", "no yfinal"])
@pytest.mark.parametrize(
"systype, time_2d",
[("ltisys", False),
("time response", False),
("time response", True),
],
ids=["ltisys", "time response (n,)", "time response (1,n)"])
@pytest.mark.parametrize(
"tsystem",
["siso_tf_step_matlab",
"siso_ss_step_matlab",
"siso_tf_kpos",
"siso_tf_kneg",
"siso_tf_type1",
"siso_tf_peak1"],
indirect=["tsystem"])
def test_step_info(self, tsystem, systype, time_2d, yfinal):
"""Test step info for SISO systems."""
step_info_kwargs = tsystem.kwargs.get('step_info', {})
if systype == "time response":
# simulate long enough for steady state value
tfinal = 3 * tsystem.step_info['SettlingTime']
if np.isnan(tfinal):
pytest.skip("test system does not settle")
t, y = step_response(tsystem.sys, T=tfinal, T_num=5000)
sysdata = y
step_info_kwargs['T'] = t[np.newaxis, :] if time_2d else t
else:
sysdata = tsystem.sys
if yfinal:
step_info_kwargs['yfinal'] = tsystem.step_info['SteadyStateValue']
info = step_info(sysdata, **step_info_kwargs)
> self.assert_step_info_match(tsystem.sys, info, tsystem.step_info)
control/tests/timeresp_test.py:509:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <control.tests.timeresp_test.TestTimeresp object at 0x7f44b0132df0>, sys = TransferFunction(array([-1, 1]), array([1, 1]))
info = {'Overshoot': 0, 'Peak': 1.0, 'PeakTime': 0.0, 'RiseTime': 2.1630344812974367, ...}
info_ref = {'Overshoot': 0, 'Peak': 1.0, 'PeakTime': 0.0, 'RiseTime': 2.2002, ...}
def assert_step_info_match(self, sys, info, info_ref):
"""Assert reasonable step_info accuracy."""
if sys.isdtime(strict=True):
dt = sys.dt
else:
_, dt = _ideal_tfinal_and_dt(sys, is_step=True)
for k in ['RiseTime', 'SettlingTime', 'PeakTime']:
np.testing.assert_allclose(info[k], info_ref[k], atol=dt,
err_msg=f"{k} does not match")
for k in ['Overshoot', 'Undershoot', 'Peak', 'SteadyStateValue']:
np.testing.assert_allclose(info[k], info_ref[k], rtol=5e-3,
err_msg=f"{k} does not match")
# steep gradient right after RiseTime
absrefinf = np.abs(info_ref['SteadyStateValue'])
if info_ref['RiseTime'] > 0:
y_next_sample_max = 0.8*absrefinf/info_ref['RiseTime']*dt
else:
y_next_sample_max = 0
for k in ['SettlingMin', 'SettlingMax']:
if (np.abs(info_ref[k]) - 0.9 * absrefinf) > y_next_sample_max:
# local min/max peak well after signal has risen
> np.testing.assert_allclose(info[k], info_ref[k], rtol=1e-3)
E AssertionError:
E Not equal to tolerance rtol=0.001, atol=0
E
E Mismatched elements: 1 / 1 (100%)
E Max absolute difference: 0.0019
E Max relative difference: 0.00190019
E x: array(0.998)
E y: array(0.9999)
control/tests/timeresp_test.py:471: AssertionError
====================================================================== warnings summary =======================================================================
control/tests/rlocus_test.py:79
/home/jpp/github_repos/my_python_control/python-control/control/tests/rlocus_test.py:79: PytestUnknownMarkWarning: Unknown pytest.mark.timeout - is this a typo? You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/mark.html
@pytest.mark.timeout(2)
-- Docs: https://docs.pytest.org/en/stable/warnings.html
=================================================================== short test summary info ===================================================================
SKIPPED [1] control/tests/matlab2_test.py:204: skipping test_check_convert_shape, need to update test
SKIPPED [1] control/tests/matlab2_test.py:275: need to update test
SKIPPED [4] control/tests/timeresp_test.py:498: test system does not settle
SKIPPED [6] control/tests/timeresp_test.py:880: No continuous forced_response without time vector.
SKIPPED [1] control/tests/type_conversion_test.py:162: future test; conversions not yet fully implemented
SKIPPED [2] control/tests/xferfcn_test.py:742: .__matmul__ not implemented
XFAIL control/tests/lti_test.py::TestLTI::test_timebaseEqual_deprecated[None-True-True]
returns false
XFAIL control/tests/optimal_test.py::test_discrete_lqr
reason: discrete LQR not implemented
XFAIL control/tests/statefbk_test.py::TestStatefbk::testLQR_warning
warning not implemented
FAILED control/tests/timeresp_test.py::TestTimeresp::test_step_info[siso_tf_peak1-ltisys-yfinal] - AssertionError:
FAILED control/tests/timeresp_test.py::TestTimeresp::test_step_info[siso_tf_peak1-ltisys-no yfinal] - AssertionError:
========================================= 2 failed, 2483 passed, 15 skipped, 3 xfailed, 1 warning in 93.49s (0:01:33) =========================================
(control-dev) jpp@jpp-linux:~/github_repos/my_python_control/python-control$ /home/jpp/miniconda3/envs/control-dev/bin/python /home/jpp/github_repos/my_python_control/python-control/examples/step_info_example2.py
Metadata
Metadata
Assignees
Labels
No labels