Create Tunable Calibration Parameter in the Generated Code
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.
Represent Block Parameter as Tunable Global Variable
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 InlineBlockParameters
and configure it to show the generated names of blocks.
load_system('InlineBlockParameters') set_param('InlineBlockParameters','HideAutomaticNames','off') open_system('InlineBlockParameters')
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('InlineBlockParameters/G1','Gain','myGainParam') mws = get_param('InlineBlockParameters', 'modelworkspace'); mws.assignin('myGainParam',Simulink.Parameter(2)); cm = coder.mapping.utils.create('InlineBlockParameters'); 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('InlineBlockParameters/G2','Gain','myOtherGain') mws.assignin('myOtherGain',Simulink.Parameter(-2)); setModelParameter(cm,'myOtherGain','StorageClass','ExportedGlobal');
Generate and Inspect Code
Generate code from the model.
slbuild('InlineBlockParameters')
### Starting build procedure for: InlineBlockParameters ### Successful completion of build procedure for: InlineBlockParameters Build Summary Top model targets: Model Build Reason Status Build Duration ======================================================================================================================== InlineBlockParameters Information cache folder or artifacts were missing. Code generated and compiled. 0h 0m 17.262s 1 of 1 models built (0 models already up to date) Build duration: 0h 0m 19.391s
The generated file InlineBlockParameters.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('InlineBlockParameters_grt_rtw','InlineBlockParameters.h'); coder.example.extractLines(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 InlineBlockParameters.c
allocates memory for and initializes myGainParam
and myOtherGain
.
file = fullfile('InlineBlockParameters_grt_rtw','InlineBlockParameters.c'); coder.example.extractLines(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.
coder.example.extractLines(file,... '/* Model step function */','/* Model initialize function */',1,0)
/* Model step function */ void InlineBlockParameters_step(void) { /* Outport: '<Root>/Out1' incorporates: * Gain: '<Root>/G1' * Gain: '<Root>/G2' * Inport: '<Root>/In1' * Sum: '<Root>/Sum' */ InlineBlockParameters_Y.Out1 = myGainParam * InlineBlockParameters_U.In1 + myOtherGain * -75.0; }
Apply Storage Class When Block Parameter Refers to Numeric MATLAB Variable
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, selectConvert 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.
Create Storage Class That Represents Calibration Parameters (Embedded Coder)
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.
Create Package for Storing Storage Class and Memory Section Definitions
Create a package in your current folder. Add definitions of a new storage class and an associated memory section to the package. Then, apply the storage class to data objects in models.
Open the example containing the package MATLAB® namespace folder
+myPackage
. The package stores definitions ofParameter
andSignal
classes.openExample('ecoder/ExploreExampleModelCustomStorageClassesExample')
Navigate inside the namespace folder
+myPackage
to the fileSignal.m
.Open
Signal.m
and uncomment themethods
section that defines methodsetupCoderInfo
. In the call to the functionuseLocalCustomStorageClasses
, replace'packageName'
with'myPackage'
.methods function setupCoderInfo(h) % Use custom storage classes from this package useLocalCustomStorageClasses(h, 'myPackage'); end end % methods
Save and close the file.
Open the file
Parameter.m
and make the same changes that you made in the fileSignal.m
.Save and close the file.
Create Storage Class and Memory Section
Set your current folder to the folder that contains the package namespace 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 to the values listed in this 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 to the values listed in this 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.
Set Default Parameter Object to 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.
Apply Storage Class
In the example model RollAxisAutopilot
, the
BasicRollMode
subsystem represents a PID controller. Configure the
P
, I
, and D
parameters as
calibration parameters.
Open the model.
openExample('RollAxisAutopilot');
In the model, navigate into the
BasicRollMode
subsystem.Open the Embedded Coder app.
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
.
Generate and Inspect Code
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
RollAxisAutopilot.a2l
. The file contains information about each parameter, for example, fordispGain
./begin CHARACTERISTIC /* Name */ dispGain /* Long Identifier */ "" /* Type */ VALUE /* ECU Address */ 0x0000 /* @ECU_Address@dispGain@ */ /* Record Layout */ Scalar_FLOAT32_IEEE /* Maximum Difference */ 0 /* Conversion Method */ RollAxisAutopilot_CM_single /* Lower Limit */ -3.4E+38 /* Upper Limit */ 3.4E+38 /end CHARACTERISTIC
Initialize Parameter Value From System Constant or Other Macro (Embedded Coder)
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 expressionnumVessels * vesInitVol
. To specify that the generated code preserve the expression, use theslexpr
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.
Code Generation Impact of Storage Location for Parameter Objects
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 (Embedded Coder).
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 (Embedded Coder).
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 (Embedded Coder).
If you store an AUTOSAR.Parameter
object in a model workspace, the code
generator ignores the storage class that you specify for the object.
Configure Accessibility of Signal Data
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.
Programmatic Interfaces for Tuning Parameters
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 Write External Code to Access Generated C API Code.
A Target Language Compiler API for tuning parameters independently of external mode. See Parameter Functions.
Set Tunable Parameter Minimum and Maximum Values
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.
Considerations for Other Modeling Goals
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 (Embedded Coder). |
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 Lookup Tables and Configure Lookup Tables for AUTOSAR Calibration and Measurement (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 (Embedded Coder). |
See Also
Simulink.Parameter
| Simulink.LookupTable
| Simulink.Breakpoint
Related Topics
- Exchange Data Between External C/C++ Code and Simulink Model or Generated Code
- Reuse Parameter Data in Different Data Type Contexts
- Limitations for Block Parameter Tunability in Generated Code
- How Generated Code Stores Internal Signal, State, and Parameter Data
- C Data Code Interface Configuration for Model Interface Elements
- Access Structured Data Through a Pointer That External Code Defines (Embedded Coder)
- Configure Lookup Tables for AUTOSAR Calibration and Measurement (AUTOSAR Blockset)