Nebula
Loading...
Searching...
No Matches
extrapolator.h
Go to the documentation of this file.
1#pragma once
2//------------------------------------------------------------------------------
17#include "timing/time.h"
18
19namespace Math
20{
21template<class TYPE> class Extrapolator
22{
23public:
27 virtual ~Extrapolator();
29 bool AddSample(Timing::Time packetTime, Timing::Time curTime, const TYPE& pos);
31 bool AddSample(Timing::Time packetTime, Timing::Time curTime, const TYPE& pos, const TYPE& vel);
33 void Reset(Timing::Time packetTime, Timing::Time curTime, const TYPE& pos);
35 void Reset(Timing::Time packetTime, Timing::Time curTime, const TYPE& pos, const TYPE& vel);
39 bool ReadValue(Timing::Time forTime, TYPE& oPos) const;
43 bool ReadValue(Timing::Time forTime, TYPE& oPos, TYPE& oVel) const;
48
49private:
51 bool Estimates(Timing::Time packetTime, Timing::Time curTime);
52
53 TYPE snapPos;
54 TYPE snapVel;
55 TYPE aimPos;
56 TYPE lastPacketPos; // only used when re-constituting velocity
57 Timing::Time snapTime; // related to this->snapPos
58 Timing::Time aimTime; // related to this->aimPos
59 Timing::Time lastPacketTime; // related to this->lastPacketPos
62};
63
64//------------------------------------------------------------------------------
67template<class TYPE>
69{
70 this->Reset(0, 0, TYPE());
71}
72
73//------------------------------------------------------------------------------
76template<class TYPE>
80
81//------------------------------------------------------------------------------
84template<class TYPE> bool
85Extrapolator<TYPE>::AddSample(Timing::Time packetTime, Timing::Time curTime, const TYPE& pos)
86{
87 // The best guess I can make for velocity is the difference between
88 // this sample and the last registered sample.
89 // if you use this function, TYPE must implement zero assignment
90 TYPE vel(0);
91 if (Math::abs(packetTime - this->lastPacketTime) > N_TINY) //1e-4
92 {
93 float dt = (float)(1.0 / (packetTime - this->lastPacketTime));
94 vel = (pos - this->lastPacketPos) * dt;
95 }
96 return this->AddSample(packetTime, curTime, pos, vel);
97}
98
99//------------------------------------------------------------------------------
102template<class TYPE> bool
103Extrapolator<TYPE>::AddSample(Timing::Time packetTime, Timing::Time curTime, const TYPE& pos, const TYPE& vel)
104{
105 if (!Estimates(packetTime, curTime)) {
106 return false;
107 }
108 this->lastPacketPos = pos;
109 this->lastPacketTime = packetTime;
110 this->ReadValue(curTime, this->snapPos);
111 this->aimTime = curTime + this->updateTime;
112 float dt = (float)(this->aimTime - packetTime);
113 this->snapTime = curTime;
114 this->aimPos = pos + vel * dt;
115
116 // I now have two positions and two times:
117 // this->aimPos / this->aimTime
118 // this->snapPos / this->snapTime
119 // I must generate the interpolation velocity based on these two samples.
120 // However, if this->aimTime is the same as this->snapTime, I'm in trouble. In that
121 // case, use the supplied velocity.
122 if (Math::abs(this->aimTime - this->snapTime) < N_TINY)
123 {
124 this->snapVel = vel;
125 }
126 else
127 {
128 float dt = (float)(1.0 / (this->aimTime - this->snapTime));
129 this->snapVel = (this->aimPos - this->snapPos) * dt;
130 }
131 return true;
132}
133
134//------------------------------------------------------------------------------
137template<class TYPE> void
138Extrapolator<TYPE>::Reset(Timing::Time packetTime, Timing::Time curTime, const TYPE& pos)
139{
140 TYPE vel;
141 this->Reset(packetTime, curTime, pos, vel);
142}
143
144//------------------------------------------------------------------------------
147template<class TYPE> void
148Extrapolator<TYPE>::Reset(Timing::Time packetTime, Timing::Time curTime, const TYPE& pos, const TYPE& vel)
149{
150 n_assert(packetTime <= curTime);
151 this->lastPacketTime = packetTime;
152 this->lastPacketPos = pos;
153 this->snapTime = curTime;
154 this->snapPos = pos;
155 this->updateTime = curTime - packetTime;
156 this->latency = this->updateTime;
157 this->aimTime = curTime + this->updateTime;
158 this->snapVel = vel;
159 this->aimPos = this->snapPos + this->snapVel * (float)this->updateTime;
160}
161
162//------------------------------------------------------------------------------
165template<class TYPE> bool
167{
168 TYPE vel;
169 return this->ReadValue(forTime, oPos, vel);
170}
171
172//------------------------------------------------------------------------------
175template<class TYPE> bool
176Extrapolator<TYPE>::ReadValue(Timing::Time forTime, TYPE& oPos, TYPE& oVel) const
177{
178 bool ok = true;
179
180 // asking for something before the allowable time?
181 if (forTime < this->snapTime)
182 {
183 forTime = this->snapTime;
184 ok = false;
185 }
186
187 // asking for something very far in the future?
188 Timing::Time maxRange = this->aimTime + this->updateTime;
189 if (forTime > maxRange)
190 {
191 forTime = maxRange;
192 ok = false;
193 }
194
195 // calculate the interpolated position
196 oVel = this->snapVel;
197 oPos = this->snapPos + oVel * (float)(forTime - this->snapTime);
198
199 return ok;
200}
201
202//------------------------------------------------------------------------------
205template<class TYPE> Timing::Time
207{
208 return this->latency;
209}
210
211//------------------------------------------------------------------------------
214template<class TYPE> Timing::Time
216{
217 return this->updateTime;
218}
219
220//------------------------------------------------------------------------------
223template<class TYPE> bool
225{
226 if (packet <= this->lastPacketTime)
227 {
228 return false;
229 }
230
231 // The theory is that, if latency increases, quickly
232 // compensate for it, but if latency decreases, be a
233 // little more resilient; this is intended to compensate
234 // for jittery delivery.
235 Timing::Time lat = cur - packet;
236 if (lat < 0) lat = 0;
237 if (lat > this->latency)
238 {
239 this->latency = (this->latency + lat) * 0.5;
240 }
241 else
242 {
243 this->latency = (this->latency * 7 + lat) * 0.125;
244 }
245
246 // Do the same running average for update time.
247 // Again, the theory is that a lossy connection wants
248 // an average of a higher update time.
249 Timing::Time tick = packet - this->lastPacketTime;
250 if (tick > this->updateTime)
251 {
252 this->updateTime = (this->updateTime + tick) * 0.5;
253 }
254 else
255 {
256 this->updateTime = (this->updateTime * 7 + tick) * 0.125;
257 }
258
259 return true;
260}
261
262}
Extrapolator maintains state about updates for remote entities, and will generate smooth guesses abou...
Definition extrapolator.h:22
virtual ~Extrapolator()
destructor
Definition extrapolator.h:77
Timing::Time latency
Definition extrapolator.h:60
Timing::Time lastPacketTime
Definition extrapolator.h:59
Timing::Time EstimateUpdateTime() const
Definition extrapolator.h:215
TYPE lastPacketPos
Definition extrapolator.h:56
Timing::Time aimTime
Definition extrapolator.h:58
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:166
Timing::Time EstimateLatency() const
Definition extrapolator.h:206
Extrapolator()
constructor
Definition extrapolator.h:68
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:138
bool AddSample(Timing::Time packetTime, Timing::Time curTime, const TYPE &pos)
add sample without velocity, velocity is compute from positions
Definition extrapolator.h:85
TYPE snapVel
Definition extrapolator.h:54
Timing::Time updateTime
Definition extrapolator.h:61
bool Estimates(Timing::Time packetTime, Timing::Time curTime)
is this packet newer than already received
Definition extrapolator.h:224
TYPE snapPos
Definition extrapolator.h:53
Timing::Time snapTime
Definition extrapolator.h:57
TYPE aimPos
Definition extrapolator.h:55
#define n_assert(exp)
Definition debug.h:50
Different curves.
Definition angularpfeedbackloop.h:17
__forceinline scalar abs(scalar a)
Definition scalar.h:432
double Time
the time datatype
Definition time.h:18
#define N_TINY
Definition scalar.h:43
Typedefs for the Timing subsystem.