LabVIEW Development Best Practices Discussions

cancel
Showing results for 
Search instead for 
Did you mean: 

LVRT: (How) Do you share your tags on the network?

I've developed multiple cRIO and sbRIO applications using CVT to hold the RT system's state and provide an API to it for the multiple engines running in the RT layer. (It's not important that I use CVT for my tag engine, state variable API, etc. You might use a different module or even a huge set of global or shared variables; the implementation is immaterial to this discussion.)

In every application, I run up on the same set of questions regarding sharing the RT system's state with an HMI application or other external component.

It's much easier, in some senses, to just expose the RT's state variables (tags) to the HMI. Should I? Omitting the need for software-based network security, I can't really see why not. I certainly want to make sure to encapsulate write access to any given tag so I'm not stomping on state variables in unexpected places. But for read-only access, it seems logical to let any system component see whatever it wants to see.

http://dogobediencetips.org/wp-content/uploads/2008/11/puppy.jpg

Fig 1: A cute puppy breaks up the wall of text in this post.

So if that's the case, what's the best method for doing so? NI has an engine called the CCC that acts like reflective memory, mirroring a subset of the RT's tag database on a local system and constantly polling for changes or pushing updates. I don't really like the polling model though; I'd rather see an event or notification based system similar to "push" notifications on your cell phone. I'm also unsure of how the CCC behaves in a multi-HMI system (or any system that has multiple parties interested in the values of the RT's state). Since everything is initiated by the client (HMI), two clients may query state at different times and get different information.

At present, I generally use a message-based scheme: The HMI sends messages to the RT to enact commands, and the RT changes its own state variables as those commands are carried out. When a command or process changes a "published" tag, a message is sent back to the HMI to notify it of the tag value's change. (I could get fancier with this, allowing each listener to subscribe to the subset of tags it cares about like a typically fleshed out pub-sub model.) This approach is inefficient over TCP, but I've never seen it actually clog the network in my applications.

So how do you handle this type of general application? Do you publish your RT's state directly to the HMI? If so, how do you do it (messaging, reflected memory, or another approach)?

0 Kudos
Message 1 of 6
(5,871 Views)

I have a system that works similar to the NI CVT component and basically implements a TCP/IP server alongside that supports querying and updating individual tags as well as querying batches of tags. It also has other features like a message that allows quiting or restarting the entire RT application, updating the CVT channel configuration table followed with an engine restart, and of course qeurying a list of available tags as well as their attributes. Since it works on a closed network, I left out security completely and on purpose.

My idea is that the HMI knows best what information it needs to get and therefore polling from the HMI is the most easy solution. I have entertained the idea to add some sort of subscription mechanisme where the HMI could register for updates but found that that would complicate both the HMI interface library and the RT engine considerably. The complication in the HMI interface while not really a problem, would also complicate the entire access in the HMI applciation to fully support push operation, but more importantly it complicates and increases the load on the RT side considerably and might in fact cause more difficulties than it solves especially since it still needs to run on some old rather resource constrained CompactFieldpoint systems too. The addition of a batch tag request message has actually made the biggest difference in performance, since it avoids 2 * n network messages by replacing it with two single network messages returning the state of as many tags as I would like.

Rolf Kalbermatter
My Blog
0 Kudos
Message 2 of 6
(3,760 Views)

rolfk wrote:


My idea is that the HMI knows best what information it needs to get and therefore polling from the HMI is the most easy solution. I have entertained the idea to add some sort of subscription mechanisme where the HMI could register for updates but found that that would complicate both the HMI interface library and the RT engine considerably. The complication in the HMI interface while not really a problem, would also complicate the entire access in the HMI applciation to fully support push operation, but more importantly it complicates and increases the load on the RT side considerably...

Can you explain in more detail how the pub-sub push model complicates each system? In my estmation, the HMI just needs to send a message to the RT with a list of tags it wants to hear about. It can then either create a mirror of that tag on its side for local access or tie the network notification from the RT to an event/notifier inside the HMI context. On the RT side, there's a little more complexity in having to manage a table of subscription lists, but that's not too hard to implement. What am I missing?

rolfk wrote:

The addition of a batch tag request message has actually made the biggest difference in performance, since it avoids 2 * n network messages by replacing it with two single network messages returning the state of as many tags as I would like.

My applications haven't needed more than a few dozen tags yet, so the network messages really haven't been a problem. I also like to use the Network Stream engine for my networking, instead of raw TCP, so there may be some bandwidth optimization being done in there for me. How many tags do you normally work with? Did you write your own TCP client/server for communicating tag information?

0 Kudos
Message 3 of 6
(3,760 Views)

DavidStaab wrote:

Can you explain in more detail how the pub-sub push model complicates each system? In my estmation, the HMI just needs to send a message to the RT with a list of tags it wants to hear about. It can then either create a mirror of that tag on its side for local access or tie the network notification from the RT to an event/notifier inside the HMI context. On the RT side, there's a little more complexity in having to manage a table of subscription lists, but that's not too hard to implement. What am I missing?

Well, for one the mechanisme to setup some server interface on the client that can receive the push messages and then the need to translate them somehow into user events or whatever I would consider rather invasive in most simple HMIs. For more complex HMIs that need to do more than just displaying data it gets even more complicated. It's a lot easier to have some control loop simply poll the values it needs to do for its work than setting it up to wait on push events, especially if this loop depends on more than one input value. Yes there is some overhead in polling data more than strictly necessary but the simplicity of the implementation makes up for a lot of this.

On the RT site, to do clean push notifications, I would have to provide the ability for each tag to be registered to a variable number of clients, making this a variable sized data structure that needs to be maintained per tag, and I want to minimize all potentially variable sized arrays and strings in the RT engine to a minimum, as this is especially for low resource systems a potential killer. There are certainly ways to make this a single array structure that maintains all such state for all tags and have each tag only maintain an index into that array, but that is complicating matters a lot and makes updating that table also go through all tags each time to update those indices.

My applications haven't needed more than a few dozen tags yet, so the network messages really haven't been a problem. I also like to use the Network Stream engine for my networking, instead of raw TCP, so there may be some bandwidth optimization being done in there for me. How many tags do you normally work with? Did you write your own TCP client/server for communicating tag information?

My applications have typically several 100 tags on the RT system, although some of them are not strictly RT related but really also help tags that maintain simply some system state information, not necessarily directly related to the RT operation itself. There is usually one HMI application that allows controlling the system and one or more monitor HMIs that only display current information. The communication is based on my own TCP/IP client server protocol, similar to what CCC uses. I added the batch tag request mainly for the UI update of the HMI application. This component usually requires several dozen tags to be displayed and requesting them once every second for all channels at once, certainly beats having the RT engine having to send one push notification for each tag change, potentially several times a second for some tasgs, and it allows me to leave out any form of server interface on the HMI client side, making this interface a lot easier to maintain.

Rolf Kalbermatter
My Blog
0 Kudos
Message 4 of 6
(3,760 Views)

We use networked shared variables to do what you describe. We like it because it offers publish-subscribe communication out of the box. This makes it very easy to decouple components. The View (HMI) processes shared variable event value changes for the relevant shared variables. This is ultimately clean and simple.

Of course there are eventually limitations to the data rates (as with any network scheme) but since we are talking about updating the HMI that's not a problem. Certainly we can update faster than the user can see!

0 Kudos
Message 5 of 6
(3,760 Views)

David, Rolf

On a large non-LabVIEW implementation I was recently a part of, there were redundant-pair data servers that extracted data from the real time machines.  Since each real-time machine talked to only one redundant pair of such servers, the real-time systems were minimally loaded.  The data servers took care of variable lists of subscribers for the data, etc., pushing data back and forth to each other as needed to ensure that all points were available to all subscribers if wanted, and generally performing as historians as well.  Admittedly, a much larger and more complex implementation than what you are talking about, but I would expect that over a long project lifetime, a smaller-scale but similar implementation could serve a LabVIEW project well also, protecting the RT machines from the vagaries of user subscription management.  At a minimum, a single data server to buffer the RT machines from the greater world would do.

Blair

0 Kudos
Message 6 of 6
(3,760 Views)