01-21-2010 04:38 PM
Hey all,
I have a question about Sub-vi's. When writing code, I will often find that I need to dupliate a task, such as writing PID code for a left and right drivetrain. After writing the "Left" drivetrain code, I select it all, go to Edit->Create Sub-vi (don't have the program in front of me right now, but it's something very much like that). I then copy that vi so I can control the "Right" drivetrain.
Once I start running the program, I encounter odd behavior. It seems like the two vi's are interacting with each other, where inputs to one can cause changes to the other. The only thing I can think of is that both vi's have the same local variables (since they're just copies of each other), but shouldn't that be encapsulated by the vi?
I solved the problem by saving each vi with a different name (like LeftPID.vi and RightPID.vi), which stopped the interaction (even though they have identical code), but it seems like a strange workaround.
Has anybody else had a problem like this, or understand what I'm doing wrong?
Thanks in advance,
-John
01-21-2010 04:41 PM
Just found this answer from Philbot:
Your problem is that all your insances of the VI (all the places you use it) are sharing the same data, so since it has a "memory" of past events, it's getting them all mixed up.
What you need to do is make the VI "re-entrant", which means it can be called many times simultaniously and still keep all the instances straight.
Open up your SubVI
Right Click on the VI Icon (top corner of Front Panel).
Select "VI Properties"
Expand the "Category" list and select "Execution"
Check the "Reentrant Excution" box and then ckeck "Pre-allocate clone for each instance".
You should be set.
BTW, have you saved the VI out as a logical file name like: FlipFlop.vi?
Have you also edited the Icon to make it your own (choose a color scheme and use it on all your SubVI's).
Phil.
I'll try this out, but it sounds like exactly the solution.
01-22-2010 08:46 AM
Re-entrant will change what you are seeing, but I not sure you had a problem depending on just what you were doing inside the subVI
Because what you where seeing is what is expected.
FYI before you start making ALL your sub VI re-entrant.
It seems like the two vi's are interacting with each other, where inputs to one can cause changes to the other
What you where seeing is each call to the single sub VI being call "one at a time" and each passing "their" inputs to the sub VI.
Then returning to the calling point the calculation for that point.
To save memory, LabVIEW only load a single copy of non-re-entrant sub VI and each call takes it turn in using the code.
Clicking on either of the two copies of the icon on your block diagram only takes you to the same bit of code.
This works just like a function call in C. Calling the same C function in two different places still only runs the same piece of code.
If you also watched that C function you would also see the inputs of that C function change as each call passed in their inputs in one at a time.
LabVIEW has the added feature of Re-entrants where it will create in extra memory a copy of the code for every icon on a block diagram and allow them to run in parallel.
Use Re-entrant when you NEED more than one copy of the sub code to run in parallel (the sub VI takes some time to run)
Most of the time where you have a short (quick) sub VI that takes inputs does same quick calculation and returns the answer you do not need re-entrant.
Don't use Re-entrant when you use the sub VI to store internally data that is needed in other places in your code like the motor references or joy sticks references.
Plus if your program starts to get to big for the cRIO FPGA you might want to review how and where you are using Re-entrant.
Omar
01-22-2010 12:28 PM
Two clarifications:
1) You will only see VIs sharing data if that VI contains some sort of internal storage (a shift register or feedback node). Sometimes this is an advantage (it provides a way to share data between loops that execute concurrently). Sometimes it's a disadvantage, because you need each copy to execute independently. That second case is when you should make a VI reentrant.
2) You will not run out of space on the cRIO FPGA, since FRC teams cannot change the code on it. The FPGA is used mostly for high-speed IO tasks; code written by FRC teams runs on the cRIO's main processor, with many fewer restrictions on code size.