Skip to main content

Map-based Relocalization Sample

This sample will use map-based relocalization to find the shared anchor from a map, and show a cube on the shared anchor position on successful relocalization. After the shared anchor is found, the SDK will move the AR origin (0, 0, 0) to the position of the shared anchor. For map-based shared anchors, this location in the real world space is the place where you first started scanning the map.

Understanding the Scene

Scene Hierarchy

Let's start by looking at how the scene is setup. This is the hierarchy of game objects in the sample scene.

We can see the usual AR Session Origin and AR Session objects in the hierarchy provided from AR Foundation. Apps built with Pretia SDK is very similar compared to the usual AR apps built with standard AR Foundation components. The relocalization features in Pretia SDK is built on top of Unity's XR Subsystem to have good interoperability with AR Foundation.

AR Shared Anchor Manager

On the AR Session Origin object, there is a component called ARSharedAnchorManager. This component is provided by the SDK and is the one responsible to manage the relocalization process. From the inspector, we can see that there are several fields that we can modify. For this tutorial, we are only interested in Map Selection. We can keep AR Tracked Image Manager empty because we are not using image-based relocalization feature.

Note: There is an option to run relocalization automatically, but it is not used in this sample. Please refer to the ARSharedAnchorManager API Reference to learn more about it.

Map Selection

Assigning Map Selection will set the default map selection strategy used for map-based relocalization. Pretia SDK offers two default map selection strategy, which is DirectMapSelection and CriteriaBasedMapSelection (Refer to MapSelection to learn more).

DirectMapSelection will simply returns the Map Key assigned in the asset. You can grab the map key from Developer Console.

Starting/Stopping Relocalization

On the SceneController object, there is a component called MapBasedRelocSceneController. This script will start/stop the relocalization when a button is pressed. Below are the related APIs to start and stop relocalization.

// Grab an instance of ARSharedAnchorManager
private ARSharedAnchorManager _sharedAnchorManager;

// Start map-based relocalization using the default map selection strategy
// set in the inspector
_sharedAnchorManager.StartCloudMapRelocalization();

// Alternatively, you can skip the default map selection strategy and
// start map-based relocalization directly using mapKey
string mapKey = "XXXX"
_sharedAnchorManager.StartCloudMapRelocalization(mapKey);

// Stop any running relocalization process and
// reset the shared anchor status
_sharedAnchorManager.ResetSharedAnchor();

Handling Events

Let's move our focus to ARContentHandler and ARContents objects. We can see that ARContents is disabled in the hierarchy. And this is because we want to enable it only when relocalization is successful. To accomplish this, there is a component in ARContentHandler that will listen to OnRelocalized event from ARSharedAnchorManager, and enable it.

public delegate void RelocalizedEvent();
public event RelocalizedEvent OnRelocalized;

To have finer control on responding to the shared anchor behaviour, the SDK provides a callback for when the shared anchor state has changed. A shared anchor can be in one of these four states, Stopped, Initializing, Relocalizing, and Relocalized. The component in StatusUpdater object is responsible for updating the status text in the UI canvas whenever it changes.

public delegate void RelocalizationStateChanged(RelocalizationState newState);
public event RelocalizationStateChanged OnRelocalizationStateChanged;

// Alternatively, you can get the current shared anchor state from RelocalizationState
public RelocalizationState RelocalizationState { get; }

public enum RelocalizationState
{
Stopped = 0,
Initializing = 1,
Relocalizing = 2,
Relocalized = 3
}

It is also important to know and handle failure cases, so the SDK provides these events as well. The component in ErrorHandler will show an error message in the UI canvas when an error has occured.

public delegate void SharedAnchorSubsystemException(Exception e);
public event SharedAnchorSubsystemException OnException;

Relocalization Score

During relocalization, it can be difficult to know whether we are scanning the correct location or not. We provide a relocalization score to help with this process. This score ranges from 0f to 1f: A small value means that the relocalization process is not able to recognize the environment. The closer the score is to 1f, the closer it is to a successful relocalization. Note that this scores varies with the position of the device, so if the score remains low, the user is advised to move from their current position. There is a component in ScoreUpdater that updates the score text in the UI canvas everytime the score changes. Alternatively, you can also get the score from RelocalizationScore field in ARSharedAnchorManager.

public delegate void RelocalizationScoreUpdated(float score);
public event RelocalizationScoreUpdated OnRelocalizationScoreUpdated;

// Alternatively, get the score from RelocalizationScore
public float RelocalizationScore { get; }

Building the Sample

There are some settings we need to do before we can build our application. Please refer to this guide on how to build your application.

Running the Sample

Run the sample on a device, and verify the app's behaviour by scanning the area of the map that you used for the Map Key. You should be able to see a cube on the shared anchor position, which is the location where you first started mapping this map.

After getting to this point, it is time to start adding AR contents to the project. We recommend going through our guide on how to place map contents.