ARCL 1.3.0

ARCL 1.3.0

测试已测试
语言语言 SwiftSwift
许可证 MIT
发布最后发布2019年12月
SPM支持 SPM

Eric InternicolaAndrew HartAaron Brethorst 维护。



ARCL 1.3.0

  • Andrew Hart

ARKit + CoreLocation

CI Status MIT License Pods Version Carthage Compatible

ARKit:利用摄像头和运动数据在你移动时绘制出周围的世界。

CoreLocation:利用 Wi-Fi 和 GPS 数据确定你的全球位置,精度较低。

ARKit + CoreLocation:结合了 AR 的高精度和 GPS 数据的规模。

Points of interest demo Navigation demo

结合这些技术的潜力巨大,可以在许多不同领域产生许多潜在的应用。这个库包含两个主要功能

  • 允许使用现实世界的坐标在 AR 世界中放置项目。
  • 大幅度提升位置精度,通过结合最新的位置数据点以及通过 AR 世界运动的知识。

改进的位置精度目前处于“实验”阶段,但可能是最重要的组件。

因为在这方面以及其他方面仍有工作要做,所以这个项目最好由一个开放的社区来维护,而不仅仅是 GitHub Issues 允许我们的。所以,我正在开设一个任何人都可以加入的 Slack 群组,以讨论这个库及其改进,以及他们自己的工作。

加入 Slack 社区

要求

ARKit 需要 iOS 11,并支持以下设备

  • iPhone 6S 及以上
  • iPhone SE
  • iPad(2017)
  • 所有 iPad Pro 型号

iOS 11 可从苹果开发者网站下载。

用法

这个库包含了 ARKit + CoreLocation 框架,以及一个类似于 Demo 1 的演示应用程序。

务必阅读关于真北校准的部分。

使用 Swift 构建

swift build \
        -Xswiftc "-sdk" -Xswiftc "`xcrun --sdk iphonesimulator --show-sdk-path`" \
        -Xswiftc "-target" -Xswiftc "x86_64-apple-ios12.1-simulator"

使用 Swift Package Manager 设置

使用 CocoaPods 设置

  1. 将以下内容添加到 podfile 中

pod 'ARCL'

  1. 在终端中,切换到您的项目文件夹,然后

pod update

pod install

  1. NSCameraUsageDescriptionNSLocationWhenInUseUsageDescription 添加到 plist 中,并简要说明(请参考示例项目)

手动设置

  1. ARKit+CoreLocation/Source 目录下的所有文件添加到您的项目中。
  2. 导入 ARKit、SceneKit、CoreLocation 和 MapKit。
  3. NSCameraUsageDescriptionNSLocationWhenInUseUsageDescription 添加到 plist 中,并简要说明(请参考示例项目)

快速入门指南

例如,要在伦敦金丝雀码头这样的建筑上放置一个标记,我们将使用 ARCL 构建的类 - SceneLocationView

首先,导入 ARCL 和 CoreLocation,然后声明 SceneLocationView 作为属性

import ARCL
import CoreLocation

class ViewController: UIViewController {
  var sceneLocationView = SceneLocationView()
}

当它处于焦点时,应该调用 sceneLocationView.run(),如果它被中断(例如移动到不同的视图或离开应用程序),则应调用 sceneLocationView.pause()

override func viewDidLoad() {
  super.viewDidLoad()

  sceneLocationView.run()
  view.addSubview(sceneLocationView)
}

override func viewDidLayoutSubviews() {
  super.viewDidLayoutSubviews()

  sceneLocationView.frame = view.bounds
}

在调用run()之后,我们可以添加我们的坐标。ARCL SDK中有一个名为LocationNode的类——3D场景中的一个对象,它具有真正的地理位置和其他一些属性,使得它可以在世界中适当地显示。LocationNode是SceneKit库中的SCNNode的子类,还可以进一步进行子类化。在这个例子中我们将使用一个名为LocationAnnotationNode的子类,我们使用它来在世界中显示一张2D图像,它总是面向我们

let coordinate = CLLocationCoordinate2D(latitude: 51.504571, longitude: -0.019717)
let location = CLLocation(coordinate: coordinate, altitude: 300)
let image = UIImage(named: "pin")!

let annotationNode = LocationAnnotationNode(location: location, image: image)

LocationAnnotationNode也可以使用UIView进行初始化。内部,UIView被转换成了UIImage,因此你无法动态更新内容。然而,此方法允许你轻松地以POI的形式显示复杂的布局。

let coordinate = CLLocationCoordinate2D(latitude: 51.504571, longitude: -0.019717)
let location = CLLocation(coordinate: coordinate, altitude: 300)
let view = UIView() // or a custom UIView subclass

let annotationNode = LocationAnnotationNode(location: location, view: view)

它还可以用CALayer进行初始化。当你想要实时更新内容时可以使用这个方法。

let coordinate = CLLocationCoordinate2D(latitude: 51.504571, longitude: -0.019717)
let location = CLLocation(coordinate: coordinate, altitude: 300)
let layer = CALayer() // or a custom CALayer subclass

let annotationNode = LocationAnnotationNode(location: location, layer: layer)

默认情况下,你设置的图片应该始终显示为其给定的尺寸,例如如果给你一个100x100的图片,它将显示为100x100。这意味着远程标注节点总是以与近距离节点相同的大小显示。如果你希望它们按距离进行缩放,可以将LocationAnnotationNode的scaleRelativeToDistance设置为true

sceneLocationView.addLocationNodeWithConfirmedLocation(locationNode: annotationNode)

有两种方式可以向场景中添加位置节点——使用addLocationNodeWithConfirmedLocation,或者使用addLocationNodeForCurrentPosition,后者将其定位在与世界内设备相同的位置,然后给它一个坐标。

所以,这就完成了。如果你设置了sceneLocationView的边框,现在你应该能看到而是在Canary Wharf上方的针标。

为了在sceneLocationView中被触发的节点时获取通知,你需要在ViewController类中遵守LNTouchDelegate

annotationNodeTouched(node: AnnotationNode)让你可以访问在屏幕上被触摸的节点。AnnotationNode是SCNNode的一个子类,有两个额外的属性:image: UIImage?view: UIView?。这两个属性将根据如何初始化LocationAnnotationNode(使用接受UIImage或UIView的构造函数)来填充。

locationNodeTouched(node: LocationNode)则提供从PolyNode(例如,MKRoute的渲染方向)创建的节点的访问。

class ViewController: UIViewController, LNTouchDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()
        //...
        self.sceneLocationView.locationNodeTouchDelegate = self
        //...
    }

    func annotationNodeTouched(node: AnnotationNode) {
        // Do stuffs with the node instance

        // node could have either node.view or node.image
        if let nodeView = node.view{
            // Do stuffs with the nodeView
            // ...
        }
        if let nodeImage = node.image{
            // Do stuffs with the nodeImage
            // ...
        }
    }

    func locationNodeTouched(node: LocationNode) {
        guard let name = node.tag else { return }
        guard let selectedNode = node.childNodes.first(where: { $0.geometry is SCNBox }) else { return }

        // Interact with the selected node
    }

}

附加功能

库和示例都附带了一组额外的配置功能。它们都有充分的文档说明,一定要看看。

SceneLocationView是ARSCNView的子类。请注意,尽管这让你完全能够在其他方式中使用ARSCNView,你不应该将其委托设置到另一个类。如果你需要使用委托功能,应该子类化SceneLocationView

真北校准

我个人尚未解决的一个问题是,iPhone的真正北方校准在最佳情况下只能达到15度的精度。这对于地图导航来说还可以,但是当在AR世界中放置东西时,它就变成了一个问题。

我相信可以通过使用各种AR技术来解决这个难题——我认为这是一个可以从共同努力中真正受益的领域。

为了提高这个问题,我在库中添加了一些功能,可以调整北方。

  • sceneLocationView.moveSceneHeadingClockwise
  • sceneLocationView.moveSceneHeadingAntiClockwise
  • sceneLocationView.resetSceneHeading

您应该使用这些功能,通过设置sceneLocationView.useTrueNorthfalse,然后在开始之前将设备指向大致的北方,以便它足够接近。当useTrueNorth设置为true(默认值)时,它会不断调整,直到对北方有一个更好的感觉。

在演示应用中,有一个名为adjustNorthByTappingSidesOfScreen的可禁用属性,它访问这些功能,并在启用后,允许用户轻击屏幕的左右两边来调整场景航向。

我的建议是找到附近的标志性建筑,从您的位置直接指向真正的北方,使用坐标在那里放置一个物体,然后使用moveSceneHeading函数调整场景,直到它们对齐。

改进的定位精度

CoreLocation可以在每1-15秒之间提供位置更新,精度从150米到4米不等。有时,您会收到更精确的读数,如4米或8米,然后再返回到更不精确的读数。同时,AR使用运动和相机数据创建当地世界的地图。

用户可能会收到一个精确度为4米的位置读数,然后他们向北走10米,并接收到另一个精确度为65米的位置读数。这个65米精确度读数是CoreLocation能提供的最佳读数,但如果我们知道用户在收到4米读数时的AR场景中的位置,并且他们已经通过场景向北移动了10米,我们可以将这份数据转换为提供一个新坐标,精度约为4米。这大约精确到100米。

关于这一点在维基百科上还有更多详细信息。.

问题

我提到这是一项实验性的技术——目前,ARKit在用户在场景中行走时可能会偶尔混乱,并且可能会不准确地更改其位置。这个问题似乎还影响了设备的“欧拉角”,或方向信息,因此经过短暂的距离后,它可能认为您正走在不同的方向。

尽管苹果可以通过时间改进ARKit,但我认为我们可以通过识别这种情况并努力更正它来避免这些问题,例如,通过与我们的预计位置比较位置数据,以确定我们是否已经移出可能的边界。

位置算法改进

还可以进一步优化确定用户位置的方法。

例如,一种技术可以是查看最近的位置数据,使用用户自那时以来的旅行将每个数据点进行转换,并使用数据点之间的重叠来更精确地确定用户的可能位置。

关于这一点在维基百科上还有更多详细信息。.

未来方向

我们有与它们相关的一些里程碑和问题 - 欢迎任何人讨论和贡献。欢迎 Pull 请求。您可以通过添加新问题或通过以下链接加入 Slack 社区来讨论新的特性、增强或错误。

感谢

@AndrewProjDent 创建的库,但此后成为社区努力的结果。

根据MIT许可协议开源。