/// <summary>
        /// Runs a localization session on the specific <see cref="SpatialCoordinateSystemParticipant"/>'s connected peer, followed
        /// by creating a persisted WorldAnchor-based <see cref="ISpatialCoordinate"/> based on the located coordinate.
        /// </summary>
        /// <param name="participant">The participant to use to initiate the remote localization sessions.</param>
        /// <param name="spatialLocalizerId">The ID of the <see cref="ISpatialLocalizer"/> to use
        /// for discovering a spatial coordinate.</param>
        /// <param name="settings">The settings to pass to the remote localizer.</param>
        public async void RunRemoteLocalizationWithWorldAnchorPersistence(SpatialCoordinateSystemParticipant participant, Guid spatialLocalizerId, ISpatialLocalizationSettings settings)
        {
            // If the initial request to restore a coordinate from a WorldAnchor hasn't completed, wait for that to complete first.
            if (participantLocalizationTasks.TryGetValue(participant, out Task <bool> currentTask))
            {
                await currentTask;
            }

            // Request localization using the specific localizer and settings, and wait for that localization to complete.
            participantLocalizationTasks[participant] = currentTask = SpatialCoordinateSystemManager.Instance.RunRemoteLocalizationAsync(participant.SocketEndpoint, spatialLocalizerId, settings);
            bool localizationSucceeded = await currentTask;

            if (localizationSucceeded)
            {
                // Once the specific localizer has found a shared coordinate, ask the WorldAnchorSpatialLocalizer
                // to create a WorldAnchor-based coordinate at the same location, and persist that coordinate across sessions.
                participantLocalizationTasks[participant] = currentTask = SpatialCoordinateSystemManager.Instance.RunRemoteLocalizationAsync(participant.SocketEndpoint, WorldAnchorSpatialLocalizer.Id, new WorldAnchorSpatialLocalizationSettings
                {
                    Mode           = WorldAnchorLocalizationMode.CreateAnchorAtWorldTransform,
                    AnchorId       = CompositorWorldAnchorId,
                    AnchorPosition = participant.PeerSpatialCoordinateWorldPosition,
                    AnchorRotation = participant.PeerSpatialCoordinateWorldRotation
                });
                await currentTask;
            }
            else
            {
                Debug.LogError($"Remote localization failed on device {participant.SocketEndpoint.Address} for spatial localizer {spatialLocalizerId}");
            }
        }
Beispiel #2
0
        private bool TryCleanupExistingLocalizationSession(SpatialCoordinateSystemParticipant participant)
        {
            bool succeeded = true;
            LocalizationSessionDetails sessionToCancel = null;

            lock (localizationLock)
            {
                if (currentLocalizationSession != null)
                {
                    // When connecting to the StationaryCameraBroadcaster within the editor and performing spatial coordinate sharing through it,
                    // both sessions are running within the editor. Completing one part of the session will leave a completed task assigned to
                    // the remote participant within the same session. That session should be cleaned up here to allow the local session
                    // to start.
                    if (currentLocalizationSession.Participant == participant || currentLocalizationSession.CompletionSource.Task.IsCompleted)
                    {
                        sessionToCancel            = currentLocalizationSession;
                        currentLocalizationSession = null;
                    }
                    else
                    {
                        succeeded = false;
                    }
                }
            }

            if (sessionToCancel != null)
            {
                DebugLog($"Cancelling spatial localization session for participant: {participant?.NetworkConnection?.ToString() ?? "Unknown"}");
                sessionToCancel.Session.Cancel();
                sessionToCancel.Session.Dispose();
                sessionToCancel.CompletionSource.TrySetResult(false);
            }

            return(succeeded);
        }
Beispiel #3
0
        private void OnConnected(INetworkConnection connection)
        {
            if (participants.TryGetValue(connection, out var existingParticipant))
            {
                Debug.LogWarning("SpatialCoordinateSystemParticipant connected that already existed.");
                return;
            }

            DebugLog($"Creating new SpatialCoordinateSystemParticipant, NetworkConnection: {connection.ToString()}, DebugLogging: {debugLogging}");

            SpatialCoordinateSystemParticipant participant = new SpatialCoordinateSystemParticipant(connection, debugVisual, debugVisualScale);

            participants[connection]     = participant;
            participant.ShowDebugVisuals = showDebugVisuals;
            participant.SendSupportedLocalizersMessage(connection, localizers.Keys);

            if (ParticipantConnected == null)
            {
                DebugLog($"No ParticipantConnected event handlers exist");
            }
            else
            {
                DebugLog($"Invoking ParticipantConnected event");
                ParticipantConnected.Invoke(participant);
            }
        }
        private void OnConnected(SocketEndpoint endpoint)
        {
            if (participants.TryGetValue(endpoint, out var existingParticipant))
            {
                Debug.LogWarning("SpatialCoordinateSystemParticipant connected that already existed.");
                return;
            }

            DebugLog($"Creating new SpatialCoordinateSystemParticipant, IPAddress: {endpoint.Address}, DebugLogging: {debugLogging}");

            SpatialCoordinateSystemParticipant participant = new SpatialCoordinateSystemParticipant(endpoint, debugVisual, debugVisualScale);

            participants[endpoint]       = participant;
            participant.ShowDebugVisuals = showDebugVisuals;
            participant.SendSupportedLocalizersMessage(endpoint, localizers.Keys);

            if (ParticipantConnected == null)
            {
                DebugLog($"No ParticipantConnected event handlers exist");
            }
            else
            {
                DebugLog($"Invoking ParticipantConnected event");
                ParticipantConnected.Invoke(participant);
            }
        }
Beispiel #5
0
 private void NetworkManagerConnected(INetworkConnection connection)
 {
     // Restart the timeline at 0 each time we reconnect to the HoloLens
     timestampStopwatch          = Stopwatch.StartNew();
     sharedCoordinateParticipant = null;
     currentConnection           = connection;
 }
        private void OnConnected(SocketEndpoint endpoint)
        {
            if (participants.ContainsKey(endpoint))
            {
                Debug.LogWarning("SpatialCoordinateSystemParticipant connected that already existed");
                return;
            }

            DebugLog($"Creating new SpatialCoordinateSystemParticipant, IPAddress: {endpoint.Address}, DebugLogging: {debugLogging}");

            SpatialCoordinateSystemParticipant participant = new SpatialCoordinateSystemParticipant(endpoint, debugVisual, debugVisualScale);

            participants[endpoint]       = participant;
            participant.ShowDebugVisuals = showDebugVisuals;

            if (ParticipantConnected == null)
            {
                Debug.LogWarning("Participant created, but no connection listeners were found");
                return;
            }

            participant.SendSupportedLocalizersMessage(endpoint, localizers.Keys);

            DebugLog($"Invoking ParticipantConnected event");
            ParticipantConnected.Invoke(participant);
        }
        private async void OnParticipantConnected(SpatialCoordinateSystemParticipant participant)
        {
            DebugLog($"Waiting for the set of supported localizers from connected participant {participant.SocketEndpoint.Address}");

            // When a remote participant connects, get the set of ISpatialLocalizers that peer
            // supports. This is asynchronous, as it comes across the network.
            ISet <Guid> peerSupportedLocalizers = await participant.GetPeerSupportedLocalizersAsync();

            // If there are any supported localizers, find the first configured localizer in the
            // list that supports that type. If and when one is found, use it to perform localization.
            if (peerSupportedLocalizers != null)
            {
                DebugLog($"Received a set of {peerSupportedLocalizers.Count} supported localizers");

                if (SpatialLocalizationInitializationSettings.IsInitialized &&
                    TryRunLocalization(SpatialLocalizationInitializationSettings.Instance.PrioritizedInitializers, peerSupportedLocalizers, participant))
                {
                    // Succeeded at using a custom localizer specified by the app.
                    return;
                }

                if (TryRunLocalization(defaultSpatialLocalizationInitializers, peerSupportedLocalizers, participant))
                {
                    // Succeeded at using one of the default localizers from the prefab.
                    return;
                }

                Debug.LogWarning($"None of the configured LocalizationInitializers were supported by the connected participant, localization will not be started");
            }
            else
            {
                Debug.LogWarning($"No supported localizers were received from the participant, localization will not be started");
            }
        }
 private void TcpConnectionManager_OnConnected(SocketEndpoint endpoint)
 {
     // Restart the timeline at 0 each time we reconnect to the HoloLens
     timestampStopwatch          = Stopwatch.StartNew();
     sharedCoordinateParticipant = null;
     currentConnection           = endpoint;
 }
        private bool TryCleanupExistingLocalizationSession(SpatialCoordinateSystemParticipant participant)
        {
            bool succeeded = true;
            LocalizationSessionDetails sessionToCancel = null;

            lock (localizationLock)
            {
                if (currentLocalizationSession != null)
                {
                    if (currentLocalizationSession.Participant == participant)
                    {
                        sessionToCancel            = currentLocalizationSession;
                        currentLocalizationSession = null;
                    }
                    else
                    {
                        succeeded = false;
                    }
                }
            }

            if (sessionToCancel != null)
            {
                DebugLog($"Cancelling spatial localization session for participant: {participant?.SocketEndpoint?.Address ?? "Unknown"}");
                sessionToCancel.Session.Cancel();
                sessionToCancel.Session.Dispose();
                sessionToCancel.CompletionSource.TrySetResult(false);
            }

            return(succeeded);
        }
        public override void RunLocalization(SpatialCoordinateSystemParticipant participant)
        {
            SpatialCoordinateSystemManager.Instance.LocalizeAsync(participant.SocketEndpoint, SpatialAnchorsLocalizer.Id, configuration);

            configuration.IsCoordinateCreator = true;
            SpatialCoordinateSystemManager.Instance.RunRemoteLocalizationAsync(participant.SocketEndpoint, SpatialAnchorsLocalizer.Id, configuration);
        }
Beispiel #11
0
        public override void RunLocalization(SpatialCoordinateSystemParticipant participant)
        {
            DebugLog($"Marker-based localization started for: {participant?.SocketEndpoint?.Address ?? "IPAddress unknown"} with marker type {markerType}");

            // Note: We need to send the remote localization message prior to starting marker visual localization. The MarkerVisualSpatialLocalizer won't return until localization has completed.
            SpatialCoordinateSystemManager.Instance.RunRemoteLocalizationAsync(participant.SocketEndpoint, PeerSpatialLocalizerId, new MarkerVisualDetectorLocalizationSettings());
            SpatialCoordinateSystemManager.Instance.LocalizeAsync(participant.SocketEndpoint, LocalSpatialLocalizerId, new MarkerVisualLocalizationSettings());
        }
 private void OnParticipantConnected(SpatialCoordinateSystemParticipant participant)
 {
     DebugLog($"Participant connected: {participant?.NetworkConnection?.ToString() ?? "Unknown NetworkConnection"}");
     if (currentParticipant != null)
     {
         DebugLog("Participant was already registered when new participant connected");
     }
     currentParticipant = participant;
 }
 private void OnParticipantDisconnected(SpatialCoordinateSystemParticipant participant)
 {
     DebugLog($"Participant disconnected: {participant?.NetworkConnection?.ToString() ?? "Unknown NetworkConnection"}");
     if (currentParticipant == null)
     {
         DebugLog("No participant was registered when a participant disconnected");
     }
     currentParticipant = null;
 }
 private void OnParticipantConnected(SpatialCoordinateSystemParticipant participant)
 {
     // When a new participant connects, send a request to re-load the shared spatial coordinate world anchor.
     participantLocalizationTasks.Add(participant, SpatialCoordinateSystemManager.Instance.RunRemoteLocalizationAsync(participant.SocketEndpoint, WorldAnchorSpatialLocalizer.Id, new WorldAnchorSpatialLocalizationSettings
     {
         Mode     = WorldAnchorLocalizationMode.LocateExistingAnchor,
         AnchorId = CompositorWorldAnchorId
     }));
 }
Beispiel #15
0
 private void OnParticipantConnected(SpatialCoordinateSystemParticipant participant)
 {
     DebugLog($"Participant connected: {participant?.SocketEndpoint?.Address ?? "IPAddress unknown"}");
     if (currentParticipant != null)
     {
         DebugLog("Participant was already registered when new participant connected");
     }
     currentParticipant = participant;
 }
 private void OnParticipantConnected(SpatialCoordinateSystemParticipant participant)
 {
     DebugLog($"Participant connected: {participant?.SocketEndpoint?.Address ?? "IPAddress unknown"}");
     if (currentParticipant != null)
     {
         Debug.LogError("Unexpected existing participant when another participant connected");
     }
     currentParticipant = participant;
 }
Beispiel #17
0
 private void OnParticipantDisconnected(SpatialCoordinateSystemParticipant participant)
 {
     DebugLog($"Participant disconnected: {participant?.SocketEndpoint?.Address ?? "IPAddress unknown"}");
     if (currentParticipant == null)
     {
         DebugLog("No participant was registered when a participant disconnected");
     }
     currentParticipant = null;
 }
        private async Task <bool> TryRunLocalizationImplAsync(SpatialCoordinateSystemParticipant participant)
        {
            DebugLog($"Marker-based localization started for: {participant?.SocketEndpoint?.Address ?? "IPAddress unknown"} with marker type {markerType}");

            // Note: We need to send the remote localization message prior to starting marker visual localization. The MarkerVisualSpatialLocalizer won't return until localization has completed.
            Task <bool> remoteTask = SpatialCoordinateSystemManager.Instance.RunRemoteLocalizationAsync(participant.SocketEndpoint, PeerSpatialLocalizerId, new MarkerVisualDetectorLocalizationSettings());
            Task <bool> localTask  = SpatialCoordinateSystemManager.Instance.LocalizeAsync(participant.SocketEndpoint, LocalSpatialLocalizerId, new MarkerVisualLocalizationSettings());
            await Task.WhenAll(remoteTask, localTask);

            bool localSuccess  = await localTask;
            bool remoteSuccess = await remoteTask;

            return(localSuccess && remoteSuccess);
        }
        private async Task <bool> TryRunLocalizationImplAsync(SpatialCoordinateSystemParticipant participant)
        {
            configuration.IsCoordinateCreator = false;
            Task <bool> localTask = SpatialCoordinateSystemManager.Instance.LocalizeAsync(participant.NetworkConnection, SpatialAnchorsLocalizer.Id, configuration);

            configuration.IsCoordinateCreator = true;
            Task <bool> remoteTask = SpatialCoordinateSystemManager.Instance.RunRemoteLocalizationAsync(participant.NetworkConnection, SpatialAnchorsLocalizer.Id, configuration);
            await Task.WhenAll(localTask, remoteTask);

            bool localSuccess  = await localTask;
            bool remoteSuccess = await remoteTask;

            return(localSuccess && remoteSuccess);
        }
        private async Task <bool> ConditionallyRunWorldAnchorLocalizationAsync(SpatialCoordinateSystemParticipant participant)
        {
            var supportedLocalizers = await participant.GetPeerSupportedLocalizersAsync();

            if (!supportedLocalizers.Contains(WorldAnchorSpatialLocalizer.Id))
            {
                return(false);
            }

            return(await SpatialCoordinateSystemManager.Instance.RunRemoteLocalizationAsync(participant.NetworkConnection, WorldAnchorSpatialLocalizer.Id, new WorldAnchorSpatialLocalizationSettings
            {
                Mode = WorldAnchorLocalizationMode.LocateExistingAnchor,
                AnchorId = CompositorWorldAnchorId
            }));
        }
Beispiel #21
0
        private async Task <bool> TryRunLocalizationForParticipantAsync(SpatialCoordinateSystemParticipant participant)
        {
            DebugLog($"Waiting for the set of supported localizers from connected participant {participant.SocketEndpoint.Address}");

            if (!peerSupportedLocalizers.ContainsKey(participant))
            {
                // When a remote participant connects, get the set of ISpatialLocalizers that peer
                // supports. This is asynchronous, as it comes across the network.
                peerSupportedLocalizers[participant] = await participant.GetPeerSupportedLocalizersAsync();
            }

            // If there are any supported localizers, find the first configured localizer in the
            // list that supports that type. If and when one is found, use it to perform localization.
            if (peerSupportedLocalizers.TryGetValue(participant, out var supportedLocalizers) &&
                supportedLocalizers != null)
            {
                DebugLog($"Received a set of {peerSupportedLocalizers.Count} supported localizers");

                var initializers = new List <SpatialLocalizationInitializer>();
                if (SpatialLocalizationInitializationSettings.IsInitialized &&
                    SpatialLocalizationInitializationSettings.Instance.PrioritizedInitializers != null)
                {
                    DebugLog($"Found prioritized spatial localization initializers list in spectator view settings");
                    foreach (var initializer in SpatialLocalizationInitializationSettings.Instance.PrioritizedInitializers)
                    {
                        initializers.Add(initializer);
                    }
                }

                if (defaultSpatialLocalizationInitializers != null)
                {
                    DebugLog($"Found default spatial localization initializers list for spectator view settings");
                    foreach (var initializer in defaultSpatialLocalizationInitializers)
                    {
                        initializers.Add(initializer);
                    }
                }

                return(await TryRunLocalizationWithInitializerAsync(initializers, supportedLocalizers, participant));
            }
            else
            {
                Debug.LogWarning($"No supported localizers were received from the participant, localization will not be started");
            }

            return(false);
        }
        private async Task <bool> TryRunLocalizationForParticipantAsync(SpatialCoordinateSystemParticipant participant)
        {
            DebugLog($"Waiting for the set of supported localizers from connected participant {participant.SocketEndpoint.Address}");

            if (!peerSupportedLocalizers.ContainsKey(participant))
            {
                // When a remote participant connects, get the set of ISpatialLocalizers that peer
                // supports. This is asynchronous, as it comes across the network.
                peerSupportedLocalizers[participant] = await participant.GetPeerSupportedLocalizersAsync();
            }

            // If there are any supported localizers, find the first configured localizer in the
            // list that supports that type. If and when one is found, use it to perform localization.
            if (peerSupportedLocalizers.TryGetValue(participant, out var supportedLocalizers) &&
                supportedLocalizers != null)
            {
                DebugLog($"Received a set of {peerSupportedLocalizers.Count} supported localizers");
                DebugLog($"Using prioritized initializers list from spectator view settings: {SpatialLocalizationInitializationSettings.IsInitialized && SpatialLocalizationInitializationSettings.Instance.PrioritizedInitializers != null}");

                if (SpatialLocalizationInitializationSettings.IsInitialized &&
                    await TryRunLocalizationWithInitializerAsync(SpatialLocalizationInitializationSettings.Instance.PrioritizedInitializers, supportedLocalizers, participant))
                {
                    // Succeeded at using a custom localizer specified by the app.
                    return(true);
                }

                if (await TryRunLocalizationWithInitializerAsync(defaultSpatialLocalizationInitializers, supportedLocalizers, participant))
                {
                    // Succeeded at using one of the default localizers from the prefab.
                    return(true);
                }

                Debug.LogWarning($"None of the configured LocalizationInitializers were supported by the connected participant, localization will not be started");
            }
            else
            {
                Debug.LogWarning($"No supported localizers were received from the participant, localization will not be started");
            }

            return(false);
        }
 public LocalizationSessionDetails(ISpatialLocalizationSession session, SpatialCoordinateSystemParticipant participant)
 {
     this.Session          = session;
     this.Participant      = participant;
     this.CompletionSource = new TaskCompletionSource <bool>();
 }
 /// <inheritdoc />
 public override async Task <bool> TryResetLocalizationAsync(SpatialCoordinateSystemParticipant participant)
 {
     return(await TryRunLocalizationImplAsync(participant));
 }
 private void OnParticipantDisconnected(SpatialCoordinateSystemParticipant participant)
 {
     participantLocalizationTasks.Remove(participant);
 }
 public bool TryGetSpatialCoordinateSystemParticipant(SocketEndpoint connectedEndpoint, out SpatialCoordinateSystemParticipant participant)
 {
     return(participants.TryGetValue(connectedEndpoint, out participant));
 }
        private async Task <bool> RunLocalizationSessionAsync(ISpatialLocalizer localizer, ISpatialLocalizationSettings settings, SpatialCoordinateSystemParticipant participant)
        {
            DebugLog($"Creating localization session: {participant.SocketEndpoint.Address}, {settings.ToString()}, {localizer.ToString()}");
            if (!localizer.TryCreateLocalizationSession(participant, settings, out ISpatialLocalizationSession currentLocalizationSession))
            {
                Debug.LogError($"Failed to create an ISpatialLocalizationSession from localizer {localizer.SpatialLocalizerId}");
                return(false);
            }

            using (currentLocalizationSession)
            {
                DebugLog($"Setting localization session for participant: {participant.SocketEndpoint.Address}, {currentLocalizationSession.ToString()}");
                participant.CurrentLocalizationSession = currentLocalizationSession;

                try
                {
                    DebugLog($"Starting localization: {participant.SocketEndpoint.Address}, {currentLocalizationSession.ToString()}");
                    // Some SpatialLocalizers/SpatialCoordinateServices key off of token cancellation for their logic flow.
                    // Therefore, we need to create a cancellation token even it is never actually cancelled by the SpatialCoordinateSystemManager.
                    using (var localizeCTS = new CancellationTokenSource())
                    {
                        var coordinate = await currentLocalizationSession.LocalizeAsync(localizeCTS.Token);

                        participant.Coordinate = coordinate;
                    }
                }
                finally
                {
                    participant.CurrentLocalizationSession = null;
                }
            }
            currentLocalizationSession = null;
            return(participant.Coordinate != null);
        }
Beispiel #28
0
 private void OnParticipantConnected(SpatialCoordinateSystemParticipant participant)
 {
     currentParticipant = participant;
     TryRunLocalizationForParticipantAsync(currentParticipant).FireAndForget();
 }
Beispiel #29
0
        private async Task <bool> TryRunLocalizationWithInitializerAsync(IList <SpatialLocalizationInitializer> initializers, ISet <Guid> supportedLocalizers, SpatialCoordinateSystemParticipant participant)
        {
            if (initializers == null || supportedLocalizers == null)
            {
                Debug.LogWarning("Did not find a supported localizer/initializer combination.");
                return(false);
            }
            DebugLog($"TryRunLocalizationWithInitializerAsync, initializers:{initializers.Count}, supportedLocalizers:{supportedLocalizers.Count}");

            for (int i = 0; i < initializers.Count; i++)
            {
                if (supportedLocalizers.Contains(initializers[i].PeerSpatialLocalizerId))
                {
                    DebugLog($"Localization initializer {initializers[i].GetType().Name} supported localization with ID {initializers[i].PeerSpatialLocalizerId}, starting localization");
                    bool result = await initializers[i].TryRunLocalizationAsync(participant);
                    if (!result)
                    {
                        Debug.LogError($"Failed to localize experience with participant: {participant.SocketEndpoint.Address}");
                    }
                    else
                    {
                        DebugLog($"Succeeded in localizing experience with participant: {participant.SocketEndpoint.Address}");
                    }

                    return(result);
                }
                else
                {
                    DebugLog($"Localization initializer {initializers[i].GetType().Name} not supported by peer.");
                }
            }

            return(await Task.FromResult(false));
        }
        private async Task <bool> RunLocalizationSessionAsync(ISpatialLocalizer localizer, ISpatialLocalizationSettings settings, SpatialCoordinateSystemParticipant participant)
        {
            if (!TryCleanupExistingLocalizationSession(participant))
            {
                DebugLog("Existing localization session with different participant prevented creating new localization session");
                return(false);
            }

            if (!localizer.TryCreateLocalizationSession(participant, settings, out var localizationSession))
            {
                Debug.LogError($"Failed to create an ISpatialLocalizationSession from localizer {localizer.SpatialLocalizerId}");
                return(false);
            }

            Task <bool> resultTask;
            bool        startSession = false;
            var         localizationSessionDetails = new LocalizationSessionDetails(localizationSession, participant);

            lock (localizationLock)
            {
                if (currentLocalizationSession != null)
                {
                    DebugLog($"Current localization session repopulated after cleanup, localization not performed.");
                    localizationSessionDetails.Session.Dispose();
                    resultTask = Task.FromResult(false);
                }
                else
                {
                    currentLocalizationSession = localizationSessionDetails;
                    localizationSessionDetails.Participant.CurrentLocalizationSession = localizationSessionDetails.Session;
                    resultTask   = localizationSessionDetails.CompletionSource.Task;
                    startSession = true;
                }
            }

            if (startSession)
            {
                await Dispatcher.ScheduleAsync(async() =>
                {
                    try
                    {
                        // Some SpatialLocalizers/SpatialCoordinateServices key off of token cancellation for their logic flow.
                        // Therefore, we need to create a cancellation token even it is never actually cancelled by the SpatialCoordinateSystemManager.
                        using (var localizeCTS = new CancellationTokenSource())
                        {
                            var coordinate = await localizationSessionDetails.Session.LocalizeAsync(localizeCTS.Token);
                            bool succeeded = (coordinate != null);
                            localizationSessionDetails.Session.Dispose();
                            localizationSessionDetails.CompletionSource.TrySetResult(succeeded);

                            if (localizationSessionDetails.Participant.CurrentLocalizationSession == localizationSessionDetails.Session)
                            {
                                localizationSessionDetails.Participant.Coordinate = coordinate;
                                localizationSessionDetails.Participant.CurrentLocalizationSession = null;
                            }
                            else
                            {
                                Debug.LogWarning("Localization session completed but was no longer assigned to the associated participant");
                            }
                        }
                    }
                    catch (OperationCanceledException)
                    {
                        DebugLog("Localization operation cancelled.");
                    }
                    catch (Exception e)
                    {
                        Debug.LogError($"Exception thrown localizing experience: {e.ToString()}");
                    }
                }, CancellationToken.None, true);
            }

            return(await resultTask);
        }