Оценка значений параметров модели механической системы
Оценка значений параметров модели механической системы
В этом примере показано, как использовать экспериментальные данные для оценки значений параметров модели.
Модель механической системы
Модель механической системы состоит из массы, пружины и демпфера. Датчик относительного поступательного движения установлен таким образом, чтобы выходные данные модели соответствовали измеренным данным.
Параметры модели
Известно, что значение массы m составляет 3.6 кг., ее начальное положение x0 равно 1 м. Коэффициенты жесткости поступательной пружины k и демпфирования поступательного демпфера b неизвестны, поэтому для них укажем приблизительные значения:
m = 3.600 # кг
k = 400.0 # Н/м
b = 10.0 # Н*с/м
x0 = 1.0; #м
Создание эксперимента для оценки
Загрузим измеренные данные:
using CSV
using DataFrames
#Загружаем измеренные данные из CSV файла и создаем DataFrame
position_ref = CSV.read("$(@__DIR__)/position_reference.csv", DataFrame)
Первый столбец данных содержит вектор времени, второй соответствующие ему измеренные значения положения массы.
Создадим объект position для хранения измеренных значений данных position_ref, связав его с 1-м выходом блока Датчик относительного поступательного движения и сигналом position:
position = EngeeDesignOptimization.simulation_signal(
block_path = "MassSpringDamper",
block = "Датчик относительного поступательного движения",
port = "1",
values = position_ref,
name = "position",
);
Внимание
Для сигнала position обязательно должно быть включено логирование в модели.
Выберем неизвестные параметры модели b и k, создав вектор объектов оцениваемых параметров. Начальные значения оставим равными уже заданным приблизительным значениям. Укажем границы, исходя из того, что искомые параметры по физическому смыслу должны быть неотрицательными:
parameters = EngeeDesignOptimization.getParameterFromWorkspace(["b", "k"])
parameters[1].value = 10.0; #b
parameters[1].minimum = 0.0;
parameters[2].value = 400.0; #k
parameters[2].minimum = 0.0;
Внимание
Переменные b и k обязательно должны быть определены в Рабочей области.
Создадим объект эксперимента, хранящий выходные данные и вектор оцениваемых параметров:
exp = EngeeDesignOptimization.Experiment(
model_name = "MassSpringDamper",
output_data = position,
parameters = parameters,
);
Сравнение измеренного выходного сигнала и смоделированного
Загрузим и откроем модель механической системы MassSpringDamper для создания сценария моделирования на основе эксперимента:
engee.load("$(@__DIR__)/MassSpringDamper.engee", force=true)
engee.open("MassSpringDamper");
#Создание сценария симуляции
simulator = EngeeDesignOptimization.SimulationTest(exp);
Запустим симуляцию, найдем сигнал position в результатах моделирования и получим его значения:
#Запуск сценария моделирования
sim_data = EngeeDesignOptimization.run(simulator)
#Найдем сигнал position
position_sim = EngeeDesignOptimization.find(sim_data, exp.output_data);
#Выгрузим данные из WorkspaceArray в DataFrame
position_sim = collect(position_sim)
Определим функцию для построения графика сравнения двух сигналов:
function compare_plot(reference, simulation, title)
plot(
simulation[:,1],
simulation[:,2],
label = "Смоделированное положение массы",
title = title,
xlabel = "t, с",
ylabel = "x, м",
lw = 3,
legend=:bottomright,
)
plot!(
reference[:,1],
reference[:,2],
label = "Измеренное положение массы",
lw = 3,
)
end
Установим необходимые зависимости и подключим пакет построения графиков Plots:
import Pkg
Pkg.add("PlotlyKaleido")
using Plots
plotly();
Построим график смоделированных и измеренных данных:
compare_plot(
exp.output_data.values,
position_sim,
"Смоделированное и измеренное положение массы до оценки",
)
Как и ожидалось, отклик модели не соответствует экспериментальным данным.
Целевая функция для оценки параметров
Целевая функция позволяет вычислить, насколько точно результаты моделирования, полученные с использованием оцениваемых значений параметров, соответствуют измеренным данным.
В ходе оценки параметров EngeeDesignOptimization.optimize минимизирует значение, возвращаемое целевой функцией.
Определим целевую функцию objective_function, принимающую следующие аргументы:
· p - вектор оцениваемых параметров;
· sim - сценарий моделирования;
· exp - объект эксперимента.
Функция будет возвращать вектор ошибок (невязок) между измеренным и смоделированным сигналами.
function objective_function(p, sim, exp)
#Объект требований, заданных к выходному сигналу модели:
# - измеренный и смоделированный сигналы должны совпадать
# - вычисляем вектор ошибок (невязок) между измеренным и смоделированным сигналами
req = EngeeDesignOptimization.SignalTracking()
req.Type = "=="
req.Method = "Residuals"
req.Normalize = false
#Устанавливаем новые значения оцениваемых параметров в рабочей области
exp = EngeeDesignOptimization.setEstimatedValues!(exp, p)
#Обновляем сценарий моделирования
sim = EngeeDesignOptimization.SimulationTest!(sim,exp)
#Запуск моделирования
sim_data = EngeeDesignOptimization.run(sim)
#Находим нужный сигнал и извлекаем его
position = EngeeDesignOptimization.find(sim_data, exp.output_data) |> collect
#Вычисляем разницу между измеренным и смоделированным сигналами исходя из предъявленных требований
position_error = EngeeDesignOptimization.evalRequirement(req, position, exp.output_data.values)
#Возвращаем словарь, содержащий вектор ошибок (невязок)
return Dict("F"=>vec(position_error))
end
Оценка параметров
Для оценки параметров будем использовать настройки оптимизатора по умолчанию:
opt = EngeeDesignOptimization.OptimizeOptions();
EngeeDesignOptimization.optimize может минимизировать функцию, принимающую только один аргумент - вектор оцениваемых параметров. Поэтому определим вспомогательную анонимную функцию с одним аргументом p, которая будет вызывать целевую функцию objective_function:
est_fcn = (p) -> objective_function(p, simulator, exp);
Запустим оценку параметров:
parameters_opt, _ = EngeeDesignOptimization.optimize(est_fcn, parameters, opt);
Сравнение измеренного выходного сигнала и смоделированного после оценки параметров
Обновим результаты эксперимента, используя результаты оценки:
exp = EngeeDesignOptimization.setEstimatedValues!(exp, parameters_opt);
Проведем симуляцию с новыми параметрами и построим график смоделированных и измеренных данных:
simulator = EngeeDesignOptimization.SimulationTest!(simulator,exp)
sim_data = EngeeDesignOptimization.run(simulator)
position_sim = EngeeDesignOptimization.find(sim_data, exp.output_data)
position_sim = collect(position_sim)
compare_plot(
exp.output_data.values,
position_sim,
"Смоделированное и измеренное положение массы после оценки",
)
На графике видно, что результаты моделирования точно соответствуют данным, полученным в ходе эксперимента.
Заключение
Библиотека EngeeDesignOptimization дает возможность подбирать параметры моделей используя экспериментальные данные. При наличии данных с реальной системы, метод позволяет получать результаты моделирования, точно совпадающие с измеренными характеристиками объектов.
