Documentation

## Estimate Model Parameters with Parameter Constraints (Code)

This example shows how to estimate model parameters while imposing constraints on the parameter values.

You estimate dynamic and static friction coefficients of a simple friction system.

### Open the Model and Get Experimental Data

This example estimates parameters for a simple friction system, `sdoFriction`. The model input is the force applied to a mass and the model outputs are the mass position and velocity.

```open_system('sdoFriction'); ``` The model is based on a mass sliding on a surface. The mass is subject to a static friction that must be overcome before the mass moves and a dynamic friction once the mass moves. The static friction, `u_static`, is a fraction of the mass normal force; similarly the dynamic friction, `u_dynamic`, is a fraction of the mass normal force.

Load the experiment data. The mass was subjected to an applied force and its position recorded.

```load sdoFriction_ExperimentData ```

The variables `AppliedForce`, `Position`, and `Velocity` are loaded into the workspace. The first column of each of these variables represents time and the second column represents the measured data. Because velocity is the first derivative of position, we only use the position measurements for this example.

### Plot the Experiment Data

```subplot(211), plot(AppliedForce(:,1),AppliedForce(:,2)) title('Measured Applied Force Input for Simple Friction System'); ylabel('Applied Force (N)') subplot(212) plot(Position(:,1),Position(:,2)) title('Measured Mass Position for Simple Friction System'); xlabel('Time (seconds)') ylabel('Position (m)') ``` ### Define the Estimation Experiment

Create an experiment object to specify the experiment data.

```Exp = sdo.Experiment('sdoFriction'); ```

Specify the input data (applied force) as a timeseries object.

```Exp.InputData = timeseries(AppliedForce(:,2),AppliedForce(:,1)); ```

Create an object to specify the measured mass position output.

```PositionSig = Simulink.SimulationData.Signal; PositionSig.Name = 'Position'; PositionSig.BlockPath = 'sdoFriction/x'; PositionSig.PortType = 'outport'; PositionSig.PortIndex = 1; PositionSig.Values = timeseries(Position(:,2),Position(:,1)); ```

Add the measured mass position data to the experiment as the expected output data.

```Exp.OutputData = PositionSig; ```

### Compare the Measured Output and the Initial Simulated Output

Create a simulation scenario using the experiment and obtain the simulated output.

```Simulator = createSimulator(Exp); Simulator = sim(Simulator); ```

Search for the position signal in the logged simulation data.

```SimLog = find(Simulator.LoggedData,get_param('sdoFriction','SignalLoggingName')); Position = find(SimLog,'Position'); ```

Plot the measured and simulated data.

As expected, the model response does not match the experimental output data.

```figure plot(... Position.Values.Time,Position.Values.Data, ... Exp.OutputData.Values.Time, Exp.OutputData.Values.Data,'-.') title('Simulated and Measured Responses Before Estimation') ylabel('Position (m)') xlabel('Time (seconds)') legend('Simulated Position','Measured Position','Location','NorthWest') ``` ### Specify Parameters to Estimate

Estimate the `u_static` and `u_dynamic` friction coefficients using the experiment data. These coefficients are used as gains in the `Static Friction` and `Dynamic Friction` blocks, respectively. Physics indicates that friction coefficients should be constrained so that `u_static` `u_dynamic`; this parameter constraint is implemented in the estimation objective function.

Select the `u_static` and `u_dynamic` model parameters. Specify bounds for the estimated parameter values. Both coefficients are limited to the range [0 1].

```p = sdo.getParameterFromModel('sdoFriction',{'u_static','u_dynamic'}); p(1).Minimum = 0; p(1).Maximum = 1; p(2).Minimum = 0; p(2).Maximum = 1; ```

### Define the Estimation Objective

Create an estimation objective function to evaluate how closely the simulation output, generated using the estimated parameter values, matches the measured data.

Use an anonymous function with one input argument that calls the `sdoFriction_Objective` function. We pass the anonymous function to `sdo.optimize`, which evaluates the function at each optimization iteration.

```estFcn = @(v) sdoFriction_Objective(v,Simulator,Exp); ```

The `sdoFriction_Objective` function:

• Has one input argument that specifies the estimated friction coefficients.

• Has one input argument that specifies the experiment object containing the measured data.

• Returns the sum-squared-error errors between simulated and experimental outputs, and returns the parameter constraint.

The `sdoFriction_Objective` function requires two inputs, but `sdo.optimize` requires a function with one input argument. To work around this, `estFcn` is an anonymous function with one input argument, `v`, but it calls `sdoFriction_Objective` using two input arguments, `v` and `Exp`.

For more information regarding anonymous functions, see "Anonymous Functions".

The `sdo.optimize` command minimizes the return argument of the anonymous function `estFcn`, that is, the residual errors returned by `sdoFriction_Objective`. For more details on how to write an objective/constraint function to use with the `sdo.optimize` command, type `help sdoExampleCostFunction` at the MATLAB command prompt.

To examine the estimation objective function in more detail, type `edit sdoFriction_Objective` at the MATLAB command prompt.

```type sdoFriction_Objective ```
```function vals = sdoFriction_Objective(p,Simulator,Exp) %SDOFRICTION_OBJECTIVE % % The sdoFriction_Objective function is used to compare model % outputs against experimental data and measure how well constraints are % satisfied. % % vals = sdoFriction_Objective(p,Exp) % % The |p| input argument is a vector of estimated model parameter values. % % 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 how well % constraints are satisfied. The |vals| argument is used by the % |sdo.optimize| function to estimate the model parameters. % % See also sdo.optimize, sdoExampleCostFunction, sdoFriction_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 sum-squared-error. % r = sdo.requirements.SignalTracking; r.Type = '=='; r.Method = 'SSE'; %% % Update the experiments with the estimated parameter values. % Exp = setEstimatedValues(Exp,p); %% % Simulate the model and compare model outputs with measured experiment % data. % Simulator = createSimulator(Exp,Simulator); Simulator = sim(Simulator); SimLog = find(Simulator.LoggedData,get_param('sdoFriction','SignalLoggingName')); Position = find(SimLog,'Position'); PositionError = evalRequirement(r,Position.Values,Exp.OutputData(1).Values); %% % Measure how well the parameters satisfy the friction coefficient constraint, % |u_static| >= |u_dynamic|. Note that constraints are returned to the % optimizer in a c <=0 format. The friction coefficient constraint is % rewritten accordingly. PConstr = p(2).Value - p(1).Value; % u_dynamic - u_static <= 0 %% % Return the sum-squared-error and constraint violation to the optimization % solver. % vals.F = PositionError(:); vals.Cleq = PConstr; end ```

The friction coefficient constraint, `u_static` `u_dynamic`, is implemented in the `sdoFriction_Objective` function as `u_dynamic` - `u_static` 0. This is because the optimizer requires constraint values in a format. For more information, type `help sdo.optimize` at the MATLAB command prompt.

### Estimate the Parameters

Use the `sdo.optimize` function to estimate the friction model parameter values.

Specify the optimization options. The estimation function `sdoFriction_Objective` returns the sum-squared-error between simulated and experimental data and includes a parameter constraint. The default 'fmincon' solver is ideal for this type of problem.

Estimate the parameters.

```pOpt = sdo.optimize(estFcn,p) ```
``` Optimization started 26-Aug-2019 12:46:50 max First-order Iter F-count f(x) constraint Step-size optimality 0 5 27.7267 0 1 11 22.5643 0 2.21 72.9 2 15 17.4771 0 0.51 16 3 22 0.76336 0 1.33 10.7 4 29 0.412423 0 0.263 3.15 5 34 0.0247882 0 0.09 1.19 6 39 0.0052024 0 0.0293 0.251 7 44 0.00387348 0 0.0209 0.225 8 49 0.00171504 0 0.11 0.201 9 58 0.00160758 0 0.0356 0.205 10 69 0.00153466 0 0.0294 0.192 11 86 0.00153466 0 0.00162 0.192 Local minimum possible. Constraints satisfied. fmincon stopped because the size of the current step is less than the value of the step size tolerance and constraints are satisfied to within the value of the constraint tolerance. pOpt(1,1) = Name: 'u_static' Value: 0.7912 Minimum: 0 Maximum: 1 Free: 1 Scale: 0.5000 Info: [1x1 struct] pOpt(2,1) = Name: 'u_dynamic' Value: 0.4035 Minimum: 0 Maximum: 1 Free: 1 Scale: 0.2500 Info: [1x1 struct] 2x1 param.Continuous ```

### Compare the Measured Output and the Final Simulated Output

Update the experiments with the estimated parameter values.

```Exp = setEstimatedValues(Exp,pOpt); ```

Obtain the simulated output for the experiment.

```Simulator = createSimulator(Exp,Simulator); Simulator = sim(Simulator); SimLog = find(Simulator.LoggedData,get_param('sdoFriction','SignalLoggingName')); Position = find(SimLog,'Position'); ```

Plot the measured and simulated data.

It can be seen that the model response using the estimated parameter values nicely matches the experiment output data.

```plot(... Position.Values.Time,Position.Values.Data, ... Exp.OutputData.Values.Time, Exp.OutputData.Values.Data,'-.') title('Simulated and Measured Responses After Model Parameter Estimation') ylabel('Position (m)') xlabel('Time (seconds)') legend('Simulated Position','Measured Position','Location','NorthWest') ``` ### Update the Model Parameter Values

Update the model `u_static` and `u_dynamic` parameter values.

```sdo.setValueInModel('sdoFriction',pOpt); ```

Close the model

```bdclose('sdoFriction') ```
##### Support Get trial now