Argeotrackingstatus和相机跟踪状态可以显示

发布于 2025-02-06 20:28:13 字数 7381 浏览 2 评论 0原文

我正在尝试在UI上显示地理折磨状态和相机跟踪状态。我已经尝试了Func Session(_会话:Arsession,Didupdate Frame:arframe)和Func Session(_会话:arsession,Didchange geotrackingstatus:argeotrackingstatus)以获得GeoTracking state,但它没有显示出来。我还尝试了Func会话(_会话:武器,摄像机ChangeTrackingState摄像头:Arcamera)以显示相机跟踪状态,但没有显示出来。有人可以帮我吗?谢谢。

ContentView

import SwiftUI
import ARKit
import RealityKit

struct ContentView: View {
    @State var viewModel = ARViewContainer.ViewModel()
    
    var body: some View {
        ZStack {
            ARViewContainer(viewModel: $viewModel)
                .ignoresSafeArea(.all)
            VStack(alignment: .leading) {
                Text("Camera State: \(viewModel.cameraTrackingStatus)")
                Text("GeoTracking State: \(viewModel.geoTrackingStatus)")
                Text("Accuracy: \(viewModel.accuracy)")
            }
            .font(.system(size: 20))
            .position(x: 92, y: 36)
        }
    }
}


struct ARViewContainer: UIViewRepresentable {
    
    struct ViewModel {
        var notAvailable = false
        var geoTrackingStatus = ""
        var cameraTrackingStatus = ""
        var accuracy = ""
    }
    
    @Binding var viewModel: ViewModel
    

    let arView = ARView(frame: .zero)
    
    func makeUIView(context: Context) -> ARView {
        if ARGeoTrackingConfiguration.isSupported {
            ARGeoTrackingConfiguration.checkAvailability { available, error in
                if !available {
                    viewModel.notAvailable = true
                    print("GeoTracking is not available at your location")
                }
            }
        } else {
            print("Your Decive support ARGeoTracking")
        }
        
        let config = ARGeoTrackingConfiguration()
        arView.automaticallyConfigureSession = false
        arView.session.run(config)
        context.coordinator.addCoaching()
        return arView
    }
    
    func makeCoordinator() -> Coordiantor {
        Coordiantor(self)
    }
    
    func updateUIView(_ uiView: ARView, context: Context) {
        
    }
    
}


struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

协调员

import ARKit
import RealityKit

class Coordiantor: NSObject, ARSessionDelegate, ARCoachingOverlayViewDelegate {
    
    var parent: ARViewContainer
    
    init(_ parent: ARViewContainer) {
        self.parent = parent
    }
    
    func addCoaching() {
        let coachingOverlay = ARCoachingOverlayView()
        coachingOverlay.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        coachingOverlay.goal = .geoTracking
        coachingOverlay.session = parent.arView.session
        coachingOverlay.delegate = self
        parent.arView.addSubview(coachingOverlay)
    }
    
    public func coachingOverlayViewDidRequestSessionReset(_ coachingOverlayView: ARCoachingOverlayView) {
        let config = ARGeoTrackingConfiguration()
        parent.arView.session.run(config, options: [.resetTracking, .removeExistingAnchors])
    }
    
    
    func session(_ session: ARSession, cameraDidChangeTrackingState camera: ARCamera) {
        parent.viewModel.cameraTrackingStatus = camera.trackingState.description
    }
    
    func session(_ session: ARSession, didChange geoTrackingStatus: ARGeoTrackingStatus) {
        switch geoTrackingStatus.state {
            
        case .notAvailable:
            parent.viewModel.geoTrackingStatus = "Not Available"
        case .initializing:
            switch geoTrackingStatus.stateReason {
                
            case .none:
                parent.viewModel.geoTrackingStatus = "No issue reported"
            case .notAvailableAtLocation:
                parent.viewModel.geoTrackingStatus = "Geotracking not available at this location"
            case .needLocationPermissions:
                parent.viewModel.geoTrackingStatus = "Geotracking requires location permission"
            case .worldTrackingUnstable:
                parent.viewModel.geoTrackingStatus = "World tracking is not stable"
            case .waitingForLocation:
                parent.viewModel.geoTrackingStatus = "ARKit waiting for location"
            case .waitingForAvailabilityCheck:
                parent.viewModel.geoTrackingStatus = "ARKit waiting for availablity check"
            case .geoDataNotLoaded:
                parent.viewModel.geoTrackingStatus = "Geo data not loaded, please check network connection"
            case .devicePointedTooLow:
                parent.viewModel.geoTrackingStatus = "Camera pointed too low"
            case .visualLocalizationFailed:
                parent.viewModel.geoTrackingStatus = "Visual localization failed"
            @unknown default:
                break
            }
        case .localizing:
            switch geoTrackingStatus.stateReason {
                
            case .none:
                parent.viewModel.geoTrackingStatus = "No issue reported"
            case .notAvailableAtLocation:
                parent.viewModel.geoTrackingStatus = "Geotracking not available at this location"
            case .needLocationPermissions:
                parent.viewModel.geoTrackingStatus = "Geotracking requires location permission"
            case .worldTrackingUnstable:
                parent.viewModel.geoTrackingStatus = "World tracking is not stable"
            case .waitingForLocation:
                parent.viewModel.geoTrackingStatus = "ARKit waiting for location"
            case .waitingForAvailabilityCheck:
                parent.viewModel.geoTrackingStatus = "ARKit waiting for availablity check"
            case .geoDataNotLoaded:
                parent.viewModel.geoTrackingStatus = "Geo data not loaded, please check network connection"
            case .devicePointedTooLow:
                parent.viewModel.geoTrackingStatus = "Camera pointed too low"
            case .visualLocalizationFailed:
                parent.viewModel.geoTrackingStatus = "Visual localization failed"
            @unknown default:
                break
            }
        case .localized:
            switch geoTrackingStatus.accuracy {
                
            case .undetermined:
                parent.viewModel.accuracy = "Undetermined"
            case .low:
                parent.viewModel.accuracy = "Low"
            case .medium:
                parent.viewModel.accuracy = "Medium"
            case .high:
                parent.viewModel.accuracy = "High"
            @unknown default:
                break
            }
        @unknown default:
            break
        }
    }
    
}

    
extension ARCamera.TrackingState: CustomStringConvertible {
    public var description: String {
        switch self {
        case .notAvailable:
            return "Not Available"
        case .limited(.initializing):
            return "Limited-Initializing"
        case .limited(.excessiveMotion):
            return "Limited-Excessive motion"
        case .limited(.insufficientFeatures):
            return "Limited-Insufficient image input"
        case .limited(.relocalizing):
            return "Relocalizing"
        case .normal:
            return "Normal"
        case .limited:
            return "Unspecified Reason"
        }
    }
}

I'm trying to display geotracking status and camera tracking state on UI. I've tried func session(_ session: ARSession, didUpdate frame: ARFrame) and func session(_ session: ARSession, didChange geoTrackingStatus: ARGeoTrackingStatus) to obtain geotracking state, but it showed nothing. I also tried func session(_ session: ARSession, cameraDidChangeTrackingState camera: ARCamera) to display camera tracking state, but it showed nothing neither. Could someone help me out? Thanks.

ContentView

import SwiftUI
import ARKit
import RealityKit

struct ContentView: View {
    @State var viewModel = ARViewContainer.ViewModel()
    
    var body: some View {
        ZStack {
            ARViewContainer(viewModel: $viewModel)
                .ignoresSafeArea(.all)
            VStack(alignment: .leading) {
                Text("Camera State: \(viewModel.cameraTrackingStatus)")
                Text("GeoTracking State: \(viewModel.geoTrackingStatus)")
                Text("Accuracy: \(viewModel.accuracy)")
            }
            .font(.system(size: 20))
            .position(x: 92, y: 36)
        }
    }
}


struct ARViewContainer: UIViewRepresentable {
    
    struct ViewModel {
        var notAvailable = false
        var geoTrackingStatus = ""
        var cameraTrackingStatus = ""
        var accuracy = ""
    }
    
    @Binding var viewModel: ViewModel
    

    let arView = ARView(frame: .zero)
    
    func makeUIView(context: Context) -> ARView {
        if ARGeoTrackingConfiguration.isSupported {
            ARGeoTrackingConfiguration.checkAvailability { available, error in
                if !available {
                    viewModel.notAvailable = true
                    print("GeoTracking is not available at your location")
                }
            }
        } else {
            print("Your Decive support ARGeoTracking")
        }
        
        let config = ARGeoTrackingConfiguration()
        arView.automaticallyConfigureSession = false
        arView.session.run(config)
        context.coordinator.addCoaching()
        return arView
    }
    
    func makeCoordinator() -> Coordiantor {
        Coordiantor(self)
    }
    
    func updateUIView(_ uiView: ARView, context: Context) {
        
    }
    
}


struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

Coordinator

import ARKit
import RealityKit

class Coordiantor: NSObject, ARSessionDelegate, ARCoachingOverlayViewDelegate {
    
    var parent: ARViewContainer
    
    init(_ parent: ARViewContainer) {
        self.parent = parent
    }
    
    func addCoaching() {
        let coachingOverlay = ARCoachingOverlayView()
        coachingOverlay.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        coachingOverlay.goal = .geoTracking
        coachingOverlay.session = parent.arView.session
        coachingOverlay.delegate = self
        parent.arView.addSubview(coachingOverlay)
    }
    
    public func coachingOverlayViewDidRequestSessionReset(_ coachingOverlayView: ARCoachingOverlayView) {
        let config = ARGeoTrackingConfiguration()
        parent.arView.session.run(config, options: [.resetTracking, .removeExistingAnchors])
    }
    
    
    func session(_ session: ARSession, cameraDidChangeTrackingState camera: ARCamera) {
        parent.viewModel.cameraTrackingStatus = camera.trackingState.description
    }
    
    func session(_ session: ARSession, didChange geoTrackingStatus: ARGeoTrackingStatus) {
        switch geoTrackingStatus.state {
            
        case .notAvailable:
            parent.viewModel.geoTrackingStatus = "Not Available"
        case .initializing:
            switch geoTrackingStatus.stateReason {
                
            case .none:
                parent.viewModel.geoTrackingStatus = "No issue reported"
            case .notAvailableAtLocation:
                parent.viewModel.geoTrackingStatus = "Geotracking not available at this location"
            case .needLocationPermissions:
                parent.viewModel.geoTrackingStatus = "Geotracking requires location permission"
            case .worldTrackingUnstable:
                parent.viewModel.geoTrackingStatus = "World tracking is not stable"
            case .waitingForLocation:
                parent.viewModel.geoTrackingStatus = "ARKit waiting for location"
            case .waitingForAvailabilityCheck:
                parent.viewModel.geoTrackingStatus = "ARKit waiting for availablity check"
            case .geoDataNotLoaded:
                parent.viewModel.geoTrackingStatus = "Geo data not loaded, please check network connection"
            case .devicePointedTooLow:
                parent.viewModel.geoTrackingStatus = "Camera pointed too low"
            case .visualLocalizationFailed:
                parent.viewModel.geoTrackingStatus = "Visual localization failed"
            @unknown default:
                break
            }
        case .localizing:
            switch geoTrackingStatus.stateReason {
                
            case .none:
                parent.viewModel.geoTrackingStatus = "No issue reported"
            case .notAvailableAtLocation:
                parent.viewModel.geoTrackingStatus = "Geotracking not available at this location"
            case .needLocationPermissions:
                parent.viewModel.geoTrackingStatus = "Geotracking requires location permission"
            case .worldTrackingUnstable:
                parent.viewModel.geoTrackingStatus = "World tracking is not stable"
            case .waitingForLocation:
                parent.viewModel.geoTrackingStatus = "ARKit waiting for location"
            case .waitingForAvailabilityCheck:
                parent.viewModel.geoTrackingStatus = "ARKit waiting for availablity check"
            case .geoDataNotLoaded:
                parent.viewModel.geoTrackingStatus = "Geo data not loaded, please check network connection"
            case .devicePointedTooLow:
                parent.viewModel.geoTrackingStatus = "Camera pointed too low"
            case .visualLocalizationFailed:
                parent.viewModel.geoTrackingStatus = "Visual localization failed"
            @unknown default:
                break
            }
        case .localized:
            switch geoTrackingStatus.accuracy {
                
            case .undetermined:
                parent.viewModel.accuracy = "Undetermined"
            case .low:
                parent.viewModel.accuracy = "Low"
            case .medium:
                parent.viewModel.accuracy = "Medium"
            case .high:
                parent.viewModel.accuracy = "High"
            @unknown default:
                break
            }
        @unknown default:
            break
        }
    }
    
}

    
extension ARCamera.TrackingState: CustomStringConvertible {
    public var description: String {
        switch self {
        case .notAvailable:
            return "Not Available"
        case .limited(.initializing):
            return "Limited-Initializing"
        case .limited(.excessiveMotion):
            return "Limited-Excessive motion"
        case .limited(.insufficientFeatures):
            return "Limited-Insufficient image input"
        case .limited(.relocalizing):
            return "Relocalizing"
        case .normal:
            return "Normal"
        case .limited:
            return "Unspecified Reason"
        }
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

甚是思念 2025-02-13 20:28:14

我认为您忘了分配parent.arview.session.delegate = self在您的协调器中,因此以下功能永远不会被调用

func session(_ session: ARSession, didChange geoTrackingStatus: ARGeoTrackingStatus) {
}

I think you forgot to assign parent.arView.session.delegate = self in your coordinator so the following function is never called

func session(_ session: ARSession, didChange geoTrackingStatus: ARGeoTrackingStatus) {
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文