예제 #1
0
    def _setup_MPC_solver(self,
                          file_path,
                          opt_name,
                          dt,
                          horizon,
                          n_e,
                          par_values,
                          constr_viol_costs={},
                          mpc_options={}):

        op = transfer_optimization_problem(
            opt_name,
            file_path,
            compiler_options={'state_initial_equations': True})
        op.set(par_values.keys(), par_values.values())

        opt_opts = op.optimize_options()
        opt_opts['n_e'] = n_e
        opt_opts['n_cp'] = 2
        opt_opts['IPOPT_options']['tol'] = 1e-10
        opt_opts['IPOPT_options']['print_time'] = False

        if 'IPOPT_options' in mpc_options:
            opt_opts['IPOPT_options'].update(mpc_options['IPOPT_options'])
        for key in mpc_options:
            if key != 'IPOPT_options':
                opt_opts[key] = mpc_options[key]

        self.solver = MPC(op,
                          opt_opts,
                          dt,
                          horizon,
                          constr_viol_costs=constr_viol_costs)
예제 #2
0
    def test_du_bounds(self):
        """
        Test with blocking_factor du_bounds.
        """
        op = transfer_to_casadi_interface(
            "CSTR.CSTR_MPC",
            self.cstr_file_path,
            compiler_options={"state_initial_equations": True})
        op.set('_start_c', float(self.c_0_A))
        op.set('_start_T', float(self.T_0_A))

        # Set options collocation
        n_e = 50
        opt_opts = op.optimize_options()
        opt_opts['n_e'] = n_e
        opt_opts['IPOPT_options']['print_level'] = 0

        # Define some MPC-options
        sample_period = 3
        horizon = 50
        seed = 7

        # Define blocking factors
        bl_list = [1] * horizon
        factors = {'Tc': bl_list}
        du_bounds = {'Tc': 5}
        bf = BlockingFactors(factors=factors, du_bounds=du_bounds)
        opt_opts['blocking_factors'] = bf

        # Create MPC-object
        MPC_object = MPC(op,
                         opt_opts,
                         sample_period,
                         horizon,
                         noise_seed=seed,
                         initial_guess='trajectory')

        MPC_object.update_state()
        u_k1 = MPC_object.sample()

        res = MPC_object.get_results_this_sample()

        Tc = res['Tc']

        prev_value = Tc[0]
        largest_delta = 0

        for value in Tc:
            delta = value - prev_value
            if delta > largest_delta:
                largest_delta = delta
            prev_value = value

        assert largest_delta < 5, "Value {} is not less than {}".format(
            largest_delta, 5)
예제 #3
0
    def test_auto_bl_factors(self):
        """
        Test blocking factors generated in the mpc-class.
        """
        op = transfer_to_casadi_interface(
            "CSTR.CSTR_MPC",
            self.cstr_file_path,
            compiler_options={"state_initial_equations": True})

        # Set options collocation
        n_e = 50
        opt_opts = op.optimize_options()
        opt_opts['n_e'] = n_e
        opt_opts['IPOPT_options']['print_level'] = 0

        # Define some MPC-options
        sample_period = 3
        horizon = 50

        # Create MPC-object
        MPC_object_auto = MPC(op, opt_opts, sample_period, horizon)
        MPC_object_auto.update_state()
        MPC_object_auto.sample()
        res_auto = MPC_object_auto.get_results_this_sample()

        opt_opts_auto = op.optimize_options()
        opt_opts_auto['n_e'] = n_e
        opt_opts_auto['IPOPT_options']['print_level'] = 0
        bf_list = [1] * horizon
        factors = {'Tc': bf_list}
        bf = BlockingFactors(factors)
        opt_opts_auto['blocking_factors'] = bf

        MPC_object = MPC(op, opt_opts_auto, sample_period, horizon)
        MPC_object.update_state()
        MPC_object.sample()
        res = MPC_object.get_results_this_sample()

        # Assert that res_auto['Tc'] and res['Tc'] are equal
        N.testing.assert_array_equal(res_auto['Tc'], res['Tc'])
예제 #4
0
    def test_get_results_this_sample(self):
        """
        Test that get_results_this_sample returns the optimization result for
        this optimization.
        """
        op = transfer_to_casadi_interface(
            "CSTR.CSTR_MPC",
            self.cstr_file_path,
            compiler_options={"state_initial_equations": True})
        op.set('_start_c', float(self.c_0_A))
        op.set('_start_T', float(self.T_0_A))

        # Set options collocation
        n_e = 50
        opt_opts = op.optimize_options()
        opt_opts['n_e'] = n_e
        opt_opts['IPOPT_options']['print_level'] = 0

        # Define some MPC-options
        sample_period = 3
        horizon = 50
        seed = 7
        cvc = {'T': 1e6}

        # Define blocking factors
        bl_list = [1] * horizon
        factors = {'Tc': bl_list}
        bf = BlockingFactors(factors=factors)
        opt_opts['blocking_factors'] = bf

        # Create MPC-object
        MPC_object = MPC(op,
                         opt_opts,
                         sample_period,
                         horizon,
                         constr_viol_costs=cvc,
                         noise_seed=seed)

        MPC_object.update_state()
        u_k1 = MPC_object.sample()
        result1 = MPC_object.get_results_this_sample()
        N.testing.assert_equal(0, result1['time'][0])
        N.testing.assert_equal(sample_period * horizon, result1['time'][-1])

        MPC_object.update_state()
        u_k2 = MPC_object.sample()
        result2 = MPC_object.get_results_this_sample()
        N.testing.assert_equal(sample_period, result2['time'][0])
        N.testing.assert_equal(sample_period * (horizon + 1),
                               result2['time'][-1])
예제 #5
0
    def test_warm_start_options(self):
        """ 
        Test that the warm start options are activated.
        """
        op = transfer_to_casadi_interface(
            "CSTR.CSTR_MPC",
            self.cstr_file_path,
            compiler_options={"state_initial_equations": True})
        op.set('_start_c', float(self.c_0_A))
        op.set('_start_T', float(self.T_0_A))

        # Set options collocation
        n_e = 50
        opt_opts = op.optimize_options()
        opt_opts['n_e'] = n_e
        opt_opts['IPOPT_options']['print_level'] = 0

        # Define some MPC-options
        sample_period = 3
        horizon = 50
        cvc = {'T': 1e6}

        # Create MPC-object
        MPC_object = MPC(op,
                         opt_opts,
                         sample_period,
                         horizon,
                         initial_guess='trajectory',
                         constr_viol_costs=cvc)
        MPC_object.update_state({
            '_start_c': 587.47543496,
            '_start_T': 345.64619542
        })
        u_k1 = MPC_object.sample()
        MPC_object.update_state()
        u_k2 = MPC_object.sample()

        N.testing.assert_(MPC_object.collocator.warm_start)
        wsip =\
         MPC_object.collocator.solver_object.getOption('warm_start_init_point')
        mu_init = MPC_object.collocator.solver_object.getOption('mu_init')
        prl = MPC_object.collocator.solver_object.getOption('print_level')

        N.testing.assert_(wsip == 'yes')
        N.testing.assert_equal(mu_init, 1e-3)
        N.testing.assert_equal(prl, 0)
예제 #6
0
    def test_softening_bounds(self):
        """
        Test the automatic softening of hard variable bounds.
        """
        op = transfer_to_casadi_interface(
            "CSTR.CSTR_MPC",
            self.cstr_file_path,
            compiler_options={"state_initial_equations": True})

        # Set options collocation
        n_e = 50
        opt_opts = op.optimize_options()
        opt_opts['n_e'] = n_e

        # Define some MPC-options
        sample_period = 3
        horizon = 50
        seed = 7

        # Define blocking factors
        bl_list = [1] * horizon
        factors = {'Tc': bl_list}
        bf = BlockingFactors(factors=factors)
        opt_opts['blocking_factors'] = bf
        opt_opts['IPOPT_options']['print_level'] = 0

        cvc = {'T': 1e6}
        originalPathConstraints = op.getPathConstraints()

        # Create MPC-object
        MPC_object = MPC(op,
                         opt_opts,
                         sample_period,
                         horizon,
                         constr_viol_costs=cvc,
                         noise_seed=seed)

        # Assert that an optimization with an initial value outside of bounds
        # succeeds
        MPC_object.update_state({'_start_c': self.c_0_A, '_start_T': 355})
        MPC_object.sample()
        N.testing.assert_(
            'Solve_Succeeded',
            MPC_object.collocator.solver_object.getStat('return_status'))
예제 #7
0
    def test_infeasible_start(self):
        """
        Test that the MPC class throws an exception if the first optimization 
        is unsuccessful.
        """
        op = transfer_to_casadi_interface(
            "CSTR.CSTR_MPC",
            self.cstr_file_path,
            compiler_options={"state_initial_equations": True})

        # Set options collocation
        n_e = 50
        opt_opts = op.optimize_options()
        opt_opts['n_e'] = n_e
        opt_opts['IPOPT_options']['print_level'] = 0

        # Define some MPC-options
        sample_period = 3
        horizon = 50
        cvc = {'T': 1e6}

        # Define blocking factors
        bl_list = [1] * horizon
        factors = {'Tc': bl_list}
        bf = BlockingFactors(factors=factors)
        opt_opts['blocking_factors'] = bf

        # Create MPC-object
        MPC_object = MPC(op,
                         opt_opts,
                         sample_period,
                         horizon,
                         constr_viol_costs=cvc)

        # Test with infeasible problem
        MPC_object.update_state({'_start_c': 900, '_start_T': 700})

        N.testing.assert_raises(Exception, MPC_object.sample)
예제 #8
0
def run_demo(with_plots=True):
    """
    This example is based on the Hicks-Ray Continuously Stirred Tank Reactors 
    (CSTR) system. The system has two states, the concentration and the 
    temperature. The control input to the system is the temperature of the 
    cooling flow in the reactor jacket. The chemical reaction in the reactor is 
    exothermic, and also temperature dependent; high temperature results in 
    high reaction rate.

    The problem is solved using the CasADi-based collocation algorithm through 
    the MPC-class. FMI is used for initialization and simulation purposes.

    The following steps are demonstrated in this example:

    1.  How to generate an initial guess for a direct collocation method by
        means of simulation with a constant input. The trajectories resulting
        from the simulation are used to initialize the variables in the
        transcribed NLP, in the first sample(optimization).

    2.  An optimal control problem is defined where the objective is to 
        transfer the state of the system from stationary point A to point B. 
        An MPC object for the optimization problem is created. After each 
        sample the NLP is updated with an estimate of the states in the next 
        sample. The estimate is done by simulating the model for one sample 
        period with the optimal input calculated in the optimization as input.
        To each estimate a normally distributed noise, with the mean 0 
        and standard deviation 0.5% of the nominal value of each state, is 
        added. The MPC object uses the result from the previous optimization as
        initial guess for the next optimization (for all but the first 
        optimization, where the simulation result from #1 is used instead).

   (3.) If with_plots is True we compile the same optimization problem again 
        and define the options so that the op has the same options and 
        resolution as the op we solved through the MPC-class. By same 
        resolution we mean that both op should have the same mesh and blocking 
        factors. This allows us to compare the MPC-results to an open loop 
        optimization. Note that the MPC-results contains noise while the open 
        loop optimization does not. 

    """
    ### 1. Compute initial guess trajectories by means of simulation
    # Locate the Modelica and Optimica code
    file_path = os.path.join(get_files_path(), "CSTR.mop")

    # Compile and load the model used for simulation
    sim_fmu = compile_fmu("CSTR.CSTR_MPC_Model", file_path, 
                            compiler_options={"state_initial_equations":True})
    sim_model = load_fmu(sim_fmu)

    # Define stationary point A and set initial values and inputs
    c_0_A = 956.271352
    T_0_A = 250.051971
    sim_model.set('_start_c', c_0_A)
    sim_model.set('_start_T', T_0_A)
    sim_model.set('Tc', 280)
    
    opts = sim_model.simulate_options()
    opts["CVode_options"]["maxh"] = 0.0
    opts["ncp"] = 0
    
    init_res = sim_model.simulate(start_time=0., final_time=150, options=opts)

    ### 2. Define the optimal control problem and solve it using the MPC class
    # Compile and load optimization problem
    op = transfer_optimization_problem("CSTR.CSTR_MPC", file_path,
                            compiler_options={"state_initial_equations":True})

    # Define MPC options
    sample_period = 3                           # s
    horizon = 33                                # Samples on the horizon
    n_e_per_sample = 1                          # Collocation elements / sample
    n_e = n_e_per_sample*horizon                # Total collocation elements
    finalTime = 150                             # s
    number_samp_tot = int(finalTime/sample_period)   # Total number of samples to do

    # Create blocking factors with quadratic penalty and bound on 'Tc'
    bf_list = [n_e_per_sample]*(horizon/n_e_per_sample)
    factors = {'Tc': bf_list}
    du_quad_pen = {'Tc': 500}
    du_bounds = {'Tc': 30}
    bf = BlockingFactors(factors, du_bounds, du_quad_pen)

    # Set collocation options
    opt_opts = op.optimize_options()
    opt_opts['n_e'] = n_e
    opt_opts['n_cp'] = 2
    opt_opts['init_traj'] = init_res
    opt_opts['blocking_factors'] = bf

    if with_plots:
        # Compile and load a new instance of the op to compare the MPC results 
        # with an open loop optimization 
        op_open_loop = transfer_optimization_problem(
            "CSTR.CSTR_MPC", file_path,
            compiler_options={"state_initial_equations":True})
        op_open_loop.set('_start_c', float(c_0_A))
        op_open_loop.set('_start_T', float(T_0_A)) 
        
        # Copy options from MPC optimization
        open_loop_opts = copy.deepcopy(opt_opts)
        
        # Change n_e and blocking_factors so op_open_loop gets the same 
        # resolution as op
        open_loop_opts['n_e'] = number_samp_tot
        
        bf_list_ol = [n_e_per_sample]*(number_samp_tot/n_e_per_sample)
        factors_ol = {'Tc': bf_list_ol}
        bf_ol = BlockingFactors(factors_ol, du_bounds, du_quad_pen)
        open_loop_opts['blocking_factors'] = bf_ol
        open_loop_opts['IPOPT_options']['print_level'] = 0

    constr_viol_costs = {'T': 1e6}

    # Create the MPC object
    MPC_object = MPC(op, opt_opts, sample_period, horizon, 
                    constr_viol_costs=constr_viol_costs, noise_seed=1)

    # Set initial state
    x_k = {'_start_c': c_0_A, '_start_T': T_0_A }

    # Update the state and optimize number_samp_tot times
    for k in range(number_samp_tot):

        # Update the state and compute the optimal input for next sample period
        MPC_object.update_state(x_k)
        u_k = MPC_object.sample()

        # Reset the model and set the new initial states before simulating
        # the next sample period with the optimal input u_k
        sim_model.reset()
        sim_model.set(list(x_k.keys()), list(x_k.values()))
        sim_res = sim_model.simulate(start_time=k*sample_period, 
                                     final_time=(k+1)*sample_period, 
                                     input=u_k, options=opts)

        # Extract state at end of sample_period from sim_res and add Gaussian
        # noise with mean 0 and standard deviation 0.005*(state_current_value)
        x_k = MPC_object.extract_states(sim_res, mean=0, st_dev=0.005)


    # Extract variable profiles
    MPC_object.print_solver_stats()
    complete_result = MPC_object.get_complete_results()
    c_res_comp = complete_result['c']
    T_res_comp = complete_result['T']
    Tc_res_comp = complete_result['Tc']
    time_res_comp = complete_result['time']

    # Verify solution for testing purposes
    try:
        import casadi
    except:
        pass
    else:
        Tc_norm = N.linalg.norm(Tc_res_comp) / N.sqrt(len(Tc_res_comp))
        assert(N.abs(Tc_norm - 311.7362) < 1e-3)
        c_norm = N.linalg.norm(c_res_comp) / N.sqrt(len(c_res_comp))
        assert(N.abs(c_norm - 653.5369) < 1e-3)
        T_norm = N.linalg.norm(T_res_comp) / N.sqrt(len(T_res_comp))
        assert(N.abs(T_norm - 328.0852) < 1e-3)
    
    # Plot the results
    if with_plots: 
        ### 3. Solve the original optimal control problem without MPC
        res = op_open_loop.optimize(options=open_loop_opts)
        c_res = res['c']
        T_res = res['T']
        Tc_res = res['Tc']
        time_res = res['time']
        
        # Get reference values
        Tc_ref = op.get('Tc_ref')
        T_ref = op.get('T_ref')
        c_ref = op.get('c_ref')

        # Plot
        plt.close('MPC')
        plt.figure('MPC')
        plt.subplot(3, 1, 1)
        plt.plot(time_res_comp, c_res_comp)
        plt.plot(time_res, c_res )
        plt.plot([time_res[0],time_res[-1]],[c_ref,c_ref],'--')
        plt.legend(('MPC with noise', 'Open-loop without noise', 'Reference value'))
        plt.grid()
        plt.ylabel('Concentration')
        plt.title('Simulated trajectories')

        plt.subplot(3, 1, 2)
        plt.plot(time_res_comp, T_res_comp)
        plt.plot(time_res, T_res)
        plt.plot([time_res[0],time_res[-1]],[T_ref,T_ref], '--')
        plt.grid()
        plt.ylabel('Temperature [C]')

        plt.subplot(3, 1, 3)
        plt.step(time_res_comp, Tc_res_comp)
        plt.step(time_res, Tc_res)
        plt.plot([time_res[0],time_res[-1]],[Tc_ref,Tc_ref], '--')
        plt.grid()
        plt.ylabel('Cooling temperature [C]')
        plt.xlabel('time')
        plt.show()
예제 #9
0
    def test_eliminated_variables(self):
        """ 
        Test that the results when using eliminated variables are the same as when not using them.
        """
        # Compile and load the model used for simulation
        sim_fmu = compile_fmu(
            "CSTR.CSTR_MPC_Model",
            self.cstr_file_path,
            compiler_options={"state_initial_equations": True})
        sim_model = load_fmu(sim_fmu)

        # Compile and load the model with eliminated variables used for simulation
        sim_fmu_elim = compile_fmu("CSTR.CSTR_elim_vars_MPC_Model",
                                   self.cstr_file_path,
                                   compiler_options={
                                       "state_initial_equations": True,
                                       'equation_sorting': True,
                                       'automatic_tearing': False
                                   })
        sim_model_elim = load_fmu(sim_fmu_elim)

        # Define stationary point A and set initial values and inputs
        c_0_A = 956.271352
        T_0_A = 250.051971
        sim_model.set('_start_c', c_0_A)
        sim_model.set('_start_T', T_0_A)
        sim_model.set('Tc', 280)
        init_res = sim_model.simulate(start_time=0., final_time=150)

        # Compile and load optimization problems
        op = transfer_to_casadi_interface("CSTR.CSTR_MPC",
                                          self.cstr_file_path,
                                          compiler_options={
                                              "state_initial_equations": True,
                                              "common_subexp_elim": False
                                          })
        op_elim = transfer_to_casadi_interface("CSTR.CSTR_elim_vars_MPC",
                                               self.cstr_file_path,
                                               compiler_options={
                                                   "state_initial_equations":
                                                   True,
                                                   'equation_sorting': True,
                                                   'automatic_tearing': False,
                                                   "common_subexp_elim": False
                                               })

        # Define MPC options
        sample_period = 5  # s
        horizon = 10  # Samples on the horizon
        n_e_per_sample = 1  # Collocation elements / sample
        n_e = n_e_per_sample * horizon  # Total collocation elements
        finalTime = 50  # s
        number_samp_tot = 5  # Total number of samples to do

        # Create blocking factors with quadratic penalty and bound on 'Tc'
        bf_list = [n_e_per_sample] * (horizon / n_e_per_sample)
        factors = {'Tc': bf_list}
        du_quad_pen = {'Tc': 50}
        du_bounds = {'Tc': 30}
        bf = BlockingFactors(factors, du_bounds, du_quad_pen)

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

        constr_viol_costs = {'T': 1e6}

        # Create the MPC object
        MPC_object = MPC(op,
                         opt_opts,
                         sample_period,
                         horizon,
                         constr_viol_costs=constr_viol_costs,
                         noise_seed=1)

        # Set initial state
        x_k = {'_start_c': c_0_A, '_start_T': T_0_A}

        # Update the state and optimize number_samp_tot times
        for k in range(number_samp_tot):

            # Update the state and compute the optimal input for next sample period
            MPC_object.update_state(x_k)
            u_k = MPC_object.sample()

            # Reset the model and set the new initial states before simulating
            # the next sample period with the optimal input u_k
            sim_model.reset()
            sim_model.set(list(x_k.keys()), list(x_k.values()))
            sim_res = sim_model.simulate(start_time=k * sample_period,
                                         final_time=(k + 1) * sample_period,
                                         input=u_k)

            # Extract state at end of sample_period from sim_res and add Gaussian
            # noise with mean 0 and standard deviation 0.005*(state_current_value)
            x_k = MPC_object.extract_states(sim_res, mean=0, st_dev=0.005)

        # Extract variable profiles
        complete_result = MPC_object.get_complete_results()

        op_elim.eliminateAlgebraics()

        assert (len(op_elim.getEliminatedVariables()) == 2)

        opt_opts_elim = op_elim.optimize_options()
        opt_opts_elim['n_e'] = n_e
        opt_opts_elim['n_cp'] = 2
        opt_opts_elim['init_traj'] = init_res

        # Create the MPC object with eliminated variables
        MPC_object_elim = MPC(op_elim,
                              opt_opts_elim,
                              sample_period,
                              horizon,
                              constr_viol_costs=constr_viol_costs,
                              noise_seed=1)

        # Set initial state
        x_k = {'_start_c': c_0_A, '_start_T': T_0_A}

        # Update the state and optimize number_samp_tot times
        for k in range(number_samp_tot):

            # Update the state and compute the optimal input for next sample period
            MPC_object_elim.update_state(x_k)
            u_k = MPC_object_elim.sample()

            # Reset the model and set the new initial states before simulating
            # the next sample period with the optimal input u_k
            sim_model_elim.reset()
            sim_model_elim.set(list(x_k.keys()), list(x_k.values()))
            sim_res = sim_model_elim.simulate(start_time=k * sample_period,
                                              final_time=(k + 1) *
                                              sample_period,
                                              input=u_k)

            # Extract state at end of sample_period from sim_res and add Gaussian
            # noise with mean 0 and standard deviation 0.005*(state_current_value)
            x_k = MPC_object_elim.extract_states(sim_res, mean=0, st_dev=0.005)

        # Extract variable profiles
        complete_result_elim = MPC_object_elim.get_complete_results()

        N.testing.assert_array_almost_equal(complete_result['c'],
                                            complete_result_elim['c'])
        N.testing.assert_array_almost_equal(complete_result['T'],
                                            complete_result_elim['T'])
        N.testing.assert_array_almost_equal(complete_result['Tc'],
                                            complete_result_elim['Tc'])
예제 #10
0
    def test_infeasible_return_input(self):
        """
        Test that the input returned from an unsuccessful optimization is the 
        next input in the last successful optimization.
        """
        op = transfer_to_casadi_interface(
            "CSTR.CSTR_MPC",
            self.cstr_file_path,
            compiler_options={"state_initial_equations": True})

        # Set options collocation
        n_e = 50
        opt_opts = op.optimize_options()
        opt_opts['n_e'] = n_e
        opt_opts['IPOPT_options']['print_level'] = 0

        # Define some MPC-options
        sample_period = 3
        horizon = 50
        seed = 7
        cvc = {'T': 1e6}

        # Define blocking factors
        bl_list = [1] * horizon
        factors = {'Tc': bl_list}
        bf = BlockingFactors(factors=factors)
        opt_opts['blocking_factors'] = bf

        # Create MPC-object
        MPC_object = MPC(op,
                         opt_opts,
                         sample_period,
                         horizon,
                         constr_viol_costs=cvc,
                         noise_seed=seed,
                         create_comp_result=False,
                         initial_guess='trajectory')
        # NOTE: THIS NOT WORKING WITH initial_guess='shift'!!

        MPC_object.update_state({
            '_start_c': 587.47543496,
            '_start_T': 345.64619542
        })
        u_k1 = MPC_object.sample()
        result1 = MPC_object.get_results_this_sample()

        # Optimize with infeasible problem
        MPC_object.update_state({'_start_c': 900, '_start_T': 400})
        u_k2 = MPC_object.sample()

        # Assert that problem was infeasible and that the returned input is
        # the next input from the last succesful optimization
        N.testing.assert_(
            'Infeasible_Problem_Detected',
            MPC_object.collocator.solver_object.getStat('return_status'))

        N.testing.assert_almost_equal(u_k2[1](0)[0],
                                      result1['Tc'][4],
                                      decimal=10)

        # Assert that the returned resultfile is that of the last succesful
        # optimization
        result2 = MPC_object.get_results_this_sample()

        assert result1 == result2, "UNEQUAL VALUES. result1={}\nresult2={}".format(
            result1, result2)

        # Assert that problem was infeasible yet again and that the returned
        # input is the next (third) input from the last succesful optimization
        MPC_object.update_state({'_start_c': 900, '_start_T': 400})
        u_k3 = MPC_object.sample()

        N.testing.assert_(
            'Infeasible_Problem_Detected',
            MPC_object.collocator.solver_object.getStat('return_status'))

        N.testing.assert_almost_equal(u_k3[1](0)[0],
                                      result1['Tc'][7],
                                      decimal=10)
예제 #11
0
    def test_du_quad_pen(self):
        """
        Test with blocking_factor du_quad_pen.
        """
        op = transfer_to_casadi_interface(
            "CSTR.CSTR_MPC",
            self.cstr_file_path,
            compiler_options={"state_initial_equations": True})
        op.set('_start_c', float(self.c_0_A))
        op.set('_start_T', float(self.T_0_A))

        # Set options collocation
        n_e = 50
        opt_opts = op.optimize_options()
        opt_opts['n_e'] = n_e
        opt_opts['IPOPT_options']['print_level'] = 0

        # Define some MPC-options
        sample_period = 3
        horizon = 50
        seed = 7

        # Define blocking factors
        bl_list = [1] * horizon
        factors = {'Tc': bl_list}
        bf = BlockingFactors(factors=factors)
        opt_opts['blocking_factors'] = bf

        # Create MPC-object without du_quad_pen
        MPC_object = MPC(op,
                         opt_opts,
                         sample_period,
                         horizon,
                         noise_seed=seed,
                         initial_guess='trajectory')

        MPC_object.update_state()
        MPC_object.sample()
        res = MPC_object.get_results_this_sample()

        # Create MPC-object with du_quad_pen
        opt_opts_quad = op.optimize_options()
        opt_opts_quad['n_e'] = n_e
        opt_opts_quad['IPOPT_options']['print_level'] = 0
        bf_list = [1] * horizon
        factors = {'Tc': bf_list}
        du_quad_pen = {'Tc': 100}
        bf = BlockingFactors(factors, du_quad_pen=du_quad_pen)
        opt_opts_quad['blocking_factors'] = bf

        MPC_object_quad = MPC(op,
                              opt_opts_quad,
                              sample_period,
                              horizon,
                              noise_seed=seed,
                              initial_guess='trajectory')
        MPC_object_quad.update_state()
        MPC_object_quad.sample()
        res_quad = MPC_object_quad.get_results_this_sample()

        Tc = res['Tc']
        prev_value = Tc[0]
        largest_delta = 0

        for value in Tc:
            delta = value - prev_value
            if delta > largest_delta:
                largest_delta = delta
            prev_value = value

        Tc = res_quad['Tc']
        prev_value = Tc[0]
        largest_delta_quad = 0

        for value in Tc:
            delta = value - prev_value
            if delta > largest_delta_quad:
                largest_delta_quad = delta
            prev_value = value

        N.testing.assert_(largest_delta_quad < largest_delta)