exponenta event banner

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

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

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

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

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

open_system('sdoBattery');

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

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

В уравнении:

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

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

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

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

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

Потеря - это падение напряжения при зарядке, выраженное как доля постоянного напряжения батареи. Когда батарея разряжается, это значение равно нулю.

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

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

Определение экспериментов по оценке

Создайте двухэлементный массив объектов эксперимента, чтобы указать измеренные данные для двух экспериментов.

Создайте объект эксперимента для эксперимента разрядки батареи. Измеренные текущие данные задаются как временные ряды в объекте эксперимента.

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

Figure contains 3 axes. Axes 1 contains an object of type line. Axes 2 contains an object of type line. Axes 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 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')

Figure contains 2 axes. Axes 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 2 with title Charging Experiment: Simulated and Measured Responses After Estimation contains 2 objects of type line. These objects represent Simulated Voltage, Measured Voltage.

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

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

sdo.setValueInModel('sdoBattery',vOpt);

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

Чтобы узнать, как оценить параметры батареи с помощью модуля оценки параметров, см. раздел Оценка параметров модели в эксперименте (GUI).

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

bdclose('sdoBattery')