ARKit 101: So messen Sie den Boden mit ARKit

0 Shares

Haben Sie die vielen ARKit-Dienstprogramme im App Store bemerkt, mit denen Sie die Größe horizontaler Ebenen in der Welt messen können? Erraten Sie, was? Nach diesem Tutorial können Sie dies selbst tun!

In diesem Tutorial erfahren Sie, wie Sie mithilfe von ARKit Ihre Augmented Reality-App für iPads und iPhones erstellen. Insbesondere werden wir untersuchen, wie wir horizontale Ebenen und ihre Abmessungen (Breite und Länge) erkennen können.

Was wirst du lernen?

Wir werden lernen, wie man horizontale Ebenen und ihre Größen mit ARKit genau erkennt.

Mindestanforderungen

Mac mit MacOS 10.13.2 oder höher. Xcode 9.2 oder höher. Ein Gerät mit iOS 11+ auf einem A9 oder höher Prozessor. Grundsätzlich das iPhone 6S und höher, das iPad Pro (9,7 Zoll, 10,5 Zoll oder 12,9 Zoll; erste und zweite Generation) und das iPad 2017 oder höher. Swift 4.0. Obwohl Swift 3.2 unter Xcode 9.2 funktioniert, empfehle ich dringend, den neuesten Xcode herunterzuladen, um auf dem neuesten Stand zu bleiben. Ein Apple Developer-Konto. Es ist jedoch zu beachten, dass Sie kein kostenpflichtiges Apple Developer-Konto benötigen. Mit Apple können Sie Apps mit einem unbezahlten Apple Developer-Konto auf einem Testgerät bereitstellen. Sie benötigen jedoch ein kostenpflichtiges Entwicklerkonto, um Ihre App in den App Store zu stellen. (Informationen zur Funktionsweise des Programms finden Sie auf der Apple-Website, bevor Sie sich für Ihr kostenloses Apple Developer-Konto registrieren.)

Schritt 1: Laden Sie die Assets herunter, die Sie benötigen

Um das Befolgen dieses Tutorials zu vereinfachen, habe ich einen Ordner mit den erforderlichen 2D-Assets und der für das Projekt erforderlichen Swift-Datei erstellt. Diese Dateien stellen sicher, dass Sie sich in diesem Handbuch nicht verlaufen. Laden Sie daher den komprimierten Ordner mit den Assets herunter und entpacken Sie ihn.

Schritt 2: Richten Sie das AR-Projekt in Xcode ein

Wenn Sie sich nicht sicher sind, wie Sie dies tun sollen, befolgen Sie Schritt 2 in unserem Beitrag zum Steuern einer 3D-Ebene mit hitTest, um Ihr AR-Projekt in Xcode einzurichten. Geben Sie Ihrem Projekt einen anderen Namen, z NextReality_Tutorial4. Stellen Sie sicher, dass Sie einen kurzen Testlauf durchführen, bevor Sie mit dem folgenden Tutorial fortfahren.

Schritt 3: Importieren Sie Assets in Ihr Projekt

Klicken Sie im Projektnavigator auf den Ordner “Assets.xcassets”. Wir werden hier unsere 2D-Bilder hinzufügen. Klicken Sie dann mit der rechten Maustaste auf den linken Bereich des Bereichs auf der rechten Seite des Projektnavigators. Wählen Sie “Importieren” und fügen Sie die Datei “overlay_grid.png” aus dem entpackten Ordner “Assets” hinzu.

ARKit 101: So messen Sie den Boden mit ARKit

Klicken Sie anschließend im Projektnavigator erneut mit der rechten Maustaste auf den gelben Ordner für “NextReality_Tutorial4” (oder wie auch immer Sie Ihr Projekt benannt haben). Wählen Sie die Option “Dateien zu ‘NextReality_Tutorial4’ hinzufügen”.

ARKit 101: So messen Sie den Boden mit ARKit

Navigieren Sie zum entpackten Ordner “Assets” und wählen Sie die Datei “Grid.swift”. Stellen Sie sicher, dass Sie “Elemente bei Bedarf kopieren” aktivieren und alles andere unverändert lassen. Klicken Sie auf “Hinzufügen”.

ARKit 101: So messen Sie den Boden mit ARKit

“Grid.swift” sollte Ihrem Projekt hinzugefügt werden, und Ihr Projektnavigator sollte ungefähr so ​​aussehen:

ARKit 101: So messen Sie den Boden mit ARKit

Diese Datei hilft beim Rendern eines Rasters für jede horizontale Ebene, die ARKit erkennt.

Schritt 4: Platzieren Sie ein Raster, um erkannte horizontale Ebenen anzuzeigen

In unserem Tutorial zur Erkennung horizontaler Ebenen finden Sie Informationen zu den Ebenenerkennungsfunktionen von ARKit.

Öffnen Sie die Klasse “ViewController.swift”, indem Sie darauf doppelklicken. Wenn Sie dem endgültigen Code für Schritt 4 folgen möchten, öffnen Sie einfach diesen Link, um ihn auf GitHub anzuzeigen.

Ändern Sie in der Datei “ViewController.swift” die Zeile zum Erstellen von Szenen in der viewDidLoad () Methode. Ändern Sie es von:

let scene = SCNScene(named: "art.scnassets/ship.scn")!

Im Folgenden wird sichergestellt, dass keine Szene mit dem Standardschiffmodell erstellt wird.

let scene = SCNScene()

Als nächstes finden Sie diese Zeile oben in der Datei:

@IBOutlet var sceneView: ARSCNView!

Fügen Sie unter dieser Linie diese Linie hinzu, um ein Array von “Gittern” für alle erkannten horizontalen Ebenen zu erstellen:

var grids = [Grid]()

Kopieren Sie die folgenden zwei Methoden und fügen Sie sie wie unten aufgeführt am Ende der Datei vor der letzten geschweiften Klammer ein ( }} ) in der Datei. Mit diesen Methoden können wir unser Raster in den von ARKit erkannten horizontalen Ebenen als visuellen Indikator hinzufügen.

// 1.
func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
    let grid = Grid(anchor: anchor as! ARPlaneAnchor)
    self.grids.append(grid)
    node.addChildNode(grid)
}
// 2.
func renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor) {
    let grid = self.grids.filter { grid in
        return grid.anchor.identifier == anchor.identifier
    }.first

    guard let foundGrid = grid else {
        return
    }

    foundGrid.update(anchor: anchor as! ARPlaneAnchor)
}

Lassen Sie uns kurz durchgehen, was in diesen beiden Methoden passiert:

    Das didAdd () wird aufgerufen, wenn ein neuer Knoten zum hinzugefügt wird ARSCNView. Hier nehmen wir die erkannten ARPlaneAnchor und füge es als unser hinzu Gitter Objekt, das das von uns importierte Rasterbild zu jeder erkannten Ebene hinzufügt. Das didUpdate () wird immer dann aufgerufen, wenn neuer ARPlaneAnchor Knoten werden erkannt oder wenn die Ebene erweitert wird. In diesem Fall möchten wir auch unser Raster aktualisieren und erweitern. Wir machen das hier, indem wir anrufen aktualisieren() auf diesem spezifischen Gitter.

Lassen Sie uns nun Feature-Punkte aktivieren. Unter dieser Zeile in viewDidLoad ()::

sceneView.showsStatistics = true

Hinzufügen:

sceneView.debugOptions = ARSCNDebugOptions.showFeaturePoints

Als nächstes aktivieren wir die Erkennung der horizontalen Ebene. Unter dieser Zeile in viewWillAppear ()::

let configuration = ARWorldTrackingConfiguration()

Hinzufügen:

configuration.planeDetection = .horizontal

Das ist sehr wichtig! Dadurch wird sichergestellt, dass ARKit horizontale, flache geometrische Ebenen in der realen Welt erkennen kann. Mit den Feature-Punkten können wir alle 3D-Punkte anzeigen, die ARKit erkennen kann.

Führen Sie jetzt Ihre App auf Ihrem Telefon aus und gehen Sie herum. Wenn Sie sich auf einen gut beleuchteten Bereich auf dem Boden konzentrieren, sollten Sie blaue Gitter sehen können, wenn eine horizontale Ebene erkannt wird:

ARKit 101: So messen Sie den Boden mit ARKit

Kontrollpunkt: Ihr gesamtes Projekt am Ende dieses Schritts sollte wie der endgültige Schritt 4-Code auf meinem GitHub aussehen.

Schritt 5: Messen Sie die erkannten horizontalen Ebenen

Jetzt verwenden wir die Eigenschaft “Ausdehnung” der erkannten Ebenen, um ihre Abmessungen zu erfassen und sie mithilfe von SceneKit auszudrucken. Alle folgenden Codeänderungen werden in der Datei “Grid.swift” vorgenommen. Stellen Sie sicher, dass Sie das öffnen und die folgenden Schritte ausführen. Gehen Sie die fertige Version entlang, während Sie durch die Schritte gehen.

Öffnen Sie die Klasse “Grid.swift” und unter dieser Zeile:

var planeGeometry: SCNPlane!

Fügen Sie eine neue Geometrie für den Text hinzu, in der die Abmessungen der erkannten Ebenen angezeigt werden:

var textGeometry: SCNText!

Suchen Sie als Nächstes die Zeile, die importiert wird ARKit::

import ARKit

Fügen Sie unter dieser Zeile und über der Zeile, in der die Grid-Klasse erstellt wird, den folgenden Code hinzu:

extension ARPlaneAnchor {
    // Inches
    var width: Float { return self.extent.x * 39.3701}
    var length: Float { return self.extent.z * 39.3701}
}

Hier erweitern wir die Funktionalität von ARPlaneAnchor. Standardmäßig wird die Größe in Metern zurückgegeben. Wir erstellen zwei Eigenschaften: “Breite” und “Länge”, die die Meter in Zoll umrechnen. Wir verwenden die Eigenschaft “Umfang” der ARPlaneAnchor und erhalten Sie die Werte “x” und “z”. Können Sie sich vorstellen, warum wir den Wert “y” nicht erhalten? Das liegt daran, dass geometrische Ebenen flach sind und keine Höhe haben!

Weitere Informationen zu Erweiterungen in Swift finden Sie in der Apple-Dokumentation.

Als nächstes finden Sie die Konfiguration() Methode. Löschen Sie diese Methode und ersetzen Sie sie durch eine aktualisierte Version der Methode, wie unten gezeigt:

private func setup() {
    planeGeometry = SCNPlane(width: CGFloat(anchor.width), height: CGFloat(anchor.length))

    let material = SCNMaterial()
    material.diffuse.contents = UIImage(named:"overlay_grid.png")

    planeGeometry.materials = [material]
    let planeNode = SCNNode(geometry: self.planeGeometry)
    planeNode.physicsBody = SCNPhysicsBody(type: .static, shape: SCNPhysicsShape(geometry: planeGeometry, options: nil))
    planeNode.physicsBody?.categoryBitMask = 2

    planeNode.position = SCNVector3Make(anchor.center.x, 0, anchor.center.z);
    planeNode.transform = SCNMatrix4MakeRotation(Float(-Double.pi / 2.0), 1.0, 0.0, 0.0);

    // 1.
    let textNodeMaterial = SCNMaterial()
    textNodeMaterial.diffuse.contents = UIColor.black

    // Set up text geometry
    textGeometry = SCNText(string: String(format: "%.1f"", anchor.width) + " x " + String(format: "%.1f"", anchor.length), extrusionDepth: 1)
    textGeometry.font = UIFont.systemFont(ofSize: 10)
    textGeometry.materials = [textNodeMaterial]

    // Integrate text node with text geometry
    // 2.
    let textNode = SCNNode(geometry: textGeometry)
    textNode.name = "textNode"
    textNode.position = SCNVector3Make(anchor.center.x, 0, anchor.center.z);
    textNode.scale = SCNVector3Make(0.005, 0.005, 0.005)

    addChildNode(textNode)
    addChildNode(planeNode)
}

Wir behalten das Konfiguration() Methode wie zuvor, um die Logik des Gitters einzurichten. Wir haben es jedoch durch eine Logik ergänzt, die die Größe des Rasters über dem Raster hinzufügt. Lassen Sie uns dies untersuchen:

    Wir haben eine Geometrie für den Text mit dem eingerichtet SCNText Klasse. Anschließend legen wir den Text auf die Breite und Höhe der Ebene fest, die mit unserer benutzerdefinierten Erweiterung berechnet wird. Wir haben dann die Schriftgröße geändert und unser benutzerdefiniertes Material (schwarzer Text) auf die Eigenschaft “Materialien” des SCNText Geometrie.
    Hier haben wir eine neue erstellt SCNNode mit dem SCNText Geometrie aus dem obigen Schritt und aktualisiert seine Position und Skalierung entsprechend. Wir haben dann sowohl den Text- als auch den Ebenenknoten zu unserem Gitterknoten hinzugefügt.

Auf diese Weise können wir die Größe des Flugzeugs beim ersten Einrichten anzeigen. Außerdem sollten wir die Größe des Flugzeugs ständig aktualisieren, da es immer größer wird. Lassen Sie uns das in den nächsten Codeänderungen tun.

Finden Sie die Update (Anker: ARPlaneAnchor) Methode. Am Ende der Methode vor der letzten geschweiften Klammer (}}), fügen Sie den folgenden Code hinzu:

if let textGeometry = self.childNode(withName: "textNode", recursively: true)?.geometry as? SCNText {
    // Update text to new size
    textGeometry.string = String(format: "%.1f"", anchor.width) + " x " + String(format: "%.1f"", anchor.length)
}

Wir haben auch den Text des aktualisiert SCNText Geometrie, die wir zuvor hinzugefügt haben, um sicherzustellen, dass die Bemaßungen weiterhin visuell aktualisiert werden, wenn sich die Ebene erweitert.

Speichern Sie die App und führen Sie sie aus. Gehen Sie in einem gut beleuchteten, strukturierten Bereich herum und konzentrieren Sie sich auf den Boden (oder eine beliebige horizontale Ebene wie einen Tisch). Sie sollten beginnen, blaue Gitter zusammen mit der Größe der zu aktualisierenden Ebenen zu sehen, wenn die erkannten Ebenen immer größer werden.

Kontrollpunkt: Ihr gesamtes Projekt am Ende dieses Schritts sollte wie der endgültige Schritt 5-Code auf meinem GitHub aussehen.

Was wir erreicht haben

Gut gemacht! Mit ARKit konnten Sie den Boden erfolgreich und präzise messen! Lassen Sie uns das durchgehen, was Sie aus diesem Tutorial gelernt haben: Platzieren eines Rasters über erkannten horizontalen Ebenen unter Verwendung der Eigenschaft Extent von ARPlaneAnchor um die Größe des Flugzeugs zu ermitteln und die Größe mit SceneKit visuell zu rendern.

Wenn Sie den vollständigen Code für dieses Projekt benötigen, finden Sie ihn in meinem GitHub-Repo. Ich hoffe, Ihnen hat dieses Tutorial auf ARKit gefallen. Wenn Sie Kommentare oder Feedback haben, können Sie diese gerne im Kommentarbereich hinterlassen. Viel Spaß beim Codieren!

Verpassen Sie nicht: So starten Sie eine AR-Rakete in den Himmel

0 Shares