Azure Spatial Anchors を使って、アンカー情報の共有を行ってみた！【 HoloLens, Google Pixel 3 編 】

#はじめに ( ※執筆途中 )
__[MWC 2019 Microsoft 基調講演 （ Mobile World Congress @ Barcelona ）](https://youtu.be/rOeAek-Ltoo)__で発表された、
「 __Azure Spatial Anchors__ 」を使って、```HoloLens``` と ```Google Pixel 3``` のアンカー情報を共有してみる。

<img src="https://qiita-image-store.s3.amazonaws.com/0/180432/ba9d19ec-10ba-450c-506b-ebda6c7aead9.png" width="800">
__[Azure Spatial Anchors ( Preview ) ](https://azure.microsoft.com/ja-jp/services/spatial-anchors?WT.mc_id=MR-MVP-5003868) | Microsoft Azure ( 公式サイト )__

# 目次
__1. What's <font color="black">Azure Spatial Anchors</font> !?__
__2. 本記事を読んで実現できること__
__3. 前提条件 ( 開発環境 )__
__4. ```HoloLens``` 単体サンプル 動作確認 ( Unity )__
__5. アンカー共有サービス ( ASP.NET ) をデプロイする__
__6. ```HoloLens``` , ```Google Pixel 3``` で仮想オブジェクトの配置情報を共有する ( Unity )__
__7. 終わりに__

# 1. What's __Azure Spacial Anchors__ !?
<font color="black">__現実空間をトラッキングしたデータ ( 空間情報 ) をクラウド上で管理・複数端末間で共有できるサービスです。__</font>
本サービスを利用することで、<font color="black">__アンカー情報 ( 空間トラッキング + 仮想オブジェクトの配置位置 ) を、
複数端末で、永続的に (再)利用することが可能__</font> になります。

> <img src="https://img.esa.io/uploads/production/attachments/3505/2019/03/22/10862/460b8a42-2fab-4ee7-aac7-fe36e508ef95.gif" width="800">
「 [Tutorial: Sharing across sessions and devices with Azure Spatial Anchors](https://docs.microsoft.com/ja-jp/azure/spatial-anchors/tutorials/tutorial-share-anchors-across-devices?WT.mc_id=MR-MVP-5003868) 」より抜粋。


> _拡張現実 (AR) プラットフォームでは、"アンカー" は、_ <font color="red">__複数のユーザーが同じ物理的な場所にデジタル コンテンツを配置できるようにするための共通座標系__</font> _です。さまざまなデバイスで、環境を基準に同じ位置と向きでコンテンツを表示できます。Azure Spatial Anchors を使用すると、アンカーの永続性とアクセス許可を追加し、ユーザーが近くのコンテンツを見つけることができるように、アプリケーション内でアンカーに接続できます。「_ __[Azure Spatial Anchors](https://azure.microsoft.com/ja-jp/services/spatial-anchors?WT.mc_id=MR-MVP-5003868)__ _」より抜粋。_


## クロスプラットフォーム対応
__Azure Spatial Anchors__ は、以下、__クロスプラットフォームのマルチデバイス__に対応しています。

- __[Microsoft HoloLens](https://www.microsoft.com/ja-jp/hololens)__
- __[iOS端末 ( ARKit 対応 ) ](https://developer.apple.com/library/archive/documentation/DeviceInformation/Reference/iOSDeviceCompatibility/DeviceCompatibilityMatrix/DeviceCompatibilityMatrix.html)__ 
 - iOS 11.0 or later 〔 ex. iPhone SE 以降 〕
- __[Android端末 ( ARCore 対応 ) ]((https://developers.google.com/ar/discover/supported-devices))__
 - Android 7.0 or later 〔 ex. Pixcel 3, Galaxy S9 〕

# 2. 本記事を読んで実現できること
```Microsoft HoloLens```と、```Google Pixel 3``` の2つのデバイス間で、空間情報を共有する。

__[ 動画 ] を張り付ける！__


## 想定されるユースケース ( Azure Spatial Anchors )

> - <font color="black">__マルチユーザーエクスペリエンス__</font>  
ー ( マルチユーザー、マルチデバイスでの体験共有 )
- <font color="black">__道案内__</font>  
ー ( アンカー情報のリレーションシップ作成 )
- <font color="black">__仮想オブジェクトの現実世界での永続化__</font>  
ー ( 配置した仮想オブジェクトの配置位置データを記録 )

>「 [Azure Spatial Anchors overview](https://docs.microsoft.com/ja-jp/azure/spatial-anchors/overview?WT.mc_id=MR-MVP-5003868) 」より、抜粋。

---

#### 【 参考 】 __Google Pixel 3 ( XL )__ で、「 __Azure Spatial Anchors__ 」を試してみた！
会社の先輩の ```Google Pixel 3 XL``` を無理やりパクリ、以下__Android端末 2台__で動作検証してみました。

- __Google Pixel 3__ ( ```検証用端末``` )
- __Google Pixel 3 XL__ ( @torisankanasan の私物 )

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">Azure Spatial Anchors、Google Pixel 3 (XL)で動かしてみました！想像以上に、精度が良い。<a href="https://twitter.com/hashtag/Azure?src=hash&amp;ref_src=twsrc%5Etfw">#Azure</a> <a href="https://twitter.com/hashtag/AzureSpatialAnchors?src=hash&amp;ref_src=twsrc%5Etfw">#AzureSpatialAnchors</a> <a href="https://twitter.com/hashtag/Pixel3XL?src=hash&amp;ref_src=twsrc%5Etfw">#Pixel3XL</a> <a href="https://t.co/Vd2YagwjRu">pic.twitter.com/Vd2YagwjRu</a></p>&mdash; Futo Horio@xRエンジニア (@Futo_Horio) <a href="https://twitter.com/Futo_Horio/status/1110816076151951361?ref_src=twsrc%5Etfw">2019年3月27日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

---


# 3. 前提条件 ( 開発環境 )

- __Surface Book 2__ ( ```Windows 10 Pro``` )
 - __Unity__ ( ```2018.3.8f1``` )    
  - __[ARCore SDK for Unity v1.7.0](https://github.com/google-ar/arcore-unity-sdk/releases)__
 - __Microsoft Visual Studio__ ( ```Community 2017``` )
 - __Android Studio__ ( ```3.3.2``` )
- __Azure アカウント__ ( ```発行済み``` ) 
- __デプロイ端末__ 
 - __Android端末__ ( ex. ```Google Pixel 3``` )
 - __Windows端末__ ( ex. ```HoloLens``` )
 - __iOS端末__ ( ex. ```iPhone XS``` )


# 4. HoloLens 単体サンプル 動作確認 ( Unity )
本章では、以下、公式チュートリアルに従い、作業を進めます。

- __[クイック スタート : Azure Spatial Anchors を使用して HoloLens Unity アプリを作成する](https://docs.microsoft.com/ja-jp/azure/spatial-anchors/quickstarts/get-started-unity-hololens?WT.mc_id=MR-MVP-5003868)__

## 開発環境

- __開発環境__
 - __Windows 10 Pro__ ( 開発者モード オン )

- __デプロイ端末__
 - __Microsoft HoloLens__ ( Windows 10 - Build xxx )

## (1) Spatial Anchors リソースを作成する ( Azure Portal )
「```リソース作成```」ボタンを押下し、「```Spatial Anchors```」を検索する。
<img src="https://qiita-image-store.s3.amazonaws.com/0/180432/e80413bf-a45b-5939-36e7-2d030b90b998.png" width="800">

画面左下に表示される「```作成```」ボタンを押下する。
<img src="https://qiita-image-store.s3.amazonaws.com/0/180432/d2e7dcb2-013c-3c6d-dde4-b2768f841b00.png" width=400">

「```*リソース名```」「```*サブスクリプション```」「```*リソースグループ```」「```*リージョン ( 場所 ) ```」を指定します。
※ リージョンに関しては、現時点で「```East US 2 ( 米国東部 2 )``` 」のみ選択可 (2019/03/27)

<img src="https://qiita-image-store.s3.amazonaws.com/0/180432/57375993-9f39-bdc2-f685-9f3c074c03bf.png" width="800">

「```アカウントID ( = Account ID )``` 」と「```プライマリキー ( = Accout Key )``` 」をメモします。
※ 後で、Unity上で使用します。
<img src="https://qiita-image-store.s3.amazonaws.com/0/180432/c8170b97-0176-7f18-a7ea-ec715832bd34.png" width="800">
<img src="https://qiita-image-store.s3.amazonaws.com/0/180432/192281eb-ca8c-2797-b7d5-a8c46d3d22f8.png" width="800">

以上で、Azure Portalでの作業は終了です。

## (2) Unity上で、サンプルプロジェクトを開きます。
VSCode ターミナルより、```git clone```を実行する。

```
git clone https://github.com/Azure/azure-spatial-anchors-samples.git
```

<img src="https://qiita-image-store.s3.amazonaws.com/0/180432/90c3ce99-cf7b-614c-2a98-95b76d587bf4.png" width="800">

<img src="https://qiita-image-store.s3.amazonaws.com/0/180432/d02e7f9b-2b1d-8e96-cb80-85a0d61cb8dd.png" width="800">

クローンができたら、Unity上でプロジェクト ( Unityフォルダ ) を読み込みます。
このサンプル自体が、__Unity 2018.3.6f1__ で開発されているため、アラートが表示されますが、
__「 Continue 」__ ボタンを押下し、次に進みます。

<img src="https://qiita-image-store.s3.amazonaws.com/0/180432/804b0edb-94db-ea64-e4b6-2d0c63a556d7.png" width="400">

```File``` > ```New Scene``` より、以下シーンファイルを開きます。
```Assets/AzureSpatialAnchorsPlugin/Examples/AzureSpatialAnchorsBasicDemo.unity```
<img src="https://qiita-image-store.s3.amazonaws.com/0/180432/22438271-55bc-c167-4f6f-1db4895db661.png" width="800">

__AzureSpatialAnchors__ にアタッチされている「 ```AzureSpatialAnchorsDemoWrapper``` 」に以下、値を入力します。

- __Spatial Anchors Id__ ( = Account Id )
- __Spatial Anchors Key__ ( = Primary Key )

<img src="https://qiita-image-store.s3.amazonaws.com/0/180432/1ea308a6-08f8-9d4f-2dc2-816fcb83585d.png" width="800">

シーンの保存が終われば、次はUWP用のビルド設定を行います。
```Ctrl + Shift + B``` にて、「__Build Settings__」タブを開き、
プラットフォームを「__UWP__」、ターゲットデバイスを「__HoloLens__」に変更し、
「__Switch Platform__」ボタンを押下します。

※ プラットフォームをUWPに変更した途端、シーン選択領域が狭くなります、、。汗
<img src="https://qiita-image-store.s3.amazonaws.com/0/180432/045377ab-445d-dfb8-7f67-a501433de6c2.png" width="800">

エクスポート先のディレクトリ「__UWP__」を新規作成し、ビルドを実行します。
<img src="https://qiita-image-store.s3.amazonaws.com/0/180432/65d78a6b-6b4d-3de5-4c1d-da49528f4d11.png" width="800">

<img src="https://qiita-image-store.s3.amazonaws.com/0/180432/bded6408-c89f-793b-177b-25faf79aa1c3.png" width="800">

## (3) 実機確認 ( HoloLens )
では、実機で動作確認してみましょう。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr"><a href="https://twitter.com/hashtag/MWC19?src=hash&amp;ref_src=twsrc%5Etfw">#MWC19</a> Microsoft 基調講演で、<a href="https://twitter.com/hashtag/HoloLens2?src=hash&amp;ref_src=twsrc%5Etfw">#HoloLens2</a> と共に発表された、「Azure Spatial Anchors」の公式チュートリアル試してみた。「AzureSpatialAnchorsBasicDemo ( Unity ) 」<a href="https://twitter.com/hashtag/HoloLens?src=hash&amp;ref_src=twsrc%5Etfw">#HoloLens</a> <a href="https://twitter.com/hashtag/Azure?src=hash&amp;ref_src=twsrc%5Etfw">#Azure</a> <a href="https://twitter.com/hashtag/AzureSpatialAnchors?src=hash&amp;ref_src=twsrc%5Etfw">#AzureSpatialAnchors</a> <a href="https://t.co/eMxS2DUhKc">pic.twitter.com/eMxS2DUhKc</a></p>&mdash; 堀尾 風仁 / Futo Horio (@Futo_Horio) <a href="https://twitter.com/Futo_Horio/status/1109019576426065920?ref_src=twsrc%5Etfw">2019年3月22日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

> __【 サンプルアプリ処理フロー 】__
Next: Create Azure Spatial Anchors Session
Next: Configure Azure Spatial Anchors Session
Next: Start Azure Spatial Anchors Session
Tap a surface to add the Local Anchor
Next: Save Local Anchor to cloud
Saving local Anchor to cloud...
Next: Stop Azure Spatial Anchors Session
Next: Create Azure Spatial Anchors Session for query
Next: Start Azure Spatial Anchors Session for query
Next: Look for Anchor
Looking for Anchor...
Next: Delete Anchor
Next: Stop Azure Spatial Anchors Session for query
Next: Restart demo


Azure Portal 画面上からも、正常に動作していることが確認できます。
<img src="https://qiita-image-store.s3.amazonaws.com/0/180432/dad10d97-6015-9496-da5c-f34e789de6a2.gif" width="800">

# 5. アンカー共有サービス ( ASP.NET ) をデプロイする。
マルチデバイス間で、アンカー情報をやり取りするためのWebアプリをデプロイします (サンプル)

### (1) Visual Studioを開き、「Sharing\SharingServiceSample」フォルダーを開きます。
<img src="https://qiita-image-store.s3.amazonaws.com/0/180432/7dab262d-7e54-8a5e-58c0-6a3e44c2c8dc.png" width="400">

### (2) 「SharingService.sln」をダブルクリックします。
<img src="https://qiita-image-store.s3.amazonaws.com/0/180432/8fa51b52-d3c9-bf7c-8ad1-884c9ddb2e06.png" width="400">

### (3) 「Azure App Service」を発行します。 ( Azure ログイン済み )
発行先を__「 App Service 」__に選択し、発行ボタンを押下。
<img src="https://qiita-image-store.s3.amazonaws.com/0/180432/bf8d466a-d15b-5d2a-48ed-6c5919d562d8.png" width="800">

### (4) 「App Service」のリソース、サブスクリプション等を指定し、作成ボタンを押下する。
[※ 基本は、デフォルトのままでOK！](https://docs.microsoft.com/ja-jp/azure/spatial-anchors/tutorials/tutorial-share-anchors-across-devices)
<img src="https://qiita-image-store.s3.amazonaws.com/0/180432/ddacf89f-5feb-4491-e8a2-5a42d28491f0.png" width="800">

### (5) 作成ボタンを押下すると、アプリが発行されます。(1~2分)
<img src="https://qiita-image-store.s3.amazonaws.com/0/180432/4047303b-4775-2023-67e3-21c3bb7b6232.png" width="800">


### (6) アプリの発行が終わると、ブラウザ上でアプリが起動します。
<img src="https://qiita-image-store.s3.amazonaws.com/0/180432/ab1f351d-5ebe-3826-907a-04c32eecfd12.png" width="800">

<font color="red">__※ 後で、こちらのURLを使用するので、メモしておくこと。__</font>

```
https://sharingservice-xxxxxxxxxxx.azurewebsites.net/index.html
```


# 6. ```HoloLens``` , ```Google Pixel 3``` で仮想オブジェクトの配置情報を共有する ( Unity )
本章では、```HoloLens``` と、 ```Google Pixel 3``` のデバイス間で、アンカー情報の共有をしてみたいと思います。

- __[チュートリアル : Azure Spatial Anchors を使用したセッションやデバイス間での共有](https://docs.microsoft.com/ja-jp/azure/spatial-anchors/tutorials/tutorial-share-anchors-across-devices)__


## (1) 必要な作業項目

- __<font color="silver">Azure Spatial Anchors 作成 ( Azure Portal )</font> <font color="red">※ 作成済み</font>__
- __<font color="silver">Azure App Service ( Web Apps ) 作成</font> <font color="red">※ 作成済み</font>__

_( --- 以下、新たに作業が必要となります --- )_

- __[GitHubサンプル](https://github.com/Azure/azure-spatial-anchors-samples) 「 AzureSpatialAnchorsLocalSharedDemo.unity 」 を実機へデプロイ__
 - __Android向けアプリをデプロイ ( Google Pixel 3 )__
 - __UWP向けアプリをデプロイ ( HoloLens )__
 - __<font color="silver">iOS向けアプリをデプロイ ( iPhone XS )</font> <font color="red">※TBD</font>__

---

### 6-1. Android向けアプリをデプロイ ( ```Google Pixel 3``` )
__[【 Unity 】Android 開発環境の構築手順](https://qiita.com/Nossa/items/4b2c5026698ed4ab7d2b)__　を参考に、Andoroid向けのビルド環境を整える。

__【 環境構築 ( 手順 ) 】__

- __Android Studio インストール__
- __Java JDK ( Java Development Kit ) インストール__
- __Android NDK ( Native Development Kit ) セットアップ__

後述の理由にて、なかなかAndroidアプリがうまく動作しなかったので、
まずARCoreのサンプルプログラムで、「 __Hello AR__ 」をしてみた。

---
#### 【 参考 】 __ARCore__ で、「 __Hello AR__ 」してみた！

```Google Pixel 3``` で、```ARCore``` に入門してみた！ __( 動画 )__
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">AzureSpatialAnchorsをどうしてもAndroidで動かしてみたかったので、ARCoreに入門してみた。<a href="https://twitter.com/hashtag/ARCore?src=hash&amp;ref_src=twsrc%5Etfw">#ARCore</a> <a href="https://twitter.com/hashtag/HelloAR?src=hash&amp;ref_src=twsrc%5Etfw">#HelloAR</a> <a href="https://t.co/8L2XLCO6m1">pic.twitter.com/8L2XLCO6m1</a></p>&mdash; Futo Horio@xRエンジニア (@Futo_Horio) <a href="https://twitter.com/Futo_Horio/status/1110547133277429761?ref_src=twsrc%5Etfw">2019年3月26日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

Hello World できた瞬間は、いつだって嬉しいですね。笑

---

#### Unity上で、サンプルコードを開きます。
[ ```Azure-Spatial-Anchors-Samples``` ] > [ ```Unity``` ]
<img src="https://qiita-image-store.s3.amazonaws.com/0/180432/02348bad-5e35-800d-ad87-cfe48e61e158.png" width="600">

#### サンプルシーンを開き、各種値を入力します。
「 ```Unity\Assets\AzureSpatialAnchorsPlugin\Examples\AzureSpatialAnchorsLocalSharedDemo``` 」を開き、
以下、3つの値を追加します。

- __※ Base Sharing Url__ 
- __Spatial Anchors Account Id ( = Account Id )__
- __Spatial Anchors Account Key ( = Primary Key )__ 

※ Base Sharing Urlは、5.で発行したWebアプリのURLの末尾を、
「index.html」から「api/anchors」に修正したものを入力します。
「https://sharingservice-〇〇〇〇〇.azurewebsites.net/api/anchors 」

<img src="https://qiita-image-store.s3.amazonaws.com/0/180432/c431c343-8911-f3f9-a9e6-41870cfa31af.png" width="800">

#### ARCoreをインポートし、ビルドセッティングをAndroidにセット。
省略

---

### 6-2. UWP向けアプリをデプロイ ( ```HoloLens``` )

### <font color="silver">6-3. iOS向けアプリをデプロイ ( ```iPhone XS``` )</font> <font color="red">※TBD</font>


## (2) 実際にアプリを起動し、検証してみる！



# 7. 終わりに
最後までお読みいただき、ありがとうございましたー！ いやー、長かった。。
記事を書きながらなので、進捗出すのに苦戦しましたが、記事に残しているからこそ、思考の深掘りができ、
<font color="red">__「 Azure Spatial Anchors 」__</font>への理解が、少し深まったような気がします！


## 参考文献
- __[Microsoft HoloLens 2](https://www.microsoft.com/ja-jp/hololens?WT.mc_id=MR-MVP-5003868) ( 公式サイト )__
- __[公式ドキュメントを元に、Azure Spatial AnchorsをiOSとAndroidで試してみた](https://www.crossroad-tech.com/entry/azure-spatial-anchor-android#42-Android)__
- __[マルチデバイス間でシェアリングできるAzure Spatial Anchorsをやってみた（HoloLens、iOS、ARKit）](https://qiita.com/SatoshiGachiFujimoto/items/0f8e71b5977cba61a290)__

皆さま、情報公開ありがとうございます！

## キーワード ( 解説 )

#### __[Spatial ( スペーシャル )](https://ejje.weblio.jp/content/spatial)__
> __【 形容詞 】__: 空間の、空間に存在する、空間的広がりのある、空間的な

#### __[Anchor ( アンカー )](https://eow.alc.co.jp/search?q=anchor)__
> __【 名詞 】__:　≪海事≫ いかり
__【 自動詞 】__: いかりを下ろす、投錨する
__【 他動詞 】__: 〔船を〕いかりで固定する、～をしっかりと固定する

#### __[ASP.NET](https://ja.wikipedia.org/wiki/ASP.NET)__
> マイクロソフトが開発・提供しているWebアプリケーションフレームワークで、
動的なウェブサイトやWebアプリケーションやXML Webサービスの開発や運用を行う。

#### __[Gradle](https://ja.wikipedia.org/wiki/Gradle)__ ( 読み : グレードル )
> Gradleは、進化系のビルド自動化ツールです。Gradleは、ソフトウェアパッケージはもちろん、その他様々な形式のプロジェクト ( 例えば自動生成された静的Webサイトやドキュメント等 ) のビルド・テスト・ ( ライブラリ等の ) 公開・デプロイ・その他を自動化します。「 [Gradle入門](https://dev.classmethod.jp/server-side/gradle/gradle-first-contact/) 」より引用。