Оцените параметры модели на эксперимент (код)

В этом примере показано, как использовать несколько экспериментов, чтобы оценить соединение значений параметра модели; некоторые, которые оцениваются с помощью всех экспериментов и других, которые оцениваются с помощью отдельных экспериментов. Пример также показывает, как сконфигурировать эксперименты оценки с зависимыми значениями параметров эксперимента.

Вы оцениваете параметры аккумулятора на основе данных, собранных в экспериментах, которые разряжают и заряжают батарею.

Откройте модель и получите экспериментальные данные

Этот пример оценивает параметры простой модели аккумулятора, sdoBattery. Вход модели является текущей батареей, и выход модели, напряжение клеммы батареи, вычисляется из состояния заряда батареи.

open_system('sdoBattery');

Модель основана на уравнении

E=(1-Loss)V-KQmax1-ss

В уравнении:

E напряжение клеммы батареи в Вольтах.

V батарея постоянное напряжение в Вольтах.

K сопротивление поляризации батареи в Омах.

Qmax максимальная емкость батареи в Ампер-часах.

s состояние заряда батареи, с 1 полностью заряжаемый и 0 разряженных. Состояние заряда батареи вычисляется из интеграла батареи, текущей с положительным текущим выбросом указания и отрицательной текущей зарядкой указания. Состояние заряда начальной буквы батареи задано Q0 в Ампер-часах.

Loss падение напряжения при зарядке, описанный как часть батареи постоянное напряжение. Когда батарея разряжается, это значение является нулем.

VK, 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)')

Figure contains 4 axes objects. Axes object 1 with title Experiment: Discharge contains an object of type line. Axes object 2 contains an object of type line. Axes object 3 with title Experiment: Charge contains an object of type line. Axes object 4 contains an object of type line.

Задайте эксперименты оценки

Создайте массив с 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')

Figure contains 3 axes objects. Axes object 1 contains an object of type line. Axes object 2 contains an object of type line. Axes object 3 with title Discharging Experiment: Simulated and Measured Responses Before Estimation contains 2 objects of type line. These objects represent Simulated Voltage, Measured Voltage.

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 25-Aug-2021 19:10:18

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

Figure contains 2 axes objects. Axes object 1 with title Discharging Experiment: Simulated and Measured Responses After Estimation contains 2 objects of type line. These objects represent Simulated Voltage, Measured Voltage. Axes object 2 with title Charging Experiment: Simulated and Measured Responses After Estimation contains 2 objects of type line. These objects represent Simulated Voltage, Measured Voltage.

Обновите значения параметра модели

Обновите модель VK, и Loss значения параметров.

sdo.setValueInModel('sdoBattery',vOpt);

Связанные примеры

Чтобы изучить, как оценить параметры батареи с помощью Parameter Estimator, смотрите Оценочные Параметры модели На Эксперимент (графический интерфейс пользователя).

Закройте модель

bdclose('sdoBattery')