A calibration parameter is a value stored in global memory that an algorithm reads for use in calculations but does not write to. Calibration parameters are tunable because you can change the stored value during algorithm execution. You create calibration parameters so that you can:
Determine an optimal parameter value by tuning the parameter and monitoring signal values during execution.
Efficiently adapt an algorithm to different execution conditions by overwriting the parameter value stored in memory. For example, you can use the same control algorithm for multiple vehicles of different masses by storing different parameter values in each vehicle’s engine control unit.
In Simulink®, create a Simulink.Parameter
object to represent a calibration
parameter. You use the parameter object to set block parameter values, such as the
Gain parameter of a Gain block. To control the
representation of the parameter object in the generated code, you apply a storage class to the
object.
To make block parameters accessible in the generated code by default, for example for
rapid prototyping, set Default parameter behavior (see Default parameter behavior) to
Tunable
. For more information, see Preserve Variables in Generated Code.
This example shows how to create tunable parameter data by representing block parameters as global variables in the generated code.
Configure Block Parameter by Using Parameter Object
Open the example model rtwdemo_paraminline
and configure it to show the generated names of blocks.
load_system('rtwdemo_paraminline') set_param('rtwdemo_paraminline','HideAutomaticNames','off') open_system('rtwdemo_paraminline')
On the Modeling tab, click Model Data Editor.
In the Model Data Editor, inspect the Parameters tab.
In the model, click the G1
Gain block. The Model Data Editor highlights the row that corresponds to the Gain parameter of the block.
In the Model Data Editor Value column, change the gain value from 2
to myGainParam
.
Next to myGainParam
, click the action button (with three vertical dots) and select Create.
In the Create New Data block dialog box, set Value to Simulink.Parameter(2)
. Click Create. A Simulink.Parameter
object myGainParam
stores the parameter value, 2
, in the model workspace.
In the myGainParam dialog box, on the Code Generation tab, click Configure in Coder App.
In the Code Mappings editor, set Storage Class of myGainParam
to ExportedGlobal
. This storage class causes the parameter object to appear in the generated code as a tunable global variable.
Alternatively, to create the parameter object and configure the model, use these commands at the command prompt:
set_param('rtwdemo_paraminline/G1','Gain','myGainParam') mws = get_param('rtwdemo_paraminline', 'modelworkspace'); mws.assignin('myGainParam',Simulink.Parameter(2)); cm = coder.mapping.utils.create('rtwdemo_paraminline'); setModelParameter(cm,'myGainParam','StorageClass','ExportedGlobal');
Use the Model Data Editor to create a parameter object, myOtherGain
, for the G2
Gain block. Apply the storage class ExportedGlobal
.
Alternatively, use these commands at the command prompt:
set_param('rtwdemo_paraminline/G2','Gain','myOtherGain') mws.assignin('myOtherGain',Simulink.Parameter(-2)); setModelParameter(cm,'myOtherGain','StorageClass','ExportedGlobal');
Generate and Inspect Code
Generate code from the model.
rtwbuild('rtwdemo_paraminline')
### Starting build procedure for: rtwdemo_paraminline ### Generated code for 'rtwdemo_paraminline' is up to date because no structural, parameter or code replacement library changes were found. ### Successful completion of build procedure for: rtwdemo_paraminline Build Summary 0 of 1 models built (1 models already up to date) Build duration: 0h 0m 3.222s
The generated file rtwdemo_paraminline.h
contains extern
declarations of the global variables myGainParam
and myOtherGain
. You can include (#include
) this header file so that your code can read and write the value of the variable during execution.
file = fullfile('rtwdemo_paraminline_grt_rtw','rtwdemo_paraminline.h'); rtwdemodbtype(file,... 'extern real_T myGainParam;','Referenced by: ''<Root>/G2''',1,1)
extern real_T myGainParam; /* Variable: myGainParam * Referenced by: '<Root>/G1' */ extern real_T myOtherGain; /* Variable: myOtherGain * Referenced by: '<Root>/G2'
The file rtwdemo_paraminline.c
allocates memory for and initializes myGainParam
and myOtherGain
.
file = fullfile('rtwdemo_paraminline_grt_rtw','rtwdemo_paraminline.c'); rtwdemodbtype(file,... '/* Exported block parameters */','Referenced by: ''<Root>/G2''',1,1)
/* Exported block parameters */ real_T myGainParam = 2.0; /* Variable: myGainParam * Referenced by: '<Root>/G1' */ real_T myOtherGain = -2.0; /* Variable: myOtherGain * Referenced by: '<Root>/G2'
The generated code algorithm in the model step
function uses myGainParam
and myOtherGain
for calculations.
rtwdemodbtype(file,... '/* Model step function */','/* Model initialize function */',1,0)
/* Model step function */ void rtwdemo_paraminline_step(void) { /* Outport: '<Root>/Out1' incorporates: * Gain: '<Root>/G1' * Gain: '<Root>/G2' * Inport: '<Root>/In1' * Sum: '<Root>/Sum' */ rtwdemo_paraminline_Y.Out1 = myGainParam * rtwdemo_paraminline_U.In1 + myOtherGain * -75.0; }
If you use a numeric variable to set the value of a block parameter, you cannot apply a storage class to the variable. As a workaround, you can convert the variable to a parameter object, and then apply a storage class to the object. To convert the variable to a parameter object, choose one of these techniques:
On the Model Data Editor Parameters tab, with
Change view set to Code
, find the
row that corresponds to the variable. In the Storage Class
column, from the drop-down list, select Convert to parameter
object
. The Model Data Editor converts the variable to a parameter
object. Then, use the Storage Class column to apply a storage
class to the object.
You can also use this technique in the Model Explorer.
Use the Data Object Wizard (see Create Data Objects for a Model Using Data Object Wizard). In the Wizard, select the Parameters check box. The Wizard converts variables to objects. Then, apply storage classes to the objects, for example, by using the Model Data Editor or the Model Explorer.
This example shows how to create a storage class that yields a calibration parameter in
the generated code. The storage class causes each parameter object
(Simulink.Parameter
) to appear as a global variable with special
decorations such as keywords and pragmas.
In the generated code, the calibration parameters must appear as global variables
defined in a file named calPrms.c
and declared in
calPrms.h
. The variable definitions must look like these
definitions:
#pragma SEC(CALPRM) const volatile float param1 = 3.0F; const volatile float param2 = 5.0F; const volatile float param3 = 7.0F; #pragma SEC()
The variables use the keywords const
and volatile
.
The pragma #pragma SEC(CALPRM)
controls the placement of the variables in
memory. To implement the pragma, variable definitions must appear in a contiguous block of
code.
Also, the generated code must include an ASAP2 (a2l
) description of
each parameter.
Now, create a package in your current folder by copying the example package
+SimulinkDemos
. The package stores the definitions of
Parameter
and Signal
classes that you later use to
apply the storage class to data elements in models. Later, the package also stores the
definitions of the storage class and an associated memory section.
Set your current MATLAB® folder to a writable location.
Copy the +SimulinkDemos
package folder into your current
folder. Name the copy +myPackage
.
copyfile(fullfile(matlabroot,... 'toolbox','simulink','simdemos','dataclasses','+SimulinkDemos'),... '+myPackage','f')
Navigate inside the +myPackage
folder to the file
Signal.m
to edit the definition of the
Signal
class.
Uncomment the methods
section that defines the method
setupCoderInfo
. In the call to the function
useLocalCustomStorageClasses
, replace
'packageName'
with 'myPackage'
. When you
finish, the section looks like this:
methods function setupCoderInfo(h) % Use custom storage classes from this package useLocalCustomStorageClasses(h, 'myPackage'); end end % methods
Save and close the file.
Navigate inside the +myPackage
folder to the file
Parameter.m
to edit the definition of the
Parameter
class. Uncomment the methods
section that defines the method setupCoderInfo
and replace
'packageName'
with 'myPackage'
.
Save and close the file.
Set your current folder to the folder that contains the package folder
+myPackage
.
Open the Custom Storage Class Designer.
cscdesigner('myPackage')
In the Custom Storage Class Designer, on the Memory Sections tab, click New.
For the new memory section, set properties according to the table.
Property | Value |
---|---|
Name | CalMem |
Statements Surround | Group of variables |
Pre Statement | #pragma SEC(CALPRM) |
Post Statement | #pragma SEC() |
Is const | Select |
Is volatile | Select |
Click Apply.
On the Custom Storage Class tab, click New.
For the new storage class, set properties according to the table.
Property | Value |
---|---|
Name | CalParam |
For signals | Clear |
Data scope | Exported |
Header File | calPrms.h |
Definition File | calPrms.c |
Memory Section | CalMem |
Click OK. In response to the message about saving changes, click Yes.
myPackage.Parameter
To make applying the storage class easier, use the Model Explorer to change the
default parameter object from Simulink.Parameter
to
myPackage.Parameter
.
At the command prompt, open the Model Explorer.
daexplr
In the Model Explorer Model Hierarchy pane, select Base Workspace.
In the Model Explorer toolbar, click the arrow next to the Add Simulink Parameter button. In the drop-down list, select Customize class lists.
In the Customize class lists dialog box, under Parameter classes, select the check box next to myPackage.Parameter. Click OK.
In the Model Explorer toolbar, click the arrow next to the Add Simulink Parameter button. In the drop-down list, select myPackage Parameter.
A myPackage.Parameter
object appears in the base workspace. You
can delete this object.
Now, when you use tools such as the Model Data Editor to create parameter objects,
Simulink creates myPackage.Parameter
objects instead of
Simulink.Parameter
objects.
In the example model rtwdemo_roll
, the
BasicRollMode
subsystem represents a PID controller. Configure the P,
I, and D parameters as calibration parameters.
Open the model.
rtwdemo_roll
In the model, navigate into the BasicRollMode
subsystem.
In the Apps gallery, click Embedded Coder.
Underneath the block diagram, open the Model Data Editor by selecting the Model Data Editor tab.
In the Model Data Editor, select the Parameters tab and update the block diagram.
Now, the data table contains rows that correspond to workspace variables used by the Gain blocks (which represent the P, I, and D parameters of the controller).
In the Model Data Editor, next to the Filter contents box, activate the Filter using selection button.
In the model, select the three Gain blocks.
In the Filter contents box, enter model
workspace
.
The variables that the Gain blocks use are in the model workspace.
In the data table, select the three rows and, in the Storage
Class column for a row, select Convert to parameter
object
.
The Model Data Editor converts the workspace variables to
myPackage.Parameter
objects. Now, you can apply a storage class
to the objects.
In the Storage Class column for a row, select
CalParam
.
Configure the model to generate a2l
files. Select Configuration Parameters > Code Generation > Interface > ASAP2 interface.
Generate code from the model.
In the code generation report, inspect the calPrms.c
file.
The file defines the calibration parameters.
/* Exported data definition */ #pragma SEC(CALPRM) /* Definition for custom storage class: CalParam */ const volatile real32_T dispGain = 0.75F; const volatile real32_T intGain = 0.5F; const volatile real32_T rateGain = 2.0F; #pragma SEC()
The file calPrms.h
declares the parameters.
Inspect the interface file rtwdemo_roll.a2l
. The file
contains information about each parameter, for example, for
dispGain
.
/begin CHARACTERISTIC /* Name */ dispGain /* Long Identifier */ "" /* Type */ VALUE /* ECU Address */ 0x0000 /* @ECU_Address@dispGain@ */ /* Record Layout */ Scalar_FLOAT32_IEEE /* Maximum Difference */ 0 /* Conversion Method */ rtwdemo_roll_CM_single /* Lower Limit */ -3.4E+38 /* Upper Limit */ 3.4E+38 /end CHARACTERISTIC
You can generate code that initializes a tunable parameter with a value calculated from
some system constants (macros). For example, you can generate this code, which initializes a
tunable parameter totalVol
with a value calculated from macros
numVessels
and vesInitVol
:
#define numVessels 16 #define vesInitVol 18.2 double totalVol = numVessels * vesInitVol;
This initialization technique preserves the mathematical relationship between the tunable parameter and the system constants, which can make the generated code more readable and easier to maintain. To generate this code:
Create parameter objects that represent the system constants.
numVessels = Simulink.Parameter(16); vesInitVol = Simulink.Parameter(18.2);
Configure the objects to use the storage class Define
, which
yields a macro in the generated code.
numVessels.CoderInfo.StorageClass = 'Custom'; numVessels.CoderInfo.CustomStorageClass = 'Define'; vesInitVol.CoderInfo.StorageClass = 'Custom'; vesInitVol.CoderInfo.CustomStorageClass = 'Define';
Create another parameter object that represents the tunable parameter. Configure
the object to use the storage class ExportedGlobal
, which yields a
global variable in the generated code.
totalVol = Simulink.Parameter;
totalVol.CoderInfo.StorageClass = 'ExportedGlobal';
Set the value of totalVol
by using the expression
numVessels * vesInitVol
. To specify that the generated code
preserve the expression, use the slexpr
function.
totalVol.Value = slexpr('numVessels * vesInitVol');
Use totalVol
to set block parameter values in your model. The
code that you generate from the model initializes the tunable parameter with a value
based on the system constants.
For more information and limitations about using an expression to set the value of a
Simulink.Parameter
object, see Set Variable Value by Using a Mathematical Expression.
You can create a parameter object in the base workspace, a model workspace, or a data dictionary. However, when you end your MATLAB session, variables in the base workspace are deleted. To determine where to store parameter objects and other variables that a model uses, see Determine Where to Store Variables and Objects for Simulink Models.
The location of a parameter object can impact the file placement of the corresponding data definition in the generated code.
If you place a parameter object in the base workspace or a data dictionary, the
code generator assumes that the corresponding parameter data (for example, a global
variable) belongs to the system from which you generate code, not to a specific
component in the system. For example, if a model in a model reference hierarchy uses a
parameter object with a storage class other than Auto
, the data
definition appears in the code generated for the top model in the hierarchy, not in
the code generated for the model that uses the object.
However, if you have Embedded Coder®, some storage classes enable you to specify the name of the model that owns a piece of data. When you specify an owner model, the code generated for that model defines the data. For more information about data ownership, see Control Placement of Global Data Definitions and Declarations in Generated Files.
If you place a parameter object in a model workspace, the code generator assumes that the model owns the data. If you generate code from a reference hierarchy that includes the containing model, the data definition appears in the code generated for the containing model.
For more information about data ownership, see Control Placement of Global Data Definitions and Declarations in Generated Files.
If you apply a storage class other than Auto
to a parameter
object, the object appears in the generated code as a global symbol. Therefore, in a
model reference hierarchy, two such objects in different model workspaces or
dictionaries cannot have the same name. The name of each object must be unique
throughout the model hierarchy.
However, if you have Embedded Coder, you can use the storage class FileScope
to prevent
name clashes between parameter objects in different model workspaces. See Organize Parameter Data into a Structure by Using Struct Storage Class.
If you store an AUTOSAR.Parameter
object in a model workspace, the code
generator ignores the storage class that you specify for the object.
When you tune the value of a parameter during algorithm execution, you monitor or capture output signal values to analyze the results of the tuning. To represent signals in the generated code as accessible data, you can use techniques such as test points and storage classes. See Preserve Variables in Generated Code.
You can configure the generated code to include:
A C application programming interface (API) for tuning parameters independent of external mode. The generated code includes extra code so that you can write your own code to access parameter values. See Exchange Data Between Generated and External Code Using C API.
A Target Language Compiler API for tuning parameters independently of external mode. See Parameter Functions.
It is a best practice to specify minimum and maximum values for tunable parameters.
You can specify these minimum and maximum values:
In the block dialog box that uses the parameter object. Use this technique to store the minimum and maximum information in the model.
By using the properties of a Simulink.Parameter
object that you use to set the parameter value. Use
this technique to store the minimum and maximum information outside the model.
For more information, see Specify Minimum and Maximum Values for Block Parameters.
Goal | Considerations and More Information |
---|---|
Apply storage type qualifiers const and
volatile | If you have Embedded Coder, to generate the storage type qualifiers, see Protect Global Data with const and volatile Type Qualifiers. |
Prevent name clashes between parameters in different components by applying
the keyword static | If you have Embedded Coder, use the storage class |
Generate ASAP2 (a2l ) description |
You can generate an |
Generate AUTOSAR XML (ARXML) description | If you have Embedded Coder, you can generate an ARXML file that describes calibration parameters used by models that you configure for the AUTOSAR standard. See Model AUTOSAR Calibration Parameters and Lookup Tables (AUTOSAR Blockset). |
Store lookup table data for calibration | To store lookup table data for calibration according to the ASAP2 or
AUTOSAR standards (for example, STD_AXIS, COM_AXIS, or CURVE), you can use
However, some limitations apply. See For more information, see Define ASAP2 Information for Parameters and Signals and Configure Lookup Tables for AUTOSAR Measurement and Calibration (AUTOSAR Blockset). |
Use pragmas to store parameter data in specific memory locations | If you have an Embedded Coder license, to generate code that includes custom pragmas, use storage classes and memory sections. See Control Data and Function Placement in Memory by Inserting Pragmas. |
Simulink.Breakpoint
| Simulink.LookupTable
| Simulink.Parameter