I'm working on a robot control program that is based on a state machine. While the program uses Qt State Machine Framework, I also attempted to implement it using Boost.statechart (BS) as a theoretical exercise and a way to learn / evaluate the library.
In Qt version I used the following pattern in several places: a compound state has parallel nested sub-graphs, each of which eventually reaches a final state. When all parallel sub-states finish, the parent state emits "finished()" signal, which causes the machine to transit to the next top-level state. E.g. (Beware: pseudo diagram):
Idle -calibRequest-> Calibrate( calibrate_camera | calibrate_arm ) -finished-> Idle
and calibrate_* states in turn have nested states inside them like S -trigger[calibrated?]-> F where F is a final state. When both calibrate_* states reach their respective F states finished signal causes the state machine to transit into Idle.
Qt's parallel child state are analogous to BS's orthogonal nested states. At first I though "termination" was BS's analogue to final states, but in fact it isn't. It's more like "terminate the state machine unless there is still some orthogonal thing going somewhere" - once you terminate all orthogonal states the parent state terminates as well without any chance to transit. Posting events upon termination doesn't help either since there is no state that these events could be delivered to.
I ended up implementing "final states" which post a notification event when reached and reacting on this event in the parent state - checking if all orthogonal states have reached their final events and transiting then. Which is basically reimplementation of Qt State Machine's approach, but which has to be redone each time I need this pattern. But may be I'm just so used to one way of achieving this effect that I don't see an alternative?
Related
Explanation part:
I tried to read several articles with threads but I quite new to this topic therefore I'm not sure if I can accomplish what I think about.
I already implemented an object orientated state machine for detection of movement based on this tutorial C++ State machine implementation
There is also a tutorial for multi-threading with state machines but the example is a bit to complex for me and implemented for windows so for now I'm trying to do it myself. The goal is to have several final state machines running parallel for labelling of sensor information. I thought that multi-threading is needed because events will arrive asynchronously and it shall be ensured that every information will be processed (Queue has to be implemented also).
As you can see in the picture my FSM has 4 states which should be realized within one thread. It will wait for an event (movement or timer) to happen and transform to the next state. The states are saved within an object and the transition is based on an object function.
Question part:
The movement event will be triggered from outside (receiving of sensor event).
Depending on the event I can execute the corresponding object function change into the next state.
But how can I realize that a timer runs after triggering a certain state which eventually will lead to the previous state. Also the timer has to be stopped if another event happens asynchronous. Should this be handled within the thread or outside?
I see no motivation to involve multi-threading in this scenario. Therefore, "thread safety" is not an issue. You will define some software object which represents "the state machine" with its internal state, and two methods that can be called, one for each possible notification. These should be handled serially: a message arrives (in a thread-safe queue) to tell you the timer went off, or a message arrives to tell you about the alarm, and you pop and process those messages one at a time. Or, you can use a mutex within the methods to ensure that two method calls are never attempted simultaneously ... if that's an issue, and I see no reason for it to be. Just do all of this in one thread and be done.
Apparently, your state machine receives two notifications: (1) that the timer has just gone off, and (2) that the sensor/alarm has something to report.
And then, you simply work out the logic that needs to happen, for each of these, depending on (1) the current state, and (2) various internal variables The logic within your state-machine handles both of these: nothing is actually being done in parallel.
case state == MOVING_BETWEEN_ROOM:
case stimulus == TIMER_POP:
timer_counter++;
if timer_counter > 1 then {
state = UNSURE_MOVEMENT;
timer_counter = 0; // maybe?
}
case stimulus == ALARM:
timer_counter = 0;
if current_room == room_last_alarm {
same_room_count++;
if in_same_room_count > n then {
state = MOVING_SAME_ROOM;
in_same_room_count = 0; // maybe???
}
} else {
in_same_room_count = 0;
room_last_alarm = current_room;
}
... and, so on. I'm not saying that the above logic is correct, but it should point you in the right direction.
Hello I am looking for a signal for gtkmm. Basically I am doing some simulations and what I want is something like this :
I assume I do 5 simulations :
progressBar.set_fraction(0);
1 simulation
progressBar.set_fraction(progressBar.get_fraction()+1/5)
2 simulation
progressBar.set_fraction(progressBar.get_fraction()+1/5)
3 simulation
progressBar.set_fraction(progressBar.get_fraction()+1/5)
4 simulation
progressBar.set_fraction(progressBar.get_fraction()+1/5)
5 simulation
progressBar.set_fraction(progressBar.get_fraction()+1/5)
But I don't know which signal I have to use and how to translate to this.
Thank you a lot for your help !!!
The pseudo code which you presented in your question should actually work - no signal is necessary. However, you could introduce a signal into your simulation for update of the progress bar. IMHO this will not solve your problem and I will try to explain why and what to do to solve it:
You provided a little bit too less context, so, that I will introduce some more assumptions: You have a main window with a button or toolbar item or menu item (or even all of them) which start the simulation.
Let's imagine you set a breakpoint at Gtk::ProgressBar::set_fraction().
Once the debugger stopped at this break point you will find the following calls on the stack trace (probably with many other calls in between):
Gtk::Main::run()
the signal handler of the widget or action which started the simulation
the function which runs the five simulations
and last the call of Gtk::ProgressBar::set_fraction().
If you could inspect the internals of Gtk::ProgressBar you would notice that everything in Gtk::ProgressBar::set_fraction() is done properly. So what's wrong?
When you call Gtk::ProgressBar::set_fraction() it probably generates an expose event (i.e. adds an event to the event queue inside of Gtk::Main with a request for its own refresh). The problem is that you probably do not process the request until all five runs of the simulation are done. (Remember that Gtk::Main::run() which is responsible for this is the uppermost/outmost call of my imaginery stack trace.) Thus, the refresh does not happen until the simulation is over - that's too late. (Btw. the authors of Gtk+ stated somewhere in the manual about their cleverness to optimize events. I.e. there might be finally only one expose event for the Gtk::ProgressBar in the event queue but this does not make your situation better.)
Thus, after you called Gtk::ProgressBar::set_fraction() you must somehow flush the event queue before doing further progress with your simulation.
This sounds like leaving the simulation, leaving the calling widget signal handler, returning to Gtk::Main::run() for further event processing and finally coming back for next simulation step - terrible idea. But we did it much simpler. For this, we use essentially the following code (in gtkmm 2.4):
while (Gtk::Main::events_pending()) Gtk::Main::iteration(false);
(This should hopefully be the same in the gtkmm version you use but if in doubt consult the manual.)
It should be done immediately after updating the progress bar fraction and before simulation is continued.
This recursively enters (parts of) the main loop and processes all pending events in the event queue of Gtk::Main and thus, the progress bar is exposed before the simulation continues. You may be concerned to "recursively enter the main loop" but I read somewhere in the GTK+ manual that it is allowed (and reasonable to solve problems like this) and what to care about (i.e. to limit the number of recursions and to grant a proper "roll-back").
What in your case is the simulation we call in general long running functions. Because such long running functions are algorithms (in libraries for anything) which shall not be polluted with any GUI stuff, we built some administrational infra structure around this basic concept including
a progress "proxy" object with an update(double) method and a signal slot
a customized progress dialog which can connect a signal handler to such a progress object (i.e. its signal slot).
The long running function gets a progress object (as argument) and is responsible to call the Progress::update() method in appropriate intervals with an appropriate progress factor. (We simply use values in the range [0, 1].)
One issue is the interval of calling the progress update. If it is called to often the GUI will slow down your long running function significantly. The opposite case (calling it not often enough) results in less responsiveness of GUI. Thus, we decided for more often progress update. To lower the time consuming of GUI, we remember the time of last update in our progress dialog and skip the next refreshs until a certain duration since last refresh is measured. Thus, the long running function has still some extra effort for progress update but it is not recognizable anymore. (A good refresh interval is IMHO 0.1 s - the perception threshold of humans but you may choose 0.05 s if in doubt.)
Flushing all pending events results in processing of mouse events (and other GTK+ signals) also. This allows another useful feature: aborting the long running function.
When the "Cancel" button of our progress dialog is pressed it sets an internal flag. If the progress is updated next time it checks the flag. If the flag became true it throws a special exception. The throw aborts the caller of the progress update (the long running function) immediately. This exception must be catched in the signal handler of the button (or whatever called the long running function). Otherwise, it would "fall through" to the event dispatcher in Gtk::Main where it is catched definitely which would abort your application. (I saw it often enough whenever I forgot to catch.) On the other hand: catching the special exception tells clearly that the long running function has been aborted (in opposition to ended by regulary return). This may or may not be something which can be stated on GUI also.
Finally, the above solution can cause another issue: It enables to start the simulation (via GUI) while a simulation is already running. This is possible because button presses for simulation start could be processed while in progress update. To prevent this, there is actually a simple solution: set a flag at start of simulation in the GUI until it has finished and prevent further starts while the flag is set. Another option can be to make the widget/action insensitive when simulation is started. This topic becomes more complicated if you have multiple distinct long running functions in your application which may or may not exclude each other - leads to something like an exclusion matrix. Well, we solved it pragmatically... (but without the matrix).
And last but not least I want to mention that we use a similar concept for output of log views (e.g. visual logging of infos, warnings, and errors while anything long running is in progress). IMHO it is always good to provide some visual action for end users. Otherwise, they might get bored and use the telephone to complain about the (too) slow software which actually steals you the time to make it faster (a vicious cycle you have to break...)
I plan to hook up a raspberry pi to a 64x64 led matrix, and writing a sort-of boot loader software written in c++. I would like the software to be plug-and-play with custom games I make. That is, I put all the compiled code for the games into a directory and the boot loader will recognize them and, using fork() and execvp() calls, run the selected games. I want there to be different states to the loader such as: start_state, game_selection_state, preview_state, idle_state to name a few. Each state would do their own thing and a transition from state to state based on input from a input device or idle time.
Now I do not know the best way as far as the architecture to set this up. I am not even sure that a state machine is the best way to handle this. But so far, what I have come up with is I would have 2 threads.
Thread 1:
Handles all the functionality and sanity of the states. This would include starting, stopping, and data of each state. It would also include function calls to transition from state to state.
Thread 2:
Parses input from the input Device (game controller) and makes sure a transition is valid. Then using a thread 1's function calls change the state accordingly. I planned on using a message queue to send any input that is not reserved for transitioning to the current state. (E.g A & B signify transitioning, but Y is pressed and would be sent to current state) This way the state can do what ever it wants with these button presses.
Now where this gets a little fuzzy is when the user picks a game a fork() call will be made inside a thread and I have read this can cause issues. If I did do it this way I would need a way to terminate or halt thread 2 until execvp() call ends.
Now what I want to know is this a valid or best way of implementing something like this.
Let's say I have 2 states, an Active state and an Idle state. If I receive some events in Active state I would like to defer them and execute them when I go back to Idle state.
But when I go back to Idle State is there a way to chose which previously deferred event to process? or is there a way to prioritize them or even ignore few of them?
Thanks,
I see that the basic capability of deferred events is covered in the documentation provided on the project, which I have found helpful in general. In the section titled Orthogonal regions, terminate state, event deferring look for the text "UML defines event deferring as a state property. To accommodate this, MSM lets you specify this in states by providing a deferred_events type..." Note that there are two different methods described there for implementing the deferred events.
Without testing an example, I cannot say whether or not the referenced material on Conflicting transitions and guards will allow you to establish the priority you are seeking on deferred events. You could post your problem or a simplified example.
I am not aware of a solution native to boost MSM. I have heard that the author Christophe Henry is quite responsive to this kind of question on the Mailing list.
If your situation really is that trivial (only two states) nothing is stopping you from implementing your own deferred event queue, passing "defferred events" to it in Active. You can implement an internal transition for each event type with an action that pushes them into your custom queue. Upon entering Idle you can reorder them however you want and post them all back to the SM. This solution doesn't scale all that well though and its a bit of a hack.
I'm using Qt framework which has by default non-blocking I/O to develop an application navigating through several web pages (online stores) and carrying out different actions on these pages. I'm "mapping" specific web page to a state machine which I use to navigate through this page.
This state machine has these transitions;
Connect, LogIn, Query, LogOut, Disconnect
and these states;
Start, Connecting, Connected, LoggingIn, LoggedIn, Querying, QueryDone, LoggingOut, LoggedOut, Disconnecting, Disconnected
Transitions from *ing to *ed states (Connecting->Connected), are due to LoadFinished asynchronous network events received from network object when currently requested url is loaded. Transitions from *ed to *ing states (Connected->LoggingIn) are due to events send by me.
I want to be able to send several events (commands) to this machine (like Connect, LogIn, Query("productA"), Query("productB"), LogOut, LogIn, Query("productC"), LogOut, Disconnect) at once and have it process them. I don't want to block waiting for the machine to finish processing all events I sent to it. The problem is they have to be interleaved with the above mentioned network events informing machine about the url being downloaded. Without interleaving machine can't advance its state (and process my events) because advancing from *ing to *ed occurs only after receiving network type of event.
How can I achieve my design goal?
EDIT
The state machine I'm using has its own event loop and events are not queued in it so could be missed by machine if they come when the machine is busy.
Network I/O events are not posted directly to neither the state machine nor the event queue I'm using. They are posted to my code (handler) and I have to handle them. I can forward them as I wish but please have in mind remark no. 1.
Take a look at my answer to this question where I described my current design in details. The question is if and how can I improve this design by making it
More robust
Simpler
Sounds like you want the state machine to have an event queue. Queue up the events, start processing the first one, and when that completes pull the next event off the queue and start on that. So instead of the state machine being driven by the client code directly, it's driven by the queue.
This means that any logic which involves using the result of one transition in the next one has to be in the machine. For example, if the "login complete" page tells you where to go next. If that's not possible, then the event could perhaps include a callback which the machine can call, to return whatever it needs to know.
Asking this question I already had a working design which I didn't want to write about not to skew answers in any direction :) I'm going to describe in this pseudo answer what the design I have is.
In addition to the state machine I have a queue of events. Instead of posting events directly to the machine I'm placing them in the queue. There is however problem with network events which are asynchronous and come in any moment. If the queue is not empty and a network event comes I can't place it in the queue because the machine will be stuck waiting for it before processing events already in the queue. And the machine will wait forever because this network event is waiting behind all events placed in the queue earlier.
To overcome this problem I have two types of messages; normal and priority ones. Normal ones are those send by me and priority ones are all network ones. When I get network event I don't place it in the queue but instead I send it directly to the machine. This way it can finish its current task and progress to the next state before pulling the next event from the queue of events.
It works designed this way only because there is exactly 1:1 interleave of my events and network events. Because of this when the machine is waiting for a network event it's not busy doing anything (so it's ready to accept it and does not miss it) and vice versa - when the machine waits for my task it's only waiting for my task and not another network one.
I asked this question in hope for some more simple design than what I have now.
Strictly speaking, you can't. Because you only have state "Connecting", you don't know whether you need top login afterwards. You'd have to introduce a state "ConnectingWithIntentToLogin" to represent the result of a "Connect, then Login" event from the Start state.
Naturally there will be a lot of overlap between the "Connecting" and the "ConnectingWithIntentToLogin" states. This is most easily achieved by a state machine architecture that supports state hierarchies.
--- edit ---
Reading your later reactions, it's now clear what your actual problem is.
You do need extra state, obviously, whether that's ingrained in the FSM or outside it in a separate queue. Let's follow the model you prefer, with extra events in a queue. The rick here is that you're wondering how to "interleave" those queued events vis-a-vis the realtime events. You don't - events from the queue are actively extracted when entering specific states. In your case, those would be the "*ed" states like "Connected". Only when the queue is empty would you stay in the "Connected" state.
If you don't want to block, that means you don't care about the network replies. If on the other hand the replies interest you, you have to block waiting for them. Trying to design your FSM otherwise will quickly lead to your automaton's size reaching infinity.
How about moving the state machine to a different thread, i. e. QThread. I would implent a input queue in the state machine so I could send queries non blocking and a output queue to read the results of the queries. You could even call back a slotted function in your main thread via connect(...) if a result of a query arrives, Qt is thread safe in this regard.
This way your state machine could block as long as it needs without blocking your main program.
Sounds like you just want to do a list of blocking I/O in the background.
So have a thread execute:
while( !commands.empty() )
{
command = command.pop_back();
switch( command )
{
Connect:
DoBlockingConnect();
break;
...
}
}
NotifySenderDone();