%% Introduction to Managing Data with Model Reference
% This example shows the basic concepts related to managing data with model
% reference.
%
% For a more detailed discussion of this topic, see 
% <docid:simulink_ref#example-sldemo_mdlref_datamngt2 Detailed Workflow for
% Managing Data with Model Reference>.
%
% *NOTE:* This example uses the same model as the more detailed example.
% As a result, the model uses certain features that this introductory
% example does not describe.

% Copyright 1990-2021 The MathWorks, Inc.
%% Open the Example Model
% Open the example model |sldemo_mdlref_datamngt|.
open_system('sldemo_mdlref_datamngt');
%% Example Content
% This example uses a top model |sldemo_mdlref_datamngt| that contains
% three Model blocks: Counter1, Counter2, and Counter3. These blocks
% reference the same model |sldemo_mdlref_counter_datamngt|.
%
% The referenced model implements a limited counter algorithm that:
%
% * Resets the counter if the first trigger input changes
% * Increments the counter by a specified amount if the second input changes
% * Saturates the counter between the specified upper and lower limits
%
% The referenced model outputs a bus signal that contains:
%
% * *Count:* the value of the counter as an 8-bit integer
% * *OverflowState:* an enumerated value that indicates whether the counter is
% at the upper limit, lower limit, or in range
%% Example Outline
% *The sequence of steps in the example is as follows:*
%
% 1. Prepare the referenced model (|sldemo_mdlref_counter_datamngt|) to use
% structures for the signals and parameters in its external interface.
%
% 2. Prepare the top model (|sldemo_mdlref_datamngt|) to call the
% referenced model.
%
% 3. Simulate the top model and examine the results.

%% Referenced Model: Setting Up Parameters
% The referenced model has two model arguments (CounterParams, CounterICs)
% that parameterize the blocks in the model. Model arguments provide
% different parameter values to each instance of a referenced model. In
% this model, the arguments are defined as parameter structures to reduce
% the number of arguments being passed to the referenced model.
%
% *The process for defining the model arguments is as follows:*

%%
% 1. Open the referenced model |sldemo_mdlref_counter_datamngt|.
open_system('sldemo_mdlref_counter_datamngt');

%%
% 2. Define MATLAB structures to parameterize the referenced model.
%
%   CounterParams.Increment  = int8(1);
%   CounterParams.LowerLimit = int8(-10);
%   CounterParams.UpperLimit = int8(10);
%   
%   CounterICs.Count         = int8(0);
%   CounterICs.OverflowState = SlDemoRangeCheck.InRange;
CounterParams.Increment  = int8(1);
CounterParams.LowerLimit = int8(-10);
CounterParams.UpperLimit = int8(10);

CounterICs.Count         = int8(0);
CounterICs.OverflowState = SlDemoRangeCheck.InRange;

clear CounterParams CounterICs;

%%
% *NOTE:* This example uses an 8-bit integer for the counter, so the numeric fields
% also use 8-bit integers.

%%
% 3. Use the MATLAB structures as model arguments.
%
% Model arguments are defined as variables in the model workspace of a referenced
% model.  You can initialize the model workspace from a number of different data sources.
% This example uses a MATLAB script (<matlab:edit('sldemo_mdlref_counter_datamngt_wsdata'); |sldemo_mdlref_counter_datamngt_wsdata|>)
% to create the parameter structures for the model arguments.  Using a
% MATLAB script makes it easy to create and modify the parameter structure
% outside the model.  It also facilitates incremental changes, version control,
% and data differencing.
%
% Set the data source in the dialog of the model workspace.
%
% <<../sldemo_mdlref_datamngt_snapshot_01.png>>
%
%%
% You can use the <matlab:daexplr; Model Explorer> to view and edit the
% contents of the model workspace.
%
% Select the Argument checkbox to configure variables as model arguments.
%
% <<../sldemo_mdlref_datamngt_snapshot_02.png>>
%
%% Referenced Model: Defining the Shape of the Output Bus Signal
% The referenced model produces two results and packages them into a bus signal:
%
% * *Count:* the value of the counter as an 8-bit integer
% * *OverflowState:* an enumerated value that indicates whether the counter is
% at the upper limit, lower limit, or in range

%%
% *To define the bus type for the root output of the referenced model:*
%
% 1. Use the <matlab:buseditor Bus Editor> to define the bus object (OutputType).
%
% <<../sldemo_mdlref_datamngt_snapshot_03.png>>
%
%%
% Alternatively, you can create the bus object at the MATLAB command line:
%
%   OutputType = Simulink.Bus;
%   OutputType.Elements = Simulink.BusElement;
%   OutputType.Elements(1).Name = 'Count';
%   OutputType.Elements(1).DataType = 'int8';
%   OutputType.Elements(2) = Simulink.BusElement;
%   OutputType.Elements(2).Name = 'OverflowState';
%   OutputType.Elements(2).DataType = 'Enum: SlDemoRangeCheck';
OutputType = Simulink.Bus;
OutputType.Elements = Simulink.BusElement;
OutputType.Elements(1).Name = 'Count';
OutputType.Elements(1).DataType = 'int8';
OutputType.Elements(2) = Simulink.BusElement;
OutputType.Elements(2).Name = 'OverflowState';
OutputType.Elements(2).DataType = 'Enum: SlDemoRangeCheck';

%%
% 2. Configure the root outport of the referenced model to output a nonvirtual
% bus signal based on this bus object (OutputType).
%
% <<../sldemo_mdlref_datamngt_snapshot_04.png>>
%

%% Referenced Model: Setting Initial Value for Bus Output
% In general, the initial values for bus signals and states can be specified as '0',
% in which case all of the elements of the bus will be initialized to zero (or the
% relevant ground value). However, in certain cases, it is desirable to specify
% nonzero initial values for bus signals and states.  In this example, the initial
% condition of the counter is tunable, so the initial value of output signal must
% be set consistently.
%
% *To specify the initial value of the output of the referenced model:*
%
% 1. Create a parameter structure that is compatible with the bus signal that
% you want to initialize.  One of the model arguments (CounterICs) is a parameter
% structure that matches the shape of the output signal.  This structure was
% defined as follows:
%
%   CounterICs.Count         = int8(0);
%   CounterICs.OverflowState = SlDemoRangeCheck.InRange;
CounterICs.Count         = int8(0);
CounterICs.OverflowState = SlDemoRangeCheck.InRange;

%%
% 2. Open the dialog box for the root outport and enter the name of the
% structure (CounterICs) into the *Initial output* field.
%
% <<../sldemo_mdlref_datamngt_snapshot_05.png>>
%
%%
% *NOTE:* In general, when initializing a bus signal or state, the parameter
% structure does not need to match the bus type exactly, but its fields must be
% a subset of the elements in the bus object and the attributes of these fields
% must match the elements in the bus object.

%% Referenced Model: Masking Referenced Model
% It is often useful to mask the referenced model to customize the user interface.
% You can create a mask on a model and then reference it from a Model block. 
% To mask a model, click *Create Model Mask* in the model workspace section of Model Explorer for the model. 
%%
% <<../sldemo_mdlref_datamngt_snapshot_modelmask.png>>
%
close_system('sldemo_mdlref_datamngt');
%% Top Model: Parameterizing Model Blocks
% The referenced model is configured to accept a structure for its model
% argument. This example calls each instance of the referenced model with
% different parameter values.
%
% 1. Open the top model |sldemo_mdlref_datamngt|.
open_system('sldemo_mdlref_datamngt');

close_system('sldemo_mdlref_datamngt/Scope1');
close_system('sldemo_mdlref_datamngt/Scope2');
close_system('sldemo_mdlref_datamngt/Scope3');

%%
% 2. Create parameter structures with the same "shape" as the model
% arguments defined in the referenced model.
%
%   clear Param1 Param2 IC1 IC2;
%   Param1.Increment  = int8(1);
%   Param1.LowerLimit = int8(-20);
%   Param1.UpperLimit = int8(20);
%   
%   Param2 = Param1;
%   Param2.Increment  = int8(2);
%   
%   IC1.Count         = int8(0);
%   IC1.OverflowState = SlDemoRangeCheck.InRange;
%   
%   IC2 = IC1;
%   IC2.Count = int8(-10);
clear Param1 Param2 IC1 IC2;
Param1.Increment  = int8(1);
Param1.LowerLimit = int8(-20);
Param1.UpperLimit = int8(20);

Param2 = Param1;
Param2.Increment  = int8(2);

IC1.Count         = int8(0);
IC1.OverflowState = SlDemoRangeCheck.InRange;

IC2 = IC1;
IC2.Count = int8(-10);
%%
% 3. Set the mask parameters on the masked Model blocks to use these parameters.
%
% For example, the parameters of the first Model block
% |'sldemo_mdlref_datamngt/Counter1'| are set as:
% 
% * *Param1* for the *Counter parameters*
% * *IC1* for the *Initial conditions*
%
% <<../sldemo_mdlref_datamngt_snapshot_06.png>>
%
%% Top Model: Scheduling Calls to the Referenced Model
% As mentioned earlier, the referenced model implements a limited counter
% algorithm with two trigger inputs.  The algorithm detects "rising edges"
% in the trigger inputs and reacts as follows:
%
% * Resets the counter if the first trigger input changes.
% * Increments the counter by a specified amount if the second input changes.
%
% In this example, you drive all three instances of the counter algorithm with
% the same trigger inputs, generated by the Stimulus subsystem.  The period
% and sample time of the trigger inputs are defined by the values entered
% for the mask parameters of the Stimulus subsystem:
%
% * Reset counter every 4 seconds.
% * Increment counter 5 times per second (period = 0.2 second).
% * Sample time is 0.1 second.
%
% *NOTE:* Reset and increment periods must be at least 2 times the sample time.

%% Simulating the Top Model
% 1. Save or close the referenced model.
%
% You need to save the referenced model before it can be used by the top model.
% Alternatively, you can close the referenced model and use the original
% version of the model provided with this example.
set_param('sldemo_mdlref_counter_datamngt', 'Dirty', 'off');
%%
% 2. Simulate the top model by selecting *Simulation* > *Run*.
%
evalc('sim(''sldemo_mdlref_datamngt'');'); 
%%
% *NOTE:* Simulating the top model automatically generates a simulation
% target for the referenced model.
%%
% 3. Review the simulation results as displayed by the Scope blocks.
open_system('sldemo_mdlref_datamngt/Scope1');
open_system('sldemo_mdlref_datamngt/Scope2');
open_system('sldemo_mdlref_datamngt/Scope3');

evalc('sim(''sldemo_mdlref_datamngt'');');
%%
close_system('sldemo_mdlref_datamngt/Scope1');
close_system('sldemo_mdlref_datamngt/Scope2');
close_system('sldemo_mdlref_datamngt/Scope3');

