WorldTrackingProvider's queryDeviceAnchor is not giving correct deviceAnchor

I'm constructing a RealityView where I'd like to display content in front of user's face. When testing, I found that the deviceAnchor I initially get was wrong, so I implement following code to wait until the deviceAnchor I get from worldTrackingProvider has the correct value:

private let arkitSession = ARKitSession()
private let worldTrackingProvider = WorldTrackingProvider()

var body: some View {
        RealityView { content, attachments in

            Task {
                do {
// init worldTrackingProvider
                    try await arkitSession.run([worldTrackingProvider])

// wait until deviceAnchor returns correct info
                    var deviceAnchor : DeviceAnchor?
// continuously get deviceAnchor and check until it's valid
                   while (deviceAnchor == nil || !checkDeviceAnchorValid(Transform(matrix: deviceAnchor!.originFromAnchorTransform).translation)) {
                       deviceAnchor = worldTrackingProvider.queryDeviceAnchor(atTimestamp: CACurrentMediaTime())
                    }
                    let cameraTransform = Transform(matrix: deviceAnchor!.originFromAnchorTransform)

                  // ...codes that update my entity's translation

                } catch {
                    print("Error: \(error)")
                }
            }
        } 
    }
    
    private func checkDeviceAnchorValid(_ translation: SIMD3<Float>) -> Bool {
      // codes that check if the `deviceAnchor` has a valid translation.
    }

However, I found that sometimes I can't get out from the while loop defined above. Not because my rules inside checkDeviceAnchorValid func are too strict, but because the translation I get from deviceAnchor is always invalid(it is [0,0,0] and never changed)

Why is this happening? Is this a known issue? I wonder if I can get recalled when the worldTrackingProvider returns the correct deviceAnchor,

Hello,

Could you provide a focused sample project that reproduces the issue?

Hello gchiste, Thanks for the reply!

Please create a new visionOS app from xcode, replace the code in ImmersiveView with the following code, and change the preferred Default Scene Session Role to Immersive Space Application Session Role.


//

//  ImmersiveView.swift

//  deviceAnchorSample


//



import SwiftUI

import RealityKit

import ARKit



struct ImmersiveView: View {

    var body: some View {

        RealityView { content in

            Task {

                do {

                    try await arkitSession.run([worldTrackingProvider])

                    var deviceAnchor : DeviceAnchor?

                    while (deviceAnchor == nil || !checkDeviceAnchorValid(Transform(matrix: deviceAnchor!.originFromAnchorTransform).translation)) {

                        deviceAnchor = worldTrackingProvider.queryDeviceAnchor(atTimestamp: CACurrentMediaTime())

                    }

                    let cameraTransform = Transform(matrix: deviceAnchor!.originFromAnchorTransform)

//                    attachmentEntity.transform.translation = cameraTransform.translation + [0, 0.05, -1]

                } catch {

                    print("Error: \(error)")

                }

            }

        }

    }

    

    private func checkDeviceAnchorValid(_ translation: SIMD3<Float>) -> Bool {

        // device anchor's x and z should be almost zero, with y in the valid range of a human being's height

        print("deviceAnchor's translation:\(translation)")

        return abs(translation.x) < 0.1 && abs(translation.z) < 0.1 && translation.y > 0.2 && translation.y < 3

    }

    

    // MARK: Private



    private let arkitSession = ARKitSession()

    private let worldTrackingProvider = WorldTrackingProvider()

}



#Preview {

    ImmersiveView()

        .previewLayout(.sizeThatFits)

}//

When running, look for logs that start with deviceAnchor's translation:.The dead loop problem cannot be reproduced stably, But it did happen more than once.

Notice the jump change of the translation value, I think the main issue is that there are no callbacks or flags indicating the worldTrackingProvider is initiated.

I'm on Xcode 15.2(15C500b), and visionOS 1.0 (21N305) simulator

WorldTrackingProvider's queryDeviceAnchor is not giving correct deviceAnchor
 
 
Q