Comments on: Time to Convert to Variant Subsystems https://blogs.mathworks.com/simulink/2013/03/18/time-to-convert-to-variant-subsystems/?s_tid=feedtopost Guy Rouleau is an Application Engineer for MathWorks. He writes here about Simulink and other MathWorks tools used in Model-Based Design. Fri, 06 Sep 2019 10:06:01 +0000 hourly 1 https://wordpress.org/?v=6.2.2 By: Prakash https://blogs.mathworks.com/simulink/2013/03/18/time-to-convert-to-variant-subsystems/#comment-266300 Fri, 06 Sep 2019 10:06:01 +0000 https://blogs.mathworks.com/seth/?p=1977#comment-266300 Hi! I have the same querry as the comment 9 above. Is it replied somewhere?

]]>
By: Guy Rouleau https://blogs.mathworks.com/simulink/2013/03/18/time-to-convert-to-variant-subsystems/#comment-219418 Fri, 30 Mar 2018 17:53:07 +0000 https://blogs.mathworks.com/seth/?p=1977#comment-219418 @Jason

For other readers, Jason contacted MathWorks technical support with an example illustrating the challenge. In MATLAB R2018a, the main issue is that each level of Masked Subsystem needs to pass the parameters needed to configure the variants to the inner level using the set_param command. That way, each inner subsystem gets notified from its parent subsystem that its mask initialization code needs to be updated.

Here is a model and library illustrating how to implement nested variants.

]]>
By: Jason Nicholson https://blogs.mathworks.com/simulink/2013/03/18/time-to-convert-to-variant-subsystems/#comment-219398 Thu, 29 Mar 2018 19:35:14 +0000 https://blogs.mathworks.com/seth/?p=1977#comment-219398 Hey Guy. I know this is an old thread but I still think it is relevant.

I am a blockset author similar the authors of “Aerospace Blockset” and “Powertrain Blockset.” I build mathematical models of hydraulic pumps used in offroad vehicle models. The products I model have a high amount of configuration. Possible combinations are something like 1e6 or more but only about 1e3-1e4 configurations are used in practice. Using a Simulink library seems the most appropriate way to maintain my mathematical models. With a library, it is general bad practice to use the base workspace because of conflicts with other copies of the library in a single Simulink model file. Variant Subsystems depend on the base workspace or a data dictionary usually. Libraries cannot use data dictionaries I have learned. Variant Subsystem requires configuration one of three ways:

1. Variant object or Parameter object in the base workspace or data dictionary.
2. Conditional expression that can be evaluated from variables in the base workspace.
3. Or using the “OverrideUsingVariant” with set_param configure a Variant subsystem.

I do not want to use the first two ways because they require the base workspace or data dictionaries which I have already established I cannot use. Therefore option 3 is my only option. There is a problem that I ran into. You cannot configure nested variant subsystems except from above or at the top level variant subsystem. i.e. If you have 4 levels of variant subsystems nested, level 1 (or above) must configure level 2, 3, and 4. I would prefer to do the configuration of level 3 from level 2 because of the flexibility that allows. Configuring multiple levels from the top level makes changes have very broad reaching effects. When I must configure using OverrideusingVariant down 4 levels, any change to the name or location of the blocks between 1 and 4 breaks the chain of configuration at the top level. This is not desirable. This is painful.

So finally.
1. Is this an appropriate place to use a configurable subsystem” instead of a Variant Subsystem?
2. Thoughts or approaches to manage high levels of configuration in a library model?

]]>
By: fl https://blogs.mathworks.com/simulink/2013/03/18/time-to-convert-to-variant-subsystems/#comment-61092 Mon, 31 Mar 2014 13:56:12 +0000 https://blogs.mathworks.com/seth/?p=1977#comment-61092 Hi all!

I have tried a similar approach as described in
https://www.mathworks.com/matlabcentral/answers/91562-how-can-i-set-the-variant-object-of-a-variant-subsystem-block-based-on-the-current-value-of-a-mask-p
except the fact, that the user of the masked block is also allowed to enter a variable as mask parameter (not only a value itself). This variable lies in the

base workspace and contains the value which is used to select the appropriate subsystem variant.

Therefore I use the ‘evalin’ function to evaluate the passed variable inside the callback function of the mask parameter.

So far, everything works just fine: The current active variant is changed, as the user of the masked block changes the corresponding mask parameter.

The only problem is, that if the VALUE of the passed varialbe does change in the workspace, the callback function of the mask parameter is not executed and thus

the active variant is not updated.

My first idea to solve this problem was to use the ‘InitFcn’ callback of the masked block instead of the callback function of the mask parameter, which should be

executed BEFORE the simulation starts.
When trying this, i get following error:
‘attempted to change the active variant during simulation. The active variant must be configured before the simulation is started’

Another approach was to use the initialization callback function of the mask, which produces the same error.

Then I tried the LoadFcn callback of the masked block, which does it’s job fine, but this is very inconvenient, since every time the corresponding workspace

variable changes, the model would have to be loaded…

Thank’s in advance, I appreciate any help!

PS: the reason why I don’t select the active variant through a workspace variable directly is, because I do not have control over the base workspace, i.e. the

variable holding the information about the variant to select, can have any name and can lie within an arbitrarily structured object, struct, etc.
That’s why I prompt the user of the masked block to specifiy a workspace variable and then perform the evalin function.

]]>
By: John B. https://blogs.mathworks.com/simulink/2013/03/18/time-to-convert-to-variant-subsystems/#comment-45562 Fri, 01 Nov 2013 15:23:15 +0000 https://blogs.mathworks.com/seth/?p=1977#comment-45562 @Jason:

You can have the mask initialization callback, which has access to variables in the mask workspace [1], use one of these variables to set the ‘OverrideUsingVariant’ parameter. This could be as simple as:

set_param(gcb,’OverrideUsingVariant’,MyMaskVariable)

where ‘MyMaskVariable’ is a regular mask parameter, or you could add logic to select from available variants based on the values of your mask variables.

I agree that the current implementation is more convoluted than it needs to be. The way I see it, a given variant subsystem must have one and only one active variant at a time. Why not just have an ‘ActiveVariant’ parameter that is a ‘popup’ type, with the choices being a list of block names (or a ‘VariantName’ parameter) of the available variant blocks? This enforces the “one and only one” aspect of variants, and is far simpler than the current implementation. With the ‘popup’ type control, you could use logic to set the parameter value using base workspace values, other parameters, etc., either in the mask initialization, or in a model callback. And as a standard mask parameter, it could be promoted to a parent system, etc. [2].

To me, this would be both simpler and more flexible than having to spread the selection logic among multiple Variant Controls, and having to store and load Simulink.Variant objects separate from the model. For example, what happens if the boolean conditions in the Variant Controls are not mutually exclusive, or there is a case where they all evaluate to |false|? I would much rather put all the selection logic in one place (mask initialization or model callback), where it is far easier to catch logic errors.

Notes:
[1] You can access base workspace variables in the mask initialization by dereferencing them in a mask parameter (e.g. create a parameter BaseWSReference, with its ‘Evaluate’ attribute enabled, and its value set to the name of the base workspace variable you want to access.)

[2] I have unsuccessfully tried to promote the ‘OverrideUsingVariant’ parameter of a variant subsystem to its parent’s mask, but it appears that the variant-related parameters are non-standard parameters that cannot be promoted.

]]>
By: Jason S. https://blogs.mathworks.com/simulink/2013/03/18/time-to-convert-to-variant-subsystems/#comment-40032 Mon, 12 Aug 2013 17:17:19 +0000 https://blogs.mathworks.com/seth/?p=1977#comment-40032 John: I’m having the same issue, and it’s really frustrating to have to jump through all these hoops.

Variant subsystem selection needs to have some method of accessing to the mask workspace instead of the base workspace. I’m working on blocks for a library which is being used by some customers of ours. So I have no control over the base workspace contents. It’s up to the end users, and it’s also up to the end user how to configure their variants, on a case-by-case basis (i.e. individual instance of a library block).

]]>
By: John B. https://blogs.mathworks.com/simulink/2013/03/18/time-to-convert-to-variant-subsystems/#comment-24646 Thu, 11 Apr 2013 14:38:21 +0000 https://blogs.mathworks.com/seth/?p=1977#comment-24646 A quick followup note for future reference:

The error I described in the previous comment when trying to use subsystem variants with library blocks was caused by my forgetting to enable the ‘Allow library block to modify its contents’ parameter. This can be set in the Mask Editor -> Initialization tab, or via the command line using: set_param(gcb,’MaskSelfModifiable’,’on’).

When this parameter is set correctly, everything works as advertised.

@Guy: thanks again for your help.

-John

]]>
By: John B. https://blogs.mathworks.com/simulink/2013/03/18/time-to-convert-to-variant-subsystems/#comment-23507 Mon, 25 Mar 2013 19:18:22 +0000 https://blogs.mathworks.com/seth/?p=1977#comment-23507 @Guy: Thanks for the link – that behavior is very close to what I’m looking for. I think in many cases it could work for us, except for the following twist: Some of our library components (blocks) are made up of several subsystems (also library blocks). I would like to be able to use variant subsystems to implement our various model versions for each of these subsystems. For example, I have a masked library block named ‘ABC’, which contains subsystems ‘X’ and ‘Y’, which are also instances of library blocks. I have three variants of X and two of Y: X_std, X_nlin, X_null, Y_std, Y_nlin. My model then contains multiple instances of ABC : ABC001, ABC002, etc. In general, each instance of ABC has different active variants of its X and Y subsytems for a given run. So ABC001 might have X_nlin and Y_std, while ABC002 has X_null and Y_nlin.

The method described in the link you posted does not work for subsystems inside of a library – I get the following error:

Error evaluating ‘MaskCallback’ callback of (mask) ‘(model name)/ABC001’.
Attempting to override parameters of ‘(model name)/ABC001/X_variant_subsystem’ which is inside a library link.

So it looks like the best I can do is to create a set of library blocks corresponding to each combination of X and Y variants: X_std and Y_std, X_nlin and Y_std, etc., and then use a variant subsystem block containing each of these permutations as the library block that gets instantiated in the model. The drawback here is having to maintain a lot more block diagrams (5 for the subcomponent variants plus 6 for each of the permutations), instead of just 6 (1 for the component plus the 5 subcomponent variants).

P.S. Our models are structured this way because they consist of many instances each of a large set of library blocks (500 to 1000 total blocks). The models and libraries are designed such that the block connectivity does not change for any of the possible variants – the variants only modify the block’s internal behavior during a simulation. Changing the connectivity between components is handled by creating different models, while all of the control of component behavior is handled via block parameters. Hence the interest I have in implementing variant subsystems in a way that is similar to block/mask parameters – basically, keeping connectivity/topology (external) and component behavior (internal) separated.

To handle the large number of parameters needed, I have a single struct in the base workspace, with a field for each component: params.ABC001, params.DEF123, etc. The blocks all have a mask parameter ‘ComponentParameters’, that is set to point to the corresponding field of ‘params’ (so get_param(‘myModel/ABC002′,’ComponentParameters’) returns ‘params.ABC002’.) Ideally, I would have the parameter struct for each component contain fields that define its active variants: params.ABC001.X_variant = ‘X_nlin’, params.ABC002.Y_variant = ‘y_std’, etc., and the desired variants would simply be determined by setting these fields in the base workspace before a model run – no mask callbacks or set_param() calls would be needed.

Thanks again for the info, and for all of your informative blog posts.

-John

]]>
By: Guy Rouleau https://blogs.mathworks.com/simulink/2013/03/18/time-to-convert-to-variant-subsystems/#comment-23502 Mon, 25 Mar 2013 16:47:07 +0000 https://blogs.mathworks.com/seth/?p=1977#comment-23502 @John: Thank you for the additional details.

Did you try the approach described in the following solution:

https://www.mathworks.com/support/solutions/en/data/1-HH9JAJ/index.html

Using the “OverrideUsingVariant” property, the variant subsystem behaves very close to the old configurable subsystem.

Please let me know if this does not behave as you are looking for.

]]>
By: John B. https://blogs.mathworks.com/simulink/2013/03/18/time-to-convert-to-variant-subsystems/#comment-23497 Mon, 25 Mar 2013 15:27:55 +0000 https://blogs.mathworks.com/seth/?p=1977#comment-23497 @Guy: Thanks for the info. I updated to 2013a, and it behaves as described, which is a big improvement over having to create Simulink.Variant objects in the base workspace.

Unfortunately, for my projects, it looks like variant subsystems still lack the flexibility we need. Our models contain multiple instances of masked library components. To accommodate different simulation scenarios, many of these library blocks have several different versions (high fidelity (nonlinear), low fidelity (linearized), null/constant (for unused sections of the model), etc.). So for a given simulation, I might want the blocks in Subsystem A to use the high-fidelity variant, Subsystem B to use low-fidelity, and Subsystem C to use the null version. In my opinion, the best way to implement this would be to have the library blocks each contain a variant subsystem, with the condition being determined by the value of a mask parameter. Then, different instances of this library block in the model can have different active variants, controlled by setting the value of the mask parameter (either directly or having the mask parameter point to a workspace variable). In my case, it would end up pointing to a field within a large parameter struct that we use to hold all of our model parameters in the base workspace.

However, I get Simulink errors when I set a variant control to point to a mask parameter – it looks like they can only refer to a base workspace variable. This precludes having different instances of a library block use different active variants at runtime, unless I am not understanding something. The older ‘Configurable Subsystem’ blocks have the ‘BlockChoice’ parameter, which can be set for instances of library blocks. But I haven’t found a way to make this parameter point to a workspace variable, so it can only be changed for a given simulation run via set_param() for each block instance.

Anyway, I appreciate the enhancements in R2013a. If you have any thoughts or questions about my particular use-case, I’d be happy to discuss it further.

-John

]]>