这个例子展示了如何使用多个实验估计混合模型参数值;一些估计使用的所有实验和其他人估计使用单独的实验。示例还展示了如何配置估计实验与实验相关的参数值。
你估计的参数基于实验,收集的数据的可充电电池放电和充电电池。
这个例子估计参数的一个简单的、可充电电池模型,sdoBattery
。模型的输入是电池电流和模型输出电池终端电压,计算从电池电荷状态。
open_system (“sdoBattery”);
模型是基于方程
在方程:
伏电池端电压。
伏电池恒压。
是电池的欧姆极化电阻。
在安时最大的电池容量。
电池充电状态,1是完全充电和0放电。电池电荷状态计算的积分与积极的电流放电指示电池电流和负电流指示充电。指定的电池初始电荷状态 在安时。
充电时的电压降,表示为电池恒压的一小部分。电池放电时这个值是零。
V
,K
,Qmax
,Q0处
,损失
模型中的变量定义的工作区。
加载实验数据。1.2 v (6500 mah)电池受到放电实验和充电实验。
负载sdoBattery_ExperimentData
的变量Charge_Data
和DCharge_Data
被加载到工作区。第一列的Charge_Data
包含时间数据。第二和第三列Charge_Data
描述了在电池充电电流和电压的实验。DCharge_Data
同样是结构化和包含一个电池放电实验数据。
次要情节(221),情节(DCharge_Data (: 1) / 3600, DCharge_Data(:, 2)标题(“实验:放电”)包含(的时间(小时))ylabel (“电流(A)”)次要情节(223)情节(DCharge_Data (: 1) / 3600, DCharge_Data(:, 3)包含(的时间(小时))ylabel (“电压(V)”)次要情节(222)、图(Charge_Data (: 1) / 3600, Charge_Data(:, 2)标题(实验:电荷的)包含(的时间(小时))ylabel (“电流(A)”)次要情节(224)情节(Charge_Data (: 1) / 3600, Charge_Data(:, 3)包含(的时间(小时))ylabel (“电压(V)”)
创建一个2-element组实验对象指定两个实验的测量数据。
创建一个实验对象对电池放电实验。测量当前数据被指定为实验对象的timeseries。
DCharge_Exp = sdo.Experiment (“sdoBattery”);
指定输入数据(当前)作为timeseries对象。
DCharge_Exp。InputData = timeseries (DCharge_Data (:, 2), DCharge_Data (: 1));
创建一个对象指定测量电压输出数据。
VoltageSig = 金宝appSimulink.SimulationData.Signal;VoltageSig。Name =“电压”;VoltageSig。BlockPath =“sdoBattery / SOC - >电压”;VoltageSig。PortType =“输出港”;VoltageSig。PortIndex = 1;VoltageSig。Values = timeseries(DCharge_Data(:,3),DCharge_Data(:,1));
将电压信号添加到放电实验预期的输出数据。
DCharge_Exp。OutputData = VoltageSig;
指定的电池初始充电状态的实验。电池充电状态建模的问(啊)
指定块的初始值的变量Q0处
。创建一个参数Q0处
变量和参数添加到实验。Q0处
是依赖于实验和放电和充电实验假设不同的值。
Q0 = sdo.getParameterFromModel (“sdoBattery”,“Q0处”);Q0处。Value = 6.5; Q0.Free = false;
Q0.Free
被设置为假
因为最初的电池充电,不需要估计。
添加Q0处
参数实验。
DCharge_Exp。参数= 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啊),但是收费的价值损失分数(损失
)是未知的。
Q0处。Value = 0; Loss = sdo.getParameterFromModel(“sdoBattery”,“损失”);Loss.Free=true; Loss.Minimum = 0; Loss.Maximum = 0.5; Charge_Exp.Parameters = [Q0;Loss];
Loss.Free
的值被设置为true,这样吗损失
估计。
收集两个实验为一个向量。
经验= [DCharge_Exp;Charge_Exp];
创建一个模拟场景使用第一(放电)实验,获得模拟输出。
模拟器= createSimulator (Exp (1));模拟器= sim(模拟器);
电压信号的搜索记录的仿真数据。
SimLog =找到(Simulator.LoggedData get_param (“sdoBattery”,“SignalLoggingName”));电压(1)=找到(SimLog“电压”);
获得第二个模拟电压信号(充电)的实验。
模拟器= createSimulator (Exp(2),模拟器);模拟器= sim(模拟器);SimLog =找到(Simulator.LoggedData get_param (“sdoBattery”,“SignalLoggingName”));电压(2)=找到(SimLog,“电压”);
图测量和模拟数据。模型响应不匹配实验输出数据。
次要情节(211)图(…电压(1).Values.Time / 3600、电压(1).Values.Data,…实验(1).OutputData.Values。时间/ 3600、Exp (1) .OutputData.Values.Data“-”。)标题(的放电试验:模拟和测量响应之前估计的)ylabel (“电压(V)”)传说(模拟电压的,测量电压的,“位置”,“西南”)
次要情节(212)图(…电压(2).Values.Time / 3600、电压(2).Values.Data,…Exp (2) .OutputData.Values。时间/ 3600、Exp (2) .OutputData.Values.Data“-”。)标题(“充电试验:模拟和测量响应之前估计的)包含(的时间(小时))ylabel (“电压(V)”)传说(模拟电压的,测量电压的,“位置”,“东南”)
估计电池电压的值V
,电池极化电阻K
,充电部分损失损失
。的V
和K
参数估计使用所有实验数据时损失
参数估计只使用收费数据。
选择电池电压V
和电池极化电阻K
从模型参数。为这些参数指定最小值和最大值范围。
p = sdo.getParameterFromModel (“sdoBattery”,{“V”,“K”});(1页)。最小值= 0;(1页)。最大= 2;(2页)。最小值= 1 e-6;(2页)。最大= 1 e 1;
得到experiment-specific损失
从实验参数。
s = getValuesToEstimate (Exp);
集团所有的参数估计。
v = (p, s)
v(1, - 1) =名字:“v”值:1.2000最低:0最大:2自由:1规模:2信息:[1 x1 struct] v(2, 1) =名字:“K”值:1.0000 e 03最低:1.0000 e-06最大:0.1000自由:1比例:0.0020信息:[1 x1 struct] v(3,1) =名字:“损失”值:0.0100最低:0最高:0.5000自由:1比例:0.0156信息:[1 x1 struct] 3 x1 param.Continuous
创建一个估计目标函数来评估仿真输出,使用估计的参数值,生成匹配的测量数据。
使用一个匿名函数调用的一个输入参数sdoBattery_Objective
函数。我们通过匿名函数sdo.optimize
在每个迭代优化,评估函数。
estFcn = @ (v) sdoBattery_Objective (v,模拟器,Exp);
的sdoBattery_Objective
功能:
有一个输入参数,用于指定估计电池参数值。
有一个输入参数,用于指定包含测量数据的实验对象。
返回一个向量模拟和实验输出之间的误差。
的sdoBattery_Objective
函数需要两个输入,但是sdo.optimize
需要一个函数和一个输入参数。为了解决这一问题,estFcn
是一个匿名函数输入参数,v
,但它调用sdoBattery_Objective
使用两个输入参数,v
和经验值
。
有关匿名函数的更多信息,请参阅匿名函数。
的sdo.optimize
命令最小化返回参数的匿名函数estFcn
,即剩余错误返回sdoBattery_Objective
。更多细节关于如何编写一个目标/约束函数使用sdo.optimize
命令,键入帮助sdoExampleCostFunction
在MATLAB®命令提示符。
更详细地检查估计目标函数,类型编辑sdoBattery_Objective
在MATLAB命令提示符。
类型sdoBattery_Objective
函数vals = sdoBattery_Objective (v,模拟器,Exp) % sdoBattery_Objective % % % sdoBattery_Objective函数是用来比较模型输出实验数据。% % vals = sdoBattery_Objective v (v, Exp) % % | |输入参数是一个向量的估计模型参数值%和初始状态。% % | |模拟器的输入参数是一个模拟对象使用%模拟模型估计参数值。% % | Exp |输入参数包含评估实验数据。% % | vals |返回参数包含有关如何%模型仿真结果与实验数据和使用% | sdo。优化|函数来估计模型参数。% %也看到sdo。优化,sdoExampleCostFunction % % 2012 - 2015版权MathWorks, Inc . % % %定义一个信号跟踪要求计算,模型输出%匹配实验数据。配置跟踪要求%这样返回跟踪误差残差(而不是% sum-squared-error)和不正常的错误。% 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解算器。
选择= sdo.OptimizeOptions;opt.Method =“lsqnonlin”;
估计的参数。
vOpt = sdo.optimize (estFcn, v,选择)
优化开始2021年- 2月23日19:26:38一阶Iter F-count f (x)步长最优14 0 7 3272.22 1 1 619.356 0.1634 3.15 e + 05年2 21 3 28 405.529 0.3838 2.16 411.131 0.2175 28.7 e + 03 4 35 42 403.379 0.1645 1.14 403.727 - 0.2767 15.2 - 5 e + 03局部最小值。lsqnonlin停止是因为最后的平方和的变化相对于其初始值小于公差的值函数。vOpt(1, - 1) =名字:“V”值:1.3083最低:0最大:2自由:1规模:2信息:[1 x1 struct] vOpt(2, 1) =名字:“K”值:0.0010最低:1.0000 e-06最大:0.1000自由:1比例:0.0020信息:[1 x1 struct] vOpt(3,1) =名字:“损失”值:5.1801 e-05最低:0最高:0.5000自由:1比例:0.0156信息:[1 x1 struct] 3 x1 param.Continuous
更新实验估计参数值。
经验= setEstimatedValues (Exp、vOpt);
获得第一(放电)模拟输出实验。
模拟器= createSimulator (Exp(1)模拟器);模拟器= sim(模拟器);SimLog =找到(Simulator.LoggedData get_param (“sdoBattery”,“SignalLoggingName”));电压(1)=找到(SimLog“电压”);
获得模拟输出第二个实验(收费)。
模拟器= createSimulator (Exp(2),模拟器);模拟器= sim(模拟器);SimLog =找到(Simulator.LoggedData get_param (“sdoBattery”,“SignalLoggingName”));电压(2)=找到(SimLog,“电压”);
图测量和模拟数据。仿真结果与实验数据除了区域当电池完全充电。这不是意外的简单的电池模型并不模型指数电池完全充电时电压降。
次要情节(211)图(…电压(1).Values.Time / 3600、电压(1).Values.Data,…实验(1).OutputData.Values。时间/ 3600、Exp (1) .OutputData.Values.Data“-”。)标题(后的放电试验:模拟和测量响应估计的)ylabel (“电压(V)”)传说(模拟电压的,测量电压的,“位置”,“西南”情节)次要情节(212)(…电压(2).Values.Time / 3600、电压(2).Values.Data,…Exp (2) .OutputData.Values。时间/ 3600、Exp (2) .OutputData.Values.Data“-”。)标题(“充电试验:模拟和测量反应后评估”)包含(的时间(小时))ylabel (“电压(V)”)传说(模拟电压的,测量电压的,“位置”,“东南”)
更新模型V
,K
,损失
参数值。
sdo.setValueInModel (“sdoBattery”,vOpt);
学习如何使用估计电池参数参数估计量,请参阅每个实验(GUI)估计模型参数。
关闭模式
bdclose (“sdoBattery”)