В этом примере показано, как использовать несколько экспериментов для оценки комбинации значений параметров модели; некоторые из них оцениваются с использованием всех экспериментов, а другие - с использованием отдельных экспериментов. В примере также показано, как настроить эксперименты оценки с зависимыми от эксперимента значениями параметров.
Вы оцениваете параметры перезаряжаемой батареи на основе данных, собранных в экспериментах, которые разряжают и заряжают батарею.
В этом примере оцениваются параметры простой модели аккумуляторной батареи, sdoBattery. Входной сигнал модели представляет собой ток батареи, а выходной сигнал модели, напряжение на клемме батареи, вычисляется на основе состояния заряда батареи.
open_system('sdoBattery');
Модель основана на уравнении
V-KQmax1-ss
В уравнении:
- напряжение на клемме батареи в вольтах.
- постоянное напряжение батареи в вольтах.
- сопротивление поляризации батареи в Омах.
- максимальная емкость аккумулятора в ампер-часах.
- состояние заряда батареи, при этом 1 заряжается полностью, а 0 разряжается. Состояние заряда батареи вычисляется из интеграла тока батареи с положительным током, указывающим разряд, и отрицательным током, указывающим заряд. Начальное состояние заряда батареи определяется в ампер-часах.
- это падение напряжения при зарядке, выраженное как доля постоянного напряжения батареи. Когда батарея разряжается, это значение равно нулю.
V, K, Qmax, Q0, и Loss - переменные, определенные в рабочей области модели.
Загрузите данные эксперимента. 1.2V (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)')

Создайте двухэлементный массив объектов эксперимента, чтобы указать измеренные данные для двух экспериментов.
Создайте объект эксперимента для эксперимента разрядки батареи. Измеренные текущие данные задаются как временные ряды в объекте эксперимента.
DCharge_Exp = sdo.Experiment('sdoBattery');Укажите входные данные (текущие) в качестве объекта временных рядов.
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 имеет значение true, чтобы значение 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_Objectivefunction 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);Чтобы узнать, как оценить параметры батареи с помощью модуля оценки параметров, см. раздел Оценка параметров модели в эксперименте (GUI).
Закрыть модель
bdclose('sdoBattery')