Start a new topic

Finding (true) North using the HMD

I'd like to place an object into the AR scene relative to Earth's North. Is it possible? 


My experience so far is that the Unity scene's "North" is relative to when the headset is initialized.


Technically, if you can get GPS from the Motorola phone, you can calculate a really accurate heading using a Delta Positioning algorithm.

Thank you again, Simon. This is really helpful. I've tried to get access through a number of ways, so at the very least it's good to get confirmation that it's not available.


I've thought about your suggestion of just having the user align themselves to the phone for a moment. But the more accurate the heading I can get, the better the UX will be. So the workaround I'm implementing now is to show a live compass on the phone screen and then have the user look at the phone. Then I can use the Image Tracking feature and resolve the heading from the relative rotations (and position within the camera's FOV, in case they're not looking dead-on for some reason). I can get true north from there relatively easy.


If this works, I think it'll suffice. And I feel I can make it sort of fun for the user so they shouldn't be bothered by the UX. The A3 is remarkably good at tracking relative rotation, so it's just getting the initial heading that I need to get through.

Hi Brian,


Unfortunately, we do not have the magnetic field sensor for the glasses exposed (and I'm not 100% sure the A3 glasses have this specific sensor). I will put in a ticket with our engineering team.


For the new Input System I got it running with the phone sensor: 


using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.UI;

public class MagneticFieldReader : MonoBehaviour
{
    public Text magneticFieldValue;
    public Text sensorAvailableText;
    void Start()
    {
        if (MagneticFieldSensor.current != null)
        {
            InputSystem.EnableDevice(MagneticFieldSensor.current);
            sensorAvailableText.text = "true";
        }
        else
        {
            sensorAvailableText.text = "false";
        }
    }

    void Update()
    {
        var magneticFieldValue = MagneticFieldSensor.current.magneticField.ReadValue();
        this.magneticFieldValue.text = $"(X {magneticFieldValue.x.ToString("0.00000")}; Y {magneticFieldValue.z.ToString("0.00000")}; Z {magneticFieldValue.z.ToString("0.00000")})";
    }
}


You didn't enable the sensor in Start();



You could do a less imprecise alignment step where the user aligns the phone and headset looking north as a workaround. 






1 person likes this

Thank you Simon, this sounds exactly like what I was looking for. This is really helpful!


Unfortunately, I'm only getting 0.00s for the MagneticFieldSensor, and the legacy Compass is returning values for the Moto Edge phone. 

  
08-25 13:40:25.999 6436 6460 I Unity : Magnetic Field Value: (0.00, 0.00, 0.00)

08-25 13:40:25.999 6436 6460 I Unity : Heading: 130.9803


It feels really close. Do you know if there's something I need to enable to starting reading this data from the A3 headset? I've isolated the code to a single behavior and attached the file, if it helps.

cs
(1.48 KB)

Hi Brian,


Unity input allows you to access measurements from the magnetic field sensor - here's the documentation: Class MagneticFieldSensor | Package Manager UI website (unity3d.com)


Depending on the device you're using and your use case you may require different sensor data. Per default the sensor data is coming from the headset - e.g. A3 or VRX.  If you need the Motorola Edge phone's orientation, additional communication with native Android methods is required. 


Another reference I found uses the legacy input system: https://docs.unity3d.com/ScriptReference/Compass.html


Let me know if that helps! 


1 person likes this
Login or Signup to post a comment