WWDC17でのARKitセッションの動画のメモ

WWDC17の[Introducing ARKit: Augmented Reality for iOS](https://developer.apple.com/videos/play/wwdc2017/602/)を見ながら取ったメモです。

自分で見返しやすいように、あるいは今後見る人に役立つかもしれないので、ここにそのメモを公開しておきます。動画を見ながら書いたのでtypoや間違いがあるかもしれません。

## 「Introducing ARKit」のメモ

- Overview　〜3:30

- Tracking 3:30〜
  - Track your device in real time
  - World tracking・・・物理的環境の中であなたの相対的位置を取得できる
  - Visual inertial odometryという手法を使って、カメラからの入力とデバイスのモーションデータを利用して、デバイスの位置と向きを高精度に推定している
（Inertial: 慣性、 Odometry: 走行距離計測法）
  - No external setup - 利用する環境についての情報とか、追加センサーも必要ない

- Scene Understanding 4:15〜
  - Plane detection
  - Hit-testing
  - Light estimation

- Rendering 5:10〜
  - Easy integration
  - AR views
  - Custom rendering

- Unity & Unreal 5:40〜

- アーキテクチャ（6:09〜）
  - Processing・・・ARKit
  - Rendering・・・SceneKit, SpriteKit, Metal
  - （ARKitの下に）Capturing・・・AVFoundation, Core Motion

- ARKitの使い方（6:40〜）
  - ARKitはセッションベースAPI
  - まず、ARSessionをつくる・・・ARSessionはすべての処理をコントロールするオブジェクト
  - どんな種類のトラッキングを行いたいか、をARSessionConfigurationで設定する
  - ARSeesionのrunメソッドでトラッキングが開始される
  - AVCaptureSessionとCMMotionManager
  - 毎フレームARFrameが得られる

- ARSessionConfiguration（8:10〜）
  - ARWorldTrackingSessionConfiguration・・・ARSessionConfigurationのサブクラス

- ARSession（9:40〜）
  - run(configuration)
  - pause()
  - pauseからのresume（runをまた呼ぶ）、configの変更（runをまた呼ぶだけ）
  - Reset tracking・・・run(_:options:) に .resetTracking を渡す。全てのトラッキングを最初期化し、カメラは0,0,0からスタートする
  - ARSessionDelegate
  - session(_:didUpdate:)・・・第2引数で直近で処理したARFrameが得られる

- ARFrameから得られる情報（11:30〜）
  - Captured image
  - Tracking information
  - Scene information

- ARAnchor（12:10〜）
  - 実世界における位置と向き
  - ARSessionがadd/removeできる
  - バーチャルオブジェクトを実環境（physical embironment）にアンカーするのに利用する
  - 自動でも追加される
  - ARFrame `anchors` シーン内にあるアンカーのリスト
  - ARSessionDelegate アンカーがセッションからadd/update/removeすると呼ばれる

- Tracking詳細（13:10〜）
  - デバイスをパンさせても、空間内を歩いても、イスはその位置に固定されている
  - これはつまり、コンスタントにその仮想オブジェクトを描画するためのprojection matrixを更新しているということ

- World Tracking（14:00〜）
  - visual inertial odometryという技術を利用
  - 位置と向きを推定する
  - Physical distances・・・実世界におけるscaleも推定する。距離（メートル）も得られる
  - 開始位置からの相対位置
  - 3D feature points

- コード（15:44〜）
  - 「最小実装」として最初にこれを提示するの良さそう

- CMMotionManagerとAVCaptureSessionとARSessionのフレームレート（16:00〜）
  - CMMotionManagerのレートはCaptureSessionより細かく
  - ARSessionのフレーム取得はCaptureSessionのフレーム取得より少し後

![Screen Shot 2017-07-17 at 13.01.20 copy.png](https://qiita-image-store.s3.amazonaws.com/0/3180/d46ca30d-e646-17eb-7ed6-38bfbbbb490f.png)

- ARCamera （17:00〜）
  - Camera intrinsics・・・カメラの内部パラメータ・・・focal length, principal point

- デモ：はじめてのARKitアプリをつくる（17:30〜）
  - ライブコーディング
  - 各角度で撮ったスナップショットをその撮影位置に固定表示する

- 最高品質でのTracking結果を得るには（23:45〜）
  - Uninterrupted sensor data・・・たとえばカメラからのデータが得られなくなったらトラッキングは停止してしまう
  - Textured environments
  - Static scenes

- Tracking State（24:40）
  - この図わかりやすい
  - ARSessionDelegateのメソッドが呼ばれる

![Screen Shot 2017-07-17 at 13.22.19 copy.png](https://qiita-image-store.s3.amazonaws.com/0/3180/5c8904df-887d-c50d-86a7-cec193968dfb.png)

- Session Interruptions（25:50）
  - ARSessionDelegateのメソッドが呼ばれる

- [Scene Understanding]　（27:00〜）人が交代
  - Scene Understandingとは、みたいな話
  - planeDetectionをオフにするには、.noneを渡せばよい

- ARPlaneAnchor（30:10〜）
  - ARAnchorのサブクラス・・・現実世界においける位置と向きを表す
  - Transform
  - Extent・・・シーン内を移動すればその水平面についてもっと知ることができるのでextentはアップデートされる
  - Center

- Hit-Testing（31:50）
  - infinite planeの意味もここでわかった。extent内だけhitするようにするか、その平面が無限に続くものとしてhitさせるか、という話
  - Feature points から水平面を推定する話も出てくる（33:50〜）

- コード例（34:30）
  - ヒットテストの結果は配列で返ってくる、前にあるものほどカメラに近い
  - その結果から新しいアンカーを作り、それをセッションにaddする、みたいな使い方ができる

- Light Estimation
  - 困る事例（36:30）・・・暗いシーンでオブジェクトが暗くならない・・・これを回避するのがLight Estimation

- デモ（38:20〜）
  - Debug Visualizationオン　→　ひとつの平面を見つける。すばやくカメラを動かすと、また別の平面を見つける。そしてゆっくり最初の平面の方にカメラを移動させると、２つの平面がひとつの平面に統合される
  - カメレオンのモデルを、ユーザーのカメラの方に顔が向くようにinteractさせられる
  - カメレオンのモデルの色を、背景色になじむように変化させる

- レンダリング方法（43:10〜）
- SceneKitでのレンダリング
  - ARSCNView・・・SCNViewのサブクラスであり、ARSessionへの参照を持つ
    - Draws captured image
    - Updates a SCNCamera
    - Updates scene lighting
    - Maps SCNNodes to ARAnchors

- SpriteKitでのレンダリング
  - ARSKView・・・ARSessionへの参照を持つ
  - Draws captured image
  - Maps SKNodes to ARAnchors
  - Sprites are billboarded to physical locations

- Metalを用いたカスタムレンダリング
  - Draw camera background
  - Update virtual camera
  - Update lighting
  - Update transforms for geometry
  - 逆行列とるのに、simd_inverse() ってのがある？おそらくAccelerateを使った独自関数？

![Screen Shot 2017-07-17 at 14.09.37 copy.jpg](https://qiita-image-store.s3.amazonaws.com/0/3180/6b06f336-d689-6b89-9339-528766dff6f5.jpeg)

---

## なぜこんなメモを取ったのか？

AppleのWWDCの動画は重要で、プログラミングガイドやAPIリファレンスに乗ってない情報をさらっと動画で言ってたりするので、立派な**公式情報リソースのひとつ**です。

そんな貴重なWWDCのセッション動画ですが、個人的には

- 「あの仕様、リファレンスには書いてないけどどこで言ってたんだっけ？」
- 「あの図良かったんだけど何年のどこで見たんだっけ？」
- 「これ説明難しいんだけどAppleの人はどう説明してたのかな」

となることが多いのですが、そうなってからまた**50分の英語の動画を見直すのもつらい**ので、（そのネタで[本を書く](https://peaks.cc/shu223/iOS11)ようなときは）こうやって自分でインデックス付けしたりスクショ撮ったりしながら見るようにしてます。

いや、実際のところ、最近は**公式動画にTranscriptが付く**ようになったので、後から検索したりするにはそれで十分だし、メモ取りながらだと結果的に動画全体を見る時間が実時間よりもかかったりもするのですが、この方が「おれは学んでいるぞ！」という実感があって**完走しやすい**というメリットもあります。



## ARKitの参考書籍

こんなメモ的な記事の後だと逆PRになってしまうかもしれませんが・・・つい先日発売された「iOS 11 Programming」という技術書にて、ARKitの章の執筆を担当させていただきました。

一般販売はされてなくて、PEAKSというサイトでのみご購入いただけます。

<div class="peaks_widget" style="overflow:hidden; padding:20px; border:1px solid #dedede;"><div class="peaks_widget__image" style="float:left; margin-right:15px; line-height:0;"><a target="_blank" id="purchase" href="https://peaks.cc/shu223/iOS11"><img alt="iOS 11 Programming" style="border:none; max-width:140px;" src="https://s3-ap-northeast-1.amazonaws.com/peaks-images/project002_cover.jpg" width="500"></a></div><div class="peaks_widget__info"><p style="margin:0 0 3px 0; font-size:110%; font-weight:bold;"><a target="_blank" id="purchase" href="http://peaks.cc/shu223/iOS11">iOS 11 Programming</a></p><ul style="margin:0; padding:0;"><li style="font-size:90%; list-style:none;"><span>著者：</span><span>堤 修一,</span><span>吉田 悠一,</span><span>池田 翔,</span><span>坂田 晃一,</span><span>加藤 尋樹,</span><span>川邉 雄介,</span><span>岸川克己,</span><span>所 友太,</span><span>永野 哲久,</span><span>加藤&#160;寛人,</span></li><li style="font-size:90%; list-style:none;">発行日：2017年11月16日</li><li style="font-size:90%; list-style:none;">対応フォーマット：製本版,PDF</li><li style="font-size:90%; list-style:none;"><a target="_blank" id="purchase" style="text-decoration:underline; color:#1DA1F2;" href="http://peaks.cc/shu223/iOS11">PEAKSで購入する</a></li></ul></div></div>

こんな感じの章立てになってまして、

- 第1章　iOS 11 概要
- 第2章　ARKit
- 第3章　Core ML
- 第4章　Swift 4の新機能とアップデート
- 第5章　Xcode 9 の新機能
- 第6章　Drag and Drop
- 第7章　FilesとDocument Based Application
- 第8章　レイアウト関連の新機能及び変更点
- 第9章　Core NFC
- 第10章　PDF Kit
- 第11章　SiriKit
- 第12章　HomeKit入門とiOS 11のアップデート
- 第13章　Metal
- 第14章　Audio関連アップデート


執筆を担当したARKitの章は、3行で書けるサンプルからスタートして、平面を検出する方法、その平面に仮想オブジェクトを設置する方法、そしてその仮想オブジェクトとインタラクションできるようにする方法…と、**読み進めるにつれて「作りながら」引き出しが増えていく**よう構成しています。

- 第2章　ARKit
  - 2.1 はじめに
  - 2.2 ARKit入門その１ - 最小実装で体験してみる
  - 2.3 ARKit入門その２ - 水平面を検出する
  - 2.4 ARKit入門その３ - 検出した水平面に仮想オブジェクトを置く
  - 2.5 ARKit開発に必須の機能
  - 2.6 特徴点（Feature Points）を利用する
  - 2.7 AR空間におけるインタラクションを実現する
  - 2.8 アプリケーション実装例１: 現実空間の長さを測る
  - 2.9 アプリケーション実装例２: 空中に絵や文字を描く
  - 2.10 アプリケーション実装例３: Core ML + Vision + ARKit
  - 2.11 Metal + ARKit

ARKitの章だけでも30ページ以上あります。最終的にはARKitを用いた巻尺（メジャー）や、空間に絵や文字を描くといったアプリケーションの実装ができるようになります。

![](http://cdn-ak.f.st-hatena.com/images/fotolife/s/shu223/20171128/20171128085004.jpg)


版元のPEAKSのサイトで[サンプルPDF](https://peaks.cc/shu223/iOS11)も読めるので、気になった方はぜひお試しください。

- [PEAKS（ピークス）｜iOS 11 Programming](https://peaks.cc/shu223/iOS11)