Coordinate Systems

The Tango API returns pose data as a rotation and translation between two coordinate frames with X, Y, and Z values. It is important to understand the coordinate system used for each coordinate frame type. This page describes our common coordinate systems.

If you work with Tango alone, or Tango + OpenGL, there are two coordinate systems you need to work with. If you work with Tango + Unity, there is a third coordinate system to add to the list. Each is explained below.

Tango Coordinate Systems

Tango uses two systems that follow the Right Hand convention but are slightly different, so we have labeled them Right Hand Local Level and Right Hand Android to minimize confusion.

Right Hand Local Level: The X axis is horizontal with the positive direction to the right, the Z axis is vertical with the positive direction pointing up, and the Y axis is depth (forward and back), with the positive direction pointing out the back of the device away from the user.

Right Hand Android: This system is the same as the Android Sensor Coordinate System. When a device is held in its default orientation, the X axis is horizontal with the positive direction to the right, the Y axis is vertical with the positive direction pointing up, and the Z axis is depth (forward and back), with the positive direction pointing out of the screen towards the user.

Here are the coordinate frames you can use for motion tracking and the coordinate systems associated with them:

Base Frame Coordinate System
COORDINATE_FRAME_START_OF_SERVICE Right Hand Local Level
COORDINATE_FRAME_AREA_DESCRIPTION Right Hand Local Level
COORDINATE_FRAME_DEVICE Right Hand Android

OpenGL Coordinate System

The OpenGL World Frame and Camera Frame both use a right-handed coordinate system similar to the Right Hand Android system: the X axis is horizontal with the positive direction to the right, the Y axis is vertical with the positive direction pointing up, and the Z axis is depth (forward and back), with the positive direction pointing out of the screen and towards the user.

If an Android device in its default orientation is being used to control a camera, the device and OpenGL camera are using the same coordinate system.

Unity Coordinate System

The Unity World Frame and Camera Frame both use a left-handed coordinate system: the X axis is horizontal with the positive direction to the right, the Y axis is vertical with the positive direction pointing up, and the Z axis is depth (forward and back), with the positive direction pointing away from the user. In this system, the camera looks in the direction the Z axis is pointing.

On-Device Coordinate Frames

Each component on a Tango device, like the IMU, the cameras, and the display, has its own coordinate frame. The device itself also has a coordinate frame which aligns with the default Android Device coordinate frame. You can get the position and orientation offset between each component (extrinsics) using the Tango APIs.

Coordinate Frame Conversions

In both OpenGL and Unity, the World Frames define the origin of the scene and the Camera Frames represent the viewport attached to the camera. The pose data returned by the Tango APIs must be transformed into the appropriate alternate coordinate systems, such as the OpenGL and the Unity Camera Frames. The C support library provides functions for this purpose. This is the easiest way to handle these transformations, but for those interested, in this section we explain some of the matrix math involved.

We use the following notation to represent the matrix that can be used to transform a vector between a Target coordinate frame and a Base coordinate frame.

We will look at the pose of the device using DEVICE (D) as the target coordinate frame and START_OF_SERVICE (SS) as the base coordinate frame, represented by this notation:

We will also convert the device's position to match the target platform's camera coordinate frame. You would do this in an application that matches the camera's movement to the device movement.

Converting Tango pose data into the OpenGL Coordinate System

We use two transformations to convert Tango pose data into the OpenGL Camera coordinate frame. The first transformation converts between the Tango START_OF_SERVICE (SS) coordinate frame and the OpenGL World (OW) coordinate frame.

The second transformation converts between the OpenGL Camera (OC) coordinate frame and the Tango Device (D) coordinate frame. Because both frames use the same coordinate system, this is the identity matrix.

By multiplying the transformations together in this order, we are able to obtain a single transformation matrix that converts the pose returned by the API between the OpenGL Camera (OC) target coordinate frame and the OpenGL World (OW) base coordinate frame.

Multiply the Tango Pose with and then multiply the result with as shown here:

This is provided in the API Sample Code using quaternions. Note that is an identity transformation matrix and can be omitted, but is shown here for completeness.

Converting Tango Pose data into the Unity Coordinate System

We can handle Unity Coordinate System conversion the same way as OpenGL. The first transformation converts between the Project Tango START_OF_SERVICE (SS) coordinate frame and the Unity World (UW) coordinate frame.

The second transformation converts between the Unity Camera (UC) coordinate frame and the Tango Device (D) coordinate frame. You’ll notice that unlike in OpenGL, this is not the identity matrix because Unity uses a left-handed coordinate system.

Multiply the first conversion and then multiply the second conversion to get a matrix that converts pose data between the Unity Camera (UC) coordinate frame and the Unity World (UW) coordinate frame.