Ejemplo n.º 1
0
    def _estimate(self, Model):
        '''Perform UKF estimation.

        '''

        estimationpy_logging.configure_logger(log_level=logging.DEBUG,
                                              log_level_console=logging.INFO,
                                              log_level_file=logging.DEBUG)
        # Write the inputs, measurements, and parameters to csv
        self._writeukfcsv(Model)
        # Select inputs
        for key in Model.input_names:
            inputvar = self.model.get_input_by_name(key)
            inputvar.get_csv_reader().open_csv(self.csv_path)
            inputvar.get_csv_reader().set_selected_column(key)
        # Select outputs
        for key in Model.measurement_variable_list:
            outputvar = self.model.get_output_by_name(key)
            outputvar.get_csv_reader().open_csv(self.csv_path)
            outputvar.get_csv_reader().set_selected_column(key)
            outputvar.set_measured_output()
            outputvar.set_covariance(0.5)
        # Select the parameters to be identified
        i = 0
        for key in Model.parameter_data.keys():
            if Model.parameter_data[key]['Free'].get_base_data():
                self.model.add_parameter(self.model.get_variable_object(key))
                par = self.model.get_parameters()[i]
                par.set_initial_value(
                    Model.parameter_data[key]['Value'].get_base_data())
                par.set_covariance(
                    Model.parameter_data[key]['Covariance'].get_base_data())
                par.set_min_value(
                    Model.parameter_data[key]['Minimum'].get_base_data())
                par.set_max_value(
                    Model.parameter_data[key]['Maximum'].get_base_data())
                par.set_constraint_low(True)
                par.set_constraint_high(True)
                i = i + 1
        # Initialize the model for the simulation
        self.model.initialize_simulator()
        # Set model parameters
        for name in Model.parameter_data.keys():
            self.model.set_real(
                self.model.get_variable_object(name),
                Model.parameter_data[name]['Value'].get_base_data())
        # Instantiate the UKF for the FMU
        ukf_FMU = UkfFmu(self.model)
        # Start filter
        t0 = pd.to_datetime(0, unit="s", utc=True)
        t1 = pd.to_datetime(Model.elapsed_seconds, unit="s", utc=True)
        self.res_est = ukf_FMU.filter(start=t0, stop=t1)
        # Update parameter results
        self._get_parameter_results(Model)
Ejemplo n.º 2
0
    def _estimate(self, Model):
        '''Perform UKF estimation.

        '''

        estimationpy_logging.configure_logger(log_level = logging.DEBUG, log_level_console = logging.INFO, log_level_file = logging.DEBUG)
        # Write the inputs, measurements, and parameters to csv
        self._writeukfcsv(Model);
        # Select inputs
        for name in Model.input_names:
            inputvar = self.model.get_input_by_name(name);
            inputvar.get_csv_reader().open_csv(Model.csv_path);
            inputvar.get_csv_reader().set_selected_column(name);    
        # Select outputs
        for name in Model.measured_data.keys():
            outputvar = self.model.get_output_by_name(name);
            outputvar.get_csv_reader().open_csv(Model.csv_path);
            outputvar.get_csv_reader().set_selected_column(name);        
            outputvar.set_measured_output()
            outputvar.set_covariance(0.5)        
        # Select the parameters to be identified
        i = 0;
        for name in Model.parameter_data.keys():
            if Model.parameter_data[name]['Free'].get_base_data():
                self.model.add_parameter(self.model.get_variable_object(name));
                par = self.model.get_parameters()[i];
                par.set_initial_value(Model.parameter_data[name]['Value']);
                par.set_covariance(Model.parameter_data[name]['Covariance']);
                par.set_min_value(Model.parameter_data[name]['Minimum']);
                par.set_max_value(Model.parameter_data[name]['Maximum']);
                par.set_constraint_low(True);
                par.set_constraint_high(True);
                i = i + 1;
        # Initialize the model for the simulation
        self.model.initialize_simulator();
        # Set model parameters
        for name in Model.parameter_data.keys():
            self.model.set_real(self.model.get_variable_object(name),Model.parameter_data[name]['Data']); 
        for name in Model.coefficients.keys():
            self.model.set_real(self.model.get_variable_object(name),Model.coefficients[name]['InitialGuess']);
            print(self.model.get_real(self.model.get_variable_object(name)));
        # Instantiate the UKF for the FMU
        ukf_FMU = UkfFmu(self.model);
        # Start filter
        t0 = pd.to_datetime(0, unit = "s", utc = True);
        t1 = pd.to_datetime(Model.final_time, unit = "s", utc = True);
        time, x, sqrtP, y, Sy, y_full = ukf_FMU.filter(start = t0, stop = t1);
Ejemplo n.º 3
0
def main():
    
    # Assign an existing FMU to the model, depending on the platform identified
    dir_path = os.path.dirname(__file__)
    
    # Define the path of the FMU file
    if platform.architecture()[0]=="32bit":
        print "32-bit architecture"
        filePath = os.path.join(dir_path, "..", "..", "modelica", "FmuExamples", "Resources", "FMUs", "FirstOrder.fmu")
    else:
        print "64-bit architecture"
        filePath = os.path.join(dir_path, "..", "..", "modelica", "FmuExamples", "Resources", "FMUs", "FirstOrder_64bit.fmu")
        
    # Initialize the FMU model empty
    m = Model(filePath)
    
    # Path of the csv file containing the data series
    csvPath = os.path.join(dir_path, "..", "..", "modelica", "FmuExamples", "Resources", "data", "NoisySimulationData_FirstOrder.csv")
    
    # Set the CSV file associated to the input, and its covariance
    input_u = m.get_input_by_name("u")
    input_u.get_csv_reader().open_csv(csvPath)
    input_u.get_csv_reader().set_selected_column("system.u")
    input_u.set_covariance(2.0)
    
    # Set the CSV file associated to the output, and its covariance
    output = m.get_output_by_name("y")
    output.get_csv_reader().open_csv(csvPath)
    output.get_csv_reader().set_selected_column("system.y")
    output.set_measured_output()
    output.set_covariance(2.0)
    
    # Select the states to be identified, and add it to the list
    m.add_variable(m.get_variable_object("x"))
    
    # Set initial value of state, and its covariance and the limits (if any)
    var = m.get_variables()[0]
    var.set_initial_value(1.5)
    var.set_covariance(0.5)
    var.set_min_value(0.0)
    var.set_constraint_low(True)
    
    # show the info about the variable to be estimated
    print var.info()
    
    # Set parameters been identified
    par_a = m.get_variable_object("a")
    m.set_real(par_a, -0.90717055)
    par_b = m.get_variable_object("b")
    m.set_real(par_b, 2.28096907)
    par_c = m.get_variable_object("c")
    m.set_real(par_c, 3.01419707)
    par_d = m.get_variable_object("d")
    m.set_real(par_d, 0.06112703)
    
    # Initialize the model for the simulation
    m.initialize_simulator()
    
    # instantiate the UKF for the FMU
    ukf_FMU = UkfFmu(m)
    
    # Start the filter
    t0 = pd.to_datetime(0.0, unit = "s", utc = True)
    t1 = pd.to_datetime(30.0, unit = "s", utc = True)
    time, x, sqrtP, y, Sy, y_full = ukf_FMU.filter(start = t0, stop = t1)
    
    # Path of the csv file containing the True data series
    csvTrue = os.path.join(dir_path, "..", "..", "modelica", "FmuExamples", "Resources", "data", "SimulationData_FirstOrder.csv")
    
    # Get the measured outputs
    show_results(time, x, sqrtP, y, Sy, y_full, csvTrue, csvPath, m)
Ejemplo n.º 4
0
    def test_ukf_filter_first_order(self):
        """
        This method tests the ability of the filter to estimate the state
        of the first order system.
        """
        # Initialize the first order model
        self.set_first_order_model()

        # Associate inputs and outputs
        self.set_first_order_model_input_outputs()

        # Define the variables to estimate
        self.set_state_to_estimate_first_order()

        # Initialize the simulator
        self.m.initialize_simulator()

        # Retry to instantiate, now with a proper model
        ukf_FMU = UkfFmu(self.m)

        # Start the filter
        t0 = pd.to_datetime(0.0, unit="s", utc=True)
        t1 = pd.to_datetime(30.0, unit="s", utc=True)
        time, x, sqrtP, y, Sy, y_full = ukf_FMU.filter(start=t0, stop=t1)

        # Convert the results to numpy array
        time = time - time[0]
        time = np.array(map(lambda x: x.total_seconds(), time))
        x = np.array(x)
        y = np.array(y)
        sqrtP = np.array(sqrtP)
        Sy = np.array(Sy)
        y_full = np.squeeze(np.array(y_full))

        # Path of the csv file containing the True data series
        path_csv_simulation = os.path.join(dir_path, "..", "modelica",
                                           "FmuExamples", "Resources", "data",
                                           "SimulationData_FirstOrder.csv")

        # Compare the estimated states with the ones used to generate the data
        df_sim = pd.read_csv(path_csv_simulation, index_col=0)
        time_sim = df_sim.index.values

        # Difference between state estimated and real state
        x_sim = np.interp(time, time_sim, df_sim["system.x"])
        err_state = np.abs(x_sim - x[:, 0])

        # Identify maximum error and the time when it occurs
        max_error = np.max(err_state)
        t_max_error = np.where(err_state == max_error)

        # Make sure that the maximum error is less or equal than 0.5, and it happens at
        # the first time instant t = 0
        self.assertTrue(
            max_error <= 0.5,
            "The maximum error in the estimation has to be less than 0.5")
        self.assertTrue(t_max_error[0][0] == 0.0 and len(t_max_error[0]) == 1,\
                      "The maximum error is one and it is at t = 0")

        # Compute the mean absolute error
        avg_error = np.mean(err_state)
        self.assertTrue(avg_error < 0.06,
                        "The average error should be less than 0.06")

        # Compute that the estimation +/- covariance contains the real state
        x_plus_sigma = x[:, 0] + sqrtP[:, 0, 0]
        x_minus_sigma = x[:, 0] - sqrtP[:, 0, 0]
        self.assertTrue(len(np.where(x_sim < x_minus_sigma)[0]) == 0,\
                        "The state estimation must contain the real state in its boundaries")
        self.assertTrue(len(np.where(x_sim > x_plus_sigma)[0]) == 0,\
                        "The state estimation must contain the real state in its boundaries")

        return
Ejemplo n.º 5
0
    def test_ukf_filter_first_order(self):
        """
        This method tests the ability of the filter to estimate the state
        of the first order system.
        """
        # Initialize the first order model
        self.set_first_order_model()

        # Associate inputs and outputs
        self.set_first_order_model_input_outputs()

        # Define the variables to estimate
        self.set_state_to_estimate_first_order()

        # Initialize the simulator
        self.m.initialize_simulator()

        # Retry to instantiate, now with a proper model
        ukf_FMU = UkfFmu(self.m)

        # Start the filter
        t0 = pd.to_datetime(0.0, unit = "s", utc = True)
        t1 = pd.to_datetime(30.0, unit = "s", utc = True)
        time, x, sqrtP, y, Sy, y_full = ukf_FMU.filter(start = t0, stop = t1)

        # Convert the results to numpy array
        time = time - time[0]
        time = np.array(map(lambda x: x.total_seconds(), time))
        x = np.array(x)
        y = np.array(y)
        sqrtP = np.array(sqrtP)
        Sy = np.array(Sy)
        y_full = np.squeeze(np.array(y_full))
        
        # Path of the csv file containing the True data series
        path_csv_simulation = os.path.join(dir_path, "..", "modelica", "FmuExamples", "Resources", "data", "SimulationData_FirstOrder.csv")

        # Compare the estimated states with the ones used to generate the data
        df_sim = pd.read_csv(path_csv_simulation, index_col = 0)
        time_sim = df_sim.index.values
        
        # Difference between state estimated and real state
        x_sim = np.interp(time, time_sim, df_sim["system.x"])
        err_state = np.abs(x_sim - x[:,0])

        # Identify maximum error and the time when it occurs
        max_error = np.max(err_state)
        t_max_error = np.where(err_state == max_error)

        # Make sure that the maximum error is less or equal than 0.5, and it happens at
        # the first time instant t = 0
        self.assertTrue(max_error <= 0.5, "The maximum error in the estimation has to be less than 0.5")
        self.assertTrue(t_max_error[0][0] == 0.0 and len(t_max_error[0]) == 1,\
                      "The maximum error is one and it is at t = 0")
        
        # Compute the mean absolute error
        avg_error = np.mean(err_state)
        self.assertTrue(avg_error < 0.06, "The average error should be less than 0.06")
        
        # Compute that the estimation +/- covariance contains the real state
        x_plus_sigma = x[:,0] + sqrtP[:,0,0]
        x_minus_sigma = x[:,0] - sqrtP[:,0,0]
        self.assertTrue(len(np.where(x_sim < x_minus_sigma)[0]) == 0,\
                        "The state estimation must contain the real state in its boundaries")
        self.assertTrue(len(np.where(x_sim > x_plus_sigma)[0]) == 0,\
                        "The state estimation must contain the real state in its boundaries")

        return