Skip to content

Commit 95326b0

Browse files
committed
initial pass at defining lists of systems for time responses
1 parent feeb56a commit 95326b0

3 files changed

Lines changed: 63 additions & 13 deletions

File tree

control/nlsys.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1317,7 +1317,7 @@ def nlsys(
13171317

13181318

13191319
def input_output_response(
1320-
sys, T, U=0., X0=0, params=None, ignore_errors=False,
1320+
sysdata, T, U=0., X0=0, params=None, ignore_errors=False,
13211321
transpose=False, return_x=False, squeeze=None,
13221322
solve_ivp_kwargs=None, t_eval='T', **kwargs):
13231323
"""Compute the output response of a system to a given input.
@@ -1327,8 +1327,8 @@ def input_output_response(
13271327
13281328
Parameters
13291329
----------
1330-
sys : InputOutputSystem
1331-
Input/output system to simulate.
1330+
sysdata : I/O system or list of I/O systems
1331+
I/O system(s) for which input/output response is simulated.
13321332
13331333
T : array-like
13341334
Time steps at which the input is defined; values must be evenly spaced.
@@ -1448,6 +1448,15 @@ def input_output_response(
14481448
if kwargs:
14491449
raise TypeError("unrecognized keyword(s): ", str(kwargs))
14501450

1451+
# Convert the first argument to a list
1452+
syslist = sysdata if isinstance(sysdata, (list, tuple)) else [sysdata]
1453+
1454+
# TODO: implement step responses for multiple systems
1455+
if len(syslist) > 1:
1456+
raise NotImplementedError(
1457+
"step responses for multiple systems not yet implemented")
1458+
sys = syslist[0]
1459+
14511460
# Sanity checking on the input
14521461
if not isinstance(sys, NonlinearIOSystem):
14531462
raise TypeError("System of type ", type(sys), " not valid")

control/tests/timeplot_test.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,14 @@ def test_combine_time_responses():
313313
combresp6 = ct.combine_time_responses([resp1, resp])
314314

315315

316+
def test_list_responses():
317+
sys1 = ct.rss(2, 2, 2)
318+
sys2 = ct.rss(2, 2, 2)
319+
320+
resp = ct.step_response([sys1, sys2]).plot()
321+
assert resp.ntraces == 2
322+
323+
316324
@slycotonly
317325
def test_linestyles():
318326
# Check to make sure we can change line styles

control/timeresp.py

Lines changed: 43 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1280,8 +1280,9 @@ def _process_time_response(
12801280
return tout, yout
12811281

12821282

1283-
def step_response(sys, T=None, X0=0, input=None, output=None, T_num=None,
1284-
transpose=False, return_x=False, squeeze=None, params=None):
1283+
def step_response(
1284+
sysdata, T=None, X0=0, input=None, output=None, T_num=None,
1285+
transpose=False, return_x=False, squeeze=None, params=None):
12851286
# pylint: disable=W0622
12861287
"""Compute the step response for a linear system.
12871288
@@ -1296,8 +1297,8 @@ def step_response(sys, T=None, X0=0, input=None, output=None, T_num=None,
12961297
12971298
Parameters
12981299
----------
1299-
sys : StateSpace or TransferFunction
1300-
LTI system to simulate
1300+
sysdata : I/O system or list of I/O systems
1301+
I/O system(s) for which step response is computed.
13011302
13021303
T : array_like or float, optional
13031304
Time vector, or simulation time duration if a number. If T is not
@@ -1391,6 +1392,15 @@ def step_response(sys, T=None, X0=0, input=None, output=None, T_num=None,
13911392
from .statesp import _convert_to_statespace
13921393
from .xferfcn import TransferFunction
13931394

1395+
# Convert the first argument to a list
1396+
syslist = sysdata if isinstance(sysdata, (list, tuple)) else [sysdata]
1397+
1398+
# TODO: implement step responses for multiple systems
1399+
if len(syslist) > 1:
1400+
raise NotImplementedError(
1401+
"step responses for multiple systems not yet implemented")
1402+
sys = syslist[0]
1403+
13941404
# Create the time and input vectors
13951405
if T is None or np.asarray(T).size == 1:
13961406
T = _default_time_vector(sys, N=T_num, tfinal=T, is_step=True)
@@ -1681,8 +1691,9 @@ def step_info(sysdata, T=None, T_num=None, yfinal=None, params=None,
16811691
return ret[0][0] if retsiso else ret
16821692

16831693

1684-
def initial_response(sys, T=None, X0=0, output=None, T_num=None, params=None,
1685-
transpose=False, return_x=False, squeeze=None):
1694+
def initial_response(
1695+
sysdata, T=None, X0=0, output=None, T_num=None, params=None,
1696+
transpose=False, return_x=False, squeeze=None):
16861697
# pylint: disable=W0622
16871698
"""Compute the initial condition response for a linear system.
16881699
@@ -1695,6 +1706,9 @@ def initial_response(sys, T=None, X0=0, output=None, T_num=None, params=None,
16951706
16961707
Parameters
16971708
----------
1709+
sysdata : I/O system or list of I/O systems
1710+
I/O system(s) for which initial response is computed.
1711+
16981712
sys : StateSpace or TransferFunction
16991713
LTI system to simulate
17001714
@@ -1773,6 +1787,15 @@ def initial_response(sys, T=None, X0=0, output=None, T_num=None, params=None,
17731787
"""
17741788
from .lti import LTI
17751789

1790+
# Convert the first argument to a list
1791+
syslist = sysdata if isinstance(sysdata, (list, tuple)) else [sysdata]
1792+
1793+
# TODO: implement step responses for multiple systems
1794+
if len(syslist) > 1:
1795+
raise NotImplementedError(
1796+
"step responses for multiple systems not yet implemented")
1797+
sys = syslist[0]
1798+
17761799
# Create the time and input vectors
17771800
if T is None or np.asarray(T).size == 1:
17781801
T = _default_time_vector(sys, N=T_num, tfinal=T, is_step=False)
@@ -1800,8 +1823,9 @@ def initial_response(sys, T=None, X0=0, output=None, T_num=None, params=None,
18001823
transpose=transpose, return_x=return_x, squeeze=squeeze)
18011824

18021825

1803-
def impulse_response(sys, T=None, input=None, output=None, T_num=None,
1804-
transpose=False, return_x=False, squeeze=None):
1826+
def impulse_response(
1827+
sysdata, T=None, input=None, output=None, T_num=None,
1828+
transpose=False, return_x=False, squeeze=None):
18051829
# pylint: disable=W0622
18061830
"""Compute the impulse response for a linear system.
18071831
@@ -1816,8 +1840,8 @@ def impulse_response(sys, T=None, input=None, output=None, T_num=None,
18161840
18171841
Parameters
18181842
----------
1819-
sys : StateSpace, TransferFunction
1820-
LTI system to simulate
1843+
sysdata : I/O system or list of I/O systems
1844+
I/O system(s) for which impluse response is computed.
18211845
18221846
T : array_like or float, optional
18231847
Time vector, or simulation time duration if a scalar (time vector is
@@ -1896,6 +1920,15 @@ def impulse_response(sys, T=None, input=None, output=None, T_num=None,
18961920
from .lti import LTI
18971921
from .statesp import _convert_to_statespace
18981922

1923+
# Convert the first argument to a list
1924+
syslist = sysdata if isinstance(sysdata, (list, tuple)) else [sysdata]
1925+
1926+
# TODO: implement step responses for multiple systems
1927+
if len(syslist) > 1:
1928+
raise NotImplementedError(
1929+
"step responses for multiple systems not yet implemented")
1930+
sys = syslist[0]
1931+
18991932
# Make sure we have an LTI system
19001933
if not isinstance(sys, LTI):
19011934
raise ValueError("system must be LTI system for impulse response")

0 commit comments

Comments
 (0)