09-27-2005 08:04 AM
09-27-2005 08:57 AM
09-27-2005 09:40 AM
09-27-2005 10:35 AM
09-27-2005 10:46 AM
Don,
I'm ~99% sure that you can't get the 'Wait until Done = false' functionality out of the 'Call by Reference Node' method. The previously posted example is neat, but it uses the 'Run VI' method of an Invoke Node that you're hoping to avoid.
I have also wanted the same kind of capability, primarily so I could launch a parallel-running process while feeding it input data through wires (rather than a whole bunch of calls to 'Set Control Value'). I came up with a near-solution that has some quirks, but I think I'm getting to the bottom of most of the quirks.
The basic approach is that I create a wrapper vi that I call my "launcher" or "interface." The front panel has all the same controls / indicators as the lower-level parallel process vi, including the exact same names. When I call the interface vi and specify "launch", I use VI Server calls to copy down all control values from the interface vi to the process vi. This is done simply by first calling "Get All Control Values" on the interface vi, then looping through the results to "Set Control Value" on each control of the process vi. (Similarly if I specify query, I use VI Server to copy up all indicator values from process vi to interface vi).
The net effect is that my main app will only ever call the interface layer and can always pass data along wires.
Now for the problems (see also this thread I jumped into). I've found that I need to have the interface vi's front panel open or else the values I read using "Get All Control Values" are liable to be the default values for the controls, regardless of what I've wired in. In practice I set it to be open and minimized to avoid clutter. I've further found (I think) that it also helps (is necessary?) to read from all the controls using wires in the interface vi before making the "Get All Control Values" call.
I think there's a separate dataspace for the value held in the block diagram terminal and the value held in the front panel control. Somehow the act of accessing the terminal makes sure that the value is also copied into the front panel dataspace. All I do with the wire is terminate it in a place that guarantees that the value is read before I call "Get All Control Values". (I do a similar thing in "query" mode -- I read from a local variable copy of each indicator after I've performed all the "Set Control Value" calls).
I'm still trying to poke and prod at this strangeness. In the thread I referenced, I now think that the success others had was because they were using "Get Control Value" to determine whether "Set Control Value" worked properly. I think these both access the front panel dataspace without regard for whether it has been sync'ed with the value held in the block diagram terminal. My testing used the block diagram terminal to produce a distinct output value sent back by wire. The oddness I observed led me to the above ad hoc guidelines. I still have different problems with reentrant process vi's than non-reentrant ones, and haven't gotten back to compare the behavior under RT vs Windows.
I'm presently putting up with a work-around solution in the app that got me into this mess, but am still interested in understanding it more fully. I still think this interface layer idea could be a handy one, but am not presently confident that it's reliable.
-Kevin P.
09-28-2005 10:55 AM
HI Don,
What you are asking for a VI that launches a background process that you want to interact with. Yes I think you are correct that there is no way to get a call by reference to break the dataflow paradigm. That can only be done using a sub-routine and that is not useful for dynamic VI calls.
I use a standard structure to do this that is based on making the the dynaimic VI the slave and the instantiator is the master and use VI name based queues to share commands status and resluts.
The master creates a command/request queue and passes the queue reference to the Slave launcher. THe launcher post the queue refernce VI a VI global adn then does an invoke node to start the slave. The slave runs and grabs its command queue refernence and creates a response queue before starting to do it thing.
Meanwhile back in the master....
The master has been checking fo the slaves response queue to be created. Once the response queue is found the slave is considered operational and we proceed to the next slave.
Once all of the slaves are up and running you can use the call by reference node to call a sub-VI that knows the Slaves comand and response queues. I queus up a request and wiats for a response. The response is returned VI the call by reference terminals.
Ben
09-28-2005 11:24 AM