LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Action Engine noob

Solved!
Go to solution

I am learning how to use "action engines" (or functional globals, or ...) and noticed that most are used for one variable.  I have various inputs from a motorized pump.  I initialize these inputs in the beginning and use them throughout the program.  Instead of creating an action engine for each input task, could it be beneficial to include all the tasks in one action engine?  I also thought about putting them into an array but I like having them come out individually so I do not have to remember what order they were in.

 

Thank you for your input.

Ron Deavers, CLD
0 Kudos
Message 1 of 10
(6,249 Views)
Solution
Accepted by topic author programmindragon
Sure, you could store multiple values either using multiple shift registers, or better yet, combine them into a cluster.  You would have 2 action enums, one for Get and Set, the other defining which of the items in the cluster you want to work with.  If you are dealing with multiple data types in the cluster, you may need to have the input and output for the data on the connector pane be a variant.
Message 2 of 10
(6,244 Views)

THe final example I included in my Action Engine Nugget illustrated using a single Action Engine to control multiple pumps.

 

My view on single vs multiple AEs

 

I take a philosophical approach to this decision and first analyze all of the actions that can be invoked looking for interactions or syncronization issues.

 

EX

 

I need to shut-down all pumps if one goes over-pressure. This type of situation screams for a single AE so that when the safety limit violation is detected and action taken, I know that is taken for all sub-systems. With seperate AEs I could sset the safety trip for some while others are waiting to get updated. Along with that I'd need to invoke the proper method on as many AEs as i have widgets. Along with that, if I add another pump I just have to update my AE and the rest of the code can stay unchanged. If I was using multiple AEs I'd have make sure I added the AE for the new widget in all of the right places. Maybe easy for me the original developers but someone following-up behind me may miss something that happens in a dynamically loaded VI.

 

On the other hand...

 

Again if you reference my AE Nugget you will see that AEs can only execute in one thread at a time. If all of my pumps had absolutely nothing to do with each other and I wanted to ensure actions involving one pump did not block another pump, then sepearate AEs are concidered.

 

So...

 

This question has to be answered on a application basis where the req's indicate the proper approach.

 

I'd love hear what others have to say about this topic!

 

Ben

Retired Senior Automation Systems Architect with Data Science Automation LabVIEW Champion Knight of NI and Prepper LinkedIn Profile YouTube Channel
Message 3 of 10
(6,209 Views)

Ben,

 

I was thinking along the same lines.  You expressed it very well.

 

Similarly, if there data or commands which have nothing to do with the pumps \, it should probably be in a separate AE.  For example file I/O which is in an independent loop.

 

Lynn 

0 Kudos
Message 4 of 10
(6,195 Views)

Thanks Ravens Fan and Ben for your help.

 

I actually learned how to create an AE from your nugget, Ben.  Thank you very much.  The hardware tasks that I am utilizing in the AE are outputs from a single pump.  I adjust the parameters of the pump and monitor the changes with these tasks.  I have many more AEs to write in this program so I thought I would pass my first attempt through the experts.

 

I did not want to create a cluster because I would have to bundle and unbundle the data when I enter and exit the AE respectively.  Since they are of the same data type, if I were to bundle them, I might use an array instead.

Ron Deavers, CLD
0 Kudos
Message 5 of 10
(6,161 Views)

More thoughts to keep your synapses lubricated.

  1. Your first post said that you initialize a bunch of variables at the beginning and then use them throughout the code.  This sounds like a look-up table.  If you only have one place you are writing and you read many places, the easiest and most efficient thing to use is a global.  Don't use it if you have more than one writer, or you can face race conditions, which are usually intermittent, do nasty things to your code,  and difficult to find (e.g. we spent two man-weeks to find one once - it took 2 minutes to actually fix).
  2. Read some books on object oriented design if you want some pointers on how to break up your code into different action engines.  Each action engine is essentially an object, containing encapsulated data and methods.  It has no inherent inheritance, but that can be fixed by making the data a LabVIEW object.  Note that good books on object oriented design tend to be expensive.  Check out your local library or university library before you get one.
  3. You may also want to investigate the single-element queue model.  You can find information about it on these forums.  Whether to use it or an action engine depends on your programming style. The single-element queue model lends itself more to traditional object-oriented techniques.
0 Kudos
Message 6 of 10
(6,133 Views)

DFGray wrote:

More thoughts to keep your synapses lubricated.

  1. Your first post said that you initialize a bunch of variables at the beginning and then use them throughout the code.  This sounds like a look-up table.  If you only have one place you are writing and you read many places, the easiest and most efficient thing to use is a global.  Don't use it if you have more than one writer, or you can face race conditions, which are usually intermittent, do nasty things to your code,  and difficult to find (e.g. we spent two man-weeks to find one once - it took 2 minutes to actually fix).

...


I'd like to make a point to counter that staement Dr. Gray.

 

The special attribute of the applicaion that "... you only have one place you are writing ..." can only be made by someone that is familiar with the application and exacly what is happening where and when. If at a latter date, a follow-up developer is asked to be able to "just* make a small change", they may introduce a race condition. In order to prevent my customers from running into that situation, I insist that no matter how simple the application is, that our application use AEs even though a global may work.

 

Ben

 

 

* In my office, "just" is a four letter word. Smiley Very Happy

Retired Senior Automation Systems Architect with Data Science Automation LabVIEW Champion Knight of NI and Prepper LinkedIn Profile YouTube Channel
Message 7 of 10
(6,127 Views)

Concerning globals I want to back up Mr AE Ben:

 

> initialize a bunch of variables at the beginning

 

That's one of my favorite use cases of Action Engines: Have a bunch of variables (pretty static configuration data).The AE mainly consists of the default 'Get' action wherethe variables are only passed to the indicator from the SR and a first call case (using the first call primitive), where the data is loaded from any kind of ini file.

Of course, a good point in this practice is, that  the code becomes scalable (globals are absolutly not scalable).

 

But the real great point is, that writig this way, I never need to take care if these variables were properly initalized.It don't need to tell them in an initialzation state to get proper loaded, they just say 'ah, it's my first call so I have a look which value I'm supposed to have'. 50% of the race conditions I hade in my coding went on the initialization problem.

 

And globals have no error out, how should I know if their value is good?

 

Felix

Message 8 of 10
(6,097 Views)

All very good points which I totally agree with (I knew I would need asbestos BVDs when I wrote that post).  I never use globals for all the reasons you mention (and have never needed them in almost two decades of LabVIEW programming).

 

However, for a lookup table, if you are careful, their performance cannot be matched, and it just got better in LabVIEW 8.6.
Improper use of the global may result in high stress, endless aimless searches for difficult bugs, long development times, and ridicule in public forums.  Less common side effects include stress, hair loss, damaged monitors and other computer equipment, loss of employment, loss of spouse, and loss of self esteem.  National Instruments is not responsible for the improper use of globals.

Message 9 of 10
(6,063 Views)

 

Thanks for the input.  I will invest some money and time into LVOOP literature.  My last program used globals (alot).  That was before I learned of AEs and their versatility.

Since I will be using these tasks throughout the program, I decided to place them in a shift register as a cluster.  If I go back to placing them in an AE, I will look into using the first call primitive which I have seen but never used.

 

Ben,

My last supervisor actually cringed whenever I used the word *just*.

Ron Deavers, CLD
0 Kudos
Message 10 of 10
(6,046 Views)