コード例 #1
0
ファイル: iosys_test.py プロジェクト: magnusxd/AMaDiA
    def test_discrete(self):
        """Test discrete time functionality"""
        # Create some linear and nonlinear systems to play with
        linsys = ct.StateSpace(
            [[-1, 1], [0, -2]], [[0], [1]], [[1, 0]], [[0]], True)
        lnios = ios.LinearIOSystem(linsys)

        # Set up parameters for simulation
        T, U, X0 = self.T, self.U, self.X0

        # Simulate and compare to LTI output
        ios_t, ios_y = ios.input_output_response(lnios, T, U, X0)
        lin_t, lin_y, lin_x = ct.forced_response(linsys, T, U, X0)
        np.testing.assert_array_almost_equal(ios_t, lin_t, decimal=3)
        np.testing.assert_array_almost_equal(ios_y, lin_y, decimal=3)

        # Test MIMO system, converted to discrete time
        linsys = ct.StateSpace(self.mimo_linsys1)
        linsys.dt = self.T[1] - self.T[0]
        lnios = ios.LinearIOSystem(linsys)

        # Set up parameters for simulation
        T = self.T
        U = [np.sin(T), np.cos(T)]
        X0 = 0

        # Simulate and compare to LTI output
        ios_t, ios_y = ios.input_output_response(lnios, T, U, X0)
        lin_t, lin_y, lin_x = ct.forced_response(linsys, T, U, X0)
        np.testing.assert_array_almost_equal(ios_t, lin_t, decimal=3)
        np.testing.assert_array_almost_equal(ios_y, lin_y, decimal=3)
コード例 #2
0
ファイル: iosys_test.py プロジェクト: magnusxd/AMaDiA
    def test_connect(self):
        # Define a couple of (linear) systems to interconnection
        linsys1 = self.siso_linsys
        iosys1 = ios.LinearIOSystem(linsys1)
        linsys2 = self.siso_linsys
        iosys2 = ios.LinearIOSystem(linsys2)

        # Connect systems in different ways and compare to StateSpace
        linsys_series = linsys2 * linsys1
        iosys_series = ios.InterconnectedSystem(
            (iosys1, iosys2),   # systems
            ((1, 0),),          # interconnection (series)
            0,                  # input = first system
            1                   # output = second system
        )

        # Run a simulation and compare to linear response
        T, U = self.T, self.U
        X0 = np.concatenate((self.X0, self.X0))
        ios_t, ios_y, ios_x = ios.input_output_response(
            iosys_series, T, U, X0, return_x=True)
        lti_t, lti_y, lti_x = ct.forced_response(linsys_series, T, U, X0)
        np.testing.assert_array_almost_equal(lti_t, ios_t)
        np.testing.assert_array_almost_equal(lti_y, ios_y, decimal=3)

        # Connect systems with different timebases
        linsys2c = self.siso_linsys
        linsys2c.dt = 0         # Reset the timebase
        iosys2c = ios.LinearIOSystem(linsys2c)
        iosys_series = ios.InterconnectedSystem(
            (iosys1, iosys2c),   # systems
            ((1, 0),),          # interconnection (series)
            0,                  # input = first system
            1                   # output = second system
        )
        self.assertTrue(ct.isctime(iosys_series, strict=True))
        ios_t, ios_y, ios_x = ios.input_output_response(
            iosys_series, T, U, X0, return_x=True)
        lti_t, lti_y, lti_x = ct.forced_response(linsys_series, T, U, X0)
        np.testing.assert_array_almost_equal(lti_t, ios_t)
        np.testing.assert_array_almost_equal(lti_y, ios_y, decimal=3)

        # Feedback interconnection
        linsys_feedback = ct.feedback(linsys1, linsys2)
        iosys_feedback = ios.InterconnectedSystem(
            (iosys1, iosys2),   # systems
            ((1, 0),            # input of sys2 = output of sys1
             (0, (1, 0, -1))),  # input of sys1 = -output of sys2
            0,                  # input = first system
            0                   # output = first system
        )
        ios_t, ios_y, ios_x = ios.input_output_response(
            iosys_feedback, T, U, X0, return_x=True)
        lti_t, lti_y, lti_x = ct.forced_response(linsys_feedback, T, U, X0)
        np.testing.assert_array_almost_equal(lti_t, ios_t)
        np.testing.assert_array_almost_equal(lti_y, ios_y, decimal=3)
コード例 #3
0
ファイル: iosys_test.py プロジェクト: magnusxd/AMaDiA
    def test_nonsquare_bdalg(self):
        # Set up parameters for simulation
        T = self.T
        U2 = [np.sin(T), np.cos(T)]
        U3 = [np.sin(T), np.cos(T), T]
        X0 = 0

        # Set up systems to be composed
        linsys_2i3o = ct.StateSpace(
            [[-1, 1, 0], [0, -2, 0], [0, 0, -3]], [[1, 0], [0, 1], [1, 1]],
            [[1, 0, 0], [0, 1, 0], [0, 0, 1]], np.zeros((3, 2)))
        iosys_2i3o = ios.LinearIOSystem(linsys_2i3o)

        linsys_3i2o = ct.StateSpace(
            [[-1, 1, 0], [0, -2, 0], [0, 0, -3]],
            [[1, 0, 0], [0, 1, 0], [0, 0, 1]],
            [[1, 0, 1], [0, 1, -1]], np.zeros((2, 3)))
        iosys_3i2o = ios.LinearIOSystem(linsys_3i2o)

        # Multiplication
        linsys_multiply = linsys_3i2o * linsys_2i3o
        iosys_multiply = iosys_3i2o * iosys_2i3o
        lin_t, lin_y, lin_x = ct.forced_response(linsys_multiply, T, U2, X0)
        ios_t, ios_y = ios.input_output_response(iosys_multiply, T, U2, X0)
        np.testing.assert_array_almost_equal(ios_y, lin_y, decimal=3)

        linsys_multiply = linsys_2i3o * linsys_3i2o
        iosys_multiply = iosys_2i3o * iosys_3i2o
        lin_t, lin_y, lin_x = ct.forced_response(linsys_multiply, T, U3, X0)
        ios_t, ios_y = ios.input_output_response(iosys_multiply, T, U3, X0)
        np.testing.assert_array_almost_equal(ios_y, lin_y, decimal=3)

        # Right multiplication
        # TODO: add real tests once conversion from other types is supported
        iosys_multiply = ios.InputOutputSystem.__rmul__(iosys_3i2o, iosys_2i3o)
        ios_t, ios_y = ios.input_output_response(iosys_multiply, T, U3, X0)
        np.testing.assert_array_almost_equal(ios_y, lin_y, decimal=3)

        # Feedback
        linsys_multiply = ct.feedback(linsys_3i2o, linsys_2i3o)
        iosys_multiply = iosys_3i2o.feedback(iosys_2i3o)
        lin_t, lin_y, lin_x = ct.forced_response(linsys_multiply, T, U3, X0)
        ios_t, ios_y = ios.input_output_response(iosys_multiply, T, U3, X0)
        np.testing.assert_array_almost_equal(ios_y, lin_y, decimal=3)

        # Mismatch should generate exception
        args = (iosys_3i2o, iosys_3i2o)
        self.assertRaises(ValueError, ct.series, *args)
コード例 #4
0
ファイル: iosys_test.py プロジェクト: magnusxd/AMaDiA
    def test_linearize(self):
        # Create a single input/single output linear system
        linsys = self.siso_linsys
        iosys = ios.LinearIOSystem(linsys)

        # Linearize it and make sure we get back what we started with
        linearized = iosys.linearize([0, 0], 0)
        np.testing.assert_array_almost_equal(linsys.A, linearized.A)
        np.testing.assert_array_almost_equal(linsys.B, linearized.B)
        np.testing.assert_array_almost_equal(linsys.C, linearized.C)
        np.testing.assert_array_almost_equal(linsys.D, linearized.D)

        # Create a simple nonlinear system to check (kinematic car)
        def kincar_update(t, x, u, params):
            return np.array([np.cos(x[2]) * u[0], np.sin(x[2]) * u[0], u[1]])
        def kincar_output(t, x, u, params):
            return np.array([x[0], x[1]])
        iosys = ios.NonlinearIOSystem(kincar_update, kincar_output)
        linearized = iosys.linearize([0, 0, 0], [0, 0])
        np.testing.assert_array_almost_equal(linearized.A, np.zeros((3,3)))
        np.testing.assert_array_almost_equal(
            linearized.B, [[1, 0], [0, 0], [0, 1]])
        np.testing.assert_array_almost_equal(
            linearized.C, [[1, 0, 0], [0, 1, 0]])
        np.testing.assert_array_almost_equal(linearized.D, np.zeros((2,2)))
コード例 #5
0
ファイル: iosys_test.py プロジェクト: magnusxd/AMaDiA
    def test_bdalg_functions(self):
        """Test block diagram functions algebra on I/O systems"""
        # Set up parameters for simulation
        T = self.T
        U = [np.sin(T), np.cos(T)]
        X0 = 0

        # Set up systems to be composed
        linsys1 = self.mimo_linsys1
        linio1 = ios.LinearIOSystem(linsys1)
        linsys2 = self.mimo_linsys2
        linio2 = ios.LinearIOSystem(linsys2)

        # Series interconnection
        linsys_series = ct.series(linsys1, linsys2)
        iosys_series = ct.series(linio1, linio2)
        lin_t, lin_y, lin_x = ct.forced_response(linsys_series, T, U, X0)
        ios_t, ios_y = ios.input_output_response(iosys_series, T, U, X0)
        np.testing.assert_array_almost_equal(ios_y, lin_y, decimal=3)

        # Make sure that systems don't commute
        linsys_series = ct.series(linsys2, linsys1)
        lin_t, lin_y, lin_x = ct.forced_response(linsys_series, T, U, X0)
        self.assertFalse((np.abs(lin_y - ios_y) < 1e-3).all())

        # Parallel interconnection
        linsys_parallel = ct.parallel(linsys1, linsys2)
        iosys_parallel = ct.parallel(linio1, linio2)
        lin_t, lin_y, lin_x = ct.forced_response(linsys_parallel, T, U, X0)
        ios_t, ios_y = ios.input_output_response(iosys_parallel, T, U, X0)
        np.testing.assert_array_almost_equal(ios_y, lin_y, decimal=3)

        # Negation
        linsys_negate = ct.negate(linsys1)
        iosys_negate = ct.negate(linio1)
        lin_t, lin_y, lin_x = ct.forced_response(linsys_negate, T, U, X0)
        ios_t, ios_y = ios.input_output_response(iosys_negate, T, U, X0)
        np.testing.assert_array_almost_equal(ios_y, lin_y, decimal=3)

        # Feedback interconnection
        linsys_feedback = ct.feedback(linsys1, linsys2)
        iosys_feedback = ct.feedback(linio1, linio2)
        lin_t, lin_y, lin_x = ct.forced_response(linsys_feedback, T, U, X0)
        ios_t, ios_y = ios.input_output_response(iosys_feedback, T, U, X0)
        np.testing.assert_array_almost_equal(ios_y, lin_y, decimal=3)
コード例 #6
0
ファイル: iosys_test.py プロジェクト: magnusxd/AMaDiA
    def test_feedback(self):
        # Set up parameters for simulation
        T, U, X0 = self.T, self.U, self.X0

        # Linear system with constant feedback (via "nonlinear" mapping)
        ioslin = ios.LinearIOSystem(self.siso_linsys)
        nlios =  ios.NonlinearIOSystem(None, \
            lambda t, x, u, params: u, inputs=1, outputs=1)
        iosys = ct.feedback(ioslin, nlios)
        linsys = ct.feedback(self.siso_linsys, 1)

        ios_t, ios_y = ios.input_output_response(iosys, T, U, X0)
        lti_t, lti_y, lti_x = ct.forced_response(linsys, T, U, X0)
        np.testing.assert_array_almost_equal(ios_y, lti_y, decimal=3)
コード例 #7
0
ファイル: iosys_test.py プロジェクト: magnusxd/AMaDiA
    def test_summer(self):
        # Construct a MIMO system for testing
        linsys = self.mimo_linsys1
        linio = ios.LinearIOSystem(linsys)

        linsys_parallel = linsys + linsys
        iosys_parallel = linio + linio

        # Set up parameters for simulation
        T = self.T
        U = [np.sin(T), np.cos(T)]
        X0 = 0

        lin_t, lin_y, lin_x = ct.forced_response(linsys_parallel, T, U, X0)
        ios_t, ios_y = ios.input_output_response(iosys_parallel, T, U, X0)
        np.testing.assert_array_almost_equal(ios_y, lin_y, decimal=3)
コード例 #8
0
ファイル: iosys_test.py プロジェクト: magnusxd/AMaDiA
    def test_linear_iosys(self):
        # Create an input/output system from the linear system
        linsys = self.siso_linsys
        iosys = ios.LinearIOSystem(linsys)

        # Make sure that the right hand side matches linear system
        for x, u in (([0, 0], 0), ([1, 0], 0), ([0, 1], 0), ([0, 0], 1)):
            np.testing.assert_array_almost_equal(
                np.reshape(iosys._rhs(0, x, u), (-1,1)),
                linsys.A * np.reshape(x, (-1, 1)) + linsys.B * u)

        # Make sure that simulations also line up
        T, U, X0 = self.T, self.U, self.X0
        lti_t, lti_y, lti_x = ct.forced_response(linsys, T, U, X0)
        ios_t, ios_y = ios.input_output_response(iosys, T, U, X0)
        np.testing.assert_array_almost_equal(lti_t, ios_t)
        np.testing.assert_array_almost_equal(lti_y, ios_y, decimal=3)
コード例 #9
0
ファイル: iosys_test.py プロジェクト: magnusxd/AMaDiA
    def test_rmul(self):
        # Test right multiplication
        # TODO: replace with better tests when conversions are implemented

        # Set up parameters for simulation
        T, U, X0 = self.T, self.U, self.X0

        # Linear system with input and output nonlinearities
        # Also creates a nested interconnected system
        ioslin = ios.LinearIOSystem(self.siso_linsys)
        nlios =  ios.NonlinearIOSystem(None, \
            lambda t, x, u, params: u*u, inputs=1, outputs=1)
        sys1 = nlios * ioslin
        sys2 = ios.InputOutputSystem.__rmul__(nlios, sys1)

        # Make sure we got the right thing (via simulation comparison)
        ios_t, ios_y = ios.input_output_response(sys2, T, U, X0)
        lti_t, lti_y, lti_x = ct.forced_response(ioslin, T, U*U, X0)
        np.testing.assert_array_almost_equal(ios_y, lti_y*lti_y, decimal=3)
コード例 #10
0
ファイル: iosys_test.py プロジェクト: magnusxd/AMaDiA
    def test_neg(self):
        """Test negation of a system"""

        # Set up parameters for simulation
        T, U, X0 = self.T, self.U, self.X0

        # Static nonlinear system
        nlios =  ios.NonlinearIOSystem(None, \
            lambda t, x, u, params: u*u, inputs=1, outputs=1)
        ios_t, ios_y = ios.input_output_response(-nlios, T, U, X0)
        np.testing.assert_array_almost_equal(ios_y, -U*U, decimal=3)

        # Linear system with input nonlinearity
        # Also creates a nested interconnected system
        ioslin = ios.LinearIOSystem(self.siso_linsys)
        sys = (ioslin) * (-nlios)

        # Make sure we got the right thing (via simulation comparison)
        ios_t, ios_y = ios.input_output_response(sys, T, U, X0)
        lti_t, lti_y, lti_x = ct.forced_response(ioslin, T, U*U, X0)
        np.testing.assert_array_almost_equal(ios_y, -lti_y, decimal=3)
コード例 #11
0
ファイル: iosys_test.py プロジェクト: magnusxd/AMaDiA
    def test_static_nonlinearity(self):
        # Linear dynamical system
        linsys = self.siso_linsys
        ioslin = ios.LinearIOSystem(linsys)

        # Nonlinear saturation
        sat = lambda u: u if abs(u) < 1 else np.sign(u)
        sat_output = lambda t, x, u, params: sat(u)
        nlsat =  ios.NonlinearIOSystem(None, sat_output, inputs=1, outputs=1)

        # Set up parameters for simulation
        T, U, X0 = self.T, 2 * self.U, self.X0
        Usat = np.vectorize(sat)(U)

        # Make sure saturation works properly by comparing linear system with
        # saturated input to nonlinear system with saturation composition
        lti_t, lti_y, lti_x = ct.forced_response(linsys, T, Usat, X0)
        ios_t, ios_y, ios_x = ios.input_output_response(
            ioslin * nlsat, T, U, X0, return_x=True)
        np.testing.assert_array_almost_equal(lti_t, ios_t)
        np.testing.assert_array_almost_equal(lti_y, ios_y, decimal=2)
コード例 #12
0
ファイル: iosys_test.py プロジェクト: magnusxd/AMaDiA
    def test_named_signals(self):
        sys1 = ios.NonlinearIOSystem(
            updfcn = lambda t, x, u, params: np.array(
                np.dot(self.mimo_linsys1.A, np.reshape(x, (-1, 1))) \
                + np.dot(self.mimo_linsys1.B, np.reshape(u, (-1, 1)))
            ).reshape(-1,),
            outfcn = lambda t, x, u, params: np.array(
                self.mimo_linsys1.C * np.reshape(x, (-1, 1)) \
                + self.mimo_linsys1.D * np.reshape(u, (-1, 1))
            ).reshape(-1,),
            inputs = ('u[0]', 'u[1]'),
            outputs = ('y[0]', 'y[1]'),
            states = self.mimo_linsys1.states,
            name = 'sys1')
        sys2 = ios.LinearIOSystem(self.mimo_linsys2,
            inputs = ('u[0]', 'u[1]'),
            outputs = ('y[0]', 'y[1]'),
            name = 'sys2')

        # Series interconnection (sys1 * sys2) using __mul__
        ios_mul = sys1 * sys2
        ss_series = self.mimo_linsys1 * self.mimo_linsys2
        lin_series = ct.linearize(ios_mul, 0, 0)
        for M, N in ((ss_series.A, lin_series.A), (ss_series.B, lin_series.B),
                     (ss_series.C, lin_series.C), (ss_series.D, lin_series.D)):
            np.testing.assert_array_almost_equal(M, N)

        # Series interconnection (sys1 * sys2) using series
        ios_series = ct.series(sys2, sys1)
        ss_series = ct.series(self.mimo_linsys2, self.mimo_linsys1)
        lin_series = ct.linearize(ios_series, 0, 0)
        for M, N in ((ss_series.A, lin_series.A), (ss_series.B, lin_series.B),
                     (ss_series.C, lin_series.C), (ss_series.D, lin_series.D)):
            np.testing.assert_array_almost_equal(M, N)

        # Series interconnection (sys1 * sys2) using named + mixed signals
        ios_connect = ios.InterconnectedSystem(
            (sys2, sys1),
            connections=(
                (('sys1', 'u[0]'), 'sys2.y[0]'),
                ('sys1.u[1]', 'sys2.y[1]')
            ),
            inplist=('sys2.u[0]', ('sys2', 1)),
            outlist=((1, 'y[0]'), 'sys1.y[1]')
        )
        lin_series = ct.linearize(ios_connect, 0, 0)
        for M, N in ((ss_series.A, lin_series.A), (ss_series.B, lin_series.B),
                     (ss_series.C, lin_series.C), (ss_series.D, lin_series.D)):
            np.testing.assert_array_almost_equal(M, N)

        # Make sure that we can use input signal names as system outputs
        ios_connect = ios.InterconnectedSystem(
            (sys1, sys2),
            connections=(
                ('sys2.u[0]', 'sys1.y[0]'), ('sys2.u[1]', 'sys1.y[1]'),
                ('sys1.u[0]', '-sys2.y[0]'), ('sys1.u[1]', '-sys2.y[1]')
            ),
            inplist=('sys1.u[0]', 'sys1.u[1]'),
            outlist=('sys2.u[0]', 'sys2.u[1]')  # = sys1.y[0], sys1.y[1]
        )
        ss_feedback = ct.feedback(self.mimo_linsys1, self.mimo_linsys2)
        lin_feedback = ct.linearize(ios_connect, 0, 0)
        np.testing.assert_array_almost_equal(ss_feedback.A, lin_feedback.A)
        np.testing.assert_array_almost_equal(ss_feedback.B, lin_feedback.B)
        np.testing.assert_array_almost_equal(ss_feedback.C, lin_feedback.C)
        np.testing.assert_array_almost_equal(ss_feedback.D, lin_feedback.D)
コード例 #13
0
ファイル: iosys_test.py プロジェクト: magnusxd/AMaDiA
    def test_params(self):
        # Start with the default set of parameters
        ios_secord_default = ios.NonlinearIOSystem(
            secord_update, secord_output, inputs=1, outputs=1, states=2)
        lin_secord_default = ios.linearize(ios_secord_default, [0, 0], [0])
        w_default, v_default = np.linalg.eig(lin_secord_default.A)

        # New copy, with modified parameters
        ios_secord_update = ios.NonlinearIOSystem(
            secord_update, secord_output, inputs=1, outputs=1, states=2,
            params={'omega0':2, 'zeta':0})

        # Make sure the default parameters haven't changed
        lin_secord_check = ios.linearize(ios_secord_default, [0, 0], [0])
        w, v = np.linalg.eig(lin_secord_check.A)
        np.testing.assert_array_almost_equal(np.sort(w), np.sort(w_default))

        # Make sure updated system parameters got set correctly
        lin_secord_update = ios.linearize(ios_secord_update, [0, 0], [0])
        w, v = np.linalg.eig(lin_secord_update.A)
        np.testing.assert_array_almost_equal(np.sort(w), np.sort([2j, -2j]))

        # Change the parameters of the default sys just for the linearization
        lin_secord_local = ios.linearize(ios_secord_default, [0, 0], [0],
                                          params={'zeta':0})
        w, v = np.linalg.eig(lin_secord_local.A)
        np.testing.assert_array_almost_equal(np.sort(w), np.sort([1j, -1j]))

        # Change the parameters of the updated sys just for the linearization
        lin_secord_local = ios.linearize(ios_secord_update, [0, 0], [0],
                                          params={'zeta':0, 'omega0':3})
        w, v = np.linalg.eig(lin_secord_local.A)
        np.testing.assert_array_almost_equal(np.sort(w), np.sort([3j, -3j]))

        # Make sure that changes propagate through interconnections
        ios_series_default_local = ios_secord_default * ios_secord_update
        lin_series_default_local = ios.linearize(
            ios_series_default_local, [0, 0, 0, 0], [0])
        w, v = np.linalg.eig(lin_series_default_local.A)
        np.testing.assert_array_almost_equal(
            np.sort(w), np.sort(np.concatenate((w_default, [2j, -2j]))))

        # Show that we can change the parameters at linearization
        lin_series_override = ios.linearize(
            ios_series_default_local, [0, 0, 0, 0], [0],
            params={'zeta':0, 'omega0':4})
        w, v = np.linalg.eig(lin_series_override.A)
        np.testing.assert_array_almost_equal(w, [4j, -4j, 4j, -4j])

        # Check for warning if we try to set params for LinearIOSystem
        linsys = self.siso_linsys
        iosys = ios.LinearIOSystem(linsys)
        T, U, X0 = self.T, self.U, self.X0
        lti_t, lti_y, lti_x = ct.forced_response(linsys, T, U, X0)
        with warnings.catch_warnings(record=True) as warnval:
            # Turn off deprecation warnings
            warnings.simplefilter("ignore", category=DeprecationWarning)
            warnings.simplefilter("ignore", category=PendingDeprecationWarning)

            # Trigger a warning
            ios_t, ios_y = ios.input_output_response(
                iosys, T, U, X0, params={'something':0})

            # Verify that we got a warning
            self.assertEqual(len(warnval), 1)
            self.assertTrue(issubclass(warnval[-1].category, UserWarning))
            self.assertTrue("LinearIOSystem" in str(warnval[-1].message))
            self.assertTrue("ignored" in str(warnval[-1].message))

        # Check to make sure results are OK
        np.testing.assert_array_almost_equal(lti_t, ios_t)
        np.testing.assert_array_almost_equal(lti_y, ios_y, decimal=3)
コード例 #14
0
ファイル: iosys_test.py プロジェクト: magnusxd/AMaDiA
    def test_find_eqpts(self):
        """Test find_eqpt function"""
        # Simple equilibrium point with no inputs
        nlsys = ios.NonlinearIOSystem(predprey)
        xeq, ueq, result = ios.find_eqpt(
            nlsys, [1.6, 1.2], None, return_result=True)
        self.assertTrue(result.success)
        np.testing.assert_array_almost_equal(xeq, [1.64705879, 1.17923874])
        np.testing.assert_array_almost_equal(
            nlsys._rhs(0, xeq, ueq), np.zeros((2,)))

        # Ducted fan dynamics with output = velocity
        nlsys = ios.NonlinearIOSystem(pvtol, lambda t, x, u, params: x[0:2])

        # Make sure the origin is a fixed point
        xeq, ueq, result = ios.find_eqpt(
            nlsys, [0, 0, 0, 0], [0, 4*9.8], return_result=True)
        self.assertTrue(result.success)
        np.testing.assert_array_almost_equal(
            nlsys._rhs(0, xeq, ueq), np.zeros((4,)))
        np.testing.assert_array_almost_equal(xeq, [0, 0, 0, 0])

        # Use a small lateral force to cause motion
        xeq, ueq, result = ios.find_eqpt(
            nlsys, [0, 0, 0, 0], [0.01, 4*9.8], return_result=True)
        self.assertTrue(result.success)
        np.testing.assert_array_almost_equal(
            nlsys._rhs(0, xeq, ueq), np.zeros((4,)), decimal=5)

        # Equilibrium point with fixed output
        xeq, ueq, result = ios.find_eqpt(
            nlsys, [0, 0, 0, 0], [0.01, 4*9.8],
            y0=[0.1, 0.1], return_result=True)
        self.assertTrue(result.success)
        np.testing.assert_array_almost_equal(
            nlsys._out(0, xeq, ueq), [0.1, 0.1], decimal=5)
        np.testing.assert_array_almost_equal(
            nlsys._rhs(0, xeq, ueq), np.zeros((4,)), decimal=5)

        # Specify outputs to constrain (replicate previous)
        xeq, ueq, result = ios.find_eqpt(
            nlsys, [0, 0, 0, 0], [0.01, 4*9.8], y0=[0.1, 0.1],
            iy = [0, 1], return_result=True)
        self.assertTrue(result.success)
        np.testing.assert_array_almost_equal(
            nlsys._out(0, xeq, ueq), [0.1, 0.1], decimal=5)
        np.testing.assert_array_almost_equal(
            nlsys._rhs(0, xeq, ueq), np.zeros((4,)), decimal=5)

        # Specify inputs to constrain (replicate previous), w/ no result
        xeq, ueq = ios.find_eqpt(
            nlsys, [0, 0, 0, 0], [0.01, 4*9.8], y0=[0.1, 0.1], iu = [])
        np.testing.assert_array_almost_equal(
            nlsys._out(0, xeq, ueq), [0.1, 0.1], decimal=5)
        np.testing.assert_array_almost_equal(
            nlsys._rhs(0, xeq, ueq), np.zeros((4,)), decimal=5)

        # Now solve the problem with the original PVTOL variables
        # Constrain the output angle and x velocity
        nlsys_full = ios.NonlinearIOSystem(pvtol_full, None)
        xeq, ueq, result = ios.find_eqpt(
            nlsys_full, [0, 0, 0, 0, 0, 0], [0.01, 4*9.8],
            y0=[0, 0, 0.1, 0.1, 0, 0], iy = [2, 3],
            idx=[2, 3, 4, 5], ix=[0, 1], return_result=True)
        self.assertTrue(result.success)
        np.testing.assert_array_almost_equal(
            nlsys_full._out(0, xeq, ueq)[[2, 3]], [0.1, 0.1], decimal=5)
        np.testing.assert_array_almost_equal(
            nlsys_full._rhs(0, xeq, ueq)[-4:], np.zeros((4,)), decimal=5)

        # Fix one input and vary the other
        nlsys_full = ios.NonlinearIOSystem(pvtol_full, None)
        xeq, ueq, result = ios.find_eqpt(
            nlsys_full, [0, 0, 0, 0, 0, 0], [0.01, 4*9.8],
            y0=[0, 0, 0.1, 0.1, 0, 0], iy=[3], iu=[1],
            idx=[2, 3, 4, 5], ix=[0, 1], return_result=True)
        self.assertTrue(result.success)
        np.testing.assert_almost_equal(ueq[1], 4*9.8, decimal=5)
        np.testing.assert_array_almost_equal(
            nlsys_full._out(0, xeq, ueq)[[3]], [0.1], decimal=5)
        np.testing.assert_array_almost_equal(
            nlsys_full._rhs(0, xeq, ueq)[-4:], np.zeros((4,)), decimal=5)

        # PVTOL with output = y velocity
        xeq, ueq, result = ios.find_eqpt(
            nlsys_full, [0, 0, 0, 0.1, 0, 0], [0.01, 4*9.8],
            y0=[0, 0, 0, 0.1, 0, 0], iy=[3],
            dx0=[0.1, 0, 0, 0, 0, 0], idx=[1, 2, 3, 4, 5],
            ix=[0, 1], return_result=True)
        self.assertTrue(result.success)
        np.testing.assert_array_almost_equal(
            nlsys_full._out(0, xeq, ueq)[-3:], [0.1, 0, 0], decimal=5)
        np.testing.assert_array_almost_equal(
            nlsys_full._rhs(0, xeq, ueq)[-5:], np.zeros((5,)), decimal=5)

        # Unobservable system
        linsys = ct.StateSpace(
            [[-1, 1], [0, -2]], [[0], [1]], [[0, 0]], [[0]])
        lnios = ios.LinearIOSystem(linsys)

        # If result is returned, user has to check
        xeq, ueq, result = ios.find_eqpt(
            lnios, [0, 0], [0], y0=[1], return_result=True)
        self.assertFalse(result.success)

        # If result is not returned, find_eqpt should return None
        xeq, ueq = ios.find_eqpt(lnios, [0, 0], [0], y0=[1])
        self.assertEqual(xeq, None)
        self.assertEqual(ueq, None)
コード例 #15
0
ファイル: iosys_test.py プロジェクト: magnusxd/AMaDiA
    def test_algebraic_loop(self):
        # Create some linear and nonlinear systems to play with
        linsys = self.siso_linsys
        lnios = ios.LinearIOSystem(linsys)
        nlios =  ios.NonlinearIOSystem(None, \
            lambda t, x, u, params: u*u, inputs=1, outputs=1)
        nlios1 = nlios.copy()
        nlios2 = nlios.copy()

        # Set up parameters for simulation
        T, U, X0 = self.T, self.U, self.X0

        # Single nonlinear system - no states 
        ios_t, ios_y = ios.input_output_response(nlios, T, U, X0)
        np.testing.assert_array_almost_equal(ios_y, U*U, decimal=3)

        # Composed nonlinear system (series)
        ios_t, ios_y = ios.input_output_response(nlios1 * nlios2, T, U, X0)
        np.testing.assert_array_almost_equal(ios_y, U**4, decimal=3)

        # Composed nonlinear system (parallel)
        ios_t, ios_y = ios.input_output_response(nlios1 + nlios2, T, U, X0)
        np.testing.assert_array_almost_equal(ios_y, 2*U**2, decimal=3)

        # Nonlinear system composed with LTI system (series)
        ios_t, ios_y = ios.input_output_response(
            nlios * lnios * nlios, T, U, X0)
        lti_t, lti_y, lti_x = ct.forced_response(linsys, T, U*U, X0)
        np.testing.assert_array_almost_equal(ios_y, lti_y*lti_y, decimal=3)

        # Nonlinear system in feeback loop with LTI system
        iosys = ios.InterconnectedSystem(
            (lnios, nlios),         # linear system w/ nonlinear feedback
            ((1,),                  # feedback interconnection (sig to 0)
             (0, (1, 0, -1))),
            0,                      # input to linear system
            0                       # output from linear system
        )
        ios_t, ios_y = ios.input_output_response(iosys, T, U, X0)
        # No easy way to test the result

        # Algebraic loop from static nonlinear system in feedback
        # (error will be due to no states)
        iosys = ios.InterconnectedSystem(
            (nlios1, nlios2),       # two copies of a static nonlinear system
            ((0, 1),                # feedback interconnection
             (1, (0, 0, -1))),
            0, 0
        )
        args = (iosys, T, U, X0)
        self.assertRaises(RuntimeError, ios.input_output_response, *args)

        # Algebraic loop due to feedthrough term
        linsys = ct.StateSpace(
            [[-1, 1], [0, -2]], [[0], [1]], [[1, 0]], [[1]])
        lnios = ios.LinearIOSystem(linsys)
        iosys = ios.InterconnectedSystem(
            (nlios, lnios),         # linear system w/ nonlinear feedback
            ((0, 1),                # feedback interconnection
             (1, (0, 0, -1))),
            0, 0
        )
        args = (iosys, T, U, X0)
        # ios_t, ios_y = ios.input_output_response(iosys, T, U, X0)
        self.assertRaises(RuntimeError, ios.input_output_response, *args)