From faf06b42a3d5389e91ce24ef8bd039b5da28bcef Mon Sep 17 00:00:00 2001 From: jean pellotier Date: Tue, 18 Dec 2018 01:41:26 +0100 Subject: [PATCH] preparation for the lag correction based on time sync, instead of fixed lag compensation, this is the time manager part. - introduction of a pure steady clock initialised from system clock at init - the mp protocol clock have an offset available (will be used to sync the players, in case ntpd is not accurate or inavailable) - got a way to see drift between system clock and the fg steady clock, mainly to see how differents OS behave ... --- src/Time/TimeManager.cxx | 36 ++++++++++++++++++++++++++++++------ src/Time/TimeManager.hxx | 8 +++++++- 2 files changed, 37 insertions(+), 7 deletions(-) diff --git a/src/Time/TimeManager.cxx b/src/Time/TimeManager.cxx index fd2fd8747..73c7b1bf7 100644 --- a/src/Time/TimeManager.cxx +++ b/src/Time/TimeManager.cxx @@ -75,7 +75,7 @@ void TimeManager::init() _firstUpdate = true; _inited = true; _dtRemainder = 0.0; - _mpProtocolClock = 0.0; + _mpProtocolClock = _steadyClock = 0.0; _adjustWarpOnUnfreeze = false; _maxDtPerFrame = fgGetNode("/sim/max-simtime-per-frame", true); @@ -114,13 +114,21 @@ void TimeManager::init() _modelHz = fgGetNode("sim/model-hz", true); _timeDelta = fgGetNode("sim/time/delta-realtime-sec", true); _simTimeDelta = fgGetNode("sim/time/delta-sec", true); - _mpClockNode = fgGetNode("sim/time/mp-clock-sec", true); + _mpProtocolClockNode = fgGetNode("sim/time/mp-clock-sec", true); + _steadyClockNode = fgGetNode("sim/time/steady-clock-sec", true); + _mpClockOffset = fgGetNode("sim/time/mp-clock-offset-sec", true); + _steadyClockDrift = fgGetNode("sim/time/steady-clock-drift-ms", true); + _computeDrift = fgGetNode("sim/time/compute-clock-drift", true); _frameWait = fgGetNode("sim/time/frame-wait-ms", true); _simTimeFactor = fgGetNode("/sim/speed-up", true); // use pre-set value but ensure we get a sane default if (!_simTimeDelta->hasValue()) { _simTimeFactor->setDoubleValue(1.0); } + if (!_mpClockOffset->hasValue()) { + _mpClockOffset->setDoubleValue(0.0); + } + _computeDrift->setBoolValue(true); } void TimeManager::unbind() @@ -138,7 +146,11 @@ void TimeManager::unbind() _modelHz.clear(); _timeDelta.clear(); _simTimeDelta.clear(); - _mpClockNode.clear(); + _mpProtocolClockNode.clear(); + _steadyClockNode.clear(); + _mpClockOffset.clear(); + _steadyClockDrift.clear(); + _computeDrift.clear(); _simTimeFactor.clear(); } @@ -189,7 +201,7 @@ void TimeManager::computeTimeDeltas(double& simDt, double& realDt) // we initialise the mp protocol clock with the system clock. _systemStamp.systemClockHoursAndMinutes(); - _mpProtocolClock = _systemStamp.toSecs(); + _steadyClock = _systemStamp.toSecs(); _firstUpdate = false; _lastClockFreeze = _clockFreeze->getBoolValue(); @@ -209,6 +221,16 @@ void TimeManager::computeTimeDeltas(double& simDt, double& realDt) SGTimeStamp currentStamp; currentStamp.stamp(); + // if asked, we compute the drift between the steady clock and the system clock + + if (_computeDrift->getBoolValue()) { + _systemStamp.systemClockHoursAndMinutes(); + double clockdrift = _steadyClock + (currentStamp - _lastStamp).toSecs() + + _dtRemainder - _systemStamp.toSecs(); + _steadyClockDrift->setDoubleValue(clockdrift * 1000.0); + _computeDrift->setBoolValue(false); + } + // this dt will be clamped by the max sim time by frame. double dt = (currentStamp - _lastStamp).toSecs(); @@ -260,9 +282,11 @@ void TimeManager::computeTimeDeltas(double& simDt, double& realDt) _lastStamp = currentStamp; globals->inc_sim_time_sec(simDt); - _mpProtocolClock += mpProtocolDt; + _steadyClock += mpProtocolDt; + _mpProtocolClock = _steadyClock + _mpClockOffset->getDoubleValue(); - _mpClockNode->setDoubleValue(_mpProtocolClock); + _steadyClockNode->setDoubleValue(_steadyClock); + _mpProtocolClockNode->setDoubleValue(_mpProtocolClock); // These are useful, especially for Nasal scripts. _timeDelta->setDoubleValue(realDt); diff --git a/src/Time/TimeManager.hxx b/src/Time/TimeManager.hxx index eb771248b..612536b4c 100644 --- a/src/Time/TimeManager.hxx +++ b/src/Time/TimeManager.hxx @@ -48,6 +48,7 @@ public: void setTimeOffset(const std::string& offset_type, long int offset); inline double getMPProtocolClockSec() const { return _mpProtocolClock; } + inline double getSteadyClockSec() const { return _steadyClock; } static const char* subsystemName() { return "time"; } private: @@ -80,7 +81,11 @@ private: SGPropertyNode_ptr _warp; SGPropertyNode_ptr _warpDelta; SGPropertyNode_ptr _simTimeFactor; - SGPropertyNode_ptr _mpClockNode; + SGPropertyNode_ptr _mpProtocolClockNode; + SGPropertyNode_ptr _steadyClockNode; + SGPropertyNode_ptr _mpClockOffset; + SGPropertyNode_ptr _steadyClockDrift; + SGPropertyNode_ptr _computeDrift; SGPropertyNode_ptr _frameWait; SGPropertyNode_ptr _maxFrameRate; @@ -94,6 +99,7 @@ private: time_t _lastFrameTime; double _frameLatencyMax; double _mpProtocolClock; + double _steadyClock; int _frameCount; SGPropertyNode_ptr _sceneryLoaded;