%% Pass Parameter Data to Referenced Model Entry-Point Functions as Arguments
% NOTE: This example to remain authored in XML until dev area settles down.
% Configure a referenced model to accept
% parameter data through formal parameters of the generated model
% entry-point
% function. This technique enables you to specify a different parameter
% value for each instance (Model block) of the referenced model. 
%% Configure Referenced Model to Use Model Arguments
% Create the model |ex_arg_code_ref|. This model represents a reusable
% algorithm. 
open_system('ex_arg_code_ref')
%%
% In the Inport block dialog box, on the *Signal Attributes* tab, set *Data
% type* to |single|. Due to data type inheritance, the other signals in the
% model use the same data type.
set_param('ex_arg_code_ref/In1','OutDataTypeStr','single')
%%
% In the Model Explorer *Model Hierarchy* pane, expand the node
% *ex_arg_code_ref* and select *Model Workspace*.
%
% Select *Add > Simulink Parameter* twice. Two |Simulink.Parameter| objects
% appear in the *Contents* pane.
%
% Rename the objects as |gainArg| and |coeffArg|.
%
% Set the |Value| property of the objects. For example, set them to |3.17| and |1.05|, respectively.
modelWorkspace = get_param('ex_arg_code_ref','ModelWorkspace');
assignin(modelWorkspace,'gainArg',Simulink.Parameter(3.17));
assignin(modelWorkspace,'coeffArg',Simulink.Parameter(1.05));
%%
% In the *Contents* pane, for |coeffArg| and |gainArg|, select the check
% box in the *Argument* column.
set_param('ex_arg_code_ref','ParameterArgumentNames','coeffArg,gainArg')
%%
% <<../ref_mdlwksp.png>>
%
% In the |ex_arg_code_ref| model, in the Gain block dialog box, set *Gain*
% to |gainArg|.
set_param('ex_arg_code_ref/Gain','Gain','gainArg')
%%
% In the Discrete Filter block dialog box, set *Numerator*
% to |coeffArg|.
set_param('ex_arg_code_ref/Discrete Filter','Numerator','coeffArg')
%%
% Save the |ex_arg_code_ref| model.
save_system('ex_arg_code_ref')
%% Specify Instance-Specific Parameter Values in Model Blocks
% Create the model |ex_arg_code_ref|. This model uses multiple instances
% (Model blocks) of the reusable algorithm.
open_system('ex_arg_code')
%%
% Open the upper Model block dialog box.
%
% Under *Model arguments*, set *coeffArg* and *gainArg* to |0.98| and |2.98|.
set_param('ex_arg_code/Model','ParameterArgumentValues',...
    struct('coeffArg','0.98','gainArg','2.98'))
%%
% <<../model_blk_1.png>>
%
% In the other Model block dialog box, set *coeffArg* and *gainArg* to
% |1.11| and |3.34|.
set_param('ex_arg_code/Model1','ParameterArgumentValues',...
    struct('coeffArg','1.11','gainArg','3.34'))
%%
% Generate code from the top model.
rtwbuild('ex_arg_code')
%%
% The file |ex_arg_code_ref.c| defines the referenced
% model entry-point function, |ex_arg_code_ref|. The function has two formal
% parameters,
% |rtp_coeffArg| and |rtp_gainArg|, that correspond to the model arguments, |coeffArg| and |gainArg|. The
% formal parameters use the data type |real32_T|, which corresponds to the
% data type |single| in Simulink.
file = fullfile('slprj','grt','ex_arg_code_ref','ex_arg_code_ref.c');
rtwdemodbtype(file,'/* Output and update for referenced model:',...
    'real32_T rtp_gainArg)',1,1)
%%
% The file |ex_arg_code.c| contains the definition of the top model
% entry-point function, |ex_arg_code|. This function calls the referenced
% model entry-point 
% function, |ex_arg_code_ref|, and uses the model argument values that
% you specified (such as |1.11| and |3.34|) as the values of |rtp_coeffArg| and |rtp_gainArg|.
file = fullfile('ex_arg_code_grt_rtw','ex_arg_code.c');
rtwdemodbtype(file,'/* ModelReference: ''<Root>/Model'' incorporates:',...
    '1.11F, 3.34F)',1,1)
%%
% The formal parameters use the data type |real32_T| (|single|) because:
%
% # The block parameters in |ex_arg_code_ref| determine their data types
% through internal rules. For example, in the Gain block dialog box, on the
% *Parameter Attributes* tab, *Parameter data type* is set to |Inherit:
% Inherit via internal rule| (the default). In this case, the internal rule chooses the
% same data type as the input and output signals, |single|.
% # The model arguments in the model workspace use context-sensitive data
% typing because the value of the |DataType| property is set to |auto| (the
% default). With
% this setting, the model arguments use the same data type as the block
% parameters, |single|.
% # The formal parameters in the generated code use the same data type as
% the model arguments, |single|.
%% Generate Tunable Argument Values
% You can configure the
% instance-specific values in the Model blocks to appear in the generated code as tunable
% global variables. This technique enables you to store the parameter
% values
% for each instance in memory and to tune the values during code execution.
%
% View the contents of the |ex_arg_code_ref| model workspace in Model
% Explorer.
%
% Copy |gainArg| and |coeffArg| from the
% |ex_arg_code_ref| model workspace to the base workspace.
%
% Rename |gainArg| as |gainForInst1|. Rename |coeffArg| as |coeffForInst1|.
gainForInst1 = getVariable(modelWorkspace,'gainArg');
gainForInst1 = copy(gainForInst1);
coeffForInst1 = getVariable(modelWorkspace,'coeffArg');
coeffForInst1 = copy(coeffForInst1);
%%
% Copy |gainForInst1| and |coeffForInst1| as |gainForInst2| and
% |coeffForInst2|.
gainForInst2 = copy(gainForInst1);
coeffForInst2 = copy(coeffForInst1);
%%
% Set the instance-specific parameter values by using the |Value| property
% of the parameter objects in the base workspace. 
gainForInst1.Value = 2.98;
coeffForInst1.Value = 0.98;

gainForInst2.Value = 3.34;
coeffForInst2.Value = 1.11;
%%
% For the new parameter objects, set |StorageClass| to |ExportedGlobal|.
% This setting causes the parameter objects to appear in the generated code
% as tunable global variables.
gainForInst1.StorageClass = 'ExportedGlobal';
coeffForInst1.StorageClass = 'ExportedGlobal';
gainForInst2.StorageClass = 'ExportedGlobal';
coeffForInst2.StorageClass = 'ExportedGlobal';
%%
% In the top model, |ex_arg_code|, open the upper Model block dialog box.
%
% Set *coeffArg* to |coeffForInst1| and *gainArg* to |gainForInst1|.
set_param('ex_arg_code/Model','ParameterArgumentValues',...
    struct('coeffArg','coeffForInst1','gainArg','gainForInst1'))
%%
% <<../model_blk_2.png>>
%
% In the other Model block dialog box, set *coeffArg* to |coeffForInst2|
% and *gainArg* to |gainForInst2|.
set_param('ex_arg_code/Model1','ParameterArgumentValues',...
    struct('coeffArg','coeffForInst2','gainArg','gainForInst2'))
%%
% Generate code from the top model.
rtwbuild('ex_arg_code')
%%
% The file |ex_arg_code.c| defines the global variables that correspond to
% the parameter objects in the base workspace.
file = fullfile('ex_arg_code_grt_rtw','ex_arg_code.c');
rtwdemodbtype(file,'/* Exported block parameters */',...
    '/* Block states (default storage) */',1,0)
%%
% In each call to |ex_arg_code_ref|, the top model algorithm uses the
% global variables to set the values of the formal parameters.
rtwdemodbtype(file,'/* ModelReference: ''<Root>/Model'' incorporates:',...
    'gainForInst2);',1,1)
%%
% The global variables in the generated code use the data type |real32_T|
% (|single|)
% because:
%
% # The parameter objects in the base workspace use context-sensitive data
% typing because the |DataType| property is set to |auto| (the default).
% With this setting, the parameter objects in the base workspace use the
% same data type as the model arguments, |single|.
% # The global variables in the generated code use the same data type as
% the parameter objects in the base workspace.
%% Group Multiple Model Arguments into Single Structure
% Use the Model Explorer to copy |gainArg| and |coeffArg| from the
% |ex_arg_code_ref| model workspace into the base workspace.
temp = getVariable(modelWorkspace,'gainArg');
gainArg = copy(temp);
temp = getVariable(modelWorkspace,'coeffArg');
coeffArg = copy(temp);
%%
% At the command prompt, combine these two parameter objects into a
% structure, |structArg|.
structArg = Simulink.Parameter(struct('gain',gainArg.Value,...
    'coeff',coeffArg.Value));
%%
% Use the Model Explorer to move |structArg| into the model workspace.
assignin(modelWorkspace,'structArg',copy(structArg));
clear structArg gainArg coeffArg
%%
% In the *Contents* pane, configure |structArg| as the only model argument.
set_param('ex_arg_code_ref','ParameterArgumentNames','structArg')
%%
% <<../structArg.png>>
%
% In the |ex_arg_code_ref| model, set the *Gain* parameter of the Gain
% block to |structArg.gain|.
set_param('ex_arg_code_ref/Gain','Gain','structArg.gain')
%%
% In the Discrete Filter block dialog box, set *Numerator*
% to |structArg.coeff|.
set_param('ex_arg_code_ref/Discrete Filter',...
    'Numerator','structArg.coeff')
%%
% At the command prompt, combine the four parameter objects in the base
% workspace into two structures. Each structure stores the
% parameter values for one instance of |ex_arg_code_ref|.
structForInst1 = Simulink.Parameter(struct('gain',gainForInst1.Value,...
    'coeff',coeffForInst1.Value));

structForInst2 = Simulink.Parameter(struct('gain',gainForInst2.Value,...
    'coeff',coeffForInst2.Value));
%%
% Apply the storage class |ExportedGlobal| to the parameter objects.
structForInst1.StorageClass = 'ExportedGlobal';
structForInst2.StorageClass = 'ExportedGlobal';
%%
% In the top model, in the upper Model block dialog box, set *structArg* to
% |structForInst1|.
set_param('ex_arg_code/Model','ParameterArgumentValues',...
    struct('structArg','structForInst1'))
%%
% <<../model_blk_3.png>>
% 
% In the other Model block dialog box, set *structArg* to
% |structForInst2|.
set_param('ex_arg_code/Model1','ParameterArgumentValues',...
    struct('structArg','structForInst2'))
%%
% Use the function |Simulink.Bus.createObject| to create a |Simulink.Bus|
% object. The hierarchy of elements in the object matches the hierarchy of the structure
% fields. The default name of the object is |slBus1|.
Simulink.Bus.createObject(structForInst1.Value);
%%
% Rename the bus object as |myParamStructType| by copying it.
myParamStructType = copy(slBus1);
%%
% Set the data type of the parameter objects in the base workspace by using
% the bus object.
structForInst1.DataType = 'Bus: myParamStructType';
structForInst2.DataType = 'Bus: myParamStructType';
%%
% Use the Model Explorer to view the contents of the |ex_arg_code_ref|
% model workspace.
%
% For the parameter object
% |structArg|, set |DataType| to |Bus: myParamStructType|.
temp = getVariable(modelWorkspace,'structArg');
temp = copy(temp);
temp.DataType = 'Bus: myParamStructType';
assignin(modelWorkspace,'structArg',copy(temp));
%%
% <<../structArg_type.png>>
%
% Save the |ex_arg_code_ref| model.
save_system('ex_arg_code_ref')
%%
% When you use structures to group parameter values, you cannot take
% advantage of context-sensitive data typing to control the data types of
% the fields of the structures (for example, the fields of
% |structForInst1|). However, you can use the properties of the bus object
% to control the field data types.
%
% Set the data type of the elements in the bus object to |single|. The
% corresponding fields in the structures (such as |structForInst1| and |structArg|) use the
% same data type.
myParamStructType.Elements(1).DataType = 'single';
myParamStructType.Elements(2).DataType = 'single';
%%
% Generate code from the top model, |ex_arg_code|.
rtwbuild('ex_arg_code')
%%
% The file |ex_arg_code_types.h| defines the structure type
% |myParamStructType|, which corresponds to the |Simulink.Bus| object.
file = fullfile('ex_arg_code_grt_rtw','ex_arg_code_types.h');
rtwdemodbtype(file,'typedef struct {','} myParamStructType;',1,1)
%%
% In the file |ex_arg_code_ref.c|, the referenced model entry-point function has a formal
% parameter,
% |rtp_structArg|, that correspond to the model argument |structArg|.
file = fullfile('slprj','grt','ex_arg_code_ref','ex_arg_code_ref.c');
rtwdemodbtype(file,'/* Output and update for referenced model:',...
    '*rtp_structArg)',1,1)
%%
% The file |ex_arg_code.c| defines the global structure variables that correspond to
% the parameter objects in the base workspace.
file = fullfile('ex_arg_code_grt_rtw','ex_arg_code.c');
rtwdemodbtype(file,'/* Exported block parameters */',...
    '/* Block states (default storage) */',1,0)
%%
% The top model algorithm in the file |ex_arg_code.c| passes the addresses
% of the structure variables to the referenced model entry-point function.
file = fullfile('ex_arg_code_grt_rtw','ex_arg_code.c');
rtwdemodbtype(file,'/* ModelReference: ''<Root>/Model'' incorporates:',...
    '&structForInst2);',1,1)

%% 
% Copyright 2012 The MathWorks, Inc.