As mentioned in my previous post, I have been trying for some time to write about the new Initialize Function, Reset Function and Terminate Function introduced in R2016b. However, every time I end up realizing that I need to introduce another feature first.
Not your everyday standard block...
Let's begin with a simple model where I have a Discrete State-Space block.
I can add to the model a State Reader block, open its dialog, and select the Discrete State-Space block to read its states. Notice the diamond shaped "x" on top of the Discrete State-Space block. It is there to indicate that its states are being read somewhere else. Also, notice the block name next to the State Reader, indicating where it is reading from.
You probably also want to notice that the State Reader block is highlighted in red. This is thanks to a new feature in R2016b: Edit-Time Checking. If you hover the mouse on top of the block, you will get more details:
Hmm... What does that mean? What's wrong with putting those two blocks in the same subsystem?
As I said, the State Reader and State Writer blocks are not like every other block! Let's try to update the diagram. This time we receive this error:
For those of you reading this blog for a long time, I hope you remember a post I wrote many years ago titled How Do I Change a Block Parameter Based on the Output of Another Block?
In this post, I explained that if a block could change the parameter of another block, this would lead to unpredictable sorted order. During one time step, no one could predict if the parameter would be modified before or after the block executes.
A similar reasoning applies to the State Reader and Writer blocks. Since there is no signal connecting the Reader/Writer to the state owner, there is no explicit data dependency to enforce the sorted order. This is why those blocks can only be used in contexts where the execution order is explicitly specified by the user.
In other words, this "constraint" is a good thing, designed to make your life easier on the long run.
Let's look at those constructs where the State Reader and State Writer blocks can be used.
Mutually Exclusive Subsystems
In a manner similar to how the Clutch Lock-Up Example uses the State port of the Integrator block, it is possible to use the State Reader and State Writer block to pass states between conditionally executed subsystems.
A simple way to illustrate that is to implement the equation of two falling masses rigidly linked together; that suddenly separate. In the first part of the simulation, the motion is computed using two Discrete-Time Integrator blocks in series.
In the second part of the simulation, we use two series of Discrete-Time Integrator blocks, initialized using the State Reader block, configured to read the state of the Integrator blocks from the first part of the simulation
At the top level, the simulation looks like:
Export Function Models
Using an Export Function Model like the one described in my previous post, you can explicitly control which block executes first.
Begin by creating a model with two Function-Call Subsystems, one for the Discrete State-Space, and one for the State Reader:
You can then use this model as a referenced model, where the parent explicitly schedules the order into which the Discrete State-Space and the State Reader blocks are executed
Branched Function Call
This syntax is similar to the previous example, except that everything is in the same model.
It is important to realize that the examples above using the branched function call and the Export Function Model are too simple to really illustrate the real power of the State Reader and State Writer blocks. They are the simplest models I can think of to illustrate the usage of those blocks.