I'm trying use NMinimize to determine the parameters of a model, but I'm having problems using OutputResponse as part of the objective function. The model represents lithium-ion cells used to power an autonomous underwater vehicle. I can measure a real cell's voltage response to changes in output current, and I want to compare that output to the output of my model for a given set of model circuit parameters. If I can minimize the difference between the output of my model and the output of a real cell, then my model will be correct. In general, I'm trying to minimize the difference between two curves.
I use OutputResponse to generate the output of my model. My problem is that OutputResponse can't simulate the response of a system that contains symbolic parameters. But my model parameters have to be symbolic so NMinimize can vary them. Here is my code (sorry for the long posting):
Write the transfer function of the circuit that models the complex impedance of the cell.
tf = (Rser + Rfast/((Rfast s Cfast) + 1) + Rslow/((Rslow s Cslow) + 1));
Convert the tf into a transfer function model.
tfm = TransferFunctionModel[{{tf}}, s];
Generate a battery current profile.
Ibatt = UnitStep[t - 1] - UnitStep[t - 5];
Plot[Ibatt, {t, 0, 10}, Exclusions -> None]
Assign values to the circuit parameters.
vals = {Rser -> 0.1, Rfast -> 0.05, Cfast -> 10, Rslow -> 0.01, Cslow -> 100};
Voc = 4.2;
Find the output response for these circuit values and current profile.
y = OutputResponse[tfm /. vals, Ibatt, {t, 10}];
Plot[Voc - y, {t, 0, 10}]
Define some different circuit values to get a different response and plot both responses.
dvals = {Rser -> 0.06, Rfast -> 0.08, Cfast -> 15, Rslow -> 0.015, Cslow -> 50};
dy = OutputResponse[tfm /. dvals, Ibatt, {t, 10}];
Plot[{Voc - y, Voc - dy}, {t, 0, 10}]
Find the area of the difference between the two responses.
Plot[Abs[y - dy], {t, 0, 10}]
NIntegrate[Abs[y - dy], {t, 0, 10}]
{0.156543}
I now have an objective function and can try modeling. Given only the first response curve as a template, find the circuit values that produced that response as a test of the modeling algorithm. Do this by minimizing the difference between the template and the output of a model whose circuit values are adjusted by NMinimize. In this case I already know the answer, but if it works then I can use measurements of an actual cell as my template.
NMinimize[
NIntegrate[
Abs[
OutputResponse[tfm, Ibatt, {t, 0, 10}] - y
], {t, 0, 10}
], {Rser, Rfast, Cfast, Rslow, Cslow}
]
OutputResponse::symbs: Cannot simulate response of system StateSpaceModel[{{{0,1},{-(1/(Cfast Cslow Rfast Rslow)),-((Cfast Rfast+Cslow Rslow)/(Cfast Cslow Rfast Rslow))}},{{0},{1}},{{-(Rser/(Cfast Cslow Rfast Rslow))+(Rfast+Rser+Rslow)/(Cfast Cslow Rfast Rslow),-((Rser (Cfast Rfast+Cslow Rslow))/(Cfast Cslow Rfast Rslow))+(<<1>>+<<2>>+<<1>>)/<<1>>}},{{Rser}}},<<18>>->None] that contains symbolic parameter(s). >>
As you can see, OutputResponse can't produce an output because it has symbolic parameters.
How do I get NMinimize to set the values of the parameters before OutputResponse uses them? Will NMinimize work at all with this type of objective function?
Thanks for any help,
Paul