Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.

Is there a way to get velocity and acceleration of a VR user (The headset itself?)

Discussion in 'AR/VR (XR) Discussion' started by naomi_k, Feb 7, 2020.

  1. naomi_k

    naomi_k

    Joined:
    Jan 23, 2020
    Posts:
    24
    Hello,

    I am trying to record the roll, pitch, yaw as well as the velocity and acceleration of a rift.

    I used transform.eulerAngles to get the roll, pitch and yaw of the headset

    Is there a similar way to get the velocity and acceleration?

    Thanks
     
    Last edited: Feb 7, 2020
  2. alexchesser

    alexchesser

    Joined:
    Sep 15, 2017
    Posts:
    147
    Not out of the box, but there are velocity estimators out there that you can sample from. Mostly those are concerned with the hands, but I don't see why you couldn't customize for your needs on the head.

    You can take a look at something like VRTK https://vrtoolkit.readme.io/docs/vrtk_velocityestimator

    Further, I'd actually assume that the XR-Interaction-Toolkit has them as well, but I don't know where exactly.

    Or if you have a few hours to do the course: https://learn.unity.com/course/oculus-vr is so good I'd be virtually willing to call it "required reading" for a VR developer. Even though it is starting to get a little out of date by now (already).
     
    wisemanneedshelp and naomi_k like this.
  3. hawken

    hawken

    Joined:
    Aug 22, 2013
    Posts:
    826
    The headset and controller positions are hardwired data from the input api, so sadly attaching a rigidbody to track velocity doesn't work in Unity as it gives back scrambled data.

    The controllers have velocity data from input which you can access through

    OVRInput.GetLocalControllerVelocity(OVRInput.Controller.LTouch)
    and

    OVRInput.GetLocalControllerAcceleration(OVRInput.Controller.LTouch)


    Sadly there doesn't seem to be the same function for getting the local velocity or acceleration of the headset.

    As @alexchesser mentions above, the best way might be to attach a velocity estimator that doesn't use Unity physics. VRTK make it sound like a complex system but really it's just the following code:


    Code (CSharp):
    1. public float headsetVelocity;
    2.     Vector3 lastHeadsetPosition;
    3.     public Transform headset;
    4.  
    5.     public void Update()
    6.     {
    7.         headsetVelocity = (headset.position - lastHeadsetPosition).magnitude / Time.deltaTime;
    8.         lastHeadsetPosition = headset.position;
    9.     }
    Acceleration can be calculated using this handy set of 3d math functions from the unity wiki
     
    Last edited: Feb 10, 2020
    naomi_k and alexchesser like this.
  4. creat327

    creat327

    Joined:
    Mar 19, 2009
    Posts:
    1,688
    Actually, it´s not that simple.

    1. public void Update()
    2. {
    3. headsetVelocity = (headset.position - lastHeadsetPosition).magnitude / Time.deltaTime;
    4. lastHeadsetPosition = headset.position;
    5. }
    That code won´t help you much. You can test it and see how it fails to even come close to a decent simulation.
    The issue is that you calculate from previous frame to current frame... and when you throw something, the release of the object is not instantaneous.

    You may release the button just a bit late, which in that function could mean that you are actually having a velocity vector pointing down... so you would need to work so much practicing on how to release the button properly that it would become a nightmare.

    VKIK and several others, what they do is store the last few frame positions and then interpolate to calculate what was the most likely direction. Probably is not when you released the button but just a bit before that.

    If anyone got the code to work, please share it. I've been trying to avoid the specific Oculus sdk calls for a while. In theory OpenXR has a way to get the controller velocity but I couldn´t figure out without making it controller specific.
     
  5. Dark-Table

    Dark-Table

    Joined:
    Nov 25, 2008
    Posts:
    315
  6. creat327

    creat327

    Joined:
    Mar 19, 2009
    Posts:
    1,688
    do you have a sample code? I'm looking at the script but i'm not sure how to use it
     
  7. creat327

    creat327

    Joined:
    Mar 19, 2009
    Posts:
    1,688
  8. habibahshm96

    habibahshm96

    Joined:
    Oct 13, 2022
    Posts:
    2
    Hello, I have found a way to get the HMD's Velcoity, position, rotation, etc..
    You can use the "InputTracking" class from the UnityEngine.XR package.
    https://docs.unity3d.com/2022.2/Documentation/ScriptReference/XR.InputTracking.html
    Then you can use the function "GetNodesStates" to get the states of all the "XRNodes" currently registered.
    You can read about Accessing input devices by XR node from here:
    https://docs.unity3d.com/Manual/xr_input.html

    You will gave to loop though to get exactly the node you need. Here's the code I implemented:

    Code (CSharp):
    1. public class GameManager : MonoBehaviour
    2. {
    3.  
    4.     [SerializeField] private TextMeshProUGUI debugText;
    5.     private Vector3 head_vel;
    6.  
    7.     private void Start()
    8.     {
    9.      
    10.      
    11.     }
    12.     private void Update()
    13.     {
    14.  
    15.         List<XRNodeState> nodes = new List<XRNodeState>();
    16.         InputTracking.GetNodeStates(nodes);
    17.         foreach (XRNodeState node in nodes)
    18.         {
    19.             if (node.nodeType == XRNode.Head)
    20.             {
    21.                 node.TryGetVelocity(out head_vel);
    22.                 debugText.SetText(head_vel.ToString());
    23.             }
    24.         }
    25.  
    26.  
    27.     }
    28. }
     
    Last edited: Jan 12, 2023