Guy and Seth on Simulink

February 15th, 2009

Where Does That Variable Come From?

Most Simulink models use workspace variable to define the important parameters.  For example, setting the gain value to K and then defining K in the workspace.  I wrote about initializing these parameters in the base workspace in a recent post.  Have you ever noticed that there are many sources for these parameters?  The value of K might be in the base workspace, or it could be in the model workspace.  The source of K could even be in a mask.

Simulink determines the value of a variable by searching in the workspaces above the block that uses the variable.  Starting from the block, it searches each mask workspace up the subsystem hierarchy until it reaches the root of the model.  Simulink searches the model workspace and the base workspace last, respectively.  This process is hierarchical symbol resolution, and in this post, I will demonstrate these rules that determine how Simulink resolves the value of a variable.

An Example Model

To illustrate the concepts of hierarchical symbol resolution, let’s use a simple model (Download here).  This model consists of nothing but subsystems, constant blocks and displays.  The constant blocks refer to variables in different workspaces and get their value based on where they are in the hierarchy.  Starting at the root of the model, we find the variables k and m.

Variable Resolution Simulink model.

Look in the Workspace above the Block

I think of the model workspace as being at the root of the model.  The model workspace is the first place to search for k and m.  I use the Model Explorer to see the contents of the model workspace.

Model explorer showing the model workspace.

We have found k, but m is not in the model workspace.  The next workspace up in the hierarchy is the base workspace.  The model explorer conveniently shows a tree that reflects the model hierarchy.

Model explorer showing the base workspace.

Mask Workspaces

Masked subsystems introduce mask workspaces in the model hierarchy.  If the block is in a masked subsystem, it first evaluates in the mask workspace then works its way up through the hierarchy until it reaches the root of the model.  Here is the Top subsystem.

Top subsystem, top subsystem mask and the contents of the system.

The mask dialog initializes the variable m with a value of 3000.  The variable k is also appears at this level of the model, but resolves to the variable defined at the model workspace level.

Subsystems Inherit Variables from Their Context

Because of hierarchical symbol resolution, subsystems inherit variables from their context.  The Bottom subsystem refers to k, which comes from its mask.  It also refers to m, which is resolved in the Top Mask.  If the Bottom subsystem were at the root of the model, m would resolve to the base workspace.

Bottom subsystem, bottom subsystem mask and the contents of the system.

This behavior can make the same library blocks behave differently depending on their parent system.  For example, a pendulum subsystem may inherit the acceleration due to gravity (g) from its parent system.  These parent system may define variables for different environments.

A subsystem hierarchy that would allow inheritance of the variable g based on context.

Controlling Hierarchical Resolution

You can control the resolution of variables in your subsystem by setting the Permit hierarchical resolution parameter in the subsystem parameters (right click on the subsystem and select Subsystem parameters…).

Subsystem parameters, Permit hierarchical resolution.

The default setting is All and gives you the behavior described above.  If you don’t want variables to resolve to symbols defined in the hierarchy above your subsystem you can change this to None.   The ExplicitOnly setting controls resolution of signal and state names by only resolving objects that have been set to resolve explicitly.

What about Model Reference Hierarchy?

Hierarchical symbol resolution stops when it gets to the root of the model.  Model reference hierarchy is not considered as part of hierarchical symbol resolution.  Any model must be able to define itself stand alone, or as part of a larger model reference hierarchy.  It is possible to pass variables down into a model workspace through the model reference arguments.  For more on that, see documentation about using model arguments.

Now it’s your turn

If you program in M-code than you might see discussion as similar to the way variables are resolved in nested functions of an M-file.  Do you take advantage of hierarchical symbol resolution?  Leave a comment here and tell us how.

18 Responses to “Where Does That Variable Come From?”

  1. John replied on :

    Seth,

    Is it possible to see the mask workspace variables from the model explorer?

    Thank you,
    John

  2. Anand Rangaramu replied on :

    Seth,
    I have .m files where I define the variable and its values. I refer this .m file in the Init function of the model properties. In this method all the variables wil be added to global workspace. (I mean i can see the variables on workspace screen). Is there anyway I can avoid listing these variables visible to the main matlab workspace.

    Thanks

  3. Seth replied on :

    @John – the model explorer doesn’t provide a view into the mask workspace, but it is possible to explore what variables exist. Try: get_param(gcb,’MaskWSVariables’)

    @Anand Rangaramu – When the M-file runs in the Init function, it is run in the base workspace. You could instead run the file to initialize the model workspace. Set the Data source to M-code and run your file there. This will populate the model workspace and avoid cluttering the MATLAB Base workspace with variables only used by this model.

    Check out the Model Workspace documentation for more details.

  4. John Reilly replied on :

    Hey Seth,

    I posted this in the newsgroup, but it is germane to this entry:

    I’m creating a Simulink library in R2007b. I have a masked Failure Detector (FD) block in my library. It has some initialization code that checks parameter values and calculates some child block parameters. It works fine.

    I’m creating another masked block, Adaptive Controller (AC), that contains the FD block as a child. The AC block has a mask parameter variable, p_fdGain. Under the AC mask, just like I’m doing with built-in blocks, I set the FD block’s gain parameter (in the dialog) to the AC mask variable string, “p_fdGain”. The parent AC block’s p_fdGain is set to a valid value, 5.0.

    I was expecting that the child FD block’s mask initialization code would evaluate “p_fdGain”. That does not happen. My child FD block’s initialization script throws an error because it can’t evaluate. get_param() returns the string ‘p_fdGain’, which is a variable in the parent block’s mask, but I can’t evaluate it with either evalin(‘base’), evalin(‘caller’), eval() or in the model workspace (e.g. get_param(bdroot, ‘modelworkspace’)).

    What gives? This *HAS* to work. I can put a simple Gain block in my AC subsystem, set the gain parameter to “p_fdGain” and it works. The online docs for the latest Simulink addresses this situation and seems to imply that it will work. Of course, the R2007b docs don’t seem to contain those particular pages.

    Thanks.

  5. John Reilly replied on :

    Hi Seth,

    Never my my question above. After rooting hard in the online documentation, I found that the “Understanding Mask Code Execution” topic solved my issues. I was updating the child blocks and dependent parameters in the callbacks, which is verboten. Now I understand that the callbacks run in the base workspace and the initialization routine runs in the mask workspace, which explains my issues. (I took the sample from this article as a simplified experimental system.)

    I was trying to put parameter validation in the callbacks so that my users would be notified of an error as early as possible. This is the typical paradigm in UI design, but doesn’t work so well in Simulink.

    Thanks.

  6. Seth replied on :

    @John Reilly – Great work answering your own question! Many people have run into that problem before. I’m glad the doc section written to help with this, did as intended.

    Some types of parameter validation can be done using Dialog Callbacks, but that code is not triggered when using set_param() to change values. Thanks for continuing this discussion here.

  7. Jack replied on :

    Seth
    When I try get_param(gcb,’MaskWSVariables’) under Matlab2006b, I get empty struct. Is there another way to evaluate litteral parameters initialized from parent subsystem ?

  8. Seth replied on :

    @Jack – Have you updated the diagram? I think that parameter will only be non-empty after MaskInitialization code has run once (also, your mask needs to have variables in it).

    The parameters in the parent system should be available to be parameters in blocks under that system. For example… imagine model/top is a masked subsystem with parameter k. The top mask dialog prompt could be set to 5. If k is set to evaluate the parameter, inside model/top, instances of k will have the value of 5. A gain block: model/top/gain could have a gain value set to k in the dialog. This would pass down from the top mask, into the gain block. No code required.

  9. Jack replied on :

    I know that the value is passed without code but if I want to retrieve my parameter value to make data range check validity, how can I do it ?

    Thanks for your answer

  10. Vipul replied on :

    Hi Seth,
    I have a two column (time and signal value) array in my base workspace. I am trying to read this array with ‘From Workspace’ block in my model. I can read it but it gives me only one of the column value (signal value) from array. I would like to use the value from first column (time) based on certain conditions. Unfortunately, with this block I can not read time value (first column). Is there any specific way to do that? Am I using wrong block?
    Thanks.

  11. Guy replied on :

    Hi Vipul,

    As the doc says for the From Workspace block, the first column is the time stamp at which the data of the other columns is outputted.

    One quick solution if you want the From Workspace block to output also a time signal is to create a 3 columns matrix where you will have [t t u]. However this might not be the best solution.

    Another way to think about it is that if you want time as a signal in your simulation you should use the “Clock” or “Digital Clock” block from the Sources section of the Simulink library.

    I hope this helps.

    Guy

  12. Vipul replied on :

    Hi Guy,

    I appreciate your response. I can not use 2nd suggestion of using “Clock” or “Digital Clock” block because the time in my data comes from data acquisition system. Actually this is a PWM type signal and I am trying to determine the time between two successive signal rises. If I used your first suggestion, the problem arises when I try to find rising or falling edge of the signal. A topic on simulink ‘From Workspace’ block with example would be worth discussing here.

    Thanks,
    Vipul

  13. josy replied on :

    how can i place empty subsystem in my model

  14. josy replied on :

    how can please answer me how to place empty subsystem in my model.
    josy_cp@yahoo.com

  15. Amy replied on :

    I have a tangentially related question. Is there a way to set the gain to a variable that is defined by inputs to the model? I’m running a simulation that receives streamed data from a separate computer during execution, and I’d like to stream the gain settings in real-time. I know I can just define my own gain block that does this calculation manually, but I was just curious if there was a way to use the built-in gain block. Thanks!

  16. Guy replied on :

    @Amy,

    It is feasible to set the gain of a Gain block based on the value of another signal. However I do not recommend doing that. Typically in Simulink you have to types of data:

    - Signals: Intended to change every time step
    - Parameters: Intended to change not frequently

    Trying to set a parameter every time step is using it as a signal. Parameters are not designed to change every time step and doing that can sometimes lead to unexpected behavior.

    The recommended approach is, as you mention, to implement your algorithm with signals for values changing every time step. For your example, it means using a Product block instead of a Gain block.

    I hope this helps.

    Guy

  17. liang replied on :

    UNABLE TO EVALUATE WORKSPACE PARAMETER

  18. Amy replied on :

    @Guy,

    Thanks for the tip. I suspected that was the best option, but I’m not as familiar with the way Simulink works and wanted to be sure I was doing the calculations optimally.

    Best,

    Amy

Leave a Reply

Wrap code fragments inside <pre> tags, like this:

<pre class="code">
a = magic(3);
sum(a)
</pre>

If you have a "<" character in your code, either follow it with a space or replace it with "&lt;" (including the semicolon).


MathWorks
Guy Rouleau and Seth Popinchalk are Application Engineers for MathWorks. They write here about Simulink and other MathWorks tools used in Model-Based Design.

These postings are the author's and don't necessarily represent the opinions of The MathWorks.