ARFoundation is an experimental package from unity that provides a common layer on top of Apple ARCore and Apple ARKit https://docs.unity3d.com/Packages/com.unity.xr.arfoundation@1.0/manual/index.html
Unity world origin and orientation
This point is fixed in the AR environment. To preserve accuracy and simplicity in dealing with the AR libraries, this will be aligned with the users starting GPS location.
User location and heading
The user is moving around the physical world. Their position can be tracked with the phone GPS and compass. As inertial tracking and camera tracking are already used by the AR libraries, we will interact with them through the unity AR camera, not directly. The users GPS location will be stored on startup and used to offset all other GPS coordinates to align with the Unity World Origin
AR Camera location and heading
This is tracked by the AR Libraries, and not directly controlled by our app. This position will be an offset from origin position determined when the application was started. The heading is not important at this time.
Object location and heading
Location of objects in the real world, and the direction they’re facing. These coordinates will be mapped into the Unity world space when they are displayed.
Transforming GPS locations into Unity
User location can be provided by Unity’s built in Location Service https://docs.unity3d.com/ScriptReference/LocationService.html, which interfaces with the device GPS.
Note: If debugging using Unity Remote https://docs.unity3d.com/Manual/UnityRemote5.html, the GPS service can take a significant time to startup, so the application will need to wait and retry until until GPS is established.
We wrap the GPS access in a class to handle the startup, polling and provides a fake location mode for local testing.
Now that we have the position,we need to convert from real world coordinates into unity AR world coordindates. Conversion between cartesian coordinate systems involes scaling and rotation transforms. As the earth is roughly spherical, the arc length of a degree of longitude changes with the latitude, approaching zero at the pole. This can be calculated by 111319.9 * Math.Cos(latitude * (Math.PI/180)). As the earth is not a perfect sphere, the distance between degrees latitude also varies slightly, but an insignificant amount compared to logitude, so I will use the approximation of 111132m per degree.
To then align the GPS real world coordinate space with the Unity AR space, we can sample the devices compass to determine there direction it is facing when when AR is initialised. This rotation can then be applied when doing the coordinate transform to align both spaces.
The heading can be read in Unity by using Input.compass.trueHeading. This rotation can then be used to transform a position on the GPS coordinate system to be aligned with the unity coordinates.