Real-Time Workshop | ![]() ![]() |
Before reading this section, you should be familiar with the parameter storage and tuning concepts described in Parameters: Storage, Interfacing, and Tuning.
Overview
Real-Time Workshop provides data structures and a C API that enable a running program to access model parameters without use of external mode. Using the C API, you can
To access model parameters via the C API, you generate a model-specific parameter mapping file, model
_pt.c
. This file contains parameter mapping arrays containing information required for parameter tuning:
rtBlockTuning
array contains information on all the modifiable block parameters in the model by block name and parameter name. Each element of the array is a BlockTuning
struct. Note that if the Inline parameters option is selected, an empty rtBlockTuning
array is generated.
rtVariableTuning
array contains information about all workspace variables that were referenced as block parameters by one or more blocks or Stateflow charts in the model. Each element of the array is a VariableTuning
struct. Note that if the Inline parameters option is not selected, the elements of this array correspond to Stateflow sata of machine scope.
rtParametersMap
array, or map vector, contains the absolute base address of all block or model parameters. The entries of the map are initialized by the function model
_InitializeParametersMap
, which is called during model initialization.
rtDimensionsMap
array, or dimensions map, is a structure that contains the dimensions sizes for parameters having dimensions greater than 2.
Your code should not access the data structures of model
_pt.c
directly. Pointers to these arrays are loaded into a ModelMappingInfo
structure that is cached in the rtModel
data structure. Your code must obtain a pointer to the ModelMappingInfo
structure, using an accessor macro provided for the purpose. Your code can then use the rtBlockTuning
and rtVariableTuning
structures to access model parameters.
Real-Time Workshop provides sample code demonstrating how to use the parameter mapping information. You can use this sample code as a starting point in developing your own parameter tuning code.
The following sections discuss:
model
_pt.c
file
Generating the model.pt File
To generate the model
_pt.c
file, you must set the global TLC variable ParameterTuning
to 1
(by default, ParameterTuning
is disabled.) You can use the following statement in your system target file for this purpose.
Alternatively, you can append the following command to the System target file field on the Target configuration section of the Real-Time Workshop pane.
The the model
_pt.c
file is written to the build directory.
Parameter Map Data Types and Data Structures
The file matlabroot
/rtw/c/src/pt_info.h
defines enumerated data types and data structures used in the parameter map. Please refer to pt_info.h
while reading this discussion.
Enumerated Types. Two enumerations, ParamClass
and ParamSource
, are defined in pt_info.h
.
The ParamClass
enumeration specifies how a parameter is to be updated. The values rt_SCALAR
and rt_VECTOR
represent scalars and column vectors, respectively. The C declarations for these types are
real_T scalarParam; /* correpsponds to rt_SCALAR */ real_T vectorParam[width]; /* correpsponds to rt_VECTOR */
The value rt_MATRIX_ROW_MAJOR
indicates that the parameter is a matrix that is stored in memory in row major ordering. Conceptually, the C declaration for a parameter of this type is
The value rt_MATRIX_COL_MAJOR
specifies that the parameter is a matrix that is stored in memory in column major ordering. Conceptually, the C declaration for a parameter of this type is
The value rt_MATRIX_COL_MAJOR_ND
specifies that the parameter is an N-dimensional matrix. Conceptually, the C declaration for a parameter of this type is
Note that Real-Time Workshop actually declares matrices as vectors in column major order in each case. For example, a 2x3 matrix is represented as follows.
The ParamSource
enumeration specifies the source of the parameter, which may be one of the following:
rt_SL_PARAM
indicates a parameter used by a Simulink block.
rt_SF_PARAM
indicates Stateflow machine data.
rt_SHARED_PARAM
indicates data shared by Simulink and Stateflow.
Map Vector. The map vector (rtParametersMap
) is an array containing the absolute base addresses of all block parameters that are members of rtP
, the global parameter data structure. The code fragment below shows an example map vector. This example was generated from the model shown in Figure 14-1.
ParameterTuning, BlockTuning, and VariableTuning Structures. The ParameterTuning
structure contains the core of information stored in the BlockTuning
and VariableTuning
structures. ParameterTuning
is defined as follows:
typedef struct ParameterTuning_tag { ParamClass paramClass; /* Class of parameter */ int_T nRows; /* Number of rows */ int_T nCols; /* Number of columns */ int_T nDims; /* Number of dimensions */ int_T dimsOffset; /* Offset into dimensions vector */ ParamSource source; /* Source of parameter */ uint_T dataType; /* data type enumeration */ uint_T numInstances; /* Num of parameter instances */ int_T mapOffset; /* Offset into map vector */ } ParameterTuning;
The paramClass and source fields take on one of the enumerated values mentioned in Enumerated Types.
The dataType field is the Simulink data type of the parameter, indicated by an enumerated value such as SS_DOUBLE
.
The mapOffset
field is the offset to the parameter's entry in the map vector. Using mapOffset
, your code can obtain the actual address of the parameter.
The numInstances
field is described in Mapping Parameter Instances in Simulink and Stateflow.
The fields nDims, nRows
and nCols
indicate the number of dimensions, rows and columns in the parameter, respectively.
If the number of dimensions of the parameter is greater than 2, the value dimsOffset
is used to index into the dimensions map. This array contains the dimensions sizes for parameters having dimensions greater than 2. If there are no parameters having more than 2 dimensions, the dimensions map is empty.
The following table summarizes the relationship of the number of dimensions to the dimensions information in the ParameterTuning structure.
The BlockTuning
structure, in addition to the ParameterTuning
information, contains the names of the originating block and parameter.
The VariableTuning
structure, in addition to the ParameterTuning
information, contains the name of the workspace variable.
Inlining Parameters
The Inline parameters option affects the information generated in the rtBlockTuning
and rtVariableTuning
arrays.
If Inline parameters is deselected:
rtBlockTuning
array contains an entry for every modifiable parameter of every block in the model.
rtVariableTuning
array contains only Stateflow data of machine scope (it contains only a null entry in the absence of such data).
If Inline parameters is selected:
rtBlockTuning
array is empty (it contains only a null entry).
rtVariableTuning
array contains an entry for all workspace variables that are referenced as tunable Simulink block parameters or Stateflow data of machine scope.
Example Parameter Maps. In this section, we will examine parameter mapping information generated from a simple model. In the example model, the amplitude and frequency of the Sine Wave block are controlled by the workspace variables amp
and freq
, as shown below.
Figure 14-10: Example Model Referencing Workspace Variables as Parameters
The following code fragment shows the rtBlockTuning
and rtVariableTuning
arrays generated from this model (in model
_pt.c
), as well as the parameter map and the function initializing the map, with Inline parameters off.
/* Tunable block parameters */ static const BlockTuning rtBlockTuning[] = { /* blockName, parameterName, * class, nRows, nCols, nDims, dimsOffset, source, dataType, numInstances, * mapOffset */ /* Sin */ {"simple/Sine Wave", "Amplitude", {rt_SCALAR, 1, 1, 2, -1, rt_SL_PARAM, SS_DOUBLE, 1, 0} }, /* Sin */ {"simple/Sine Wave", "Bias", {rt_SCALAR, 1, 1, 2, -1, rt_SL_PARAM, SS_DOUBLE, 1, 1} }, /* Sin */ {"simple/Sine Wave", "Frequency", {rt_SCALAR, 1, 1, 2, -1, rt_SL_PARAM, SS_DOUBLE, 1, 2} }, /* Sin */ {"simple/Sine Wave", "Phase", {rt_SCALAR, 1, 1, 2, -1, rt_SL_PARAM, SS_DOUBLE, 1, 3} }, /* Gain */ {"simple/Gain", "Gain", {rt_SCALAR, 1, 1, 2, -1, rt_SL_PARAM, SS_DOUBLE, 1, 4} }, {NULL, NULL, {(ParamClass)0, 0, 0, 0, 0, (ParamSource)0, 0, 0, 0} } }; /* Tunable variable parameters */ static const VariableTuning rtVariableTuning[] = { /* variableName, * class, nRows, nCols, nDims, dimsOffset, source, dataType, numInstances, * mapOffset */ {NULL, {(ParamClass)0, 0, 0, 0, 0, (ParamSource)0, 0, 0, 0} } }; static void * rtParametersMap[5]; void simple_InitializeParametersMap(void) { rtParametersMap[0] = &rtP.Sine_Wave_Amp; /* 0 */ rtParametersMap[1] = &rtP.Sine_Wave_Bias; /* 1 */ rtParametersMap[2] = &rtP.Sine_Wave_Freq; /* 2 */ rtParametersMap[3] = &rtP.Sine_Wave_Phase; /* 3 */ rtParametersMap[4] = &rtP.Gain_Gain; /* 4 */ }
The following code fragment shows the rtBlockTuning
and rtVariableTuning
arrays generated (in model
_pt.c
), as well as the parameter map and the function initializing the map, with Inline parameters on. The workspace variables amp
and freq
have been declared tunable with storage class SimulinkGlobal(Auto)
.
/* Individual block tuning is not valid when inline parameters is selected. * * An empty map is produced to provide a consistent interface independent * * of inlining parameters. */ static const BlockTuning rtBlockTuning[] = { /* blockName, parameterName, * class, nRows, nCols, nDims, dimsOffset, source, dataType, numInstances, * mapOffset */ {NULL, NULL, {(ParamClass)0, 0, 0, 0, 0, (ParamSource)0, 0, 0, 0} } }; /* Tunable variable parameters */ static const VariableTuning rtVariableTuning[] = { /* variableName, * class, nRows, nCols, nDims, dimsOffset, source, dataType, numInstances, * mapOffset */ {"amp", {rt_SCALAR, 1, 1, 2, -1, rt_SL_PARAM, SS_DOUBLE, 1, 0} }, {"freq", {rt_SCALAR, 1, 1, 2, -1, rt_SL_PARAM, SS_DOUBLE, 1, 1} }, {NULL, {(ParamClass)0, 0, 0, 0, 0, (ParamSource)0, 0, 0, 0} } }; static void * rtParametersMap[2]; void simple_inline_InitializeParametersMap(void) { rtParametersMap[0] = &rtP.amp; /* 0: amp */ rtParametersMap[1] = &rtP.freq; /* 1: freq */ }
Mapping Parameter Instances in Simulink and Stateflow
Simulink and Stateflow can have a shared or nonshared mapping of a parameter, depending on the parameter's Simulink storage class and Stateflow scope. A shared mapping is one in which the address of the parameter is the same in the code generated for Simulink blocks and Stateflow charts. This table shows how Simulink storage class and Stateflow scope affect the sharing of parameters in Simulink and Stateflow
Note a: Recommended; does not require any user defined data definition.
Note b: Requires user defined data definition.
Therefore, to best share data between Simulink and Stateflow, define parameters as exported in Stateflow and as ImportedExtern in Simulink. When the mapping is nonshared, separate instances of that parameter appear in the code generated for Simulink and Stateflow.
As an example, consider the model shown in this picture.In this model, the MATLAB variable Kp
is specified in two Gain blocks and as data of machine scope in a Stateflow chart.
When Inline parameters is selected, both Gain blocks share a single instance of Kp
, and the Stateflow chart references a second instance. In such cases, the numInstances
and mapOffset
fields of the ParameterTuning structure are used in conjunction. The numInstances
field specifies the number of parameter instances, while mapOffset
is the offset into the map vector (rtParametersMap
). The map vector determines the actual address of each instance from its source.
The following code shows the rtVariableTuning
and rtParametersMap
arrays for this case.
/* Tunable variable parameters */ static const VariableTuning rtVariableTuning[] = { /* variableName, * class, nRows, nCols, nDims, dimsOffset, source, dataType, numInstances, * mapOffset */ {"Kp", {rt_SCALAR, 1, 1, 2, -1, rt_SL_PARAM, SS_DOUBLE, 2, 0} }, {NULL, {(ParamClass)0, 0, 0, 0, 0, (ParamSource)0, 0, 0, 0} } }; static void * rtParametersMap[2]; void complex_inline_InitializeParametersMap(void) { rtParametersMap[0] = &rtP.Kp; /* 0: Kp */ rtParametersMap[1] = &Kp; /* 1: Kp */ } static uint_T const rtDimensionsMap[] = { 0 /* Dummy */ };
When Inline parameters is not selected, Real-Time Workshop creates two instances of Kp
in the global parameters structure rtP
for the two Simulink Gain blocks referencing Kp
, and a third instance as a global variable for the Stateflow chart. All three instances must be updated to reflect any change in Kp
. In the code example below, the entries for the Gain blocks in rtBlockTuning
correspond to the two instances of Kp
for those blocks. In addition, the entry for Kp
in rtVariableTuning
corresponds to the third instance for the Stateflow chart.
/* Tunable block parameters */ static const BlockTuning rtBlockTuning[] = { /* blockName, parameterName, * class, nRows, nCols, nDims, dimsOffset, source, dataType, numInstances, * mapOffset */ /* Sin */ {"complex_noninline/Sine Wave", "Amplitude", {rt_SCALAR, 1, 1, 2, -1, rt_SL_PARAM, SS_DOUBLE, 1, 0} }, /* Sin */ {"complex_noninline/Sine Wave", "Bias", {rt_SCALAR, 1, 1, 2, -1, rt_SL_PARAM, SS_DOUBLE, 1, 1} }, /* Sin */ {"complex_noninline/Sine Wave", "Frequency", {rt_SCALAR, 1, 1, 2, -1, rt_SL_PARAM, SS_DOUBLE, 1, 2} }, /* Sin */ {"complex_noninline/Sine Wave", "Phase", {rt_SCALAR, 1, 1, 2, -1, rt_SL_PARAM, SS_DOUBLE, 1, 3} }, /* Gain */ {"complex_noninline/Gain", "Gain", {rt_SCALAR, 1, 1, 2, -1, rt_SL_PARAM, SS_DOUBLE, 1, 4} }, /* Sin */ {"complex_noninline/Sine Wave1", "Amplitude", {rt_SCALAR, 1, 1, 2, -1, rt_SL_PARAM, SS_DOUBLE, 1, 5} }, /* Sin */ {"complex_noninline/Sine Wave1", "Bias", {rt_SCALAR, 1, 1, 2, -1, rt_SL_PARAM, SS_DOUBLE, 1, 6} }, /* Sin */ {"complex_noninline/Sine Wave1", "Frequency", {rt_SCALAR, 1, 1, 2, -1, rt_SL_PARAM, SS_DOUBLE, 1, 7} }, /* Sin */ {"complex_noninline/Sine Wave1", "Phase", {rt_SCALAR, 1, 1, 2, -1, rt_SL_PARAM, SS_DOUBLE, 1, 8} }, /* Gain */ {"complex_noninline/Gain1", "Gain", {rt_SCALAR, 1, 1, 2, -1, rt_SL_PARAM, SS_DOUBLE, 1, 9} }, {NULL, NULL, {(ParamClass)0, 0, 0, 0, 0, (ParamSource)0, 0, 0, 0} } }; /* Tunable variable parameters */ static const VariableTuning rtVariableTuning[] = { /* variableName, * class, nRows, nCols, nDims, dimsOffset, source, dataType, numInstances, * mapOffset */ {"Kp", {rt_SCALAR, 1, 1, 2, -1, rt_SF_PARAM, SS_DOUBLE, 1, 10} }, {NULL, {(ParamClass)0, 0, 0, 0, 0, (ParamSource)0, 0, 0, 0} } }; static void * rtParametersMap[11]; void complex_noninline_InitializeParametersMap(void) { rtParametersMap[0] = &rtP.Sine_Wave_Amp; /* 0 */ rtParametersMap[1] = &rtP.Sine_Wave_Bias; /* 1 */ rtParametersMap[2] = &rtP.Sine_Wave_Freq; /* 2 */ rtParametersMap[3] = &rtP.Sine_Wave_Phase; /* 3 */ rtParametersMap[4] = &rtP.Gain_Gain; /* 4 */ rtParametersMap[5] = &rtP.Sine_Wave1_Amp; /* 5 */ rtParametersMap[6] = &rtP.Sine_Wave1_Bias; /* 6 */ rtParametersMap[7] = &rtP.Sine_Wave1_Freq; /* 7 */ rtParametersMap[8] = &rtP.Sine_Wave1_Phase; /* 8 */ rtParametersMap[9] = &rtP.Gain1_Gain; /* 9 */ rtParametersMap[10] = &Kp; /* 10: Kp */ } static uint_T const rtDimensionsMap[] = { 0 /* Dummy */ };
Accessing the Parameter Mapping Structures.
The parameter mapping arrays in model
_pt.c
are declared static
. Pointers to the parameter mapping arrays are stored in a ModelMappingInfo
structure, defined as follows in matlabroot
/rtw/c/src/mdl_info.h
.
typedef struct ModelMappingInfo_tag { /* block signal monitoring */ struct { BlockIOSignals const *blockIOSignals; /* Block signals map */ uint_T numBlockIOSignals; /* Num signals in map */ } Signals; /* parameter tuning */ struct { BlockTuning const *blockTuning; /* Block parameters map */ VariableTuning const *variableTuning; /* Variable parameters map */ void * const *parametersMap; /* Parameter index map */ uint_T const *dimensionsMap; /* Dimensions index map */ uint_T numBlockTuning; /* Num block parameters in map */ uint_T numVariableTuning; /* Num variable parameter in map */ } Parameters; } ModelMappingInfo;
The ModelMappingInfo
structure is cached in the rtModel
data structure. Use the rtmGetModelMappingInfo
macro to obtain a pointer to the ModelMappingInfo
structure, as in the following example.
#include "mdl_info.h
"/* note: rTM is a pointer to the real-time Model Object */
.
.
.
ModelMappingInfo *MMI = rtmGetModelMappingInfo(rtM);
In mdl_info.h
, Real-Time Workshop provides additional macros that let you access members of the ModelMappingInfo
structurevia a ModelMappingInfo
pointer.
Using the Example Code
Real-Time Workshop provides example code that uses the parameter tuning API in matlabroot
/rtw/c/src/pt_print.c
. This file contains three functions:
rt_PrintParamInfo
displays all the tunable block parameters and MATLAB variables to the standard output.
rt_PrintPTRec
prints and then tests a parameter tuning record.
rt_ModifyParameter
updates all parameters associated with a specified parameter tuning record.
This code is intended as a starting point for your parameter tuning code. For more information see the function abstracts preceding each function.
To become familiar with the example code, we suggest building a model that displays all the tunable block parameters and MATLAB variables to the screen. You can use ptdemo
, the parameter tuning demo model, for this purpose. First, run the demo with Inline parameters on:
includes the TLC file matlabroot
/rtw/c/tlc/mw/ptinfotestfile.tlc
. This file generates code required to display the parameter tuning information.
./ptdemo_grt_rtw/ptdemo_pt.c
).
Next, run the demo with Inline parameters off:
ptdemo_pt.c
file, with Inline parameters on versus off.
Restrictions
The parameter tuning C API does not support:
k=1+i
)
a=k
) are supported.
The coefficients of the Transfer Fcn, State-Space, Discrete Filter, Discrete Transfer Function and Discrete State-Space blocks are tunable, subject to requirements described in Tunability of Linear Block Parameters.
Summary of Parameter Tuning Source Files
matlabroot
/rtw/c/src/mdl_info.h
: model mapping structure definition
matlabroot
/rtw/c/src/pt_info.h
: parameter tuning structure definitions
matlabroot
/rtw/c/tlc/ptinfo.tlc
: TLC file to produce model
_pt.c
matlabroot
/rtw/c/tlc/mw/ptinfotestfile.tlc
: TLC file to hook in example print code
matlabroot
/rtw/c/src/pt_print.c
: example code to print/modify parameters
![]() | Signal Monitoring via Block Outputs | Target Language Compiler API for Signals and Parameters | ![]() |