ZED Mini 解体新書 

#はじめに
この記事は[Unityゆるふわサマーアドベントカレンダー 2019 #ゆるふわアドカレ](https://qiita.com/nkjzm/items/7c933bb5c772a0b75512)の8月8日の記事です。
当初リズムゲームの設計思想について書こうとしていましたが、
よくよくルール読んだら「Unityに関すること」と書いてあったので、急遽ネタ変えました。

リズムゲーム設計思想シリーズはこちら
[【初級】](https://qiita.com/GONBEEE_project/items/8e0ce446efa7bd076c22)[【中級】](https://qiita.com/GONBEEE_project/items/e359ec6fff044d8a6c08)

少し前からステレオカメラいじり回してましたが、
今回[ZED Mini](https://www.stereolabs.com/zed-mini/)を入手しました。
（同じくステレオカメラ繋がりで、だいぶ前に書いた[OVRVision Pro 解体新書](https://qiita.com/GONBEEE_project/items/bc91d6328869af7a9724)もよろしくお願いします。）

この記事ではSDKとドライバのセットアップからUnityで動かすところまでを紹介したいと思います。

#Stereolabs ZED Mini
ZED MiniはStereolabsが販売しているステレオカメラで、UnityとUE4に対応しています。
非VRでもVRでも使えます。（が、ステレオカメラをVRゴーグル以外で使うシーンてあるのかな？）
OVRVisionよりもかなり新しく、カメラ本体の質もさることながら処理できる内容も改善しています。
しかしその分要求スペックも跳ね上がっており、販売ページのスペック要件では
>Quad-core 3.0GHz or faster processor
8 GB RAM or more
NVIDIA GTX 1070 or higher
Windows 7, 8, 10
USB 3.0

と指定されています。VRReadyPCなら大体どれでも動かせると思います。
今回はWindowsのみなので検証していませんが、動作環境OSはLinux系もサポートしているとのことです。
要求スペックはともかくラズパイ系でも動かせたりするんでしょうか。

映像出力は4モードあります。

| 映像モード | フレームレート | 解像度 |
|:---|---|---|
| 2.2K |  15 | 4416*1242 |
| 1080p |  30 | 3840*1080 |
| 720p |  60 | 2560*720 ※ |
| WVGA |  100 | 1344*376 |
※ステレオパス

画質とフレームレートのバランスがいいのは720pなので、メインで720pを使うことになると思います。
1080pは30FPSしかでないので、MR用カメラとして使う場合は酔いの観点からあまりおすすめできません。

##接続に関する注意
ZED miniはUSB3.0ケーブルでの接続になりますが、
**何故か表裏の区別が存在するらしく、正しい方向に刺さないと認識しません。**USB3.0とは（憤怒
付属品ケーブルのZED mini側端子をよく見ると矢印マークが刻まれています。
![InkedOYJ1LbEY_LI.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241210/d51d35b7-566f-30a5-91bf-d9d607fcd84b.jpeg)

**この矢印マークが表面（カメラ側）に来るように接続してください。**
ケーブルを繋いでいるのに何故か認識しない場合は端子の裏表を疑ってみてください。
謎が深いです。



#セットアップ
セットアップは比較的簡単です。
**NVIDIA CUDAが必要**になりますが、ZED SDKインストーラ内で勝手にCUDAを入れてくるので
自分でインストーラを持ってくる必要はありません。

##1.インストール
[ZEDドライバ配布ページ](https://www.stereolabs.com/developers/release/)から最新版ドライバを落としてきます。
2019/08/08現在最新版は2.8.3です。
![SnapCrab_2019-08-07_16-15-25_No-0000.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241210/f3057e43-7153-5c9d-84b6-9ee1eb0bdae9.png)

Downloadボタンを押すとインストーラ一覧が出ます。
自分の環境に合ったものを選択してください。Ubuntuもあります🐧

CUDA 9 とCUDA 10 がありますが、Recommendedなので特別な理由がない限りCUDA 10 の物を持っていきましょう。
![InkedSnapCrab_2019-08-07_16-21-20_No-0000_LI.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241210/222b1916-dd63-7394-af07-6786b76ddcb9.jpeg)

既にインストールしてしまったのでインストーラ画面が出せませんが、
初回インストール時は**自動でCUDAをインストールしていいかの確認**がでます。
抗わず同意しましょう。

グラボドライバ相当の物をインストールしているので、
インストーラ最後に**PCを再起動するかどうかを聞かれます。**
しかも**最初に選択されている方が Yes,restart the computer NOWになっています。**
![SnapCrab_2019-08-07_16-32-32_No-0000.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241210/35916104-e1b4-9583-8035-0c347a81161b.png)

何も考えずにNext連打しまくる人ほど引っかかりやすい罠です。
保存してないプロジェクトとかを失わないために、後から再起動を選択してNextしましょう。（一敗

##2.動作確認
ZEDドライバをインストールし終わったらインストールディレクトリから以下の階層を探します。
![SnapCrab_2019-08-07_17-02-40_No-0000.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241210/97bd27e7-7b37-2495-9d00-4f087b80783c.png)
`C:\Program Files (x86)\ZED SDK\app\ZEDfu`
この中から`ZEDfu.exe`を起動します。
これが最も手軽にZED mini動作確認ができて、**周囲環境のメッシュを取れるアプリ**になります。

###試してみよう
ZEDfuを起動したら画面上部に注目してください。ここからカメラの起動状態を操作します。
![InkedSnapCrab_2019-08-07_17-14-21_No-0000_LI.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241210/3fbbe9fd-8556-59b1-fa37-e003371c8e2a.jpeg)

`Input`ボタンを押すと`Live`か`SVO`を選択できます。
今回は`Live`でカメラ映像を出します。`SVO`は録画済みの.svoファイルからデータをロードする機能みたいです。
![SnapCrab_2019-08-07_17-24-46_No-0000.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241210/be9998e5-6823-098d-5a8a-55a050bf1db0.png)

起動すると左側に現在見えているカメラ状況と（おそらく）深度データが表示されます。
この状態になれば動作確認成功です。
せっかくなのでこのまま周囲のメッシュデータをキャプチャしてみます。

###お手軽メッシュキャプチャ
カメラを起動した後、`Input`ボタンだったところが`Start`になっています。
これを押すとメッシュキャプチャモードに入ります。押してみましょう。
![SnapCrab_2019-08-07_17-29-55_No-0000.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241210/2daf2384-4bb8-dbd5-e5b4-2c435e4a7e15.png)

メッシュキャプチャの感触はHololensに近く、
キャプチャとトラッキングを同時並行で行ってくれます。
メッシュ化速度はHololensと同等か少し早い程度ですが、
メッシュ密度が高くキレイにモデル化できます。
ただカメラ視差で深度を取っているので、画面の色や点滅に少し弱いかな？という印象です。
（Hololensなら平らに取れる画面がボコボコ気味になる。）

一通り色んな方向に向けて周囲をキャプチャしてみます。
注意点として**一度トラッキングが外れるとその回ではトラッキング復旧が困難になります。**
優しく動かしましょう。
Stereolabsの想定ではVRゴーグルに取り付けて使うデバイスなので、
人間の頭の速度ほどしかトラッキングできないということだと思います。

<blockquote class="twitter-tweet" data-partner="tweetdeck"><p lang="ja" dir="ltr">ZED miniでとったメッシュデータ<br>Hololensよりも早くキャプチャできてメッシュ密度が高い。<br>ただその一連のキャプチャ中にトラッキングロストすると復帰が難しい<br>なるべく丁寧に動かして一発でキャプチャできないと厳しいかも<br><br>Qiita用 <a href="https://t.co/3nF3nDRXn3">pic.twitter.com/3nF3nDRXn3</a></p>&mdash; ごんびぃー@RefrainCore (@GONBEEE_project) <a href="https://twitter.com/GONBEEE_project/status/1159022951712210944?ref_src=twsrc%5Etfw">August 7, 2019</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

デスク周囲をキャプチャしてみました。
適当にやった割にはしっかり空間として見えるかなというイメージです。
動画中央部に見えている灰色の昆布みたいなのがカメラが移動した軌跡です。
トラッキング精度がかなりよく、失わなければ本当にキレイに取れます。
出力データは.plyファイルなのでそのままUnity等に持っていくことはできません。
変換をかけて形式を変えましょう。

#Unityへ
動作確認できたところでUnityで使ってみましょう。

先程ZEDドライバをダウンロードしてきたサイトから`Plugins`に飛びましょう。
![SnapCrab_2019-08-07_18-04-49_No-0000.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241210/9851f2b6-fce6-9b48-bf5d-0df813008aea.png)

今回はUnityで進めます。
UnrealはともかくROSもPythonもあるのすごい。
リンクを踏むとGitHubのリリースページに飛びます。
最新版を落としましょう。2019/08/08現在2.8.1です。

![SnapCrab_2019-08-07_18-19-27_No-0000.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241210/877c1a70-09b2-c848-bb20-269ea60e98da.png)
インポートするとこうなります。
ファイル量は多いですが、実際に使うのは選択されている`ZED_Rig_Mono`と`ZED_Rig_Stereo`の2つです。
SteamVRの[CameraRig]みたいなものです。

早速適当なシーンを構築してみましょう。
サンプルシーンはどうもVRゴーグルがあることを前提に組まれているようで、
手持ちで見ると真っ暗で何も映りませんでした。
初テスト当時Looking Glassが刺さっててセットアップがめんどくさく、
手持ち状態で試しました。

##シーンにカメラを設置
まずはシーンを作ってカメラを設置します。
とりあえず手持ちモードで試すので`ZED_Rig_Mono`を持っていきましょう。
SteamVRなどと同じく、これでZED mini対応できました。一瞬ですね。

![SnapCrab_2019-08-07_19-37-13_No-0000.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241210/4335a432-cae7-fd4c-3c0a-eaa333c27bba.png)


ZEDのRigはこのような構造になっています。

###Input
そのRigで投影する映像の入力元を指定します。
プリセットではUSBが選択されています。
SVOは先程ZEDfuのところでチラッと書いた動画形式の事かと思われます。
Streamは試していませんが、IPアドレスとポート番号のボックスが出現するので、
ネットワーク経由で映像を飛ばせるみたいです。

USBモードでは画質とフレームレートを選択できます。
ZED mini概要説明のところで表にしてある画質から選べます。
基本的にはプリセットのHD720の60フレームで問題ないと思います。

###Motion Tracking
トラッキングに関する設定項目です。
基本的にはここは触らないでいいです。
Path Spatial Memoryというのは恐らく予め空間情報をとっておいてトラッキングの補佐とする機能かと思われます。

###Rendering
ここも触らないでいいと思います。
Camera Brightnessのスライダーは映像の明るさを調整します。
デモ動画の中に公園で使っている動画があったので、恐らく外界で使う際に下げるパラメータだと思います。

###Spatial Mapping
Spatial Mappingに関する設定です。
スキャンの密度や距離、誤差の埋める度合いを選択できます。
現在はグレーアウトしていますが実行するとキャプチャできるようになります。
Storageの`Save Mesh`をオンにすると実行終了時にメッシュデータをその下のパスに保存します。

###Recording
ここでSVOデータの録画ができます。
メッシュ保存などと同じく実行中に`Start Recording`を押して撮影しましょう。
ここで撮影したデータをZEDfuの項目でちらっと説明した、SVOファイルのロードに使えます。

###Advanced Settings
ここは正直どうでもいい内容です。
Fade In At Startはオンになっているとゲーム開始時にフェードインしながら始まります。
Grey Out Skybox On Startはスタート時にSkyboxを消します。
消しても消さなくてもMR状態には変わらないので、このオプションは使い方がわかりません。
Don't Destroy on Loadはその名の通りです。

Show Final AR RigとAR Layerに関してはよくわかっていません。
AR Layerは重ねる階層のことかと思われますが31以上はサポートされていませんでした。
プリセットでいいと思います。

###Camera Controls
実行中にのみ有効なオプション＝破壊変更にはならないのでデバッグなどの用途です。
内容は一般的なカメラのオプション（BrightnessやContrast）なので特に説明はしません。
使う頻度も低いと思います。

##適当なオブジェクトを設置して実行
Rig説明が終わったところで実際にオブジェクトを設置して実行してみましょう。
今回はこの様にしました。
![SnapCrab_2019-08-07_19-54-49_No-0000.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241210/6510962b-f4ae-034c-7b90-643ccb6a8f83.png)

実行した動画は以下の通りです。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">ZED Mini調査中<br>トラッキング精度最高、深度検知も精度完璧<br>影の投影も完璧<br><br>詳しくは今Qiita書いてるところ <a href="https://t.co/vNI0FDDRFY">pic.twitter.com/vNI0FDDRFY</a></p>&mdash; ごんびぃー@RefrainCore (@GONBEEE_project) <a href="https://twitter.com/GONBEEE_project/status/1157226804924432384?ref_src=twsrc%5Etfw">August 2, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

手持ち状態での実行はこのくらいで大丈夫でしょう。

次は頑張ってセットアップしてVRモードでやってみます。

##ところがどっこい

原因は一切不明ですが、
**SteamVRプラグインと同時に導入するとUnityが落ちまくる謎減少発生中**

GitHubのZEDリポジトリによるとUnity公式のVRサポート、OpenVRで見ることが可能とのことでしたが
映像出力のスクリーンがヘッドセットをトラッキングできていませんでした。
公式がダメならSteamVRでやればいいとプラグインを入れたところ落ちまくって**調査できてません。**

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">ZED mini、今WinMRでやってるけど<br>何故かヘッドセットの子オブジェクトにカメラ映像のスクリーンが登録されてなくて<br>頭を動かすとスクリーンがどっか行ってしまう謎現象<br><br>ゴーグルにカメラ貼ってるのになんでそういう動きするんじゃ<a href="https://twitter.com/asagi_00a3af?ref_src=twsrc%5Etfw">@asagi_00a3af</a> 麻木先生のTogetter見ても同様の現象は見つからず <a href="https://t.co/ZNTMmfFdVd">pic.twitter.com/ZNTMmfFdVd</a></p>&mdash; ごんびぃー@RefrainCore (@GONBEEE_project) <a href="https://twitter.com/GONBEEE_project/status/1159067718391226374?ref_src=twsrc%5Etfw">August 7, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

そのため、今回はアドカレということもあり間に合わなさそうなので
**VRモードの調査は後日追記させていただきます。**

8月8日担当の記事なので8日が終わるまでには情報更新したいと思います、、、

##惨敗、しかし糸口はある
クワマイさんの[ZED miniでAR動画を撮影する](https://kuwamai.hatenablog.com/entry/2019/02/28/235826)によると
`ZED Controller Tracker`コンポーネントによりゴーグルを追従するようにトラッキング方式を設定できるようです。
ただ2.8.1のZEDプラグインではSteamVR2.Xを前提に設計されているようで、
ちらっと試したところ赤エラーが多発しました。

もしかしたらバージョン相性なのかもしれない、、、？

`ZED Controller Tracker`コンポーネントが正常に動作した場合、非常に便利な設定ができて
カメラが物理的に張り付いている先を`HMD` `Right Controller` `Left Controller` `Vive Tracker`から選択できるようです。
つまりゴーグルに貼り付けてシースルーにするだけでなく、コントローラに貼り付けてサードパーソン視点でもできそうです。

#朗報・悲報（2019/08/08 20:19追記）

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">画質酷いですが正しく動くZED miniくんです。<br><br>OpenVRではなく、Unity公式のOculusプラグインを使っています。（Integrationじゃないやつ）<br><br>ふっつーに動いてしまった<br>WinMR対応とはなんだったのか、、、うごご、、、 <a href="https://t.co/c9oijO4LOb">pic.twitter.com/c9oijO4LOb</a></p>&mdash; ごんびぃー@RefrainCore (@GONBEEE_project) <a href="https://twitter.com/GONBEEE_project/status/1159423760635592706?ref_src=twsrc%5Etfw">August 8, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

VRゴーグルでZED mini動きました！！！！
昨日はWindows MR（Acer）で調査していたんですが、
今Rift Sに切り替えて試したら一瞬で正しく動きました！！

##Unity落ちまくる問題
こちらはどうもUnityの相性が原因らしく、
**Unity2017.4.10f1に切り替えたら突然安定しました。**
恐らく2018でPrefab周りに大改修が入ったので、あの辺りが悪さしてるのではないかと推測中です。

ZED SDKにはSteamVRプラグインのインストール状況を確認して、
自分から自分のPrefabを変更する機能があります。
多分その当たりのコードが2018の闇に飲まれていったのではないかと考えています。

ZED SDK使っててUnity落ちまくる人は**Unityのバージョンを変えてみてください。**

##頭トラッキングできない問題
**Windows MRがダメでした。**

Rift Sに切り替えたところ一発でドキュメント通りの動き方をしてしまいました。
詳しい調査はまだ続けますが、
SteamVR for WinMRあたりが悪さしてる雰囲気があります。

今回の調査の最終目的はWinMRで使うところなので、、、つらみ、、、

Oculus系の場合
`Player Settings/XR Settings/Virtual Reality SDKs`に`Oculus`を、
Vive系の場合は
`OpenVR`をそれぞれ追加してあげると動きます。
![SnapCrab_2019-08-08_20-26-25_No-0000.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241210/dbbe6b00-bbeb-8b0d-7c67-f021a45f9138.png)

##つまり
**「こんなに簡単にVRゴーグル対応までできちゃうんです！ドヤァ」**

原因不明の現象が発生している場合、
使っているゴーグルを変えると解消する可能性があります。
**少なくともWinMRでは正常動作を確認できませんでした。**

WinMRでは使えないんでしょうか、、、
調査は続けますが、光明は見えてきません。


#さいごに
当初の想定では
「こんなに簡単にVRゴーグル対応までできちゃうんです！ドヤァ」ってするつもりだったんですが、
ひどいグダリ具合ですね。

~~8月8日内でVRモードの調査詳細を書いて記事更新する予定です。
もうしばらくお待ち下さい。~~
嬉しくない結果が分かってしまいましたね、、、
WinMRは見捨てられたのでしょうか、、、

今後も調査を続けます。もしWinMRで正しく動いたらまた記事を更新します。

最新情報は [@GONBEEE_project](https://twitter.com/GONBEEE_project)で発信しています。