【问题标题】:How to Change ARKit Update Function Frequency (FPS)?如何更改 ARKit 更新函数频率 (FPS)?
【发布时间】:2019-02-17 23:11:13
【问题描述】:

我目前正在努力限制我的 ARKit iOS 应用程序的 CPU 负载。为了做到这一点,我需要限制每秒 session(_ didUpdate: 函数被调用的时间。我尝试更改我的 ARSCNView 的 preferredFramesPerSecond 属性。这确实减慢了传入视频源的 fps,但更新函数仍然被每秒调用疯狂的次数。我的另一个解决方案是使用传入 ARFrame 的 timeStamp 属性并计算上次保存的渲染时间之间的差异。我正在尝试在 Swift Playgrounds 上运行该程序并且无论出于何种原因,在渲染循环中设置 TimeInterval 类型的变量失败。此解决方案适用于普通的 iOS 应用程序。是否有任何适当的方法可以直接设置 ARKit 更新功能的频率?

当前代码:

我的 AR 属性:

private lazy var lastRenderTime = Date().timeIntervalSince1970

private lazy var sceneView: ARSCNView = {
    let sceneView = ARSCNView()
    sceneView.session.delegate = self
    sceneView.preferredFramesPerSecond = 30
    sceneView.debugOptions = [.showFeaturePoints]
    sceneView.translatesAutoresizingMaskIntoConstraints = false
    return sceneView
}()

以及委托实现:

extension MainViewController: ARSessionDelegate {
    func session(_ session: ARSession, didUpdate frame: ARFrame) {
        let timeSinceLastUpdate = lastRenderTime - frame.timestamp

        if timeSinceLastUpdate >= 0.1 || timeSinceLastUpdate < 0 {
            lastRenderTime = frame.timestamp
            // Do Updating Stuff
        }
    }
}

【问题讨论】:

    标签: ios swift arkit


    【解决方案1】:

    所以我遇到了同样的问题,我找到了解决这个问题的好方法。您可以设置一个计时器变量并基于计时器然后在 didUpdate 函数中调用您需要的任何内容。我将在下面提供一些代码示例,我将每 0.5 秒调用一次会话 Didupdate 帧函数。 (你可以改变它以适合任何看起来最好的)

    代码示例:

    //setting up timer variables and functions 
        var time = 0.0
        var timer = Timer()
    
        func startTimer() {
            timer = Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(updateTime), userInfo: nil, repeats: true)
        }
    
        func resetTimer() {
            timer.invalidate()
            time = 0
            startTimer()
        }
    
        @objc func updateTime() {
            if time < 0.5 {
               time += 0.1
            } else {
                resetTimer()
            }
        }
    

    在您的 viewdidload 或 viewwillappear 调用中

    startTimer()
    

    最后在你的 didUpdate 函数中做一个条件语句

    if time != 0.5 {
       return
    } else {
       * your code * 
    }
    

    【讨论】:

    • 您永远不应该依赖计时器来测量时间间隔。只需获取开始日期对象并检查timeIntervalSinceNow 或过去日期的阳性结果Date().timeIntervalSince(startDate)
    • 我认为@LeoDabus 的回答是一个更直接、更可靠的选择。启动和重新初始化计时器会使您的代码难以理解。由于 detectionRequestHandler 处理程序是进行任何更改的主要入口,因此可以简单地区分例如在图像检测中观察/不观察并相应地更改时间跨度。
    猜你喜欢
    • 1970-01-01
    • 2020-01-07
    • 1970-01-01
    • 2014-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多