Integrator State Port: Why is its use restricted?
8 visualizaciones (últimos 30 días)
Mostrar comentarios más antiguos
Hello.
I'd like to know why the use of the Integrator Block's State Port is restricted (and I have some more questions, see below). Here's the long story:
What I want to do
I'm trying to write a Simulink block that computes the arithmetic mean value of a continuous input signal over some period of time. In general, beginning and end of a period are given by an external trigger signal, but in this minimal working example for simplification I use a Pulse Generator as a trigger signal (constant period every 1 second). Every rising edge marks the beginning of a new period and also the end of the previous one. Additionally, I use a Triggered Subsystem to sample the computed mean value and hold it until the next period is over.
To compute the mean value I integrate the given signal and divide it by the period length (which is equal to 1 here, so I left that out). The integrator is reset at the beginning of every period. The integrator state at the end of a period is the result I'm looking for.
First attempt
My first solution looked like this:
This doesn't work as naively expected because the integrator reset occurs before the Triggered Subsystem can copy the result. So the result is always zero:
I think I understand this behavior, therefore no questions so far ...
Second attempt
My second solution involved the integrator's state port. The Integrator Block documentation states:
"[...] If the block is reset in the current time step, the output of the state port is the value that would have appeared at the block's standard output if the block had not been reset. The state port's output appears earlier in the time step than the output of the Integrator block's output port. [...]"
This doesn't work either. Simulink throws an error:
"State ports can only be used to break algebraic loops or to "hand-off" states between systems. Use the output port rather than the state port of 'model/Integrator' as the source of the signal routed (either by direct or virtual connection) to 'model/Triggered Subsystem' "
The Integrator Block documentation also tells me that the use of the state port is restricted to only two special scenarios, stating:
"When updating a model, Simulink checks that the state port applies to one of these two scenarios. If not, an error message appears."
So my first set of questions is: Why is this an error? Is there a technical necessity? Is there a problem I don't see yet?
Third attempt
One of the mentioned two special scenarios where I'm allowed to use the state port is the case of a self-resetting integrator. So I tricked Simulink to believe that that's what I'm doing. I added two Gain blocks and a Sum block which should not change anything.
Now I don't get any error messages and the model works perfectly as expected (the mean value of a constant 1 signal over 1 second is equal to 1; the result is output for the first time when the first period ends, which is at t=1):
So my second set of questions is: Why does this work, although the former example doesn't? Does this solution have any hidden disadvantages, apart from its obvious ugliness? Is it more difficult for the variable-step solver, the zero-crossing detection or any other part of the simulation? Is there any reason why I shouldn't use this solution? Could I get wrong results in a "less minimal example" context?
And my third, only supplementary question: Is there an even better way to solve the problem? (I already tried manual (trapezoidal rule) integration using memory blocks but that's less accurate and also somewhat ugly)
0 comentarios
Respuestas (2)
Paul
el 10 de Jun. de 2020
Editada: Paul
el 10 de Jun. de 2020
Only answering the third, supplementary question ....
I think I was able to do what you want without using integrator reset at all. Just let the integrator run and use the triggered subsystem to sample, and store, the integrator output at the boundaries of your intervals and compute the average. I implemented your original block diagram, but without the reset on the integrator. The triggered subsystem is:
The delays and the digital clock all have sample time of -1. Both delays have an initial output of 0, though you might want to use a different value on the clock delay to avoid potential for divide by zero if the trigger hits at t=0. Set the initial output of the output port to 0.
Here's the result I got using a sine wave as the source input.
8 comentarios
Paul
el 23 de Jun. de 2020
Here's a modification that might have more appeal, though I'm sure it has some limitations somewhere. The idea is as follows. Use the hit crossing to do two things:
Trigger the average system as has already been done.
Trigger a separate subsystem that computes a future time (from the time of the hit crossing detection) that you can use to reset the integrator.
This way the trigger only depends on the solver catching the hit crossing and you can control how much of the interval that you're going to miss at the start of the window.
Here's the model:
The Average block triggers on the hit crossing as does the Reset Time block, which is:
All the reset time block does is compute a small offset from the time of the trigger that is the time to reset the integrator. The inital output is set to zero.
When sim clock >= reset time, the integrator resets (rising). As you can see, I made the time offset 1e-8. I'd not be surprised if problems arise if you make that offset too small, but I didn't experiment. Anyway, here's the output:
So far the only odd thing I've noticed is that the solver takes a lot more steps to integrate through some reset times than others. For example, it seems to get through t = 3, pretty quickly:
>> out.tout(45:55)
ans =
2.482494474052150e+00
2.682494474052150e+00
2.882494474052150e+00
3.000000000000000e+00
3.000000009999972e+00
3.000000010000000e+00
3.000000010000028e+00
3.050000000000000e+00
3.099999989999971e+00
3.199999969999914e+00
3.399999929999800e+00
But a lot more steps to get through t = 4:
>> out.tout(55:85)
ans =
3.399999929999800e+00
3.599999929999800e+00
3.799999929999800e+00
3.999999929999801e+00
4.000000000000000e+00
4.000000009999943e+00
4.000000010000000e+00
4.000000010000057e+00
4.000000360001054e+00
4.000000710002051e+00
4.000001410004045e+00
4.000002810008033e+00
4.000005610016010e+00
4.000011210031963e+00
4.000022410063869e+00
4.000044810127682e+00
4.000089610255308e+00
4.000179210510558e+00
4.000358411021060e+00
4.000716812042064e+00
4.001433614084070e+00
4.002867218168084e+00
4.005734426336111e+00
4.011468842672165e+00
4.022937675344273e+00
4.045875340688489e+00
4.050000000000000e+00
4.070623296557556e+00
4.141246583115055e+00
4.282493156230053e+00
4.482493156230053e+00
I don't know what's going on here, but I did notice that when I made the pulse generator period 1.1 sec the solver took about the same, small number of steps to integrate through each reset time.
Jonas
el 17 de Jun. de 2020
"This doesn't work as naively expected because the integrator reset occurs before the Triggered Subsystem can copy the result. So the result is always zero:"
Maybe you can add a Unit Delay in front of the Integrator reset, such that the triggered subsystems is triggered one sample earlier than the Integrator is reset.
2 comentarios
Jonas
el 17 de Jun. de 2020
Ah indeed, my mind was fixed on discrete time simulation. I have too little experience with continuous time simulation to answer your questions.
Good luck!
Ver también
Categorías
Más información sobre Sources en Help Center y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!