In simulink, programmatically create a variant subsystem - matlab

I want to use scripting to create and define a variant subsystem in simulink.
I am able to create the variant subsystem and add subsystems within it using the add_block but cannot find the appropriate property that defines the variant subsystem by using the get_param command.
The way I graphically configure a variant subsystem is by right clicking the block and going to Block Parameters and then adding the variant control conditions for each subsystem.
I want to do the same thing but from an m-file so that I can create multiple blocks programmatically.
I checked the documentation and google search but couldn't find anything.
Thanks in advance.

Based on a comment by #Praetorian, I opened the model in a text editor and found the parameter line where the variant condition was defined.
I found that the variant conditions are stored in the subsystems within the variant subsystem and not within the top-level variant subsystem.
So you store the condition within each subsystem's "VariantControl" parameter.
Example:
set_param([variantSys '/' sys],'VariantControl','a==1') where sys is a subsystem within the variant subsystem variantSys.

The variant control should be written on the Callbacks of the Model. In order to put the simulink variant controls available to the model, the variables should be created in the workspace. For this to happen you need to put your Sys = Simulink.Variant(Mode== value) etc on the PreLoadFcn.
Check access PreLoadFcn and put the formulas in there then your table will be automatically filled.
If you do not mind can you tell me how you created the variant subsystem?
Good luck

Related

How to use structure as parmeter for simulink subsystem and use fields inside as block parameters?

I have created a subsystem in Simulink. I would like this subsystem to have a single parameter, which is supposed to be a Matlab structure. Inside the subsystem, I would then like parameters of some of the blocks to be the fields of this structure.
So for example, imagine the subsystem has a single parmeter sys_inputs, then inside the subsystem I have two Constant blocks and the value for the first Constant block should be sys_inputs.Constant1, and the other should be sys_inputs.Constant2.
Is this possible, and if so, how exactly?
I'm finding the Matlab documentation on passing mask parameters to subsystem internal blocks a bit obtuse.
The purpose is so that the user only has to provide a single parameter to the subsystem instead of changing many parameters, when this input usually comes pre-packaged as a structure.
I discovered the answer myself.
First create the subsystem
Right click and 'create mask'
Edit mask parameters
Add an 'edit' parameter. The 'Name' of this parameter will be the variable name you can use inside your subsystem, e.g. sys_inputs
Inside the subsystem, you can use the sys_inputs parameter as though it was a workspace variable, so you can enter things like sys_inputs.Constant1 in the subsystem components parameters

How to programmatically configure the tunability of model parameters?

I'm porting a large Simulink model from Simulink R2010a → R2017b.
The main model is basically a glue-layer for many interwoven reference models. My objective is to generate a standalone executable out of this main model using Coder.
Parameter tunability in this context is not done via the Signals and Parameters section on the Optimization tab in the Model Configuration Parameters dialog (as is the case in stand-alone models), but rather, via constructing Simulink.Parameter objects in the base workspace, and referencing those in the respective referenced models, or in their respective model workspaces.
Now, AFAIK, in R2010a it was enough to set
new_parameter.RTWInfo.StorageClass = 'Auto';
new_parameter.RTWInfo.CustomStorageClass = 'Define';
to make the parameter non-tunable and convert it into a #define in the generated code. In R2017b, this is no longer allowed; the StorageClass must be 'Custom' if you set a non-empty CustomStorageClass:
new_parameter.CoderInfo.StorageClass = 'Custom'; % <- can't be 'Auto'
new_parameter.CoderInfo.CustomStorageClass = 'Define';
But apparently, this does not make the parameter non-tunable:
Warning: Parameter 'OutPortSampleTime' of '[...]/Rate Transition1' is non-tunable but refers to tunable variables (Simulation_compiletimeConstant (base workspace))
I can't find anything in the R2017b documentation on making parameters non-tunable, programatically; I can only find how to do it in stand-alone models via the dialog, but that's not what I want here.
Can anyone point me in the right direction?
NOTE: Back in the day, Simulink Coder was called Real-Time Workshop (well, Real-time Workshop split into Coder and several other things), hence the difference RTWInfo vs. CoderInfo. Note that RTWInfo still works in R2017b, but issues a warning and gets converted into Coderinfo automatically.
In generated code it should appear as #define, the way you specified it.
https://www.mathworks.com/help/rtw/ug/choose-a-built-in-storage-class-for-controlling-data-representation-in-the-generated-code.html
Btw, yes, it's a bit confusing, because in m-file you specify CustomStorageClass = 'Define';, in GUI you specify Storage class as Define (custom), but in documentation they say Storage Class as Defined.
I am not sure why warning about tunability shows up.

Simulink: Control Variant Subsystems Using Mask

I would like to find a simple process for switching the model innards under a mask using the mask parameters.
This question has expanded enough such that it has been reimplemented here.
Variant subsystems are an excellent method and can be controlled via workspace parameters;
however, I have found mask parameters to not interface with the variant subsystem selection.
This link is the first of a series of posts on how to use mask parameters to make changes to blocks inside of the system;
however, the method is not as intuitive as using variant subsystems and a switch.
The link is also from 2008 and I believe that it may have been superceded at some point.
MWE
I have made a model containing a system labeled Source.
It is connected to a Display block which displays its output.
Source is a variant subsystem.
It contains 3 variants:
Source\One
Source\Two
Source\Three.
Each variant contains one Constant block.
The value of the Constant block is eponymous with the block label.
For example, Source\Two contains a constant block with value 2.
Source is also a masked subsystem.
Its mask contains a Radio Button parameter with a value labeled variantValue.
The Radio Button options for the variantValue parameter are:
Choice 1
Choice 2
Choice 3
The mask Initialization code is as follows:
switch variantValue
case 'Choice 1'
set_param('Source','OverrideUsingVariant','One')
disp('One')
case 'Choice 2'
set_param('Source','OverrideUsingVariant','Two')
case 'Choice 3'
set_param('Source','OverrideUsingVariant','Three')
end
I have set the variant to Override.
I cannot set the mask to allow library blocks to modify contents, as this is greyed out.
I will drop the variant subsystem deeper into the hierarchy from the masked subsystem when a masked subsystem which is a variant subsystem works.
To do anything which does not go via your base workspace, you first need to set the "Overwrite variant conditions...", now you can choose the active variant with code:
set_param('untitled/Variant Subsystem','OverrideUsingVariant','Variant1')
What remains is creating a mask which, whenever the parameter is changed in your mask, runs the above line. This can be done via the initialisation commands.

How can I use multiple instances of a subvi (component) in subpanels without xcontrol?

I try to build modular, reusable code in labview.
I want to create a UI component that allows me to select one of the files or directories in a given directory.
I created a subvi that does this. So far so good.
I can use this subvi as a component in other vis, by putting it into a subpanel.
I want to have several of such subpanels with an "instance" of the subvi in my main vi.
I cannot do this. Labview opens the subvi in one subpanel and throws an error for opening it in another one.
How can I tell Labview to create a duplicate/new "instance" of the subvi that runs independently from the any other one?
I found out that xcontrol are probably a better approach to creating components, but they are not available to me, whether they solve the above problem or not.
Labview 2013
You need to configure the subvi to be reentrant.
This allows LabVIEW to allocate data space for each instance.
There are different types of reentrancy, I would stick with the pre-allocated option to start.
http://zone.ni.com/reference/en-XX/help/371361J-01/lvconcepts/reentrancy/

Variable subsystem implementation in Simulink 2007a

I've seen that it's already implemented in Matlab R2013 in the form of Variant Subsystems, but budget and convenience don't show the upgrade necessary yet:
I am seeking a subsystem in which a concrete implementation can be selected prior to running the simulation, in Matlab R2007a.
A bunch of enabled subsystems along with a switch block connected to a masked variable would do the trick, however the whole family of selectable implementations must coexist inside the "container" subsystem.
Any workaround, other than upgrading to R2013?
Thank you.
I have come up with the following workaround.
1- Include all the possible implementations in a Library
2- Create a Configurable Subsystem block in the Library and edit it to include all the desired implementations
3- Right clicking in a Configurable Subsystem instance will show the "Block Choice" option where the desired implementation can be chosen.
Regardless of differences that may exist with respect to the Variant Subsystem solution when it comes to code generation, RT targets etc..., this solution works for me.