def test_problem_3_5(self):
        """Problem 3.5: LQR ROA, Evaluating F, V, and Vdot"""
        from set_3_for_testing import calcF, calcV, calcVdot

        # Sample at a couple of points and sanity-check some
        # basic things.
        # Not super-involved testing -- visual checking of the
        # plots is easier and more informative.
        np.random.seed(0)
        for i in range(100):
            sample_x = np.random.random(4)*100 - 50.
            # Make sure they don't return a nan for any of these conditions
            self.assertFalse(np.any(np.isnan(calcF(sample_x))),
                "".join([
                    "calcF(",
                    np.array_str(sample_x),
                    ") returned a NaN"
                    ]))
            if np.sum(np.abs(sample_x)) > 0.0:
                self.assertGreater(calcV(sample_x), 0.0,
                    "".join([
                        "V(",
                        np.array_str(sample_x),
                        ") was nonpositive."
                        ]))
        
        vAtFP = calcV(np.array([math.pi, 0., 0., 0.]))
        self.assertAlmostEqual(vAtFP, 0.0,
            msg="V(pi,0,0,0) = %f != 0.0" % vAtFP)
        vdotAtFP = calcVdot(np.array([math.pi, 0., 0., 0.]))
        self.assertAlmostEqual(vdotAtFP, 0.0,
            msg="Vdot(pi,0,0,0) = %f != 0.0" % vdotAtFP)
Exemplo n.º 2
0
    def test_problem_3_6(self):
        """Problem 3.6: LQR ROA, Numerical estimate of the ROA"""

        from inertial_wheel_pendulum import RunSimulation
        # Assume from the run-through that vsamples, vdot samples are good...
        from set_3_for_testing import (estimate_rho, V_samples, Vdot_samples,
                                       calcV, calcVdot, lqr_controller)

        # But regenerate rho to make sure that wasn't clobbered... more likely
        # to have been, as it's a simpler name and just a scalar
        rho = estimate_rho(V_samples, Vdot_samples)

        self.assertGreater(rho, 0.0, "rho should be bigger than 0.")
        self.assertLess(
            rho, calcV(np.zeros(4)),
            "rho can't include (0, 0, 0, 0) due to the input limits.")

        np.random.seed(0)

        # Sample at a few points in the ROA
        # and sanity check that:
        #   Vdot is negative
        #   the LQR simulation converges from this position
        for i in range(10):

            # Rejection sample to find a rho
            # (this might be a bad idea for small rho...)
            sample_v = rho + 1.
            while sample_v >= rho:
                sample_x = np.random.random(4) * 10
                sample_v = calcV(sample_x)

            sample_vdot = calcVdot(sample_x)
            self.assertLess(
                sample_vdot, 0.0, "".join([
                    "Vdot sampled at x0=",
                    np.array_str(sample_x), " was positive (Vdot = ",
                    str(sample_vdot), ")"
                ]))

            # Run a forward sim from here
            duration = 10.
            eps = 1E-2  # pretty permissive, but should catch divergences
            input_log, state_log = RunSimulation(self.pendulum_plant,
                                                 lqr_controller,
                                                 x0=sample_x,
                                                 duration=duration)
            self.checkConvergenceOfStateLog(state_log, True)