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)
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);
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)
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
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