%% Unifying MATLAB and Simulink: A User Story Part 2
% In my previous post, I described how to parameterize a Simulink model using MATLAB objects. To be honest, there is nothing magic or revolutionary to that in itself. The reason why I decided to cover this topic in a series of posts is because of what this enables.
% In this post, I am building the foundation of a framework that, in my opinion, makes it very convenient to discover and interact with a Simulink model.
% Here are links to other posts in this series:
% Unifying MATLAB and Simulink: A User Story Part 1: Parameterizing a model with MATLAB objects
% Unifying MATLAB and Simulink: A User Story Part 2: The slPart class, block template and data variants
% Unifying MATLAB and Simulink: A User Story Part 3: Controlling variants with MATLAB objects
% Unifying MATLAB and Simulink: A User Story Part 4: Post-processing and visualizing logged data
% Unifying MATLAB and Simulink: A User Story Part 5: Larger examples
%% The Building Blocks
% This framework will be centered around a fundamental unit I decided to call a Simulink Part or slPart for short. I use the word "part" because I like to think of this as the mechanical parts you can find on the shelves of a garage or a machine shop: gears, nuts, bolts, etc. Parts can be made of other parts, like a car is made of an engine, suspensions, and wheels, and like a suspension is made of springs and dampers.
% The basic unit of this framework is built around two fundamental building blocks: a MATLAB class and a Simulink masked subsystem.
%% The superclass: slPart
% Let's begin with the MATLAB class, which I will name slPart, as in Simulink Part.
% This class allows me to define properties and methods common to all parts. I am making it a handle class, which allows both MATLAB code and Simulink blocks to refer to and interact with slPart objects back and forth.
% Through this series of posts, I will incrementally add functionalities to this class, but as a starting point, here is what the slPart class looks like:
% classdef slPart < handle
%     properties (Hidden = true)
%         BlockPath char
%     end
%     methods
%         function obj = maskInit(obj,blk)
%             obj.BlockPath = blk;
%         end
%     end
% end
% It has one property BlockPath, where I will store the path of the block where the object is being used and one method maskInit which, as its name implies, will be used for mask initialization.
%% The Template Block
% For the block, I created a "template" empty Subsystem and stored it in a library.
%
% Using the Mask Editor, I defined one parameter named "obj":
%
% To make sure that only objects of class slPart are passed to this parameter, I created a Parameter Constraint.
%
% I set the Mask type to be "slPart" (This will help me find instances of this block in the future)
%
% and I specify the maskInit method defined in slPart as Mask Initialization code:
%
% Finally, since I want users to edit blocks created from this template, I break the link to the library when I create a copy of this block. For that, I leverage the ClipboardFcn callback:
%
% With that setup, I can copy this library block into a model and begin creating my first Simulink Part!
%% Creating a First slPart
% For this first example, I will reuse the same spring class as in my previous post. The only difference is that it now subclasses slPart:
% classdef spring < slPart
%     properties
%         m
%         k
%         c
%     end
%     methods
%         function obj = spring()
%             obj.m = 0.5;
%             obj.k = 5;
%             obj.c = 3;
%         end
%     end
% end
% For convenience, I stored this spring class in a package folder named +springLib. I will describe why below. For now this means that I will refer to this class as springLib.spring.
% On the Simulink side, I drag a copy of the template block into a model, open the empty subsystem and implement my algorithm using the properties of "obj" as block parameters:
%
% I then instantiate a spring object:

mySpring = springLib.spring

% and specify mySpring in the block dialog:
%
% With that set up, I can simulate the model and once the simulation completes, mySpring knows where it has been simulated.

sim('spring_sim');
mySpring.BlockPath

% I will leverage this capability in following posts.
%% Creating Data Variants
% The next thing we can do is create a library of springs, like the ones you could buy from the catalog of a company selling springs. They will all use the same algorithm, but with different parameter values. For that, we can use our generic spring class as a template to create multiple subclasses inheriting from the spring superclass.
% This can quickly give you a catalog of springs. You can use these springs in all sorts of component models, or share this library of springs with collaborators. Those collaborators pick a spring from the catalog without worrying about the parameters or the algorithm under the mask.
%
% For convenience, it is possible to place all those data variants classes in a package folder.
%
% This creates a namespace that enables you to "scan" the catalog using tab-complete:
%
% With this library or catalog of springs, it becomes easy to simulate a model with different parameterizations:

in(1:2) = Simulink.SimulationInput('spring_sim');
in(1) = in(1).setVariable('mySpring',springLib.springN1234);
in(2) = in(2).setVariable('mySpring',springLib.spring_SupplierB_code5);
out = sim(in,'ShowProgress','off');

%% Now it's your Turn
% At this point, it's probably fair to say that I have not introduced anything really game changing. What I did so far is create the foundation of a framework that I will extend in the following posts by adding methods and properties to the slPart class that I created today.
% You can download the current status of the project here.
% If you have seen a similar framework or if the above gives you ideas on what you would like to see added to it, let me know in the comments below.