aboutsummaryrefslogtreecommitdiffstats
path: root/LibOVR/Src/OVR_SensorImpl.h
diff options
context:
space:
mode:
Diffstat (limited to 'LibOVR/Src/OVR_SensorImpl.h')
-rw-r--r--LibOVR/Src/OVR_SensorImpl.h316
1 files changed, 316 insertions, 0 deletions
diff --git a/LibOVR/Src/OVR_SensorImpl.h b/LibOVR/Src/OVR_SensorImpl.h
new file mode 100644
index 0000000..f53b831
--- /dev/null
+++ b/LibOVR/Src/OVR_SensorImpl.h
@@ -0,0 +1,316 @@
+/************************************************************************************
+
+Filename : OVR_SensorImpl.h
+Content : Sensor device specific implementation.
+Created : March 7, 2013
+Authors : Lee Cooper
+
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
+
+Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License");
+you may not use the Oculus VR Rift SDK except in compliance with the License,
+which is provided at the time of installation or download, or which
+otherwise accompanies this software in either electronic or hard copy form.
+
+You may obtain a copy of the License at
+
+http://www.oculusvr.com/licenses/LICENSE-3.1
+
+Unless required by applicable law or agreed to in writing, the Oculus VR SDK
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+*************************************************************************************/
+
+#ifndef OVR_SensorImpl_h
+#define OVR_SensorImpl_h
+
+#include "OVR_HIDDeviceImpl.h"
+#include "OVR_SensorTimeFilter.h"
+#include "OVR_Device.h"
+
+#ifdef OVR_OS_ANDROID
+#include "OVR_PhoneSensors.h"
+#endif
+
+namespace OVR {
+
+struct TrackerMessage;
+class ExternalVisitor;
+
+//-------------------------------------------------------------------------------------
+// SensorDeviceFactory enumerates Oculus Sensor devices.
+class SensorDeviceFactory : public DeviceFactory
+{
+public:
+ static SensorDeviceFactory &GetInstance();
+
+ // Enumerates devices, creating and destroying relevant objects in manager.
+ virtual void EnumerateDevices(EnumerateVisitor& visitor);
+
+ virtual bool MatchVendorProduct(UInt16 vendorId, UInt16 productId) const;
+ virtual bool DetectHIDDevice(DeviceManager* pdevMgr, const HIDDeviceDesc& desc);
+protected:
+ DeviceManager* getManager() const { return (DeviceManager*) pManager; }
+};
+
+
+// Describes a single a Oculus Sensor device and supports creating its instance.
+class SensorDeviceCreateDesc : public HIDDeviceCreateDesc
+{
+public:
+ SensorDeviceCreateDesc(DeviceFactory* factory, const HIDDeviceDesc& hidDesc)
+ : HIDDeviceCreateDesc(factory, Device_Sensor, hidDesc) { }
+
+ virtual DeviceCreateDesc* Clone() const
+ {
+ return new SensorDeviceCreateDesc(*this);
+ }
+
+ virtual DeviceBase* NewDeviceInstance();
+
+ virtual MatchResult MatchDevice(const DeviceCreateDesc& other,
+ DeviceCreateDesc**) const
+ {
+ if ((other.Type == Device_Sensor) && (pFactory == other.pFactory))
+ {
+ const SensorDeviceCreateDesc& s2 = (const SensorDeviceCreateDesc&) other;
+ if (MatchHIDDevice(s2.HIDDesc))
+ return Match_Found;
+ }
+ return Match_None;
+ }
+
+ virtual bool MatchHIDDevice(const HIDDeviceDesc& hidDesc) const
+ {
+ // should paths comparison be case insensitive?
+ return ((HIDDesc.Path.CompareNoCase(hidDesc.Path) == 0) &&
+ (HIDDesc.SerialNumber == hidDesc.SerialNumber) &&
+ (HIDDesc.VersionNumber == hidDesc.VersionNumber));
+ }
+
+ virtual bool GetDeviceInfo(DeviceInfo* info) const;
+};
+
+// A simple stub for notification of a sensor in Boot Loader mode
+// This descriptor does not support the creation of a device, only the detection
+// of its existence to warn apps that the sensor device needs firmware.
+// The Boot Loader descriptor reuses and is created by the Sensor device factory
+// but in the future may use a dedicated factory
+class BootLoaderDeviceCreateDesc : public HIDDeviceCreateDesc
+{
+public:
+ BootLoaderDeviceCreateDesc(DeviceFactory* factory, const HIDDeviceDesc& hidDesc)
+ : HIDDeviceCreateDesc(factory, Device_BootLoader, hidDesc) { }
+
+ virtual DeviceCreateDesc* Clone() const
+ {
+ return new BootLoaderDeviceCreateDesc(*this);
+ }
+
+ // Boot Loader device creation is not allowed
+ virtual DeviceBase* NewDeviceInstance() { return NULL; };
+
+ virtual MatchResult MatchDevice(const DeviceCreateDesc& other,
+ DeviceCreateDesc**) const
+ {
+ if ((other.Type == Device_BootLoader) && (pFactory == other.pFactory))
+ {
+ const BootLoaderDeviceCreateDesc& s2 = (const BootLoaderDeviceCreateDesc&) other;
+ if (MatchHIDDevice(s2.HIDDesc))
+ return Match_Found;
+ }
+ return Match_None;
+ }
+
+ virtual bool MatchHIDDevice(const HIDDeviceDesc& hidDesc) const
+ {
+ // should paths comparison be case insensitive?
+ return ((HIDDesc.Path.CompareNoCase(hidDesc.Path) == 0) &&
+ (HIDDesc.SerialNumber == hidDesc.SerialNumber));
+ }
+
+ virtual bool GetDeviceInfo(DeviceInfo* info) const
+ {
+ OVR_UNUSED(info);
+ return false;
+ }
+};
+
+
+//-------------------------------------------------------------------------------------
+// ***** OVR::SensorDisplayInfoImpl
+
+// DisplayInfo obtained from sensor; these values are used to report distortion
+// settings and other coefficients.
+// Older SensorDisplayInfo will have all zeros, causing the library to apply hard-coded defaults.
+// Currently, only resolutions and sizes are used.
+struct SensorDisplayInfoImpl
+{
+ enum { PacketSize = 56 };
+ UByte Buffer[PacketSize];
+
+ enum
+ {
+ Mask_BaseFmt = 0x0f,
+ Mask_OptionFmts = 0xf0,
+ Base_None = 0,
+ Base_ScreenOnly = 1,
+ Base_Distortion = 2,
+ };
+
+ UInt16 CommandId;
+
+ UByte DistortionType;
+ UInt16 HResolution, VResolution;
+ float HScreenSize, VScreenSize;
+ float VCenter;
+ float LensSeparation;
+ // Currently these values are not well-measured.
+ float OutsideLensSurfaceToScreen[2];
+ // TODO: add DistortionEqn
+ // TODO: currently these values are all zeros and the
+ // distortion is hard-coded in HMDDeviceCreateDesc::GetDeviceInfo()
+ float DistortionK[6];
+
+ SensorDisplayInfoImpl();
+
+ void Unpack();
+};
+
+//-------------------------------------------------------------------------------------
+// ***** OVR::SensorDeviceImpl
+
+// Oculus Sensor interface.
+
+class SensorDeviceImpl : public HIDDeviceImpl<OVR::SensorDevice>
+{
+public:
+ SensorDeviceImpl(SensorDeviceCreateDesc* createDesc);
+ ~SensorDeviceImpl();
+
+
+ // DeviceCommaon interface
+ virtual bool Initialize(DeviceBase* parent);
+ virtual void Shutdown();
+
+ virtual void AddMessageHandler(MessageHandler* handler);
+
+ // HIDDevice::Notifier interface.
+ virtual void OnInputReport(UByte* pData, UInt32 length);
+ virtual double OnTicks(double tickSeconds);
+
+ // HMD-Mounted sensor has a different coordinate frame.
+ virtual void SetCoordinateFrame(CoordinateFrame coordframe);
+ virtual CoordinateFrame GetCoordinateFrame() const;
+
+ // SensorDevice interface
+ virtual bool SetRange(const SensorRange& range, bool waitFlag);
+ virtual void GetRange(SensorRange* range) const;
+
+ virtual void GetFactoryCalibration(Vector3f* AccelOffset, Vector3f* GyroOffset,
+ Matrix4f* AccelMatrix, Matrix4f* GyroMatrix,
+ float* Temperature);
+ virtual void SetOnboardCalibrationEnabled(bool enabled);
+ virtual bool IsMagCalibrated();
+
+ // Sets report rate (in Hz) of MessageBodyFrame messages (delivered through MessageHandler::OnMessage call).
+ // Currently supported maximum rate is 1000Hz. If the rate is set to 500 or 333 Hz then OnMessage will be
+ // called twice or thrice at the same 'tick'.
+ // If the rate is < 333 then the OnMessage / MessageBodyFrame will be called three
+ // times for each 'tick': the first call will contain averaged values, the second
+ // and third calls will provide with most recent two recorded samples.
+ virtual void SetReportRate(unsigned rateHz);
+ // Returns currently set report rate, in Hz. If 0 - error occurred.
+ // Note, this value may be different from the one provided for SetReportRate. The return
+ // value will contain the actual rate.
+ virtual unsigned GetReportRate() const;
+
+ bool SetSerialReport(const SerialReport& data);
+ bool GetSerialReport(SerialReport* data);
+
+ // Hack to create HMD device from sensor display info.
+ static void EnumerateHMDFromSensorDisplayInfo(const SensorDisplayInfoImpl& displayInfo,
+ DeviceFactory::EnumerateVisitor& visitor);
+
+ // These methods actually store data in a JSON file
+ virtual bool SetMagCalibrationReport(const MagCalibrationReport& data);
+ virtual bool GetMagCalibrationReport(MagCalibrationReport* data);
+
+protected:
+
+ virtual void openDevice();
+ void closeDeviceOnError();
+
+ Void setCoordinateFrame(CoordinateFrame coordframe);
+ bool setRange(const SensorRange& range);
+
+ Void setReportRate(unsigned rateHz);
+
+ Void setOnboardCalibrationEnabled(bool enabled);
+
+ bool setSerialReport(const SerialReport& data);
+ bool getSerialReport(SerialReport* data);
+
+ // Called for decoded messages
+ void onTrackerMessage(TrackerMessage* message);
+ bool decodeTrackerMessage(TrackerMessage* message, UByte* buffer, int size);
+
+ // Helpers to reduce casting.
+/*
+ SensorDeviceCreateDesc* getCreateDesc() const
+ { return (SensorDeviceCreateDesc*)pCreateDesc.GetPtr(); }
+
+ HIDDeviceDesc* getHIDDesc() const
+ { return &getCreateDesc()->HIDDesc; }
+*/
+
+ // Set if the sensor is located on the HMD.
+ // Older prototype firmware doesn't support changing HW coordinates,
+ // so we track its state.
+ CoordinateFrame Coordinates;
+ CoordinateFrame HWCoordinates;
+ double NextKeepAliveTickSeconds;
+
+ bool SequenceValid;
+ UInt16 LastTimestamp;
+ UByte LastSampleCount;
+ float LastTemperature;
+ Vector3f LastAcceleration;
+ Vector3f LastRotationRate;
+ Vector3f LastMagneticField;
+
+ // This tracks wrap around, and should be monotonically increasing.
+ UInt32 FullTimestamp;
+
+ // Current sensor range obtained from device.
+ SensorRange MaxValidRange;
+ SensorRange CurrentRange;
+
+ // IMU calibration obtained from device.
+ Vector3f AccelCalibrationOffset;
+ Vector3f GyroCalibrationOffset;
+ Matrix4f AccelCalibrationMatrix;
+ Matrix4f GyroCalibrationMatrix;
+ float CalibrationTemperature;
+
+ UInt16 OldCommandId;
+
+ SensorTimeFilter TimeFilter;
+ double PrevAbsoluteTime;
+
+#ifdef OVR_OS_ANDROID
+ void replaceWithPhoneMag(Vector3f* val);
+ PhoneSensors* pPhoneSensors;
+#endif
+
+private:
+ Matrix4f magCalibration;
+ bool magCalibrated;
+};
+
+} // namespace OVR
+
+#endif // OVR_SensorImpl_h