Jun 30, 2015

System parameter estimation with Simulink

In previous blog entries, I created custom Simscape components for TEC and forced air heatsink for a thermal control system.  I built an open-loop system model with a current source, and now I want to find reasonable values for the model's parameters using openloop data.  While I've done this exercise many times in the past, I always did it within Matlab itself rather than in Simulink.  In an effort to catch up to the modern Matlab workflow, I will document my new work procedure.

Create input/output ports for the model

I already have my model (creatively called "take1") open, but it is currently missing output signal.  I dragged an out1 port from the Simulink Library Browser --> Simulink --> Sinks, and changed the port property to show port name and number.  Similarly, I dragged an in1 port from the Library Browser and connected to the ideal current source in my model.

Bring the openloop data into Matlab workspace

My data is already in a CSV file in my Matlab folder (~/Documents/MATLAB), so I can easily bring it into the workspace by right clicking on the file in the Current Folder view  --> Import Data... --> Import.  Now my Matlab Workspace is choke-full of column vectors.

I believe the csvread() command would work just as well.  In there, I identify the vectors I want to use for this experiment:
  • input1: TECValue, commanded value to the current generating FW
  • output1: CenterTemp
  • ouput2: I have several thermistor readings, which I should average, like this:

    >> center = mean([Sensor5 Sensor6 Sensor9 Sensor10], 2);
    >> center = center(4215:6000); % Just deal with relevant data

  • output3: HeatsinkTemp
The data was captured at 2 Hz, but the time was not recorded.  So I just make it up with this Matlab command:

>> time = (0 : 0.5 : 0.5*(size(center,1)-1))';

Note the transpose (') operator to keep the time as a column vector, just like the other openloop data columns.  I suppose I could have defined a sampling frequency as a constant, but let's just keep moving for now.

Create an experiment

In the Simulink model window, select Analysis > Parameter Estimation.  This action opens a new session, Parameter Estimation - take1, in the Parameter Estimation tool.  Click "New Experiment" in the toolbar to bring up "Edit Experiment: Exp" wizard--"Exp" is the default name of the experiment.
  • Select all output ports I created in the model, and supply the openloop data
    • output 1: [time, CenterTemp(4215:6000)]
    • output 2: [time, center]
    • output 3: [time, HeatsinkTemp] I ignored the heatsink temperature because it is actively controlled.
  • In the "Inputs" category, select only some of the rows: [time, TECValue(4215:6000)]
  • Select Initial States. Optional?
  • Select parameters: Simulink found all parameters in my model: those that were left in symbolic form.  I checked all of them.  If necessary (usually a good idea), the parameters should be constrained to sensible bounds. when expanded, the parameter tab shows the minimum and maximum bounds.  For almost all physical parameters, the minimum should be some small value.

Clean up data

To view the imported data, click  Add Plot on the Parameter Estimation tab and select the experiment name--"Exp" here.

Since the open loop data covers many different cases, here is a way to restrict the data range: in the "EXPERIMENTAL PLOT" tab, click "Extract Data" button, and specify the "Start/End Time", as shown below:
Then I clicked "Save As", which created another experiment "Exp1".  I renamed Exp1 to "Exp TEC".  In the EXPERIMENT PLOT tab above, there are other ways to clean up the experiment data:
  • Remove outlier, offset
  • Scale, filter data

Estimate parameters

When I click on the "Estimate" button shown below, the GUI runs optimization loop, and adjusts the parameters until the score (sum of the squared error) stops converging.
The EsitmatedParams "Scales Value" shows that my initial guess for one of the parameters was particularly poor.  Going back to the Experiments browser --> Edit --> Parameters, the parameter values at the end of the estimation iteration are shown, and I can just read them off.

Clicking on "Plot Model Response" button above overlays the simulation result against the experimental data.
The fit is not all that great, suggesting that my simple model is missing at least 1 first order dynamics between the TEC and the out1, and maybe the TEC data I have is somewhat off.  Rather than complicate the model further, I let the parameter estimator vary the TEC parameters to obtain a better fit, as shown below:

If I had more openloop data, I could validate the model + parameter against it.

Next step

I have to design a feedback and feed-forward controller for this system.   The feedback controller will be relatively easy, but the feed-forward tends to have lots of heuristics and tuning knobs.