diff --git a/control/iosys.py b/control/iosys.py index 2bb445bdd..df75f3b54 100644 --- a/control/iosys.py +++ b/control/iosys.py @@ -890,7 +890,7 @@ def __init__(self, syslist, connections=None, inplist=None, outlist=None, kwargs, defaults, end=True) # Initialize the system list and index - self.syslist = syslist + self.syslist = list(syslist) # insure modifications can be made self.syslist_index = {} # Initialize the input, output, and state counts, indices @@ -903,12 +903,12 @@ def __init__(self, syslist, connections=None, inplist=None, outlist=None, sysname_count_dct = {} # Go through the system list and keep track of counts, offsets - for sysidx, sys in enumerate(syslist): + for sysidx, sys in enumerate(self.syslist): # If we were passed a SS or TF system, convert to LinearIOSystem if isinstance(sys, (StateSpace, TransferFunction)) and \ not isinstance(sys, LinearIOSystem): - sys = LinearIOSystem(sys) - syslist[sysidx] = sys + sys = LinearIOSystem(sys, name=sys.name) + self.syslist[sysidx] = sys # Make sure time bases are consistent dt = common_timebase(dt, sys.dt) @@ -2850,12 +2850,12 @@ def interconnect(syslist, connections=None, inplist=None, outlist=None, inputs=inputs, outputs=outputs, states=states, params=params, dt=dt, name=name, warn_duplicate=warn_duplicate) - # check for implicity dropped signals + # check for implicitly dropped signals if check_unused: newsys.check_unused_signals(ignore_inputs, ignore_outputs) # If all subsystems are linear systems, maintain linear structure - if all([isinstance(sys, LinearIOSystem) for sys in syslist]): + if all([isinstance(sys, LinearIOSystem) for sys in newsys.syslist]): return LinearICSystem(newsys, None) return newsys diff --git a/control/tests/interconnect_test.py b/control/tests/interconnect_test.py index 3b99adc6e..2c29aeaca 100644 --- a/control/tests/interconnect_test.py +++ b/control/tests/interconnect_test.py @@ -230,3 +230,25 @@ def test_string_inputoutput(): P_s2 = ct.interconnect([P1_iosys, P2_iosys], inputs=['u1'], output='y2') assert P_s2.output_index == {'y2' : 0} + +def test_linear_interconnect(): + tf_ctrl = ct.tf(1, (10.1, 1), inputs='e', outputs='u') + tf_plant = ct.tf(1, (10.1, 1), inputs='u', outputs='y') + ss_ctrl = ct.ss(1, 2, 1, 2, inputs='e', outputs='u') + ss_plant = ct.ss(1, 2, 1, 2, inputs='u', outputs='y') + nl_ctrl = ct.NonlinearIOSystem( + lambda t, x, u, params: x*x, + lambda t, x, u, params: u*x, states=1, inputs='e', outputs='u') + nl_plant = ct.NonlinearIOSystem( + lambda t, x, u, params: x*x, + lambda t, x, u, params: u*x, states=1, inputs='u', outputs='y') + + assert isinstance(ct.interconnect((tf_ctrl, tf_plant), inputs='e', outputs='y'), ct.LinearIOSystem) + assert isinstance(ct.interconnect((ss_ctrl, ss_plant), inputs='e', outputs='y'), ct.LinearIOSystem) + assert isinstance(ct.interconnect((tf_ctrl, ss_plant), inputs='e', outputs='y'), ct.LinearIOSystem) + assert isinstance(ct.interconnect((ss_ctrl, tf_plant), inputs='e', outputs='y'), ct.LinearIOSystem) + + assert ~isinstance(ct.interconnect((nl_ctrl, ss_plant), inputs='e', outputs='y'), ct.LinearIOSystem) + assert ~isinstance(ct.interconnect((nl_ctrl, tf_plant), inputs='e', outputs='y'), ct.LinearIOSystem) + assert ~isinstance(ct.interconnect((ss_ctrl, nl_plant), inputs='e', outputs='y'), ct.LinearIOSystem) + assert ~isinstance(ct.interconnect((tf_ctrl, nl_plant), inputs='e', outputs='y'), ct.LinearIOSystem) \ No newline at end of file diff --git a/control/tests/iosys_test.py b/control/tests/iosys_test.py index 8a6ed8165..7d3b9fee9 100644 --- a/control/tests/iosys_test.py +++ b/control/tests/iosys_test.py @@ -1454,6 +1454,11 @@ def test_linear_interconnection(): inputs = ('u[0]', 'u[1]'), outputs = ('y[0]', 'y[1]'), name = 'sys2') + tf_siso = ct.tf(1, [0.1, 1]) + ss_siso = ct.ss(1, 2, 1, 1) + nl_siso = ios.NonlinearIOSystem( + lambda t, x, u, params: x*x, + lambda t, x, u, params: u*x, states=1, inputs=1, outputs=1) # Create a "regular" InterconnectedSystem nl_connect = ios.interconnect( @@ -1500,6 +1505,18 @@ def test_linear_interconnection(): np.testing.assert_array_almost_equal(io_connect.C, ss_connect.C) np.testing.assert_array_almost_equal(io_connect.D, ss_connect.D) + # make sure interconnections of linear systems are linear and + # if a nonlinear system is included then system is nonlinear + assert isinstance(ss_siso*ss_siso, ios.LinearIOSystem) + assert isinstance(tf_siso*ss_siso, ios.LinearIOSystem) + assert isinstance(ss_siso*tf_siso, ios.LinearIOSystem) + assert ~isinstance(ss_siso*nl_siso, ios.LinearIOSystem) + assert ~isinstance(nl_siso*ss_siso, ios.LinearIOSystem) + assert ~isinstance(nl_siso*nl_siso, ios.LinearIOSystem) + assert ~isinstance(tf_siso*nl_siso, ios.LinearIOSystem) + assert ~isinstance(nl_siso*tf_siso, ios.LinearIOSystem) + assert ~isinstance(nl_siso*nl_siso, ios.LinearIOSystem) + def predprey(t, x, u, params={}): """Predator prey dynamics"""
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: