Java API Area Learning Tutorial


There are two configuration options that are relevant to area learning.

Loading area descriptions

To load an area description file, your TangoConfig must have KEY_STRING_AREADESCRIPTION set to the UUID of the ADF you wish to load. When the TangoService starts, it loads this area description.

try {
    mConfig.putString(TangoConfig.KEY_STRING_AREADESCRIPTION, uuid);
} catch (TangoErrorException e) {
    // handle exception

Here is an example of how you could load the latest saved area description file. It retrieves a list of all area description files and takes the last one in the list, which would be the most recent:

ArrayList<String> fullUUIDList = new ArrayList<String>();
// Returns a list of ADFs with their UUIDs
fullUUIDList = mTango.listAreaDescriptions();

// Load the latest ADF if ADFs are found.
if (fullUUIDList.size() > 0) {
                       fullUUIDList.get(fullUUIDList.size() - 1));

Learning mode

In order to use area learning, your TangoConfig must have KEY_BOOLEAN_LEARNINGMODE set to true. In the default TangoConfig, KEY_BOOLEAN_LEARNINGMODE is set to false.

try {
    TangoConfig mConfig = mTango.getConfig(TangoConfig.CONFIG_TYPE_CURRENT);
    mConfig.putBoolean(TangoConfig.KEY_BOOLEAN_LEARNINGMODE, true);
} catch (TangoErrorException e) {
    // handle exception

You can save an ADF by calling Tango.saveAreaDescription(). This call can be long-running, so don't call it on the UI thread.

Learning mode with a loaded area description

If both options are used, an area description of the current session will be built. If localization occurs against the loaded ADF and Tango.saveAreaDescription() is called, a new ADF will be saved containing the combination of both.

Motion tracking with area learning

In general, using motion tracking with area learning is very similar to basic motion tracking. You need to define the coordinate pairs you are interested in, then use either callbacks or polling to get data.

There are two coordinate frame pairs for area learning. The TangoCoordinateFramePair

with baseFrame == TangoPoseData.COORDINATE_FRAME_AREA_DESCRIPTION and targetFrame == TangoPoseData.COORDINATE_FRAME_DEVICE gets you the pose of the device from the area description's origin, including drift corrections. If an ADF was loaded, pose data is only available after you have localized to the ADF and the origin will be the same as the ADF. If learning mode enabled without loading an ADF, pose data will be available immediately after initialization and the origin will be the same as the start of service.

The frame pair with baseFrame == TangoPoseData.COORDINATE_FRAME_AREA_DESCRIPTION and targetFrame == TangoPoseData.COORDINATE_FRAME_START_OF_SERVICE provides the offset between the area description and start of service at the requested time. This pair updates only when a localization occurs.

Applications should use TangoPoseData.COORDINATE_FRAME_DEVICE with respect to TangoPoseData.COORDINATE_FRAME_AREA_DESCRIPTION for tracking a device's motion, and use TangoPoseData.COORDINATE_FRAME_START_OF_SERVICE with respect to TangoPoseData.COORDINATE_FRAME_AREA_DESCRIPTION only as a localization signal.

public void onPoseAvailable(TangoPoseData pose) {

if (pose.baseFrame == TangoPoseData.COORDINATE_FRAME_AREA_DESCRIPTION
        && pose.targetFrame == TangoPoseData.COORDINATE_FRAME_DEVICE) {
    // Process new ADF to device pose data.
else if (pose.baseFrame == TangoPoseData.COORDINATE_FRAME_AREA_DESCRIPTION
        && pose.targetFrame == TangoPoseData.COORDINATE_FRAME_START_OF_SERVICE) {
    // Process new localization.

Working with ADFs

Using metadata

ADFs have metadata you can use, so you don't have to work with UUID alone. The metadata consists of key-value pairs; for a list of supported keys see the constant values for TangoAreaDescriptionMetaData.

Get the name field for the ADF identified by uuid:

public String getName(String uuid) {

    TangoAreaDescriptionMetaData metadata = new TangoAreaDescriptionMetaData();
    metadata = mTango.loadAreaDescriptionMetaData(uuid);
    byte[] nameBytes = metadata.get(TangoAreaDescriptionMetaData.KEY_NAME);
    if (nameBytes != null) {
        String name = new String(nameBytes);
        return name;
    } // Do something if null

Set the name field to name, for the ADF identified by uuid:

public void setName(String name, String uuid) {

    TangoAreaDescriptionMetaData metadata = new TangoAreaDescriptionMetaData();
    metadata = mTango.loadAreaDescriptionMetaData(uuid);
    metadata.set(TangoAreaDescriptionMetaData.KEY_NAME, name.getBytes());
    mTango.saveAreaDescriptionMetadata(uuid, metadata);

Listing all the UUIDs of currently accessible ADFs:

ArrayList<String> mFullUUIDList;
try {
    mFullUUIDList = mTango.listAreaDescriptions();
} catch(TangoErrorException e) {
    // handle the errors
if (mFullUUIDList.size() == 0) {
    // handle the fact that there's no ADFs stored

Send feedback about...

Tango Java API
Tango Java API