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_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_string_inputoutput(): # regression test for gh-692 P1 = ct.rss(2, 1, 1) P1_iosys = ct.LinearIOSystem(P1, inputs='u1', outputs='y1') P2 = ct.rss(2, 1, 1) P2_iosys = ct.LinearIOSystem(P2, inputs='y1', outputs='y2') P_s1 = ct.interconnect([P1_iosys, P2_iosys], inputs='u1', outputs=['y2']) assert P_s1.input_index == {'u1' : 0} P_s2 = ct.interconnect([P1_iosys, P2_iosys], input='u1', outputs=['y2']) assert P_s2.input_index == {'u1' : 0} P_s1 = ct.interconnect([P1_iosys, P2_iosys], inputs=['u1'], outputs='y2') assert P_s1.output_index == {'y2' : 0} P_s2 = ct.interconnect([P1_iosys, P2_iosys], inputs=['u1'], output='y2') assert P_s2.output_index == {'y2' : 0}
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'])
# # We construct the system using the InterconnectedSystem constructor and using # signal labels to keep track of everything. steering = ct.interconnect( # List of subsystems (trajgen, controller, vehicle), name='steering', # Interconnections between subsystems connections=(['controller.ex', 'trajgen.xd', '-vehicle.x'], ['controller.ey', 'trajgen.yd', '-vehicle.y'], ['controller.etheta', 'trajgen.thetad', '-vehicle.theta'], ['controller.vd', 'trajgen.vd'], ['controller.phid', 'trajgen.phid'], ['vehicle.v', 'controller.v' ], ['vehicle.phi', 'controller.phi']), # System inputs inplist=['trajgen.vref', 'trajgen.yref'], inputs=['yref', 'vref'], # System outputs outlist=[ 'vehicle.x', 'vehicle.y', 'vehicle.theta', 'controller.v', 'controller.phi' ], outputs=['x', 'y', 'theta', 'v', 'phi']) # Set up the simulation conditions yref = 1 T = np.linspace(0, 5, 100)