PDA

View Full Version : QTimer



saman_artorious
9th June 2012, 09:05
I'd like to know how to trigger my SLOT before QTimer actually times out.
Here's an example scenario:

we have a pump which if conditioned turns on. I have defined the pump life period in a timer. So, when the timer times out, pump turns off.
Here, I need to check when 83% of the pump life period passes, then I need to do some instructions (after 83% life period of pump).
finally when the whole pump life period passes it switches off.
//-----------

wysota
9th June 2012, 09:12
Start another timer set at 83% of what you set the first timer to.

kuroi_neko
12th June 2012, 04:04
Have you considered building a finite state machine to handle your pump? Something that would vaguely look like this:
class pump {
enum pump_state {
on, // running
wait_endcourse, // waiting to reach your "83%" course
wait_off, // waiting to reach the point where pump shall be turned off
off // stopped
};

pump_state state;

pump::manage (MySplendidEventType event)
{
switch (state)
{
case on:
if (event == command_shutdown)
{
whatever_I_need_to_do_to_start_shutdown();
Timer.start (time_to_reach_83_pc_of_the_course);
state = wait_endcourse;
}
break;
case wait_endcourse:
if (event == timeout)
{
whatever_I_need_to_do_at_83_pc_course();
Timer.start(time_to_go_the_remaining_17_pc_of_the_ course);
state = wait_off;
}
break;
case wait_off:
if (event == timeout)
{
whatever_I_need_to_do_to_finish_shutdown();
state = off;
}
}
}
};

Note that if you intend to command a real pump you are in dire need of feedback. I hope you don't assume sending the "on" command will prevent the pump to jam if, let's say, the janitor's broomstick has been sucked into the intake?
This finite state machine technique allows to handle these feedbacks, for instance:
case wait_endcourse:
if (some_sensor_tells_me_that_the_pump_is_jammed)
{
fire_the_bloody_janitor();
state = broomstick_stuck_in_intake;
}
else if (event == timeout)
{
whatever_I_need_to_do_at_83_pc_course();
Timer.start(time_to_go_the_remaining_17_pc_of_the_ course);
state = wait_off;
}
break;

saman_artorious
13th June 2012, 19:26
Thank You for... trying to infer your good insight of this matter. It's nice to hear from an experienced expert.

I merely check all these condition in my code, but your way of implementation looks more organized. I will try to change my code
to look like this.

about the first part of the code, at line 11, I want to know how you implemented the MySplendidEvent!
I am considering it as kinda even a simple QString sent whenever the method manage is called. Or , it's different?

amleto
13th June 2012, 19:43
can be just another enum here

kuroi_neko
15th June 2012, 14:35
Well the idea behind 'MySplendidEvent' is to have a queue containing the events. The timer expiration would create such an event with the special type "timer expired", while other parts of the software would create events like "this sensor passed a given threshold", "this device has acknowledged a given command" or whatever your control system needs to trigger the finite state machine transitions.

The finite state machine would then receive an unified stream of conditions likely to cause a transition to another state.

As for the event type, it could be as simple as an enum (as amleto suggested), or more complex data structure if need be (not unlike Qt mouse or keyboard events, for instance).
It all depends on the complexity of the process you're controlling. For instance, if you control only one pump, no need to bother with a pump identifier. If you have several different pumps in your system, it could be better to create an event structure with a "pump switched off" enum value associated with the actual pump identifier.

wysota
15th June 2012, 15:11
BTW. QStateMachine...

kuroi_neko
15th June 2012, 22:30
An humble newcomer like me would hardly dare to question such an authority as yours, pan wysota, but I've never found the Qt FSM very friendly as far as code maintenability and readability is concerned.
Very well suited for GUI animation/synchronization, but not that good for low-level process control, in my opinion.
The main trouble with QStateMachine is that the code does not reflect the state-transition diagram, just like widget/layouts code does not reflect a GUI structure in a visually understandable form.
Maybe one day TrollTech will invest in a Qt designer-like tool for FSMs, but untill then I would rather use plain C switches, LUA (if a game developer tool does not seem too folish) or a custom-made FSM language for big machines.

wysota
16th June 2012, 01:45
An humble newcomer like me would hardly dare to question such an authority as yours, pan wysota, but I've never found the Qt FSM very friendly as far as code maintenability and readability is concerned.
I agree but for this particular approach you describe, the design fits well since all we need is events to trigger transitions and property changes/actions upon entering/exiting a state.

kuroi_neko
16th June 2012, 05:50
Indeed that could be an option. Some people are thinking visually, some other are more at ease with textual representations.

However, from my experience in industrial software, graphical representations of FSM were pretty useful to discuss functional issues with non-programmers (customers, among others :)).

Using a coding paradigm close to this representation may allow to go easier back and forth between functional description and implementation.

By the way, I wonder if someone actually produced a graphic design tool to generate QStateMachine-based FSMs?

wysota
16th June 2012, 07:59
Qt state machines are standard SCXML thus I'm sure there are tools for creating such charts.

kuroi_neko
19th June 2012, 07:56
Yes! Good point. I missed that entirely. Still wet behind the ears, sorry :).

d_stranz
20th June 2012, 04:38
Qt state machines are standard SCXML thus I'm sure there are tools for creating such charts.

I'm not sure how useful this is. Apache has Visual SCXML for creating and editing state charts, but is there any Qt tool that will read the resulting SCXML file and either build the state machine at run time or generate source files at build time?

I built a complex state machine a while ago to handle mouse and keyboard interactions with a graphics view; dozens of top level and sub-states and as many transitions. I ended up drawing the whole thing out on a very large sheet of graph paper. But it still required hand-coding everything, which was very tedious and resulted in many mistakes that needed to be tracked down. Thankfully, there is qDebug().

Edit: I see there is a Qt Labs effort (http://qt.gitorious.org/qt-labs/scxml) to develop a SCXML loader for the Qt state machine framework. This looks promising.

kuroi_neko
23rd June 2012, 19:14
Writing a code generator from SCXML should not be too difficult. That could be integrated into any IDE, lex/yacc style. Qt Designer-like interactivity would be a plus, but it's not mandatory.

wysota
23rd June 2012, 19:34
Since it is XML, all one needs is a proper XSL template :)