rev |
line source |
nuclear@3
|
1 /************************************************************************************
|
nuclear@3
|
2
|
nuclear@3
|
3 Filename : Util_LatencyTest.cpp
|
nuclear@3
|
4 Content : Wraps the lower level LatencyTester interface and adds functionality.
|
nuclear@3
|
5 Created : February 14, 2013
|
nuclear@3
|
6 Authors : Lee Cooper
|
nuclear@3
|
7
|
nuclear@3
|
8 Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
|
nuclear@3
|
9
|
nuclear@3
|
10 Use of this software is subject to the terms of the Oculus license
|
nuclear@3
|
11 agreement provided at the time of installation or download, or which
|
nuclear@3
|
12 otherwise accompanies this software in either electronic or hard copy form.
|
nuclear@3
|
13
|
nuclear@3
|
14 *************************************************************************************/
|
nuclear@3
|
15
|
nuclear@3
|
16 #include "Util_LatencyTest.h"
|
nuclear@3
|
17
|
nuclear@3
|
18 #include "../Kernel/OVR_Log.h"
|
nuclear@3
|
19 #include "../Kernel/OVR_Timer.h"
|
nuclear@3
|
20
|
nuclear@3
|
21 namespace OVR { namespace Util {
|
nuclear@3
|
22
|
nuclear@3
|
23 static const UInt32 TIME_TO_WAIT_FOR_SETTLE_PRE_CALIBRATION = 16*10;
|
nuclear@3
|
24 static const UInt32 TIME_TO_WAIT_FOR_SETTLE_POST_CALIBRATION = 16*10;
|
nuclear@3
|
25 static const UInt32 TIME_TO_WAIT_FOR_SETTLE_POST_MEASUREMENT = 16*5;
|
nuclear@3
|
26 static const UInt32 TIME_TO_WAIT_FOR_SETTLE_POST_MEASUREMENT_RANDOMNESS = 16*5;
|
nuclear@3
|
27 static const UInt32 DEFAULT_NUMBER_OF_SAMPLES = 10; // For both color 1->2 and color 2->1 transitions.
|
nuclear@3
|
28 static const UInt32 INITIAL_SAMPLES_TO_IGNORE = 4;
|
nuclear@3
|
29 static const UInt32 TIMEOUT_WAITING_FOR_TEST_STARTED = 1000;
|
nuclear@3
|
30 static const UInt32 TIMEOUT_WAITING_FOR_COLOR_DETECTED = 4000;
|
nuclear@3
|
31 static const Color CALIBRATE_BLACK(0, 0, 0);
|
nuclear@3
|
32 static const Color CALIBRATE_WHITE(255, 255, 255);
|
nuclear@3
|
33 static const Color COLOR1(0, 0, 0);
|
nuclear@3
|
34 static const Color COLOR2(255, 255, 255);
|
nuclear@3
|
35 static const Color SENSOR_DETECT_THRESHOLD(128, 255, 255);
|
nuclear@3
|
36 static const float BIG_FLOAT = 1000000.0f;
|
nuclear@3
|
37 static const float SMALL_FLOAT = -1000000.0f;
|
nuclear@3
|
38
|
nuclear@3
|
39 //-------------------------------------------------------------------------------------
|
nuclear@3
|
40 // ***** LatencyTest
|
nuclear@3
|
41
|
nuclear@3
|
42 LatencyTest::LatencyTest(LatencyTestDevice* device)
|
nuclear@3
|
43 : Handler(getThis())
|
nuclear@3
|
44 {
|
nuclear@3
|
45 if (device != NULL)
|
nuclear@3
|
46 {
|
nuclear@3
|
47 SetDevice(device);
|
nuclear@3
|
48 }
|
nuclear@3
|
49
|
nuclear@3
|
50 reset();
|
nuclear@3
|
51
|
nuclear@3
|
52 srand(Timer::GetTicksMs());
|
nuclear@3
|
53 }
|
nuclear@3
|
54
|
nuclear@3
|
55 LatencyTest::~LatencyTest()
|
nuclear@3
|
56 {
|
nuclear@3
|
57 clearMeasurementResults();
|
nuclear@3
|
58 }
|
nuclear@3
|
59
|
nuclear@3
|
60 bool LatencyTest::SetDevice(LatencyTestDevice* device)
|
nuclear@3
|
61 {
|
nuclear@3
|
62
|
nuclear@3
|
63 if (device != Device)
|
nuclear@3
|
64 {
|
nuclear@3
|
65 if (device != NULL)
|
nuclear@3
|
66 {
|
nuclear@3
|
67 if (device->GetMessageHandler() != NULL)
|
nuclear@3
|
68 {
|
nuclear@3
|
69 OVR_DEBUG_LOG(
|
nuclear@3
|
70 ("LatencyTest::AttachToDevice failed - device %p already has handler", device));
|
nuclear@3
|
71 return false;
|
nuclear@3
|
72 }
|
nuclear@3
|
73 }
|
nuclear@3
|
74
|
nuclear@3
|
75 if (Device != NULL)
|
nuclear@3
|
76 {
|
nuclear@3
|
77 Device->SetMessageHandler(0);
|
nuclear@3
|
78 }
|
nuclear@3
|
79 Device = device;
|
nuclear@3
|
80
|
nuclear@3
|
81 if (Device != NULL)
|
nuclear@3
|
82 {
|
nuclear@3
|
83 Device->SetMessageHandler(&Handler);
|
nuclear@3
|
84
|
nuclear@3
|
85 // Set trigger threshold.
|
nuclear@3
|
86 LatencyTestConfiguration configuration(SENSOR_DETECT_THRESHOLD, false); // No samples streaming.
|
nuclear@3
|
87 Device->SetConfiguration(configuration, true);
|
nuclear@3
|
88
|
nuclear@3
|
89 // Set display to intial (3 dashes).
|
nuclear@3
|
90 LatencyTestDisplay ltd(2, 0x40400040);
|
nuclear@3
|
91 Device->SetDisplay(ltd);
|
nuclear@3
|
92 }
|
nuclear@3
|
93 }
|
nuclear@3
|
94
|
nuclear@3
|
95 return true;
|
nuclear@3
|
96 }
|
nuclear@3
|
97
|
nuclear@3
|
98 UInt32 LatencyTest::getRandomComponent(UInt32 range)
|
nuclear@3
|
99 {
|
nuclear@3
|
100 UInt32 val = rand() % range;
|
nuclear@3
|
101 return val;
|
nuclear@3
|
102 }
|
nuclear@3
|
103
|
nuclear@3
|
104 void LatencyTest::BeginTest()
|
nuclear@3
|
105 {
|
nuclear@3
|
106 if (State == State_WaitingForButton)
|
nuclear@3
|
107 {
|
nuclear@3
|
108 // Set color to black and wait a while.
|
nuclear@3
|
109 RenderColor = CALIBRATE_BLACK;
|
nuclear@3
|
110
|
nuclear@3
|
111 State = State_WaitingForSettlePreCalibrationColorBlack;
|
nuclear@3
|
112 OVR_DEBUG_LOG(("State_WaitingForButton -> State_WaitingForSettlePreCalibrationColorBlack."));
|
nuclear@3
|
113
|
nuclear@3
|
114 setTimer(TIME_TO_WAIT_FOR_SETTLE_PRE_CALIBRATION);
|
nuclear@3
|
115 }
|
nuclear@3
|
116 }
|
nuclear@3
|
117
|
nuclear@3
|
118 void LatencyTest::handleMessage(const Message& msg, LatencyTestMessageType latencyTestMessage)
|
nuclear@3
|
119 {
|
nuclear@3
|
120 // For debugging.
|
nuclear@3
|
121 /* if (msg.Type == Message_LatencyTestSamples)
|
nuclear@3
|
122 {
|
nuclear@3
|
123 MessageLatencyTestSamples* pSamples = (MessageLatencyTestSamples*) &msg;
|
nuclear@3
|
124
|
nuclear@3
|
125 if (pSamples->Samples.GetSize() > 0)
|
nuclear@3
|
126 {
|
nuclear@3
|
127 // Just show the first one for now.
|
nuclear@3
|
128 Color c = pSamples->Samples[0];
|
nuclear@3
|
129 OVR_DEBUG_LOG(("%d %d %d", c.R, c.G, c.B));
|
nuclear@3
|
130 }
|
nuclear@3
|
131 return;
|
nuclear@3
|
132 }
|
nuclear@3
|
133 */
|
nuclear@3
|
134
|
nuclear@3
|
135 if (latencyTestMessage == LatencyTest_Timer)
|
nuclear@3
|
136 {
|
nuclear@3
|
137 if (!Device)
|
nuclear@3
|
138 {
|
nuclear@3
|
139 reset();
|
nuclear@3
|
140 return;
|
nuclear@3
|
141 }
|
nuclear@3
|
142
|
nuclear@3
|
143 if (State == State_WaitingForSettlePreCalibrationColorBlack)
|
nuclear@3
|
144 {
|
nuclear@3
|
145 // Send calibrate message to device and wait a while.
|
nuclear@3
|
146 Device->SetCalibrate(CALIBRATE_BLACK);
|
nuclear@3
|
147
|
nuclear@3
|
148 State = State_WaitingForSettlePostCalibrationColorBlack;
|
nuclear@3
|
149 OVR_DEBUG_LOG(("State_WaitingForSettlePreCalibrationColorBlack -> State_WaitingForSettlePostCalibrationColorBlack."));
|
nuclear@3
|
150
|
nuclear@3
|
151 setTimer(TIME_TO_WAIT_FOR_SETTLE_POST_CALIBRATION);
|
nuclear@3
|
152 }
|
nuclear@3
|
153 else if (State == State_WaitingForSettlePostCalibrationColorBlack)
|
nuclear@3
|
154 {
|
nuclear@3
|
155 // Change color to white and wait a while.
|
nuclear@3
|
156 RenderColor = CALIBRATE_WHITE;
|
nuclear@3
|
157
|
nuclear@3
|
158 State = State_WaitingForSettlePreCalibrationColorWhite;
|
nuclear@3
|
159 OVR_DEBUG_LOG(("State_WaitingForSettlePostCalibrationColorBlack -> State_WaitingForSettlePreCalibrationColorWhite."));
|
nuclear@3
|
160
|
nuclear@3
|
161 setTimer(TIME_TO_WAIT_FOR_SETTLE_PRE_CALIBRATION);
|
nuclear@3
|
162 }
|
nuclear@3
|
163 else if (State == State_WaitingForSettlePreCalibrationColorWhite)
|
nuclear@3
|
164 {
|
nuclear@3
|
165 // Send calibrate message to device and wait a while.
|
nuclear@3
|
166 Device->SetCalibrate(CALIBRATE_WHITE);
|
nuclear@3
|
167
|
nuclear@3
|
168 State = State_WaitingForSettlePostCalibrationColorWhite;
|
nuclear@3
|
169 OVR_DEBUG_LOG(("State_WaitingForSettlePreCalibrationColorWhite -> State_WaitingForSettlePostCalibrationColorWhite."));
|
nuclear@3
|
170
|
nuclear@3
|
171 setTimer(TIME_TO_WAIT_FOR_SETTLE_POST_CALIBRATION);
|
nuclear@3
|
172 }
|
nuclear@3
|
173 else if (State == State_WaitingForSettlePostCalibrationColorWhite)
|
nuclear@3
|
174 {
|
nuclear@3
|
175 // Calibration is done. Switch to color 1 and wait for it to settle.
|
nuclear@3
|
176 RenderColor = COLOR1;
|
nuclear@3
|
177
|
nuclear@3
|
178 State = State_WaitingForSettlePostMeasurement;
|
nuclear@3
|
179 OVR_DEBUG_LOG(("State_WaitingForSettlePostCalibrationColorWhite -> State_WaitingForSettlePostMeasurement."));
|
nuclear@3
|
180
|
nuclear@3
|
181 UInt32 waitTime = TIME_TO_WAIT_FOR_SETTLE_POST_MEASUREMENT + getRandomComponent(TIME_TO_WAIT_FOR_SETTLE_POST_MEASUREMENT_RANDOMNESS);
|
nuclear@3
|
182 setTimer(waitTime);
|
nuclear@3
|
183 }
|
nuclear@3
|
184 else if (State == State_WaitingForSettlePostMeasurement)
|
nuclear@3
|
185 {
|
nuclear@3
|
186 // Prepare for next measurement.
|
nuclear@3
|
187
|
nuclear@3
|
188 // Create a new result object.
|
nuclear@3
|
189 MeasurementResult* pResult = new MeasurementResult();
|
nuclear@3
|
190 Results.PushBack(pResult);
|
nuclear@3
|
191
|
nuclear@3
|
192 State = State_WaitingToTakeMeasurement;
|
nuclear@3
|
193 OVR_DEBUG_LOG(("State_WaitingForSettlePostMeasurement -> State_WaitingToTakeMeasurement."));
|
nuclear@3
|
194 }
|
nuclear@3
|
195 else if (State == State_WaitingForTestStarted)
|
nuclear@3
|
196 {
|
nuclear@3
|
197 // We timed out waiting for 'TestStarted'. Abandon this measurement and setup for the next.
|
nuclear@3
|
198 getActiveResult()->TimedOutWaitingForTestStarted = true;
|
nuclear@3
|
199
|
nuclear@3
|
200 State = State_WaitingForSettlePostMeasurement;
|
nuclear@3
|
201 OVR_DEBUG_LOG(("** Timed out waiting for 'TestStarted'."));
|
nuclear@3
|
202 OVR_DEBUG_LOG(("State_WaitingForTestStarted -> State_WaitingForSettlePostMeasurement."));
|
nuclear@3
|
203
|
nuclear@3
|
204 UInt32 waitTime = TIME_TO_WAIT_FOR_SETTLE_POST_MEASUREMENT + getRandomComponent(TIME_TO_WAIT_FOR_SETTLE_POST_MEASUREMENT_RANDOMNESS);
|
nuclear@3
|
205 setTimer(waitTime);
|
nuclear@3
|
206 }
|
nuclear@3
|
207 else if (State == State_WaitingForColorDetected)
|
nuclear@3
|
208 {
|
nuclear@3
|
209 // We timed out waiting for 'ColorDetected'. Abandon this measurement and setup for the next.
|
nuclear@3
|
210 getActiveResult()->TimedOutWaitingForColorDetected = true;
|
nuclear@3
|
211
|
nuclear@3
|
212 State = State_WaitingForSettlePostMeasurement;
|
nuclear@3
|
213 OVR_DEBUG_LOG(("** Timed out waiting for 'ColorDetected'."));
|
nuclear@3
|
214 OVR_DEBUG_LOG(("State_WaitingForColorDetected -> State_WaitingForSettlePostMeasurement."));
|
nuclear@3
|
215
|
nuclear@3
|
216 UInt32 waitTime = TIME_TO_WAIT_FOR_SETTLE_POST_MEASUREMENT + getRandomComponent(TIME_TO_WAIT_FOR_SETTLE_POST_MEASUREMENT_RANDOMNESS);
|
nuclear@3
|
217 setTimer(waitTime);
|
nuclear@3
|
218 }
|
nuclear@3
|
219 }
|
nuclear@3
|
220 else if (latencyTestMessage == LatencyTest_ProcessInputs)
|
nuclear@3
|
221 {
|
nuclear@3
|
222 if (State == State_WaitingToTakeMeasurement)
|
nuclear@3
|
223 {
|
nuclear@3
|
224 if (!Device)
|
nuclear@3
|
225 {
|
nuclear@3
|
226 reset();
|
nuclear@3
|
227 return;
|
nuclear@3
|
228 }
|
nuclear@3
|
229
|
nuclear@3
|
230 // Send 'StartTest' feature report with opposite target color.
|
nuclear@3
|
231 if (RenderColor == COLOR1)
|
nuclear@3
|
232 {
|
nuclear@3
|
233 RenderColor = COLOR2;
|
nuclear@3
|
234 }
|
nuclear@3
|
235 else
|
nuclear@3
|
236 {
|
nuclear@3
|
237 RenderColor = COLOR1;
|
nuclear@3
|
238 }
|
nuclear@3
|
239
|
nuclear@3
|
240 getActiveResult()->TargetColor = RenderColor;
|
nuclear@3
|
241
|
nuclear@3
|
242 // Record time so we can determine usb roundtrip time.
|
nuclear@3
|
243 getActiveResult()->StartTestTicksMicroS = Timer::GetTicks();
|
nuclear@3
|
244
|
nuclear@3
|
245 Device->SetStartTest(RenderColor);
|
nuclear@3
|
246
|
nuclear@3
|
247 State = State_WaitingForTestStarted;
|
nuclear@3
|
248 OVR_DEBUG_LOG(("State_WaitingToTakeMeasurement -> State_WaitingForTestStarted."));
|
nuclear@3
|
249
|
nuclear@3
|
250 setTimer(TIMEOUT_WAITING_FOR_TEST_STARTED);
|
nuclear@3
|
251
|
nuclear@3
|
252 LatencyTestDisplay ltd(2, 0x40090040);
|
nuclear@3
|
253 Device->SetDisplay(ltd);
|
nuclear@3
|
254 }
|
nuclear@3
|
255 }
|
nuclear@3
|
256 else if (msg.Type == Message_LatencyTestButton)
|
nuclear@3
|
257 {
|
nuclear@3
|
258 BeginTest();
|
nuclear@3
|
259 }
|
nuclear@3
|
260 else if (msg.Type == Message_LatencyTestStarted)
|
nuclear@3
|
261 {
|
nuclear@3
|
262 if (State == State_WaitingForTestStarted)
|
nuclear@3
|
263 {
|
nuclear@3
|
264 clearTimer();
|
nuclear@3
|
265
|
nuclear@3
|
266 // Record time so we can determine usb roundtrip time.
|
nuclear@3
|
267 getActiveResult()->TestStartedTicksMicroS = Timer::GetTicks();
|
nuclear@3
|
268
|
nuclear@3
|
269 State = State_WaitingForColorDetected;
|
nuclear@3
|
270 OVR_DEBUG_LOG(("State_WaitingForTestStarted -> State_WaitingForColorDetected."));
|
nuclear@3
|
271
|
nuclear@3
|
272 setTimer(TIMEOUT_WAITING_FOR_COLOR_DETECTED);
|
nuclear@3
|
273 }
|
nuclear@3
|
274 }
|
nuclear@3
|
275 else if (msg.Type == Message_LatencyTestColorDetected)
|
nuclear@3
|
276 {
|
nuclear@3
|
277 if (State == State_WaitingForColorDetected)
|
nuclear@3
|
278 {
|
nuclear@3
|
279 // Record time to detect color.
|
nuclear@3
|
280 MessageLatencyTestColorDetected* pDetected = (MessageLatencyTestColorDetected*) &msg;
|
nuclear@3
|
281 UInt16 elapsedTime = pDetected->Elapsed;
|
nuclear@3
|
282 OVR_DEBUG_LOG(("Time to 'ColorDetected' = %d", elapsedTime));
|
nuclear@3
|
283
|
nuclear@3
|
284 getActiveResult()->DeviceMeasuredElapsedMilliS = elapsedTime;
|
nuclear@3
|
285
|
nuclear@3
|
286 if (areResultsComplete())
|
nuclear@3
|
287 {
|
nuclear@3
|
288 // We're done.
|
nuclear@3
|
289 processResults();
|
nuclear@3
|
290 reset();
|
nuclear@3
|
291 }
|
nuclear@3
|
292 else
|
nuclear@3
|
293 {
|
nuclear@3
|
294 // Run another measurement.
|
nuclear@3
|
295 State = State_WaitingForSettlePostMeasurement;
|
nuclear@3
|
296 OVR_DEBUG_LOG(("State_WaitingForColorDetected -> State_WaitingForSettlePostMeasurement."));
|
nuclear@3
|
297
|
nuclear@3
|
298 UInt32 waitTime = TIME_TO_WAIT_FOR_SETTLE_POST_MEASUREMENT + getRandomComponent(TIME_TO_WAIT_FOR_SETTLE_POST_MEASUREMENT_RANDOMNESS);
|
nuclear@3
|
299 setTimer(waitTime);
|
nuclear@3
|
300
|
nuclear@3
|
301 LatencyTestDisplay ltd(2, 0x40400040);
|
nuclear@3
|
302 Device->SetDisplay(ltd);
|
nuclear@3
|
303 }
|
nuclear@3
|
304 }
|
nuclear@3
|
305 }
|
nuclear@3
|
306 else if (msg.Type == Message_DeviceRemoved)
|
nuclear@3
|
307 {
|
nuclear@3
|
308 reset();
|
nuclear@3
|
309 }
|
nuclear@3
|
310 }
|
nuclear@3
|
311
|
nuclear@3
|
312 LatencyTest::MeasurementResult* LatencyTest::getActiveResult()
|
nuclear@3
|
313 {
|
nuclear@3
|
314 OVR_ASSERT(!Results.IsEmpty());
|
nuclear@3
|
315 return Results.GetLast();
|
nuclear@3
|
316 }
|
nuclear@3
|
317
|
nuclear@3
|
318 void LatencyTest::setTimer(UInt32 timeMilliS)
|
nuclear@3
|
319 {
|
nuclear@3
|
320 ActiveTimerMilliS = timeMilliS;
|
nuclear@3
|
321 }
|
nuclear@3
|
322
|
nuclear@3
|
323 void LatencyTest::clearTimer()
|
nuclear@3
|
324 {
|
nuclear@3
|
325 ActiveTimerMilliS = 0;
|
nuclear@3
|
326 }
|
nuclear@3
|
327
|
nuclear@3
|
328 void LatencyTest::reset()
|
nuclear@3
|
329 {
|
nuclear@3
|
330 clearMeasurementResults();
|
nuclear@3
|
331 State = State_WaitingForButton;
|
nuclear@3
|
332
|
nuclear@3
|
333 HaveOldTime = false;
|
nuclear@3
|
334 ActiveTimerMilliS = 0;
|
nuclear@3
|
335 }
|
nuclear@3
|
336
|
nuclear@3
|
337 void LatencyTest::clearMeasurementResults()
|
nuclear@3
|
338 {
|
nuclear@3
|
339 while(!Results.IsEmpty())
|
nuclear@3
|
340 {
|
nuclear@3
|
341 MeasurementResult* pElem = Results.GetFirst();
|
nuclear@3
|
342 pElem->RemoveNode();
|
nuclear@3
|
343 delete pElem;
|
nuclear@3
|
344 }
|
nuclear@3
|
345 }
|
nuclear@3
|
346
|
nuclear@3
|
347 LatencyTest::LatencyTestHandler::~LatencyTestHandler()
|
nuclear@3
|
348 {
|
nuclear@3
|
349 RemoveHandlerFromDevices();
|
nuclear@3
|
350 }
|
nuclear@3
|
351
|
nuclear@3
|
352 void LatencyTest::LatencyTestHandler::OnMessage(const Message& msg)
|
nuclear@3
|
353 {
|
nuclear@3
|
354 pLatencyTestUtil->handleMessage(msg);
|
nuclear@3
|
355 }
|
nuclear@3
|
356
|
nuclear@3
|
357 void LatencyTest::ProcessInputs()
|
nuclear@3
|
358 {
|
nuclear@3
|
359 updateForTimeouts();
|
nuclear@3
|
360 handleMessage(Message(), LatencyTest_ProcessInputs);
|
nuclear@3
|
361 }
|
nuclear@3
|
362
|
nuclear@3
|
363 bool LatencyTest::DisplayScreenColor(Color& colorToDisplay)
|
nuclear@3
|
364 {
|
nuclear@3
|
365 updateForTimeouts();
|
nuclear@3
|
366
|
nuclear@3
|
367 if (State == State_WaitingForButton)
|
nuclear@3
|
368 {
|
nuclear@3
|
369 return false;
|
nuclear@3
|
370 }
|
nuclear@3
|
371
|
nuclear@3
|
372 colorToDisplay = RenderColor;
|
nuclear@3
|
373 return true;
|
nuclear@3
|
374 }
|
nuclear@3
|
375
|
nuclear@3
|
376 const char* LatencyTest::GetResultsString()
|
nuclear@3
|
377 {
|
nuclear@3
|
378 if (!ResultsString.IsEmpty() && ReturnedResultString != ResultsString.ToCStr())
|
nuclear@3
|
379 {
|
nuclear@3
|
380 ReturnedResultString = ResultsString;
|
nuclear@3
|
381 return ReturnedResultString.ToCStr();
|
nuclear@3
|
382 }
|
nuclear@3
|
383
|
nuclear@3
|
384 return NULL;
|
nuclear@3
|
385 }
|
nuclear@3
|
386
|
nuclear@3
|
387 bool LatencyTest::areResultsComplete()
|
nuclear@3
|
388 {
|
nuclear@3
|
389 UInt32 initialMeasurements = 0;
|
nuclear@3
|
390
|
nuclear@3
|
391 UInt32 measurements1to2 = 0;
|
nuclear@3
|
392 UInt32 measurements2to1 = 0;
|
nuclear@3
|
393
|
nuclear@3
|
394 MeasurementResult* pCurr = Results.GetFirst();
|
nuclear@3
|
395 while(true)
|
nuclear@3
|
396 {
|
nuclear@3
|
397 // Process.
|
nuclear@3
|
398 if (!pCurr->TimedOutWaitingForTestStarted &&
|
nuclear@3
|
399 !pCurr->TimedOutWaitingForColorDetected)
|
nuclear@3
|
400 {
|
nuclear@3
|
401 initialMeasurements++;
|
nuclear@3
|
402
|
nuclear@3
|
403 if (initialMeasurements > INITIAL_SAMPLES_TO_IGNORE)
|
nuclear@3
|
404 {
|
nuclear@3
|
405 if (pCurr->TargetColor == COLOR2)
|
nuclear@3
|
406 {
|
nuclear@3
|
407 measurements1to2++;
|
nuclear@3
|
408 }
|
nuclear@3
|
409 else
|
nuclear@3
|
410 {
|
nuclear@3
|
411 measurements2to1++;
|
nuclear@3
|
412 }
|
nuclear@3
|
413 }
|
nuclear@3
|
414 }
|
nuclear@3
|
415
|
nuclear@3
|
416 if (Results.IsLast(pCurr))
|
nuclear@3
|
417 {
|
nuclear@3
|
418 break;
|
nuclear@3
|
419 }
|
nuclear@3
|
420 pCurr = Results.GetNext(pCurr);
|
nuclear@3
|
421 }
|
nuclear@3
|
422
|
nuclear@3
|
423 if (measurements1to2 >= DEFAULT_NUMBER_OF_SAMPLES &&
|
nuclear@3
|
424 measurements2to1 >= DEFAULT_NUMBER_OF_SAMPLES)
|
nuclear@3
|
425 {
|
nuclear@3
|
426 return true;
|
nuclear@3
|
427 }
|
nuclear@3
|
428
|
nuclear@3
|
429 return false;
|
nuclear@3
|
430 }
|
nuclear@3
|
431
|
nuclear@3
|
432 void LatencyTest::processResults()
|
nuclear@3
|
433 {
|
nuclear@3
|
434
|
nuclear@3
|
435 UInt32 minTime1To2 = UINT_MAX;
|
nuclear@3
|
436 UInt32 maxTime1To2 = 0;
|
nuclear@3
|
437 float averageTime1To2 = 0.0f;
|
nuclear@3
|
438 UInt32 minTime2To1 = UINT_MAX;
|
nuclear@3
|
439 UInt32 maxTime2To1 = 0;
|
nuclear@3
|
440 float averageTime2To1 = 0.0f;
|
nuclear@3
|
441
|
nuclear@3
|
442 float minUSBTripMilliS = BIG_FLOAT;
|
nuclear@3
|
443 float maxUSBTripMilliS = SMALL_FLOAT;
|
nuclear@3
|
444 float averageUSBTripMilliS = 0.0f;
|
nuclear@3
|
445 UInt32 countUSBTripTime = 0;
|
nuclear@3
|
446
|
nuclear@3
|
447 UInt32 measurementsCount = 0;
|
nuclear@3
|
448 UInt32 measurements1to2 = 0;
|
nuclear@3
|
449 UInt32 measurements2to1 = 0;
|
nuclear@3
|
450
|
nuclear@3
|
451 MeasurementResult* pCurr = Results.GetFirst();
|
nuclear@3
|
452 UInt32 count = 0;
|
nuclear@3
|
453 while(true)
|
nuclear@3
|
454 {
|
nuclear@3
|
455 count++;
|
nuclear@3
|
456
|
nuclear@3
|
457 if (!pCurr->TimedOutWaitingForTestStarted &&
|
nuclear@3
|
458 !pCurr->TimedOutWaitingForColorDetected)
|
nuclear@3
|
459 {
|
nuclear@3
|
460 measurementsCount++;
|
nuclear@3
|
461
|
nuclear@3
|
462 if (measurementsCount > INITIAL_SAMPLES_TO_IGNORE)
|
nuclear@3
|
463 {
|
nuclear@3
|
464 if (pCurr->TargetColor == COLOR2)
|
nuclear@3
|
465 {
|
nuclear@3
|
466 measurements1to2++;
|
nuclear@3
|
467
|
nuclear@3
|
468 if (measurements1to2 <= DEFAULT_NUMBER_OF_SAMPLES)
|
nuclear@3
|
469 {
|
nuclear@3
|
470 UInt32 elapsed = pCurr->DeviceMeasuredElapsedMilliS;
|
nuclear@3
|
471
|
nuclear@3
|
472 minTime1To2 = Alg::Min(elapsed, minTime1To2);
|
nuclear@3
|
473 maxTime1To2 = Alg::Max(elapsed, maxTime1To2);
|
nuclear@3
|
474
|
nuclear@3
|
475 averageTime1To2 += (float) elapsed;
|
nuclear@3
|
476 }
|
nuclear@3
|
477 }
|
nuclear@3
|
478 else
|
nuclear@3
|
479 {
|
nuclear@3
|
480 measurements2to1++;
|
nuclear@3
|
481
|
nuclear@3
|
482 if (measurements2to1 <= DEFAULT_NUMBER_OF_SAMPLES)
|
nuclear@3
|
483 {
|
nuclear@3
|
484 UInt32 elapsed = pCurr->DeviceMeasuredElapsedMilliS;
|
nuclear@3
|
485
|
nuclear@3
|
486 minTime2To1 = Alg::Min(elapsed, minTime2To1);
|
nuclear@3
|
487 maxTime2To1 = Alg::Max(elapsed, maxTime2To1);
|
nuclear@3
|
488
|
nuclear@3
|
489 averageTime2To1 += (float) elapsed;
|
nuclear@3
|
490 }
|
nuclear@3
|
491 }
|
nuclear@3
|
492
|
nuclear@3
|
493 float usbRountripElapsedMilliS = 0.001f * (float) (pCurr->TestStartedTicksMicroS - pCurr->StartTestTicksMicroS);
|
nuclear@3
|
494 minUSBTripMilliS = Alg::Min(usbRountripElapsedMilliS, minUSBTripMilliS);
|
nuclear@3
|
495 maxUSBTripMilliS = Alg::Max(usbRountripElapsedMilliS, maxUSBTripMilliS);
|
nuclear@3
|
496 averageUSBTripMilliS += usbRountripElapsedMilliS;
|
nuclear@3
|
497 countUSBTripTime++;
|
nuclear@3
|
498 }
|
nuclear@3
|
499 }
|
nuclear@3
|
500
|
nuclear@3
|
501 if (measurements1to2 >= DEFAULT_NUMBER_OF_SAMPLES &&
|
nuclear@3
|
502 measurements2to1 >= DEFAULT_NUMBER_OF_SAMPLES)
|
nuclear@3
|
503 {
|
nuclear@3
|
504 break;
|
nuclear@3
|
505 }
|
nuclear@3
|
506
|
nuclear@3
|
507 if (Results.IsLast(pCurr))
|
nuclear@3
|
508 {
|
nuclear@3
|
509 break;
|
nuclear@3
|
510 }
|
nuclear@3
|
511 pCurr = Results.GetNext(pCurr);
|
nuclear@3
|
512 }
|
nuclear@3
|
513
|
nuclear@3
|
514 averageTime1To2 /= (float) DEFAULT_NUMBER_OF_SAMPLES;
|
nuclear@3
|
515 averageTime2To1 /= (float) DEFAULT_NUMBER_OF_SAMPLES;
|
nuclear@3
|
516
|
nuclear@3
|
517 averageUSBTripMilliS /= countUSBTripTime;
|
nuclear@3
|
518
|
nuclear@3
|
519 float finalResult = 0.5f * (averageTime1To2 + averageTime2To1);
|
nuclear@3
|
520 finalResult += averageUSBTripMilliS;
|
nuclear@3
|
521
|
nuclear@3
|
522 ResultsString.Clear();
|
nuclear@3
|
523 ResultsString.AppendFormat("RESULT=%.1f (add half Tracker period) [b->w %d|%.1f|%d] [w->b %d|%.1f|%d] [usb rndtrp %.1f|%.1f|%.1f] [cnt %d] [tmouts %d]",
|
nuclear@3
|
524 finalResult,
|
nuclear@3
|
525 minTime1To2, averageTime1To2, maxTime1To2,
|
nuclear@3
|
526 minTime2To1, averageTime2To1, maxTime2To1,
|
nuclear@3
|
527 minUSBTripMilliS, averageUSBTripMilliS, maxUSBTripMilliS,
|
nuclear@3
|
528 DEFAULT_NUMBER_OF_SAMPLES*2, count - measurementsCount);
|
nuclear@3
|
529
|
nuclear@3
|
530 // Display result on latency tester display.
|
nuclear@3
|
531 LatencyTestDisplay ltd(1, (int)finalResult);
|
nuclear@3
|
532 Device->SetDisplay(ltd);
|
nuclear@3
|
533 }
|
nuclear@3
|
534
|
nuclear@3
|
535 void LatencyTest::updateForTimeouts()
|
nuclear@3
|
536 {
|
nuclear@3
|
537 if (!HaveOldTime)
|
nuclear@3
|
538 {
|
nuclear@3
|
539 HaveOldTime = true;
|
nuclear@3
|
540 OldTime = Timer::GetTicksMs();
|
nuclear@3
|
541 return;
|
nuclear@3
|
542 }
|
nuclear@3
|
543
|
nuclear@3
|
544 UInt32 newTime = Timer::GetTicksMs();
|
nuclear@3
|
545 UInt32 elapsedMilliS = newTime - OldTime;
|
nuclear@3
|
546 if (newTime < OldTime)
|
nuclear@3
|
547 {
|
nuclear@3
|
548 elapsedMilliS = OldTime - newTime;
|
nuclear@3
|
549 elapsedMilliS = UINT_MAX - elapsedMilliS;
|
nuclear@3
|
550 }
|
nuclear@3
|
551 OldTime = newTime;
|
nuclear@3
|
552
|
nuclear@3
|
553 elapsedMilliS = Alg::Min(elapsedMilliS, (UInt32) 100); // Clamp at 100mS in case we're not being called very often.
|
nuclear@3
|
554
|
nuclear@3
|
555
|
nuclear@3
|
556 if (ActiveTimerMilliS == 0)
|
nuclear@3
|
557 {
|
nuclear@3
|
558 return;
|
nuclear@3
|
559 }
|
nuclear@3
|
560
|
nuclear@3
|
561 if (elapsedMilliS >= ActiveTimerMilliS)
|
nuclear@3
|
562 {
|
nuclear@3
|
563 ActiveTimerMilliS = 0;
|
nuclear@3
|
564 handleMessage(Message(), LatencyTest_Timer);
|
nuclear@3
|
565 return;
|
nuclear@3
|
566 }
|
nuclear@3
|
567
|
nuclear@3
|
568 ActiveTimerMilliS -= elapsedMilliS;
|
nuclear@3
|
569 }
|
nuclear@3
|
570
|
nuclear@3
|
571 }} // namespace OVR::Util
|