def test_interconnect_exceptions(): # First make sure the docstring example works P = ct.tf2io(ct.tf(1, [1, 0]), input='u', output='y') C = ct.tf2io(ct.tf(10, [1, 1]), input='e', output='u') sumblk = ct.summing_junction(inputs=['r', '-y'], output='e') T = ct.interconnect((P, C, sumblk), input='r', output='y') assert (T.ninputs, T.noutputs, T.nstates) == (1, 1, 2) # Unrecognized arguments # LinearIOSystem with pytest.raises(TypeError, match="unknown parameter"): P = ct.LinearIOSystem(ct.rss(2, 1, 1), output_name='y') # Interconnect with pytest.raises(TypeError, match="unknown parameter"): T = ct.interconnect((P, C, sumblk), input_name='r', output='y') # Interconnected system with pytest.raises(TypeError, match="unknown parameter"): T = ct.InterconnectedSystem((P, C, sumblk), input_name='r', output='y') # NonlinearIOSytem with pytest.raises(TypeError, match="unknown parameter"): nlios = ct.NonlinearIOSystem( None, lambda t, x, u, params: u*u, input_count=1, output_count=1) # Summing junction with pytest.raises(TypeError, match="input specification is required"): sumblk = ct.summing_junction() with pytest.raises(TypeError, match="unknown parameter"): sumblk = ct.summing_junction(input_count=2, output_count=2)
def test_summation_exceptions(): # Bad input description with pytest.raises(ValueError, match="could not parse input"): sumblk = ct.summing_junction(None, 'y') # Bad output description with pytest.raises(ValueError, match="could not parse output"): sumblk = ct.summing_junction('u', None) # Bad input dimension with pytest.raises(ValueError, match="unrecognized dimension"): sumblk = ct.summing_junction('u', 'y', dimension=False)
def test_interconnect_docstring(): """Test the examples from the interconnect() docstring""" # MIMO interconnection (note: use [C, P] instead of [P, C] for state order) P = ct.LinearIOSystem( ct.rss(2, 2, 2, strictly_proper=True), name='P') C = ct.LinearIOSystem(ct.rss(2, 2, 2), name='C') T = ct.interconnect( [C, P], connections = [ ['P.u[0]', 'C.y[0]'], ['P.u[1]', 'C.y[1]'], ['C.u[0]', '-P.y[0]'], ['C.u[1]', '-P.y[1]']], inplist = ['C.u[0]', 'C.u[1]'], outlist = ['P.y[0]', 'P.y[1]'], ) T_ss = ct.feedback(P * C, ct.ss([], [], [], np.eye(2))) np.testing.assert_almost_equal(T.A, T_ss.A) np.testing.assert_almost_equal(T.B, T_ss.B) np.testing.assert_almost_equal(T.C, T_ss.C) np.testing.assert_almost_equal(T.D, T_ss.D) # Implicit interconnection (note: use [C, P, sumblk] for proper state order) P = ct.tf2io(ct.tf(1, [1, 0]), inputs='u', outputs='y') C = ct.tf2io(ct.tf(10, [1, 1]), inputs='e', outputs='u') sumblk = ct.summing_junction(inputs=['r', '-y'], output='e') T = ct.interconnect([C, P, sumblk], inplist='r', outlist='y') T_ss = ct.feedback(P * C, 1) np.testing.assert_almost_equal(T.A, T_ss.A) np.testing.assert_almost_equal(T.B, T_ss.B) np.testing.assert_almost_equal(T.C, T_ss.C) np.testing.assert_almost_equal(T.D, T_ss.D)
def test_summing_junction(inputs, output, dimension, D): ninputs = 1 if isinstance(inputs, str) else \ inputs if isinstance(inputs, int) else len(inputs) sum = ct.summing_junction( inputs=inputs, output=output, dimension=dimension) dim = 1 if dimension is None else dimension np.testing.assert_array_equal(sum.A, np.ndarray((0, 0))) np.testing.assert_array_equal(sum.B, np.ndarray((0, ninputs*dim))) np.testing.assert_array_equal(sum.C, np.ndarray((dim, 0))) np.testing.assert_array_equal(sum.D, D)
def test_interconnect_implicit(): """Test the use of implicit connections in interconnect()""" import random # System definition P = ct.ss2io( ct.rss(2, 1, 1, strictly_proper=True), inputs='u', outputs='y', name='P') kp = ct.tf(random.uniform(1, 10), [1]) ki = ct.tf(random.uniform(1, 10), [1, 0]) C = ct.tf2io(kp + ki, inputs='e', outputs='u', name='C') # Block diagram computation Tss = ct.feedback(P * C, 1) # Construct the interconnection explicitly Tio_exp = ct.interconnect( (C, P), connections = [['P.u', 'C.u'], ['C.e', '-P.y']], inplist='C.e', outlist='P.y') # Compare to bdalg computation np.testing.assert_almost_equal(Tio_exp.A, Tss.A) np.testing.assert_almost_equal(Tio_exp.B, Tss.B) np.testing.assert_almost_equal(Tio_exp.C, Tss.C) np.testing.assert_almost_equal(Tio_exp.D, Tss.D) # Construct the interconnection via a summing junction sumblk = ct.summing_junction(inputs=['r', '-y'], output='e', name="sum") Tio_sum = ct.interconnect( (C, P, sumblk), inplist=['r'], outlist=['y']) np.testing.assert_almost_equal(Tio_sum.A, Tss.A) np.testing.assert_almost_equal(Tio_sum.B, Tss.B) np.testing.assert_almost_equal(Tio_sum.C, Tss.C) np.testing.assert_almost_equal(Tio_sum.D, Tss.D) # Setting connections to False should lead to an empty connection map empty = ct.interconnect( (C, P, sumblk), connections=False, inplist=['r'], outlist=['y']) np.testing.assert_array_equal(empty.connect_map, np.zeros((4, 3))) # Implicit summation across repeated signals kp_io = ct.tf2io(kp, inputs='e', outputs='u', name='kp') ki_io = ct.tf2io(ki, inputs='e', outputs='u', name='ki') Tio_sum = ct.interconnect( (kp_io, ki_io, P, sumblk), inplist=['r'], outlist=['y']) np.testing.assert_almost_equal(Tio_sum.A, Tss.A) np.testing.assert_almost_equal(Tio_sum.B, Tss.B) np.testing.assert_almost_equal(Tio_sum.C, Tss.C) np.testing.assert_almost_equal(Tio_sum.D, Tss.D) # TODO: interconnect a MIMO system using implicit connections # P = control.ss2io( # control.rss(2, 2, 2, strictly_proper=True), # input_prefix='u', output_prefix='y', name='P') # C = control.ss2io( # control.rss(2, 2, 2), # input_prefix='e', output_prefix='u', name='C') # sumblk = control.summing_junction( # inputs=['r', '-y'], output='e', dimension=2) # S = control.interconnect([P, C, sumblk], inplist='r', outlist='y') # Make sure that repeated inplist/outlist names generate an error # Input not unique Cbad = ct.tf2io(ct.tf(10, [1, 1]), inputs='r', outputs='x', name='C') with pytest.raises(ValueError, match="not unique"): Tio_sum = ct.interconnect( (Cbad, P, sumblk), inplist=['r'], outlist=['y']) # Output not unique Cbad = ct.tf2io(ct.tf(10, [1, 1]), inputs='e', outputs='y', name='C') with pytest.raises(ValueError, match="not unique"): Tio_sum = ct.interconnect( (Cbad, P, sumblk), inplist=['r'], outlist=['y']) # Signal not found with pytest.raises(ValueError, match="could not find"): Tio_sum = ct.interconnect( (C, P, sumblk), inplist=['x'], outlist=['y']) with pytest.raises(ValueError, match="could not find"): Tio_sum = ct.interconnect( (C, P, sumblk), inplist=['r'], outlist=['x'])