Debug of real time dependent app
-
Hello, can you please share your hints?
I am developing an application whose behaviour is real time dependent. Its events are real time driven and I use QElapsedTimer to update state in eternal loop of separate thread.
Based on a time stepped update of object's state, my thread sleeps, wakes up, calls methods and signals outside.
Having an undefined behaviour I want to debug my app observing its variable in step through mode. While I'm watching the screen and pushing the mouse button the timer runs and I fail find out what's been written wrong
How do you manage such issues?
-
Hi,
Can you generate those events in a synthetic manner to make things reproducible ?
-
I have made a hurry mode first that runs as fast as cpu can lead it using synthetic time step increment. But now I need a real time run to have a time window between events to run prediction model and give the app controller a feedback what would happen after its action. It is a closed loop control dispatch: predict - analize -act - compare result - fix guidance - predict again. It is very time sensitive loop
-
The way you describe the loop should rather be an exchange of message that is not time dependent.
As fast as can be yes but the real-time part sensitivity makes it sounds a bit brittle or you are aiming for trade exchange speed which is a different can of worm. -
dear op. your definition of real-time and mine may be different. Please be advised that in the strict sense Qt and the OS it runs on are not "real-time" but are preemptive with scheduling timeslices that exclude serious realtime app processing...so, you need to be very careful and define and disclose what you you expect in terms realtime fidelity. QTimer isn't going to be accurate at intervals less than the 2*(1/HZ) value of the OS, and even then no time deadline guarantees exist.
Of course the correct but more development intensive path (that @SGaist alluded to) is to simulate your whole system using a synthetic clock that you can manipulate manually and use to set the state of the simulation to an atrbitrary (Time).
Then when you have proven out your system, you should research OS/framework solutions to make sure they will meet your true realtime needs.
-
dear op. your definition of real-time and mine may be different. Please be advised that in the strict sense Qt and the OS it runs on are not "real-time" but are preemptive with scheduling timeslices that exclude serious realtime app processing...so, you need to be very careful and define and disclose what you you expect in terms realtime fidelity. QTimer isn't going to be accurate at intervals less than the 2*(1/HZ) value of the OS, and even then no time deadline guarantees exist.
Of course the correct but more development intensive path (that @SGaist alluded to) is to simulate your whole system using a synthetic clock that you can manipulate manually and use to set the state of the simulation to an atrbitrary (Time).
Then when you have proven out your system, you should research OS/framework solutions to make sure they will meet your true realtime needs.
@Kent-Dorfman said in Debug of real time dependent app:
QTimer isn't going to be accurate at intervals less than the 2*(1/HZ) value of the OS
Thank you. It was a surprize for me that neither my Win11 nor Qt can manage intervals I expected to deal with.
Let me show you my setup to make my expectations clear for you.
It is a pure math/physics simulations that describe launch and further path of propelled projectile. At some points its velocity exceeds 1000 m/s that`s why for precise its state update I need a very short intervals e.g 1/1000 second. And I supposed to make my thread sleep within this interval )))void SimulationWorker::runSimulation() { double nextStateInterval=0.001; //update of coordinates, velocity, thrust, pitch, yaw double nextEnvInterval=0.005; //update of air density, drag, gravity double nextEstimatorInterval=0.5; //update of predicted impact point //QElapsedTimer m_timer.start(); while(!m_shouldStop){ elapsedTime = m_timer.elapsed()/1000.0; //to seconds pitchManeuverEvent(elapsedTime); //thrust angle adjustment based on current velocity vector and timer if(elapsedTime>=nextStateUpdate){ stateTimeIncrement=elapsedTime-lastStateUpdate; lastStateUpdate=elapsedTime; m_state->updateMissileState(stateTimeIncrement, m_CurrentState, m_thrustVec); //Projectile dynamics calculations: coords, thrust, pitch, azimuth nextStateUpdate=elapsedTime+nextStateInterval; } if(elapsedTime>=nextEnvUpdate){ envTimeIncrement=elapsedTime-lastEnvUpdate; lastEnvUpdate=elapsedTime; m_env->updateEnvironment(m_CurrentState); //environment update drag and atmosphere condition nextEnvUpdate=elapsedTime+nextEnvInterval; } if(elapsedTime>=nextEstimatorUpdate){ m_estimator->updateEstimation(elapsedTime); //impact point predictor nextEstimatorUpdate=elapsedTime+nextEstimatorInterval; } //some other events for guidance //thread goes to sleep if it has time to next event sleepUntilNextEvent(elapsedTime, nextStateUpdate, nextEnvUpdate, nextEstimatorUpdate, nextRecorderUpdate); if(!cutOff){ //mass update and thrust cut off switcher m_CurrentState.currentMass=updateMass(cutOff, elapsedTime); } }
So my current approach is impossible, right?
I added loop cycle counter and logged sleep duration in milliseconds it seems that thread oversleeps
loopCounter 1 , time 0
slept 1
loopCounter 2 , time 0.001
slept 2
loopCounter 3 , time 0.003
slept 9
loopCounter 4 , time 0.012
slept 15
loopCounter 5 , time 0.028
slept 19
loopCounter 6 , time 0.047
slept 19
loopCounter 7 , time 0.066
slept 21
loopCounter 8 , time 0.087
slept 20
loopCounter 9 , time 0.107
slept 20
loopCounter 10 , time 0.127
slept 20