HoloLensやTangoなど、最近のデバイスは空間認識機能に関するものが増えています。そこで、空間認識機能について学ぶため、iOSデバイスで使える赤外線センサの「Structure Sensor」を試してみました。
概要はこちらにまとめられてますのでご確認ください。
■Structure Sensorの概要
iOS用赤外線センサー「 Structure Sensor 」ファーストインプレッション - Natural Software
■Structure Sensorのアプリを試した感想
ポータブル3DスキャナのStructure Sensorが届きました | develog.holo
■ Structure Sensorで3Dサイズが計測できるアプリの紹介(ビジネス向け)
Structure Sensor App開発(3Dサイズ計測アプリ) | PointCloudConsortium
だいたいの内容はすでに皆さんが書かれているので、今回はUnityでアプリを作る方法を紹介したいと思います。
1.準備
公式サイトにアクセスし、「JOIN Developer Program」をクリックします。個人利用か企業での利用かを選択し名前とメールアドレスを入力します。入力するとURLがメールで届きます。Developer のページにあるダウンロードの部分をクリックすると、SDK一式をダウンロードできます。
2.UnitySDKについて
2.1 Unity SDKの概要
この中には、Xcodeのプロジェクトと、Unityのunity packageが入っています。ここではUnity側について解説します。UnityのSDKは2種類あります。
StructureUnityAR
Structure Sensorを使って、対象物のメッシュデータを取得し、UnityのCollisionを使ってGameobjectとの衝突判定をさせる機能です。
StructureUnityUBT
Structure Sensorのカメラでキャプチャした画像のフレーム単位の変化から、実空間の移動をUnity空間にマッチングさせる機能です。
なお、アプリ開発には以下の環境を準備する必要があります。()は、私の動作環境です。
- Unity5.1.3f1以上 (Unity5.3.4f1)
- Xcode 6.4 (7.3.1)
- Mac OX 10.10.5 (10.11.5)
- iOS 8.4 (iPhone SE 9.3.1)
- Structure IO SDK ver0.5.5
また、前提として、2つのunity packageは排他的なので、別々のUnityプロジェクトで開発する必要があります。たとえば、StructureUnityAR.unitypackageをインポートした後、StructureUnityUBT.unitypackageを同じUnityプロジェクトにインポートすると、このようなエラーがでます。
2-2. StructureUnityAR の概要
まずはダウンロードしたSDKから、StructureUnityAR.unitypackageをインポートします。インポートすると、3種類のサンプルシーンがあります。これをベースに開発するのがよいです。
BallPhysics
空間のメッシュを取得して、"DropBall"ボタンをタップすると、たくさんボールが落ちてきます。メッシュにはColliderがついているので、ボールはメッシュに当たるとバウンドします。
メッシュは普段見えないようになっていて、ボールがぶつかると、この画像のようにぶつかった付近だけが見えます。
Fetch
空間のメッシュを取得して、"Toggle Hoop"ボタンをタップすると、キャラクターが出てきます。キャラクターをタップして、星形のオブジェクトまで連れて行けばよいようです。
Simple
空間のメッシュを取得してカメラプレビューに重ねて表示します。これが基本のサンプルです。
文字がたくさんあるのは、ソフトの挙動をテキスト表示するようになっているためです。
ちなみに、空間スキャンをするためには、Assets/StructureUnityAR/Sample/Simple/Scripts/SimpleObject.csの処理を使います。
"Simple"の場合、ここで定義したCubeの大きさの範囲内にある物体をスキャンします。
2-3. StructureUnityUBTの概要
ダウンロードしたSDKから、StructureUnityUBT.unitypackageをインポートします。インポートすると、5種類のサンプルシーンがあります。
ただ、Example、Barehouse、Stackerの違いはよくわかりませんでした。ここでは、Example、MotionLoggingEnabled、SanFranciscoApartmentの3つを解説します。
Example
Structure Sensorを装着したiOSデバイスを持って歩き回ると、画面上のUnity空間が歩行量に合わせて移動します。
MotionLoggingEnabled
歩いた軌跡をUnity空間に保存する機能です。
Structure Sensorを装着したiOSデバイスを持ってから、Record Pathボタンをタップします。
Stop Recordingをタップするまでの歩いた軌跡がUnity空間で保存されます。Play Last Pathをタップすると、保存した軌跡に合わせて、カメラオブジェクトが動きます。
SanFranciscoApartment
これはStructure Sensorを使わずに、Unity EditorだけでExampleの雰囲気を体感するものです。
WASDキーでシーン内を移動できます。おそらく、Unityに慣れてない人向けです。UBT機能を使うために、いくつかのPrefabが準備されています。
STPlayer
トラッキングさせるための機能が入ったPrefabです。原則、これをHierarchy Viewにドラッグしておきます。
StructureStatusUI
UI関係の機能が入っています。Hierarchy Viewにドラッグしておくと、debugログや、uGUIのテキスト表示、バッテリー状態の表示ができます。
また、MotionLoggingEnabledで使った、モーションパスを保存し、iTunes経由で取り出すこともできるようです。
MiniMapCanvas
STPlayerの動いた量を地図で表示します。
BarebonesPlayer
すいません、これはちょっとわかりませんでした。
3. HoloLensの空間スキャンのような描画を作ってみる
HoloLensには、一定時間で空間をスキャンするとき、アニメーション付きでメッシュが生成されます。
自動的にメッシュ生成のアニメーションをつけるとHoloLensのようになって面白いかも、ということで、アニメーション付きメッシュの自動生成方法を調べました。
まずは、StructureUnityARのunitypackgeをインポートします。Assets/StructureUnityAR/Samples/Simple/Scenesから、Simpleシーンを開きます。このまま、File→ Save Scene as で別名で保存します。
以下のようなスクリプトを準備します。
Clicking button emulation at 4 sec interval
また、AutoScanController.csをCubeにアタッチし、さらに、ActionButtonオブジェクトをAutoScanControllerコンポーネントにドラッグします。
デバッグログは残りますが、これで実機を見ると、4秒おきにスキャンするアニメーションを見ることができます。
補足
やっていることは非常に単純で、単にSimpleアプリに実装されていたuGUIのボタンを4秒おきに押しているだけです。
Simpleアプリは、以下の処理でボタンがタップされるたびに内部の状態を1ずつインクリメントしています。
Part of Buttons.cs provided by Occipital Team
なので、そこを利用して、ボタンタップのエミュレーション処理を入れました。
ちなみに、ボタンタップのエミュレーションは下記のようなコードとuGUIのボタンがあれば再現できます。この場合、キーボードのEをクリックすると、ボタンタップに合わせた動きをします。
4. Tips
4-1. ビルドエラーの対処方法
Unhandled Exception : System.TypeLoadException、というエラーがでるときは、Build SettingsのSwitch PlatformをiOSに変更します。
4-2. ビルド設定
UnityでXcodeのプロジェクトを生成するとき、Build Settingsの設定が不十分だと、
・実機転送に失敗する
・実機転送は成功するが、アプリが起動しない
・アプリは起動するが何も動かない
のどれかになります。わかるまで少し時間がかかりました。
では、設定方法です。
Resolution and Presentation
Default OrientationをLandscape Leftにします。
Other Settings
Automatic Graphics APIのチェックを外します。すると、OpenGLES2とMetalというAPIが表示されるので、Metalにカーソルを合わせて”ー”ボタンでdeleteします。Bundle Identifier は com.<文字列>.<文字列>のようにします。
また、Optimization / API Compatibility Level は.NET2.0にします。それ以外はスクショの通りです。
以後、ビルドしてUnityで動かすまでの手順については、下記をご覧ください。
iOSアプリを作ったことがない人が、Unityで作ったアプリをiOSデバイスに実機転送する方法(無料 ) - Cross Technology
4-3. 床をスキャンしてくれないときの対処方法
空間認識を試しているけど、壁方向はなんとなくメッシュを取れるけど、床が全く取れない。何か設定で無効化されてる?? #StructureSensor
— Riftup in VR/MR@JP (@WheetTweet) 2016年5月29日
Structure Sensor で色々試しているとき、壁は認識するのですが、床が認識されませんでした。下記のようにQuality Settingsのレベルを下げたところ、認識するようになりました。(初期設定ではFantasiticになっていました)
5. 感想
センサー関係はこれまでKinectくらいしか試したことがなかったので、色々と勉強になりました。
(Kinectを使う例)
Unityでモーションキャプチャを取れる、Cinema Mocapを試してみました - Cross Technology
もう一つの使い方である、3Dスキャナとしてはあまり使いこなせてません。たとえば、手元にあったLPIC公式キャラクタをスキャンしてみます。
これをスキャンするとこうなります。
このように、周囲の物体(床含む)が入り込んでしまいます。私のモデリング技術が低いので、この辺を取り除く方法がわかってません。
あと、今のところ、色情報はスキャンしないようです。
=======
2016/6/12 追記
@kaorun55 さんより、iPad であれば色情報も取得できそうという情報をいただきました。(私が試したのはiPhoneSEです)
@kaorun55さん、ありがとうございます。
ただ、私のiPadは古くてLightningケーブルが挿さらないため、確認ができない状態です。
しばらくiPadを買い換える予定がないので、確認は先になりそうですが、モデリングの勉強をするときになったら試してみたいと思います。
=======
空間認識としても色々可能性がありそうですが、3Dスキャナとしてもう少し使いやすいとさらによいなと思いました。