Skip to content

Commit 9484a50

Browse files
CoolSpy3TonyWelte
andauthored
Improve Timestep Algorithm (#6898)
* average ideal sleep times rather than elapsed times * add lower bound to idealSleepTime * use Qt::PreciseTimer and remove synchronization code Co-authored-by: Anthony Welte <tony.welte@gmail.com> * include libwinpthread in distribution * update changelog * fix bug when basicTimeStep was edited while the simulation was running in realtime mode * move variable definition --------- Co-authored-by: Anthony Welte <tony.welte@gmail.com>
1 parent 27f45e5 commit 9484a50

File tree

4 files changed

+11
-36
lines changed

4 files changed

+11
-36
lines changed

docs/reference/changelog-r2025.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
- Added missing import libraries on Windows ([#6753](https://github.com/cyberbotics/webots/pull/6753)).
88
- Added some missing function definitions to the existing Windows libraries ([#6753](https://github.com/cyberbotics/webots/pull/6753)).
99
- Webots now prints the cause when it fails to create a memory-mapped file for a camera node ([#6896](https://github.com/cyberbotics/webots/pull/6896)).
10+
- Made the timestep algorithm more consistent when running in realtime mode ([#6898](https://github.com/cyberbotics/webots/pull/6898)).
1011
- Cleanup
1112
- **Removed `libController.a` and `libCppController.a` libraries on Windows. Please use `Controller.lib` and `CppController.lib` instead ([#6753](https://github.com/cyberbotics/webots/pull/6753)).**
1213
- Bug Fixes

scripts/packaging/files_msys64.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
/mingw64/bin/libpcre2-16-0.dll
2020
/mingw64/bin/libpng16-16.dll
2121
/mingw64/bin/libssl-3-x64.dll
22+
/mingw64/bin/libwinpthread-1.dll
2223
/mingw64/bin/Qt6Core.dll
2324
/mingw64/bin/Qt6Gui.dll
2425
/mingw64/bin/Qt6Network.dll

src/webots/engine/WbSimulationWorld.cpp

Lines changed: 8 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,6 @@ WbSimulationWorld::WbSimulationWorld(WbTokenizer *tokenizer) :
7373
}
7474
}
7575

76-
mSleepRealTime = basicTimeStep();
77-
7876
WbPerformanceLog *log = WbPerformanceLog::instance();
7977
if (log)
8078
log->setTimeStep(basicTimeStep());
@@ -128,6 +126,7 @@ WbSimulationWorld::WbSimulationWorld(WbTokenizer *tokenizer) :
128126
if (log)
129127
log->stopMeasure(WbPerformanceLog::LOADING);
130128

129+
mTimer->setTimerType(Qt::PreciseTimer);
131130
connect(mTimer, &QTimer::timeout, this, &WbSimulationWorld::triggerStepFromTimer);
132131
const WbSimulationState *const s = WbSimulationState::instance();
133132
connect(s, &WbSimulationState::rayTracingEnabled, this, &WbSimulationWorld::rayTracingEnabled);
@@ -185,35 +184,10 @@ void WbSimulationWorld::step() {
185184

186185
const double timeStep = basicTimeStep();
187186

188-
if (WbSimulationState::instance()->isRealTime()) {
189-
const int elapsed = mRealTimeTimer.restart();
190-
191-
// computing the mean of an history of several elapsedTime
192-
// improves significantly the stability of the algorithm
193-
// in case of simulations where elapsedTime oscillates often
194-
// above and below basicTimeStep.
195-
// Moreover it improves the stability of simulations where
196-
// basicTimeStep contains significant decimals
197-
mElapsedTimeHistory.append(elapsed);
198-
if (mElapsedTimeHistory.size() > qMax(4.0, 128.0 / timeStep)) // history size found empirically
199-
mElapsedTimeHistory.pop_front();
200-
double mean = 0.0;
201-
foreach (const int &v, mElapsedTimeHistory)
202-
mean += v;
203-
mean /= mElapsedTimeHistory.size();
204-
205-
// useful hack: uncomment to run Webots at 90% of the real-time
206-
// (if the real-time mode is enabled, of course)
207-
// mean *= 0.90;
208-
209-
if (mean > timeStep && mSleepRealTime > 0.0) {
210-
mSleepRealTime -= 0.03 * timeStep;
211-
if (mSleepRealTime < 0)
212-
mSleepRealTime = 0.0;
213-
} else if (mean < timeStep)
214-
mSleepRealTime += 0.03 * timeStep;
215-
216-
mTimer->start(mSleepRealTime);
187+
// Update the timer's timestep if it's been changed
188+
if (timeStep != mOldTimeStep && WbSimulationState::instance()->isRealTime()) {
189+
mOldTimeStep = timeStep;
190+
mTimer->start(timeStep);
217191
}
218192

219193
emit physicsStepStarted();
@@ -303,6 +277,7 @@ void WbSimulationWorld::restartStepTimer() {
303277

304278
void WbSimulationWorld::modeChanged() {
305279
WbPerformanceLog *log = WbPerformanceLog::instance();
280+
const double timeStep = basicTimeStep();
306281

307282
const WbSimulationState::Mode mode = WbSimulationState::instance()->mode();
308283
switch (mode) {
@@ -317,10 +292,10 @@ void WbSimulationWorld::modeChanged() {
317292
WbSoundEngine::setMute(WbPreferences::instance()->value("Sound/mute").toBool());
318293
break;
319294
case WbSimulationState::REALTIME:
320-
mRealTimeTimer.start();
321295
WbSoundEngine::setPause(false);
322296
WbSoundEngine::setMute(WbPreferences::instance()->value("Sound/mute").toBool());
323-
mTimer->start(mSleepRealTime);
297+
mOldTimeStep = timeStep;
298+
mTimer->start(timeStep);
324299
break;
325300
case WbSimulationState::FAST:
326301
WbSoundEngine::setPause(false);

src/webots/engine/WbSimulationWorld.hpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,7 @@ protected slots:
7676
WbOdeContext *mOdeContext;
7777
WbPhysicsPlugin *mPhysicsPlugin;
7878
QTimer *mTimer;
79-
QElapsedTimer mRealTimeTimer;
80-
double mSleepRealTime;
81-
QList<int> mElapsedTimeHistory;
79+
double mOldTimeStep;
8280
QVector<WbNode *> mAddedNode; // list of nodes added since the simulation started
8381

8482
void storeLastSaveTime() override;

0 commit comments

Comments
 (0)