119
static REAL se_timerStartFudge = 0.0;
120
static tSettingItem<REAL> se_timerStartFudgeConf("TIMER_SYNC_START_FUDGE",se_timerStartFudge);
121
static REAL se_timerStartFudgeStop = 2.0;
122
static tSettingItem<REAL> se_timerStartFudgeStopConf("TIMER_SYNC_START_FUDGE_STOP",se_timerStartFudgeStop);
124
121
void eTimer::ReadSync(nMessage &m){
125
122
nNetObject::ReadSync(m);
124
if( sn_GetNetState() != nCLIENT || m.SenderID() != 0 )
129
m >> remoteCurrentTime_; // read in the remote time
133
//std::cerr << "Got sync:" << remote_currentTime << ":" << speed << '\n';
136
static REAL se_cullDelayEnd=3.0; // end of extra delay cull
137
static REAL se_cullDelayPerSecond=3.0; // delay cull drop per second
138
static REAL se_cullDelayMin=10.0; // plateau of delay cull after extra
140
static tSettingItem< REAL > se_cullDelayEndConf( "CULL_DELAY_END", se_cullDelayEnd );
141
static tSettingItem< REAL > se_cullDelayPerSecondConf( "CULL_DELAY_PER_SECOND", se_cullDelayPerSecond );
142
static tSettingItem< REAL > se_cullDelayMinConf( "CULL_DELAY_MIN", se_cullDelayMin );
144
void eTimer::ProcessSync()
127
148
bool checkDrift = true;
129
//std::cerr << "Got sync:" << remote_currentTime << ":" << speed << '\n';
131
150
// determine the best estimate of the start time offset that reproduces the sent remote
132
151
// time and its expected quality.
133
152
REAL remoteStartTimeOffset = 0;
134
153
REAL remoteTimeNonQuality = 0;
156
nPingAverager & pingAverager = sn_Connections[0].ping;
157
REAL ping = pingAverager.GetPing();
158
REAL pingVariance = pingAverager.GetFastAverager().GetAverageVariance();
136
//REAL oldTime=currentTime;
137
REAL remote_currentTime, remoteSpeed;
138
m >> remote_currentTime; // read in the remote time
161
// adapt remote time a little, we're processing syncs with a frame delay
162
REAL remote_currentTime = remoteCurrentTime_ + averageSpf_.GetAverage();
163
REAL remoteSpeed = remoteSpeed_;
141
165
// forget about earlier syncs if the speed changed
142
166
if ( fabs( speed - remoteSpeed ) > 10 * EPS )
149
173
speed = remoteSpeed;
152
nPingAverager & averager = sn_Connections[m.SenderID()].ping;
153
// pingAverager_.Add( rawAverager.GetPing(), remote_currentTime > .01 ? remote_currentTime : .01 );
154
REAL ping = averager.GetPing();
156
175
// add half our ping (see Einsteins SRT on clock syncronisation)
157
176
REAL real_remoteTime=remote_currentTime+ping*speed*.5;
166
185
remote_currentTime=real_remoteTime;
168
// HACK: warp time into the future at the beginning of the round.
169
// I can't explain why this is required; without it, the timer is late.
170
if ( remote_currentTime < se_timerStartFudgeStop )
172
remote_currentTime += ping * ( se_timerStartFudgeStop - remote_currentTime ) * se_timerStartFudge;
176
187
// determine quality from ping variance
177
remoteTimeNonQuality = averager.GetFastAverager().GetAverageVariance();
188
remoteTimeNonQuality = pingVariance;
179
190
// determine start time
180
191
remoteStartTimeOffset = smoothedSystemTime_ - startTime_ - remote_currentTime;
214
225
// add the variance to the non-quality, along with an offset to avoid division by zero
215
226
remoteTimeNonQuality += 0.00001 + 4 * qualityTester_.GetAverageVariance();
229
con << "T=" << smoothedSystemTime_ << " " << lastRemoteTime_ << ", Q= " << remoteTimeNonQuality << ", P= " << ping << " +/- " << sqrt(pingVariance) << " Time offset: " << remoteStartTimeOffset << " : " << startTimeOffset_.GetAverage() << "\n";
231
std::ofstream plot("timesync.txt",std::ios_base::app);
232
plot << smoothedSystemTime_ << " " << remoteStartTimeOffset << " " << startTimeOffset_.GetAverage() << "\n";
235
// check for unusually delayed packets, give them lower weight
236
REAL delay = remoteStartTimeOffset - startTimeOffset_.GetAverage();
239
// fluctuations up to the ping variance are acceptable,
240
// (plus some extra factors, like a 1 ms offset and 10% of the current ping)
241
// severity will be < 1 for those
242
REAL severity = delay*delay/(.000001 + pingVariance + .01*ping*ping);
243
// but it is culled above 1
246
severity = pow(severity,.25);
249
REAL cullFactor = (se_cullDelayEnd-lastRemoteTime_)*se_cullDelayPerSecond;
254
cullFactor += se_cullDelayMin;
257
con << "severity=" << severity << ", cull= " << cullFactor << "\n";
259
remoteTimeNonQuality *= 1+(cullFactor-1)*severity;
217
262
// add the offset to the statistics, weighted by the quality
218
263
startTimeOffset_.Add( remoteStartTimeOffset, 1/remoteTimeNonQuality );
355
407
startTimeOffset_.Add(100,EPS);
356
408
startTimeOffset_.Add(-100,EPS);
358
412
qualityTester_.Reset();
359
413
static const REAL qual = sqrt(1/EPS);
360
414
qualityTester_.Add(qual,EPS);