Random Ramblings on LabVIEW Design

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

Parsing State Machines: An Iterative Design Process

swatts
Active Participant

Joerg Hampel is a guest blogger. As the owner of Hampel Software Engineering, a CLA and LabVIEW Champion, his professional interest lies in team development best practices.

 

G’day my marvellous mates (me speaking in the beloved non-comprehensible Steve Watts way)!

 

Last year, one of our customer projects called for a proper state machine for sequencing the actions and events in a test system. A robot, a PLC, a DAQ device and the operator play the most important parts in that system. Inspired by one of Steve’s recent ramblings and a previous heated discussion with another customer on how to integrate state machine logic into a DQMH module, I decided to set out and create a reference design for an HSE State Machine.

The Design

Steve was generous enough to share SSDC’s rock-solid state machine design with us. It basically advocates the use of states while the system is doing something, and transitions for leaving and changing between states.

 

Basic stateBasic state

Basic state

 

The screenshot shows a regular state with a VI waiting indefinitely (i.e. without timeout) for transitions to be sent from outside the state machine, and then decide on a per-state basis how to react to any given transition sent to the state machine.

 

SSDC uses queues for most of their communication needs, and also for sending transitions to their state machines. Seeing as DQMH uses events for communicating with or from a module, I did not want to introduce another mechanism which would potentially confuse team members and other users of our open-sourced code. After lots of discussion with Steve weighing the pros and cons, I decided to go with events.

 

Deviating further from the Original SSDC School of Pure State Machinery, I want our reference design to not only react to externally (i.e. explicitly) triggered transitions, but also be able to react implicitly to changing conditions in the system.

 

Polling state: Waiting while required system state is not reachedPolling state: Waiting while required system state is not reached

Polling state: Waiting while required system state is not reached

 

The screenshot shows a polling state that waits for a certain boolean value (which is acquired somewhere else) to turn from False to True. While it’s waiting, other transitions are evaluated periodically. If no transition is received, the case structure is left but the state doesn’t change, so the same case is entered again.

 

Polling state: Reacting to the expected system state change implicitlyPolling state: Reacting to the expected system state change implicitly

Polling state: Reacting to the expected system state change implicitly

 

When the required system change eventually happens, the transition from the current state to the next (that’s “Waiting for Radiator Ramp-Up” to “Waiting for Radiator Settling” in the example screenshot) happens implicitly, i.e. without triggering it from outside the state machine.

 

The reasoning behind this design decision is that evaluating a given system status inside the state machine gives context to the evaluation. If I need to debug the system, I will know immediately where to look for the logic.

 

Steve: “There's certainly no rule that says a shared transition scheme per state is required, I reckon that is acceptable from a design perspective (might cause some navigation issues if you're firing transitions outside of the state). So a minor cohesion hit, but with a simplicity benefit”

 

The Documentation

For a number of reasons, the only documentation in our projects that we can expect to be up-to-date and complete is the actual code itself. While that may or may not be sufficient for maintaining and expanding software, we still need to produce human-readable (i.e. readable without opening the IDE) information about the code. Some customers require this so they can file it. Others are interested in the current state of the project from time to time. For the real meat in this, though, read on…

 

So in order to satisfy the need for that human-readable documentation of our state machine, why not look into generating a state diagram programmatically from the LabVIEW code? With a bit of VI scripting - and a lot of trial and error - I was able to come up with a program that parses a VI for a case structure with a given label, and then drills down and identifies all the states, transitions and their interdependencies. These are then expressed in PlantUML, an awesome open-source tool that allows the generation of UML diagrams from a plain text language (many thanks to Benjamin Hinrichs for pointing me to PlantUML in the first place).

 

Excerpt of a programmatically generated PlantUML state diagramExcerpt of a programmatically generated PlantUML state diagram

Excerpt of a programmatically generated PlantUML state diagram

 

Big outlined arrows represent explicit transitions (i.e. transitions that are triggered somewhere outside the state machine), small filled arrows visualize implicit transitions that result from polling states, and polling transitions (i.e re-entering the same state over and over again) are visualised with dashed lines.

 

While implementing the parser, I already stumbled over a few flaws both in the design and the execution of my state machine code. 

 

For example, the polling case structure had the boolean value of the polling condition wired directly. It turned out that having an enum with readable values (“Check transitions…” and “Leave this state!” is what I settled on) instead of true and false is beneficial both to the readability of the code and to the automated parsing of it.

 

There were a few other places where I had to settle on a unified way of implementing things, define some extra labels and make them visible, and so on.

Circling back from Documentation to Design

What I didn’t expect, though, was the immediate impact that looking at the generated diagram had: An impact on visualising and understanding the state machine I was working on, and an impact on identifying flaws in both the naming and the sequencing of states and transitions.

 

Example of misleading combination/use of transitionsExample of misleading combination/use of transitions

Example of misleading combination/use of transitions

 

Image6.png

Example of questionable reuse of transitions

 

Having these diagrams readily available when discussing different design decisions makes it so much easier to explain the ideas and the theory behind each decision. One recent example is the question of whether to have different dedicated transitions instead of a fewer number of transitions but with parameters (the answer: yes!).

 

Steve: “That's really useful from a design perspective too. The cycle of looking at a diagram and seeing design issues is not something I've considered.”

 

It’s easy to see how this kind of documentation complements our design reviews, especially as it comes with very little effort due to the programmatic approach. And as we usually go through an iterative design process, both internally and with our customers, having up-to-date state diagrams handy without having to put in the work? That’s priceless!

Automation

Seeing as we already make extended use of server-side automation - aka continuous integration - our Release Automation Tools now generate not only documentation of our libraries and DQMH modules (go take a look at Wovalab’s Doc-Generator) but also of all our state machines. For all our internal and external projects. All fully automated on our build servers.

 

Where can I get that??

If I did my job right, you must be craving some automated documentation for yourself now. The way I see it, there are two options for you:

 

1. Visit rat.hampel-soft.com for more information on our ready-made tools

 

2. Take part in one of our DSH Pragmatic Software Development Workshops and start learning about this - and much more. Planning on coming to you in 2020 (Albuquerque, NM), NIWeek (Austin, TX), GDevConNA (Denver, CO), GDevCon (CERN), and eventually NIDays (Munich, Germany). Tickets will be available as soon as we know what's going on with the world.

 

Until then, keep on wirin’!

 

Love,

J.

Steve


Opportunity to learn from experienced developers / entrepeneurs (Fab,Joerg and Brian amongst them):
DSH Pragmatic Software Development Workshop


Random Ramblings Index
My Profile

Comments