Actor Framework Discussions

Showing results for 
Search instead for 
Did you mean: 

AF and Hardware or Fieldbus Interfaces

Hi AF fans,


I've used the Actor Framework quite a bit and enjoy using it for my applications. There's one dilemma I often face in the design process though and I was wondering if anyone had a good suggestion to solve it 🙂


The systems I work often have multiple hardware components that share common interfaces like CAN bus, RS422/485 or simply the same DAQ card. Could be something like this:

AF and HW Interfaces.png

The hardware components (here axis or sensors) are not used all the time or in every application, so I want to be able to dynamically load actors for those components. When the component actor is called it would need to check if the interface is already running, start or request it if not, make itself known to the interface aka register, and finally unregister when the component actor shuts down. The interface would stay alive until all components are unregistered.


How would you implement the hardware interfaces? Would you implement them also as actors and if so how would you call them? Or would you use different concepts for the hardware interfaces or maybe even the whole application?


I'm currently thinking of implementing the hardware interfaces as actors and combining them with a registration broker, which could be a functional global variable (FGV). So, the component actor would register with a hardware interface, COM3 for example, at the broker. The broker starts the hardware actor for COM3, if not running yet, and forwards the registration. The hardware actor would then respond to the component actor with its enqueuer. From here on the component and the hardware actor communicate directly. Any thoughts on this approach?


Looking forward to your responses!




Message 1 of 8

Commenting to get notifications for this thread, as it's something I've dealt with too and I'd love to hear other's answers.


In my case, I was able to tell at the start of the "run" which actors needed what. In other words, I didn't have things arbitrarily registering and deregistering during the life of the main test actor. Things may change *between* tests, so each run could be different, but for a given run all DAQ users were constant. That can dramatically simplify things.


I did this pre-Interfaces and used abstract messages. When I called my "Launch DAQ Actor", it had an array of registrations to which it would send data. Each registration had a subset of DAQmx channels it needed to read (including scale factors, terminal config, etc), plus a concrete message that implemented an abstract message (that was just an array of Waveforms). (In my case, I was doing some high-speed sampling so everything was the same sample rate.)


The DAQmx actor then combined all of the various channels to read and set up a helper loop to just read data from the required channels. Once that data came in, I went through my registrations and sent an abstract message containing their requested data.


In my case, the DAQmx actor was only called by one actor, but each topic could do different things. For example, I had a "Measure resistance" concrete message as well as a "Position sensor"  concrete message. That way, the Main actor that had called the DAQmx actor could have different messages for each batch of data. I'll be honest- I still like this method, and I'd use it again as I don't know if I could do the same thing with Interfaces (since I depended on injecting arbitrary messages at runtime). I'm sure there's a way, but my code is fast and works as-is 🙂


In my case I didn't span the Actor tree, but I think it would be doable as long as you knew ahead of time which Actors would need which resource. I'd imagine that would get hairy quickly though, so hopefully someone else on here will have a better solution.


I think this boils down to "A bunch of independent processes need a shared resource" which is a very common programming topic. I'm sure there are some solid ways to handle it.

Message 2 of 8

Thanks for commenting Bert! Your comment actually is a huge help, cause I wasn't able come up with the keywords "shared resource" in my search 😅 I'm currently looking at the extensible session framework (ESF) that's mentioned in the Best way to handle shared resources in AF discussion and there were a couple more interesting looking results popping up in the new search. I'll do a bunch of of reading and report back with my findings!

0 Kudos
Message 3 of 8

@mike-o-tronic wrote:


AF and HW Interfaces.png


An alternative to ESF-style shared resources is to "assemble" your system like this:

  • Create the two Interfaces (CAN and RS485)
  • Configure the X, Y, Z and Sensor with the needed Interfaces
  • Configure the Robot with the X, Y, and Z axes
  • Configure System with the Robot and Sensor A
  • Launch System
0 Kudos
Message 4 of 8

I think there are two different interfaces that are getting mixed up here and I believe you're talking about the interface class, where I meant hardware interfaces. I have a rough understanding of the interface class, but don't have much experience with it yet. I believe the issues would be the same though:


- Who's initializing the hardware?

- How do actors know if the hardware is already initialized or not?

- What if I want to stop Sensor A and start a Sensor B, which might be on the CAN bus, instead?

- How does the interface know which actors are running?

0 Kudos
Message 5 of 8

@mike-o-tronic wrote:

I think there are two different interfaces that are getting mixed up here and I believe you're talking about the interface class, where I meant hardware interfaces.

No, I meant the hardware interfaces as in your diagram, whatever they might be.


- Who's initializing the hardware?

Some higher level where the hardware is not a shared resource.  In your diagram, "System" is at a level where it doesn't share the resources outside of its own world of itself and subactors.


- How do actors know if the hardware is already initialized or not?

How do they know the hardware power is turned on?   That isn't their job.  "System" initializes the hardware, before passing it to any subactor.  "System" knows it isn't already initialized, because no-one else initializes it (it isn't a shared resource at this point).


- What if I want to stop Sensor A and start a Sensor B, which might be on the CAN bus, instead?

System shuts down Sensor A, configures Sensor B with the CAN bus, and launches it.


- How does the interface know which actors are running?

I was giving an alternate method of handling shared resources.  Your trying to do a "shared between independent things" solution, which is doable, but it is often simpler to just assign management of the resources to a higher level of the program which doesn't need to share the resource.

0 Kudos
Message 6 of 8

It sounds like @drjdpowell is saying to basically invert the way the resources are allocated. Instead of launching an actor that then self-initializes the shared resource, you have something at the top level initialize all shared resources, then give each child an already-initialized resource. In that way, at the time of initialization, the resource is NOT shared. It becomes shared after configuration and initialization.


The one potential use-case this doesn't quite meet is for dynamic registration and deregistration of a shared resource. OP, do you really need dynamic registration between shared resources, or can you do it all ahead of time (like my method or Dr. Powell's)?


If you do need dynamic registration, I still think it'd be easier to handle creation at a known location in your code rather than having each caller decide on its own whether or not to actually launch the responsible actor.

0 Kudos
Message 7 of 8

Yes, for me the keypoint was The hardware components (here axis or sensors) are not used all the time or in every application. If I followed the standard actor model tree I would need to implement every interface in every application and every application would be coupled to the interfaces.


The goal would be to dynamically load components, but also to be able to take any actuator or sensor and the required interfaces into a new application without having to reimplement the interface.


I agree that it should be known location where the interface is created. That's where I thought of the FGV, which could be included in either the interface's class or library.


Also, some additional info I came across:

Sharing hardware between actors

Controlling Shared Resources in Actor Oriented Systems  with presentation on YouTube

0 Kudos
Message 8 of 8