示例#1
0
    def test_derivative_elimination(self):
        """
        Test that state derivatives are not eliminated even if causalized in torn blocks.
        """
        cost_ref = 88.740458
        u_norm_ref = 4.242559212

        op_manual = self.op_der_loop_manual
        op_automatic = self.op_der_loop_automatic

        # Eliminate
        blt_op_manual = BLTOptimizationProblem(op_manual)
        blt_op_automatic = BLTOptimizationProblem(op_automatic)

        # Check remaining variables
        var_manual = sorted([
            var.getName()
            for var in blt_op_manual.getVariables(blt_op_manual.REAL_ALGEBRAIC)
            if not var.isAlias()
        ])
        var_automatic = sorted([
            var.getName() for var in blt_op_automatic.getVariables(
                blt_op_automatic.REAL_ALGEBRAIC) if not var.isAlias()
        ])
        assert len(var_manual) == 2
        assert len(var_automatic) == 1

        # Optimize and check result
        res_manual = blt_op_manual.optimize()
        res_automatic = blt_op_automatic.optimize()
        assert_results(res_manual, cost_ref, u_norm_ref, u_norm_rtol=1e-2)
        assert_results(res_automatic, cost_ref, u_norm_ref, u_norm_rtol=1e-2)
示例#2
0
    def test_automatic_tearing(self):
        """
        Test consistency between with and without automatic tearing.
        """
        cost_ref = 1.06183273
        u_norm_ref = 0.398219663

        # Perform elimination
        blt_op_automatic = BLTOptimizationProblem(self.op_illust_automatic)
        blt_op_manual = BLTOptimizationProblem(self.op_illust_manual)

        # Check remaining variables
        var_automatic = sorted([
            var.getName() for var in blt_op_automatic.getVariables(
                blt_op_automatic.REAL_ALGEBRAIC) if not var.isAlias()
        ])
        var_manual = sorted([
            var.getName()
            for var in blt_op_manual.getVariables(blt_op_manual.REAL_ALGEBRAIC)
            if not var.isAlias()
        ])
        assert len(var_automatic) == 3
        assert len(var_manual) == 4

        # Optimize and check result
        res_automatic = blt_op_automatic.optimize()
        res_manual = blt_op_manual.optimize()
        assert_results(res_automatic, cost_ref, u_norm_ref, u_norm_rtol=1e-2)
        assert_results(res_manual, cost_ref, u_norm_ref, u_norm_rtol=1e-2)
示例#3
0
 def test_closed_form(self):
     """
     Test creation of closed form expressions when not using tearing.
     """
     # Perform elimination
     elim_opts = EliminationOptions()
     elim_opts['inline_solved'] = True
     elim_opts['closed_form'] = True
     blt_op = BLTOptimizationProblem(self.op_illust_manual, elim_opts)
     for res in blt_op.getDaeResidual():
         if 'y1)*y2)*' in res.getRepresentation():
             residual = res.getRepresentation()
     N.testing.assert_string_equal(residual,
                                   "SX(((((2*y1)*y2)*sqrt(y5))-sqrt(x1)))")
示例#4
0
    def test_ineliminable(self):
        """
        Test ineliminable variables for both manual and automatic tearing.
        """
        cost_ref = 1.08181340
        u_norm_ref = 0.399868319

        # Mark bounded varible as ineliminable
        elim_opts = EliminationOptions()
        elim_opts['ineliminable'] = ['y1']

        # Manual tearing
        op_manual = self.op_illust_manual_bound
        op_manual.getVariable('y3').setTearing(True)
        for eq in op_manual.getDaeEquations():
            if 'y1)*y2)*y4)' in eq.getResidual().getRepresentation():
                eq.setTearing(True)
        blt_op_manual = BLTOptimizationProblem(op_manual, elim_opts)

        # Automatic and manual tearing
        op_hybrid = self.op_illust_automatic_bound
        op_hybrid.getVariable('y1').setTearing(False)
        for eq in op_hybrid.getDaeEquations():
            if '(y1*y4)+sqrt(y3)' in eq.getResidual().getRepresentation():
                eq.setTearing(False)
        blt_op_hybrid = BLTOptimizationProblem(op_hybrid, elim_opts)

        # Check remaining variables
        var_manual = sorted([
            var.getName()
            for var in blt_op_manual.getVariables(blt_op_manual.REAL_ALGEBRAIC)
            if not var.isAlias()
        ])
        var_hybrid = sorted([
            var.getName()
            for var in blt_op_hybrid.getVariables(blt_op_hybrid.REAL_ALGEBRAIC)
            if not var.isAlias()
        ])
        assert len(var_manual) == 3
        assert len(var_hybrid) == 3

        # Optimize and check result
        res_manual = blt_op_manual.optimize()
        res_hybrid = blt_op_hybrid.optimize()
        assert_results(res_manual, cost_ref, u_norm_ref, u_norm_rtol=1e-2)
        assert_results(res_hybrid, cost_ref, u_norm_ref, u_norm_rtol=1e-2)

        # Reset tearing choices
        op_manual.getVariable('y3').setTearing(False)
        for eq in op_manual.getDaeEquations():
            if 'y1)*y2)*y4)' in eq.getResidual().getRepresentation():
                eq.setTearing(False)
        op_hybrid.getVariable('y1').setTearing(True)
        for eq in op_hybrid.getDaeEquations():
            if '(y1*y4)+sqrt(y3)' in eq.getResidual().getRepresentation():
                eq.setTearing(True)
示例#5
0
    def test_linear_tearing(self):
        """
        Test solution of torn linear blocks both symbolically with SX and numerically with MX.

        Numerical part of the test has been disabled, see #5208.
        """
        cost_ref = 2.5843277
        u_norm_ref = 0.647282415

        # Select linear solver
        nonlinear_opts = EliminationOptions()
        nonlinear_opts['solve_blocks'] = False
        symbolic_opts = EliminationOptions()
        symbolic_opts['solve_blocks'] = True
        symbolic_opts['solve_torn_linear_blocks'] = True
        symbolic_opts['linear_solver'] = "symbolicqr"
        numeric_opts = EliminationOptions()
        numeric_opts['solve_blocks'] = True
        numeric_opts['solve_torn_linear_blocks'] = True
        numeric_opts['linear_solver'] = "lapackqr"
        numeric_op_opts = {'expand_to_sx': 'no'}

        # Eliminate
        op = self.op_loop_automatic
        blt_op_nonlinear = BLTOptimizationProblem(op, nonlinear_opts)
        blt_op_symbolic = BLTOptimizationProblem(op, symbolic_opts)
        #~ blt_op_numeric = BLTOptimizationProblem(op, numeric_opts)

        # Check remaining variables
        var_nonlinear = sorted([
            var.getName() for var in blt_op_nonlinear.getVariables(
                blt_op_nonlinear.REAL_ALGEBRAIC) if not var.isAlias()
        ])
        var_symbolic = sorted([
            var.getName() for var in blt_op_symbolic.getVariables(
                blt_op_symbolic.REAL_ALGEBRAIC) if not var.isAlias()
        ])
        #~ var_numeric = sorted([var.getName() for var in blt_op_numeric.getVariables(blt_op_numeric.REAL_ALGEBRAIC)
        #~ if not var.isAlias()])
        assert len(var_nonlinear) == 1
        assert len(var_symbolic) == 0
        #~ assert len(var_numeric) == 0

        # Optimize and check result
        res_nonlinear = blt_op_nonlinear.optimize()
        res_symbolic = blt_op_symbolic.optimize()
        #~ res_numeric = blt_op_numeric.optimize(options=numeric_op_opts)
        assert_results(res_nonlinear, cost_ref, u_norm_ref, u_norm_rtol=1e-2)
        assert_results(res_symbolic, cost_ref, u_norm_ref, u_norm_rtol=1e-2)
示例#6
0
    def test_constraint_and_objective(self):
        """
        Test eliminating variables occurring in constraints and objective.
        """
        cost_ref = 1.08181340
        u_norm_ref = 0.399868319

        # Mark bounded varible as ineliminable for reference
        inelim_opts = EliminationOptions()
        inelim_opts['ineliminable'] = ['y1']
        elim_opts = EliminationOptions()

        # Manual tearing
        op = self.op_illust_manual_constraint
        op.getVariable('y3').setTearing(True)
        for eq in op.getDaeEquations():
            if 'y1)*y2)*y4)' in eq.getResidual().getRepresentation():
                eq.setTearing(True)
        blt_op_inelim = BLTOptimizationProblem(op, inelim_opts)
        blt_op_elim = BLTOptimizationProblem(op, elim_opts)

        # Check remaining variables
        var_inelim = sorted([
            var.getName()
            for var in blt_op_inelim.getVariables(blt_op_inelim.REAL_ALGEBRAIC)
            if not var.isAlias()
        ])
        var_elim = sorted([
            var.getName()
            for var in blt_op_elim.getVariables(blt_op_elim.REAL_ALGEBRAIC)
            if not var.isAlias()
        ])
        assert len(var_inelim) == 3
        assert len(var_elim) == 2

        # Optimize and check result
        res_inelim = blt_op_inelim.optimize()
        res_elim = blt_op_elim.optimize()
        assert_results(res_inelim, cost_ref, u_norm_ref, u_norm_rtol=1e-2)
        assert_results(res_elim, cost_ref, u_norm_ref, u_norm_rtol=1e-2)

        # Reset tearing choices
        op.getVariable('y3').setTearing(False)
        for eq in op.getDaeEquations():
            if 'y1)*y2)*y4)' in eq.getResidual().getRepresentation():
                eq.setTearing(False)
示例#7
0
    def test_par_est(self):
        """
        Test parameter estimation.
        """
        cost_ref = 1.1109779e-2
        u_norm_ref = 0.556018602

        model = self.model_illust
        op = self.op_illust_est_automatic

        # Simulate with nominal parameters
        n_meas = 16
        sim_res = model.simulate(input=('u', lambda t: -0.2 + N.sin(t)),
                                 final_time=4.,
                                 options={
                                     'ncp': n_meas,
                                     'CVode_options': {
                                         'rtol': 1e-10
                                     }
                                 })

        # Assemble external data by adding noise to simulation
        Q = N.diag([1., 1.])
        N.random.seed(1)
        t_meas = sim_res['time']
        sigma = 0.05
        x1_meas = sim_res['x1'] + sigma * N.random.randn(n_meas + 1)
        x2_meas = sim_res['x2'] + sigma * N.random.randn(n_meas + 1)
        u_meas = sim_res['u']
        data_x1 = N.vstack([t_meas, x1_meas])
        data_x2 = N.vstack([t_meas, x2_meas])
        data_u1 = N.vstack([t_meas, u_meas])
        quad_pen = OrderedDict()
        quad_pen['x1'] = data_x1
        quad_pen['x2'] = data_x2
        eliminated = OrderedDict()
        eliminated['u'] = data_u1
        external_data = ExternalData(Q=Q,
                                     quad_pen=quad_pen,
                                     eliminated=eliminated)

        # Eliminate
        blt_op = BLTOptimizationProblem(op)

        # Check remaining variables
        alg_vars = sorted([
            var.getName() for var in blt_op.getVariables(blt_op.REAL_ALGEBRAIC)
            if not var.isAlias()
        ])
        assert len(alg_vars) == 3

        # Set up options
        dae_opts = op.optimize_options()
        dae_opts['init_traj'] = sim_res
        dae_opts['nominal_traj'] = sim_res
        dae_opts['external_data'] = external_data
        blt_opts = blt_op.optimize_options()
        blt_opts['init_traj'] = sim_res
        blt_opts['nominal_traj'] = sim_res
        blt_opts['external_data'] = external_data

        # Optimize and check result
        res_dae = op.optimize(options=dae_opts)
        res_blt = blt_op.optimize(options=blt_opts)
        assert_results(res_dae, cost_ref, u_norm_ref, u_norm_rtol=1e-2)
        assert_results(res_blt, cost_ref, u_norm_ref, u_norm_rtol=1e-2)
        N.testing.assert_allclose([res_dae['p1'][0], res_dae['p3'][0]],
                                  [2.022765, 0.992965],
                                  rtol=2e-3)
        N.testing.assert_allclose([res_blt['p1'][0], res_blt['p3'][0]],
                                  [2.022765, 0.992965],
                                  rtol=2e-3)
示例#8
0
    def test_sparsity_preservation(self):
        """
        Test sparsity preservation for both LMFI and Markowitz.
        """
        cost_ref = 1.06183273
        u_norm_ref = 0.398219663

        # Specify sparsity preservation
        elim_opts_lmfi = EliminationOptions()
        elim_opts_lmfi['dense_tol'] = 2
        elim_opts_lmfi['dense_measure'] = "lmfi"
        elim_opts_mrkwtz = EliminationOptions()
        elim_opts_mrkwtz['dense_tol'] = 4
        elim_opts_mrkwtz['dense_measure'] = "Markowitz"
        elim_opts_mrkwtz2 = EliminationOptions()
        elim_opts_mrkwtz2['dense_tol'] = 2
        elim_opts_mrkwtz2['dense_measure'] = "Markowitz"

        # Manual tearing
        op = self.op_illust_manual
        op.getVariable('y3').setTearing(True)
        for eq in op.getDaeEquations():
            if 'y1)*y2)*y4)' in eq.getResidual().getRepresentation():
                eq.setTearing(True)
        blt_op_lmfi = BLTOptimizationProblem(op, elim_opts_lmfi)
        blt_op_mrkwtz = BLTOptimizationProblem(op, elim_opts_mrkwtz)
        blt_op_mrkwtz2 = BLTOptimizationProblem(op, elim_opts_mrkwtz2)

        # Check remaining variables
        var_lmfi = sorted([
            var.getName()
            for var in blt_op_lmfi.getVariables(blt_op_lmfi.REAL_ALGEBRAIC)
            if not var.isAlias()
        ])
        var_mrkwtz = sorted([
            var.getName()
            for var in blt_op_mrkwtz.getVariables(blt_op_mrkwtz.REAL_ALGEBRAIC)
            if not var.isAlias()
        ])
        var_mrkwtz2 = sorted([
            var.getName() for var in blt_op_mrkwtz2.getVariables(
                blt_op_mrkwtz.REAL_ALGEBRAIC) if not var.isAlias()
        ])
        assert len(var_lmfi) == 3
        assert len(var_mrkwtz) == 3
        assert len(var_mrkwtz2) == 4

        # Optimize and check result
        res_lmfi = blt_op_lmfi.optimize()
        res_mrkwtz = blt_op_mrkwtz.optimize()
        res_mrkwtz2 = blt_op_mrkwtz2.optimize()
        assert_results(res_lmfi, cost_ref, u_norm_ref, u_norm_rtol=1e-2)
        assert_results(res_mrkwtz, cost_ref, u_norm_ref, u_norm_rtol=1e-2)
        assert_results(res_mrkwtz2, cost_ref, u_norm_ref, u_norm_rtol=1e-2)

        # Reset tearing choices
        op.getVariable('y3').setTearing(False)
        for eq in op.getDaeEquations():
            if 'y1)*y2)*y4)' in eq.getResidual().getRepresentation():
                eq.setTearing(False)
示例#9
0
    def test_hybrid_tearing(self):
        """
        Test consistency between manual and automatic tearing as well as the combination of both.
        """
        cost_ref = 1.06183273
        u_norm_ref = 0.398219663

        # Automatic tearing
        blt_op_automatic = BLTOptimizationProblem(self.op_illust_automatic)

        # Manual tearing
        op_manual = self.op_illust_manual
        op_manual.getVariable('y3').setTearing(True)
        for eq in op_manual.getDaeEquations():
            if 'y1)*y2)*y4)' in eq.getResidual().getRepresentation():
                eq.setTearing(True)
        blt_op_manual = BLTOptimizationProblem(op_manual)

        # Automatic and manual tearing
        op_hybrid = self.op_illust_automatic
        op_hybrid.getVariable('y1').setTearing(False)
        for eq in op_hybrid.getDaeEquations():
            if '(y1*y4)+sqrt(y3)' in eq.getResidual().getRepresentation():
                eq.setTearing(False)
        blt_op_hybrid = BLTOptimizationProblem(op_hybrid)

        # Check remaining variables
        var_automatic = sorted([
            var.getName() for var in blt_op_automatic.getVariables(
                blt_op_automatic.REAL_ALGEBRAIC) if not var.isAlias()
        ])
        var_manual = sorted([
            var.getName()
            for var in blt_op_manual.getVariables(blt_op_manual.REAL_ALGEBRAIC)
            if not var.isAlias()
        ])
        var_hybrid = sorted([
            var.getName()
            for var in blt_op_hybrid.getVariables(blt_op_hybrid.REAL_ALGEBRAIC)
            if not var.isAlias()
        ])
        assert len(var_automatic) == 3
        assert len(var_manual) == 2
        assert len(var_hybrid) == 2

        # Optimize and check result
        res_automatic = blt_op_automatic.optimize()
        res_manual = blt_op_manual.optimize()
        res_hybrid = blt_op_hybrid.optimize()
        assert_results(res_automatic, cost_ref, u_norm_ref, u_norm_rtol=1e-2)
        assert_results(res_manual, cost_ref, u_norm_ref, u_norm_rtol=1e-2)
        assert_results(res_hybrid, cost_ref, u_norm_ref, u_norm_rtol=1e-2)

        # Reset tearing choices
        op_manual.getVariable('y3').setTearing(False)
        for eq in op_manual.getDaeEquations():
            if 'y1)*y2)*y4)' in eq.getResidual().getRepresentation():
                eq.setTearing(False)
        op_hybrid.getVariable('y1').setTearing(True)
        for eq in op_hybrid.getDaeEquations():
            if '(y1*y4)+sqrt(y3)' in eq.getResidual().getRepresentation():
                eq.setTearing(True)
def run_demo(with_plots=True):
    """
    This example solves the optimization problem from pyjmi.examples.ccpp using the Python-based symbolic elimination.
    """
    # Load initial gues
    init_path = os.path.join(get_files_path(), "ccpp_init.txt")
    init_res = LocalDAECollocationAlgResult(
        result_data=ResultDymolaTextual(init_path))

    # Compile model
    class_name = "CombinedCycleStartup.Startup6"
    file_paths = (os.path.join(get_files_path(), "CombinedCycle.mo"),
                  os.path.join(get_files_path(), "CombinedCycleStartup.mop"))
    compiler_options = {'equation_sorting': True, 'automatic_tearing': True}
    op = transfer_optimization_problem("CombinedCycleStartup.Startup6",
                                       file_paths, compiler_options)

    # Set elimination options
    elim_opts = EliminationOptions()
    elim_opts['ineliminable'] = ['plant.sigma']
    if with_plots:
        elim_opts['draw_blt'] = True

    # Eliminate algebraic variables
    op = BLTOptimizationProblem(op, elim_opts)

    # Set collocation options
    opt_opts = op.optimize_options()
    opt_opts['init_traj'] = init_res
    opt_opts['nominal_traj'] = init_res

    # Solve the optimal control problem
    opt_res = op.optimize(options=opt_opts)

    # Extract variable profiles
    opt_plant_p = opt_res['plant.p']
    opt_plant_sigma = opt_res['plant.sigma']
    opt_plant_load = opt_res['plant.load']
    opt_time = opt_res['time']

    # Plot the optimized trajectories
    if with_plots:
        plt.close(2)
        plt.figure(2)
        plt.subplot(3, 1, 1)
        plt.plot(opt_time, opt_plant_p * 1e-6)
        plt.ylabel('evaporator pressure [MPa]')
        plt.grid(True)
        plt.title('Optimized trajectories')

        plt.subplot(3, 1, 2)
        plt.plot(opt_time, opt_plant_sigma * 1e-6)
        plt.grid(True)
        plt.ylabel('turbine thermal stress [MPa]')

        plt.subplot(3, 1, 3)
        plt.plot(opt_time, opt_plant_load)
        plt.grid(True)
        plt.ylabel('input load [1]')
        plt.xlabel('time [s]')

    # Verify solution for testing purposes
    try:
        import casadi
    except:
        pass
    else:
        cost = float(opt_res.solver.solver_object.getOutput('f'))
        N.testing.assert_allclose(cost, 17492.465548193624, rtol=1e-5)
示例#11
0
def run_demo(with_plots=True):
    """
    Demonstrate symbolic elimination.
    """
    # Compile and load optimization problem
    file_path = os.path.join(get_files_path(), "JMExamples_opt.mop")
    compiler_options = {'equation_sorting': True, 'automatic_tearing': True}
    op = transfer_optimization_problem("JMExamples_opt.EliminationExample",
                                       file_path, compiler_options)

    # Set up and perform elimination
    elim_opts = EliminationOptions()
    elim_opts['ineliminable'] = [
        'y1'
    ]  # Provide list of variable names to not eliminate
    # Variables with any of the following properties are recommended to mark as ineliminable:
    # Potentially active bounds
    # Occurring in the objective or constraints
    # Numerically unstable pivots (difficult to predict)
    if with_plots:
        elim_opts['draw_blt'] = True
        elim_opts['draw_blt_strings'] = True
    op = BLTOptimizationProblem(op, elim_opts)

    # Optimize and extract solution
    res = op.optimize()
    x1 = res['x1']
    x2 = res['x2']
    y1 = res['y1']
    u = res['u']
    time = res['time']

    # Plot
    if with_plots:
        plt.figure(1)
        plt.clf()
        plt.subplot(4, 1, 1)
        plt.plot(time, x1)
        plt.grid()
        plt.ylabel('x1')

        plt.subplot(4, 1, 2)
        plt.plot(time, x2)
        plt.grid()
        plt.ylabel('x2')

        plt.subplot(4, 1, 3)
        plt.plot(time, y1)
        plt.grid()
        plt.ylabel('y1')

        plt.subplot(4, 1, 4)
        plt.plot(time, u)
        plt.grid()
        plt.ylabel('u')
        plt.xlabel('time')
        plt.show()

    # Verify solution for testing purposes
    try:
        import casadi
    except:
        pass
    else:
        cost = float(res.solver.solver_object.getOutput('f'))
        N.testing.assert_allclose(cost, 1.0818134, rtol=1e-4)
def run_demo(with_plots=True, use_ma57=True):
    """
    This example is based on a single-track model of a car with tire dynamics.
    The optimization problem is to minimize the duration of a 90-degree turn
    with actuators on the steer angle and front and rear wheel torques.

    This example also demonstrates the usage of blocking factors, to enforce
    piecewise constant inputs.

    This example needs one of the linear solvers MA27 or MA57 to work.
    The precense of MA27 or MA57 is not detected in the example, so if only 
    MA57 is present, then True must be passed in the use_ma57 argument.
    """
    # Set up optimization
    mop_path = os.path.join(get_files_path(), "vehicle_turn.mop")
    op = transfer_optimization_problem('Turn', mop_path)
    opts = op.optimize_options()
    opts['IPOPT_options']['linear_solver'] = "ma57" if use_ma57 else "ma27"
    opts['IPOPT_options']['tol'] = 1e-9
    opts['n_e'] = 60

    # Set blocking factors
    factors = {
        'delta_u': opts['n_e'] / 2 * [2],
        'Twf_u': opts['n_e'] / 4 * [4],
        'Twr_u': opts['n_e'] / 4 * [4]
    }
    rad2deg = 180. / (2 * N.pi)
    du_bounds = {'delta_u': 2. / rad2deg}
    bf = BlockingFactors(factors, du_bounds=du_bounds)
    opts['blocking_factors'] = bf

    # Use Dymola simulation result as initial guess
    init_path = os.path.join(get_files_path(), "vehicle_turn_dymola.txt")
    init_guess = ResultDymolaTextual(init_path)
    opts['init_traj'] = init_guess

    # Symbolic elimination
    op = BLTOptimizationProblem(op)

    # Solve optimization problem
    res = op.optimize(options=opts)

    # Extract solution
    time = res['time']
    X = res['car.X']
    Y = res['car.Y']
    delta = res['delta_u']
    Twf = res['Twf_u']
    Twr = res['Twr_u']
    Ri = op.get('Ri')
    Ro = op.get('Ro')

    # Verify result
    N.testing.assert_allclose(time[-1], 4.0118, rtol=5e-3)

    # Plot solution
    if with_plots:
        # Plot road
        plt.close(1)
        plt.figure(1)
        plt.plot(X, Y, 'b')
        xi = N.linspace(0., Ri, 100)
        xo = N.linspace(0., Ro, 100)
        yi = (Ri**8 - xi**8)**(1. / 8.)
        yo = (Ro**8 - xo**8)**(1. / 8.)
        plt.plot(xi, yi, 'r--')
        plt.plot(xo, yo, 'r--')
        plt.xlabel('X [m]')
        plt.ylabel('Y [m]')
        plt.legend(['position', 'road'], loc=3)

        # Plot inputs
        plt.close(2)
        plt.figure(2)
        plt.plot(time, delta * rad2deg, drawstyle='steps-post')
        plt.plot(time, Twf * 1e-3, drawstyle='steps-post')
        plt.plot(time, Twr * 1e-3, drawstyle='steps-post')
        plt.xlabel('time [s]')
        plt.legend(['delta [deg]', 'Twf [kN]', 'Twr [kN]'], loc=4)
        plt.show()
示例#13
0
def run_demo(with_plots=True):
    """
    This example is based on the multibody mechanics double pendulum example from the Modelica Standard Library (MSL).

    The MSL example has been modified by adding a torque on the first revolute joint of the pendulum as a top-level
    input. The considered optimization problem is to invert both pendulum bodies with bounded torque.

    This example needs linear solver MA27 to work.
    """
    # Simulate system with linear state feedback to generate initial guess
    file_paths = (os.path.join(get_files_path(), "DoublePendulum.mo"),
                  os.path.join(get_files_path(), "DoublePendulum.mop"))
    comp_opts = {'inline_functions': 'all', 'dynamic_states': False,
            'expose_temp_vars_in_fmu': True, 'equation_sorting': True, 'automatic_tearing': True}
    init_fmu = load_fmu(compile_fmu("DoublePendulum.Feedback", file_paths, compiler_options=comp_opts))
    init_res = init_fmu.simulate(final_time=3., options={'CVode_options': {'rtol': 1e-10}})
    
    # Set up optimization
    op = transfer_optimization_problem('Opt', file_paths, compiler_options=comp_opts)
    opts = op.optimize_options()
    opts['IPOPT_options']['linear_solver'] = "ma27"
    opts['n_e'] = 100
    opts['init_traj'] = init_res
    opts['nominal_traj'] = init_res

    # Symbolic elimination
    op = BLTOptimizationProblem(op)

    # Solve optimization problem
    res = op.optimize(options=opts)

    # Extract solution
    time = res['time']
    phi1 = res['pendulum.revolute1.phi']
    phi2 = res['pendulum.revolute2.phi']
    u = res['u']

    # Verify solution for testing purposes
    try:
        import casadi
    except:
        pass
    else:
        cost = float(res.solver.solver_object.output(casadi.NLP_SOLVER_F))
        N.testing.assert_allclose(cost, 9.632883808252522, rtol=5e-3)

    # Plot solution
    if with_plots:
        plt.close(1)
        plt.figure(1)
        plt.subplot(2, 1, 1)
        plt.plot(time, phi1, 'b')
        plt.plot(time, phi2, 'r')
        plt.legend(['$\phi_1$', '$\phi_2$'])
        plt.ylabel('$\phi$')
        plt.xlabel('$t$')
        plt.grid()
        
        plt.subplot(2, 1, 2)
        plt.plot(time, u)
        plt.ylabel('$u$')
        plt.xlabel('$t$')
        plt.grid()
        
        plt.show()