Exemplo n.º 1
0
 def sys222(self):
     """2-states square system (2 inputs x 2 outputs)"""
     A222 = [[4., 1.],
             [2., -3]]
     B222 = [[5., 2.],
             [-3., -3.]]
     C222 = [[2., -4],
             [0., 1.]]
     D222 = [[3., 2.],
             [1., -1.]]
     return StateSpace(A222, B222, C222, D222)
Exemplo n.º 2
0
    def test_copy_constructor(self):
        """Test the copy constructor"""
        # Create a set of matrices for a simple linear system
        A = np.array([[-1]])
        B = np.array([[1]])
        C = np.array([[1]])
        D = np.array([[0]])

        # Create the first linear system and a copy
        linsys = StateSpace(A, B, C, D)
        cpysys = StateSpace(linsys)

        # Change the original A matrix
        A[0, 0] = -2
        np.testing.assert_allclose(linsys.A, [[-1]])  # original value
        np.testing.assert_allclose(cpysys.A, [[-1]])  # original value

        # Change the A matrix for the original system
        linsys.A[0, 0] = -3
        np.testing.assert_allclose(cpysys.A, [[-1]])  # original value
Exemplo n.º 3
0
 def test_remove_useless_states(self):
     """Regression: _remove_useless_states gives correct ABC sizes."""
     g1 = StateSpace(np.zeros((3, 3)),
                     np.zeros((3, 4)),
                     np.zeros((5, 3)),
                     np.zeros((5, 4)))
     assert (0, 0) == g1.A.shape
     assert (0, 4) == g1.B.shape
     assert (5, 0) == g1.C.shape
     assert (5, 4) == g1.D.shape
     assert 0 == g1.states
Exemplo n.º 4
0
 def mimoss(self, request):
     """Test system with various dt values"""
     n = 5
     m = 3
     p = 2
     bx, bu = np.mgrid[1:n + 1, 1:m + 1]
     cy, cx = np.mgrid[1:p + 1, 1:n + 1]
     dy, du = np.mgrid[1:p + 1, 1:m + 1]
     return StateSpace(
         np.eye(5) + np.eye(5, 5, 1), bx * bu, cy * cx, dy * du,
         request.param)
Exemplo n.º 5
0
 def setUp(self):
     self.sys1 = TransferFunction([1, 2], [1, 2, 3])
     self.sys2 = TransferFunction([1], [1, 2, 3, 4])
     self.sys3 = StateSpace([[1., 4.], [3., 2.]], [[1.], [-4.]], [[1., 0.]],
                            [[0.]])
     s = TransferFunction([1, 0], [1])
     self.sys4 = (8.75*(4*s**2+0.4*s+1))/((100*s+1)*(s**2+0.22*s+1)) * \
                                   1./(s**2/(10.**2)+2*0.04*s/10.+1)
     self.stability_margins4 = [
         2.2716, 97.5941, 1.0454, 10.0053, 0.0850, 0.4973
     ]
Exemplo n.º 6
0
    def test_constructor(self, sys322ABCD, dt, argfun):
        """Test different ways to call the StateSpace() constructor"""
        args, kwargs = argfun(sys322ABCD + dt)
        sys = StateSpace(*args, **kwargs)

        dtref = defaults['control.default_dt'] if len(dt) == 0 else dt[0]
        np.testing.assert_almost_equal(sys.A, sys322ABCD[0])
        np.testing.assert_almost_equal(sys.B, sys322ABCD[1])
        np.testing.assert_almost_equal(sys.C, sys322ABCD[2])
        np.testing.assert_almost_equal(sys.D, sys322ABCD[3])
        assert sys.dt == dtref
Exemplo n.º 7
0
 def test_remove_useless_states(self):
     """Regression: _remove_useless_states gives correct ABC sizes"""
     g1 = StateSpace(np.zeros((3,3)),
                     np.zeros((3,4)),
                     np.zeros((5,3)),
                     np.zeros((5,4)))
     self.assertEqual((0,0), g1.A.shape)
     self.assertEqual((0,4), g1.B.shape)
     self.assertEqual((5,0), g1.C.shape)
     self.assertEqual((5,4), g1.D.shape)
     self.assertEqual(0, g1.states)
Exemplo n.º 8
0
    def test_matrixStaticGain(self):
        """Regression: can we create matrix static gains?"""
        d1 = np.matrix([[1,2,3],[4,5,6]])
        d2 = np.matrix([[7,8],[9,10],[11,12]])
        g1=StateSpace([],[],[],d1)

        # _remove_useless_states was making A = [[0]]
        self.assertEqual((0,0), g1.A.shape)

        g2=StateSpace([],[],[],d2)
        g3=StateSpace([],[],[],d2.T)

        h1 = g1*g2
        np.testing.assert_array_equal(d1*d2, h1.D)
        h2 = g1+g3
        np.testing.assert_array_equal(d1+d2.T, h2.D)
        h3 = g1.feedback(g2)
        np.testing.assert_array_almost_equal(solve(np.eye(2)+d1*d2,d1), h3.D)
        h4 = g1.append(g2)
        np.testing.assert_array_equal(block_diag(d1,d2),h4.D)
Exemplo n.º 9
0
    def testZero(self):
        """Evaluate the zeros of a SISO system."""

        sys = StateSpace(self.sys1.A, [[3.], [-2.], [4.]], [[-1., 3., 2.]],
                         [[-4.]])
        z = sys.zero()

        np.testing.assert_array_almost_equal(z, [
            4.26864638637134, -3.75932319318567 + 1.10087776649554j,
            -3.75932319318567 - 1.10087776649554j
        ])
Exemplo n.º 10
0
 def testMIMO(self):
     sys = StateSpace([[-0.5, 0.0], [0.0, -1.0]], [[1.0, 0.0], [0.0, 1.0]],
                      [[1.0, 0.0], [0.0, 1.0]], [[0.0, 0.0], [0.0, 0.0]])
     omega = np.logspace(-1, 2, 10)
     f1 = FRD(sys, omega)
     np.testing.assert_array_almost_equal(
         sys.frequency_response([0.1, 1.0, 10])[0],
         f1.frequency_response([0.1, 1.0, 10])[0])
     np.testing.assert_array_almost_equal(
         sys.frequency_response([0.1, 1.0, 10])[1],
         f1.frequency_response([0.1, 1.0, 10])[1])
Exemplo n.º 11
0
 def testMIMOMult(self):
     sys = StateSpace([[-0.5, 0.0], [0.0, -1.0]], [[1.0, 0.0], [0.0, 1.0]],
                      [[1.0, 0.0], [0.0, 1.0]], [[0.0, 0.0], [0.0, 0.0]])
     omega = np.logspace(-1, 2, 10)
     f1 = FRD(sys, omega)
     f2 = FRD(sys, omega)
     np.testing.assert_array_almost_equal(
         (f1 * f2).freqresp([0.1, 1.0, 10])[0],
         (sys * sys).freqresp([0.1, 1.0, 10])[0])
     np.testing.assert_array_almost_equal(
         (f1 * f2).freqresp([0.1, 1.0, 10])[1],
         (sys * sys).freqresp([0.1, 1.0, 10])[1])
Exemplo n.º 12
0
 def testMIMOfb(self):
     sys = StateSpace([[-0.5, 0.0], [0.0, -1.0]], [[1.0, 0.0], [0.0, 1.0]],
                      [[1.0, 0.0], [0.0, 1.0]], [[0.0, 0.0], [0.0, 0.0]])
     omega = np.logspace(-1, 2, 10)
     f1 = FRD(sys, omega).feedback([[0.1, 0.3], [0.0, 1.0]])
     f2 = FRD(sys.feedback([[0.1, 0.3], [0.0, 1.0]]), omega)
     np.testing.assert_array_almost_equal(
         f1.freqresp([0.1, 1.0, 10])[0],
         f2.freqresp([0.1, 1.0, 10])[0])
     np.testing.assert_array_almost_equal(
         f1.freqresp([0.1, 1.0, 10])[1],
         f2.freqresp([0.1, 1.0, 10])[1])
Exemplo n.º 13
0
 def test_matlab_style_constructor(self):
     # Use (deprecated?) matrix-style construction string (w/ warnings off)
     import warnings
     warnings.filterwarnings("ignore")  # turn off warnings
     sys = StateSpace("-1 1; 0 2", "0; 1", "1, 0", "0")
     warnings.resetwarnings()  # put things back to original state
     self.assertEqual(sys.A.shape, (2, 2))
     self.assertEqual(sys.B.shape, (2, 1))
     self.assertEqual(sys.C.shape, (1, 2))
     self.assertEqual(sys.D.shape, (1, 1))
     for X in [sys.A, sys.B, sys.C, sys.D]:
         self.assertTrue(isinstance(X, np.matrix))
Exemplo n.º 14
0
 def test_str(self, sys322):
     """Test that printing the system works"""
     tsys = sys322
     tref = ("A = [[-3.  4.  2.]\n"
             "     [-1. -3.  0.]\n"
             "     [ 2.  5.  3.]]\n"
             "\n"
             "B = [[ 1.  4.]\n"
             "     [-3. -3.]\n"
             "     [-2.  1.]]\n"
             "\n"
             "C = [[ 4.  2. -3.]\n"
             "     [ 1.  4.  3.]]\n"
             "\n"
             "D = [[-2.  4.]\n"
             "     [ 0.  1.]]\n")
     assert str(tsys) == tref
     tsysdtunspec = StateSpace(tsys.A, tsys.B, tsys.C, tsys.D, True)
     assert str(tsysdtunspec) == tref + "\ndt = True\n"
     sysdt1 = StateSpace(tsys.A, tsys.B, tsys.C, tsys.D, 1.)
     assert str(sysdt1) == tref + "\ndt = {}\n".format(1.)
    def test_array_access_ss(self):

        sys1 = StateSpace([[1., 2.], [3., 4.]], [[5., 6.], [6., 8.]],
                          [[9., 10.], [11., 12.]], [[13., 14.], [15., 16.]], 1)

        sys1_11 = sys1[0, 1]
        np.testing.assert_array_almost_equal(sys1_11.A, sys1.A)
        np.testing.assert_array_almost_equal(sys1_11.B, sys1.B[:, [1]])
        np.testing.assert_array_almost_equal(sys1_11.C, sys1.C[[0], :])
        np.testing.assert_array_almost_equal(sys1_11.D, sys1.D[0, 1])

        assert sys1.dt == sys1_11.dt
Exemplo n.º 16
0
 def testAgainstOctave(self):
     # with data from octave:
     #sys = ss([-2 0 0; 0 -1 1; 0 0 -3], [1 0; 0 0; 0 1], eye(3), zeros(3,2))
     #bfr = frd(bsys, [1])
     sys = StateSpace(np.matrix('-2.0 0 0; 0 -1 1; 0 0 -3'),
                      np.matrix('1.0 0; 0 0; 0 1'), np.eye(3),
                      np.zeros((3, 2)))
     omega = np.logspace(-1, 2, 10)
     f1 = FRD(sys, omega)
     np.testing.assert_array_almost_equal(
         (f1.freqresp([1.0])[0] *
          np.exp(1j * f1.freqresp([1.0])[1])).reshape(3, 2),
         np.matrix('0.4-0.2j 0; 0 0.1-0.2j; 0 0.3-0.1j'))
Exemplo n.º 17
0
 def plant(self, request):
     plants = {
         'syscont':
         TransferFunction(1, [1, 3, 0]),
         'sysdisc1':
         c2d(TransferFunction(1, [1, 3, 0]), .1),
         'syscont221':
         StateSpace([[-.3, 0], [1, 0]], [[
             -1,
         ], [
             .1,
         ]], [0, -.3], 0)
     }
     return plants[request.param]
Exemplo n.º 18
0
    def test_siso(self):
        B = np.matrix('0;1')
        D = 0
        sys = StateSpace(self.A, B, self.C, D)

        # test frequency response
        frq = sys.freqresp(self.omega)

        # test bode plot
        bode(sys)

        # Convert to transfer function and test bode
        systf = tf(sys)
        bode(systf)
Exemplo n.º 19
0
 def testAgainstOctave(self):
     # with data from octave:
     # sys = ss([-2 0 0; 0 -1 1; 0 0 -3],
     #  [1 0; 0 0; 0 1], eye(3), zeros(3,2))
     # bfr = frd(bsys, [1])
     sys = StateSpace(np.array([[-2.0, 0, 0], [0, -1, 1], [0, 0, -3]]),
                      np.array([[1.0, 0], [0, 0], [0, 1]]), np.eye(3),
                      np.zeros((3, 2)))
     omega = np.logspace(-1, 2, 10)
     f1 = FRD(sys, omega)
     np.testing.assert_array_almost_equal(
         (f1.frequency_response([1.0])[0] *
          np.exp(1j * f1.frequency_response([1.0])[1])).reshape(3, 2),
         np.array([[0.4 - 0.2j, 0], [0, 0.1 - 0.2j], [0, 0.3 - 0.1j]]))
Exemplo n.º 20
0
 def testAppendSS(self):
     """Test appending two state-space systems"""
     A1 = [[-2, 0.5, 0], [0.5, -0.3, 0], [0, 0, -0.1]]
     B1 = [[0.3, -1.3], [0.1, 0.], [1.0, 0.0]]
     C1 = [[0., 0.1, 0.0], [-0.3, -0.2, 0.0]]
     D1 = [[0., -0.8], [-0.3, 0.]]
     A2 = [[-1.]]
     B2 = [[1.2]]
     C2 = [[0.5]]
     D2 = [[0.4]]
     A3 = [[-2, 0.5, 0, 0], [0.5, -0.3, 0, 0], [0, 0, -0.1, 0],
           [0, 0, 0., -1.]]
     B3 = [[0.3, -1.3, 0], [0.1, 0., 0], [1.0, 0.0, 0], [0., 0, 1.2]]
     C3 = [[0., 0.1, 0.0, 0.0], [-0.3, -0.2, 0.0, 0.0], [0., 0., 0., 0.5]]
     D3 = [[0., -0.8, 0.], [-0.3, 0., 0.], [0., 0., 0.4]]
     sys1 = StateSpace(A1, B1, C1, D1)
     sys2 = StateSpace(A2, B2, C2, D2)
     sys3 = StateSpace(A3, B3, C3, D3)
     sys3c = sys1.append(sys2)
     np.testing.assert_array_almost_equal(sys3.A, sys3c.A)
     np.testing.assert_array_almost_equal(sys3.B, sys3c.B)
     np.testing.assert_array_almost_equal(sys3.C, sys3c.C)
     np.testing.assert_array_almost_equal(sys3.D, sys3c.D)
Exemplo n.º 21
0
 def testMIMOfb2(self):
     sys = StateSpace(np.array([[-2.0, 0, 0], [0, -1, 1], [0, 0, -3]]),
                      np.array([[1.0, 0], [0, 0], [0, 1]]), np.eye(3),
                      np.zeros((3, 2)))
     omega = np.logspace(-1, 2, 10)
     K = np.array([[1, 0.3, 0], [0.1, 0, 0]])
     f1 = FRD(sys, omega).feedback(K)
     f2 = FRD(sys.feedback(K), omega)
     np.testing.assert_array_almost_equal(
         f1.frequency_response([0.1, 1.0, 10])[0],
         f2.frequency_response([0.1, 1.0, 10])[0])
     np.testing.assert_array_almost_equal(
         f1.frequency_response([0.1, 1.0, 10])[1],
         f2.frequency_response([0.1, 1.0, 10])[1])
Exemplo n.º 22
0
 def testMIMOfb2(self):
     sys = StateSpace(np.matrix('-2.0 0 0; 0 -1 1; 0 0 -3'),
                      np.matrix('1.0 0; 0 0; 0 1'), np.eye(3),
                      np.zeros((3, 2)))
     omega = np.logspace(-1, 2, 10)
     K = np.matrix('1 0.3 0; 0.1 0 0')
     f1 = FRD(sys, omega).feedback(K)
     f2 = FRD(sys.feedback(K), omega)
     np.testing.assert_array_almost_equal(
         f1.freqresp([0.1, 1.0, 10])[0],
         f2.freqresp([0.1, 1.0, 10])[0])
     np.testing.assert_array_almost_equal(
         f1.freqresp([0.1, 1.0, 10])[1],
         f2.freqresp([0.1, 1.0, 10])[1])
Exemplo n.º 23
0
    def testEvalFr(self):
        """Evaluate the frequency response at one frequency."""

        A = [[-2, 0.5], [0.5, -0.3]]
        B = [[0.3, -1.3], [0.1, 0.]]
        C = [[0., 0.1], [-0.3, -0.2]]
        D = [[0., -0.8], [-0.3, 0.]]
        sys = StateSpace(A, B, C, D)

        resp = [[4.37636761487965e-05 - 0.0152297592997812j,
                 -0.792603938730853 + 0.0261706783369803j],
                [-0.331544857768052 + 0.0576105032822757j,
                 0.128919037199125 - 0.143824945295405j]]

        np.testing.assert_almost_equal(sys.evalfr(1.), resp)
Exemplo n.º 24
0
def reachable_form(xsys):
    """Convert a system into reachable canonical form
    Parameters
    ----------
    xsys : StateSpace object
        System to be transformed, with state `x`
    Returns
    -------
    zsys : StateSpace object
        System in reachable canonical form, with state `z`
    T : matrix
        Coordinate transformation: z = T * x
    """
    # Check to make sure we have a SISO system
    if not issiso(xsys):
        raise ControlNotImplemented(
            "Canonical forms for MIMO systems not yet supported")

    # Create a new system, starting with a copy of the old one
    zsys = StateSpace(xsys)

    # Generate the system matrices for the desired canonical form
    zsys.B = zeros(shape(xsys.B))
    zsys.B[0, 0] = 1.0
    zsys.A = zeros(shape(xsys.A))
    Apoly = poly(xsys.A)                # characteristic polynomial
    for i in range(0, xsys.states):
        zsys.A[0, i] = -Apoly[i+1] / Apoly[0]
        if (i+1 < xsys.states):
            zsys.A[i+1, i] = 1.0

    # Compute the reachability matrices for each set of states
    Wrx = ctrb(xsys.A, xsys.B)
    Wrz = ctrb(zsys.A, zsys.B)

    if matrix_rank(Wrx) != xsys.states:
        raise ValueError("System not controllable to working precision.")

    # Transformation from one form to another
    Tzx = solve(Wrx.T, Wrz.T).T  # matrix right division, Tzx = Wrz * inv(Wrx)

    if matrix_rank(Tzx) != xsys.states:
        raise ValueError("Transformation matrix singular to working precision.")

    # Finally, compute the output matrix
    zsys.C = solve(Tzx.T, xsys.C.T).T  # matrix right division, zsys.C = xsys.C * inv(Tzx)

    return zsys, Tzx
Exemplo n.º 25
0
 def testMIMOSmooth(self):
     sys = StateSpace([[-0.5, 0.0], [0.0, -1.0]], [[1.0, 0.0], [0.0, 1.0]],
                      [[1.0, 0.0], [0.0, 1.0], [1.0, 1.0]],
                      [[0.0, 0.0], [0.0, 0.0], [0.0, 0.0]])
     sys2 = np.array([[1, 0, 0], [0, 1, 0]]) * sys
     omega = np.logspace(-1, 2, 10)
     f1 = FRD(sys, omega, smooth=True)
     f2 = FRD(sys2, omega, smooth=True)
     np.testing.assert_array_almost_equal(
         (f1 * f2).frequency_response([0.1, 1.0, 10])[0],
         (sys * sys2).frequency_response([0.1, 1.0, 10])[0])
     np.testing.assert_array_almost_equal(
         (f1 * f2).frequency_response([0.1, 1.0, 10])[1],
         (sys * sys2).frequency_response([0.1, 1.0, 10])[1])
     np.testing.assert_array_almost_equal(
         (f1 * f2).frequency_response([0.1, 1.0, 10])[2],
         (sys * sys2).frequency_response([0.1, 1.0, 10])[2])
Exemplo n.º 26
0
    def test_dcgain_integrator(self):
        """DC gain when eigenvalue at DC returns appropriately sized array of nan"""
        # the SISO case is also tested in test_dc_gain_{cont,discr}
        import itertools
        # iterate over input and output sizes, and continuous (dt=None) and discrete (dt=True) time
        for inputs,outputs,dt in itertools.product(range(1,6),range(1,6),[None,True]):
            states = max(inputs,outputs)

            # a matrix that is singular at DC, and has no "useless" states as in _remove_useless_states
            a = np.triu(np.tile(2,(states,states)))
            # eigenvalues all +2, except for ...
            a[0,0] = 0 if dt is None else 1
            b = np.eye(max(inputs,states))[:states,:inputs]
            c = np.eye(max(outputs,states))[:outputs,:states]
            d = np.zeros((outputs,inputs))
            sys = StateSpace(a,b,c,d,dt)
            dc = np.squeeze(np.tile(np.nan,(outputs,inputs)))
            np.testing.assert_array_equal(dc, sys.dcgain())
Exemplo n.º 27
0
 def test_repr(self):
     ref322 = """StateSpace(array([[-3.,  4.,  2.],
    [-1., -3.,  0.],
    [ 2.,  5.,  3.]]), array([[ 1.,  4.],
    [-3., -3.],
    [-2.,  1.]]), array([[ 4.,  2., -3.],
    [ 1.,  4.,  3.]]), array([[-2.,  4.],
    [ 0.,  1.]]){dt})"""
     self.assertEqual(repr(self.sys322), ref322.format(dt=''))
     sysd = StateSpace(self.sys322.A, self.sys322.B, self.sys322.C,
                       self.sys322.D, 0.4)
     self.assertEqual(repr(sysd), ref322.format(dt=", 0.4"))
     array = np.array
     sysd2 = eval(repr(sysd))
     np.testing.assert_allclose(sysd.A, sysd2.A)
     np.testing.assert_allclose(sysd.B, sysd2.B)
     np.testing.assert_allclose(sysd.C, sysd2.C)
     np.testing.assert_allclose(sysd.D, sysd2.D)
Exemplo n.º 28
0
def test_siso():
    """Test SISO frequency response"""
    A = np.array([[1, 1], [0, 1]])
    B = np.array([[0], [1]])
    C = np.array([[1, 0]])
    D = 0
    sys = StateSpace(A, B, C, D)
    omega = np.linspace(10e-2, 10e2, 1000)

    # test frequency response
    sys.freqresp(omega)

    # test bode plot
    bode(sys)

    # Convert to transfer function and test bode
    systf = tf(sys)
    bode(systf)
Exemplo n.º 29
0
    def testMinreal(self):
        """Test a minreal model reduction"""
        #A = [-2, 0.5, 0; 0.5, -0.3, 0; 0, 0, -0.1]
        A = [[-2, 0.5, 0], [0.5, -0.3, 0], [0, 0, -0.1]]
        #B = [0.3, -1.3; 0.1, 0; 1, 0]
        B = [[0.3, -1.3], [0.1, 0.], [1.0, 0.0]]
        #C = [0, 0.1, 0; -0.3, -0.2, 0]
        C = [[0., 0.1, 0.0], [-0.3, -0.2, 0.0]]
        #D = [0 -0.8; -0.3 0]
        D = [[0., -0.8], [-0.3, 0.]]
        # sys = ss(A, B, C, D)

        sys = StateSpace(A, B, C, D)
        sysr = sys.minreal()
        self.assertEqual(sysr.states, 2)
        self.assertEqual(sysr.inputs, sys.inputs)
        self.assertEqual(sysr.outputs, sys.outputs)
        np.testing.assert_array_almost_equal(
            eigvals(sysr.A), [-2.136154, -0.1638459])
Exemplo n.º 30
0
 def sys623(self):
     """sys3: 6 states non square system (2 inputs x 3 outputs)"""
     A623 = np.array([[1, 0, 0, 0, 0, 0],
                      [0, 1, 0, 0, 0, 0],
                      [0, 0, 3, 0, 0, 0],
                      [0, 0, 0, -4, 0, 0],
                      [0, 0, 0, 0, -1, 0],
                      [0, 0, 0, 0, 0, 3]])
     B623 = np.array([[0, -1],
                     [-1, 0],
                     [1, -1],
                     [0, 0],
                     [0, 1],
                     [-1, -1]])
     C623 = np.array([[1, 0, 0, 1, 0, 0],
                      [0, 1, 0, 1, 0, 1],
                      [0, 0, 1, 0, 0, 1]])
     D623 = np.zeros((3, 2))
     return StateSpace(A623, B623, C623, D623)