LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Thought Experiment: Variable Number of Parallel Time Dependent Systems

Hi all, 

I'm just going through a thought experiment before beginning a new major project and am trying to figure out the best way this code could work. We have a new project coming up that is going to be based out a single computer, this computer is then going to control a number of identical iterations of measurement devices, at present the number is 20 but this could change depending on mechanical failure etc during trials. All of these devices need to be running at the same time and are relatively time dependent, each device has to:

  • Record measurement data at 1Hz (0.05s Active Time)
  • Respond to inputs and undertake longer tasks (0.5s Active Time). Inputs occur at random intervals greater then ~10s

As all of these systems must run in parrallel I am looking at the number of different ways LV handles the parallel instances to try and determine a reasonable design pattern before beginning anything. The current ways that I am looking at it are:


 

Standard Multiple VI parallelization

Build a SubVI, place multiple instance in block-diagram, run.

Pros:

Simple, Build a Sub-VI that can run the device plop X instances.

 

Cons:

Scalability, Not able to easily change number of instances without re-editing code, rebuilding moving etc.


State Machine parrallelization
Build a state machine for the Device, run X instances in a parrallelized For Loop, for all longer tasks run start them and then check progress each time you come back into the state machine.

Pros:

Programmatically scalable

Standard State Machine Architecture.

Cons:

Less control over long tasks

More complex programming and control.


 

I am looking forward to what the community has to say, I have a feeling I should probably be looking at OOP for this but I have never done any in LV before and I am a little worried how long the learning curve on that would add to the project without resulting in a much improved outcome.

 

Let me know your thoughts on the best way to continue.

0 Kudos
Message 1 of 9
(3,127 Views)
Your instincts about OOP are good. The NI training course recommend s starting with a small noncritical part of an application and expand slowly as you become more comfortable -- excellent advice.

If the 20 instances really are the same, write one reentrant VI that can control one system, then at run time launch as many as you need. You will of course need to pass each instance adequate parameters to tell it "who it is".

The thing to think about is what kind of GUI to create.

Mike...

Certified Professional Instructor
Certified LabVIEW Architect
LabVIEW Champion

"... after all, He's not a tame lion..."

For help with grief and grieving.
0 Kudos
Message 2 of 9
(3,118 Views)
Ps: kudos to you for thinking about this BEFORE you start writing code.

Mike...

Certified Professional Instructor
Certified LabVIEW Architect
LabVIEW Champion

"... after all, He's not a tame lion..."

For help with grief and grieving.
0 Kudos
Message 3 of 9
(3,116 Views)

If the 20 instances really are the same, write one reentrant VI that can control one system, then at run time launch as many as you need. You will of course need to pass each instance adequate parameters to tell it "who it is".


 

This is kind of what I was considering, but how would I go about launching the VI multiple times? The parameters bit it not too worrying as each device is working off a Ethernet-RS485 module, so I was simply considering an array of cluster(s) containing all of the relevant data for connecting over TCP, handle for the Connection ID etc. 

 

Just to make things slightly more complicated, at present this program is not going to have a GUI but rather act as a server that can be accessed by a GUI that will be running on a Windows Tablet running its own VI that is pulling the data down from the server. It should make things more mobile for whoever is doing the work and at least means that I don't have to worry about the GUI, just finding an effective way to pass the data from server to tablet.

 

Although I will probably want a fairly detailed information display for the server it doesn't have to be anythign as tidy or user-friendly as the end-user GUI, but as I am the one whos going to be using the server it would probably be nice if it was as usable as I could make it.

0 Kudos
Message 4 of 9
(3,103 Views)
Briefly, to launch a reentrant VI is very similar to launching a nonreentrant one. There is one parameter different on the open VI reference node. There are examples that ship with LabVIEW.

Mike...

Certified Professional Instructor
Certified LabVIEW Architect
LabVIEW Champion

"... after all, He's not a tame lion..."

For help with grief and grieving.
0 Kudos
Message 5 of 9
(3,097 Views)

As Mike said, you can launch multiple instances of a reentrant VI similar to launching a single instance of a VI - it's all in how you get your reference / what your reference actually is.

 

If you use the Open VI Reference function with a parameter of 0x80 or 0x100 on a preallocated clone reentrant VI, a clone is allocated and the reference is a reference to that clone of the VI (you can check this in testing using a property node and checking the name, which will have the clone number after a colon, and/or Is Clone VI).  At that point, anything that you do with that reference is being done to that clone.

 

 

What I did recently for a similar design was defined my class (or just a cluster if not using OOP) to have all of the information to define a single identity - TCP connection ID, queue refs, etc., and the reference to a clone.  A constructor would be called like a "regular" SubVI to create everything it needed, including allocating a clone for itself to run in, and return a Data Value Reference to the resulting object (cluster).  A launcher could then be used that would take the clone reference and Start Asynchronous Call on it, passing into one of its controls the DVR to the object.  Now the clone is running and has everything that it needs to identify itself and operate, including responding to connections like you might have for displaying detailed information about one process all on its own, and my main application still holds onto the reference to the object so that it can do things like be a common server to give new clients the list of TCP ports that each clone is available at.

 

 

As for some items in the original post:

 

  An object oriented approach is usually great for managing these kinds of designs.  If you have knowledge of object oriented design and just aren't familiar with LabVIEW's OOP support, then the learning curve should be very shallow, but it is a good idea to start with a small project or a single module first.  You don't want to be in the, "It's supposed to work this way, but I've never actually done it, and that coercian dot on a child being passed into a parent terminal is making me nervous..." boat for a critical project, even when it does work how you think its supposed to.

 

  I believe that the Actor Framework (which requires LabVIEW OOP to work with) is made for this type of stuff.

 

  I must say, I hadn't ever considered or seen using a parallel-enabled for loop with a SubVI in it to do this kind of thing, and I thought it was a cool idea.



0 Kudos
Message 6 of 9
(3,077 Views)

 

Was in a recent thread about trying to combine parallelized for loops and multiple reentrant instance vi's.  My focus was on a specific kind of reentrant vi -- one with internal persistent data storage where I needed to maintain correspondence between For loop iteration # and reentrant vi instance #.   Others in the thread discussed things more relevant to your situation where you want to launch several distinct asynchronous processes from a single reentrant vi.

 

My own personal takeaway was that I didn't discover any better way to correlate For loop iteration #'s to reentrant instance #'s than to maintain all those vi references I illustrated in this post of that thread.   Once stuck with that syntactical overhead, I no longer bothered setting up parallelization on the For loop.  And FWIW, my late-in-thread optimism about separating the reentrant vi's into a hierarchy didn't work out as cleanly for my particular needs as I had hoped.   (I think it *could* be useful in some cases -- NI's own waveform filtering hierarchy illustrates the method -- but I didn't find it helpful for my immediate needs.)

 

Just a little more food for thought...

 

 

-Kevin P

CAUTION! New LabVIEW adopters -- it's too late for me, but you *can* save yourself. The new subscription policy for LabVIEW puts NI's hand in your wallet for the rest of your working life. Are you sure you're *that* dedicated to LabVIEW? (Summary of my reasons in this post, part of a voluminous thread of mostly complaints starting here).
0 Kudos
Message 7 of 9
(3,046 Views)

Just a little more food for thought...

 

 

-Kevin P


Stepping into that thread is like going down the rabbit hole, I may need to do a lot more work with Re-entrants before I get most of it, but it does look like you have wrestled with a very similar problem to what I am dealing with. I can see what you mean about the heirarchal system seeming like it might be the best approach to this, although reading your description of the waveform filter VIs has definitely swayed me in favor of the State Machine method. If I make the main SubVi a state machine control then pass in its existing state, relevant information and array the information at the output of the parallel For Loop then it looks promising. If not quite as easy as the make N copies of the subVi, pass all its data through shift registers and run. 

Of course there is always the fact that nothing is ever as simple to program as it first looks in your head. But I may have to cross that bridge when I get to it. 

 

0 Kudos
Message 8 of 9
(3,028 Views)

 

Yeah, it seems like your state machine approach could work out fairly cleanly.  I'd advise bundling all the state variables into a typedef'ed cluster, then your processing loop can just store an array of those state variable clusters, one element for each measurement system instance.

 

It seems like you'll be safe from the problem I ran into because in your app, all the state variables are passed in and out of the subvi rather than being retained inside.  Still, I'd advise caution about parallelizing the For loops and be sure to do plenty of testing to verify that the arrays are indexed consistently for various amounts of parallelization.

 

 

-Kevin P

CAUTION! New LabVIEW adopters -- it's too late for me, but you *can* save yourself. The new subscription policy for LabVIEW puts NI's hand in your wallet for the rest of your working life. Are you sure you're *that* dedicated to LabVIEW? (Summary of my reasons in this post, part of a voluminous thread of mostly complaints starting here).
0 Kudos
Message 9 of 9
(3,008 Views)