LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Shared Variables for Real-TIme Robot Control

I'm really stuck in my efforts to use LV real-time in my hardware control application. I have a 6-axis industrial robot arm that I must control programmatically from my PC. To do this I've developed a dynamic link library of functions for various robot control commands that I can call using Code Interface Nodes in LV (using 8.5). This has worked great, that is, until I tried to port parts of the application to a real-time controller. As it turns out, because the robot control dll is linked with and relies so heavily upon several Windows libraries, it is not compatible with use on a RT target, as verified by the the "DLL Checker" application I downloaded from the NI site. When the robot is not actually executing movements, I am constantly reading/writing analog and digital I/O from various sensors, etc.....

This seemed to suggest that I should simply segregate my robot commands from the I/O activities, using my host PC for the former, and my deterministic RT loop on the target machine for the latter. I set up a Robot Controller Server (RCS) vi running on my host PC that is continuously looking for (in a timed loop) a flag (a boolean) to initiate a robot movement command. Because several parameters are used to specify the robot movement, I created a custom control cluster (which includes the boolean variable) that I then used to make a Network Shared Variable that can be updated by either the RT target or the host PC running the RCS. I chose NOT to use buffering, and FIFO is not available with shared variables based on custom controls.

Here's sequence of events I'd like to accomplish:

1) on my host PC I deploy the RCS, which continuously pools a boolean variable in the control cluster that would indicate the robot should move. The shared variable cluster is initialized in the RBS and the timed loop begins.
2) I deploy the RT vi, which should set the boolean flag in the control cluster, then update the shared variable cluster.
3) an instance of the control cluster node in the RCS should update, thereby initiating a sequence of events in a case structure. (this happens on some occassions, but very few)
4) robot movement commands are executed, after which the boolean in the control cluster is set back to its original value.
5) the RT vi (which is polling in a loop) should see this latest change in the boolean as a loop stop condition and continue with the RT vi execution.
 

With the robot controller running in a timed loop, it occassionally "sees" and responds to a change of value in members of the shared variable cluster, but most times it does not. Furthermore, when the robot controller vi tries to trigger that the movement has completed by changing a boolean in the control cluster, the RT vi never sees it and does not respond.

1) Bad or inappropriate use of network shared variables?
2) a racing issue?
3) slow network?
4) should I buffer the control cluster?
5) a limitation of a custom control?
6) too many readers/writers?
7) should I change some control cluster nodes to relative, rather than absolute?
😎 why can't I "compile" my RT vi into an executable?

Any help would be greatly appreciated. Unfortunately, I'm writing this from home and cannot attach vi files or pictures, but would be happy to do so at work tomorrow. I'm counting on the collective genius in the universe of LV users and veterans to save my bacon.....

David
0 Kudos
Message 1 of 2
(2,667 Views)

Hi David,

I'm curious why you decided to build a CIN instead of developing the code in LabVIEW.  Is there some functionality that that LabVIEW couldn't provide?  Can you provide some more information about the LabVIEW Real-Time target you're using?  What type of IO are you using?

It is impossible to get LabVIEW Real-Time performance on a desktop PC running an OS other than LabVIEW Real-Time.  Even running a timed loop in LabVIEW for Windows won't guarantee a jitter free application.  Also, no TCP based network communication can be deterministic.  This means Network Shared Variables are also not deterministic (they use a TCP for data transport) and I advise against using them as a means to send time critical control data between a Windows host and a LabVIEW Real-Time application.

In general, I would architect most LabVIEW-based control applications as follows:
- Write all control logic and IO operations in LabVIEW Real-Time.  The LabVIEW Real-Time application would accept set points and/or commands from the 'host' (desktop PC).  The Real-Time controller should be capable of running independently or automatically shutting down safely if communication to the PC is lost.
- Write a front-end user interface in LabVIEW that runs on the desktop PC.  Use Shared Variables with the RT-FIFO option enabled to send new set points and/or commands to the LabVIEW Real-Time target.

Shared variable buffering and RT-FIFOs can be a little confusing.  Granted not all control applications are the same, but I generally recommend against using buffering in control applications and in LabVIEW Real-Time applications recommend using the RT-FIFO option.  Here's why:  Imagine you have a Real-Time application with two timed loops.  Time-loop 'A' calculates the time critical control parameters that get written to hardware output in timed-loop 'B'.  Loop 'A' writes the outputs to a RT-FIFO enabled variable with a RT-FIFO length of 50.  Loop 'B' reads the outputs from the shared variable, but for some reason, if loop 'B' gets behind then the shared variable RT-FIFO will now contain several extra elements.  Unless loop 'b' runs extra fast to empty the RT-FIFO, loop 'B' will now start outputting values that it should have output on previous cycles.  The actual desired behavior is that loop 'B' should output the most recent control settings, which means you should turn off buffering and set the RT-FIFO length to 1.

There is also a clear distinction between buffering and the RT-FIFO option.  The RT-FIFO option is used to add a non-blocking layer between network communication and time-critical code in LabVIEW Real-Time applications.  It also provides a safe mechanism to share data between two loops running in a Real-Time application without introducing unnecessary jitter.  Network buffering is a feature that allows a client to receive data change updates from the server even if the client is reading the variable slower than the server is writing to it.  In the example I presented above you don't need to enable networking because the shared variable is used entirely within the Real-Time application.  However, it would be appropriate to send control set points from a Windows PC to the Real-Time application using network published shared variables with the RT-FIFO option enabled.  If it is critical that the Real-Time application executed all commands in the sequence they were sent then you could enable an appropriate buffer.  If the control application only needs the latest set point setting from the Windows host then you can safely disable network buffering (but you should still enable the RT-FIFO option with a length of 1 element.)

Network buffering is especially good if the writer is 'bursty' and the reading rate is relatively constant. In the robot application I can imagine buffering would be useful if you wanted to send a sequence of timed movements to the Real-Time controller using a cluster of timestamp and set point.  In this case, you may write the sequence values to the variable very quickly, but the Real-Time controller would read the set points out as it proceeded through the movements.

The following document presents a good overview of shared variable options:  http://zone.ni.com/devzone/cda/tut/p/id/4679

-Nick
LabVIEW R&D

~~
0 Kudos
Message 2 of 2
(2,643 Views)