I have been developing models for VeriStand in C using the VeriStand Model Framework, but recently tried to build a model using LabVIEW.
The question I have is the following:
In the Model Framework, the model is an object - it has state (than can be kept as static global variables in C), and methods
Whereas in the LabVIEW model, these don't appear to be explicit. I am interpreting the whole LabVIEW model to be the equivalent of the TakeOneStep method (that has access to inputs and parameters and can compute outputs).
Is my interpretation correct? If so, how can a LabVIEW model have state? For example, even a simple PI controller needs to keep state.
Solved! Go to Solution.
I never build a modle using C, but I have the same understanding of how is supposed to wirk a LabVIEW model - TakeOneStep only.
The VI you build to get a model for VeriStand will be loaded in memory, and 'called' at each model loop iteration (Creating Models in LabVIEW for Use in NI VeriStand).
A quite simlple way of holding some data is to use Feedback Node (or a loop that will always stop after one iteration, with a Shift Register - very similar to a Functional Global Variable, without the Case Select). From a call to an other, as long as the instance of your model stay in memory, you can keep some data from one iteration to an other.
Thank you for the reply.
I was thinking along the same lines (I didn't know about the Feedback node, but a single iteration loop with a shift register).
However, if I initialize the Feedback node or the shift register, wouldn't it be initialized every time the model VI is called by the VeriStand engine, because the whole VI, and not just the loop or Feedback node, is executed at every call?
I wonder if the FirstCall function can be used somehow (I will try and post an update).
I also wonder if reentrancy has any role in this context.
You're on the right way, I think.
Yes, the Feedback Node / shift Register should NOT be initilalized. This way, LabVIEW will keep in memory the last value passed to the Feedback Node input. And yes, FirstCall may be used to handle the case of the first iteration of your lvmodel
If you want to check the LabVIEW code of your model, you may use a test calling VI, with a loop that will emulate the VeriStand model loop, and placing your model VI in the loop, and creating controls and indicators arround it. Each iteration will be representative of a model step (TakeOneStep). You may adjust the number of iteration (For Loop) and/or a timing function to get something that will match your test cases and expected ergonomy.
Regarding reentrancy, FGV are used as global variables, so the main goal is to limit to a single instance in memory of the FGV (the VI). For a LabVIEW model, I think your VI may be reentrant for two reason :
Moreover, the VI is beeing compiled into a lvmodel. I don't know exactly what it is under the hood, but I guess the build process is very similar to a DLL or a packed library build. I don't know what is the expected behavior of the feedback node / shift register when two instances of a VI build into a lvmodel. And I did not find (yet?) information about it. So, test it carefully...
I tried exactly as you suggested, making a subVI that would have state, and testing it with a driver VI that calls the subVI in a loop.
I realize that this is a more general question of how to keep state in a subVI, and not specific to a VeriStand model.
I used Feedback Node in the subVI to store state. Doing it with a shift register would be a bit more complicated, and involve using the FirstCall function. [For others who might read this thread, this video https://www.youtube.com/watch?v=qAh3bal4_Fk does a nice job of explaining how to get similar behavior to a Feedback Node using a shift register].
I am able to verify that I get the desired behavior.
I haven't test it with VeriStand by building it into a model, which I will do also.
I have attached the subVI and the driver VI for reference.
Thank you, Mathieu.