05-03-2018 04:58 AM
Hello
I've managed to get the Bloomy Actor Framework example (http://www.bloomy.com/support/blog/getting-started-actor-framework-part-ii) working.
However, I'm wanting to access the data that the Caller Actor (or UI Actor in the Bloomy example) has collected from the Callee Actor (DAQ Actor). The Bloomy example uses the Caller Actor's 'Actor Core' method to display the data to the Front Panel. I want to be able to access the data so that I can use it in other parts of my LabVIEW project.
Can anyone give me a link to an example where this has been done? I am using LabVIEW 2017.
I have tried reading 'Using the Actor Framework in LabVIEW
(https://forums.ni.com/ni/attachments/ni/7301/130/1/Using%20the%20Actor%20Framework%203.0%20in%20LabV...), but am struggling to follow it. I'm hoping that an example will help.
Many thanks
RW
02-07-2019 10:29 AM - edited 02-07-2019 10:30 AM
I have the same question! I have been fumbling around with the actor framework in LabVIEW for a bit and I am frustrated that there is not a better resource from NI that describes how one would program using the AF. I have tried to take the NI class for AF development only to be told that the class may not be available because no one else is signed up, geez, at least let me buy the training materials.
02-07-2019 11:17 AM
You can do this by
a) create a DVR, then pass it into the actor when you create it. The actor can put data in the DVR and you can look at the data in the DVR from outside the actor as well. I don't love this method because I think it breaks the AF paradigm a little bit, but it can work okay in some cases and is pretty simple.
b) just use AF messages. In your actor that's collecting data, send a message to the other actor with the data each time it collects it. I prefer this because it follows the AF paradigm.
I'm a bit busy now, but maybe if I have time later, I'll try to make an example.
02-07-2019 12:17 PM
Yeah the Actor Framework answer is always message queues. Caller and Callee's get them for free. But if you have some other part of your program that needs to request data from an Actor you'll need to create a queues for that purpose.
Below is a fairly complicated project that demonstrates asynchronous communication between Actors but it also has a lot of documentation as there is an article and forum post accompanying it.
02-07-2019 01:07 PM
@majoris wrote:
Yeah the Actor Framework answer is always message queues. Caller and Callee's get them for free. But if you have some other part of your program that needs to request data from an Actor you'll need to create a queues for that purpose.
I would recommend against using queues that talk between actors, as it breaks the "Actor" paradigm.
I haven't done TONS of programming with AF, but so far I have never needed queues that reach across Actors. Queue's *within* actors are great (for helper loops), but not *between* actors.
OP, what exactly are you trying to do? Part of the problem with AF is that much of the discussion is very generic and can be hard to put into practice without a solid example. In general, if you have a child Actor that is generating some data, you want to send it to the parent actor using an Actor message. For example, a DAQ actor can take data from the DAQ device, do filtering or preprocessing or scaling or whatever, then send the result to the next level actor that "does stuff" with the data.
One of the harder things to get your head around with Actors is that the whole idea is that one actor does not tell another actor what to do. It can *request* it does something, but the other actor decides what to do on its own. Actors should NOT be treated like subVI's, where one Actor calls another Actor to do something. An Actor is its own, fully contained QMH. While you can certainly have trivial Actors that just do something once then sends some data back, you'd generally be better suited by just using a subVI that can actually return some data.
For example: say you want to add two numbers together, then square that data, and add a third to it. An Actor is a poor choice for this, but a subVI would be fine. The Actor is asynchronous by nature, and this operation is one where you want something synchronous, and it does ONE thing, ONE time. If you want to change the actual operation with certain overrides, make the subVI an object or a polymorphic VI.
If you want to continually collect data, and send it back to a processor for evaluation or logging or whatever, an Actor is a good choice. You can think of it as a "producer" loop that you can drop into another Actor whenever you need one- just use the built in Actor messaging protocols, don't try to build your own around it.
I won't say there's never a use to communicate across Actors using something other than their main message queue, but I can say it's unlikely that you'd need one until you're doing something very "out there".
02-07-2019 01:09 PM
I appreciate your response. I can always send a message to an child actor but can never figure out how to send a message back to the parent. I have seen it done in the LV AF demo but it was an older version of LV. I use LV2016 for now and it looks like most of the examples use an older version that has now deprecated calls for the AF so they usually dont run and/or do not jive with how things were implemented in LV2016. I can see where I can create messages for actors and callers but whenever I try to create a message to send to a parent or caller I am missing something because I always get class conflicts going back up. I feel like I am close to the ah-ha moment here but it remains elusive. Any advice is always welcome.
02-07-2019 01:15 PM
Ah, yes you're definitely close 🙂 I think we can get you through this. The initial learning curve trying to teach yourself AF is steep, but once it clicks, it's fairly smooth sailing from there!
So, the thing to remember is that messages are handled by the actor to whom they are sent. So, a parent actor can only receive messages meant for that particular actor (or a parent class of that actor). If you could give us an idea of what you're trying to do specifically, I can be more specific.
To get the ball rolling, you can start by having a message made in the parent actor that can act upon data received. When you make the message for that actor, you will get a "Send message" VI created for you (assuming you're using the built-in AF message creation tools, or the **wonderful** MGI Improved Message Maker, available for free!). In your child actor, call the "Get caller enqueuer" VI to get the enqueuer reference for the caller actor, and wire that to the "Send message" VI for that specific message. This will send the message to the parent VI.
Hope that helps get you started. The real benefit comes a bit after you've started to understand all of this, as you can start making abstract messages that can be used by arbitrary actors in the future. In other words, you won't have to hardcode in the specific message to send into the child- you can program in an abstract actor that will be overridden by the parent in the future.
02-07-2019 01:51 PM
Thanks for the response. I think the disconnect is that in normal OOP programming you don't get the queue system as in the AF. When you try to program something like a public method in OOP you dont have to worry about enqueing messages with class restrictions, you just access the data directly. When LV implemented the AF as a mix off OOP and QMH it made something that takes a bit to wrap your head around, especially if you are trying to teach it to yourself.
As a specific example. If you have an actor and class named Neighborhood and then have the actor and class House the inherits from neighborhood and house has many concrete implementations with subsequent data associated with the class House. The data in the house class is Address and Color. Now I have another Actor and class named Realtor That does not inherit from Neighborhood or House. and Realtor wants to know the color of a house at address 1234 H Street.
Currently (non OOP) I would use a one time queue to access data stored in a clone vi with a QMH that is essentially an instantiation of the House class.
I feel like within the AF I should be able to create a public method (or message or something) that abstracts the underlying AF that the Realtor class can use to find the color of houses in the Neighborhood, assuming the color of a house is public data. I feel like the tool to do this is built in, but I cant figure out all the boxes to check when creating messages to get it to work. I always get class conflicts for messages.
02-07-2019 02:06 PM
I think a small part of your problem is just how you're visualizing Actors. The AF isn't a different way to handle OOP- it's a QMH implemented with OOP. You don't pick between AF or OOP- you use both together.
"Realtor" is a good possibility for an Actor. "Neighborhood" is likely a poor choice for an Actor, but a good choice for an Object. "House" could go either way. An Actor should ideally "do" things. A "Realtor" can receive messages (like "Sell a house" or "Buy a house"), but I'm having trouble deciding what a Neighborhood might "do". A "House" might "do" things, but still, I'm not sure what message you'd send to a house. A Heater, sure, but maybe not House.
Additionally, I don't think you'd want House to inherit from Neighborhood. A House is not a type of Neighborhood. A Neighborhood *has* Houses, so you could have an array of Houses be a member of Neighborhood. Additional members could be "Swimming pool" or "HOA" or something.
You say you'd use a one-time queue to access data stored in a QMH that's an instantiation of a House. Can I ask why you'd want House to be a QMH, not just an Object? I can guess why you'd want to do such things but it would help to be explicit.
If you DO need House to be an Actor, not just a regular Object, you would likely implement a "Request Color" message as an Abstract Message in the House Actor. A Message associated with Realtor would be "Request Color" that inherits from the one in House Actor. Messages CAN include their own queue reference, so you could send a Message that says "Hey, please send your color to this Enqueuer." The point of Abstract messages is that the layout of the message can be defined by the Child actor's Abstract message, but the specific message can be sent to the child actor by the caller actor, along with the enqueuer on which to send the message.
This is getting a bit hairy to type out but let me know if that makes sense. You're close for sure.
02-07-2019 02:26 PM
I would recommend against using queues that talk between actors, as it breaks the "Actor" paradigm.
Sorry if this wasn't obvious, I just mean that Actors would need to share their message queues (for instance possibly through a message, such as a Reply, or at initialization; whatever is natural for modeling the problem).