01-13-2011 08:29 PM
Using LV2009 + WIN7+Pentium 4 @ 2.5Ghz with 3 GB RAM.
I have a machine control code inside a 10mS main loop that has 7 ( yes seven ) Queued State Machines ( QSM) and I find the Finished Late boolen keeeps poppping often. Not a very good sign if you ask me.
And the code itself does not have too much of computation or FP activity. But it has four Graphs with one plot on each of them. These are updated once every 10ms. Can slowing this update ( say once every 250ms ? ) help ?
A simple query : In terms of performance overhead, does a QSM demand more than a Simple State Machine ( SSM ) ? Can I avoid the Finished Late warning by switching over to SSM at least in three of the cases out of the seven ?
Thanks
01-13-2011 08:47 PM
Curious...
Why do you have 7 QSMs?
Can't comment much on adding delay without seeing the code. Typically, adding delay is a bandaid solution...
I do have a concern if you have multiple QSM within another loop. Actually, even a single QSM within another loop is not receommended.
The problem is that the main (outer) loop has to wait until every inner loop completes... Actually scratch that out... I must have misread because nesting QSMs within another loop does not make sense... How do the inner loops terminate to allow iterations of the outer loop?
Can you post your code?
01-14-2011 04:07 AM
Why do I have 7 QSMs ?
4 nos for identical but different machine sequences.
1 no for temperature contrrol loop.
1 no for fluid control loop.
1 no for writing to a XLS file.
Unfortunatley I cannot post the code as its quite large. But I have posted a sample which shows the structure of the code with 3 QSMs. The actual timed loop is at 10ms. I guess there is nothing wrong in this approach ??
01-14-2011 08:01 AM
Since the transitions in a QSM can not be predetermined, it is prone to issues like finished late.
I generally go with a SSM and any operation that take extened time get a sepearte loop with interactions implemented using queues or AE's.
Ben
01-14-2011 08:28 AM
I am not a fan of the queued state machine. I prefer the simple state machine. Not because of speed issues but because I think the next state should be determined by the current state and the data available to it.
In looking at your code I notice that you have not wired the timeout on any of the Dequeue VIs. The default timeout is -1 which means never timeout. If it is ever possible that the queue might be empty the loop will wait forever.
I might make all the state machines (regardless of architecture) independent loops rather than putting them all in one loop. That way if one machine stalls for any reason it does not block the whole system.
As Ben suggested interactions between loops can easily be handled by queues or Action Engines.
Lynn
01-14-2011 09:00 AM
@Raghunathan wrote:
[...]. But it has four Graphs with one plot on each of them. These are updated once every 10ms. [...]
If you do not have made a mistake here, i would say that this is definetly something to change. I know no human being capable of seeing 100 frames per second. Usually, it comes down to somewhere around 30 fps. So the fastest UI updates you normally ever need is 1/30 s = 33ms.
Somewhere in my mind resides a memory of a usability test done at an US american university where they found out that the user expects reactions on UIs after about 100-200ms, so i think it is save to raise loop waiting time to somewhere there....it will reduce the number of finished lates, but possibly not solving the issue to an expected extend.
So taking Lynns note into account, you will hopefully get a satisfactory solution.
hope this helps,
Norbert
01-14-2011 09:31 AM
@johnsold wrote:
....
I might make all the state machines (regardless of architecture) independent loops rather than putting them all in one loop. That way if one machine stalls for any reason it does not block the whole system.
I actually arrived at the current idea to put all QSMs into one loop after some practical trials . Refer this thread where I asked the query and I answered it myself : http://forums.ni.com/t5/LabVIEW/Many-Queued-SM-in-one-Timed-loop-Vs-Many-Timed-loops/m-p/1284712?req... I guess my reasoning is correct.
However I agree that attention must be paid to the Time out node. Till date a block has not happened. But that does not mean it will not happen in future
01-17-2011 08:17 AM
When constructing these types of architectures it is important to remember the difference between a state machine and a task handler and not conflate the two in your design. What most people refer to as a queued state machine is actually a task handler. Task handlers are highly useful for things such as UI interactions where you do not want to lose a task. State machines are useful when your process has several configurations it could be in (e.g. stopped, running, paused, etc.). I agree with the previous posters that state machines should not be queued. Task handlers should be queued. Yes, you can, and probably should, have both is a large, GUI-based program. But you should be very clear about the boundaries of each. Using LabVIEW classes for your task handling, it is probably easiest to make the state machine the top level and the task handler interior to it, although the opposite architecture is also quite workable.
My apologies for the rambling response. This is an area I constantly struggle with, despite knowing better.
01-17-2011 08:35 PM
>>Using LabVIEW classes for your task handling, it is probably easiest to make the state machine the top level and the task handler interior to it, although the opposite architecture is also quite workable.
I dont think I quite follow that - could you eloborate or link to an example if any ? Thanks.
The one aspect where QSMs shine as compared to a SSM, is the fact the elements can be dequeued and enqueued at different places. Like for instance a QSM can be normally updated inside of a Timed Loop but when in an emergency, like when the user clicks an Abort button, I can enqueue the relevant element from another Event loop - kind off bringing an interrupt function to the code.
This is is not easy with a SSM as i need to read the relevant user interaction in ALL the states [or] nest the whole normal code inside another outer case which is True as long as the user does not hit the Abort button. . Have tried this in the past but the whole code was a mess of nested cases.
01-18-2011 07:55 AM
I think your question demonstrates my point. Unfortunately, I don't have a good example to point you to and don't have the time to write one. I will try to explain better. Let's take a simple example - a landscape watering controller (sprinkler controller). This controller will have several states (e.g. initializing, waiting, watering, closing). Each of these states will accept several commands, but not all commands are accepted in all states. For example, if the system is watering, a command to start watering could be ignored.
In most programs, at least some states should be interruptible. For example, if it starts to rain, the watering system should stop watering immediately instead of watering for a set length of time. However, if the system is in the initialization state, this will probably not be interruptible (but also short).
As you said, the classic LabVIEW way to implement such a thing is to have a case statement to represent the state, and a case statement (usually queue driven) in each state frame to handle the commands. You thus have a loop with a double case structure. This can get somewhat unwieldy for large programs. Note that which case structure represents what will be determined by the relative number of each item. For example, if you have fifty commands and three states, the state should go into the command case.
So how do LabVIEW classes help? They can eliminate one or both levels of these case structures through the use of dynamic dispatch. This is done as follows. A parent class is created that is a generic command. It has commands for each state. For each actual command, a class is derived from the parent class. There are VIs in the specific command class for each state. A command is generated by creating the correct object for the current state, then calling the parent class command. Dynamic dispatch will execute the code for the correct command. The command execution loop is then reduced to a single command VI which dynamically dispatches based on the actual command and the current state.
In practice, things as usually not quite this simple, and you may want different cases for either different commands or different states so that you can change the connector pane of the dynamically dispatched VI as needed. Look up the LabVIEW examples on dynamic dispatch to see this in action.
I am afraid I have still not made myself clear. Keep asking questions and I will try to keep answering.