Hey, here I am again !
After dealing with [de/re]initialization procedures for the Scicos/FMI2 wrapper block, I guess the most likely next step would be to deal with regular updates, dealing with integration of continuous states and setting block outputs (x and y vectors, respectively).
However, due to some confusion regarding how these things work in Scilab (that my mentor Clément is helping me to clear up), I started looking at state discontinuities before that.
Inside Scicos block computational function, those cases are handled by two types of jobs:
flags | inputs | outputs | description |
---|---|---|---|
... | ... | ... | ... |
2 | t, nevprt>0, x, z, inptr | x, z | update states due to external activation |
2 | t, nevprt=-1, x, z, inptr, jroot | x, z | update states due to internal zero-crossing |
... | ... | ... | ... |
9 | t, phase=1, nevprt, x, z, inptr | g, mode | compute zero-crossing surfaces and set modes |
9 | t, phase=2, nevprt, x, z, inptr | g | compute zero-crossing surfaces |
which could be related to FMI2 API state events.
State Events
Suppose that you simulating a bouncing ball model: every now and then, the continuous and smooth movement of the falling mass have to be abruptly changed on collision with the ground, by resetting its velocity to a ascending one.
One could detect these events by keeping track of a variable (indicator) that reaches zero (or has a sign change) on the discontinuity situation (like, in this case, ball height relative to the ground). That’s why those rough state changes are also known as zero-crossings.
(Domain/sign change for state event indicator z)
So, to trigger a non-integration state update (flag 2) we can verify zero-crossings in event indicator variables (on flag 9) after each integration step, as described in the available documentation:
-
States update: This job is called when flag=2, it is called only if the block has event input. In this case, the computation function update the value of the continuous or discrete state. This flag is called only if the block has an event activation (nevprt=0), or an internal zero-crossing (nevprt=−1). In the second case a vector jroot specifies which surface has been crossed and in which direction. for exemple, if the ith entry of jroot is equal to 0 it means that there is no crossing, whereas if it is equal to +1 (respectively −1), then the crossing is with a positive (respectivly negative) slope.
-
Mode and zero-crossing: This job is called when flag=9. In this case, we set the mode and evaluate the zero-crossing. To set the mode, information about the nonsmoothness of the model must be given to the solver.
And then we try to implement that in our code:
Events Scheduling
As pointed in code comments above, Modelica blocks do not have to deal with an equivalent to Scicos blocks external event inputs and outputs:
(Xcos diagram showing the usage of event inputs and outputs, in red)
Inside a regular non-Modelica block, a external event input would be handled by StateUpdate job when its nevprt field has a value higher than 0 (which is ignored in our case), while the outputs would be generated during the Event Scheduler job (flag 3):
flags | inputs | outputs | description |
---|---|---|---|
... | ... | ... | ... |
3 | t, x, z, inptr, jroot | evout | program activation output delay times |
... | ... | ... | ... |
Again, from documentation:
- Events scheduler: This job is called when flag=3. In this case, the simulator updates the next event output time of the block.
The same way, as we also do not produce event outputs here, this job flag is just bypassed in our computational function.
That’s it for now. I guess I need to accelerate things a little now thar we’re approaching the first GSoC evaluation, so expect more posts soon.
As always, be aware that the implementation presented here is subject to change, if I get a better grasp of how things should work.
Thanks for sticking with me one more time. See Ya !