From 0973dd67e1a19b74a32e9dbc6b55dcd14b632fa5 Mon Sep 17 00:00:00 2001 From: CoolSpy3 Date: Tue, 7 Oct 2025 00:25:20 -0700 Subject: [PATCH 1/4] average ideal sleep times rather than elapsed times --- src/webots/engine/WbSimulationWorld.cpp | 35 +++++++++++-------------- src/webots/engine/WbSimulationWorld.hpp | 2 +- 2 files changed, 16 insertions(+), 21 deletions(-) diff --git a/src/webots/engine/WbSimulationWorld.cpp b/src/webots/engine/WbSimulationWorld.cpp index 319df02a665..ab2482104b8 100644 --- a/src/webots/engine/WbSimulationWorld.cpp +++ b/src/webots/engine/WbSimulationWorld.cpp @@ -188,30 +188,25 @@ void WbSimulationWorld::step() { if (WbSimulationState::instance()->isRealTime()) { const int elapsed = mRealTimeTimer.restart(); - // computing the mean of an history of several elapsedTime - // improves significantly the stability of the algorithm - // in case of simulations where elapsedTime oscillates often - // above and below basicTimeStep. + // How long should we have slept to be in real-time? + double idealSleepTime = timeStep - (elapsed - mSleepRealTime); + // Limit to timeStep to avoid weird behavior on large pauses (e.g., on startup) + if (idealSleepTime > timeStep) + idealSleepTime = timeStep; + // computing the mean of an history of several time values + // improves significantly the stability of the algorithm. // Moreover it improves the stability of simulations where // basicTimeStep contains significant decimals - mElapsedTimeHistory.append(elapsed); - if (mElapsedTimeHistory.size() > qMax(4.0, 128.0 / timeStep)) // history size found empirically - mElapsedTimeHistory.pop_front(); + mIdealSleepTimeHistory.append(idealSleepTime); + if (mIdealSleepTimeHistory.size() > qMax(4.0, 128.0 / timeStep)) // history size found empirically + mIdealSleepTimeHistory.pop_front(); double mean = 0.0; - foreach (const int &v, mElapsedTimeHistory) + foreach (const double &v, mIdealSleepTimeHistory) mean += v; - mean /= mElapsedTimeHistory.size(); - - // useful hack: uncomment to run Webots at 90% of the real-time - // (if the real-time mode is enabled, of course) - // mean *= 0.90; - - if (mean > timeStep && mSleepRealTime > 0.0) { - mSleepRealTime -= 0.03 * timeStep; - if (mSleepRealTime < 0) - mSleepRealTime = 0.0; - } else if (mean < timeStep) - mSleepRealTime += 0.03 * timeStep; + mean /= mIdealSleepTimeHistory.size(); + mSleepRealTime = mean; + if (mSleepRealTime < 0.0) + mSleepRealTime = 0.0; mTimer->start(mSleepRealTime); } diff --git a/src/webots/engine/WbSimulationWorld.hpp b/src/webots/engine/WbSimulationWorld.hpp index 59b528855d1..9564319c325 100644 --- a/src/webots/engine/WbSimulationWorld.hpp +++ b/src/webots/engine/WbSimulationWorld.hpp @@ -78,7 +78,7 @@ protected slots: QTimer *mTimer; QElapsedTimer mRealTimeTimer; double mSleepRealTime; - QList mElapsedTimeHistory; + QList mIdealSleepTimeHistory; QVector mAddedNode; // list of nodes added since the simulation started void storeLastSaveTime() override; From 9a8de34dd8cbf64397666ae84dbab9e5057a4030 Mon Sep 17 00:00:00 2001 From: CoolSpy3 Date: Tue, 7 Oct 2025 00:30:28 -0700 Subject: [PATCH 2/4] add lower bound to idealSleepTime --- src/webots/engine/WbSimulationWorld.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/webots/engine/WbSimulationWorld.cpp b/src/webots/engine/WbSimulationWorld.cpp index ab2482104b8..618cff8a4cd 100644 --- a/src/webots/engine/WbSimulationWorld.cpp +++ b/src/webots/engine/WbSimulationWorld.cpp @@ -191,8 +191,8 @@ void WbSimulationWorld::step() { // How long should we have slept to be in real-time? double idealSleepTime = timeStep - (elapsed - mSleepRealTime); // Limit to timeStep to avoid weird behavior on large pauses (e.g., on startup) - if (idealSleepTime > timeStep) - idealSleepTime = timeStep; + // We also can't wait less than 0 ms. + idealSleepTime = qBound(0.0, idealSleepTime, timeStep); // computing the mean of an history of several time values // improves significantly the stability of the algorithm. // Moreover it improves the stability of simulations where @@ -205,8 +205,6 @@ void WbSimulationWorld::step() { mean += v; mean /= mIdealSleepTimeHistory.size(); mSleepRealTime = mean; - if (mSleepRealTime < 0.0) - mSleepRealTime = 0.0; mTimer->start(mSleepRealTime); } From d65d478ae1ca8d2faba449e1b131217c26fdb3c3 Mon Sep 17 00:00:00 2001 From: CoolSpy3 Date: Fri, 10 Oct 2025 01:12:10 -0700 Subject: [PATCH 3/4] use Qt::PreciseTimer and remove synchronization code Co-authored-by: Anthony Welte --- src/webots/engine/WbSimulationWorld.cpp | 30 ++----------------------- src/webots/engine/WbSimulationWorld.hpp | 3 --- 2 files changed, 2 insertions(+), 31 deletions(-) diff --git a/src/webots/engine/WbSimulationWorld.cpp b/src/webots/engine/WbSimulationWorld.cpp index 618cff8a4cd..ec450c4ecea 100644 --- a/src/webots/engine/WbSimulationWorld.cpp +++ b/src/webots/engine/WbSimulationWorld.cpp @@ -73,8 +73,6 @@ WbSimulationWorld::WbSimulationWorld(WbTokenizer *tokenizer) : } } - mSleepRealTime = basicTimeStep(); - WbPerformanceLog *log = WbPerformanceLog::instance(); if (log) log->setTimeStep(basicTimeStep()); @@ -128,6 +126,7 @@ WbSimulationWorld::WbSimulationWorld(WbTokenizer *tokenizer) : if (log) log->stopMeasure(WbPerformanceLog::LOADING); + mTimer->setTimerType(Qt::PreciseTimer); connect(mTimer, &QTimer::timeout, this, &WbSimulationWorld::triggerStepFromTimer); const WbSimulationState *const s = WbSimulationState::instance(); connect(s, &WbSimulationState::rayTracingEnabled, this, &WbSimulationWorld::rayTracingEnabled); @@ -185,30 +184,6 @@ void WbSimulationWorld::step() { const double timeStep = basicTimeStep(); - if (WbSimulationState::instance()->isRealTime()) { - const int elapsed = mRealTimeTimer.restart(); - - // How long should we have slept to be in real-time? - double idealSleepTime = timeStep - (elapsed - mSleepRealTime); - // Limit to timeStep to avoid weird behavior on large pauses (e.g., on startup) - // We also can't wait less than 0 ms. - idealSleepTime = qBound(0.0, idealSleepTime, timeStep); - // computing the mean of an history of several time values - // improves significantly the stability of the algorithm. - // Moreover it improves the stability of simulations where - // basicTimeStep contains significant decimals - mIdealSleepTimeHistory.append(idealSleepTime); - if (mIdealSleepTimeHistory.size() > qMax(4.0, 128.0 / timeStep)) // history size found empirically - mIdealSleepTimeHistory.pop_front(); - double mean = 0.0; - foreach (const double &v, mIdealSleepTimeHistory) - mean += v; - mean /= mIdealSleepTimeHistory.size(); - mSleepRealTime = mean; - - mTimer->start(mSleepRealTime); - } - emit physicsStepStarted(); if (log) @@ -310,10 +285,9 @@ void WbSimulationWorld::modeChanged() { WbSoundEngine::setMute(WbPreferences::instance()->value("Sound/mute").toBool()); break; case WbSimulationState::REALTIME: - mRealTimeTimer.start(); WbSoundEngine::setPause(false); WbSoundEngine::setMute(WbPreferences::instance()->value("Sound/mute").toBool()); - mTimer->start(mSleepRealTime); + mTimer->start(basicTimeStep()); break; case WbSimulationState::FAST: WbSoundEngine::setPause(false); diff --git a/src/webots/engine/WbSimulationWorld.hpp b/src/webots/engine/WbSimulationWorld.hpp index 9564319c325..1cfcbf4a9d5 100644 --- a/src/webots/engine/WbSimulationWorld.hpp +++ b/src/webots/engine/WbSimulationWorld.hpp @@ -76,9 +76,6 @@ protected slots: WbOdeContext *mOdeContext; WbPhysicsPlugin *mPhysicsPlugin; QTimer *mTimer; - QElapsedTimer mRealTimeTimer; - double mSleepRealTime; - QList mIdealSleepTimeHistory; QVector mAddedNode; // list of nodes added since the simulation started void storeLastSaveTime() override; From 1c82c5eca403383857a3ed83afdee752720f548b Mon Sep 17 00:00:00 2001 From: CoolSpy3 Date: Sat, 11 Oct 2025 00:03:53 -0700 Subject: [PATCH 4/4] include libwinpthread in distribution --- scripts/packaging/files_msys64.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/packaging/files_msys64.txt b/scripts/packaging/files_msys64.txt index 9926518a30b..55e1f929e99 100644 --- a/scripts/packaging/files_msys64.txt +++ b/scripts/packaging/files_msys64.txt @@ -19,6 +19,7 @@ /mingw64/bin/libpcre2-16-0.dll /mingw64/bin/libpng16-16.dll /mingw64/bin/libssl-3-x64.dll +/mingw64/bin/libwinpthread-1.dll /mingw64/bin/Qt6Core.dll /mingw64/bin/Qt6Gui.dll /mingw64/bin/Qt6Network.dll