Random Ramblings on LabVIEW Design

Community Browser
Labels
cancel
Showing results for 
Search instead for 
Did you mean: 

Re: State Machines Done Right

Active Participant

 

Hello All

Not long until my USA tour (Chicago -> Albuquerque -> Austin) and I'm very much looking forward to it. So I'm busy clearing down my workload and looky here I have an hour to spare. I'm going to use it to write about state machines.

 

So first point is a Queued Message Handler (QMH) is NOT a state machine and our standard architecture that pretty much works for everything consists of...

 

Event Structure

State Machine

QMH for UI

0>more QMHs for error handing or communications or printing or whatever.

 

Optionally dialogs can have their own state machines and QMHs if they are of the wizard type.

 

We like our state machines match a State Transition Diagram and that means they have a state (doing something) and a transition (instruction to do something else).

Like this.

StateMachine.png
Whereas the classic LabVIEW state machine looks like this (replace enums with strings if you enjoy a little more guesswork/freedom in your designs)

SM1.png
You can see that there's state info, but no transition info, in fact the transition is at the point where the tunnel leaves the case structure.


In our way of doing it we have a transition queue that we can do multiple things too. It can just hold up the state, it can timeout and go round again or in the example below it just loops until told not to.

StateMachine2.png

So in the above example it gets confirmation from the host that the port is opened and that is the transition trigger to the next state.

 

The snippet maps nicely to the following diagram.

 

StateMachine3.png
Which is all nice and neat.

 

Anyway if you're in Albuquerque 21st July-28th July 2018 DM me and I'll let you buy me a drink for all the articles I write, or maybe I should buy you a drink for reading them Smiley Happy

Lots of Love

Steve

 

 

 

 

Comments
Active Participant

@swattsSteve wrote: 

So first point is a Queued Message Handler (QMH) is NOT a state machine


This! I wish everybody knew and understood this statement!

 

As usual, you managed to write a brief article, yet full of interesting tips and information. I have seen multiple implementations of the transition section of the code. Regardless of the implementation, I think it is important to separate what the state does from how the state machine decides what the next state is.

 

Looking forward to seeing you during your US tour.

 

Fab

Certified LabVIEW Architect * Certified LabVIEW Embedded Developer * Certified Professional Instructor * LabVIEW Champion * Code Janitor
Proven Zealot

Fab (who remains Fabulous) said she wished everyone knew and understood that "A Queued Message Handler (QMH) is NOT a state machine".  I count myself among the "Great Confused", as I use (some of) the mechanisms of the QMH to "Do one thing at a time" (e.g. Handle a particular "Message") and when done, either explicitly say "Now do the next thing" (by sending a Message) or, if we need to wait for User Input, letting the Event Loop send the Message at the appropriate time (when the User provides the Input).

 

I think Crossrulz once explained the difference between a Queued State Machine and a Queued Message Handler (but I can't find that post!).  Steve's example of a State Machine has a Queue that (it appears to me) essentially determines the Next State (a little indirectly) -- is this a QSM, or a Q + SM?

 

I have the sense that this is more than just Semantics, that there are "traps" that the QMH model might allow/encourage that are anathema to the State Machine model.  I'm trying to understand the essence of the SM, and how strict one needs to be (must the State be stored on a Shift Register?, for example), and why.

 

Bob Schor

Member

If you manage a stop in Denver, I'll buy you a beer.

Sam Taggart
CLA, LabVIEW Champion
automatedenver.com
Active Participant

@Fab : Agree with the implementation comment, seen some nice implementations that have an event structure after the state while loop (James Powell favours this). 

 

@Bob : For me it's having a clear state and a clear transition from that state. If you scratched the surface of my implementation you'll find a mixture of ways that I transition from a state. The key is to have mechanisms in place to handle those choices. In short you should be able to model your code accurately and concisely as a State Diagram. So you noticed correctly we use queues to fire our transitions, but that could be user events, global state changes or whatever you prefer. The important thing is not the mechanism, the important thing is mapping to a design.

 

As a practical example try mapping a QMH or a conventional state machine to a diagram and I'll wager you'll find it a bit tricky. Whereas a design that allows for a state (doing something) and a transition (go do something else) will map easily. Again this is most beneficial when your state machines get large!

Trigger.png

The example above is just 1 small function in my oscilloscope system, if you're sharp eyed you'll notice I've been a bit lazy in my state naming. The state should be (verb)ing a noun really. So Checking Master Trigger rather than Check Master Trigger.

 

@Sam sadly no Denver this time, taking the super fast bullet train from Chicago to ABQ, which has always been an ambition of mine. So will be seeing Colorado from the viewing coach.

Knight of NI

Bob,

Here is one of my posts telling the difference: Difference between QSM and QMH.  I know I have a better explanation floating around, but lack the time to find it right now.  But it essentially comes down to who controls what the loop is doing.  A QSM is in total control of itself while the QMH is purely reactionary to other loops telling it what to do.  Of course, then the grey areas come in such as a QSM getting messages from other loops and therefore goes into a transition state (but the state queue is still entirely owned by the QSM) or the QMH does something in a timeout condition (read instrument data, flush data file, etc).


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

Bob,

 

First, thanks for the compliment Smiley Wink

 

The main issue I see with treating a QMH as a State Machine is that a QMH can get messages enqueued from anywhere, not just from the message being handled at one moment within the Message Handling Loop. Even more worrisome, if the code enqueues multiple messages, there is no guarantee that a message from somewhere else will not be able to get enqueued in between.

 

To me, the State Machine should determine what makes the transition to the next state within the state machine itself. Also, there is a guarantee that if I tell the state machine to do Step 1 through Step 3, no other steps can ever be inserted between 1 and 3 (except for an abort or exit).

 

At one of the presentations I gave at NI Week this year, I dedicated tip 4 on how to add a state machine within a DQMH. This allows the module to benefit from the advantages of a QMH and at the same time ensure that a series of steps, that need to be sequential and uninterrupted, are executed in a state machine fashion.

 

I hope this helps to clarify my statement.

 

Regards,

Fab

Certified LabVIEW Architect * Certified LabVIEW Embedded Developer * Certified Professional Instructor * LabVIEW Champion * Code Janitor