%% Run Executable for Different Values of Variant Parameters Without Recompiling Code
% This example shows how to generate an executable that runs for different set of variant parameter values without any need to recompile the code for each set of values.
%
% In this example, you build an executable that represents the step response of a linear system with PID controller. 
% In the executable, the PID parameters, proportional gain and integral gain, are specified as variant parameters that have multiple values to cater to multiple requirements. 
% Each value is associated with a variant control expression.
% When you run the executable, Simulink(R) evaluates the condition expression. Based on the condition expression that evaluates to |true|, all the gain parameter values associated 
% with that condition expression becomes active and the executable runs only for those set of gain values. You can then change the value of the variant control variable to run 
% the executable for different set of gain parameter values. You are not required to recompile the code to build the executable for different set of gain parameter values.

% Copyright 2021 The MathWorks, Inc.

%% Overview of Variant Parameters 
%
% Variant parameters can have multiple values. Each value of the variant parameter is associated with a variant condition expression. 
% During simulation, the value of the variant parameter associated with the condition that evaluates to |true| is the active value of that parameter. 
% The value associated with the condition that evaluates to |false| is the inactive value of that variant parameter. 
% For more information, see <docid:simulink_ug.mw_eef24dbd-1d0a-4c7a-a09f-9bc298a5372c Variant Parameters>.
%
% The variability and the representation of variant parameters in the generated code is determined by the <docid:simulink_ref.mw_0b2d1f0b-dda5-47f1-a6a5-18ffa2721f27 activation time> and the <docid:simulink_ref.mw_a8c688d5-0f56-445c-9286-f115a7c323d3 specification> propery you specify.
% The activation time determines whether to include only active choice or
% both active and inactive choices in the code. The storage class determines whether to represent the parameters as inline or tunable variables.
% For more information, see <docid:ecoder_ug.mw_a8d6dbb5-6325-41c2-b4d6-0d92e22be29a Options to Represent Variant Parameters in Generated Code>.
%
% If you specify the activation time as |startup|, the executable that you build from the generated code include both active and inactive values of variant parameters. 
% The values are enclosed in regular |if| conditions of the |model_initialize| function of the executable. 
% The advantage of including all the values in the executable is that you are not required to recompile the code every time you change the active values. 
% You build the executable only once. You can then change the value of the variant control variable and then run the executable for a different set of active values.  
%% Prerequisite 
% Before you start this example, we recommend you complete
% <docid:ecoder_ug.mw_a8d6dbb5-6325-41c2-b4d6-0d92e22be29a Options to Represent Variant Parameters in Generated Code>.
%% Explore the model 
% Open the model. 
%
% open_system([matlabroot '/examples/simulink_variants/main/slexVariantParametersStartup]) 
%
% The PID Controller block has two variant parameters *Proportional(P)* and *Integral(I)*. The parameters are specified as |<docid:simulink_ref.mw_c93826f7-948b-4efc-8eb0-5b9edf01b3cd Simulink.VariantVariable>| objects |Kp| and |Ki|. 
% |Kp| and |Ki| have multiple values and are associated with a
% <docid:simulink_ref#mw_6364b9fa-27df-4da2-a774-3168210e3dd Simulink.VariantControl> object |VCtrl| as specified in the
% |slexVariantParameterGain.m| file.
% Since, the activation time of |VCtrl| is specified as |startup| and its storage class is specified as |ExportedGlobal|, the code that you generated from this model
% includes all the values of |Kp| and |Ki| in regular |if| conditions of the |model_initialize| function. The values inside the |if| conditions are represented as tunable variables.
% 
% When you build and run an executable from the code, Simulink reads the value of |VCtrl| from the |slexVCtrl.txt| file to evaluate the |if| conditions at the start of the execution.  
% Since, the value of |VCtrl| is specified as |1|, the condition |VCtrl == 1| evaluates to |true| and so the executable caluculates the step response
% for the values associated with |VCtrl == 1|. To calculate the step response for a different value of |VCtrl|, change the value of |VCtrl| in the |slexVCtrl.txt| file and run the executable again.
%% Generate Code and Build Executable that Contains All Choices of Variant Parameters 
% Before you generate code and build executable from the model, you must first ensure that you have write permission in your current folder.  
%% Build and Review the Generated Code 
% In the *Apps* gallery of the model toolstrip, click *Embedded Coder*. On
% the *C Code* tab, click *Build*. For more information, see <docid:ecoder_ug#bs_13dn Generate Code Using Embedded Coder>.
% 
% The code generator builds the executable and generates the *Code
% Generation Report* and places the executable in the working folder.
% On Windows(R), the executable is |slexVariantParametersStartup.exe|. On
% Linux(R), the executable is |slexVariantParameterStartup|.
% 
% 1. In the *C Code* tab, sleect *Open Report*.
%
% 2. Select the |slexVariantPArametersStartup.c| file. In this file, the
% |model_initialize| function includes:
%
% a. Symbolic names for all the values of |Kp| and |Ki| enclosed in regular
% |if| conditions. These |if| conditions are evaluated when you run the
% executable.
%
%  if (get_VCtrl() == 1) 
%  { 
%   Ki = 4.5; 
%   Kp = 0.15; 
%  } 
%  else if (get_VCtrl() == 2) 
%  { 
%   Ki = 4.0; 
%  	Kp = 0.5; 
%  } 
%  else if (get_VCtrl() == 3) 
%  { 
%   Ki = 3.5; 
%   Kp = 0.75; 
%  } 
%  else if (get_VCtrl() == 4) 
%  { 
%   Ki = 3.0; 
%   Kp = 1.0; 
%  } 
%
% b. The |utAssert| function to ensure that at least one variant condition evaluates to |true| when running the executable. 
%
%  utAssert((get_VCtrl() == 1) || (get_VCtrl() == 2) || (get_VCtrl() == 3) || (get_VCtrl() ==  4)); 
%
% 2. In the |model_step| function, the symbol names of |Kp| and |Ki| are used to form the equation. 
%
%  void slexVariantParameters_step(void) 
%  {  
%   ... 
%   slexVariantParametersStartup_Y.Out1 = 0.5 * 
%   slexVariantParametersStartup_DW.DiscreteTransferFcn_states[1]; 
% 
%   Add = (real_T)!(slexVariantParametersStartup_M->Timing.t[0] < 1.0) -slexVariantParametersStartup_Y.Out1; 
%  
%   rtb_FilterCoefficient = (0.0 * Add - 
%   slexVariantParametersStartup_DW.Filter_DSTATE) * 100.0; 
%  
%   slexVariantParametersStartup_B.Sum = (Kp * Add + 
%   slexVariantParametersStartup_DW.Integrator_DSTATE) + rtb_FilterCoefficient; 
%  
%   rtb_IntegralGain = Ki * Add; 
%   ...  
%  } 
%% Run the Generated Executable 
% 
% To run the generated executable, enter the following command in the MATLAB(R) command prompt: 
%
%  system('slexVariantParametersStartup.exe') 
%
% At the start of the execution, the executable invokes the |model_initialize| function. 
% The |model_initialize| function reads the value of |VCtrl| from the |slexVCtrl.txt| file to evaluate the |if| conditions in the function. 
% Since the value of |VCtrl| is set to |1| in the |slexVCtrl.txt| file, the |if| condition for |VCtrl == 1| evaluates to |true|. 
% The generated executable is conditionally run for the PID gain parameter values that are associated with |VCtrl == 1| and creates a |slexVariantParametersStartup.mat| MAT-file as an output. 
% The MAT-file contains values for the variables |rt_tout| and |rt_yout|, where |rt_yout| represents the linear step response at the outport block |Out1| for each time step |rt_tout|. 
%
% You can load the variables from the MAT-file by typing the following command at the MATLAB prompt: 
%
%  load slexVariantParametersStartup.mat 
%
% To plot the linear step response, use the following function in the MATLAB editor: 
% 
%  plot(rt_tout, rt_yout.signals.values, 'x-'); 
%
% Now, change the value of |VCtrl| in the |slexVCtrl.txt| to |2|. Run the executable again to observe the change in the step response. 
%% Run the Generated Executable for All Values of Variant Parameters 
%
% The |slexVariantStartup_script.m| implements the logic to plot the linear step response for different values of proportional gain and integral gain parameters by changing the value of the |VCtrl| using a |for| loop.  
%
% When you run the script: 
% 
% In the first iteration, the executable starts running and the |model_initialize| function is invoked. The executable reads the value of |VCtrl| as |1| from the |slexVCtrl.txt| file to evaluate the |if| conditions in the |model_initialize| function. 
% The condition |VCtrl == 1| evaluates to |true|, the proportional and integral gain values that are associated with |VCtrl == 1| becomes active. The executable calculates the step response for those values and creates a |slexVariantParametersStartup.mat| 
% MAT-file that contains the step response calculated for each time step. 
%
% In the next iteration, the value of |VCtrl| is incremented to |2|. The executable calculates the step response for the associated values and appends the newly calculated step response to the MAT-file. 
% 
% Similarly, the executable calculates the step response for values associated with conditions |VCtrl == 3| and |VCtrl == 4|.  
%
% Using the values in the MAT-file, the script plots the linear step response as shown. 
% 
% plot(rt_tout, rt_yout.signals.values, 'x-'); 