Repository navigation
Output calcs produce 0's at every other call #1009
Description
Activity
The reason you are seeing the alternating pattern is that when you have an interconnected system, you have to propagate the external inputs through the block structure before computing the derivative (or the final output). This is implemented in the
InterconnectedSystem._compute_static_iomethod.Generally, the idea is that you take the external inputs and compute the outputs for each of the subsystems. Any subsystem that was connected to the external input and had a feedthrough term (eg, nonzero D matrix) will now have a different output vector (which you couldn't know until you propagated the input through). If any of the outputs changed, you need to compute the outputs again, until you either stop getting changes or you determine there is an algebraic loop (which you can do by limiting the number of interactions to the number of subsystems).
For your example above, the first thing that happens is
_compute_static_iocomputes the outputs for all of the subsystems, which is based on the current state (empty in your case). At this point in time, we don't (yet) know what the internal inputs are, so anything that is not an external input is just set to zero. In your example above, this means thatinput_sysgets called with no inputs and thenoutput_sysgets called with one input (set to zero => you see a zero printed). Once we know what all of the outputs are for the subsystems, we can then call the output function again, this time with the proper input (set to 1 => now you see a one). Since the system inputs haven't changed on this second call (input_syssent out a 1 again), we know we are done and so we can proceed to compute the derivative and/or output.There might be a better way to implement this, but I think that in any case you have to call the output functions multiple in order to propagate external inputs through the interconnected system.
Gotcha, thanks for the thorough explanation. I was recently working on something similar to python-control (then switched to python-control as soon as I found it!) where I re-arranged the list of subsystems to compute things in a 'causal' order (line 204 here: https://github.com/corbinklett/modsim/blob/main/modsim/main.py). Not sure how easy it is to scale or generalize this. Definitely interested to see how others solve it!
I've noticed that subsystems can produce outputs = 0 on every other call to a system's output function. The final result of the simulation is correct; however if you are doing something like processing quaternions in the output function, a quaternion of all zeros is invalid and an error results (without some hacky handling of that situation).
In the code below, line 1 printouts alternate between 0 and 1 rather than printing 1 at each call.