02-25-2009 07:06 AM
Hi all, and thanks for the answers..
The reason for running timed loops is that I can assign priorities to the processes I run.
In the DAQ & Control & Logging classes - I start a new process with a queue as one of the input arguments. For example, using concurrent daq read processes, it is possible to gather data at a configurable loop rate. Storing data to a disk only require a process running about 1Hz or less. A PID controller loop running at 100Hz requre much faster reads and the most recent samples avaliable. So for example, running several concurrent daq processes at different rates and priorities and at the same time assigning the queues to the corresponding several pid controller loops or log loop require the ability to set priorities for deterministic RT control?
Regards,
/Roger
02-25-2009 07:27 AM
Roger,
there is no need to store all code in timed structures only to determine priorities. To be honest, setting proper priorities needs good planning; otherwise it can easily mess up your whole system!
Please read the following excerp of the LV help:
A Timed Loop executes in the data flow of a block diagram ahead of any VI not configured to run at a time-critical priority.
A "normal" loop uses the priority of the VI it is running in, so if you set the priority of the VI to time-critical, a "normal" loop has a higher priority than any timed structure!
Using timed structures to divide the application in different threads is not necessary as well since LV tries to divide the VI into several threads on its own. The only thing you have to know is:
- A "normal" loop consists in general of at least one thread (could be less if more than a loop is put into one thread which is very seldom {if at all})
- A timed loop always creates a single thread which contains every part of the code in the loop.
Therefore, using timed structures with large code included might have negative impact in performance on multicore-machines (in comparison to "normal" structures)!
And please keep in mind that Real Time (e.g. determinism) does not necessarily need multiple priorities at all.
hope this helps,
Norbert
02-25-2009 07:37 AM - edited 02-25-2009 07:38 AM
RogerI wrote:Hi all, and thanks for the answers..
The reason for running timed loops is that I can assign priorities to the processes I run.
...
/Roger
Maybe use a "smaller hammer". If you put a while loop inside of a Time Sequence, you can assign priority without having to work-around the Timed Loops nature.
Returning to your "fix";
Checking for a timeout is part of most of my queue checking code, see below.
Ben
02-25-2009 07:41 AM
First of all, do you need the PID loop to be separate from the data acquisition loop?
I understand that you want the PID loop to run at a deterministic rate, but then a queue is probably not the best way to transfer the data. Probably you could just use a local variable so you always have the latest value acquired by the DAQ loop in it. Or use a functional global or something similar.
If you want to use a queue in a timed loop you'll probably set the dequeue timeout to 0. If it times out, use the latest valid value (which you can store in a shift register).
02-25-2009 08:15 AM - edited 02-25-2009 08:20 AM
Waiting for a 0ms timeout could be an obvious solution if control jitter isn't taken care of. Suppose process A enqueues an element at time T, with interval I, and process B try to dequeue at Time T-1, with interval I. This would mean that the control jitter would be equal to I?
I have to think through the loop rates and priorities as suggested. I'll come up with some code as well. 🙂
/Roger
02-25-2009 08:31 AM
This may be completely out of context, but when I need to use a timed loop to acquire data, I use a Daemon (dynamic VI) which is spawned, executes, and is killed when the calling program is done.
The Daemon simply collects the data and stores it either in a queue or a Functional Global depending on the implementation and chosen architecture.
R
02-25-2009 08:37 AM
dan_u,
I use queues because they are fast and neater than global/local variables. 🙂
/Roger
02-25-2009 08:40 AM
Roger,
that is not entirely true (to quote from the film ID4).
Globale Variables in fact are the fastest mechanism for transferring data. But you are correct: They are not neat! Main reason: they are prone to race conditions, one of the ugliest things to debug!
Norbert
02-25-2009 08:42 AM
Ray.R,
It sounds more or less like what I have implemented. It actually works great, except for my timed loop thought glitches.. 🙂
The reason is that I'm trying to make daq/control object oriented, reusable and suitable for multicore/processor architectures.
/Roger
02-25-2009 08:52 AM
I was not talking about global variables, but functional globals (similar to what Ray suggested).
In the DAQ loop, write the current value to a functional global (using a write method), in the PID loop read it.
But you might still encounter sync problems (i.e. sometimes reading the same value twice or missing a value).
A queue with timeout in a timed loop on the other hand will cause jitter. I think you have to decide whether you want to accept jitter (but then you can as well just use a while loop and dequeue without timeout) or not. If not, use one of the methods described before (functional global, dequeue with timeout 0, local variable, ...).