Motion Control and Motor Drives

cancel
Showing results for 
Search instead for 
Did you mean: 

In a RT motion and data system, what is the best variable handling structure(s)?

I built a system that applies motion control to two axes and also takes data from a third axis encoder. 
The program structure is parallel timed loops (one motion control loop, one data collection loop, one host communication loop) with front panel.
This is targeted to a RT target; there is no host program.
 
Now I am using global variables to pass information between the loops and for exchanging information with the front panel indicators and controls.  I think this is a suboptimal solution.  I am considering the following changes:
 
1) For communicating variable values (such as commanded velocity and position) to the motion loop, I will replace the global variable structures with onboard variables in the motion card memory.
 
2) For saving the data collected from the third axis, I will use an RT-FIFO structure in the RT controller memory.
 
3) I will eliminate the front panel from the RT program and create a separate user interface program targeted to the host PC.  Communication between these programs will be accomplished using the Simple TCP/IP Messaging Protocol as described in this document:
Global variables will be replaced with Motion onboard variables.
 
Before I start this chore, am I following the best practice?  Any advice on improving any aspect of this plan?
 
My System:
Windows XP on P4 PC ethernet to
PXI-8187 RT Controller
PXI-7350 Motion Control board
(2) servo axes with quadrature feedback
(1) additional quadrature encoder used as measuring probe
I do not have a DAQ card in this system.
 
Thank you!
 
__________________________________
Laine
0 Kudos
Message 1 of 9
(5,443 Views)
Hello,
I agree with your approach.  I do believe that by doing those changes you will be following best practices.
I also recommend basing your program on the Command-based Architecture.   At the bottom of my "Simple TCP/IP Messaging Protocol" paper you'll find a link to my "Command-based Architecture for LabVIEW Real-Team" paper.  These approaches have proven to be successful in many applications.
 
Best Regards,
Daniel Elizalde
Senior Systems Engineer
National Instruments
0 Kudos
Message 2 of 9
(5,434 Views)

Thank you Daniel.  Yes, I am using your "Command-based Architecture for LabVIEW Real-Time" as a template.  I have some questions:

1) I notice that the Command Sender and Data Receiver loops on the host are running full-speed, as is the Command Parser loop on the target(i.e., no loop timers).  The Medium Priority Task loop on the target however has a 100ms timer.  Why is the Data Receiver loop on the host not also timed?  Does it need to run faster to avoid data backup?

2) Can data become asynchonous; i.e., get backed up in queue if the receive loop is slower than the send?  Is there a way to flush the queue in this case, and is that good practice?  I am getting old data now while trying to debug.

3) What are the priority settings of each VI (Target and Host)?

4) My meta data array is 60 elements.  I am getting a timeout error at Meta Data Send, even after setting the TCP send timeout to 90000 inside the Meta Data Send subVI.  It worked fine with a small (3-element) array.  I worked around by simply copying the meta data array to the host application.  Any ideas on why this could happen?

 

Thanks for your response!

 

 

__________________________________
Laine
0 Kudos
Message 3 of 9
(5,432 Views)

Hi,

Here are my thoughts on your questions:

1- The 'TCP Msg Read.vi' includes a timeout terminal.  By default it is set to 25 seconds.   This VI sleeps until a new frame is received or it times out.  This is why you don't need an extra 'wait' function to time the loop.

2- All that is handled internally by the TCP/IP driver.   The driver buffers data for you so even if the reader is slower, the driver will store the data for you until you are ready to read.   If the reader is too slow you will be getting timeout errors on the write operation.   Since the driver is buffering data, that is why you keep getting old data.   There is no direct way to flush the data.  You can try using the low level TCP functions to continuously read until all the data has been read.

3- You can check the priorities of each VI by going to the File>>VI Properties menu of each VI and then looking into the "Execution" dialog.

4-  I haven't seen any issues with sending big Metadata arrays.   Most likely it has to do something with your network settings and configuration.   The goal is that both the client and server have the exact same metadata.   Sending the data is a clean approach because you just have to maintain the data in one place.   But, if this approach is giving you trouble, having multiple copies of the metadata will work fine too.

Regards,

Daniel

0 Kudos
Message 4 of 9
(5,426 Views)

Wow this really works great!  Once I got the timing correct, everything is flowing smoothly. 

More information on the meta data transfer:  If I copy the meta data array to both host and target applications, all is fine.  If I use the Meta data transfer functions, the host creates the TCP connection and waits on Read Meta Data.vi.  The RT Target never stops listening for the TCP connection (like the host never created it).  I'll check differences with my original test program (which worked fine with the Meta Data read).  But this code seems to match exactly the example given in your paper.

One question on parsing commands received by the target:  Is it better to pass data to high-priority loops through RT-FIFOs (as in your example) or by onboard variables available on the motion card?  I'm having trouble with RT-FIFOs as in the following - if I have a value that needs to be read multiple times (e.g., motion velocity value, read each time I actuate an axis), I can read it once from an RT-FIFO, but then that FIFO is empty.  Do I need to copy the value to another structure (e.g., onboard variable or local variable) and read from that?  Or create 60 different shift registers (one for each variable) to pass default return values if the FIFO is empty?  What is the normal practice?

Thanks!

__________________________________
Laine
0 Kudos
Message 5 of 9
(5,407 Views)
Hello Laine,
 
RT FIFOs are the best way to pass data between the normal priority and high priority loops.  In your particular application, making use of shift registers would be the best way to take the value returned from the FIFO and allow it to be accessed several times.  In your case, it sounds like you would then have 60 shift registers, which may add a lot of confusion to your VI.  To account for this, you might consider bundling the values you read from the FIFOs into a cluster so that you have only one shift register containing all of the latest values from your FIFO reads.  Then you can unbundle elements as necessary.
 
I hope that helps answer your question.  If not, please post a reply.
 
Regards,
 
Kristi H
National Instruments
0 Kudos
Message 6 of 9
(5,392 Views)
Thanks Kristi.  I understand your recommendation.
 
Some of my variable instances are 4 or 5 SubVIs deep.  For instance, the main high priority loop calls MOVE.vi which calls CALC_ANGLE.vi, which calls CALC_MOVETIME.vi which calls CALC_VELOCITY.vi which uses the variable Initial_velocity.  If Initial_velocity is received from the host in the main program, passed to the high-priority loop using an RTFIFO, then bundled and kept in a shift register, what is the best way to get that information down where I need it?
 
Not only will I have to redeclare the RT-FIFO in each subVI, but I will also need to pass the reference value cluster down the chain as well?  This sounds messy and computationally expensive to me.  So my choices might be
 
1) Eliminate subVIs and bring everything to the top.  This is a rather large program, so could make quite an extensive top vi if all code is in one place.
 
2) Use onboard variables to store and pass values.  Are these less deterministic than RTFIFOs?  What is their primary purpose if not to pass data, or are they just to be used with motion card onboard programming?
 
3) Use global variables, but I think these are not deterministic.
 
4) Bite the bullet and pass the variable cluster down through the SubVI chain.  Is there an easier way to do this than what I describe above?
 
Have I made any bad assumptions or overcomplications?
 
Thanks.
__________________________________
Laine
0 Kudos
Message 7 of 9
(5,387 Views)

Hi Laine,

Unless your VIs are running in parallel, I would not recommend opening a new reference to the FIFO in each VI.  Passing the FIFO reference as a subVI should work sufficiently.  Do you think this is feasible?

Regards,

Kristi H

0 Kudos
Message 8 of 9
(5,371 Views)

Yes, this is what I'm trying now.  Not too bad, but a little wirey (is that a word?). 

I'll post an example when I finish; would appreciate your comments.

 

Thanks

__________________________________
Laine
0 Kudos
Message 9 of 9
(5,364 Views)