Nebula
Loading...
Searching...
No Matches
extrapolator.h
Go to the documentation of this file.
1
#pragma once
2
//------------------------------------------------------------------------------
34
#include "
timing/time.h
"
35
36
namespace
Math
37
{
38
template
<
class
TYPE>
class
Extrapolator
39
{
40
public
:
42
Extrapolator
();
44
~Extrapolator
() =
default
;
46
bool
AddSample
(
Timing::Time
packetTime,
Timing::Time
curTime,
const
TYPE& pos);
48
bool
AddSample
(
Timing::Time
packetTime,
Timing::Time
curTime,
const
TYPE& pos,
const
TYPE& vel);
50
void
Reset
(
Timing::Time
packetTime,
Timing::Time
curTime,
const
TYPE& pos);
52
void
Reset
(
Timing::Time
packetTime,
Timing::Time
curTime,
const
TYPE& pos,
const
TYPE& vel);
56
bool
ReadValue
(
Timing::Time
forTime, TYPE& oPos)
const
;
60
bool
ReadValue
(
Timing::Time
forTime, TYPE& oPos, TYPE& oVel)
const
;
62
Timing::Time
EstimateLatency
()
const
;
64
Timing::Time
EstimateUpdateTime
()
const
;
65
67
bool
Estimates
(
Timing::Time
packetTime,
Timing::Time
curTime);
68
69
TYPE
snapPos
;
70
TYPE
snapVel
;
71
TYPE
aimPos
;
72
TYPE
lastPacketPos
;
// only used when re-constituting velocity
73
Timing::Time
snapTime
;
// related to this->snapPos
74
Timing::Time
aimTime
;
// related to this->aimPos
75
Timing::Time
lastPacketTime
;
// related to this->lastPacketPos
76
Timing::Time
latency
;
77
Timing::Time
updateTime
;
78
};
79
80
//------------------------------------------------------------------------------
83
template
<
class
TYPE>
84
Extrapolator<TYPE>::Extrapolator
()
85
{
86
this->
Reset
(0, 0, TYPE());
87
}
88
89
//------------------------------------------------------------------------------
104
template
<
class
TYPE>
bool
105
Extrapolator<TYPE>::AddSample
(
Timing::Time
packetTime,
Timing::Time
curTime,
const
TYPE& pos)
106
{
107
// The best guess I can make for velocity is the difference between
108
// this sample and the last registered sample.
109
// if you use this function, TYPE must implement zero assignment
110
TYPE vel(0);
111
if
(
Math::abs
(packetTime - this->
lastPacketTime
) >
N_TINY
)
// 1e-4
112
{
113
float
dt = (float)(1.0 / (packetTime - this->
lastPacketTime
));
114
vel = (pos - this->
lastPacketPos
) * dt;
115
}
116
return
this->
AddSample
(packetTime, curTime, pos, vel);
117
}
118
119
//------------------------------------------------------------------------------
140
template
<
class
TYPE>
bool
141
Extrapolator<TYPE>::AddSample
(
Timing::Time
packetTime,
Timing::Time
curTime,
const
TYPE& pos,
const
TYPE& vel)
142
{
143
if
(!
Estimates
(packetTime, curTime)) {
144
return
false
;
145
}
146
this->
lastPacketPos
= pos;
147
this->
lastPacketTime
= packetTime;
148
this->
ReadValue
(curTime, this->
snapPos
);
149
this->
aimTime
= curTime + this->
updateTime
;
150
float
dt = (float)(this->
aimTime
- packetTime);
151
this->
snapTime
= curTime;
152
this->
aimPos
= pos + vel * dt;
153
154
// I now have two positions and two times:
155
// this->aimPos / this->aimTime
156
// this->snapPos / this->snapTime
157
// I must generate the interpolation velocity based on these two samples.
158
// However, if this->aimTime is the same as this->snapTime, I'm in trouble. In that
159
// case, use the supplied velocity.
160
if
(
Math::abs
(this->
aimTime
- this->
snapTime
) <
N_TINY
)
161
{
162
this->
snapVel
= vel;
163
}
164
else
165
{
166
float
dt = (float)(1.0 / (this->
aimTime
- this->
snapTime
));
167
this->
snapVel
= (this->
aimPos
- this->
snapPos
) * dt;
168
}
169
return
true
;
170
}
171
172
//------------------------------------------------------------------------------
180
template
<
class
TYPE>
void
181
Extrapolator<TYPE>::Reset
(
Timing::Time
packetTime,
Timing::Time
curTime,
const
TYPE& pos)
182
{
183
TYPE vel(0);
184
this->
Reset
(packetTime, curTime, pos, vel);
185
}
186
187
//------------------------------------------------------------------------------
195
template
<
class
TYPE>
void
196
Extrapolator<TYPE>::Reset
(
Timing::Time
packetTime,
Timing::Time
curTime,
const
TYPE& pos,
const
TYPE& vel)
197
{
198
n_assert
(packetTime <= curTime);
199
this->
lastPacketTime
= packetTime;
200
this->
lastPacketPos
= pos;
201
this->
snapTime
= curTime;
202
this->
snapPos
= pos;
203
this->
updateTime
= curTime - packetTime;
204
this->
latency
= this->
updateTime
;
205
this->
aimTime
= curTime + this->
updateTime
;
206
this->
snapVel
= vel;
207
this->
aimPos
= this->
snapPos
+ this->
snapVel
* (float)this->updateTime;
208
}
209
210
//------------------------------------------------------------------------------
223
template
<
class
TYPE>
bool
224
Extrapolator<TYPE>::ReadValue
(
Timing::Time
forTime, TYPE& oPos)
const
225
{
226
TYPE vel;
227
return
this->
ReadValue
(forTime, oPos, vel);
228
}
229
230
//------------------------------------------------------------------------------
244
template
<
class
TYPE>
bool
245
Extrapolator<TYPE>::ReadValue
(
Timing::Time
forTime, TYPE& oPos, TYPE& oVel)
const
246
{
247
bool
ok =
true
;
248
249
// asking for something before the allowable time?
250
if
(forTime < this->
snapTime
)
251
{
252
forTime = this->snapTime;
253
ok =
false
;
254
}
255
256
// asking for something very far in the future?
257
Timing::Time
maxRange = this->
aimTime
+ this->
updateTime
;
258
if
(forTime > maxRange)
259
{
260
forTime = maxRange;
261
ok =
false
;
262
}
263
264
// calculate the interpolated position
265
oVel = this->
snapVel
;
266
oPos = this->
snapPos
+ oVel * (float)(forTime - this->snapTime);
267
268
return
ok;
269
}
270
271
//------------------------------------------------------------------------------
277
template
<
class
TYPE>
Timing::Time
278
Extrapolator<TYPE>::EstimateLatency
()
const
279
{
280
return
this->
latency
;
281
}
282
283
//------------------------------------------------------------------------------
288
template
<
class
TYPE>
Timing::Time
289
Extrapolator<TYPE>::EstimateUpdateTime
()
const
290
{
291
return
this->
updateTime
;
292
}
293
294
//------------------------------------------------------------------------------
297
template
<
class
TYPE>
bool
298
Extrapolator<TYPE>::Estimates
(
Timing::Time
packet,
Timing::Time
cur)
299
{
300
if
(packet <= this->
lastPacketTime
)
301
{
302
return
false
;
303
}
304
305
// The theory is that, if latency increases, quickly
306
// compensate for it, but if latency decreases, be a
307
// little more resilient; this is intended to compensate
308
// for jittery delivery.
309
Timing::Time
lat = cur - packet;
310
if
(lat < 0) lat = 0;
311
if
(lat > this->
latency
)
312
{
313
this->
latency
= (this->
latency
+ lat) * 0.5;
314
}
315
else
316
{
317
this->
latency
= (this->
latency
* 7 + lat) * 0.125;
318
}
319
320
// Do the same running average for update time.
321
// Again, the theory is that a lossy connection wants
322
// an average of a higher update time.
323
Timing::Time
tick = packet - this->lastPacketTime;
324
if
(tick > this->
updateTime
)
325
{
326
this->
updateTime
= (this->
updateTime
+ tick) * 0.5;
327
}
328
else
329
{
330
this->
updateTime
= (this->
updateTime
* 7.0 + tick) * 0.125;
331
}
332
333
return
true
;
334
}
335
336
}
Math::Extrapolator::latency
Timing::Time latency
Definition
extrapolator.h:76
Math::Extrapolator::lastPacketTime
Timing::Time lastPacketTime
Definition
extrapolator.h:75
Math::Extrapolator::EstimateUpdateTime
Timing::Time EstimateUpdateTime() const
Definition
extrapolator.h:289
Math::Extrapolator::lastPacketPos
TYPE lastPacketPos
Definition
extrapolator.h:72
Math::Extrapolator::aimTime
Timing::Time aimTime
Definition
extrapolator.h:74
Math::Extrapolator::ReadValue
bool ReadValue(Timing::Time forTime, TYPE &oPos) const
Return an estimate of the interpolated position at a given global time (which typically will be great...
Definition
extrapolator.h:224
Math::Extrapolator::~Extrapolator
~Extrapolator()=default
destructor
Math::Extrapolator::EstimateLatency
Timing::Time EstimateLatency() const
Definition
extrapolator.h:278
Math::Extrapolator::Extrapolator
Extrapolator()
constructor
Definition
extrapolator.h:84
Math::Extrapolator::Reset
void Reset(Timing::Time packetTime, Timing::Time curTime, const TYPE &pos)
Re-set the Extrapolator's idea of time, velocity and position.
Definition
extrapolator.h:181
Math::Extrapolator::AddSample
bool AddSample(Timing::Time packetTime, Timing::Time curTime, const TYPE &pos)
add sample without velocity, velocity is compute from positions
Definition
extrapolator.h:105
Math::Extrapolator::snapVel
TYPE snapVel
Definition
extrapolator.h:70
Math::Extrapolator::updateTime
Timing::Time updateTime
Definition
extrapolator.h:77
Math::Extrapolator::Estimates
bool Estimates(Timing::Time packetTime, Timing::Time curTime)
is this packet newer than already received
Definition
extrapolator.h:298
Math::Extrapolator::snapPos
TYPE snapPos
Definition
extrapolator.h:69
Math::Extrapolator::snapTime
Timing::Time snapTime
Definition
extrapolator.h:73
Math::Extrapolator::aimPos
TYPE aimPos
Definition
extrapolator.h:71
n_assert
#define n_assert(exp)
Definition
debug.h:50
Math
Different curves.
Definition
angularpfeedbackloop.h:17
Math::abs
__forceinline scalar abs(scalar a)
Definition
scalar.h:441
Timing::Time
double Time
the time datatype
Definition
time.h:18
N_TINY
#define N_TINY
Definition
scalar.h:43
time.h
Typedefs for the Timing subsystem.
code
foundation
math
extrapolator.h
Generated on Mon Aug 4 2025 21:41:54 for Nebula. Dark theme by
Tilen Majerle
. All rights reserved.