This would be trivial to implement in LabVIEW without any toolkit, but it's even easier with LabHSM! We'll call it “Demo_ABC” (under the assumption that, at this point, you haven't bought your license and are still restricted to files starting with “Demo_”).
If you have used LabHSM Editor version 1.0 and have not yet used version 1.1, see these
changes. (If this is your first exposure to LabHSM, you've got nothing to unlearn. )
Using LabVIEW scripting, the LabHSM Editor makes changes on the block diagram of the "agent" VI to keep it in step with changes you make to actions in the editor. To make changes on a diagram, there has to be a diagram. So we have to follow the directions in the README file to open a new VI and a new HSM and save them both before proceeding with our editing. If you don't follow the directions exactly, you'll soon discover that once you've opened the editor it is difficult to open a new VI , so follow closely at least for now. (At Mike Ross's suggestion, we'll mark each step of the project with the icon and leave the explanations and discussions unmarked, to help you follow along and recover if you misstep. Please let us know if you have suggestions for either the tutorials or the LabHSM
Start up LabVIEW, if it is not already running.
Create a new blank VI.
Pop-up and select the LabHSM - HSM Template.vi from the LabHSM directory in the User Libraries folder.
This is a merge VI. Drop it onto your untitled diagram.
WHOA! Your diagram certainly isn't empty any more! Don't be intimidated with the giant diagram; things are quite modular and you'll never need to see everything at once, as we'll learn later.
(An alternative to the previous three steps is to create the new VI from LabHSM - HSM Template.vit. The effect is the same.)
Save this VI as Demo_ABC.vi in a convenient place.
Now, click the Tools menu and the LabHSM Editor... selection.
Your screen should look something like Figure 2. (Well, it probably has a Windows look, but we are platform independent and wanted to show off. )
Figure 2: Initial Screen
Click the NEW button at the lower left of the Editor panel, select File>>New from the menus, or type ctrl-N (cmd-N on the Mac) to open a new HSM project.
(Notice that the latter two operations no longer create new VIs. Good thing we already created ours.) You should now have a basic, default, state machine definition as in Figure 3.
Figure 3: A New Hierarchical State Machine
Click the SAVE button at the bottom of the Editor panel, select File>>Save from the menus, or type ctrl-S (cmd-S on the Mac), make sure you're in the folder where you just stored Demo_ABC.vi, type Demo_ABC.hsm in the dialog, and click OK. (The editor will add the .hsm extension automatically if you leave it out.)
Defining the Project
The right hand half of the editor panel is grayed out; no Transitions for Selected State are defined yet. According to our definition, the C state should transition to state A when the + button is pressed. Let's enter this rule.
Mouse down on the None event and choose Plus from the pop-up.
The right hand half is no longer grayed because this defines one transition for this state. Right now it's a self-transition, notice that the Target State (highlighted in red) is C, which is wrong.
Click on the A state in the Target State window and the desired transition is defined (Figure 7).
Figure 7: C to A Transition Defined
Click the B state in the left hand window, choose Plus and state C in the right, and the B transitions are defined.
Repeat this series for the A to B transition.
The project definition says that we should be able to get from A to C by clicking the - button. This is a new transition.
Click the increasing index button on the Defined Transitions for Selected State array to access the (currently grayed) transition 1.
This time chose the Minus event and state C as the target (Figure 8).
Figure 8: A to C Transition
At this point, we have defined all the transitions mentioned in our design, but how do we get into the ABC loop to start with. One possibility would be to define, for instance, state A as the default, in place of the Ready/Idle state. Instead, since you usually will need an Idle state, we'll define one more transition: an automatic one from Ready/Idle to A.
Just select Ready/Idle in the left window and state A in the right one, leaving the Event at None.
(Trust me. This will make Ready/Idle an ephemeral state and drop us right into the ABC loop on startup. And we haven't dropped any of the original functionality, should we ever need it later.)
Now we are really through with the LabHSM Editor.
Click the SAVE button to update the Demo_ABC.hsm file.
You could click EXIT to close the Editor window, but you'll probably want to make some changes to see if you really know how to drive this thing.
Implementing the Model
Now comes the easy part: implementing the VI.
Somewhere on your screen you should be able to find a visible piece of Demo_ABC.vi.
Click on the diagram (or the front panel, then move to the diagram) to get the full LabVIEW menus back.
Earlier we advised you not to be intimidated with the giant diagram. We promised that things were quite modular and you'd never need to see everything at once. Let's check that out.
The biggest chunk of real estate is labelled the Processing Loop. It does not cycle among the states of the system but rather processes the different Actions called for. (No, we haven't defined any actions yet. Don't worry; we don't need them for this simple project.) Most LabVIEW state machines have a loop just like this one. They don't move through states (at least not through the real system states) either. If they really stepped through the system states, each case would contain entrance actions, a transition event detection loop, and exit actions. There would be a lot of redundancy and maintenance would be horrific. Some people claim that this loop steps through the states of the computer program, but it is much better to admit that it really processes actions and is a "consumer loop", in the nomenclature of the LabVIEW built-in examples and templates.
We didn't define any actions, so we can ignore this loop for the moment. We'll also ignore almost everything else, for this project. The only thing we'll modify is the events loop just above the action Processing Loop (Figure 9).
Figure 9: The Events Loop
Recall that the README file mentioned that you now had a real HSM object but that the only thing this object could do was exit when you clicked the button. Our project requires transitions when you click a button, so let's just duplicate the code that's already there.
Choose event 0, that handles the value change event of the Exit Button.
Since we're going to duplicate things, turn on the label of the boolean, as we have done above.
Pop-up on the Event title bar and choose Duplicate Event Case...
At the bottom of the left list box in the pop up window, you'll see a new control listed as Exit Button 2. The bottom entry in the right list box is Value Change.
Choose Exit Button 2 and Value Change and hit OK.
Turn on the boolean label and rename it Plus.
Notice that the event case name changes to "Plus": Value Change.
Replace the string with Plus as well. (I copy and paste to avoid typos.)
Duplicate the case again and set the name and the string to Minus this time.
Double-click the Plus boolean to find it on the front panel.
Notice that it is in the middle of the stack of three EXIT buttons.
Widen the front panel, if necessary, so that you can see the State indicator on the left side.
Move the Plus button over there.
Change the text color to black, and the text to +, to avoid confusion (Figure 10).
The lower right EXIT button is really the Minus button. (You can show the label if you don't believe me.)
Move it next to the Plus button and change it's text and text color.
Align the tops of the three buttons to make things look professional.
Save the VI.
Figure 10: Demo_ABC.vi Front Panel
Congratulations! You've just built a working hierarchical state machine!
The Proof of the Pudding
Before you run your creation, you may want to click the Slow Down for Demo and Debug Purposes button near the lower right corner of the Demo_ABC panel. This way you'll be able to see what is going on step by step. Scroll back to the top left of the panel (as seen in Figure 10). All the interesting stuff will show here.
First notice that, when you click the Run arrow, the Ready/Idle state transitions to state A without any causative event. Remember, we made Ready/Idle an ephemeral state. The VI starts in this state, so we can put any initialization we want there and that code will execute every time the VI starts up. But the VI quickly moves on to the loop of states of interest.
Push the + button once and watch the state change from A to B. Another push and B becomes C. Another and we're back to A. Push the - button and we go back to C. Push it again, and again, and again. It is completely ignored. Gee, that is exactly what the rules say should happen!
Push the + button several times in rapid succession. The multiple events are queued and executed in sequence. The states progress clockwise each second (if you left the default Slowdown delay). Try it again, but this time watch the # elements in events queue indicator in the left center of the panel. You can watch the events flow into and out of the queue.
Move to the A state, then push the - button several times rapidly. Note that the events queue up and then come off the queue as for the Plus events above, but the state stops at C, which ignores each of the Minus events individually. (This suggests a possible enhancement. Did you notice as we were setting them up that events had priorities? What if we created a higher priority event that advances the state? Would it allow some of these queued events to be used to move back from A to C? I don't know, but we both should be able to try it out now.)
Notice that there are no actions in the Last Scheduled Actions list in the upper right of the panel. Remember we didn't create any. And we didn't need them for this example. Now watch this list closely and push the EXIT button. A Close action appears, gets executed, and the VI stops. Where did that come from? It was an exit action for the Top State, of which all our states were substates. We didn't have to worry about it because it was handled higher in the hierarchy. See, this really was a Hierarchical State Machine after all!
Paul F. Sullivan