ARKit (1)

catcota·2022년 1월 19일
0

ARKit

목록 보기
1/2

Verifying Device Support and User Permission

AR 기능을 쓰는 흐름에는 크게 3가지가 있다.

AR이 앱의 주요한 기능인 경우, AR이 앱의 부차적인 기능인 경우, AR을 이용해 사용자의 얼굴을 인식하는 경우.

첫 번째 경우 back카메라의 사용권한이 있어야하기 때문에 inpo.plist의 UIRequiredDeviceCapabilities 섹션에 arkit key를 추가한다.

두 번째 경우 해당 기기의 isSupported 속성을 확인해야한다. (ARConfiguration subclass의 속성)

세번째 Face trackcing의 경우 font-facing TrueDepty카메라(iphone X)가 필요하기 때문에 반드시 ARFaceTrakingConfiguration.isSupported속성을 이용해 해당기기가 가능한지 확인해야한다.

무엇이 되었건 ARKit를 사용하려면 사용자에게 카메라 사용권한을 받아야한다. ARKit는 따로 기능을 지정하지 않아도 자동으로 유저에게 AR session을 실행하는 경우 권한을 요청한다.

ARKit Xcode 템플릿으로 앱 제작 시작하는 경우 기본적인 카메라 사용 description이 제공된다
(=Info.plist에 NSCameraUsageDescription 키가 추가되어있다. .)

Managing Session Life Cycle and Tracking Quality

World-tracking AR session은 visual-inertial odometry라는 기술을 사용한다. 이 기술은 ARCamera transform으로 표현되는 모션센서를 통한 데이터(기기의 위치, 방향에 대한 정보. pose라고도 불림)를 이용한다. 결국 카메라를 이용한 비주얼적인 정보와(visual complexity or recognizable features) 지속적인 센서데이터가 필요하다는 것.

이러한 변화는 ARSessionObserver 델리게이트 메서드와 ARCamera라는 속성을 이용해 변화를 tracking할 수 있다.

Session의 흐름

  • ARCamera.TrackingState.notAvailable
    : ARCamera.TrackingState.limited(_:) : 기기의 위치(pose) 가능하지만(= 모션센서로 데이터 얻는것 가능) 정확도에 대해선 확신할 수 없을 때. 해당 상태에선 트래킹 퀄리티가 떨어짐. ARCamera.TrackingState.Reason.initializing 상태로 세션이 존재하게 됨
// ARCamera.TrackingState.limited(_:)
case limited(ARCamera.TrackingState.Reason)

// ARCamera.TrackingState.Reason
case initializing 
case relocalizing // interruption이후 다시 ARsession시도하려고 할 때 
case excessiveMotion  // 기기가 너무빨리 움직여서 이미지 기반의 포지션을 트래킹하지 못 할때 
case insufficientFeatures // 카메라를 통해 보여지는 화면이 구분할 만큼 충분하지 않을 때 

ARCamera.TrakingSTate.normal : 기기의 pose가 정확하며 모든 ARKit의 기능이 사용가능하다.

Limited에서 normal 상태 사이에 어떤 일이 있는가?

리밋티드 상태인 이유는 두가지. 플레인엥커를 추가하거나 업데이트하지 않음. Hit-Testing 메소드를 실행했는데 어떤 결과도 제공하지 않았을 때

기기의 상태에 따라 리밋티드 상태로 언제든지 변경될 수 있다(ex : 빈 벽을 카메라로 비추었을 때, 불빛 비추었을 때 등)

리밋상태에서 이유를 알고싶을 땐 ARCamera.TrackingState.Reason 값으로 알아내 보자!

  • hitTest : 실제 세계의 물체를 찾거나 AR anchors를 찾도록 하는 메소드.

Interruption 이후 다시 가상 물체를 위치시킬 때 (relocalizing)

  • sessionShouldAttemptRelocalization(_:) 메소드를 사용해서 relocalization

→ 해당 메소드가 true를 반환하며 ARKit는 방해받기 전 유저의 환경에 대한 정보들(지식들)을 가져와가지고 현재 카메라, 센서데이터와 reconcile한다. = 즉 방해 직전 정보 가져와서 현재 정보랑 합친다는 것. 이 과정중에 tracking state는 limited!(.Reason.relocalizing)

  • 다시 자리잡는 것 성공하면 상태는 nomal로 변경!
  • 만약 방해받기 이전 상태와 완.전.히 다른 상태로 카메라를 이동시키면 무한정 limited상태로 있게 됨! 따라서 유저에세 세션을 다시 시작하라고(run(:option:)resetTraking이용) 해야함.

    이렇게 안하면 절대 다시 물체 트래킹 못함... 명심명심


지속적인(원활한) AR경험을 만들기

버전 12 이후부터는 ARWorldMap 클래스가 ARKit가 세션을 다시 resume하기 위해 필요한 정보를 저장해 둔다.

  • 정보를 저장하는 때는 state가 normal로 변경되었을 때!

  • 클래스를 파일로 저장한 후 interruption이후 다시 relocalization해야하는 경우 등에 사용(앱을 다시 실행하는 경우도 이에 해당한다)

  • anchors도 포함하고 있기 때문에 이전 session(resume하기 이전 세션)의 가상 컨텐츠와 매칭 할 수 있다.

  • ARWorldMap에 이전 세션의 가상 컨텐츠에 대한 정보가 있으니 이 클래스를 이용하면 항상 state를 normal로 바꾸는게 성공할까? → NO. 주위 환경의 변화에 영향을 많이 받는다. 만약 이전 세션과 현재 세션의 차이가 크다면 성공적으로 session을 resume 할 수 없다.


앱 종료 후 다시 켰을 때 같은 AR session으로 돌아오고싶으면 어떻게 하면 되나요?

  1. AR session을 다시 실행하도록 하는 이벤트에 world map을 저장한다

    • 여기서 말하는 world map은 가상물체가 위치한 실제세계의 스냅샷 같은 것

    • 주의사항
      - 세션이 ARFrame.WorldMappingStatus.mapped상태였거나 세션이 실행되는 동안 단 한번이라도 해당 상태였어야 한다.

  2. initialWorldMap 속성을 이용해서 저장했던 world map을 relocalize한다.

    • 전체적인 흐름 :
      세션은 ARCamera.TrakingState.limited(_:) 상태 → ARKit(initialWorldMap)가 world map 과 현재 환경을 reconcile → 상태가 normal로 변경 → 기록된 world map과 세션이 매치되는지 표시해준다.

    • 주의사항

      • 반드시 동일한 world map 일 수 있도록 유저에게 노티를 줘야한다. (ex : 요기가서 카메라를 가져다 대세요! 안그럼 안나옴! 등등)
  • 만약 해당 가상 컨텐츠가 반드시 화면에 표시되어야 하는경우 세션상태가 normal 가 된 후 물체를 표시하도록 해야한다. 이 때 name 속성을 사용해서 가상 컨텐츠를 구분하고 이 가상컨텐츠가 위치한 앵커를 구분할 수 있다. 이 앵커들은 세션을 다시 시작할 때 가상컨텐츠를 만들기 위해 사용됨.
  1. 만약 이전 세션의 환경과 reconcile하는게 실패한 경우 세션의 상태는 다시 resume하지 않는 이상 relocalizing상태!(indefinitely)
    ⇒ 세션이 relocalizing 상태에서 벗어나려면 run(:option:)resetTraking이용

요약

  • 세션의 상태는 normal 이어야 정상적으로 가상물체를 화면에 표현할 수있다.
  • interruption 상태인 이유
    1. 카메라로 비추는 환경이 너무 빠르게 바뀌는 경우 excessiveMotion
    2. 이전 세션에 저장된 world map과 현재 상태가 다른 경우 relocalizing
    3. 환경이 너무 밝거나 어둡거나 등 환경 구분이 어려울 때 insufficientFeatures
    4. 아직 초기화 중일 때 initializing
  • 세션을 다시 시작해야하는경우 : relocalizing 실패한 경우!
    • 이전 세션에서 저장했던 worldMap이 현재 세션의 환경과 너무 다른 경우
    • limited상태에서 normal로 변경하려고 했는데 현재 상태가 방해받기 전 상태와 다른 경우 (ex : 카메라를 통해 가상컨텐츠를 보고 있었는데 잠깐 알림와서 해당 화면에서 나가서 알림 끄고 왔는데 카메라가 비추고 있는 화면이 직전과 다른 경우)

참고문서

  1. Verifying Device Support and User permission

  2. Managing Session Life Cycle and Tracking Quality

profile
to be iOS Developer

0개의 댓글