nuclear@0: /************************************************************************************ nuclear@0: nuclear@0: Filename : Tracking_SensorState.h nuclear@0: Content : Sensor state information shared by tracking system with games nuclear@0: Created : May 13, 2014 nuclear@0: Authors : Dov Katz, Chris Taylor nuclear@0: nuclear@0: Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. nuclear@0: nuclear@0: Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); nuclear@0: you may not use the Oculus VR Rift SDK except in compliance with the License, nuclear@0: which is provided at the time of installation or download, or which nuclear@0: otherwise accompanies this software in either electronic or hard copy form. nuclear@0: nuclear@0: You may obtain a copy of the License at nuclear@0: nuclear@0: http://www.oculusvr.com/licenses/LICENSE-3.2 nuclear@0: nuclear@0: Unless required by applicable law or agreed to in writing, the Oculus VR SDK nuclear@0: distributed under the License is distributed on an "AS IS" BASIS, nuclear@0: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. nuclear@0: See the License for the specific language governing permissions and nuclear@0: limitations under the License. nuclear@0: nuclear@0: *************************************************************************************/ nuclear@0: nuclear@0: #ifndef Tracking_SensorState_h nuclear@0: #define Tracking_SensorState_h nuclear@0: nuclear@0: #include "Tracking_PoseState.h" nuclear@0: #include "../Kernel/OVR_SharedMemory.h" nuclear@0: #include "../Kernel/OVR_Lockless.h" nuclear@0: #include "../Kernel/OVR_String.h" nuclear@0: #include "../Util/Util_LatencyTest2State.h" nuclear@0: #include "../Sensors/OVR_DeviceConstants.h" nuclear@0: nuclear@0: // CAPI forward declarations. nuclear@0: struct ovrTrackingState_; nuclear@0: typedef struct ovrTrackingState_ ovrTrackingState; nuclear@0: struct ovrPoseStatef_; nuclear@0: typedef struct ovrPoseStatef_ ovrPoseStatef; nuclear@0: nuclear@0: namespace OVR { namespace Tracking { nuclear@0: nuclear@0: nuclear@0: //------------------------------------------------------------------------------------- nuclear@0: // ***** Sensor State nuclear@0: // These values are reported as compatible with C API. nuclear@0: nuclear@0: // Bit flags describing the current status of sensor tracking. nuclear@0: enum StatusBits nuclear@0: { nuclear@0: // Tracked bits: Toggled by SensorFusion nuclear@0: Status_OrientationTracked = 0x0001, // Orientation is currently tracked (connected and in use) nuclear@0: Status_PositionTracked = 0x0002, // Position is currently tracked (false if out of range) nuclear@0: Status_CameraPoseTracked = 0x0004, // Camera pose is currently tracked nuclear@0: nuclear@0: // Connected bits: Toggled by TrackingManager nuclear@0: Status_PositionConnected = 0x0020, // Position tracking HW is connected nuclear@0: Status_HMDConnected = 0x0080, // HMD is available & connected nuclear@0: nuclear@0: // Masks nuclear@0: Status_AllMask = 0xffff, nuclear@0: Status_TrackingMask = Status_PositionTracked | Status_OrientationTracked | Status_CameraPoseTracked, nuclear@0: Status_ConnectedMask = Status_PositionConnected | Status_HMDConnected, nuclear@0: }; nuclear@0: nuclear@0: nuclear@0: // Full state of of the sensor reported by GetSensorState() at a given absolute time. nuclear@0: class TrackingState nuclear@0: { nuclear@0: public: nuclear@0: TrackingState() : HeadPose(), CameraPose(), LeveledCameraPose(), RawSensorData(), StatusFlags(0), LastVisionProcessingTime(0.0) { } nuclear@0: nuclear@0: // C-interop support nuclear@0: TrackingState(const ovrTrackingState& s); nuclear@0: operator ovrTrackingState () const; nuclear@0: nuclear@0: // HMD pose information for the requested time. nuclear@0: PoseStatef HeadPose; nuclear@0: nuclear@0: // Orientation and position of the external camera, if present. nuclear@0: Posef CameraPose; nuclear@0: // Orientation and position of the camera after alignment with gravity nuclear@0: Posef LeveledCameraPose; nuclear@0: nuclear@0: // Most recent sensor data received from the HMD nuclear@0: SensorDataType RawSensorData; nuclear@0: nuclear@0: // Sensor status described by ovrStatusBits. nuclear@0: uint32_t StatusFlags; nuclear@0: nuclear@0: //// 0.4.1 nuclear@0: nuclear@0: // Measures the time from receiving the camera frame until vision CPU processing completes. nuclear@0: double LastVisionProcessingTime; nuclear@0: nuclear@0: //// 0.4.3 nuclear@0: nuclear@0: // Measures the time from exposure until the pose is available for the frame, including processing time. nuclear@0: double LastVisionFrameLatency; nuclear@0: nuclear@0: // Tag the vision processing results to a certain frame counter number. nuclear@0: uint32_t LastCameraFrameCounter; nuclear@0: }; nuclear@0: nuclear@0: nuclear@0: // ----------------------------------------------- nuclear@0: nuclear@0: #pragma pack(push, 8) nuclear@0: nuclear@0: struct LocklessSensorStatePadding; nuclear@0: nuclear@0: // State version stored in lockless updater "queue" and used for nuclear@0: // prediction by GetPoseAtTime/GetSensorStateAtTime nuclear@0: struct LocklessSensorState nuclear@0: { nuclear@0: PoseState WorldFromImu; nuclear@0: SensorDataType RawSensorData; nuclear@0: Pose WorldFromCamera; nuclear@0: uint32_t StatusFlags; nuclear@0: uint32_t _PAD_0_; nuclear@0: nuclear@0: // ImuFromCpf for HMD pose tracking nuclear@0: Posed ImuFromCpf; nuclear@0: nuclear@0: // Performance logging nuclear@0: double LastVisionProcessingTime; nuclear@0: double LastVisionFrameLatency; nuclear@0: uint32_t LastCameraFrameCounter; nuclear@0: uint32_t _PAD_1_; nuclear@0: nuclear@0: // Initialized to invalid state nuclear@0: LocklessSensorState() : nuclear@0: WorldFromImu() nuclear@0: , RawSensorData() nuclear@0: , WorldFromCamera() nuclear@0: , StatusFlags(0) nuclear@0: , _PAD_0_(0) // This assignment should be irrelevant, but it quells static/runtime analysis complaints. nuclear@0: , ImuFromCpf() nuclear@0: , LastVisionProcessingTime(0.0) nuclear@0: , LastVisionFrameLatency(0.0) nuclear@0: , LastCameraFrameCounter(0) nuclear@0: , _PAD_1_(0) // " nuclear@0: { nuclear@0: } nuclear@0: nuclear@0: LocklessSensorState& operator = (const LocklessSensorStatePadding& rhs); nuclear@0: }; nuclear@0: nuclear@0: static_assert((sizeof(LocklessSensorState) == sizeof(PoseState) + sizeof(SensorDataType) + sizeof(Pose) + 2*sizeof(uint32_t) + sizeof(Posed) + sizeof(double)*2 + sizeof(uint32_t)*2), "sizeof(LocklessSensorState) failure"); nuclear@0: nuclear@0: // Padded out version stored in the updater slots nuclear@0: // Designed to be a larger fixed size to allow the data to grow in the future nuclear@0: // without breaking older compiled code. nuclear@0: struct LocklessSensorStatePadding nuclear@0: { nuclear@0: uint64_t words[64]; nuclear@0: nuclear@0: static const int DataWords = (sizeof(LocklessSensorState) + sizeof(uint64_t) - 1) / sizeof(uint64_t); nuclear@0: nuclear@0: // Just copy the low data words nuclear@0: inline LocklessSensorStatePadding& operator=(const LocklessSensorState& rhs) nuclear@0: { nuclear@0: const uint64_t* src = (const uint64_t*)&rhs; nuclear@0: nuclear@0: // if this fires off, then increase words' array size nuclear@0: OVR_ASSERT(sizeof(words) > sizeof(LocklessSensorState)); nuclear@0: nuclear@0: for (int i = 0; i < DataWords; ++i) nuclear@0: { nuclear@0: words[i] = src[i]; nuclear@0: } nuclear@0: nuclear@0: return *this; nuclear@0: } nuclear@0: }; nuclear@0: nuclear@0: // Just copy the low data words nuclear@0: inline LocklessSensorState& LocklessSensorState::operator = (const LocklessSensorStatePadding& rhs) nuclear@0: { nuclear@0: uint64_t* dest = (uint64_t*)this; nuclear@0: nuclear@0: for (int i = 0; i < LocklessSensorStatePadding::DataWords; ++i) nuclear@0: { nuclear@0: dest[i] = rhs.words[i]; nuclear@0: } nuclear@0: nuclear@0: return *this; nuclear@0: } nuclear@0: nuclear@0: #pragma pack(pop) nuclear@0: nuclear@0: // A lockless updater for sensor state nuclear@0: typedef LocklessUpdater SensorStateUpdater; nuclear@0: nuclear@0: nuclear@0: //// Combined state nuclear@0: nuclear@0: struct CombinedSharedStateUpdater nuclear@0: { nuclear@0: SensorStateUpdater SharedSensorState; nuclear@0: Util::LockessRecordUpdater SharedLatencyTestState; nuclear@0: }; nuclear@0: nuclear@0: typedef SharedObjectWriter< CombinedSharedStateUpdater > CombinedSharedStateWriter; nuclear@0: typedef SharedObjectReader< CombinedSharedStateUpdater > CombinedSharedStateReader; nuclear@0: nuclear@0: nuclear@0: }} // namespace OVR::Tracking nuclear@0: nuclear@0: #endif