Bike-X  0.8
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
OVR_Sensor2Impl.cpp
Go to the documentation of this file.
1 /************************************************************************************
2 
3 Filename : OVR_Sensor2Impl.cpp
4 Content : DK2 sensor device specific implementation.
5 Created : January 21, 2013
6 Authors : Lee Cooper
7 
8 Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
9 
10 Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License");
11 you may not use the Oculus VR Rift SDK except in compliance with the License,
12 which is provided at the time of installation or download, or which
13 otherwise accompanies this software in either electronic or hard copy form.
14 
15 You may obtain a copy of the License at
16 
17 http://www.oculusvr.com/licenses/LICENSE-3.1
18 
19 Unless required by applicable law or agreed to in writing, the Oculus VR SDK
20 distributed under the License is distributed on an "AS IS" BASIS,
21 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 See the License for the specific language governing permissions and
23 limitations under the License.
24 
25 *************************************************************************************/
26 
27 #include "OVR_Sensor2Impl.h"
28 #include "OVR_SensorImpl_Common.h"
29 #include "OVR_Sensor2ImplUtil.h"
30 #include "Kernel/OVR_Alg.h"
31 
32 //extern FILE *SF_LOG_fp;
33 
34 namespace OVR {
35 
36 //-------------------------------------------------------------------------------------
37 // ***** Oculus Sensor2-specific packet data structures
38 
39 enum {
42 
44 
46 };
47 
48 
49 // Messages we care for
51 {
56 };
57 
58 
60 {
63  UInt16 RunningSampleCount; // Named 'SampleCount' in the firmware docs.
72  UInt16 CameraFrameCount; // Named 'CameraCount' in the firmware docs.
74 
75  Tracker2MessageType Decode(const UByte* buffer, int size)
76  {
77  if (size < 64)
79 
80  LastCommandID = DecodeUInt16(buffer + 1);
81  NumSamples = buffer[3];
82  RunningSampleCount = DecodeUInt16(buffer + 4);
83  Temperature = DecodeSInt16(buffer + 6);
84  SampleTimestamp = DecodeUInt32(buffer + 8);
85 
86  // Only unpack as many samples as there actually are.
87  UByte iterationCount = (NumSamples > 1) ? 2 : NumSamples;
88 
89  for (UByte i = 0; i < iterationCount; i++)
90  {
91  UnpackSensor(buffer + 12 + 16 * i, &Samples[i].AccelX, &Samples[i].AccelY, &Samples[i].AccelZ);
92  UnpackSensor(buffer + 20 + 16 * i, &Samples[i].GyroX, &Samples[i].GyroY, &Samples[i].GyroZ);
93  }
94 
95  MagX = DecodeSInt16(buffer + 44);
96  MagY = DecodeSInt16(buffer + 46);
97  MagZ = DecodeSInt16(buffer + 48);
98 
99  FrameCount = DecodeUInt16(buffer + 50);
100 
101  FrameTimestamp = DecodeUInt32(buffer + 52);
102  FrameID = buffer[56];
103  CameraPattern = buffer[57];
104  CameraFrameCount = DecodeUInt16(buffer + 58);
105  CameraTimestamp = DecodeUInt32(buffer + 60);
106 
108  }
109 };
110 
112 {
115 };
116 
117 // Sensor reports data in the following coordinate system:
118 // Accelerometer: 10^-4 m/s^2; X forward, Y right, Z Down.
119 // Gyro: 10^-4 rad/s; X positive roll right, Y positive pitch up; Z positive yaw right.
120 
121 
122 // We need to convert it to the following RHS coordinate system:
123 // X right, Y Up, Z Back (out of screen)
124 //
126 {
127  const TrackerSample& sample = update.Samples[sampleNumber];
128  float ax = (float)sample.AccelX;
129  float ay = (float)sample.AccelY;
130  float az = (float)sample.AccelZ;
131 
132  return Vector3f(ax, ay, az) * 0.0001f;
133 }
134 
135 
137 {
138  return Vector3f( (float)update.MagX, (float)update.MagY, (float)update.MagZ) * 0.0001f;
139 }
140 
142 {
143  const TrackerSample& sample = update.Samples[sampleNumber];
144  float gx = (float)sample.GyroX;
145  float gy = (float)sample.GyroY;
146  float gz = (float)sample.GyroZ;
147 
148  return Vector3f(gx, gy, gz) * 0.0001f;
149 }
150 
152 {
153  memset(message, 0, sizeof(Tracker2Message));
154 
155  if (size < 4)
156  {
157  message->Type = Tracker2Message_SizeError;
158  return false;
159  }
160 
161  switch (buffer[0])
162  {
164  message->Type = message->Sensors.Decode(buffer, size);
165  break;
166 
167  default:
168  message->Type = Tracker2Message_Unknown;
169  break;
170  }
171 
172  return (message->Type < Tracker2Message_Unknown) && (message->Type != Tracker2Message_None);
173 }
174 
175 //-------------------------------------------------------------------------------------
176 // ***** Sensor2Device
177 
179  : SensorDeviceImpl(createDesc),
180  LastNumSamples(0),
181  LastRunningSampleCount(0),
182  FullCameraFrameCount(0),
183  LastCameraTime("C"),
184  LastFrameTime("F"),
185  LastSensorTime("S"),
186  LastFrameTimestamp(0)
187 {
188  // 15 samples ok in min-window for DK2 since it uses microsecond clock.
190 
191  pCalibration = new SensorCalibration(this);
192 }
193 
195 {
196  delete pCalibration;
197 }
198 
200 {
201 
202  // Read the currently configured range from sensor.
203  SensorRangeImpl sr(SensorRange(), 0);
204 
206  {
207  sr.Unpack();
209  }
210 
211  // Read the currently configured calibration from sensor.
214  {
215  sc.Unpack();
221  }
222 
223  // If the sensor has "DisplayInfo" data, use HMD coordinate frame by default.
224  SensorDisplayInfoImpl displayInfo;
226  {
227  displayInfo.Unpack();
230  }
231  Coordinates = Coord_HMD; // TODO temporary to force it behave
232 
233  // Read/Apply sensor config.
237 
238  // Must send DK2 keep-alive. Set Keep-alive at 10 seconds.
239  KeepAliveMuxReport keepAlive;
240  keepAlive.CommandId = 0;
241  keepAlive.INReport = 11;
242  keepAlive.Interval = 10 * 1000;
243 
244  // Device creation is done from background thread so we don't need to add this to the command queue.
245  KeepAliveMuxImpl keepAliveImpl(keepAlive);
247 
248  // Read the temperature data from the device
250 }
251 
253 {
254  bool result;
255  if (!GetManagerImpl()->GetThreadQueue()->
256  PushCallAndWaitResult(this, &Sensor2DeviceImpl::setTrackingReport, &result, data))
257  {
258  return false;
259  }
260 
261  return result;
262 }
263 
265 {
266  TrackingImpl ci(data);
268 }
269 
271 {
272  bool result;
273  if (!GetManagerImpl()->GetThreadQueue()->
274  PushCallAndWaitResult(this, &Sensor2DeviceImpl::getTrackingReport, &result, data))
275  {
276  return false;
277  }
278 
279  return result;
280 }
281 
283 {
284  TrackingImpl ci;
286  {
287  ci.Unpack();
288  *data = ci.Settings;
289  return true;
290  }
291 
292  return false;
293 }
294 
296 {
297  bool result;
298  if (!GetManagerImpl()->GetThreadQueue()->
299  PushCallAndWaitResult(this, &Sensor2DeviceImpl::setDisplayReport, &result, data))
300  {
301  return false;
302  }
303 
304  return result;
305 }
306 
308 {
309  DisplayImpl di(data);
311 }
312 
314 {
315  bool result;
316  if (!GetManagerImpl()->GetThreadQueue()->
317  PushCallAndWaitResult(this, &Sensor2DeviceImpl::getDisplayReport, &result, data))
318  {
319  return false;
320  }
321 
322  return result;
323 }
324 
326 {
327  DisplayImpl di;
329  {
330  di.Unpack();
331  *data = di.Settings;
332  return true;
333  }
334 
335  return false;
336 }
337 
339 {
340  bool result;
341  if (!GetManagerImpl()->GetThreadQueue()->
342  PushCallAndWaitResult(this, &Sensor2DeviceImpl::setMagCalibrationReport, &result, data))
343  {
344  return false;
345  }
346 
347  return result;
348 }
349 
351 {
352  MagCalibrationImpl mci(data);
354 }
355 
357 {
358  // direct call if we are already on the device manager thread
359  if (GetCurrentThreadId() == GetManagerImpl()->GetThreadId())
360  {
361  return getMagCalibrationReport(data);
362  }
363 
364  bool result;
365  if (!GetManagerImpl()->GetThreadQueue()->
366  PushCallAndWaitResult(this, &Sensor2DeviceImpl::getMagCalibrationReport, &result, data))
367  {
368  return false;
369  }
370 
371  return result;
372 }
373 
375 {
376  MagCalibrationImpl mci;
378  {
379  mci.Unpack();
380  *data = mci.Settings;
381  return true;
382  }
383 
384  return false;
385 }
386 
388 {
389  bool result;
390  if (!GetManagerImpl()->GetThreadQueue()->
391  PushCallAndWaitResult(this, &Sensor2DeviceImpl::setPositionCalibrationReport, &result, data))
392  {
393  return false;
394  }
395 
396  return result;
397 }
398 
400 {
401  UByte version = GetDeviceInterfaceVersion();
402  if (version < 5)
403  {
406  }
407 
408  PositionCalibrationImpl pci(data);
410 }
411 
413 {
414  UByte version = GetDeviceInterfaceVersion();
415  if (version < 5)
416  {
419  {
420  pci.Unpack();
421  *data = pci.Settings;
422  return true;
423  }
424 
425  return false;
426  }
427 
430  {
431  pci.Unpack();
432  *data = pci.Settings;
433  return true;
434  }
435 
436  return false;
437 }
438 
440 {
441  bool result;
442  if (!GetManagerImpl()->GetThreadQueue()->
443  PushCallAndWaitResult(this, &Sensor2DeviceImpl::getAllPositionCalibrationReports, &result, data))
444  {
445  return false;
446  }
447 
448  return result;
449 }
450 
452 {
454  bool result = getPositionCalibrationReport(&pc);
455  if (!result)
456  return false;
457 
458  int positions = pc.NumPositions;
459  data->Clear();
460  data->Resize(positions);
461 
462  for (int i = 0; i < positions; i++)
463  {
464  result = getPositionCalibrationReport(&pc);
465  if (!result)
466  return false;
467  OVR_ASSERT(pc.NumPositions == positions);
468 
469  (*data)[pc.PositionIndex] = pc;
470  // IMU should be the last one
471  OVR_ASSERT(pc.PositionType == (pc.PositionIndex == positions - 1) ?
473  }
474  return true;
475 }
476 
478 {
479  bool result;
480  if (!GetManagerImpl()->GetThreadQueue()->
481  PushCallAndWaitResult(this, &Sensor2DeviceImpl::setCustomPatternReport, &result, data))
482  {
483  return false;
484  }
485 
486  return result;
487 }
488 
490 {
491  CustomPatternImpl cpi(data);
493 }
494 
496 {
497  bool result;
498  if (!GetManagerImpl()->GetThreadQueue()->
499  PushCallAndWaitResult(this, &Sensor2DeviceImpl::getCustomPatternReport, &result, data))
500  {
501  return false;
502  }
503 
504  return result;
505 }
506 
508 {
509  CustomPatternImpl cpi;
511  {
512  cpi.Unpack();
513  *data = cpi.Settings;
514  return true;
515  }
516 
517  return false;
518 }
519 
521 {
522  bool result;
523  if (!GetManagerImpl()->GetThreadQueue()->
524  PushCallAndWaitResult(this, &Sensor2DeviceImpl::setManufacturingReport, &result, data))
525  {
526  return false;
527  }
528 
529  return result;
530 }
531 
533 {
534  ManufacturingImpl mi(data);
536 }
537 
539 {
540  bool result;
541  if (!GetManagerImpl()->GetThreadQueue()->
542  PushCallAndWaitResult(this, &Sensor2DeviceImpl::getManufacturingReport, &result, data))
543  {
544  return false;
545  }
546 
547  return result;
548 }
549 
551 {
554  {
555  mi.Unpack();
556  *data = mi.Settings;
557  return true;
558  }
559 
560  return false;
561 }
562 
564 {
565  bool result;
566  if (!GetManagerImpl()->GetThreadQueue()->
567  PushCallAndWaitResult(this, &Sensor2DeviceImpl::setLensDistortionReport, &result, data))
568  {
569  return false;
570  }
571 
572  return result;
573 }
574 
576 {
577  LensDistortionImpl ui(data);
579 }
580 
582 {
583  bool result;
584  if (!GetManagerImpl()->GetThreadQueue()->
585  PushCallAndWaitResult(this, &Sensor2DeviceImpl::getLensDistortionReport, &result, data))
586  {
587  return false;
588  }
589 
590  return result;
591 }
592 
594 {
597  {
598  ui.Unpack();
599  *data = ui.Settings;
600  return true;
601  }
602 
603  return false;
604 }
605 
607 {
608  bool result;
609  if (!GetManagerImpl()->GetThreadQueue()->
610  PushCallAndWaitResult(this, &Sensor2DeviceImpl::setUUIDReport, &result, data))
611  {
612  return false;
613  }
614 
615  return result;
616 }
617 
619 {
620  UUIDImpl ui(data);
622 }
623 
625 {
626  bool result;
627  if (!GetManagerImpl()->GetThreadQueue()->
628  PushCallAndWaitResult(this, &Sensor2DeviceImpl::getUUIDReport, &result, data))
629  {
630  return false;
631  }
632 
633  return result;
634 }
635 
637 {
638  UUIDImpl ui;
640  {
641  ui.Unpack();
642  *data = ui.Settings;
643  return true;
644  }
645 
646  return false;
647 }
648 
650 {
651  bool result;
652  if (!GetManagerImpl()->GetThreadQueue()->
653  PushCallAndWaitResult(this, &Sensor2DeviceImpl::setKeepAliveMuxReport, &result, data))
654  {
655  return false;
656  }
657 
658  return result;
659 }
660 
662 {
663  KeepAliveMuxImpl kami(data);
665 }
666 
668 {
669  bool result;
670  if (!GetManagerImpl()->GetThreadQueue()->
671  PushCallAndWaitResult(this, &Sensor2DeviceImpl::getKeepAliveMuxReport, &result, data))
672  {
673  return false;
674  }
675 
676  return result;
677 }
678 
680 {
681  KeepAliveMuxImpl kami;
683  {
684  kami.Unpack();
685  *data = kami.Settings;
686  return true;
687  }
688 
689  return false;
690 }
691 
693 {
694  // direct call if we are already on the device manager thread
695  if (GetCurrentThreadId() == GetManagerImpl()->GetThreadId())
696  {
697  return setTemperatureReport(data);
698  }
699 
700  bool result;
701  if (!GetManagerImpl()->GetThreadQueue()->
702  PushCallAndWaitResult(this, &Sensor2DeviceImpl::setTemperatureReport, &result, data))
703  {
704  return false;
705  }
706 
707  return result;
708 }
709 
711 {
712  TemperatureImpl ti(data);
714 }
715 
717 {
718  TemperatureImpl ti;
720  {
721  ti.Unpack();
722  *data = ti.Settings;
723  return true;
724  }
725 
726  return false;
727 }
728 
730 {
731  // direct call if we are already on the device manager thread
732  if (GetCurrentThreadId() == GetManagerImpl()->GetThreadId())
733  {
734  return getAllTemperatureReports(data);
735  }
736 
737  bool result;
738  if (!GetManagerImpl()->GetThreadQueue()->
739  PushCallAndWaitResult(this, &Sensor2DeviceImpl::getAllTemperatureReports, &result, data))
740  {
741  return false;
742  }
743 
744  return result;
745 }
746 
748 {
750  bool result = getTemperatureReport(&t);
751  if (!result)
752  return false;
753 
754  int bins = t.NumBins, samples = t.NumSamples;
755  data->Clear();
756  data->Resize(bins);
757  for (int i = 0; i < bins; i++)
758  (*data)[i].Resize(samples);
759 
760  for (int i = 0; i < bins; i++)
761  for (int j = 0; j < samples; j++)
762  {
763  result = getTemperatureReport(&t);
764  if (!result)
765  return false;
766  OVR_ASSERT(t.NumBins == bins && t.NumSamples == samples);
767 
768  (*data)[t.Bin][t.Sample] = t;
769  }
770  return true;
771 }
772 
774 {
775  // direct call if we are already on the device manager thread
776  if (GetCurrentThreadId() == GetManagerImpl()->GetThreadId())
777  {
778  return getGyroOffsetReport(data);
779  }
780 
781  bool result;
782  if (!GetManagerImpl()->GetThreadQueue()->
783  PushCallAndWaitResult(this, &Sensor2DeviceImpl::getGyroOffsetReport, &result, data))
784  {
785  return false;
786  }
787 
788  return result;
789 }
790 
792 {
793  GyroOffsetImpl goi;
795  {
796  goi.Unpack();
797  *data = goi.Settings;
798  return true;
799  }
800 
801  return false;
802 }
803 
805 {
806  if (message->Type != Tracker2Message_Sensors)
807  return;
808 
809  const float sampleIntervalTimeUnit = (1.0f / 1000.f);
810  double scaledSampleIntervalTimeUnit = sampleIntervalTimeUnit;
811  Tracker2Sensors& s = message->Sensors;
812 
813  double absoluteTimeSeconds = 0.0;
814 
815  if (SequenceValid)
816  {
817  UInt32 runningSampleCountDelta;
818 
820  {
821  // The running sample count on the device rolled around the 16 bit counter
822  // (expect to happen about once per minute), so RunningSampleCount
823  // needs a high word increment.
824  runningSampleCountDelta = ((((int)s.RunningSampleCount) + 0x10000) - (int)LastRunningSampleCount);
825  }
826  else
827  {
828  runningSampleCountDelta = (s.RunningSampleCount - LastRunningSampleCount);
829  }
830 
831  absoluteTimeSeconds = LastSensorTime.TimeSeconds;
832  scaledSampleIntervalTimeUnit = TimeFilter.ScaleTimeUnit(sampleIntervalTimeUnit);
833 
834  // If we missed a small number of samples, replicate the last sample.
835  if ((runningSampleCountDelta > LastNumSamples) && (runningSampleCountDelta <= 254))
836  {
837  if (HandlerRef.HasHandlers())
838  {
839  MessageBodyFrame sensors(this);
840 
841  sensors.AbsoluteTimeSeconds = absoluteTimeSeconds - s.NumSamples * scaledSampleIntervalTimeUnit;
842  sensors.TimeDelta = (float) ((runningSampleCountDelta - LastNumSamples) * scaledSampleIntervalTimeUnit);
843  sensors.Acceleration = LastAcceleration;
844  sensors.RotationRate = LastRotationRate;
846  sensors.Temperature = LastTemperature;
847 
848  pCalibration->Apply(sensors);
849  HandlerRef.Call(sensors);
850  }
851  }
852  }
853  else
854  {
858  LastTemperature = 0;
859  SequenceValid = true;
860  }
861 
864 
865  if (HandlerRef.HasHandlers())
866  {
867  MessageBodyFrame sensors(this);
868  UByte iterations = s.NumSamples;
869 
870  if (s.NumSamples > 2)
871  {
872  iterations = 2;
873  sensors.TimeDelta = (float) ((s.NumSamples - 1) * scaledSampleIntervalTimeUnit);
874  }
875  else
876  {
877  sensors.TimeDelta = (float) scaledSampleIntervalTimeUnit;
878  }
879 
880  for (UByte i = 0; i < iterations; i++)
881  {
882  sensors.AbsoluteTimeSeconds = absoluteTimeSeconds - ( iterations - 1 - i ) * scaledSampleIntervalTimeUnit;
883  sensors.Acceleration = AccelFromBodyFrameUpdate(s, i);
884  sensors.RotationRate = EulerFromBodyFrameUpdate(s, i);
886  sensors.Temperature = s.Temperature * 0.01f;
887 
888  pCalibration->Apply(sensors);
889  HandlerRef.Call(sensors);
890 
891  // TimeDelta for the last two sample is always fixed.
892  sensors.TimeDelta = (float) scaledSampleIntervalTimeUnit;
893  }
894 
895  // Send pixel read only when frame timestamp changes.
897  {
898  MessagePixelRead pixelRead(this);
899  // Prepare message for pixel read
900  pixelRead.PixelReadValue = s.FrameID;
901  pixelRead.RawFrameTime = s.FrameTimestamp;
902  pixelRead.RawSensorTime = s.SampleTimestamp;
905 
906  HandlerRef.Call(pixelRead);
908  }
909 
910  UInt16 lowFrameCount = (UInt16) FullCameraFrameCount;
911  // Send message only when frame counter changes
912  if (lowFrameCount != s.CameraFrameCount)
913  {
914  // check for the rollover in the counter
915  if (s.CameraFrameCount < lowFrameCount)
916  FullCameraFrameCount += 0x10000;
917  // update the low bits
919 
920  MessageExposureFrame vision(this);
921  vision.CameraPattern = s.CameraPattern;
922  vision.CameraFrameCount = FullCameraFrameCount;
923  vision.CameraTimeSeconds = LastCameraTime.TimeSeconds;
924 
925  HandlerRef.Call(vision);
926  }
927 
928  LastAcceleration = sensors.Acceleration;
929  LastRotationRate = sensors.RotationRate;
931  LastTemperature = sensors.Temperature;
932 
933  //LastPixelRead = pixelRead.PixelReadValue;
934  //LastPixelReadTimeStamp = LastFrameTime;
935  }
936  else
937  {
938  if (s.NumSamples != 0)
939  {
940  UByte i = (s.NumSamples > 1) ? 1 : 0;
944  LastTemperature = s.Temperature * 0.01f;
945  }
946  }
947 }
948 
949 // Helper function to handle wrap-around of timestamps from Tracker2Message and convert them
950 // to system time.
951 // - Any timestamps that didn't increment keep their old system time.
952 // - This is a bit tricky since we don't know which one of timestamps has most recent time.
953 // - The first timestamp must be the IMU one; we assume that others can't be too much ahead of it
954 
956  SensorTimestampMapping** timestamps, UInt32 *rawValues, int count)
957 {
958  int updateIndices[4];
959  int updateCount = 0;
960  int i;
961  double now = Timer::GetSeconds();
962 
963  OVR_ASSERT(count <= sizeof(updateIndices)/sizeof(int));
964 
965  // Update timestamp wrapping for any values that changed.
966  for (i = 0; i < count; i++)
967  {
968  UInt32 lowMks = (UInt32)timestamps[i]->TimestampMks; // Low 32-bits are raw old timestamp.
969 
970  if (rawValues[i] != lowMks)
971  {
972  if (i == 0)
973  {
974  // Only check for rollover in the IMU timestamp
975  if (rawValues[i] < lowMks)
976  {
977  LogText("Timestamp %d rollover, was: %u, now: %u\n", i, lowMks, rawValues[i]);
978  timestamps[i]->TimestampMks += 0x100000000;
979  }
980  // Update the low bits
981  timestamps[i]->TimestampMks = (timestamps[i]->TimestampMks & 0xFFFFFFFF00000000) | rawValues[i];
982  }
983  else
984  {
985  // Take the high bits from the main timestamp first (not a typo in the first argument!)
986  timestamps[i]->TimestampMks =
987  (timestamps[0]->TimestampMks & 0xFFFFFFFF00000000) | rawValues[i];
988  // Now force it into the reasonable range around the expanded main timestamp
989  if (timestamps[i]->TimestampMks > timestamps[0]->TimestampMks + 0x1000000)
990  timestamps[i]->TimestampMks -= 0x100000000;
991  else if (timestamps[i]->TimestampMks + 0x100000000 < timestamps[0]->TimestampMks + 0x1000000)
992  timestamps[i]->TimestampMks += 0x100000000;
993  }
994 
995  updateIndices[updateCount] = i;
996  updateCount++;
997  }
998  }
999 
1000 
1001  // TBD: Simplify. Update indices should no longer be needed with new TimeFilter accepting
1002  // previous values.
1003  // We might want to have multi-element checking time roll-over.
1004 
1005  static const double mksToSec = 1.0 / 1000000.0;
1006 
1007  for (int i = 0; i < updateCount; i++)
1008  {
1009  SensorTimestampMapping& ts = *timestamps[updateIndices[i]];
1010 
1011  ts.TimeSeconds = tf.SampleToSystemTime(((double)ts.TimestampMks) * mksToSec,
1012  now, ts.TimeSeconds, ts.DebugTag);
1013  }
1014 }
1015 
1016 
1018 {
1019  bool processed = false;
1020  if (!processed)
1021  {
1022  Tracker2Message message;
1023  if (decodeTracker2Message(&message, pData, length))
1024  {
1025  processed = true;
1026 
1027  // Process microsecond timestamps from DK2 tracker.
1028  // Mapped and raw values must correspond to one another in each array.
1029  // IMU timestamp must be the first one!
1030  SensorTimestampMapping* tsMaps[3] =
1031  {
1032  &LastSensorTime,
1033  &LastCameraTime,
1034  &LastFrameTime
1035  };
1036  UInt32 tsRawMks[3] =
1037  {
1038  message.Sensors.SampleTimestamp,
1039  message.Sensors.CameraTimestamp,
1040  message.Sensors.FrameTimestamp
1041  };
1042  // Handle wrap-around and convert samples to system time for any samples that changed.
1043  UpdateDK2Timestamps(TimeFilter, tsMaps, tsRawMks, sizeof(tsRawMks)/sizeof(tsRawMks[0]));
1044 
1045  onTrackerMessage(&message);
1046 
1047  /*
1048  if (SF_LOG_fp)
1049  {
1050  static UInt32 lastFrameTs = 0;
1051  static UInt32 lastCameraTs = 0;
1052 
1053  if ((lastFrameTs != message.Sensors.FrameTimestamp) ||
1054  (lastCameraTs = message.Sensors.CameraTimestamp))
1055  fprintf(SF_LOG_fp, "msg cameraTs: 0x%X frameTs: 0x%X sensorTs: 0x%X\n",
1056  message.Sensors.CameraTimestamp, message.Sensors.FrameTimestamp,
1057  message.Sensors.SampleTimestamp);
1058 
1059  lastFrameTs = message.Sensors.FrameTimestamp;
1060  lastCameraTs = message.Sensors.CameraTimestamp;
1061  }
1062  */
1063 
1064 #if 0
1065  // Checks for DK2 firmware bug.
1066  static unsigned SLastSampleTime = 0;
1067  if ((SLastSampleTime > message.Sensors.SampleTimestamp) && message.Sensors.SampleTimestamp > 1000000 )
1068  {
1069  fprintf(SF_LOG_fp, "*** Sample Timestamp Wrap! ***\n");
1070  OVR_ASSERT (SLastSampleTime <= message.Sensors.SampleTimestamp);
1071  }
1072  SLastSampleTime = message.Sensors.SampleTimestamp;
1073 
1074  static unsigned SLastCameraTime = 0;
1075  if ((SLastCameraTime > message.Sensors.CameraTimestamp) && message.Sensors.CameraTimestamp > 1000000 )
1076  {
1077  fprintf(SF_LOG_fp, "*** Camera Timestamp Wrap! ***\n");
1078  OVR_ASSERT (SLastCameraTime <= message.Sensors.CameraTimestamp);
1079  }
1080  SLastCameraTime = message.Sensors.CameraTimestamp;
1081 
1082  static unsigned SLastFrameTime = 0;
1083  if ((SLastFrameTime > message.Sensors.FrameTimestamp) && message.Sensors.FrameTimestamp > 1000000 )
1084  {
1085  fprintf(SF_LOG_fp, "*** Frame Timestamp Wrap! ***\n");
1086  OVR_ASSERT (SLastFrameTime <= message.Sensors.FrameTimestamp);
1087  }
1088  SLastFrameTime = message.Sensors.FrameTimestamp;
1089 #endif
1090  }
1091  }
1092 }
1093 
1094 double Sensor2DeviceImpl::OnTicks(double tickSeconds)
1095 {
1096 
1097  if (tickSeconds >= NextKeepAliveTickSeconds)
1098  {
1099  // Must send DK2 keep-alive. Set Keep-alive at 10 seconds.
1100  KeepAliveMuxReport keepAlive;
1101  keepAlive.CommandId = 0;
1102  keepAlive.INReport = 11;
1103  keepAlive.Interval = 10 * 1000;
1104 
1105  // Device creation is done from background thread so we don't need to add this to the command queue.
1106  KeepAliveMuxImpl keepAliveImpl(keepAlive);
1108 
1109  // Emit keep-alive every few seconds.
1110  double keepAliveDelta = 3.0; // Use 3-second interval.
1111  NextKeepAliveTickSeconds = tickSeconds + keepAliveDelta;
1112  }
1113  return NextKeepAliveTickSeconds - tickSeconds;
1114 }
1115 
1116 /*
1117 // TBD: don't report calibration for now, until we figure out the logic between camera and mag yaw correction
1118 bool Sensor2DeviceImpl::IsMagCalibrated()
1119 {
1120  return pCalibration->IsMagCalibrated();
1121 }
1122 */
1123 
1124 } // namespace OVR
bool setManufacturingReport(const ManufacturingReport &data)
bool setMagCalibrationReport(const MagCalibrationReport &data)
SensorCalibration * pCalibration
SensorTimestampMapping LastFrameTime
ManufacturingReport Settings
void Apply(MessageBodyFrame &msg)
void LogText(const char *fmt,...) OVR_LOG_VAARG_ATTRIBUTE(1
PositionTypeEnum PositionType
Definition: OVR_Device.h:733
virtual bool SetUUIDReport(const UUIDReport &data)
Vector3f MagFromBodyFrameUpdate(const Tracker2Sensors &update)
KeepAliveMuxReport Settings
virtual bool SetManufacturingReport(const ManufacturingReport &data)
double ScaleTimeUnit(double deviceClockDelta)
bool getLensDistortionReport(LensDistortionReport *data)
bool getKeepAliveMuxReport(KeepAliveMuxReport *data)
virtual bool GetLensDistortionReport(LensDistortionReport *data)
CustomPatternReport Settings
SensorTimeFilter TimeFilter
virtual bool GetGyroOffsetReport(GyroOffsetReport *data)
bool setTrackingReport(const TrackingReport &data)
virtual bool SetMagCalibrationReport(const MagCalibrationReport &data)
uint16_t UInt16
Definition: OVR_Types.h:251
UByte Buffer[PacketSize]
UInt32 DecodeUInt32(const UByte *buffer)
Definition: OVR_Alg.h:996
virtual bool GetAllPositionCalibrationReports(Array< PositionCalibrationReport > *data)
uint32_t UInt32
Definition: OVR_Types.h:253
virtual bool SetTrackingReport(const TrackingReport &data)
bool getTemperatureReport(TemperatureReport *data)
UInt16 DecodeUInt16(const UByte *buffer)
Definition: OVR_Alg.h:986
virtual bool SetCustomPatternReport(const CustomPatternReport &data)
Tracker2MessageType Decode(const UByte *buffer, int size)
Void setReportRate(unsigned rateHz)
virtual double OnTicks(double tickSeconds)
uint8_t UByte
Definition: OVR_Types.h:249
virtual bool SetLensDistortionReport(const LensDistortionReport &data)
Vector3f AccelFromBodyFrameUpdate(const Tracker2Sensors &update, UByte sampleNumber)
UByte Buffer[PacketSize]
double SampleToSystemTime(double sampleDeviceTime, double systemTime, double prevResult, const char *debugTag="")
bool HasHandlers() const
bool getGyroOffsetReport(GyroOffsetReport *data)
TemperatureReport Settings
bool getDisplayReport(DisplayReport *data)
bool getCustomPatternReport(CustomPatternReport *data)
void GetSensorRange(SensorRange *r)
bool setTemperatureReport(const TemperatureReport &data)
bool setCustomPatternReport(const CustomPatternReport &data)
MagCalibrationReport Settings
UByte Buffer[PacketSize]
Sensor2DeviceImpl(SensorDeviceCreateDesc *createDesc)
LensDistortionReport Settings
bool getMagCalibrationReport(MagCalibrationReport *data)
Tracker2Sensors Sensors
virtual bool GetCustomPatternReport(CustomPatternReport *data)
PositionCalibrationReport Settings
UByte Buffer[PacketSize]
bool setPositionCalibrationReport(const PositionCalibrationReport &data)
#define OVR_ASSERT(p)
SensorTimestampMapping LastCameraTime
SensorTimestampMapping LastSensorTime
virtual bool SetPositionCalibrationReport(const PositionCalibrationReport &data)
void UpdateDK2Timestamps(SensorTimeFilter &tf, SensorTimestampMapping **timestamps, UInt32 *rawValues, int count)
virtual bool GetTrackingReport(TrackingReport *data)
virtual bool SetKeepAliveMuxReport(const KeepAliveMuxReport &data)
bool setKeepAliveMuxReport(const KeepAliveMuxReport &data)
virtual void OnInputReport(UByte *pData, UInt32 length)
UByte Buffer[PacketSize]
MessageHandlerRef HandlerRef
bool getUUIDReport(UUIDReport *data)
bool getPositionCalibrationReport(PositionCalibrationReport *data)
Tracker2MessageType
Tracker2MessageType Type
UByte Buffer[PacketSize]
bool GetFeatureReport(UByte *data, UInt32 length)
virtual bool GetUUIDReport(UUIDReport *data)
DeviceManagerImpl * GetManagerImpl() const
int16_t SInt16
Definition: OVR_Types.h:250
bool getAllPositionCalibrationReports(Array< PositionCalibrationReport > *data)
PositionCalibrationReport Settings
virtual bool GetDisplayReport(DisplayReport *data)
UByte Buffer[PacketSize]
virtual bool GetKeepAliveMuxReport(KeepAliveMuxReport *data)
Vector3f EulerFromBodyFrameUpdate(const Tracker2Sensors &update, UByte sampleNumber)
bool getAllTemperatureReports(Array< Array< TemperatureReport > > *)
bool setLensDistortionReport(const LensDistortionReport &data)
CoordinateFrame Coordinates
bool decodeTracker2Message(Tracker2Message *message, UByte *buffer, int size)
__BEGIN_NAMESPACE_STD void void __END_NAMESPACE_STD void __BEGIN_NAMESPACE_STD void * memset(void *__s, int __c, size_t __n) __THROW __nonnull((1))
void UnpackSensor(const UByte *buffer, SInt32 *x, SInt32 *y, SInt32 *z)
TrackerSample Samples[2]
virtual bool SetTemperatureReport(const TemperatureReport &data)
bool setUUIDReport(const UUIDReport &data)
static double OVR_STDCALL GetSeconds()
Definition: OVR_Timer.cpp:51
virtual bool GetMagCalibrationReport(MagCalibrationReport *data)
void onTrackerMessage(Tracker2Message *message)
Void setCoordinateFrame(CoordinateFrame coordframe)
virtual bool SetFeatureReport(UByte *data, UInt32 length)=0
TrackingReport Settings
Void setOnboardCalibrationEnabled(bool enabled)
DisplayReport Settings
virtual bool GetAllTemperatureReports(Array< Array< TemperatureReport > > *)
void Call(const Message &msg)
SInt16 DecodeSInt16(const UByte *buffer)
Definition: OVR_Alg.h:991
GyroOffsetReport Settings
bool getTrackingReport(TrackingReport *data)
Vector3< float > Vector3f
Definition: OVR_Math.h:554
virtual bool SetDisplayReport(const DisplayReport &data)
ThreadId GetCurrentThreadId()
bool getManufacturingReport(ManufacturingReport *data)
bool setDisplayReport(const DisplayReport &data)
virtual bool GetManufacturingReport(ManufacturingReport *data)
UByte Buffer[PacketSize]