ARKit — Rekonstrukce scény pomocí LiDARu

01.11.2023 Programování #ios #iphone #arkit #programming

Krátká ukázka, jak zobrazit na telefonu rekonstrukční síť snímaného prostoru s využitím laserového snímače a RealityKit.


Teorie

Průlomový snímač LiDAR aktivuje funkce ARKit a RealityKit, které na starších zařízeních Apple nebyly možné. LiDAR, což je zkratka pro Light Detection And Ranging, používá pulsní laser k vysílání pulsů světla a přijímač k jejich zachycení pro měření proměnných vzdáleností k okolním objektům až do vzdálenosti 5,0 metrů (ačkoli v určitých případech může mít Apple LiDAR pokrytí až 7,0+ metrů). LiDAR byl koncipován jako jednotka pro vytváření přesných 3D map. Pracuje rychlostí nanosekund – od 0,2 do 5 ns – to znamená, že existují stovky milionů pulzů za sekundu. S tak výjimečnou rychlostí a hustým pokrytím mračna bodů je operace rekonstrukce scény v aplikacích ARKit a RealityKit téměř okamžitá.

Pro LiDAR Apple převzal komponenty od čtyř hlavních výrobců (v roce 2020). Těmito dodavateli jsou Sony se svým Near InfraRed CMOS Image Sensor (nebo jinými slovy receptor), Lumentum s Vertical Cavity Surface Emitting Laser (nebo, když se říká jednodušší, emitor )Texas Instruments s Wafer Level Chip Scale Packaging a Himax s difrakčním Optickým prvkem.

Obrazový snímač NIR CMOS od Sony má rozlišení 30 000 pixelů.

LiDAR od Applu je v podstatě přímý senzor Time-of-Flight (dToF). Hlavní rozdíl mezi přímými a nepřímými snímači doby letu je v tom, že snímač iToF vysílá spojité a modulované světlo (známé jako sinusová vlna modulovaného světla s frekvencí 20 až 100 MHz ) a měří fázi odraženého světla pro výpočet vzdálenosti k objektu, zatímco dToF senzor vysílá krátké světelné pulsy, které trvají jen několik nanosekund, a poté měří čas, který trvá, než se část vyzařovaného světla vrátí.

Ještě stručněji – iToF měří fázový posun, zatímco dToF měří přímý čas letu. Takže dToF má podstatně vyšší přesnost než iToF . V posledních letech bylo mnoho zařízení Android vybaveno iToF, které mohou být užitečné v aplikacích ARCore (potřebujete alespoň ARCore 1.18 pro implementaci Full Depth API a ARCore 1.24 pro povolení Raw Depth API).
A co zařízení Apple? Nejnovější modely iPhone s čipem A15 a modely iPad Pro s čipem M1 jsou nejlepší volbou pro spouštění aplikací ARKit 5.0 s funkcí rekonstrukce scény.

Výhody a nevýhody LIDARu

Zde jsou některé zjevné výhody a výhody, které uživatelé a vývojáři ARKit získají, když používají zařízení vybavená LiDAR:

  • Světelné podmínky v místnosti jsou nyní důležité v menší míře *
  • Není povinné sledovat pouze povrchy s dobře vnímatelnými texturami
  • Pro úspěšné sledování se uživatel nemusí fyzicky pohybovat
  • LiDAR může pracovat ve spojení s funkcí detekce roviny
  • Nezáleží na tom, zda jsou v místnosti čistě bílé stěny nebo bílé předměty
  • Získáme mid-poly síťovinu s okluzním materiálem připraveným pro kolizi
  • Vyšší rychlost pohybu zařízení v okamžiku sledování
  • Vylepšené funkce Ray-Casting, People Occlusion a Motion Capture
  • ARKit nyní bere v úvahu povrchy s velmi malým nebo dokonce žádnými body prvků
  • Rekonstruované povrchy jsou schopny zachytit skutečné i virtuální světlo
  • Každý poly-face může být klasifikován na základě případů ARMeshClassification
  • Vysoce kvalitní mapa hloubky běžící rychlostí 60 snímků za sekundu, pocházející z nového rozhraní Depth API
  • Téměř okamžitá a podstatně přesnější funkce detekce rovin
  • Pro lepší výsledek mohou být lidé vyloučeni z Reconstructed Mesh

* Musíte vzít v úvahu, že rekonstrukce scény ve špatně osvětlené místnosti má smysl pouze pro síť vytvořenou pro kolize nebo pro vylepšenou detekci rovin. Uložení ARWorldMap nebo uložení sítě s promítanými texturami na ní (s pomocí LiDARu nebo bez něj) je možné pouze při dostatečně dobrých světelných podmínkách .

Kódování pomocí Swift

Pro práci s RealityKit je nutné vložit do storyboardu objekt RealityKit AR View.

Funkce Scene Reconstruction je dostupná, když spouštíte konfiguraci World Tracking. V tuto chvíli je nejrobustnějším přístupem k použití funkce Rekonstrukce scény ve vaší aplikaci její použití volitelně, protože ji nyní podporuje jen několik zařízení Apple v modelové řadě. Chcete-li zkontrolovat, zda má zařízení uživatele zabudovaný skener LiDAR nebo ne, musíte implementovat příkaz guard-else. To lze provést v souboru AppDelegate.swift.

@UIApplicationMain  class AppDelegate: UIResponder, UIApplicationDelegate { 
    func application(_ application: UIApplication,  didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any ]?) -> Bool {
        let supportFor SceneReconstruction = ARWorldTrackingConfiguration.supportsSceneReconstruction(.mesh)
        guard  supportFor SceneReconstruction else { fatalError ("Rekonstrukce scény zde není podporována" )         }      
       return true     
    } 
} 

Poté můžete napsat tento jednoduchý fragment kódu do ViewController.swift uvnitř metody viewDidLoad nebo uvnitř metody viewWillAppear.

import UIKit
import RealityKit
import ARKit


class ViewController: UIViewController, ARSCNViewDelegate, ARSessionDelegate {

    @IBOutlet weak var arView: ARView!

    override func viewDidLoad() {
       super.viewDidLoad()
       arView.automaticallyConfigureSession = false
       let config = ARWorldTrackingConfiguration()
       config.sceneReconstruction = .meshWithClassification
       arView.debugOptions.insert(.showSceneUnderstanding)
       arView.session.run(config, options: [])
    }
}

Vlastnost instance RealityKit nazvaná automatickyConfigureSession má dva stavy – když je pravdivá (výchozí stav), RealityKit klasifikaci zakáže, protože není vyžadována pro okluzi a fyziku.

       arView.automaticallyConfigureSession = true
       config.sceneReconstruction = .mesh

Když je to nepravda — můžete vytvořit síť objektů reálného světa s klasifikací pro každý povrch.

       arView.automaticallyConfigureSession = false
       config.sceneReconstruction = .meshWithClassification

To je vše. Oba frameworky, ARKit 5.0 a RealityKit 2.0, fungují v jednom svazku. ARKit je zodpovědný za fáze sledování světa a porozumění scénám (pomáhá sledovat reálné prostředí a poté generovat trojúhelníkové sítě a odpovídající ARMeshAnchors ). RealityKit zase vykreslí výslednou 3D síť s aplikovaným materiálem OcclusionMaterial.

Pokud potřebujete resetovat konfiguraci aktuální relace a začít sledovat od začátku, použijte následující kód:

@IBAction func resetConfigurationButton( _ odesílatel: Jakýkoli ) {
    if let config = arView.session.configuration {
        let opts: ARSession.RunOptions = [.resetTracking, 
                                          .removeExistingAnchors, 
                                          .resetSceneReconstruction]
        arView.session.run(config, options: opts) 
    } 
}

Pokud chcete zobrazit nebo skrýt rekonstruovanou síť, postupujte takto:

@IBAction func toggleShowHideMeshButton( _ odesílatel: Jakýkoli ) {
    let meshShowingOrNot = arView.debugOptions.contains( 
                                         .showSceneUnderstanding)
    if meshShowingOrNot { 
        arView.debugOptions.remove(.showSceneUnderstanding) 
        sender.setTitle(" Show Poly Mesh ", for: []) 
    } else { 
        arView.debugOptions.insert(.showSceneUnderstanding) 
        sender.setTitle(" for Hide Poly Mesh ", : []) 
    } 
}

Pokud potřebujete barevně odlišenou síť na základě případů klasifikace, zkopírujte a vložte tento jednoduchý úryvek:

extension ARMeshClassification {
var description: String {
        switch self {
            case .ceiling: return "Ceiling"
            case .door: return "Door"
            case .floor: return "Floor"
            case .seat: return "Seat"
            case .table: return "Table"
            case .wall: return "Wall"
            case .window: return "Window"
            case .none: return "None"
            @unknown default: return "Unknown"
        }
    }
    var color: UIColor {
        switch self {
            case .ceiling: return .magenta
            case .door: return .green
            case .floor: return .cyan
            case .seat: return .blue
            case .table: return .yellow
            case .wall: return .red
            case .window: return .black
            case .none: return .systemOrange
            @unknown default: return .white
        }
    }
}

Jemné ladění pro Raycasting

Když implementujete raycasting a chcete vzít v úvahu rekonstruovanou síť, musíte použít 2 nesamozřejmé, ale důležité hodnoty pro parametry zvané allow a alignment.

@IBAction func tapped( _ odesílatel: UITapGestureRecognizer) {
    let tapLocation: CGPoint = sender.location(in: arView) 
    let removedPlane: ARRaycastQuery.Target = .estimatedPlane 
    let alignment: ARRaycastQuery.TargetAlignment = .any
    let result = arView.raycast(from: tapLocation, 
                            allow: removedPlane, 
                           alignment: alignment)
    guard let raycast: ARRaycastResult = result.first 
    else { return }
    let anchor = AnchorEntity(svět: raycast.worldTransform) 
    anchor.addChild(model) 
    arView.scene.anchors.append(anchor) 
 
    print(raycast.worldTransform.columns.3) 
}

Podle dokumentace Apple:

ARRaycastQuery.Target.estimatedPlane je cílem raycast, je specifikace nerovinných povrchů nebo rovin, které může ARKit pouze odhadovat. Raycast s tímto cílem protíná body kolem paprsku, o kterém ARKit odhaduje, že mohou být skutečným povrchem.

ARRaycastQuery.TargetAlignment.any je případ, který naznačuje, že cíl může být zarovnán jakýmkoli způsobem s ohledem na gravitaci.

Literatura:

https://medium.com/macoclock/arkit-911-scene-reconstruction-with-a-lidar-scanner-57ff0a8b247e