В этом примере показано, как использовать несколько экспериментов, чтобы оценить соединение значений параметра модели; некоторые, которые оцениваются с помощью всех экспериментов и других, которые оцениваются с помощью отдельных экспериментов. Пример также показывает, как сконфигурировать эксперименты оценки с зависимыми значениями параметров эксперимента.
Вы оцениваете параметры аккумулятора на основе данных, собранных в экспериментах, которые разряжают и заряжают батарею.
Этот пример оценивает параметры простой модели аккумулятора, sdoBattery
. Вход модели является текущей батареей, и выход модели, напряжение клеммы батареи, вычисляется из состояния заряда батареи.
open_system('sdoBattery');
Модель основана на уравнении
В уравнении:
напряжение клеммы батареи в Вольтах.
батарея постоянное напряжение в Вольтах.
сопротивление поляризации батареи в Омах.
максимальная емкость батареи в Ампер-часах.
состояние заряда батареи, с 1 полностью заряжаемый и 0 разряженных. Состояние заряда батареи вычисляется из интеграла батареи, текущей с положительным текущим выбросом указания и отрицательной текущей зарядкой указания. Состояние заряда начальной буквы батареи задано в Ампер-часах.
падение напряжения при зарядке, описанный как часть батареи постоянное напряжение. Когда батарея разряжается, это значение является нулем.
V
K
, Qmax
, Q0
, и Loss
переменные, заданные в рабочем пространстве модели.
Загрузите данные об эксперименте. 1.2 В (6500mAh) батарея были подвергнуты эксперименту выброса и заряжающемуся эксперименту.
load sdoBattery_ExperimentData
Переменные Charge_Data
и DCharge_Data
загружаются в рабочую область. Первый столбец Charge_Data
содержит данные времени. Вторые и третьи столбцы Charge_Data
опишите ток и напряжение во время эксперимента зарядки аккумулятора. DCharge_Data
так же структурирован и содержит данные для эксперимента разряда батареи.
subplot(221), plot(DCharge_Data(:,1)/3600,DCharge_Data(:,2)) title('Experiment: Discharge') xlabel('Time (hours)') ylabel('Current (A)') subplot(223) plot(DCharge_Data(:,1)/3600,DCharge_Data(:,3)) xlabel('Time (hours)') ylabel('Voltage (V)') subplot(222), plot(Charge_Data(:,1)/3600,Charge_Data(:,2)) title('Experiment: Charge') xlabel('Time (hours)') ylabel('Current (A)') subplot(224) plot(Charge_Data(:,1)/3600,Charge_Data(:,3)) xlabel('Time (hours)') ylabel('Voltage (V)')
Создайте массив с 2 элементами объектов эксперимента задать результаты измерений для двух экспериментов.
Создайте объект эксперимента для эксперимента выброса батареи. Измеренные текущие данные заданы как timeseries в объекте эксперимента.
DCharge_Exp = sdo.Experiment('sdoBattery');
Задайте входные данные (текущие) как объект timeseries.
DCharge_Exp.InputData = timeseries(DCharge_Data(:,2),DCharge_Data(:,1));
Создайте объект задать измеренные выходные данные напряжения.
VoltageSig = Simulink.SimulationData.Signal; VoltageSig.Name = 'Voltage'; VoltageSig.BlockPath = 'sdoBattery/SOC -> Voltage'; VoltageSig.PortType = 'outport'; VoltageSig.PortIndex = 1; VoltageSig.Values = timeseries(DCharge_Data(:,3),DCharge_Data(:,1));
Добавьте сигнал напряжения в эксперимент выброса как ожидаемые выходные данные.
DCharge_Exp.OutputData = VoltageSig;
Задайте состояние первоначального сбора батареи для эксперимента. Состояние заряда батареи моделируется Q (Ah)
блокируйтесь и это - начальное значение, задан переменной Q0
. Создайте параметр для Q0
переменная и добавляет параметр в эксперимент. Q0
зависимый эксперимента и принимает различные значения в разряде и зарядке экспериментов.
Q0 = sdo.getParameterFromModel('sdoBattery','Q0'); Q0.Value = 6.5; Q0.Free = false;
Q0.Free
установлен в false
потому что начальный заряд батареи известен и не должен быть оценен.
Добавьте Q0
параметр к эксперименту.
DCharge_Exp.Parameters = Q0;
Создайте объект эксперимента хранить заряжающиеся данные об эксперименте. Добавьте измеренный текущий вход и измеренные выходные данные напряжения к объекту.
Charge_Exp = sdo.Experiment('sdoBattery');
Charge_Exp.InputData = timeseries(Charge_Data(:,2),Charge_Data(:,1));
VoltageSig.Values = timeseries(Charge_Data(:,3),Charge_Data(:,1));
Charge_Exp.OutputData = VoltageSig;
Добавьте первоначальный сбор батареи и заряжающиеся параметры части потерь к эксперименту. Для этого эксперимента, первоначальный сбор (Q0
) известен (0 А-ч), но значение заряжающейся части потерь (Loss
) не известен.
Q0.Value = 0; Loss = sdo.getParameterFromModel('sdoBattery','Loss'); Loss.Free = true; Loss.Minimum = 0; Loss.Maximum = 0.5; Charge_Exp.Parameters = [Q0;Loss];
Loss.Free
установлен в истину так, чтобы значение Loss
оценивается.
Соберите оба эксперимента в один вектор.
Exp = [DCharge_Exp; Charge_Exp];
Создайте сценарий симуляции с помощью первого (разряд) эксперимент и получите симулированный выход.
Simulator = createSimulator(Exp(1)); Simulator = sim(Simulator);
Ищите сигнал напряжения в регистрируемых данных моделирования.
SimLog = find(Simulator.LoggedData,get_param('sdoBattery','SignalLoggingName')); Voltage(1) = find(SimLog,'Voltage');
Получите симулированный сигнал напряжения для второго (зарядка) эксперимент.
Simulator = createSimulator(Exp(2),Simulator); Simulator = sim(Simulator); SimLog = find(Simulator.LoggedData,get_param('sdoBattery','SignalLoggingName')); Voltage(2) = find(SimLog,'Voltage');
Отобразите измеренные и симулированные данные на графике. Ответ модели не совпадает с экспериментальными выходными данными.
subplot(211) plot(... Voltage(1).Values.Time/3600,Voltage(1).Values.Data, ... Exp(1).OutputData.Values.Time/3600, Exp(1).OutputData.Values.Data,'-.') title('Discharging Experiment: Simulated and Measured Responses Before Estimation') ylabel('Voltage (V)') legend('Simulated Voltage','Measured Voltage','Location','SouthWest')
subplot(212) plot(... Voltage(2).Values.Time/3600,Voltage(2).Values.Data, ... Exp(2).OutputData.Values.Time/3600, Exp(2).OutputData.Values.Data,'-.') title('Charging Experiment: Simulated and Measured Responses Before Estimation') xlabel('Time (hours)') ylabel('Voltage (V)') legend('Simulated Voltage','Measured Voltage','Location','SouthEast')
Оцените значения напряжения батареи V
, сопротивление поляризации батареи K
, и заряжающаяся потеря фракционировала Loss
. V
и K
параметры оцениваются с помощью всех данных об эксперименте в то время как Loss
параметр оценивается с помощью только заряжающиеся данные.
Выберите напряжение батареи V
и сопротивление поляризации батареи K
параметры из модели. Задайте минимальные и максимальные границы для этих параметров.
p = sdo.getParameterFromModel('sdoBattery',{'V','K'}); p(1).Minimum = 0; p(1).Maximum = 2; p(2).Minimum = 1e-6; p(2).Maximum = 1e-1;
Получите специфичный для эксперимента Loss
параметр из эксперимента.
s = getValuesToEstimate(Exp);
Группа все параметры, которые будут оценены.
v = [p;s]
v(1,1) = Name: 'V' Value: 1.2000 Minimum: 0 Maximum: 2 Free: 1 Scale: 2 Info: [1x1 struct] v(2,1) = Name: 'K' Value: 1.0000e-03 Minimum: 1.0000e-06 Maximum: 0.1000 Free: 1 Scale: 0.0020 Info: [1x1 struct] v(3,1) = Name: 'Loss' Value: 0.0100 Minimum: 0 Maximum: 0.5000 Free: 1 Scale: 0.0156 Info: [1x1 struct] 3x1 param.Continuous
Создайте целевую функцию оценки, чтобы оценить, как тесно симуляция выход, сгенерированное использование предполагаемых значений параметров, совпадает с результатами измерений.
Используйте анонимную функцию с одним входным параметром, который вызывает sdoBattery_Objective
функция. Мы передаем анонимную функцию sdo.optimize
, который выполняет функцию в каждой итерации оптимизации.
estFcn = @(v) sdoBattery_Objective(v,Simulator,Exp);
sdoBattery_Objective
функция:
Имеет один входной параметр, который задает предполагаемые значения параметров батареи.
Имеет один входной параметр, который задает объект эксперимента, содержащий результаты измерений.
Возвращает вектор из ошибок между симулированными и экспериментальными выходными параметрами.
sdoBattery_Objective
функция требует двух входных параметров, но sdo.optimize
требует функции с одним входным параметром. Работать вокруг этого, estFcn
анонимная функция с одним входным параметром, v
, но это вызывает sdoBattery_Objective
с помощью двух входных параметров, v
и Exp
.
Для получения дополнительной информации относительно анонимных функций, см. Анонимные функции.
sdo.optimize
команда минимизирует возвращаемый аргумент анонимной функции estFcn
, то есть, остаточные ошибки, возвращенные sdoBattery_Objective
. Для получения дополнительной информации о том, как записать, что цель/ограничение функционирует, чтобы использовать с sdo.optimize
команда, введите help sdoExampleCostFunction
в командной строке MATLAB®.
Чтобы исследовать целевую функцию оценки более подробно, введите edit sdoBattery_Objective
в командной строке MATLAB.
type sdoBattery_Objective
function vals = sdoBattery_Objective(v,Simulator,Exp) %SDOBATTERY_OBJECTIVE % % The sdoBattery_Objective function is used to compare model % outputs against experimental data. % % vals = sdoBattery_Objective(v,Exp) % % The |v| input argument is a vector of estimated model parameter values % and initial states. % % The |Simulator| input argument is a simulation object used % simulate the model with the estimated parameter values. % % The |Exp| input argument contains the estimation experiment data. % % The |vals| return argument contains information about how well the % model simulation results match the experimental data and is used by % the |sdo.optimize| function to estimate the model parameters. % % See also sdo.optimize, sdoExampleCostFunction % % Copyright 2012-2015 The MathWorks, Inc. %% % Define a signal tracking requirement to compute how well the model output % matches the experiment data. Configure the tracking requirement so that % it returns the tracking error residuals (rather than the % sum-squared-error) and does not normalize the errors. % r = sdo.requirements.SignalTracking; r.Type = '=='; r.Method = 'Residuals'; r.Normalize = 'off'; %% % Update the experiments with the estimated parameter values. % Exp = setEstimatedValues(Exp,v); %% % Simulate the model and compare model outputs with measured experiment % data. % Error = []; for ct=1:numel(Exp) Simulator = createSimulator(Exp(ct),Simulator); Simulator = sim(Simulator); SimLog = find(Simulator.LoggedData,get_param('sdoBattery','SignalLoggingName')); Voltage = find(SimLog,'Voltage'); VoltageError = evalRequirement(r,Voltage.Values,Exp(ct).OutputData(1).Values); Error = [Error; VoltageError(:)]; end %% % Return the residual errors to the optimization solver. % vals.F = Error(:); end
Используйте sdo.optimize
функционируйте, чтобы оценить значения параметров батареи.
Задайте опции оптимизации. Функция оценки sdoBattery_Objective
возвращает ошибочные остаточные значения между симулированными и экспериментальными данными и не включает ограничений, делая этот проблемный идеал для 'lsqnonlin' решателя.
opt = sdo.OptimizeOptions;
opt.Method = 'lsqnonlin';
Оцените параметры.
vOpt = sdo.optimize(estFcn,v,opt)
Optimization started 22-Apr-2021 20:11:49 First-order Iter F-count f(x) Step-size optimality 0 7 3272.22 1 1 14 619.356 0.1634 3.15e+05 2 21 411.131 0.2175 28.7 3 28 405.529 0.3838 2.16e+03 4 35 403.727 0.2767 15.2 5 42 403.379 0.1645 1.14e+03 Local minimum possible. lsqnonlin stopped because the final change in the sum of squares relative to its initial value is less than the value of the function tolerance. vOpt(1,1) = Name: 'V' Value: 1.3083 Minimum: 0 Maximum: 2 Free: 1 Scale: 2 Info: [1x1 struct] vOpt(2,1) = Name: 'K' Value: 0.0010 Minimum: 1.0000e-06 Maximum: 0.1000 Free: 1 Scale: 0.0020 Info: [1x1 struct] vOpt(3,1) = Name: 'Loss' Value: 5.1801e-05 Minimum: 0 Maximum: 0.5000 Free: 1 Scale: 0.0156 Info: [1x1 struct] 3x1 param.Continuous
Обновите эксперименты с предполагаемыми значениями параметров.
Exp = setEstimatedValues(Exp,vOpt);
Получите симулированный выход для первого (разряд) эксперимент.
Simulator = createSimulator(Exp(1),Simulator); Simulator = sim(Simulator); SimLog = find(Simulator.LoggedData,get_param('sdoBattery','SignalLoggingName')); Voltage(1) = find(SimLog,'Voltage');
Получите симулированный выход для второго (зарядка) эксперимент.
Simulator = createSimulator(Exp(2),Simulator); Simulator = sim(Simulator); SimLog = find(Simulator.LoggedData,get_param('sdoBattery','SignalLoggingName')); Voltage(2) = find(SimLog,'Voltage');
Отобразите измеренные и симулированные данные на графике. Результаты симуляции совпадают с экспериментальными данными хорошо кроме областей, когда батарея полностью заряжена. Это не неожиданно, когда простая модель батареи не моделирует экспоненциальное падение напряжения, когда батарея полностью заряжена.
subplot(211) plot(... Voltage(1).Values.Time/3600,Voltage(1).Values.Data, ... Exp(1).OutputData.Values.Time/3600, Exp(1).OutputData.Values.Data,'-.') title('Discharging Experiment: Simulated and Measured Responses After Estimation') ylabel('Voltage (V)') legend('Simulated Voltage','Measured Voltage','Location','SouthWest') subplot(212) plot(... Voltage(2).Values.Time/3600,Voltage(2).Values.Data, ... Exp(2).OutputData.Values.Time/3600, Exp(2).OutputData.Values.Data,'-.') title('Charging Experiment: Simulated and Measured Responses After Estimation') xlabel('Time (hours)') ylabel('Voltage (V)') legend('Simulated Voltage','Measured Voltage','Location','SouthEast')
Обновите модель V
K
, и Loss
значения параметров.
sdo.setValueInModel('sdoBattery',vOpt);
Чтобы изучить, как оценить параметры батареи с помощью Parameter Estimator, смотрите Оценочные Параметры модели На Эксперимент (графический интерфейс пользователя).
Закройте модель
bdclose('sdoBattery')