11-20-2018 11:34 AM
Hello,
I am trying to accomplish something in LabVIEW which is usually trivial in a language which has the natural notion of references and pointers. In my example scenario I have two VIs, A and B, which will be running in parallel (a main window and a popup window). I have a class which represents a physical piece of hardware, for example a motor. VI A has a few controls for making the motor move. VI B has a few indicators which display the current status and position of the motor.
Normally it would be simple enough for each VI to have pointers to the same physical motor object and use some mechanism to notify the VIs of updates to the object (for example, the C++ framework Qt has an event mechanism). However, since data is passed by value and copies in LabVIEW and objects really don't have "state" as far as I can tell, this seems to be a challenge to accomplish.
I have tried the idea of creating custom user events to notify each VI of changes. The problem with this method (or at least my implementation of it) is that I have to create a new custom event for anything new I potentially add to the object (and this is not truly part of the class so I lose encapsulation and modularity).
Are there any good methods for doing something like this in LabVIEW? I would potentially want the ability to add any number of parallel VIs that all can act upon and receive updates from the same object.
Thank you!
Solved! Go to Solution.
11-20-2018 11:43 AM
Labview does have a natural notion of references:
http://www.ni.com/white-paper/9386/en/
The structure is a bit annoying to use, but it does what you want. The error output on both the left and right node produce the same result so you can ignore one if you handle the other. toolsets which use this structure include gds (http://sine.ni.com/nips/cds/view/p/lang/en/nid/209038) I think, and esf (https://forums.ni.com/t5/Reference-Design-Content/Extensible-Session-Framework-ESF-Library/ta-p/3522...) among others.
That having been said, the more labview-y way to do this would be to have one loop managing the device locally and publishing updates either as user events or on a queue. It is common to use a enum ID + variant data type to send messages along a single queue that have different data types, if that concerns you.
11-20-2018 11:52 AM
As mentioned above, data value references (DVRs) are exactly what you are looking for. Another approach to solving your problem would be to look at using the Actor Framework which provides the necessary messaging you would need.
11-21-2018 08:11 AM
I have been looking into the Actor Framework as you mentioned and am intrigued by what it is capable of. It seems like a good choice for much of what I am trying to accomplish. I can see how to use messages to trigger user events within my actors, as well, to update the front panels of all my popups.
There are a few general things I am not clear on with this framework however. In my project I will need to be able to do actions in a defined sequence. For example, I need to first move some motors and set a power supply voltage before I begin taking measurements. I am not clear on how to accomplish this type of ordering with actors since all operations are asynchronous and you don't typically (or shouldn't) receive replys from messages. Is this a correct way to enforce some sort of ordering of actions?
Thanks
11-21-2018 09:59 AM
As I understand your problem, you may want to send data to one of several asynchronous VIs, and may want to (asynchronously) receive data from them.
For sending, receiver-specific Queues (either named queues, which I rarely use, or an array of Queues, with each Queue assigned to a specific Target. For receiving, Notifiers, using the Get Notifier Status to return the "latest" element sent (which, if nothing new has been generated, will simply be the "old" value, again).
Yes, it's "old-fashioned", but if you are using LabVIEW 2016 or higher, you can jazz it up using Channel Wires (my current Method of Choice). Use Messengers to send, Tags to receive.
Bob Schor
11-21-2018 10:18 AM
I would recommend a messaging architecture rather than using a DVR to share the object. The hardware driver should talk to the hardware, and return any query results/readings, and that's it - I would put the messaging in another 'controller' type class that handles calling the HW driver and then publishing data.
You could use user events to publish the data, however any subscribers to that data will have to use user events to receive the data - which may or may not be a problem. (A much more involved solution is to use some sort of mediator/pub-sub API with transport abstraction such that subscribers and publishers can use a variety of data communication mechanisms). I am not sure what you mean by having to create a new custom user event - the user event type can be an object, or a string/variant cluster that can accept any data type etc.
There are many ways to enforce order of operations with the actor framework. Depending on how many actors you need to synchronize operations across, there are a variety of different solutions - one possible solution is to have one 'controller' actor that controls the sequencing by sending other actors messages, and those actors return a generic 'step complete' message when they have completed the step, which triggers the controller actor to send the next actor the next message in the sequence.
11-21-2018 10:47 AM
Look at the state pattern actor. This would allow you to control your sequence of actions. You can download it from VIPM.
11-21-2018 03:01 PM
The OP should be aware that there are lots of different frameworks and techniques of message passing, and they can have significant differences. So one should look at a few to see what makes the most sense, personally. My "Messenger Library" makes lots of use of replies to messages, for example.
11-21-2018 03:33 PM
@drjdpowell wrote:
The OP should be aware that there are lots of different frameworks and techniques of message passing, and they can have significant differences. So one should look at a few to see what makes the most sense, personally. My "Messenger Library" makes lots of use of replies to messages, for example.
I agree. We actually use a network based publish/subscribe messaging system. It handles distributed tasks very nicely and scales very easily. We have actually spun up multiple message brokers so we can offload some low priority messages to a separate message broker so we don't negatively impact the primary message broker. Our main message library automatically distinguishes between local message and system wide messages. In fact, we mix many different architectures in our system including actor framework. We look to see which design pattern or framework works best for a given system component.
11-21-2018 03:41 PM
@Mark_Yedinak wrote:
@drjdpowell wrote:
The OP should be aware that there are lots of different frameworks and techniques of message passing, and they can have significant differences. So one should look at a few to see what makes the most sense, personally. My "Messenger Library" makes lots of use of replies to messages, for example.
I agree. We actually use a network based publish/subscribe messaging system. It handles distributed tasks very nicely and scales very easily. We have actually spun up multiple message brokers so we can offload some low priority messages to a separate message broker so we don't negatively impact the primary message broker. Our main message library automatically distinguishes between local message and system wide messages. In fact, we mix many different architectures in our system including actor framework. We look to see which design pattern or framework works best for a given system component.
... And this is why I'll never be a CLA.