Guy and Seth on Simulink
March 8th, 2011
How Do I Change a Block Parameter Based on the Output of Another Block?
By Guy Rouleau
One question I often receive is:
How can I change the value of a block parameter while the simulation is running?
A good example of this type of question is the following: How do I model a transfer function with coefficients that vary with simulation time in Simulink?
Every time I receive this question, I end up explaining the difference between block parameters and signals in Simulink. Here is how I explain it:
Data
In many scripted languages like MATLAB, data is stored in variables. Whether the data changes frequently or not, it is still data stored in a variable and the programmer can change it whenever he wants.
In Simulink, this is different. Simulink is a tool designed to simulate the response of dynamic systems over time. To do this efficiently, data is divided into 2 categories: Signals and Block Parameters.
Signals
In Simulink, a signal is a piece of data intended to change frequently, possibly every time step. You can find a detailed definition of signals in the Simulink documentation:
Block Parameters
A block parameter is an attribute of a block. Some block parameters, especially mathematical parameters, can be defined as tunable parameters. It is possible to change the value of a tunable parameter while the simulation is running from the block's dialog parameter, the model explorer, or using the set_param command.
Why not changing block parameters every time step?
Based on the information above, many people try to implement a MATLAB-file S-function or an Event Listener that call set_param to change the tunable parameter of another block at every time step. This can work, however, there are some major drawbacks. (Including the fact that Simulink is not intended to be used this way!) Each time you call set_param on a model, Simulink re-evaluates block parameters, and depending on how many get evaluated, this can be slow. Using MATLAB calls to set_param also preclude the model from ever being compiled into a real-time application.
In my opinion, the biggest problem is that when you use set_param to change a block parameter based on the value of a signal, you hide data dependencies from Simulink.
During model compilation, Simulink determines the sorted order of blocks. This sorted order is based on the data dependencies defined by signals. To ensure that your model behaves as you expect, you must tell Simulink what dependencies exist between your blocks. (This is done by passing the data through signals!)
What can I do if I really need to change the parameter of a block every time step?
The approach I recommend is to implement your algorithm using signals and basic blocks. For example, instead of using a Gain block, use a Product block:

or if you need a sine wave with tunable amplitude, frequency and phase, build it with basic blocks:

I agree that those examples are relatively simple. But even for more complex examples it is usually not too difficult to make your custom subsystem.
Finally, if there is a block parameter in the Simulink library that your application would require to be a signal, I recommend contacting technical support about it. Our engineers will be able to guide you in the right direction and submit an enhancement request to our development team.
An example of a block whose parameter can also be an input signal is the Direct Lookup Table (n-D). At every time step, you can change the table data if you enable the 'Make table an Input' option.
Now it's your turn
What block parameters do you want as a signal? Leave a comment here with your suggestions
By
Guy Rouleau
19:50 UTC |
Posted in Modeling, Parameters, Signals, Simulink Tips |
Permalink |
14 Comments »
You can follow any responses to this entry through the RSS 2.0 feed.
You can skip to the end and leave a response. Pinging is currently not allowed.
Leave a Reply
|
@Guy, There is probably furhter limitation with set_param/event_listener if model is intended for code generation. I have to say that the signal-parameter separation is not as natural to software engineer as to control engineer.
@wei Software engineers that treating parameters different than signals is something we’ve struggled with. They are just so used to swapping a pointer to get a different parameter set.
Unfortunately, we have not gone down the suggested route. We had custom storage classes that let users select among parameter sets before initialization. Then the users wanted to select at runtime, and that was easy to do by just relaxing the restrictions on when the pointers could swap. Then the users wanted simulation behavior to match, and that was possible using the set_param/event trigger/model update mentioned.
We did investigate using signals instead of parameters with changing values. The problem wasn’t with blocks that didn’t accept signals, but with finding efficient parameter value selection logic. The custom storage class allows only the pointer to remain in RAM, and combinations of switch and bus selector blocks just seemed to want to copy lots of data to RAM, sometimes multiple times if the winnowing occurred in several stages.
Could someone describe a typical use-case or two that demonstrates the utility of tuning a block parameter during simulation?
@Paul, I seem to remember doing this for some built-in blocks that don’t yet have the option to add an optional extra input to affect some internal operation of the block, like some of the more sophisticated blocks do.
@Wei, you are right. set_param and event listener are not compatible with code generation.
@Bob, thank you for sharing your experience. It is interesting to see how you used set_param and event listeners to mimic the behavior of a customization you made to the generated code.
@Paul, the canonical need to tune block parameters during simulation (or running of actual code) is to schedule things like transfer function coefficients in your controller (or plant model) as a function of things in the environment. For example, assume you’re doing aircraft flight control: the plant (the aircraft) can vary enormously over its flight envelope, so you often have to design controllers that vary their characteristics – say a structural notch filter that has to vary with aircraft weight. So you need to have the filter coefficients vary with aircraft weight. Currently the only way to do this sort of thing in a way supported by code generation is to do what Guy suggests and build these filters out of basic blocks.
Interestingly enough, of Matlab/Simulink’s two competitors MATRIXx/SystemBuild and EASY5, only EASY5 supported this capability, and it had no support for code generation, at least in the timeframe (mid-80′s to early-90′s) that I used it. I did the same workarounds in MATRIXx/SystemBuild that I now do in Matlab/Simulink; the problem has not gone away.
I wish that the Mathworks would make, for example, transfer function coefficients be optional inputs. But there are other fundamental problems with the Simulink TF blocks, most notably that they don’t support setting the initial output, that causes us to have to roll our own regardless…
@KMR, thanks for the feedback. However, I don’t think this example justifies the need for Simulink to support block parameter tuning. When I’ve needed to schedule controllers in Simulink, I did exactly as you described, i.e., wrote my own subsystem that takes the control gains as inputs after they’ve been computed elsewhere. I don’t think of this as parameter tuning; I think of this as how the controller design is implemented. To me, parameter tuning means changing the value of the parameter outside of the simulation equations themselves, which I have never wanted to do.
OTOH, my concern is that there are some (a lot of?) costs for Simulink to implement block parameter tuning. But I have yet to see an example where the ability to tune block parameters during a run is the only solution, or even a solution that far outweighs alternatives in terms of implementation complexity, that justifies these costs. For example, I’ve always wondered how much time is spent during a simulation checking for changes in block parameters. Suppose one has a huge matrix as a parameter in a table look-up block. How much time does Simulink spend determining whether or not the table has changed during a run? I’ve had some experience that suggests it’s not trivial; see #5 here http://blogs.mathworks.com/seth/2010/12/06/5-resources-for-simulation-performance/ (can’t know for sure because I don’t know exactly how Simulink works).
BTW, have you checked out any of the gain scheduling blocks in the Aerospace Blockset? I haven’t tried them myself…
@Paul J., the reason that I want the Mathworks to implement support for, e.g., driving transfer function numerator and denominator coefficients from inputs external to the TF block is specifically to be able to STOP rolling my own implementations of these blocks. That’s supposed to be one of the advantages of using Simulink/RTW! But for real systems, we do a lot of wheel-reinventing because of the lack of support of this feature.
I don’t use Aerospace Blockset, as I don’t see the value added for my organization – that’s core competency stuff for us.
@KMR, I’m not disagreeing with the desire/need to have a transfer function block with external num/den coefficients. I just don’t see the lack of that functionality as a good example of the need for block parameter tuning. If that block were provided, it wouldn’t really be parameter tuning at all, it would just be another block. But given we don’t have that block now, I’m interested in your thoughts on how best to implement that functionality. Would you roll your own block with those num/den coeff inputs? Or would you try to do something outside of the block diagram signal flow to tune the coefficients of the current TF block during a run? If the former, then it sounds like what’s really needed is a new block, not the ability to tune block parameters during a run. If the latter, why is that the preferred approach?
Slider gain’s block is the solution. It allows you to change in real time one variable. Then you can associate this variable to parameter you want to vary.
i don’t understand the role of the look up table and every parameter in its block parameters
The implementation of time-variant TF block using integrators and other basic blocks seems reasonable. However, if I feed the model with signals representing TF characteristics, for example, the damping ratio, the model seems to be excitated by changes in these signals, not only by the actual input signal.
Question: How to prevent this from happening? If I implement the time-variant model with ‘set_param’ called every time step, there’s no problem (except for extremely slow simulation).
At present I am working on a Simulation Model containing 2 subsystems in Matlab Simulink:
•Subsystem A – generates some data
•Subsystem B – reads the generated data from the workspace
Right now each subsystem is in a different Simulink file. I would run Subsystem A first. This data would be saved to the workspace and then I would run Subsystem B which reads the data from the workspace.
I would like to put these two models together in one simulation window. However the problem is that each model runs at a different simulation time. And in order to read the data form the workspace the first simulation must first stop and the variables sent to the workspace.
Is there any way to stop the simulation for the Subsystem A, therefore sending the variables to the workspace. And then Subsystem B would be executed to read from the workspace.
I tried using the trigger and enable blocks but because the simulation does not stop and send the variables to the workspace before Subsystem B is activated, Subsystem B is unable to read the data generated by Subsystem A. I have done some research and it shows that simulation must stop in order to be able to read from the workspace.
Is it therefore possible to have these two subsystems in one file sharing the same space? I would like Subsystem A simulation to start and stop, therefore sending the variable to the workspace and Subsystem B is activated automatically after the variables were sent to the workspace.
Please remember that:
•Subsystem B needs the variables generated by Subsystem A
•Subsystem B reads from the workspace
•Both subsystems have different simulation stop times
•Subsystem A must stop first in order to send the variables the workspace
I have tried using the Variant Subsystem Block. But I realized that yous still have to automatically change the value of the workspace variable when initializing the model.
Also the sim command is very useful for this project but I would rather everything be synchronized in one model rather than using a sim command
Hi.
I’m trying to tuning a transfer fcn’s parameter but I have not figure out how. If you can explain me how to use the set_param command to do it, I’d appreciate that.
I think it woulb be interesting if I can do it converting the transfer fcn into a product, but I don’t know how to do it.
Any help would be ok for me. Thanks