cancel
Showing results for 
Search instead for 
Did you mean: 
Reply

[QMH] Having a state repeat until a condition is met (without blocking)

Solved!
Go to solution

[QMH] Having a state repeat until a condition is met (without blocking)

Hello all!

 

I'm using a QMHarchitecture to control a robotic system.  I'm still learning more and more about the QMH programming architecture.  I have a total of 4 queues, currently:

  • UI
  • Serial Data
  • DAQMx Tasks
  • Datalogging

I have some laser sensors that will output a boolean if there is something in front vs nothing in front of them.  I also have a series of commands that I send to the various queues (haven't gotten there yet, but getting close).  My question is: How can I create a state (in the "tasks" queue) that will repeat itself until the lasers' booleans become true (then, move on to the next queued element).

 

Thanks,

Joe

0 Kudos
Message 1 of 13
(346 Views)
Highlighted
Solution
Accepted by topic author JoeKellyATI
02-09-2018 12:48 PM

Re: [QMH] Having a state repeat until a condition is met (without blocking)

What I like to do is use the queue's timeout.  You can store what the timeout should be in a shift register.  If you set it to -1, it will wait forever.  So if you do not get a timeout, you can process the message and react to it.  If you do get a timeout, you will get the default state and a Boolean output (Timed Out) will be TRUE.  So when you do get a timeout, you can do something.  If you have multiple things that could be set in a timeout condition, you can store the state to run when you get a timeout in a shift register.  A simple Select will make this simple to choose between the queue's state output and the stored state based on the Timed Out Boolean.


There are only two ways to tell somebody thanks: Kudos and Marked Solutions
Unofficial Forum Rules and Guidelines

The discussions from the Advanced User Track is not over. Join in the conversation: 2016 Advanced Users Track
Message 2 of 13
(309 Views)

Re: [QMH] Having a state repeat until a condition is met (without blocking)

So I'll admit that crossrulz suggestion above is awesome and I'm definitely going to use that implementation in the future. What I've done in the past is have the repeating state check to see if the Boolean condition is met, and if not, enqueue itself at the front of the queue. That way it would repeat itself. But this only works if nothing else will be enqueuing messages at the front of that specific queue.

Daniel K | Hiller Measurements | Certified LabVIEW Developer
0 Kudos
Message 3 of 13
(301 Views)

Re: [QMH] Having a state repeat until a condition is met (without blocking)


@ wrote:

So I'll admit that crossrulz suggestion above is awesome and I'm definitely going to use that implementation in the future. What I've done in the past is have the repeating state check to see if the Boolean condition is met, and if not, enqueue itself at the front of the queue. That way it would repeat itself. But this only works if nothing else will be enqueuing messages at the front of that specific queue.


There have been several threads lately about why this is a bad idea.  In short, a QMH should never enqueue its own state because you are causing race conditions with other loops trying to send messages and/or you cause infinite loops.


There are only two ways to tell somebody thanks: Kudos and Marked Solutions
Unofficial Forum Rules and Guidelines

The discussions from the Advanced User Track is not over. Join in the conversation: 2016 Advanced Users Track
Message 4 of 13
(293 Views)

Re: [QMH] Having a state repeat until a condition is met (without blocking)

I for one would definitely *not* have a repeating state enqueue itself to the front.  That's an infinite loop waiting to happen!  I *would* consider enqueuing to the back like normal, allowing other messages a chance to break in.

 

I've actually put together a library for QMH's that I call "scheduled messages."   I have a wrapper for the Dequeue function (reentrant of course) which knows about these scheduled messages.  When you wire in a timeout that extends beyond the time when the next scheduled message should fire, the wrapper function handles that and returns the scheduled message at the right time (if no other regular messages arrive before that).

 

It's been a handy way to make sure certain processing or status checking happens at a regular rate, even in the presence of lots of other message processing.  A simple timeout often won't work very cleanly for me because my main loop rarely goes even as much as 100 msec between messages (it's the consumer for a bunch of instrument interface producer loops).

 

 

-Kevin P  

Message 5 of 13
(290 Views)

Re: [QMH] Having a state repeat until a condition is met (without blocking)

Thanks Cruossrulz!

 

I like the idea of the shift register!  Just to clarify (and explain to others that might happen on this thread), here's what I ended up doing (and what seems to be working).

 

I have the while loop that dequeues from the queue every millisecond (then timeout and jumps to the Default case).  One of my cases , when called, checks the statues of the sensors and checks if there is something in front of them.  I have this boolean wired to a Select block.  The True side puts the case string into the shift register.  The False case puts an empty string into the shift register.  Every While loop iteration, if the Dequeue message VI gets timed out, it outputs a True boolean into a case structure.  That case structure just holds an Enqueue Message VI, and it enqueues the message that is stored in the shift register.

 

The VI I have is large, so I can't post it easily.  If anyone wants a simplified version, I can make one up.

 

Thanks!

0 Kudos
Message 6 of 13
(259 Views)

Re: [QMH] Having a state repeat until a condition is met (without blocking)


@ wrote:

That case structure just holds an Enqueue Message VI, and it enqueues the message that is stored in the shift register.


Do NOT do the.  As I stated before, a QMH should never Enqueue to itself.  Just go to the state you put in the shift register in a timeout condition.  Use the Select function.


There are only two ways to tell somebody thanks: Kudos and Marked Solutions
Unofficial Forum Rules and Guidelines

The discussions from the Advanced User Track is not over. Join in the conversation: 2016 Advanced Users Track
0 Kudos
Message 7 of 13
(242 Views)

Re: [QMH] Having a state repeat until a condition is met (without blocking)

Oh!  I see what you're saying now!  Use the timeout boolean as the "Selector" for either the repeated state or the next state.

 

I'll try that, thanks!

0 Kudos
Message 8 of 13
(238 Views)

Re: [QMH] Having a state repeat until a condition is met (without blocking)

OK, new problem (still related to this though).

 

In one of my User Event cases, I send a bunch of states to my queue at one time.  One of those states is this repeating state. 

 

Here's what I want:

Let's say I'm sending 5 states to the queue.  State 3 is the "wait" stage.  I want the state machine to run state 1, then 2, then 3 (repeat until condition is met), run 4, then run 5.

 

Here's what's happening:

I send 5 states to the queue, and it queues all of the states up at the same time.  So, it runs 1, then 2, then 3, then 4, then 5, then it repeats 3 until the condition is met.

 

I started looking at my method, and I found that in order for the "Dequeue" VI to time out is if it has zero states queued up.  So, it makes sense that the state machine would run through all of the states before coming back to the repeating stage.  Am I missing something?

 

If I need to make a simplified VI to show what I'm doing, I can.

 

Thanks!

0 Kudos
Message 9 of 13
(234 Views)

Re: [QMH] Having a state repeat until a condition is met (without blocking)

Just enqueue 1, 2, and 3.  Then in 3, you set the timeout state to be 3 until you get that condition and then you can set it to 4.  Then 4 can set it to 5.  5 can state to not timeout.  This way you can still receive messages and react to them even while waiting for the condition.


There are only two ways to tell somebody thanks: Kudos and Marked Solutions
Unofficial Forum Rules and Guidelines

The discussions from the Advanced User Track is not over. Join in the conversation: 2016 Advanced Users Track
0 Kudos
Message 10 of 13
(190 Views)