Этот пример показывает, как использовать несколько экспериментов, чтобы оценить соединение значений параметра модели; некоторые, которые оцениваются с помощью всех экспериментов и других, которые оцениваются с помощью отдельных экспериментов. Пример также показывает, как сконфигурировать эксперименты оценки с зависимыми значениями параметров эксперимента.
Вы оцениваете параметры аккумулятора на основе данных, собранных в экспериментах, которые разряжают и заряжают батарею.
Этот пример оценивает параметры простой модели аккумулятора, sdoBattery
. Образцовый вход является текущей батареей, и образцовый вывод, напряжение клеммы батареи, вычисляется из состояния заряда батареи.
open_system('sdoBattery');
Модель основана на уравнении
Где:
напряжение клеммы батареи в Вольтах.
батарея постоянное напряжение в Вольтах.
сопротивление поляризации батареи в Омах.
максимальная мощность батареи в Ампер-часе.
состояние заряда батареи, с 1 полностью заряжаемый и 0 нулевых зарядов. Состояние заряда батареи вычисляется из интеграла батареи, текущей с +ve текущим выбросом указания и-ve текущей зарядкой указания. Состояние заряда начальной буквы батареи задано в Ампер-часе.
падение напряжения при зарядке, выраженный как часть батареи постоянное напряжение. Когда батарея разряжается, это значение является нулем.
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);
Group all the parameters to be estimated.
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, sdoBattery_cmddemo % % 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 11-Jan-2019 03:23:27 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 Estimation Tool, см. "Оценочные Параметры модели На Эксперимент (графический интерфейс пользователя)".
Закройте модель
bdclose('sdoBattery')