Azure Spatial Anchorsを中心にAR技術を調査し、役に立つシナリオがないか考えてみる

#はじめに
MicrosoftでHoloLensを発明したアレックス・キップマンが、TEDというプレゼン番組で以下のようなことを話されてました。

>数千年後の未来。コンピュータが登場した世紀のことは魅力的かつ奇妙な時代として振り返られることでしょう 歴史上唯一人類が、２次元空間に限定されて生き、自分が機械であるかのように、テクノロジーに接していた時代です。悠久の時の中のこの100年の特異な期間に人類は画面の反対側からコミュニケーションや娯楽や生活の切り盛りをしていました 
https://www.ted.com/talks/alex_kipman_the_dawn_of_the_age_of_holograms?language=ja

要するに、「2Dの画面を使っている現代は人類史上で稀有な特異な状況で、将来的にはコミュニケーションや娯楽など生活のすべては3Dで消費するようになる」という意味だと思っています。

この意見を聞いた時、僕は正直真っ向から反対意見でした。なぜなら3Dより2Dの方が優れていることも多いので、2Dで表現するコンピュータは今後もずっと残ると考えていたからです。物事は2Dに単純化した方が理解しやすいはずだし、実際に仕事のパワポ資料で3Dのグラフなんか出てくると理解し難くてイラっとした経験も多かったからだ。でも、最近9歳になった息子を見ていて考えが変わってきています。彼は2DのWii マリオはなかなか上手にならないが、3DのSwitch マリオ・オデッセイやマリオカートは、すぐ上手になりました。息子に聞いてみると、どうやら2Dの方がわかりにくいらしい。よく考えたら、最近のゲームは子供向けも大人向けも3Dばかり。もしかしたら僕らの世代こそが、2Dに矯正された人類史上稀有な存在かもしれない。2Dモニターに矯正されていない子供は3Dで情報が表現される方が、自然で理解しやすいのかもしれない。もし、そうであれば3Dの方が表現できる情報量が多く、優れたユーザインターフェースのはず。

この考えが合っているか否かは、今後のさまざまな実験で実証していくしかないが、最初、このキップマンの意見に強く反対意見を持った僕の頭の固さに恥ずかしくなった。
やっぱ、アレコレ言ったり考えたりする前に「まず使って、多角的に実験してみることが大事！」だと思う。先入観は敵だ。

# AR関連技術で今回フォーカスすること

MicrosoftのHoloLensが2015年2月にセンセーショナルに発表されて、はや4年。
GoogleとAppleがそれぞれのスマフォでのARプラットフォームを発表した2017年から2年。
今年発表されたHoloLens 2 も普及してきそうな雰囲気があるし、そろそろARってビジネスなど幅広くいろんな場所で活用され始める時期に入るんじゃない？って思い始めたので、とりあえず調べていろいろ実装して使って、活用シナリオがないか考えてみました。

僕の結論からいうと、以下の２つの機能が去年ぐらいからARに実装されたことで活用シナリオが大幅に増え、ビジネスの現場で活用できる時期を迎えたのではないかという見解です。

1. リアルタイムのMachine Learningモデル利用
1. 空間認識情報の保存＆共有

僕的には 1 は予想された進化だったのであんまり驚きはなかったのですが、2は想像してなかった機能なのでその未来感に驚き、知的好奇心をめちゃめちゃくすぐられました。
AR関連技術にはいろいろ面白い技術があり、いろいろ紹介したいのですが、僕的には**「空間認識情報の保存＆共有」**のインパクトが特に強すぎたので、今回はこれについて調査した結果を共有します。

※ARといってもMRと区別しておらず、意味合い的には現実と仮想を合わせた技術を調べてます。のでHoloLensも、調査範囲に含みます。

#AR関連技術の歴史
ざっくりとした歴史はこんな感じ。

- 2015年2月にHoloLensが発表され、ARに注目が集まる
- 2017年、ARKitとARCoreが続けざまに発表され、普通のカメラでのARの可能性が提案される
    - ARCoreが 2017年5月、ARKitが2017年9月
- 2017年12月にGoogleなどが巨額の支援をして話題となったMagic Leapも製品を発表＆販売開始  
- 2018年から現在にかけて
    - HoloLensのMicrosoft、ARCoreとGoogle、ARKitのApple、デバイスはないがSpark AR studioなどでARに存在感を示すfacebookが、かなりのハイスピードでSDKをアップデートし続けている
- 2019年2月 Microsoftが大きく機能を飛躍させたHoloLens 2と新型 Kinectを発表
- 2019年5月8日のGoogle I/Oで、Googleは世の中のものの３DCG化を進めていくような発表
    - New Balanceなど製品メーカーと組んで、靴をCG化したり、サメなどの一般的な動物をCG化したり。


「スマフォの次」と言われる空間ユーザインターフェースは、プラットフォームの巨人のほぼ全員が莫大な投資をしている。そのため、1年に1回といわず、半年に1回くらい革新的な機能が各社から発表されている状況。

# 取り上げる技術

僕はMicrosoftよりの人間なので、Microsoftベースで。しかし、空間座標的なテクノロジーは、MicrosoftがHoloLensで先んじて本気で投資しまくっている領域なだけあって、ひいき目ではなくMicrosoftが品質で抜きんでているように思う。ただ、マインドシェアはやっぱGoogleが圧倒的な感覚がありますが。

### 主な機能

**Microsoft の Azure Spatial Anchors**

- 空間座標を保存し、共有する機能
    - 公式説明サイト
        - https://azure.microsoft.com/ja-jp/services/spatial-anchors/
    - Build 2019 の紹介セッション
        - https://mybuild.techcommunity.microsoft.com/sessions/77246?source=sessions#top-anchor


### その他関連する開発プラットフォーム
1. GoogleのARCore
2. AppleのARKit
3. Unity
4. HoloLens ※テストしたかったが手に入らず、実験できてない。

# 空間認識情報の保存＆共有

この領域は大きく3つの製品がありますが、MicrosoftのAzure Spatial Anchorsをベースにここからは書きます。

| 開発元       |       製品名 |今回のターゲット |
|:-----------------|:------------------|:------------------:|
| Google             |      Cloud Anchor | |
| Apple           |         ARWorldMap | |
| Microsoft           |    Azure Spatial Anchors |○|


### 空間アンカー（Spatial Anchors）は何ができるのか？
- 空間アンカー(仮想のモノ)を現実の物理空間に配置し、その物理空間座標位置を保存できる。
- 保存された空間アンカーを、再度現実の物理空間に再マップする

↓　こんな感じに**物理空間上に空間アンカーを配置でき**、それを保存して後日に再現したり、他人に共有して別デバイスで再現したりできます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74428/22ea35ba-97b9-90d2-5655-ce709a133957.png)


アンカーが配置できるのは、床や机上（重力に対してほぼ平行な平面）と壁（重力に対してほぼ垂直な平面）です。基本この２種類ですが、曲面なども対応し始めているので、数年もすれば、どこにでも配置できるようになると思います。


### 利用例

- 地面に行き先標識板を配置している動画。こういう空間アンカーをユーザが作成し、他人に共有できる
https://www.youtube.com/watch?v=4rndcC2GWNU

- スーパーマーケットでほしいものを入力すると、棚の場所が示される ※以下の動画の17分40秒のところ
https://mybuild.techcommunity.microsoft.com/sessions/77246?source=sessions#top-anchor

- オフィス内での道案内 ※以下の動画の48分20秒のところ
https://mybuild.techcommunity.microsoft.com/sessions/77246?source=sessions#top-anchor

- GoogleのARアプリ。空間に書いた文字を他人と共有できる。
https://www.youtube.com/watch?time_continue=4&v=M5zxNMAQVR0

- 学校から帰ってきたウチの小学生の子にメッセージ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74428/36cb881e-2751-74c3-2a64-08a2e44d3480.png)


### Azure Spatial Anchors の歴史
個人的な見解なので、事実と違う可能性もあります。

- Googleが、Cloud AnchorというサービスをGCPで2018/5に発表。おそらくその ~~パクリ~~ エッセンスを使って開発された製品。2019/2にHoloLens 2と共に発表された
    - Googleは、ARCoreとAppleのARKitにしか対応していないが、MicrosoftはARCoreとARKitに加えてHoloLensにも対応させた。
    - AppleのARKitもARWorldMapという機能があるがiOS専用だったり、クラウドベースじゃなかったりと少し内容が違う。ブログなどにもARWorldMapがあまり載ってなく、存在感がやや薄い。存在感はGoogleのCloud Anchorが圧倒的。

### 物理空間とアンカーの座標マップの仕組み

2つの方法で、空間座標を保存する

1. 特定の位置の空間座標を保存
    - 人の認識と同じくカメラに写る画像の特徴点分析により場所を特定する。大雑把にいうと床の広さや壁の位置、周辺にあるものの形や色などの情報も使っている。そのため、10秒ほど周辺をカメラでスキャンし、場所を特定する。HoloLens、ARKit、ARCoreすべて共通。
    - ↓ 画像から以下のような特徴図に変えて、空間座標を判断するらしい。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74428/5b3c9223-6785-286e-acd5-2749d2ccbd84.png)
※公式サイトから引用 
https://docs.microsoft.com/ja-jp/azure/spatial-anchors/spatial-anchor-faq

2. 相対的な空間座標の保存
    - 空間アンカーと別の空間アンカーにはリレーションを設定でき、空間アンカー間の相対位置を参照できる。そのため、１つのアンカーからリレーションを張られた他のアンカー位置を特定できる。相対座標はジャイロセンサーなどを使って6Dofと呼ばれる座標位置を取得し計算され、導き出される。この機能により、「今居るところから北北東に5Mのところに次のアンカーがある」といったことが実現できる


### 空間アンカーを使ったビジネスアイディア

思いつく限り書いてみる。

- 物理位置共有エンタメ・SNS
    - 旅の見どころをアンカー共有
    - 街の見どころを、順番に案内する。例えばカフェやお寺など
    - 博物館・美術館のガイド
- 正確な位置測定
    - キャッチボールの時にピッチャからキャッチャまでの距離を正確に測れる
    - ライトからホームベースの距離（レーザービームの練習）
    - 街にNPCを配置して、ゲームのように会話したり情報を受け取ったりできるようにする
- 写真と連携
    - ライフログ
        - 10年後に同じ場所で振り返れる
- 行動ログ。数量ごとにアンカー
    - ストア行動分析
        - 買い物カゴを乗せる車にカメラを載せて数秒ごとにアンカー
    - カメラを首からかけてホワイトカラー行動ログ
- 行動の物理位置がとれる
    - 店舗や倉庫の物理チェック結果共有（物理位置も非同期で共有できるようになる）
    - 小売店の店舗内チェックポイントのマーキング
        - 具体的な位置で伝えられる。非同期でチェック内容を共有てきる
    - 倉庫内のチェックポイントのマーキング
- 物理位置の指示の非同期化
    - 建機（ショベルカーなど）の運転手がARで作業場所と作業内容を確認できる
    - さらに発展させるとリモート建機操縦の際にも利用できる
    - 自動運転からのフィードバックの非同期化
    - 自動運転トラクターや運搬車などで、物理的に問題のあった場所でマークし、ログを残す。

### Azure Spatial Anchorsを使って感じた現状課題(2019/5時点)
実験していて、気になった課題をざっと書き出す。

- ARのデバッグがしにくい。
    - iOSのSwift版、AndoroidのJava版はデバッグできそうだが、大本命のUnity版がARのデバッグができない。そのため、実機にデプロイして動作確認になる。※僕の知識がないかもだが、UnityのAR開発の書籍にもデバッグ方法は書いてなかった。
    - Spatial Anchorって、物理的に動いてテストしないといけないので、ケーブルをつけたままだとテストがきつい。５Mくらいの長いケーブルがほしいところ。
- 薄暗いと床を検知しにくい。外で光が強くても床を検知しにくい。
- スキャン時に、特徴に乏しい床などで保存してしまうと、探す時にアンカーが見つからなくなる
    - どういう条件の時に見つからなくなるのか、調査する必要がある
- Near Byで他のアンカーが大幅にずれる時がある。
    - どんな条件の時にズレるのか、調査する必要がある
        - 相対位置はスマフォのセンサーで取得しているので、センサーの精度に依存する。そのため、以下のような要因が考えられる
            - スマフォの機種
            - 移動時のスマフォ振動（走ったりしたときの縦揺れや横揺れ）
            - 移動の速さ
            - **(2019/11/15追記)Androidで実験した結果、ズレは利用時の工夫によって大きく減らすことができることがわかった。ARCoreがジャイロをベースとして座標を検知し、それに加えて２Dカメラ映像を使ってズレの補正を常に行っているような動作をしている(公式サイトには情報がなかったので正しくないかもしれない)。この２Dカメラ映像による補正によって「大幅なズレ」が発生している。つまり、補正が暴発している。**
                - **２Dカメラでの補正が暴発しないようにする方法**
                    - **カメラの映像を遮らない（指などで遮ると大幅にズレる）**
                    - **アンカーを少なくとも5メートル以内間隔にする。離れすぎるとズレる。アンカーがカメラに２つ以上写るくらいの感覚が良い。**
        - おそらくセンサーの品質の差であれば、HoloLensは最強のはず。試してみたい。
            - **(2019/11/15追記)実験した結果Hololensは最強だった。スマホは２Dカメラのみなのに対してHololensはDepth Cameraも使われる。おおまかな実験結果としては、スマホだとスタートから20メートル離れるごとに1メートルほどズレる。Hololenseは100メートルくらい離れても0.5メートル以下しかズレない。**
- Near Byで探せる距離は、サンプルアプリのデフォルトは5Mになっている
    - コードを変えれば変更できる。200Mに変えて動作確認済み。
- アンカーをSaveする時間が長い（10秒くらいかかる）
    - Spatial Anchorsの応答が遅い。Previewじゃなくなったら早くなるかな。
- Startアンカーの位置を忘れてしまう
    - スタートアンカーをコンボボックスで選ぶようにする。そして、スタートアンカー位置の写真も表示しないと、どこだったか覚えていられない。
- スマフォの電池使用量がハンパない。25分使用で25％。ポケGoと同じくらい？

### 課題関して実験した結果
手持ちのPixel3で検証。
**公園でうろうろしながら検証しましたが、不審者と間違われる可能性大なのでご注意ください。**スマフォを立てて歩いている人に近づきたくないですよね？かなり怪しい人です。僕はカモフラージュにウチの子を連れていきました。ARが普及するためには、この不審者っぽさに皆が慣れないといけないというハードルもありますね。


- 相対座標で精度がでる距離
    - 相対座標はスマフォのセンサーで取得いているので、スマフォのセンサー性能に依存するはずだが、実質どれくらいの距離まで使えそうか。
    - 実験したところ30メートルくらいだと、nearbyもほぼズレなかった。50メートルくらいだと5メートルくらいズレたり表示しなかったり。5回くらいやった感じだと30メートルを超えてくるとズレが大きくなり始める
- 床の形状
    - 特徴のない床や、光の反射の激しい床だと平面と認識してくれない
- カメラの前に、スーパーの買い物カートなどが写りこんでいると、床を認識しない。
    - カメラと床との間に大きな障害物があると、だめそう。

### 公式サンプルプログラム

公式サンプルGithub（https://github.com/Azure/azure-spatial-anchors-samples）


##### サンプルのデプロイ方法
先人の方がまとめてくださっているので、ご参照ください。

[公式サイトのサンプルの利用ガイド](https://docs.microsoft.com/ja-jp/azure/spatial-anchors/)
[Azure Spatial Anchors を使って、アンカー情報の共有を行ってみた。【 HoloLens, Google Pixel 3 編 】](https://qiita.com/Futo23/items/2b0991a88a6ca08cfb3b)
[マルチデバイス間でシェアリングできるAzure Spatial Anchorsをやってみた（HoloLens、iOS、ARKit）](https://qiita.com/SatoshiGachiFujimoto/items/0f8e71b5977cba61a290)
[Azure Spatial Anchors v1.1.0 Unity Android版のデモアプリをビルドしてみる](https://qiita.com/bathtimefish/items/8184286b52ecaa358ccd)
[Azure Spatial Anchors v1.1.0 Unity iOS版をビルドしてみる](https://qiita.com/bathtimefish/items/b26354fc9e1992ed032b)

手順どおりやれば、デプロイにはあまりハマりどころはなかったです。
１点ハマったところとしては、UnityでiOSやAndoroidにデプロイした時にカメラが動かなったところでしょうか。

公式サイトに「注意」として書かれてましたが、読んでなくてハマりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74428/e3a513d9-b437-3c38-d6da-93ab80d4544d.png)
※公式サイトから抜粋


##### 公式サンプルで提供されている言語(2019/05/03時点)


- Unity(IDE:Unity＆Visual Studio)
    - C#
- iOS（IDE:X-code）
    - Swift
    - Objective-C
- Android（IDE:Andoroid Studio）
    - java
    - NDK
- HoloLens
    - C++

#####感想
Azure Spatial Anchorsの公式サンプルを使ってみた感想。（5/12時点）
公式のサンプルプログラムの各種プラットフォームほぼすべて(C++以外)試してみて、いいところとまだ悪いところがあったのでその共有。

おすすめはAndroidのJava版。サンプルで提供されている機能がフルセットで入っており、かつコードが読みやすく使いやすい。Build 2019でのデモもJava版だったし、全言語のサンプル読んだ感想ですが、たぶんJava版作った人が一番のトップエンジニアなんじゃないかと勝手に想像しています。

- Unity版（C#)
    - 同じソースでiOS&Android&HoloLensにデプロイできるし、C#だから僕は得意だし、Asetも入手しやすいから迷わずUnity版を使うべきだろうと考えていたが、以下の理由で現状は使いにくく、改善を願いつつ現状はアップデート待ちをする
        - UIがダサい。Android版やiOS版に比べてダサすぎる。カスタマイズしないとデモ映えしない。まず、他のプラットフォームにはある空間スキャン時の「スキャンしてますよ～」アニメーションがないのは致命的な気がするARっぽさがないし、使いにくい。
        - コードが読みにくすぎる。かなり長い時間、読解に挑んだが、あまり理解できなかった。
        - UnityのAR Foundationに対応していないせい？でコードが複雑なのかも。
    - iPhoneやAndroidでデバッグできない。
    - ARアプリはカメラ動かないといけないのでエミュレータでは動作確認できない。そのためiPhoneかAndroidの実機がいる
    - iPhoneはUnityのコードをXcode用のコードでに変換して、XcodeでビルドするのでシームレスさがなくUnityのままのコードでデバッグもできない。
    - AndroidはUnityから直接Androidにデプロイできるが、ブレイクポイントを設定するなどのデバッグモードで実行できない。（これは僕の認識違いかも。）
    - iPhoneやAndroidへの出力には、ビルドなどの時間が数分単位でかかり、待ち時間が苦痛
- iOS版（Swift）
    - Unity版と違い、Xcodeだけで完結し、iPhoneへのデプロイ＆デバッグも早い
    - サンプルに「Shareシナリオ」がない点が欠点
- iOS版（Objective-C）
    - iOS版は、おそらくObjective-CとSwiftの両方に対応するために、まず下位のObjective-Cをベースにライブラリが作れており、SwiftはObjective-Cのライブラリを呼んでいる様子。言語が混じっているせいで読みにくい。僕個人的としてはObjective-Cはいらないから、Swiftで完結させてほしい
- Android版（Java）
    - 最もデバッグしやすいと考えられるサンプル
    - Androidへのデプロイ＆デバッグ開始までの時間が短い（20秒くらい）
    - Android StudioはIntelli Jベースで、いろんな面で使いやすい。（個人的な見解としてはVisual Studioが最高ですが、他のIDEだとIntelliJが2番手だと思う。X Codeは酷くはないが、ちょっと使いやすいとは言えない気がする。）

#####サンプルコードで、たぶんほとんどの人が変更したくなる箇所（Java版で説明）

- Nearby（近くのアンカーを探す）機能で探す範囲がデフォルト5メートルになっている箇所
以下のコードのsetDistanceInMetersのところ。

```java:AzureSpatialAnchorsActivity.java
                AnchorLocateCriteria nearbyLocateCriteria = new AnchorLocateCriteria();
                NearAnchorCriteria nearAnchorCriteria = new NearAnchorCriteria();
                nearAnchorCriteria.setDistanceInMeters(200);
                nearAnchorCriteria.setSourceAnchor(anchorVisuals.get(anchorID).getCloudAnchor());
                nearbyLocateCriteria.setNearAnchor(nearAnchorCriteria);
                // Cannot run more than one watcher concurrently
                stopWatcher();
                cloudAnchorManager.startLocating(nearbyLocateCriteria);
```

- Nearby（近くのアンカーを探す）機能で配置できるアンカーの数。デフォルトは3。
以下のコードのnumberOfNearbyAnchors のところ。

```java:AzureSpatialAnchorsActivity.java
    private String anchorID;
    private final ConcurrentHashMap<String, AnchorVisual> anchorVisuals = new ConcurrentHashMap<>();
    private boolean basicDemo = true;
    private AzureSpatialAnchorsManager cloudAnchorManager;
    private DemoStep currentDemoStep = DemoStep.Start;
    private boolean enoughDataForSaving;
    private static final int numberOfNearbyAnchors = 3;
    private final Object progressLock = new Object();
    private final Object renderLock = new Object();
    private int saveCount = 0;
```

- アプリ画面に表示されるメッセージを日本語化する

以下2ファイルの中のStringのテキストを書き換えればよい。

AzureSpatialAnchorsActivity.java
SharedActivity.java


####別のサンプル
Build2019で、Spatial Anchorsを説明された方が公開していたサンプルGithub
https://github.com/julianparismorgan/AzureSpatialAnchors-NotesAR

空間アンカーを配置後に任意のコメントをつけられる。これだけでプロダクトとして成り立ちそう。すばらしいサンプルです。

 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74428/36cb881e-2751-74c3-2a64-08a2e44d3480.png)

#おわりに

2014年に発売されたOculusのDK2のころからVRを頻繁に使いまくって約5年くらい経ち、たまにデジャブのような感覚で現実世界の映像が3DCGのように感じてしまう時があります。現状のOculus RiftなどのVR映像は、現実世界ほど解像度は高くないのだけれど、没頭していれば人の脳は解像度とか意識しなくなり、映像を抽象化して理解するので、映像から意味を取り出すという作業は現実世界でもVRでも変わらないように感じます。近い将来、ARもメガネ化やコンタクトレンズ化して、ストレスなく使えるようになったら、記憶の中にある映像が3DCGのモノだったか物理的なモノだったかわからなくなるんだろうな。
僕が学生のころは紙も本も音楽CDも、映像のビデオテープも物理的な形があって、部屋の中に溢れかえっていたが、今ではすべてデジタル化されてPCとスマフォの中に入り、その物理的な存在は消えてなくなった。その結果、僕の部屋はあの頃と全く違うレイアウトになっている。ARはこの延長線にある技術だと思う。今後は、テレビやパソコンのモニター、時計、将棋盤、柄のある絨毯、柄のある壁紙、壁の絵、リモコン、インターフォン、など、目を楽しませるためのものはテクスチャーがバーチャルにモノに張り付けられるようになってくるんだろうなと思う。そうなると、現実空間的には無地でシンプルな内装の部屋で済むようになり、今のパソコンのデスクトップ壁紙のように、部屋の内装は切り換えれるようになるんだろうなと。

「将棋しよっか？」「いいよ！」って今だとiPadの2Dの画面を出す家が多くなってきているが、近い未来ではARによってプロの対局で使われる「五寸脚付将棋盤」を現実空間に具現化するようになる。
「卓球しよっか？」「いいよ！」っていうと、手にバナナを持ち、その周りに卓球台とラケットとピンポン玉を具現化するようになる。

RealとVirtualの違いはあれど、確かにそれは昔から人類が慣れ親しんだ3Dの世界で、iPadの2Dの世界中で将棋をしたり、テレビゲームで卓球したりしている方が、不自然に感じるようになってくるんだろうなぁと。なんだか悔しいけど、アレックス・キップマンの言うとおり、現代は2次元の世界に閉じ込められた特異な期間って未来人に言われるんだろうなと、今回の検証を通して感じました。

おわり