Google Cloud Anchors & ARCoreExtensions integration

Project explanation:
I’m trying to set up Google Cloud Anchors using this API (although it’s already deprecated, am already using the new ARCore API). I started off by using one of Dilmer Valencios’s tutorials (the video tutorial and the most important scripts) but it’s already 2 years old and therefore rather outdated. In his tutorial, he makes use of an additional Google Package (ARCoreExtensions), which I downloaded from their git repo.

Problem:
The problem I’m having is after calling HostAnchor() in ARCloudAnchorManager, it silently breaks when requesting the quality of the “FeatureMap”, with a camera pose (position & rotation) as function parameter. It does not log the statement at line 21.

When logging anchor.sessionID, it returns “00000000-0000-0000-0000-000000000000” and in several of the anchor hosting methods (for example in HostCloudAnchor()), there is a check for ARCoreExtensions._instance.currentARCoreSessionHandle == IntPtr.Zero.
I imagine that the SessionHandle is the same as sessionID. So that would mean the AR Session does not exist, while at the same time I am able to place AR objects perfectly fine.

The AR Session object I have is the only one in the scene so it’s not an issue of multiple instances clashing.

public void QueueAnchor(ARAnchor anchor)
    {
        _pendingHostAnchor = anchor;
        Logger.Log($"Received queuing request for {anchor.trackableId}.");
    }

    public void HostAnchor()
    {
        Logger.Log($"ARAnchorManager null?: {_arAnchorManager == null}. Anchor null?: {_pendingHostAnchor == null}.");

        Pose camPose = GetCameraPose();
        Logger.Log($"Campose: {camPose}.");

        FeatureMapQuality quality = FeatureMapQuality.NotProvided;
        Logger.Log($"Initialized quality map: {quality}.");
        quality = _arAnchorManager.EstimateFeatureMapQualityForHosting(camPose);
        Logger.Log($"Quality of feature map is: {quality}.");
        Logger.Log($"Pending host anchor: {_pendingHostAnchor.trackableId}.");

        _cloudAnchor = _arAnchorManager.HostCloudAnchor(_pendingHostAnchor, 1);
        Logger.Log($"Resulted cloud anchor: {_cloudAnchor.trackableId}.");

        if (_cloudAnchor == null)
        {
            Logger.Log($"Failed to host cloud anchor ({anchorIDToResolve}) at HostAnchor()");
        }
        else
        {
            Logger.Log($"Anchor hosting in progress = true");
            _anchorHostInProgress = true;
        }

        Resolve();
    }

The function called in HostAnchor() at line 20

public static ARCloudAnchor HostCloudAnchor(
            this ARAnchorManager anchorManager, ARAnchor anchor, int ttlDays)
        {
            if (ARCoreExtensions._instance.currentARCoreSessionHandle == IntPtr.Zero ||
                anchor == null || anchor.nativePtr == IntPtr.Zero ||
                anchor.AnchorHandle() == IntPtr.Zero)
            {
                return null;
            }
            if (ttlDays <= 0 || ttlDays > 365)
            {
                Debug.LogErrorFormat("Failed to host a Cloud Anchor with invalid TTL {0}. " +
                    "The lifetime of the anchor in days must be positive, " +
                    "the maximum allowed value is 1 when using an API Key to authenticate with " +
                    "the ARCore Cloud Anchor service, otherwise the maximum allowed value is 365.",
                    ttlDays);
                return null;
            }

            // Create the underlying ARCore Cloud Anchor with given ttlDays.
            IntPtr cloudAnchorHandle = SessionApi.HostCloudAnchor(
                ARCoreExtensions._instance.currentARCoreSessionHandle,
                anchor.AnchorHandle(), ttlDays);
            if (cloudAnchorHandle == IntPtr.Zero)
            {
                return null;
            }

            // Create the GameObject that is the Cloud Anchor.
            ARCloudAnchor cloudAnchor =
                new GameObject(_cloudAnchorName).AddComponent<ARCloudAnchor>();
            if (cloudAnchor)
            {
                cloudAnchor.SetAnchorHandle(cloudAnchorHandle);
            }

            // Parent the new Cloud Anchor to the session origin.
            cloudAnchor.transform.SetParent(
                ARCoreExtensions._instance.SessionOrigin.trackablesParent, false);

            return cloudAnchor;
        }

I’m quite sure my application is connected to the Google services, as the hosting requests are shown in the Google dashboard:
8724282--1179543--upload_2023-1-11_16-48-35.png8724282--1179543--upload_2023-1-11_16-48-35.png

Expected to happen:
What I’m expecting to happen is an ID being returned other than the collection of zeroes mentioned earlier, so it passes the “IntPtr.zero” check, and after that, move on with the hosting process.

API versions etc:
Unity: 2023.1.0a16 (at first 2021.3.15f1, then I tried the Google samples project which required the 2023 version)
ARFoundation: 5.1.0-pre.2
ARCore: 5.1.0-pre.2
ARCore Extensions: 1.35.0

Please let me know if I should add more information or if I should try to explain something more clearly.

Hi @Meijer ,

This is the page that we point folks to if they want to integrate Cloud Anchors. Not sure if you have seen this one: Getting started with ARCore Extensions for AR Foundation  |  Google for Developers

If you continue to have issues I would recommend reaching out to Google as well by creating an issue on their arcore-unity-extensions repo

@andyb-unity
As per this page https://developers.google.com/ar/develop/unity-arf/getting-started-extensions
ARCore Extensions requires AR Session Origin, with AR Foundation 5.0.4 AR Session Origin has replaced with XR Origin and can not assigned to Session Origin of ARCore Extensions. How to resolve this?

  • Session Origin: Use your scene’s AR Session Origin.

8863620--1209627--upload_2023-3-9_16-7-35.png

As far as I know Google has not yet upgraded to AR Foundation 5. You are locked into AR Foundation 4.2 for now if you are using ARCore Extensions.

Please read this: https://developers.google.com/ar/develop/unity-arf/update-to-ar-foundation-5

1 Like

hello, could you explain how to use OAuth2 token that is generated on Google Cloud Service ?

1 Like