Что такое ARAnchor?

Я пытаюсь понять и использовать ARKit. Но есть одна вещь, которую я не могу полностью понять.

Apple сказала об ARAnchor:

Положение и ориентация в реальном мире, которые можно использовать для размещения объектов в сцене дополненной реальности.

Но этого мало. Итак, мои вопросы:

  • Что такое ARAnchor?
  • В чем разница между якорями и характерными точками?
  • ARAnchor - это просто часть особенностей?
  • И как ARKit определяет свои якоря?

person PrepareFor    schedule 19.10.2018    source источник


Ответы (1)


Обновлено: 22 июня 2021 г.

TL;DR


ARAnchor

ARAnchor - это невидимый нулевой объект, который может удерживать 3D-модель в позиции привязки в Мировом пространстве. Думайте о ARAnchor как о transform node с локальной осью (вы можете перемещать, вращать и масштабировать ее) для вашей модели. У каждой 3D-модели есть точка поворота, верно? Таким образом, эта точка поворота должна соответствовать ARAnchor.

Если вы не используете якоря в _5 _ / _ 6_ приложении, ваши 3D-модели могут смещаться с того места, где они были размещены, и это существенно повлияет на реалистичность вашего приложения и удобство для пользователей. Таким образом, якоря являются важнейшими элементами вашей AR-сцены.

Согласно документации ARKit 2017:

ARAnchor - это положение и ориентация в реальном мире, которые можно использовать для размещения объектов в AR-сцене. Добавление привязки к сеансу помогает ARKit оптимизировать точность отслеживания мира в области вокруг этой привязки, чтобы виртуальные объекты, казалось, оставались на месте относительно реального мира. Если виртуальный объект перемещается, удалите соответствующий якорь из старого положения и добавьте его в новое положение.

ARAnchor является родительским классом для всех других типов якорей, существующих в среде ARKit, поэтому все эти подклассы наследуются от класса ARAnchor, но не могут использовать его непосредственно в вашем коде. Я также должен сказать, что ARAnchor и Feature Points не имеют ничего общего. Feature Points скорее для успешного отслеживания и для отладки.

ARAnchor не отслеживает автоматически цель в реальном мире. Если вам нужна автоматизация, вы должны использовать renderer(...) или session(...) методы экземпляра, которые вы можете вызывать, если вы соответствуете протоколам ARSCNViewDelegate или ARSessionDelegate соответственно.

Вот изображение с визуальным представлением привязки плоскости. Но имейте в виду: по умолчанию вы не можете видеть ни обнаруженную плоскость, ни соответствующую ей ARPlaneAnchor. Итак, если вы хотите увидеть какой-либо якорь в своей сцене, вы должны визуализировать его с помощью трех тонких SCNCylinder примитивов.


введите описание изображения здесь


В ARKit вы можете автоматически добавлять ARAnchors в свою сцену, используя разные сценарии:

  • ARPlaneAnchor

    • If horizontal and/or vertical planeDetection instance property is ON, ARKit is able to add ARPlaneAnchors to the current session. Sometimes enabled planeDetection considerably increases a time required for scene understanding stage.
  • ARImageAnchor (соответствует ARTrackable протокол)

    • This type of anchors contains information about the position and orientation of a detected image (anchor is placed at an image center) in world-tracking session. For activation use detectionImages instance property. In ARKit 2.0 you can totally track up to 25 images, in ARKit 3.0 and ARKit 4.0 – up to 100 images, respectively. But, in both cases, not more than just 4 images simultaneously. In ARKit 5.0, however, you can detect and track up to 100 images at a time.
  • ARBodyAnchor (соответствует ARTrackable протоколу)

    • In the latest release of ARKit you can enable body tracking by running your session with ARBodyTrackingConfiguration(). You'll get ARBodyAnchor in a Root Joint of CG Skeleton, or at pelvis position of tracked character.
  • ARFaceAnchor (соответствует ARTrackable протоколу)

    • Face Anchor stores the information about the topology and pose, as well as face's expression that you can detect with a front TrueDepth camera or with regular RGB camera. When face is detected, Face Anchor will be attached slightly behind a nose, in the center of a face. In ARKit 2.0 you can track just one face, in ARKit 3.0 – up to 3 faces, simultaneously. In ARKit 4.0 a number of tracked faces depends on a TrueDepth sensor and CPU: smartphones with TrueDepth camera tracks up to 3 faces, smartphones with A12+ chipset, but without TrueDepth camera, can also track up to 3 faces.
  • ARObjectAnchor

    • This anchor's type keeps an information about 6 Degrees of Freedom (position and orientation) of a real-world 3D object detected in a world-tracking session. Remember that you need to specify ARReferenceObject instances for detectionObjects property of session config.
  • AREnvironmentProbeAnchor

    • Probe Anchor provides environmental lighting information for a specific area of space in a world-tracking session. ARKit's Artificial Intelligence uses it to supply reflective shaders with environmental reflections.
  • ARParticipantAnchor

    • This is an indispensable anchor type for multiuser AR experiences. If you want to employ it, use true value for isCollaborationEnabled instance property in MultipeerConnectivity framework.
  • ARMeshAnchor

    • ARKit and LiDAR subdivide the reconstructed real-world scene surrounding the user into mesh anchors with corresponding polygonal geometry. Mesh anchors constantly update their data as ARKit refines its understanding of the real world. Although ARKit updates a mesh to reflect a change in the physical environment, the mesh's subsequent change is not intended to reflect in real time. Sometimes your reconstructed scene can have up to 50 anchors or even more. This is due to the fact that each classified object (wall, chair, door or table) has its own personal anchor. Each ARMeshAnchor stores data about corresponding vertices, one of eight cases of classification, its faces and vertices normals.
  • ARGeoAnchor (соответствует протоколу ARTrackable)

    • In ARKit 4.0+ there's a geo anchor (a.k.a. location anchor) that tracks a geographic location using GPS, Apple Maps and additional environment data coming from Apple servers. This type of anchor identifies a specific area in the world that the app can refer to. When a user moves around the scene, the session updates a location anchor’s transform based on coordinates and device’s compass heading of a geo anchor. Look at a list of supported cities.
  • ARAppClipCodeAnchor (соответствует протоколу ARTrackable)

    • This anchor tracks the position and orientation of App Clip Code in the physical environment in ARKit 4.0+. You can use App Clip Codes to enable users to discover your App Clip in the real world.

введите описание изображения здесь


Существуют и другие стандартные подходы к созданию якорей в сеансе дополненной реальности:

  • Методы проверки попадания

    • Tapping on the screen, projects a point onto a invisible detected plane, placing ARAnchor on a location where imaginary ray intersects with this plane. By the way, ARHitTestResult class and its corresponding hit-testing methods for ARSCNView and ARSKView will be deprecated in iOS 14, so you have to get used to a Ray-Casting.
  • Методы Ray-Casting

    • If you're using ray-casting, tapping on the screen results in a projected 3D point on an invisible detected plane. But you can also perform Ray-Casting between A and B positions in 3D scene. The main difference of Ray-Casting from Hit-Testing is that, when using the first one ARKit can keep refining the ray cast as it learns more about detected surfaces, and Ray-Casting can be 2D-to-3D and 3D-to-3D.
  • Особенности

    • Special yellow points that ARKit automatically generates on a high-contrast margins of real-world objects, can give you a place to put an ARAnchor on.
  • Преобразование ARCamera

    • iPhone's camera's position and orientation simd_float4x4 can be easily used as a place for ARAnchor.
  • Любая произвольная мировая позиция

    • Place a custom ARWorldAnchor anywhere in your scene. You can generate ARKit's version of world anchor like AnchorEntity(.world(transform: mtx)) found in RealityKit.


В этом фрагменте кода показано, как использовать ARPlaneAnchor в методе делегата: renderer(_:didAdd:for:):

func renderer(_ renderer: SCNSceneRenderer, 
             didAdd node: SCNNode, 
              for anchor: ARAnchor) {
    
    guard let planeAnchor = anchor as? ARPlaneAnchor 
    else { return }

    let grid = Grid(anchor: planeAnchor)
    node.addChildNode(grid)
}



AnchorEntity

AnchorEntity - это альфа и омега в RealityKit. Согласно документации RealityKit 2019:

AnchorEntity - это якорь, который привязывает виртуальный контент к реальному объекту в сеансе AR.

Фреймворк RealityKit и приложение Reality Composer были выпущены в WWDC'19. У них есть новый класс с именем AnchorEntity. Вы можете использовать AnchorEntity в качестве корневой точки иерархии любых сущностей, и вы должны добавить ее в коллекцию привязок сцены. AnchorEntity автоматически отслеживает цель в реальном мире. В RealityKit и Reality Composer AnchorEntity находится на вершине иерархии. Этот якорь способен удерживать сотню моделей, и в этом случае он более устойчив, чем если бы вы использовали 100 личных якорей для каждой модели.

Посмотрим, как это выглядит в коде:

func makeUIView(context: Context) -> ARView {
    
    let arView = ARView(frame: .zero)
    let modelAnchor = try! Experience.loadModel()
    arView.scene.anchors.append(modelAnchor)
    return arView
}

AnchorEntity состоит из трех компонентов:

Чтобы узнать разницу между ARAnchor и AnchorEntity, посмотрите ЭТОТ ЗАПИСЬ.

Вот девять кейсов AnchorEntity, доступных в RealityKit 2.0 для iOS:

// Fixed position in the AR scene
AnchorEntity(.world(transform: mtx)) 

// For body tracking (a.k.a. Motion Capture)
AnchorEntity(.body)

// Pinned to the tracking camera
AnchorEntity(.camera)

// For face tracking (Selfie Camera config)
AnchorEntity(.face)

// For image tracking config
AnchorEntity(.image(group: "Group", name: "model"))

// For object tracking config
AnchorEntity(.object(group: "Group", name: "object"))

// For plane detection with surface classification
AnchorEntity(.plane([.any], classification: [.seat], minimumBounds: [1.0, 1.0]))

// When you use ray-casting
AnchorEntity(raycastResult: myRaycastResult)     /* no dot notation */

// When you use ARAnchor with a given identifier
AnchorEntity(.anchor(identifier: uuid))

// Creates anchor entity on a basis of ARAnchor
AnchorEntity(anchor: arAnchor)                   /* no dot notation */

И вот только два случая AnchorEntity доступны в RealityKit 2.0 для macOS:

// Fixed world position in VR scene
AnchorEntity(.world(transform: mtx))

// Camera transform
AnchorEntity(.camera)

Также не лишним будет сказать, что вы можете использовать любой подкласс ARAnchor для AnchorEntity нужд:

func session(_ session: ARSession, didUpdate anchors: [ARAnchor]) {

    guard let faceAnchor = anchors.first as? ARFaceAnchor 
    else { return }

    arView.session.add(anchor: faceAnchor)

    let anchor = AnchorEntity(anchor: faceAnchor)
    anchor.addChild(model)        
    arView.scene.anchors.append(anchor)
}


Визуализация AnchorEntity

Вот пример того, как визуализировать якоря в RealityKit (версия для Mac).

import AppKit
import RealityKit

class ViewController: NSViewController {
    
    @IBOutlet var arView: ARView!
    var model = Entity()
    let anchor = AnchorEntity()

    fileprivate func visualAnchor() -> Entity {

        let colors: [SimpleMaterial.Color] = [.red, .green, .blue]

        for index in 0...2 {
            
            let box: MeshResource = .generateBox(size: [0.20, 0.005, 0.005])
            let material = UnlitMaterial(color: colors[index])              
            let entity = ModelEntity(mesh: box, materials: [material])

            if index == 0 {
                entity.position.x += 0.1

            } else if index == 1 {
                entity.transform = Transform(pitch: 0, yaw: 0, roll: .pi/2)
                entity.position.y += 0.1

            } else if index == 2 {
                entity.transform = Transform(pitch: 0, yaw: -.pi/2, roll: 0)
                entity.position.z += 0.1
            }
            model.scale *= 1.5
            self.model.addChild(entity)
        }
        return self.model
    }

    override func awakeFromNib() {
        anchor.addChild(self.visualAnchor())
        arView.scene.addAnchor(anchor)
    }
}

введите описание изображения здесь

person Andy Fedoroff    schedule 19.10.2018
comment
можем ли мы переопределить свойство протяженности arplaneanchor? Можно ли сделать бесконечную плоскость для привязки обнаруженной плоскости? - person Roshan Bade; 21.08.2019
comment
Энди: Отлично !! Где ты все это нашел? Есть ли страница с учебником, где я могу изучить эти вещи. У меня быстрый вопрос, как автоматически обнаружить объект реального мира, допустим, чемодан? - person raja pateriya; 17.07.2020
comment
Привет, @rajapateriya, пожалуйста, опубликуйте это как ТАК вопрос. P.S. Держу все это в голове)). На данный момент не так много хороших учебных ресурсов. Это потому, что ARKit слишком молод. Кстати, попробуйте прочитать raywenderlich's книгу ARKit. - person Andy Fedoroff; 17.07.2020
comment
Привет, @AndyFedoroff, большое спасибо за подробные ответы! Я и моя команда несколько дней зацикливались на проблеме: / Я опубликовал интересный вопрос: stackoverflow.com/questions/63662318/ Будем рады вашим предложениям! - person Roi Mulia; 31.08.2020