using UnityEngine; using Valve.VR; using TMPro; using System.Runtime.InteropServices; using System.Text; public class HeadsetGyroscope : MonoBehaviour { private TextMeshProUGUI gyroText; private uint headsetIndex = OpenVR.k_unTrackedDeviceIndexInvalid; void Start() { Debug.Log("HeadsetGyroscope: Start called"); gyroText = GetComponent(); if (gyroText == null) { Debug.LogError("TextMeshProUGUI component not found on this GameObject"); } // Initialize OpenVR if not already initialized if (OpenVR.System == null) { OpenVRUtil.System.InitOpenVR(); } // Find the headset device index (should be 0 for the HMD) headsetIndex = OpenVR.k_unTrackedDeviceIndex_Hmd; // Log the tracking system name StringBuilder trackingSystemName = new StringBuilder(64); ETrackedPropertyError error = ETrackedPropertyError.TrackedProp_Success; OpenVR.System.GetStringTrackedDeviceProperty(headsetIndex, ETrackedDeviceProperty.Prop_TrackingSystemName_String, trackingSystemName, 64, ref error); if (error == ETrackedPropertyError.TrackedProp_Success) { Debug.Log($"Tracking system: {trackingSystemName}"); } else { Debug.LogWarning($"Failed to get tracking system name: {error}"); } // Log all device properties to help find IMU data LogAllDeviceProperties(); } void Update() { if (OpenVR.System == null || gyroText == null) return; // Make sure the headset is connected if (!OpenVR.System.IsTrackedDeviceConnected(headsetIndex)) { gyroText.text = "Headset not connected"; return; } // Try different methods to get gyroscope data // Method 1: Try to get data from raw tracking universe TrackedDevicePose_t[] rawPoses = new TrackedDevicePose_t[OpenVR.k_unMaxTrackedDeviceCount]; // Get raw tracking data using the raw and uncalibrated universe OpenVR.System.GetDeviceToAbsoluteTrackingPose( ETrackingUniverseOrigin.TrackingUniverseRawAndUncalibrated, 0, rawPoses); // Check if we have valid raw data if (rawPoses[headsetIndex].bDeviceIsConnected) { Vector3 rawAngularVelocity = new Vector3( rawPoses[headsetIndex].vAngularVelocity.v0, rawPoses[headsetIndex].vAngularVelocity.v1, rawPoses[headsetIndex].vAngularVelocity.v2 ); if (rawAngularVelocity.magnitude > 0.001f) { gyroText.text = string.Format("Raw Gyro:\nX: {0:F2}\nY: {1:F2}\nZ: {2:F2}", rawAngularVelocity.x, rawAngularVelocity.y, rawAngularVelocity.z); return; } } // Method 2: Last resort - use standard tracking pose TrackedDevicePose_t[] poses = new TrackedDevicePose_t[OpenVR.k_unMaxTrackedDeviceCount]; OpenVR.System.GetDeviceToAbsoluteTrackingPose(ETrackingUniverseOrigin.TrackingUniverseStanding, 0, poses); if (!poses[headsetIndex].bDeviceIsConnected) { gyroText.text = "No gyro data available"; return; } // Extract angular velocity from the pose Vector3 angularVelocity = new Vector3( poses[headsetIndex].vAngularVelocity.v0, poses[headsetIndex].vAngularVelocity.v1, poses[headsetIndex].vAngularVelocity.v2 ); // Format and display the gyroscope data gyroText.text = string.Format("Std Gyro:\nX: {0:F2}\nY: {1:F2}\nZ: {2:F2}", angularVelocity.x, angularVelocity.y, angularVelocity.z ); // Add tracking status info if (!poses[headsetIndex].bPoseIsValid) { gyroText.text += "\n(Tracking lost)"; } } // Debug function to log all device properties private void LogAllDeviceProperties() { if (OpenVR.System == null) return; Debug.Log("Logging all device properties for headset:"); // Try to find properties that might contain IMU data // This is a comprehensive approach to find all available properties for (uint propId = 1000; propId < 3000; propId++) { try { ETrackedPropertyError error = ETrackedPropertyError.TrackedProp_Success; // Try as float first float floatValue = OpenVR.System.GetFloatTrackedDeviceProperty(headsetIndex, (ETrackedDeviceProperty)propId, ref error); if (error == ETrackedPropertyError.TrackedProp_Success) { Debug.Log($"Property {propId} (float): {floatValue}"); continue; } // Try as string uint propSize = OpenVR.System.GetStringTrackedDeviceProperty(headsetIndex, (ETrackedDeviceProperty)propId, null, 0, ref error); if (error == ETrackedPropertyError.TrackedProp_Success && propSize > 1) { StringBuilder value = new StringBuilder((int)propSize); OpenVR.System.GetStringTrackedDeviceProperty(headsetIndex, (ETrackedDeviceProperty)propId, value, propSize, ref error); Debug.Log($"Property {propId} (string): {value}"); } } catch (System.Exception e) { // Ignore errors for properties that don't exist } } // Specifically check for known IMU-related properties CheckSpecificProperty(ETrackedDeviceProperty.Prop_DeviceClass_Int32, "Device Class"); CheckSpecificProperty(ETrackedDeviceProperty.Prop_HasDisplayComponent_Bool, "Has Display"); CheckSpecificProperty(ETrackedDeviceProperty.Prop_HasCameraComponent_Bool, "Has Camera"); CheckSpecificProperty(ETrackedDeviceProperty.Prop_HasDriverDirectModeComponent_Bool, "Has Driver Direct Mode"); CheckSpecificProperty(ETrackedDeviceProperty.Prop_HasVirtualDisplayComponent_Bool, "Has Virtual Display"); } private void CheckSpecificProperty(ETrackedDeviceProperty prop, string name) { ETrackedPropertyError error = ETrackedPropertyError.TrackedProp_Success; int value = OpenVR.System.GetInt32TrackedDeviceProperty(headsetIndex, prop, ref error); if (error == ETrackedPropertyError.TrackedProp_Success) { Debug.Log($"{name}: {value}"); } } }