这个例子展示了如何使用多个实验来估计模型参数值的混合;有些是用所有实验来估计的有些是用单个实验来估计的。该示例还展示了如何配置与实验相关的参数值的估计实验。
你估计一个可充电电池的参数,基于在放电和充电的实验中收集的数据。
这个例子估计了一个简单的充电电池模型的参数,sdoBattery
这个model input is the battery current and the model output, the battery terminal voltage, is computed from the battery state-of-charge.
开放式系统(“斯多巴特里”);
该模型基于该方程
在方程式中:
为电池端电压,单位为伏特。
为电池恒压,单位为伏特。
为电池极化电阻,单位为欧姆。
是以安培小时为单位的最大电池容量。
是蓄电池充电状态,1充满电,0放电。蓄电池充电状态由蓄电池电流的积分计算得出,正极电流表示放电,负极电流表示充电。蓄电池初始充电状态由 以安培小时为单位。
为充电时的压降,用电池恒压的分数表示。当电池放电时,这个值为零。
V
,K
,最大尿流率
,Q0
,及损失
是在模型工作区中定义的变量。
加载实验数据。对1.2V(6500mAh)电池进行了放电实验和充电实验。
负载sdoBattery_ExperimentData
变量Charge_Data
和DCharge_Data
加载到工作区中。第一列Charge_Data
包含时间数据。第二列和第三列Charge_Data
描述电池充电实验中的电流和电压。DCharge_Data
结构类似,并包含电池放电实验的数据。
子地块(221),地块(收费数据(:,1)/3600,收费数据(:,2))标题(“实验:放电”)xlabel(的时间(小时))伊拉贝尔("现时(甲)") subplot(223) plot(DCharge_Data(:,1)/3600,DCharge_Data(:,3)) xlabel(的时间(小时))伊拉贝尔(‘电压(V)’) subplot(222), plot(Charge_Data(:,1)/3600,Charge_Data(:,2)) title(实验:电荷的)xlabel(的时间(小时))伊拉贝尔("现时(甲)") subplot(224) plot(Charge_Data(:,1)/3600,Charge_Data(:,3)) xlabel(的时间(小时))伊拉贝尔(‘电压(V)’)
创建一个2元素的实验对象数组,以指定两个实验的测量数据。
创建电池放电实验的实验对象。测量到的电流数据在实验对象中指定为时间序列。
DCharge_Exp = sdo。实验(“斯多巴特里”);
将输入数据(当前)指定为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=电压信号;
指定实验的电池初始充电状态。电池充电状态由问(啊)
块,它的初始值由变量指定Q0
.的参数Q0
变量,并将参数添加到实验中。Q0
是依赖于实验的,在放电和充电实验中假设不同的值。
Q0 = sdo.getParameterFromModel (“斯多巴特里”,“Q0处”);Q0处。Value = 6.5; Q0.Free = false;
Q0处。免费的
设置为假
因为初始电池电量是已知的,不需要估计。
添加Q0
参数的实验。
DCharge_Exp.Parameters=Q0;
创建一个实验对象来存储充电实验数据。将测量的电流输入和测量的电压输出数据添加到对象。
Charge_Exp = sdo。实验(“斯多巴特里”);Charge_Exp。InputData = timeseries (Charge_Data (:, 2), Charge_Data (: 1));VoltageSig。Values = timeseries(Charge_Data(:,3),Charge_Data(:,1)); Charge_Exp.OutputData = VoltageSig;
实验中加入电池初始充电和充电损耗率参数。在本实验中,初始电荷(Q0
)是已知的(0ah),但充电损耗率(损失
)不知道。
Q0.Value=0;Loss=sdo.getParameterFromModel(“斯多巴特里”,“损失”);的损失。免费的=true; Loss.Minimum = 0; Loss.Maximum = 0.5; Charge_Exp.Parameters = [Q0;Loss];
的损失。免费的
的值设置为true,以便损失
估计。
将两个实验收集到一个向量中。
经验= [DCharge_Exp;Charge_Exp];
使用第一个(放电)实验创建模拟场景,并获得模拟输出。
模拟器= createSimulator (Exp (1));模拟器= sim(模拟器);
在记录的仿真数据中查找电压信号。
SimLog =找到(模拟器。LoggedData get_param (“斯多巴特里”,“SignalLoggingName”));电压(1)=找到(SimLog“电压”);
获得第二次(充电)实验的模拟电压信号。
模拟器= createSimulator (Exp(2),模拟器);模拟器= sim(模拟器);SimLog =找到(模拟器。LoggedData get_param (“斯多巴特里”,“SignalLoggingName”));电压(2)=找到(SimLog,“电压”);
绘制测量和模拟数据。模型响应与实验输出数据不匹配。
子地块(211)地块(...电压(1).Values.Time / 3600、电压(1).Values.Data,...实验(1).OutputData.Values。时间/ 3600、Exp (1) .OutputData.Values.Data“-”。)头衔(“放电实验:估算前的模拟和测量响应”)伊拉贝尔(‘电压(V)’)传说(模拟电压的,测量电压的,“位置”,“西南”)
次要情节(212)图(...电压(2).Values.Time / 3600、电压(2).Values.Data,...Exp(2).OutputData.Values.Time/3600,Exp(2).OutputData.Values.Data,“-”。)头衔(“充电实验:在评估前模拟和测量反应”)xlabel(的时间(小时))伊拉贝尔(‘电压(V)’)传说(模拟电压的,测量电压的,“位置”,‘东南’)
估计电池电压值V
,电池极化电阻K
,充电损耗率损失
这个V
和K
利用所有的实验数据进行参数估计损失
参数仅使用充电数据进行估计。
选择电池电压V
和电池的极化电阻K
模型的参数。为这些参数指定最小和最大界限。
p = sdo.getParameterFromModel (“斯多巴特里”,{“V”,“K”});(1页)。最小值= 0;(1页)。最大= 2;(2页)。最小值= 1 e-6;(2页)。最大= 1 e 1;
让实验具体化损失
参数来自实验。
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参数。连续
创建一个估计目标函数,以评估使用估计参数值生成的模拟输出与测量数据的匹配程度。
使用带有一个输入参数的匿名函数来调用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
函数VAL=sdoBattery_目标(v,模拟器,Exp)%sdoBattery_目标%%sdoBattery_目标函数用于将模型%输出与实验数据进行比较VAL=sdoBattery_Objective(v,Exp)%%输入参数是估计模型参数值%和初始状态的向量。%%|Simulator |输入参数是一个模拟对象,用于%使用估计的参数值模拟模型。%%|Exp |输入参数包含估算实验数据。%%|vals | return参数包含有关%模型模拟结果与实验数据匹配程度的信息,并由| sdo.optimize |函数%用于估计模型参数%%另请参见sdo.optimize,sdoExampleCostFunction%%版权所有2012-2015 MathWorks,Inc.%%定义信号跟踪要求,以计算模型输出%与实验数据的匹配程度。配置跟踪要求,以便%返回跟踪误差残差(而不是%平方和误差),并且不规范化误差r=sdo.requirements.SignalTracking;r、 类型='='=';r、 方法=‘残差’;r、 规格化='off';%%%使用估计的参数值更新实验。%Exp=设置估计值(Exp,v);%%模拟模型并将模型输出与测量的实验%数据进行比较错误=[];对于ct=1:numel(Exp)模拟器=createSimulator(Exp(ct),模拟器);模拟器=sim(模拟器);SimLog=find(Simulator.LoggedData,get_param('sdoBattery','SignalLoggingName');电压=查找(SimLog,'Voltage');电压误差=评估要求(r,电压值,经验(ct).输出数据(1).值);错误=[错误;电压错误(:)];结束%%%将剩余错误返回给优化解算器。%vals.F=错误(:);结束
使用sdo.optimize
功能来估计电池参数值。
指定优化选项。估计函数sdoBattery_Objective
返回模拟数据和实验数据之间的误差残差,并且不包含任何约束条件,使这个问题成为“lsqnonlin”求解器的理想问题。
选择= sdo.OptimizeOptions;opt.Method =“lsqnonlin”;
估计的参数。
vOpt = sdo.optimize (estFcn, v,选择)
优化开始于2021年2月23日19:26:38一阶Iter F计数F(x)步长优化0 7 3272.22 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局部最小可能值。lsqnonlin停止,因为平方和相对于其初始值的最终变化小于函数公差值。vOpt(1,1)=名称:“V”值:1.3083最小值:0最大值:2自由值:1比例:2信息:[1x1结构]vOpt(2,1)=名称:“K”值:0.0010最小值:1.0000e-06最大值:0.1000自由值:1比例:0.0020信息:[1x1结构]vOpt(3,1)=名称:“损失”值:5.1801e-05最小值:0最大值:0.5000自由值:1比例:0.0156信息:[1x1结构]3x1参数连续
使用估计的参数值更新实验。
Exp=设置的估计值(Exp,vOpt);
获得第一次(放电)实验的模拟输出。
模拟器= createSimulator (Exp(1)模拟器);模拟器= sim(模拟器);SimLog =找到(模拟器。LoggedData get_param (“斯多巴特里”,“SignalLoggingName”));电压(1)=找到(SimLog“电压”);
获得第二次(充电)实验的模拟输出。
模拟器= createSimulator (Exp(2),模拟器);模拟器= sim(模拟器);SimLog =找到(模拟器。LoggedData get_param (“斯多巴特里”,“SignalLoggingName”));电压(2)=找到(SimLog,“电压”);
绘制测量和模拟数据。仿真结果与实验数据吻合较好,除了在电池充满电的区域。这是意料之中的,因为简单的电池模型没有模型的指数电压下降时,电池完全充电。
子地块(211)地块(...电压(1).Values.Time / 3600、电压(1).Values.Data,...实验(1).OutputData.Values。时间/ 3600、Exp (1) .OutputData.Values.Data“-”。)头衔(放电实验:估计后的模拟和测量响应)伊拉贝尔(‘电压(V)’)传说(模拟电压的,测量电压的,“位置”,“西南”情节)次要情节(212)(...电压(2).Values.Time / 3600、电压(2).Values.Data,...Exp(2).OutputData.Values.Time/3600,Exp(2).OutputData.Values.Data,“-”。)头衔(“充电实验:估算后的模拟和测量响应”)xlabel(的时间(小时))伊拉贝尔(‘电压(V)’)传说(模拟电压的,测量电压的,“位置”,‘东南’)
更新模型V
,K
,及损失
参数值。
sdo.setValueInModel(“斯多巴特里”, vOpt);
学习如何估计电池参数使用参数估计量,请参阅每次实验估计模型参数(GUI).
关闭模型
bdclose (“斯多巴特里”)