LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

A better and efficient alternate to Queued State Machine


MogaRaghu wrote:

. Want a new one ?No problem - just create another instance of it changing the name and maybe the icon. So good !! See the attached sample ....


You don't get a new instance, you get duplicate code. A big turn off for me. No good to me.

 

Another big problem is that once you created code that contains a FGV, you can't duplicate that in any way. Not in a loop, not with reentrant vi's or vit's, not with copying the code. You end up duplicating everything, including bugs that need to be fixed x times, once for every copy.

 

Another problem is the lack of overview (where it's used). And the almost unavoidable dependency on the FGV (since it's easy to use everything, it will be used everywhere).

 

If I need some sort of data communication between parallel loops (which I can usually avoid), I make a by reference class, or use some sort of messaging to "publish" the data. Everything that uses he class, needs he wire. Very annoying at first, very convenient when the application grows.

 

In the end, it's not all black or white. The kind of application you're doing of did, the things you know or knew, what you're comfortable with. This all matters in making choices that work for you.

 

Stay curious. Keep an open mind. Don't stop learning. Make your own choices, but try something out of you comfort zone once in a while.

0 Kudos
Message 11 of 25
(877 Views)

@MarcDub wrote:

Once you start thinking this way, it is the first step towards Actor Framework and other multi-processes framework.


And depending on who you ask, this is a step in the right or wrong direction. Some love it, some hate it. Don't seem to be much in between though.

 

To me, (mis)using any pattern (actor, (queues) state machine, decorator or whatever) as a one size fits all solution (the "F" word (from framework)) is not a good practice. I feel myself strengthened by the literature I've read.

 

Frameworks have there use, but not in a "copy of architecture" context. A framework should be "a collection of libraries that work well together", like .net framework.

 

Note that in OO, calling a class's method is after called "sending it an event". To me, a framework to facilitate sending messages just seems silly.

 

I get why people like it. The instant gratification is rewarding, but it's not for me (at the moment, mind you).

 

I want to emphasize that it's not a matter of right or wrong, but a matter of what works for you, and all your stakeholders, and this moment in time.

0 Kudos
Message 12 of 25
(873 Views)

@MogaRaghu wrote:

Oh thanks for pointing out.. I love FGVs !! ( Sure I am going to be hit on the head shortly for this love ) But frankly I have been using them as my only means to pass data between different VIs and to date there has been  no issues. Want a new one ?No problem - just create another instance of it changing the name and maybe the icon.


If all you are doing is the Get/Set variety, then you might as well just use a Global Variable.  Globals are faster and they have the exact same issues as the Get/Set FGV.

A Look At Race Conditions


GCentral
There are only two ways to tell somebody thanks: Kudos and Marked Solutions
Unofficial Forum Rules and Guidelines
"Not that we are sufficient in ourselves to claim anything as coming from us, but our sufficiency is from God" - 2 Corinthians 3:5
Message 13 of 25
(863 Views)

You know, I heard Crossrulz give this as NI Week talk (very well done).  He's absolutely right about Race Conditions and Globals being faster than FGVs.

 

Bob Schor

0 Kudos
Message 14 of 25
(857 Views)

@Bob_Schor wrote:

@MogaRaghu wrote:

See the attached sample ....

You do realize, don't you, that we can only see the Front Panel, as it is Password-Protect ...  Why bother attaching an example we cannot examine?

 

Bob Schor


Nothing intentional... its a slip forgetting to remove PWD. Sorry.

 

So here we go...

Raghunathan
LabVIEW to Automate Hydraulic Test rigs.
0 Kudos
Message 15 of 25
(848 Views)

wiebe@CARYA

Stay curious. Keep an open mind. Don't stop learning. Make your own choices, but try something out of you comfort zone once in a while.

 

I think that kind off sums up. I like it ..

 
Raghunathan
LabVIEW to Automate Hydraulic Test rigs.
0 Kudos
Message 16 of 25
(845 Views)

@crossrulz wrote:

@MogaRaghu wrote:

Oh thanks for pointing out.. I love FGVs !! ( Sure I am going to be hit on the head shortly for this love ) But frankly I have been using them as my only means to pass data between different VIs and to date there has been  no issues. Want a new one ?No problem - just create another instance of it changing the name and maybe the icon.


If all you are doing is the Get/Set variety, then you might as well just use a Global Variable.  Globals are faster and they have the exact same issues as the Get/Set FGV.

A Look At Race Conditions


I read the document at the link : https://decibel.ni.com/content/docs/DOC-41734 

This purportedly is about AE and FGV ... but let me accept ... even after reading the whole document twice the only thing that I could get was the sarcastic and humorous statements. The starting premise and the ending summary seem to contradict. Probably it would have made more sense to someone who attended the training courses.

 

Anyway let me come down to a specific situation for my application instead of a general pattern which in most situations adds little value.   

 

There is a MAIN.VI which is the interface to the hardware via the DAQMx drivers. So it reads AI and DI channels and writes them to two different FGVs ( I have provided a sample of this in my earlier post). When the user selects one operation from many possible operations, the MAIN.VI FP is hidden and the SELECTED.VI is loaded. 

 

This SELECTED.VI simply reads the AI and DI FGVs and does something with it.  It then writes back AO and DO values to other FGVs which in turn is read by the MAIN.VI.

 

And my Timed loops don't run at blazing speeds - just about 50ms is the norm. 

 

So in the above setup for AI and DI,  the MAIN.VI is the producer and the SELECTED.VI is the  consumer.

 

And for the AO and DO, the SELECTED.VI is the producer and MAIN.VI is the consumer. 

 

So two questions :

1. Where is the possibility for a race here ? 

2. Can I simply use Global variables if FGV only add to latency ? 

Raghunathan
LabVIEW to Automate Hydraulic Test rigs.
0 Kudos
Message 17 of 25
(825 Views)

Ragunathan,

 

     Two sets of comments, last first.  There have been many "debates" in the LabVIEW Community on the merits of Global Variables vs VIGs vs FGVs vs Local Variables vs Property Nodes etc., when should one use which, etc.  Some are "mainly esthetics", some are "function", some are "speed".

     Crossrulz was trying to (among other things) "Compare and Contrast" Global Variables from a Function/Speed consideration with FGVs.  He (I think correctly) pointed out that from a functional standpoint, they were the same, but Globals were faster.  Both implementations have the same susceptability to Race Conditions, as explained in this article, Race Conditions and FGVs.  A safe way to use Get/Set (or Globals) is to "Write once, read many", and even better, "Write first, read as-many-times-as-necessary later".

     I use VIGs this way, and usually in "non-time-critical" code where speed is not important.  I like being able to use Error Lines (which GV's lack) and my own Icons (which can enhance visibility/readability).

 

     I've attached my "redo" of your FGV, and have also posted it as a Snippet so I can make some comments.

FG_MODBUS_Array_BS.png

 So here are some changes I made.

  • The Block Diagram is much more compact.
  • I used the (default) 4-2-2-4 Connector Pattern, putting Error In/Out at lower corners, Array In/Out at upper corners, and Mode in the #2 input slot.
  • Changed While Indicator to Stop, wired "True" (I find "Do Until" logic more straight-forward).
  • Renamed some variables to simplify.
  • Enum names simplified.  Note that every Enum should have a corresponding TypeDef (I didn't make it, but you should).
  • Wiring changed, simplified.  Array Out always has "Latest Value" = contents of Shift Register.
  • Mode control has Default set to "Read", as this should be "Read mostly, write once", so an unwired Mode input will automatically "do the right thing".

Bob Schor

Message 18 of 25
(814 Views)

@MogaRaghu wrote:

I read the document at the link : https://decibel.ni.com/content/docs/DOC-41734 

This purportedly is about AE and FGV ... but let me accept ... even after reading the whole document twice the only thing that I could get was the sarcastic and humorous statements. The starting premise and the ending summary seem to contradict.


I am curious what article you were actually reading in there.  There was nothing sarcastic in that article and the only remotely humorous statement was to tell me if I did something stupid in my benchmarks.  Perhaps you are referring to the article I linked to (http://labviewjournal.com/2011/08/race-conditions-and-functional-global-variables-in-labview/)?

 

The whole thing about the Get/Set AE (what some of us have started to call FGV) is that it does not protect the "critical section".  This is when you read a value, update it, and write it back.  If you have multiples of these happening at the same time, what happens to the data?  With the FGV and GV, there is no protection around the data, so whoever writes last wins.  But an AE that has the processing inside of it blocks others from being able to use the data until the whole read-modify-write process is complete.

 

For example:

You have $100 in your bank account.  You deposit $50 at the same time your wife purchases an item for $25.  With the FGV, you have both the deposit process and the withdrawal reading the account balance ($100).  The deposit adds the $50 while the withdrawal subtracts $25.  Then the deposit writes the value ($150).  Then the withdrawal writes its value ($75).  You just lost your $50 deposit.

 

But with an AE, the withdrawal is not even allowed to read the balance until the deposit has completed its process.  So the final value is $125.

 

Please don't get into the hypothetical situations where you come out ahead.  The point is that the final value is wrong when the entire read-modify-write process is not protected.


GCentral
There are only two ways to tell somebody thanks: Kudos and Marked Solutions
Unofficial Forum Rules and Guidelines
"Not that we are sufficient in ourselves to claim anything as coming from us, but our sufficiency is from God" - 2 Corinthians 3:5
0 Kudos
Message 19 of 25
(798 Views)

MogaRaghu wrote:

So two questions :

1. Where is the possibility for a race here ? 

2. Can I simply use Global variables if FGV only add to latency ? 


1. As long as your values are only updated in 1 place, you will be fine.  You only care about the latest value and only 1 place is updating it.

2. Yes, you can simply use Global Variables.  Less for you to code.  They are more performant.  You can have multiple variables on a single global VI file.  I have also found the global VI useful for debugging.

 

And in case you are still curious, you can find my NI Week 2016 session here: TS9454 - Are Global Variables Truely Evil?


GCentral
There are only two ways to tell somebody thanks: Kudos and Marked Solutions
Unofficial Forum Rules and Guidelines
"Not that we are sufficient in ourselves to claim anything as coming from us, but our sufficiency is from God" - 2 Corinthians 3:5
Message 20 of 25
(794 Views)