![]() |
Multiple Dequeue Element VIs in loop
1 Attachment(s)
I'm fairly new to LabVIEW, so bear with me here... :rolleyes:
I am working on a project that entails real-time command of 6 non-FRC robots over virtual COM ports. To send the commands, I have been utilizing a state-machine architecture. I created one event handling loop, one state-machine loop, and 6 queues - one for each robot. I set these queues up with different names, and input a Dequeue Element VI for each queue in the state-machine loop. When I ran the program, only one Dequeue Element functioned, even though there were no error outs. As a result, only one robot received commands. I scaled down to a 2-robot program to simplify things, only to get the same result. However, when I took one Dequeue Element out of the state-machine loop and put it into a new, additional state-machine loop, both robots received their commands (see attached figure). Does anyone know why having multiple Dequeue Elements in one state-machine loop did not work out? The code attached works, but for future purposes, I would like to know and cannot seem to find any documentation that would explain my results. Thanks! |
Re: Multiple Dequeue Element VIs in loop
I'm far from a Labview expert (only experience has been with custom dashboard functionality) so forgive me if I'm off base, but I think I see the potential problem.
It looks like your command is getting bundled into a cluster in the case statement on the left ("Submit Turn...) and you're trying to pass the cluster to all 6 robots for processing by all N robots (I assume the dequeue block is the block at the top of the "Robot 2" case). Is that correct? If so, then your problem is that you're not processing all N robots since the case labeled "Robot 2" is only being processed for whatever the tab control is set to. You probably either want to either loop over your N robots or process them in parallel somehow. Hopefully that helps EDIT: Now that I look at it again, I might have been misinterpreting it slightly. Logically, it would make sense for the block in the "Robot 2" case to be the enqueue and the dequeue to be in the "Robot N" loops you have at the top and bottom, with the dequeue being the block on the left side of those. The issue of not processing all queues because of the case statement is still an issue though because you'll only enqueue for the selected robot. So it might not be a problem with the dequeues, but rather an issue of enqueuing for all the robots |
Re: Multiple Dequeue Element VIs in loop
Actually, I only pass a cluster to one robot at a time. I have my GUI set up such that I select the robot I want to apply a command to and then enter values for velocity, distance, etc. All of that information is what gets clustered. With this structure, I can wait any amount of time before inputting another command for any of the robots, and have those commands process immediately.
The Dequeue Element VI is actually the block on the left of each state-machine, here. What I had before was one state-machine with two Dequeue Elements in parallel inside. Thanks anyway! |
Re: Multiple Dequeue Element VIs in loop
1 Attachment(s)
I went through the exercise of making a test program and got it to work. It's based around the same model that you have. The loop in the middle waits for the input and enqueues it to the necessary queue. The other two loops are waiting on their dequeue and will update the corresponding output when data is seen. This seems to work as expected. See the attached diagram
My example used just an integer as input, but I tried passing a cluster around to make sure there wasn't something different with that, but it worked just fine. Have you tried to run with the execution highlighted to make sure your loops are running as expected? I had a bug when testing that caused only one loop to run (made the mistake of having a stop control from one loop tied to the end condition of the other while loops). Maybe you're hitting something silly like that? |
Re: Multiple Dequeue Element VIs in loop
I apologize for the confusion about what I'm actually asking - The picture I attached (one Dequeue per state-machine loop) is the code I got to work. I was curious as to why my previous code, the one that had two Dequeues in one state-machine loop, didn't.
Could I possibly be having race condition issues? I didn't think so because of the fact that I have separate clusters for separate queues going to separate robots, but am I wrong? Thanks! |
Re: Multiple Dequeue Element VIs in loop
Sorry for misinterpreting your question. Hopefully third time's the charm.
I changed my example to have a two loops instead of three like you're saying. In the "state machine" loop, I put two dequeue statements in parallel that update their corresponding outputs. What I found was that when the iteration of the loop starts, both dequeue blocks are sitting waiting for data. When one queue gets its data, the second queue is still blocking. Unless that second queue data gets data, the first queue will never be dequeued again. This is because the loop iteration can't complete since everything inside the loop hasn't completed. I was able to get this to work by doing the following - On the timeout terminal of the dequeue block, add a constant of 1 (dequeue tries to get data for 1ms then gives up) - Send the timed out terminal into a case structure. In the false case, put your processing of the data from the queue What this will do is give each queue a chance (1ms) to process each loop of the iteration. If there is data waiting for it, it will be processed. If not, it wastes the amount of ms in the timeout. Chances are with the way Labview works, they will all happen in parallel since they're not dependent on each other, which means you shouldn't be wasting too much time in the timeout cases. I can post a picture if you need me to. |
Re: Multiple Dequeue Element VIs in loop
Correctly diagnosed.
As originally written, but not what was posted, the code was told to wait for all six queues to have something posted to them before running the next loop iteration and processing the second command in any of the queues. That would in fact be a pretty odd requirement for a state machine, but that was what was written. Using the timeout to avoid the blocking of the dequeues will allow the original code to work, but it also makes it effectively a polled loop. Technically, the loop will run sooner if all queues have something in them, but if nothing is posted, the loop would run every 1ms. Probably not a big performance issue, but that would depend on what you expect. Depending on what is being enqueued and how they are processed, there are two pretty common patterns. 1. Go with a loop per queue. Don't be afraid to put the loop into a subVI which may allow you to reuse code depending on the processing, and will make the code much more readable. Because LV execution is not stack based, the engine can efficiently sleep very large numbers of parallel code clumps such as the loops, and they will awaken and be scheduled with very little overhead. 2. If you are wanting to process the results more centrally because of combined effects, consider posting to a single queue, but put an array into the queue data and combine up to your six data items into the array. Greg McKaskle |
Re: Multiple Dequeue Element VIs in loop
Dave and Greg: Thank you for your suggestions! Looks like I've got the original program up and running now (although I will indeed be keeping the multiple state-machines as set up in my revised program as you both have suggested).
|
| All times are GMT -5. The time now is 11:06. |
Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Copyright © Chief Delphi