LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Skipping Elements in a Queue?

Hey folks! I have a queue that contains numbers that tells a system in what order 1 of 4 processes should be complete. This queue is ordered in an "ideal operating sequence" however sometimes a situation comes up where the current dequeued element cannot be processed at this time. Is there a way to have the queue skip to the next element and try the skipped element on the next iteration?
 
Say for example, I want to run process 1, process 2, process 3, and process 4, one at a time, in that order and that is how they are queued up. Let's say we run process 1 and everything looks good, so we run it and it completes. The system now looks at process 2 and there is a problem. Is there a way to skip this process for now and run process 3 and then attempt to run process 2 again when process 3 is complete? Bonus points if anyone knows a way to have the queue skip over multiple processes to find the first one that "passes" and can be run immediately.
 
I'm baffled on this one. I can get the queue to "skip" a process, but I can't find a way to have the program go back and try that process again at the next opportunity. Would I need to create another queue that stores skipped processes and then adds them to the beginning of the original queue? Thanks for your help folks!
 
-- Matt
0 Kudos
Message 1 of 13
(4,686 Views)

Your suggestion near the end is a valid one. The basic queue functionality only allows dequeuing the first or last element (although you don't necessarily need a second queue. You can simply pop the element back into the queue at either end right after dequeuing it).

Another option is to use the Preview Queue Elements along with the Flush Queue to be able to get an array of all the elements, but that seems like abusing the concept of the queue. Note that to get the elements, you need to wire T into the Return Elements terminal.


___________________
Try to take over the world!
Message 2 of 13
(4,676 Views)
Instead of creating a second queue, simply store the skipped elements in an array.  I think this would be much easier to process when it comes time to inserting elements back into the queue.  You could use a loop to insert all elements into the queue, or you could just index the array to insert a certain element or group of elements.  You could create a set of subvi's to perform certain queue functions like inserting an array of elements into a queue.  Just pass in the queue, and the array, and of course an error in.  Inside the subvi, use a loop with indexing enabled to insert the elements into the queue.  Where I work, we have a library of specialize queue vi's such as this.  One will insert an array of elements.  One will insert a multiline string (element, carraige return, element, etc...) all from one string constant.  These are quite useful.  You could create a subvi to remove the next element and store into an array.  This makes the main much easier to read and control.
- tbob

Inventor of the WORM Global
Message 3 of 13
(4,661 Views)

Thanks for the reply tst! I tried (unsuccessfully) to simply dequeue the element and then feed it back into the beginning of the queue but after thinking about it I abandoned the idea because wouldn't I have to use a second queue if I wanted the ability to skip more than one process?

I think the idea of not using another queue only works when there is only 1 process that can be "forced to wait" at a time. I did a rather poor job explaining it, but the situation can occur where a process can't be run until another process is run to free up the resource. So if I wanted to go 1,2,3,4 but 1 can't go, and 2 also can't go yet, if I just feed it back into the queue, the program just keeps trying 1 and 2, which neither will work until 3 moves. I pretty much just want to make sure my thought process isn't flawed here. Thanks again for the help, especially help coming from the Legendary tst!

 

-- Matt

0 Kudos
Message 4 of 13
(4,660 Views)

Why not just enqueue the element at the end of the queue?

Also, if your processes have certain dependencies, you may wish to think a bit more about how you will structure this. It's quite possible that you can find a much better architecture for doing this.

As tbob said, if you don't need serious speed or have a lot of elements, you can simply emulate the queue functionality yourself using LV2 global or even single-element queues globals. Smiley Very Happy


___________________
Try to take over the world!
Message 5 of 13
(4,653 Views)
Thank you kindly tbob! I like the subvi idea, the main program was clean and orderly looking until I started desperately throwing alot of messy code down in an attempt to get this aspect of it working. It felt like I was taking the Mona Lisa and adding on a Hooters t-shirt, a mesh trucker hat, and some KISS makeup all in fingerpaint on her. In other words, I was starting to suspect that what I was doing was tacky...and on top of that, it wasn't working.
 
Thanks again guys!
0 Kudos
Message 6 of 13
(4,651 Views)
tst, I also think you might be correct about me needing to restructure the program. I've been trying to "tack" too much onto a program that wasn't initially designed with these restrictions in mind. It just seems like a rubix cube, to get one side solved I have to completely alter and interfer with another side.
 
-- Matt
0 Kudos
Message 7 of 13
(4,637 Views)
Are you using a state machine of some sort? This sounds like an ideal candidate for a state machine architecture. At the end of the state where Process 1 finishes it checks the condition of the preferred next process, the list of deferred processes, and any other relavant variables to determine the next state. The preferred and deferred process lists could be arrays, queues, functional globals, or perhaps other dataforms. This Next State/Process checking could be done in a subVI to keep the diagram from becoming too cluttered. And if the desired arrangements change, you only need to change the subVI, not logic in every state.

Lynn
Message 8 of 13
(4,623 Views)

I don't currently think I am currently using a state machine, at least not intentionally. I'll read up on them tonight. I've posted a few times to get help on this program and people have been gracious enough to keep me moving in the right direction. It's the same one from my "Barrels of LabVIEW" post a few weeks ago.

I basically can have up to 5 different "sequences", with each sequence moving a barrel around 40 different tanks to soak in each for a given period of time. The arm moves around thanks to it being able to use a photoeye to "count" reflectors on the tanks to know its current position. The part that has been the bane of my LabVIEW existence is that the barrels all share the same tanks and only one barrel is allowed in a tank at a time. I've tried using harsh words and yelling at the robot lift when it drops a barrel into a tank that is already occupied...but apparently negative re-inforcement does not work on robots.

-- Matt

0 Kudos
Message 9 of 13
(4,618 Views)
I think you need to get the robot's attention first.

Lynn
0 Kudos
Message 10 of 13
(4,591 Views)