Developers Perspective: Die neue LiDAR Funktion für iOS

Wir bei Photogram suchen ständig nach Innovationen und Neuheiten im Bereich der digitalen Vermessung. Unser Ziel ist es, diese Technologien benutzerfreundlich und einfacher zugänglich zu machen.Seit einiger Zeit verwandelt unsere Plattform jedes Smartphone, das Videos und Fotos in guter Qualität aufnehmen kann, in ein zuverlässiges Vermessungsinstrument. Mit den LiDAR-Sensoren der neuen PRO iPhones eröffnen sich neue Möglichkeiten, die Vermessung mit dem Smartphone noch effizienter und genauer zu gestalten. Wie wir diese neue Hardware für die Erstellung von Punktwolken verwenden, soll hier dargestellt werden.

Zurzeit verwenden wir in unserer Software hauptsächlich die Photogrammmetrie. Mit dieser Technik können aus Fotos und/oder Videos Punktwolken eines Objektes oder eines Zielortes mit beeindruckender Genauigkeit erstellt werden. Diese Technologie ist zwar sehr flexibel und liefert gute Ergebnisse, jedoch beansprucht die Umrechnung der Video- und Fotodaten in Punktwolken einiges an Zeit. Außerdem kann erst im Nachhinein beurteilt werden, ob die Rohdaten für ein zufriedenstellendes Ergebnis ausreichen.

Neben der Photogrammmetrie werden auch Laserscanner zur Erstellung von Punktwolken eingesetzt. Laserscanner funktionieren nach dem „time of flight“ (tof) Prinzip. Dazu sendet das Gerät einen Lichtstrahl aus und misst die Zeit, die der Strahl benötigt, um vom Zielobjekt reflektiert zu werden. Die Hälfte dieser Zeit multipliziert mit der Strecke, die das Licht in dieser Zeit zurücklegt, ergibt die Entfernung zum Zielobjekt. Laserscanner, auch LiDAR (Light detection and ranging oder Light imaging, detection and ranging) genannt, senden pro Sekunde Tausende dieser Laserstrahlen aus und erhalten mehrere tausend Messpunkte in kürzester Zeit. Aus all diesen Messpunkten können Punktwolken generiert werden.

Einer der größten Vorteile dieser Technologie ist, dass die Distanzen zu den Objekten sofort richtig skaliert sind. Eine nachträgliche Umrechnung in die richtige Größe ist dadurch nicht erforderlich, was Rechenleistung und damit Zeit spart. Die Orientierung der Punktwolke ist durch den im Gerät verbauten IMU ebenfalls klar. So liegt die Punktwolke immer richtig im Raum. Klassische Laserscanner bestehen aus einem Laser und einer Empfangseinheit, die auf einen rotierenden Spiegel gerichtet sind. Die gesamte Einheit dreht sich dann um die Z-Achse, so dass der Laser die gesamte Umgebung abtasten kann. Diese Geräte liefern sehr genaue Ergebnisse, sind für gelegentliche Nutzer jedoch unhandlich. Eine neue Entwicklung in der LiDAR-Technologie betrifft Systeme, die auf große mechanische Bauteile verzichten und somit äußerst kompakt sind. Diese Laserscanner nutzen die MEMS (Micro-Electro-Mechanical Systems) Technologie, um mikroskopisch kleine, bewegliche Spiegel auf Leiterplatten zu integrieren. Durch diese Technologie wird es möglich, den Laserstrahl präzise in alle Richtungen zu lenken, ohne auf einen großen mechanischen Drehspiegel angewiesen zu sein. Diese fortschrittlichen LiDARs werden als Solid State LiDARs bezeichnet, da sie keine herkömmlichen mechanischen Bauteile mehr enthalten.

Seit 2020 integriert Apple ein Solid State LiDAR in allen PRO-Modellen ihrer iPhones und iPads. Dieses LiDAR wird hauptsächlich zur Verbesserung der AR-Funktionen verwendet. Mit iOS14 wurde die ARKit API auch für Entwickler zugänglich gemacht. Das hat uns die Möglichkeit eröffnet diese neue Hardware in unsere Software zu integrieren und für Vermessungen zu nutzen. Unsere „LiDAR-Funktion“ nutzt die Tiefeninformationen der LiDAR-Scanner des iPhones oder iPads, um Punktwolken zu generieren. Die genaue Position und Rotation im Raum wird von ARKit mit der integrierten IMU bereitgestellt, wodurch 3D-Koordinaten im relativen Raum berechnet werden können. Zusätzlich liefert ARKit für jeden Punkt einen „confidence value“, der die Zuverlässigkeit der erfassten Punkte angibt. Er gibt an, wie sicher ARKit ist, dass es die Position und Orientierung der erfassten Punkte richtig bestimmt hat. Die Rohdaten des LiDAR Sensors haben noch keine Farbwerte. Daher werden während der Nutzung unserer "LiDAR-Funktion" jede Sekunde bis zu 30 Fotos mit der integrierten Kamera aufgenommen, um jedem Punkt in der Punktwolke Farbinformationen hinzuzufügen. Basierend auf all diesen Informationen versucht unser Algorithmus, die besten verfügbaren Punkte zu berechnen, die dann als Punktwolke gespeichert werden. Dieser Prozess wiederholt sich bis zu 30-mal pro Sekunde.

Unsere App basiert auf Webtechnologie, was viele Vorteile bietet, z.B. die Möglichkeit, die App nur einmal zu entwickeln und auf verschiedenen Plattformen wie Web, iOS und Android zu nutzen. Trotzdem gibt es auch einige Nachteile, wie den fehlenden Zugriff auf native APIs wie ARKit, was den Zugriff auf das LiDAR erschwert. Die Rechenleistung in einer Webanwendung ist begrenzt, und Funktionen wie live 3D-Visualisierung mit Echtzeit-Mapping sind schwer mit Web GPU APIs wie WebGL umzusetzen.

Um dieses Problem zu lösen, haben wir die gesamte LiDAR-Funktionalität nativ in Swift für iOS entwickelt. Um nicht die gesamte App neu erstellen zu müssen, haben wir ein natives Plugin für unsere Webapp entwickelt. Dabei haben wir einen nativen View Controller über den Web View Controller gelegt, um für den Benutzer einen nahtlosen Übergang zwischen der Webapp und dem nativen Plugin zu schaffen. Die Kommunikation zwischen dem Plugin und der Webapp erfolgt über eine textbasierte Bridge. In den angehängten Codebeispielen wird deutlich, dass der Web-Code in TypeScript geschrieben ist, während der native Code in Swift verfasst wurde. Der Code ist in drei Ordner unterteilt: "PluginWebBridge", "PluginCoreNative" und “WebIntegration”. "PluginWebBridge" und "PluginCoreNative" bilden das Plugin. Der Code in "PluginWebBridge" informiert die Webapp darüber, wie sie mit dem Plugin kommunizieren kann, während "PluginCoreNative" den Code für das native Plugin enthält. Im Ordner "WebIntegration" befindet sich der Code für die Webapp, der dazu dient, das LiDAR-Plugin zu steuern und die Punktwolke zu übertragen.

Um den Code am einfachsten zu verstehen, betrachten wir den Ablauf beim Aufruf. Alles beginnt damit, die Funktion “isLidarAvailable” aufzurufen, um festzustellen, ob das Gerät überhaupt ein LiDAR eingebaut hat. In der Datei useLidar.ts ruft diese Funktion dann über die Bridge definitions.ts die entsprechende Funktion isLidarAvailable in LidarPlugin.swift auf. Im nativen Swift-Code wird geprüft, ob ein LiDAR verfügbar ist und die Antwort wird über die Bridge an den Webcode zurückgegeben. Wenn ein LiDAR vorhanden ist, kann mit der Funktion openLidarCapture in useLidar.ts das tatsächliche LiDAR-Plugin mit dem nativen Benutzeroberfläche gestartet werden. Dafür wird dann die startLidar Funktion in LidarIos.swift aufgerufen. Hier wird deutlich, wie ein neuer nativer View Controller über den vorhandenen Web View Controller geschoben wird, um die Punktwolke mit der nativen Metal-Grafikschnittstelle darzustellen. Anders als bei anderen Funktionen ist die openLidarCapture Funktion nicht nach einem Aufruf abgeschlossen. Stattdessen wird ein bidirektionaler Kommunikationskanal zwischen Web und Nativ aufrechterhalten. Dieser wird genutzt, um der App mitzuteilen, was als nächstes zu tun ist. Beispielsweise wird mitgeteilt, wenn die Punktwolke fertig ist und unter welchem Pfad sie gespeichert wird. Diese Informationen benötigt die Web App später, um mit der Funktion useLidarUpload in useLidarUplaod.ts den Upload auf unsere Server zu starten. Der eigentliche Upload wird jedoch vom nativen Plugin selbst durchgeführt, da die bridge nicht genug Bandbreite besitzt, um die Punktwolke vom nativen Plugin in die Webapp zu übertragen. Der Upload-Code ist in der Datei NFSClient.swift zu finden.

Derzeit werden LiDAR-Sensoren ausschließlich von Apple verwendet. Daher ist diese Funktion nur in der PRO-Version des iPhone 12 (oder neuer) sowie des iPad 11 (oder neuer) verfügbar.

Autor:

Head of Development
Matthias Keim, dott.