# Frames of Reference

When describing the position and orientation of something (for example, your Tango device), it is important to indicate the frame of reference you are using to base your description on.

To help understand frames of reference, consider the following: Saying "Mary is standing three feet away" does not really tell you much. If you want to know Mary's position, you must also address the question "three feet from what?" If you say "Mary is standing three feet in front of the entrance to the Statue of Liberty," you can now establish Mary's position because you are using the Statue of Liberty as your frame of reference and you can measure the distance and directon of Mary relative to the Statue.

But Mary isn't simply a point with a position in 3D space—she also has an orientation, which is described in terms of some type of rotation relative to the frame of reference. In other words, Mary, like all 3D objects, faces a certain direction. A full description of Mary's position and orientation (we call this combination a pose) in 3D space would be something like this: "Mary is standing three feet in front of the entrance to the Statue of Liberty, and she is directly facing it." Now you have provided information about her orientation. If Mary turned to her right, you could say "She is now rotated 90 degrees away from the Statue." This would be another description of orientation.

So how does all of this relate to a Tango device? In order to perform motion tracking, a device reports its pose (position and orientation) relative to its chosen frame of reference, which is fixed in 3D space. For example, the device might say "from the place that I first started motion tracking, I am now three feet forward and one foot up, and I have rotated 30 degrees to the right." By doing this, the device has told you its position using meaningful directions: three feet forward and one foot up from its original starting position. It has also told you about a change in its orientation: rotated 30 degrees to the right relative to its starting position.

To set things up for motion tracking, you must do the following:

1. Choose a base frame. This is the thing you will be measuring from. As mentioned above, it is fixed in 3D space, like the Statue of Liberty in our example above. Example: the `COORDINATE_FRAME_START_OF_SERVICE` frame.

2. Choose a target frame. This is the thing you will be measuring to. For motion tracking this is usually `COORDINATE_FRAME_DEVICE` and represents your device's pose at any given instant as it moves through 3D space. The pose of the target frame changes as your device moves, and is measured against the base frame (which never changes), up to 100 times per second. This constant stream of measurements creates your motion track.

The numerical measurements of the pose of the target frame relative to the base frame at any given instant answer the question: "What is the device's position and orientation relative to its base frame of reference?"

In the next section, we discuss the use of start-of-service frame, area description frame, and device pose frame pairs for motion tracking. For certain applications, you may need to choose a frame pair that will enable you to make precise alignments of data sources from device components. We discuss these types of frame pairs later in this topic.

## Coordinate frames for motion tracking

The Tango APIs give you various frame pair options for motion tracking:

Target Frame Base Frame
`COORDINATE_FRAME_DEVICE` `COORDINATE_FRAME_START_OF_SERVICE`
`COORDINATE_FRAME_DEVICE` `COORDINATE_FRAME_AREA_DESCRIPTION`
`COORDINATE_FRAME_START_OF_SERVICE` `COORDINATE_FRAME_AREA_DESCRIPTION`

Let's consider a common use case:

Goal: Your app controls a camera in a fully virtual environment. You want the device to always calculate its pose relative to where it was when the Tango service started.

Solution: For the target frame, choose `COORDINATE_FRAME_DEVICE`. For the base frame, choose `COORDINATE_FRAME_START_OF_SERVICE`.

Here is the frame pair used in our example project titled cpp_hello_motion_tracking_example:

`````` TangoCoordinateFramePair pair;
pair.base = TANGO_COORDINATE_FRAME_START_OF_SERVICE;
pair.target = TANGO_COORDINATE_FRAME_DEVICE;
if (TangoService_connectOnPoseAvailable(1, &pair, onPoseAvailable) !=
TANGO_SUCCESS) {
LOGE("TangoHandler::OnResume, connectOnPoseAvailable error.");
std::exit(EXIT_SUCCESS);
}
``````

Let's look at the details of individual frame pairs.

Target Frame Base Frame
`COORDINATE_FRAME_DEVICE` `COORDINATE_FRAME_START_OF_SERVICE`

This frame pair provides the pose of the device relative to when the Tango service first initialized successfully. This mode accumulates the movement of the device over time since the service started. The service can also detect if there is a motion tracking failure. During this period, the system reports an invalid pose. If `TangoService_resetMotionTracking()` is called or auto-reset is enabled in the service configuration, the system attempts to re-initialize tracking. After successful re-initialization, it makes a best effort attempt to recover the last known good pose of the device relative to the start of service frame and pick up where it left off. For more information, see Lifecycle of pose status. This frame pair does not include drift correction or localization. If your application does not use drift correction or localization, you can lower processing requirements by disabling area learning mode and not loading an ADF.

Target Frame Base Frame
`COORDINATE_FRAME_DEVICE` `COORDINATE_FRAME_AREA_DESCRIPTION`

This frame pair provides the pose of the device, including corrections, relative to the loaded area description's origin. It requires that area learning mode is turned on or a previously created ADF is loaded. If you turn on learning mode without loading an ADF, the origin of the area description base frame is initially the same as start of service. If you load an ADF with or without learning mode, the origin of the area description base frame is the origin stored in the ADF, and you will receive data only after the device has localized. Depending on your configuration settings, this mode is not always available. For more information, see Using Learning Mode and loaded Area Description Files. If you need to use motion tracking before the `COORDINATE_FRAME_DEVICE` to `COORDINATE_FRAME_AREA_DESCRIPTION` frame pair becomes valid, you can use the `COORDINATE_FRAME_START_OF_SERVICE` base frame in the interim.

For pairs using the `COORDINATE_FRAME_DEVICE` target frame, updates are available at the pose estimation rate supported by the device.

Target Frame Base Frame
`COORDINATE_FRAME_START_OF_SERVICE` `COORDINATE_FRAME_AREA_DESCRIPTION`

This frame pair provides updates only when a localization event or a drift correction occurs. This requires that area learning mode is turned on or a previously created ADF is loaded. If an ADF is loaded, the origin of the area description base frame is the origin stored in the ADF. This isolates the adjustments to the pose of the device from the incremental frame-to-frame motion, allowing you to decide when and how to incorporate the pose adjustments in your application to minimize disruption to the user experience.

## Coordinate frames for component alignment

Target Frame Base Frame
`COORDINATE_FRAME_DEVICE` `COORDINATE_FRAME_IMU`
`COORDINATE_FRAME_CAMERA_COLOR` `COORDINATE_FRAME_IMU`
`COORDINATE_FRAME_CAMERA_DEPTH` `COORDINATE_FRAME_IMU`
`COORDINATE_FRAME_CAMERA_FISHEYE` `COORDINATE_FRAME_IMU`

Some applications need to align multiple data sources, such as the data from the color and depth cameras. You can pair the `COORDINATE_FRAME_IMU` base frame with one of the component target frames for these scenarios:

1. You want to query the relative offsets of the individual components to the IMU frame of reference without knowing the layout of the specific device.

2. You want the virtual image from the rendering camera to align with the center of the display.

Combined with the motion tracking coordinate frames and timestamps on the data, these offsets give you a more complete understanding of the various sensor inputs in both space and time. This is necessary for aligning and compositing multiple data sources together.

Since devices are designed to be mechanically rigid, these offsets are not expected to change and updates will not occur in the API. However, devices vary in how their components are spaced. Updating extrinsic parameters over time is not currently supported by the Tango APIs. These values are generated either from a one-time factory calibration or from the manufacturer's mechanical design files. Applications that require extremely tight requirements for the extrinsic parameters should consider implementing their own calibration procedure which can be performed by the end user.

The `COORDINATE_FRAME_IMU` base frame provides a common reference point for all of the internal components in the device. The origin of this base frame does not necessarily correspond to any one particular component and may differ between devices. Like other Android sensors, the axis of the device coordinate frame is aligned with the natural (default) orientation of the device as defined by the manufacturer. The manufacturer-defined natural orientation of the device may not match the desired orientation of your app. For maximum future compatibility, do not assume a Tango-compliant device has a natural orientation that is either landscape or portrait. Instead, use the Android `getRotation()` method to determine screen rotation, and then use the Android `remapCoordinateSystem()` method to map sensor coordinates to screen coordinates. For more general information about sensors, see the Android documentation on the sensor coordinate system. For a more detailed discussion of issues surrounding device orientation, see this Android Developers Blog post.

The component offsets are static and should only need to be queried once.