示例#1
0
    def _create_external_data(self):
        '''Define external data inputs to optimization problem.
        
        '''

        quad_pen = OrderedDict()
        N_mea = 0
        if hasattr(self, 'measurement_variable_list'):
            for key in self.measurement_variable_list:
                df = self.Model.measurements[key]['Measured'].get_base_data(
                )[self.Model.start_time:self.Model.final_time].to_frame()
                df_simtime = self._add_simtime_column(df)
                mea_traj = np.vstack((df_simtime['SimTime'].get_values(), \
                                     df_simtime[key].get_values()))
                quad_pen['mpc_model.' + key] = mea_traj
                N_mea = N_mea + 1
        else:
            Q = None
        # Create objective error weights
        Q = np.diag(np.ones(N_mea))
        # Eliminate inputs from optimization problem
        eliminated = {}
        i = 1
        N_input = 0
        if self._input_object != {}:
            for key in self._input_object[0]:
                input_traj = np.vstack((np.transpose(self._input_object[1][:,0]), \
                                       np.transpose(self._input_object[1][:,i])))
                eliminated[key] = input_traj
                N_input = N_input + 1
                i = i + 1
        # Create ExternalData structure
        self.external_data = ExternalData(Q=Q,
                                          quad_pen=quad_pen,
                                          eliminated=eliminated)
示例#2
0
 def _create_external_data(self):
     """
     Creates an ExternalData object that is loaded into the optimization. 
     The object eliminates the inputs defined when creating the GreyBox object 
     as well as the inputs added for the measured data (if costType='integral').
     """
     dictionary = {}
     
     # add external data for measured variables
     if self.costType == "integral":
         for (name, data) in self.measurements.items():
             dictionary[self.prefix+'measured_'+name] = np.vstack([self.time,data])
     
     # add external data for inputs    
     for (name, data) in self.inputs.items():
         dictionary[name] = np.vstack([self.time,data])
 
     #create mesurement_data object to load into the optimization
     measurement_data = ExternalData(dictionary)
     self.options['external_data'] = measurement_data
示例#3
0
def _get_eliminated_data_object(u_0, process_noise_names,
                                undefined_input_names, input_names):
    """
    Creates a ExternalData object used to eliminate the input 
    signals from the optimization by providing values for them.
    
    Parameters::
        u_0 --
            A dictionary on the form 
            dict([('input1', u1),...,('inputN', uN)]), 
            where 'inputX' is the name of the input and uX is the 
            value of the input at time zero. N is the number of 
            control signals and X goes from 1 to N.
            
        process_noise_names --
            A list of names of all the process noise inputs.
            
        input_names --
            A list of names of all the input signals who are not 
            pure process noise inputs.
            
    Returns::
        external_data --
            A ExternalData object used to eliminate the inputs.
    """
    eliminated = OrderedDict()
    #Eliminate process noise and undefined inputs
    for name in process_noise_names + undefined_input_names:
        data = N.vstack([0., 0.])
        eliminated[name] = data
    #Eliminate inputs
    for name in input_names:
        data = N.vstack([0., u_0[name]])
        eliminated[name] = data

    external_data = ExternalData(eliminated=eliminated)
    return external_data
示例#4
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)
示例#5
0
def run_demo(with_plots=True):
    """
    This example demonstrates how to solve parameter estimation problmes.

    The system is tanks with connected inlets and outlets. The objective is to
    estimate the outlet area of two of the tanks based on measurement data.
    """
    # Compile and load FMU, which is used for simulation
    file_path = os.path.join(get_files_path(), "QuadTankPack.mop")
    model = load_fmu(compile_fmu('QuadTankPack.QuadTank', file_path))

    # Transfer problem to CasADi Interface, which is used for estimation
    op = transfer_optimization_problem("QuadTankPack.QuadTank_ParEstCasADi",
                                       file_path)

    # Set initial states in model, which are stored in the optimization problem
    x_0_names = ['x1_0', 'x2_0', 'x3_0', 'x4_0']
    x_0_values = op.get(x_0_names)
    model.set(x_0_names, x_0_values)
    
    # Load measurement data from file
    data_path = os.path.join(get_files_path(), "qt_par_est_data.mat")
    data = loadmat(data_path, appendmat=False)

    # Extract data series
    t_meas = data['t'][6000::100, 0] - 60
    y1_meas = data['y1_f'][6000::100, 0] / 100
    y2_meas = data['y2_f'][6000::100, 0] / 100
    y3_meas = data['y3_d'][6000::100, 0] / 100
    y4_meas = data['y4_d'][6000::100, 0] / 100
    u1 = data['u1_d'][6000::100, 0]
    u2 = data['u2_d'][6000::100, 0]
    
    # Plot measurements and inputs
    if with_plots:
        plt.close(1)
        plt.figure(1)
        plt.subplot(2, 2, 1)
        plt.plot(t_meas, y3_meas)
        plt.title('x3')
        plt.grid()
        plt.subplot(2, 2, 2)
        plt.plot(t_meas, y4_meas)
        plt.title('x4')
        plt.grid()
        plt.subplot(2, 2, 3)
        plt.plot(t_meas, y1_meas)
        plt.title('x1')
        plt.xlabel('t[s]')
        plt.grid()
        plt.subplot(2, 2, 4)
        plt.plot(t_meas, y2_meas)
        plt.title('x2')
        plt.xlabel('t[s]')
        plt.grid()

        plt.close(2)
        plt.figure(2)
        plt.subplot(2, 1, 1)
        plt.plot(t_meas, u1)
        plt.hold(True)
        plt.title('u1')
        plt.grid()
        plt.subplot(2, 1, 2)
        plt.plot(t_meas, u2)
        plt.title('u2')
        plt.xlabel('t[s]')
        plt.hold(True)
        plt.grid()

    # Build input trajectory matrix for use in simulation
    u = N.transpose(N.vstack([t_meas, u1, u2]))
    
    # Simulate model response with nominal parameter values
    res_sim = model.simulate(input=(['u1', 'u2'], u),
                             start_time=0., final_time=60.)

    # Load simulation result
    x1_sim = res_sim['x1']
    x2_sim = res_sim['x2']
    x3_sim = res_sim['x3']
    x4_sim = res_sim['x4']
    t_sim  = res_sim['time']
    u1_sim = res_sim['u1']
    u2_sim = res_sim['u2']

    # Check simulation results for testing purposes
    assert N.abs(res_sim.final('x1') - 0.05642485) < 1e-3
    assert N.abs(res_sim.final('x2') - 0.05510478) < 1e-3
    assert N.abs(res_sim.final('x3') - 0.02736532) < 1e-3
    assert N.abs(res_sim.final('x4') - 0.02789808) < 1e-3
    assert N.abs(res_sim.final('u1') - 6.0) < 1e-3
    assert N.abs(res_sim.final('u2') - 5.0) < 1e-3

    # Plot simulation result
    if with_plots:
        plt.figure(1)
        plt.subplot(2, 2, 1)
        plt.plot(t_sim, x3_sim)
        plt.subplot(2, 2, 2)
        plt.plot(t_sim, x4_sim)
        plt.subplot(2, 2, 3)
        plt.plot(t_sim, x1_sim)
        plt.subplot(2, 2, 4)
        plt.plot(t_sim, x2_sim)

        plt.figure(2)
        plt.subplot(2, 1, 1)
        plt.plot(t_sim, u1_sim, 'r')
        plt.subplot(2, 1, 2)
        plt.plot(t_sim, u2_sim, 'r')

    # Create external data object for optimization
    Q = N.diag([1., 1., 10., 10.])
    data_x1 = N.vstack([t_meas, y1_meas])
    data_x2 = N.vstack([t_meas, y2_meas])
    data_u1 = N.vstack([t_meas, u1])
    data_u2 = N.vstack([t_meas, u2])
    quad_pen = OrderedDict()
    quad_pen['x1'] = data_x1
    quad_pen['x2'] = data_x2
    quad_pen['u1'] = data_u1
    quad_pen['u2'] = data_u2
    external_data = ExternalData(Q=Q, quad_pen=quad_pen)

    # Set optimization options and optimize
    opts = op.optimize_options()
    opts['n_e'] = 60 # Number of collocation elements
    opts['external_data'] = external_data
    opts['init_traj'] = res_sim
    opts['nominal_traj'] = res_sim
    res = op.optimize(options=opts) # Solve estimation problem

    # Extract estimated values of parameters
    a1_opt = res.initial("a1")
    a2_opt = res.initial("a2")

    # Print and assert estimated parameter values
    print(('a1: ' + str(a1_opt*1e4) + 'cm^2'))
    print(('a2: ' + str(a2_opt*1e4) + 'cm^2'))
    a_ref = [0.02656702, 0.02713898]
    N.testing.assert_allclose(1e4 * N.array([a1_opt, a2_opt]),
                              a_ref, rtol=1e-4)

    # Load state profiles
    x1_opt = res["x1"]
    x2_opt = res["x2"]
    x3_opt = res["x3"]
    x4_opt = res["x4"]
    u1_opt = res["u1"]
    u2_opt = res["u2"]
    t_opt  = res["time"]

    # Plot estimated trajectories
    if with_plots:
        plt.figure(1)
        plt.subplot(2, 2, 1)
        plt.plot(t_opt, x3_opt, 'k')
        plt.subplot(2, 2, 2)
        plt.plot(t_opt, x4_opt, 'k')
        plt.subplot(2, 2, 3)
        plt.plot(t_opt, x1_opt, 'k')
        plt.subplot(2, 2, 4)
        plt.plot(t_opt, x2_opt, 'k')

        plt.figure(2)
        plt.subplot(2, 1, 1)
        plt.plot(t_opt, u1_opt, 'k')
        plt.subplot(2, 1, 2)
        plt.plot(t_opt, u2_opt, 'k')
        plt.show()
示例#6
0
plt.subplot(212)
plt.plot(t_sim, Ts_ext_sim - 273.15, 'r', label='Simulation')
plt.hold(True)
plt.show()
'''Clearly, there is a mismatch in the response, which is
why we need calibration by tuning some parameters.
'''

# Create external data object for optimization
Q = N.diag([1., 1.])
data_x1 = N.vstack([t_mea, Ts_ext_mea])
data_x2 = N.vstack([t_mea, Ts_int_mea])
quad_pen = OrderedDict()
quad_pen['Ts_ext'] = data_x1
quad_pen['Ts_int'] = data_x2
external_data = ExternalData(Q=Q, quad_pen=quad_pen)

# Set optimization options and optimize
opts = op.optimize_options()
opts['n_e'] = 60  # Number of collocation elements
opts['external_data'] = external_data
opts['init_traj'] = res_sim
opts['nominal_traj'] = res_sim
res = op.optimize(options=opts)  # Solve estimation problem

# Extract estimated values of parameters
r_opt = N.zeros([n + 1, 1])
c_opt = N.zeros([n, 1])
for i in range(0, n):
    r_opt[i] = res.initial('r[' + str(i + 1) + ']')
    c_opt[i] = res.initial('c[' + str(i + 1) + ']')
def test_change_quad_pen_input(eliminate_algebraics=False):
    check_changed_input('Integrator', 'u',
        (lambda input:ExternalData(quad_pen=input, Q = N.atleast_2d(1))),
        eliminate_algebraics)
def test_change_constrained_input(eliminate_algebraics=False):
    check_changed_input('DisturbedIntegrator', 'w',
        (lambda input:ExternalData(constr_quad_pen=input, Q = N.atleast_2d(1))),
        eliminate_algebraics)
def test_change_eliminated_input(eliminate_algebraics=False, result_mode='collocation_points'):
    check_changed_input('DisturbedIntegrator', 'w',
        (lambda input:ExternalData(eliminated=input)),
        eliminate_algebraics, result_mode)
示例#10
0
文件: MPC.py 项目: borlum/jmMPC
 def _create_external_data(self):
     from pyjmi.optimization.casadi_collocation import ExternalData
     return ExternalData(eliminated=self.external)