diff --git a/control/tests/timeresp_test.py b/control/tests/timeresp_test.py index 16ee01a3d..e00fdb970 100644 --- a/control/tests/timeresp_test.py +++ b/control/tests/timeresp_test.py @@ -2,6 +2,7 @@ from copy import copy from math import isclose +import warnings import numpy as np import pytest @@ -14,6 +15,8 @@ step_response + + class TSys: """Struct of test system""" def __init__(self, sys=None, call_kwargs=None): @@ -826,6 +829,14 @@ def test_auto_generated_time_vector_tfinal(self, tfsys, tfinal): np.testing.assert_allclose(ideal_tfinal, tfinal, rtol=1e-4) T = _default_time_vector(tfsys) np.testing.assert_allclose(T[-1], tfinal, atol=0.5*ideal_dt) + + def test_discrete_time_negative_one_settling(self): + #system with -1 pole + TF = TransferFunction([1,3,0],[1,3,2], dt=True) + with warnings.catch_warnings(): + warnings.simplefilter("error") + impulse_response(TF) + @pytest.mark.parametrize("wn, zeta", [(10, 0), (100, 0), (100, .1)]) def test_auto_generated_time_vector_dt_cont1(self, wn, zeta): diff --git a/control/timeresp.py b/control/timeresp.py index 3c49d213e..1d252b270 100644 --- a/control/timeresp.py +++ b/control/timeresp.py @@ -2172,7 +2172,7 @@ def _ideal_tfinal_and_dt(sys, is_step=True): m_z = np.abs(p) < sqrt_eps p = p[~m_z] # Negative reals- treated as oscillatory mode - m_nr = (p.real < 0) & (np.abs(p.imag) < sqrt_eps) + m_nr = (p.real < 0) & (np.abs(p.imag) < sqrt_eps) & (np.abs(p.real+1) > sqrt_eps) p_nr, p = p[m_nr], p[~m_nr] if p_nr.size > 0: t_emp = np.max(log_decay_percent / np.abs((np.log(p_nr)/dt).real))