Natural Software

KinectなどのDepthセンサーを中心に活動しています。最近はHoloLensになりました。

SpectatorViewのCalibrationアプリでカメラ画像が出ない問題について

SpectatorViewについて、しばらく見ない間にちゃんとリリースパッケージになってました。

github.com

HoloTooliitのバージョンやUNET対応などでパッケージが分かれているようです(UNET対応版の1.5.7.2は未検証です)。

f:id:kaorun55:20170820002715p:plain

f:id:kaorun55:20170820002719p:plain

1.5.7.0でCalibrationアプリでカメラ画像が出ないことがあります。 f:id:kaorun55:20170820002437p:plain

解決方法を教えてもらったので記録しておきます。

DeckLingManager.cppの72行目あたり

videoDisplayMode = bmdModeHD1080p5994

これを

videoDisplayMode = bmdModeHD1080i5994

にすると動作します。または「1080p」などに該当する部分を環境に合わせて変更します。

SpectatorViewの環境を作るときはGoPro HERO 5とBlackmagic Intensity Shuttle USB 3.0を使うことが多いのですが、Blackmagic Intensity Shuttle USB 3.0が1080pに対応しておらず1080iのみでしか出力できないためと思われます。リファレンスのIntensity Pro 4K Captureは1080pに対応しています。

Blackmagic Design キャプチャーカード Intensity Shuttle for USB 3.0 000856

Blackmagic Design キャプチャーカード Intensity Shuttle for USB 3.0 000856

Xtion 2 新製品発表会に参加、登壇しました

8/9に行われた「Xtion 2 新製品発表会」に参加、登壇しました www.tekwind.co.jp

スライドはこちら。

Xtion2やOpenNI2、NiTE2の概要と、KinectやRealSenseでの事例です。内容的には数年前のおさらいです。

Xtion2について

2013年にPrimeSenseがAppleに買収されたことで、XtionやOpenNIがクローズされました。その時期からASUSとしてはXtion2のセンサーを探していたそうで、やっと今年製品としてリリースすることができたそうです。

センシング形式はToF、チップはTIを使っています。

流通はは来週あたりから開始されるとのこと。

Xtion2の特長

Kinect v2やRealSenseとの仕様上の性能比較は下記の通りです。

センサー性能的にはKinect v2、サイズ的にはRealSenseに近くなっています。 f:id:kaorun55:20170810104247p:plain f:id:kaorun55:20170810104642p:plain

特長を下記に列挙します。

  • OpenNI2が使える
  • Depth画像がきれい
  • USBバスパワーで動作する
  • 軽い、小さい
  • ROSがサポートされている

購入にあたっての注意事項も列挙します

  • 点群精度が微妙
  • 縦対応というのは三脚穴だけの話で自動的にソフトで回転してくれない
  • 製品としてNiTE対応版と未対応版の2種類が存在し価格が変わる
  • 1PCで複数台Xtion2の制御ができない(Kinect v2と同様)

点群精度についてはかなり微妙な感じがします。。。

発表会でASUSの製品担当の方もいたのでフィードバックしました。せっかくOpenNIを使える環境が復活したので、今後の改善に期待したいです。

データ取得イメージ

Depth画像は、かなりきれいに取れています。 f:id:kaorun55:20170810125814p:plain

点群については、状況確認中です。

HPのWindows Mixed Realityヘッドセットが届きました

昨日、HPのWindows Mixed Realityヘッドセットが届きました。 8/3に注文して8/9に届くという予想外の早さでした。

Windows Mixed Realityヘッドセット

Windows Mixed Realityヘッドセットについて「HoloLens互換」や「廉価版HoloLens」という言い方をされることがありますが、基本的には別物と考えた方が良いです。

互換があるとすれば「HoloLensと同じ排他の3DアプリがUWPで動作する」くらいです。ソフトウェア開発では近いところにいますが、ハードウェアや体験については別々にと思った方が間違いありません。 f:id:kaorun55:20170809113214j:plain

製品としては「Mixed Realityヘッドセット」ですが、ドキュメントでは「Immersive(イマーシブ:没入)ヘッドセット」と記載されており、Oculus RiftやHTC ViveなどVRヘッドセットに近いです。 ドキュメントにある機能的な違いを下記表にしました。 f:id:kaorun55:20170810095803p:plain

Windows Mixed Realityヘッドセットの特長

f:id:kaorun55:20170809095300j:plain

メリット

  • 外部センサーは不要なので、MRヘッドセット以外の付属品がない
  • 要件を満たしたPCであれば、MRヘッドセットを接続するだけでセットアップが完了する

デメリット

  • HoloLensのように単体で動作せずPCが必要で有線で接続される
  • カメラで現実空間は見えない、空間マッピングが使えないことで、現実空間に作用ができない
  • UWP環境で動作するので、Oculus RiftやHTC Viveからの移植にはポーティング作業が発生する

アプリケーション開発

HoloLens同様Unityでの開発が中心となります。

開発環境はこちらのfor immersive headsetsを参照。

概要としては下記です

  • Windows 10 Creaters Update(Insider Previewは不要)
  • Visual Studio 2017(SDKは10.0.15063を使用する)
  • Unity 5.6以上
    • アプリとしてはUnity 5.6でも動作します
    • エディターからの実行はUnity 2017.2から正式サポート予定ですが、まだベータなのとC#プロジェクトサポートでビルドができない不具合があるので様子見です

AcademyはMRヘッドセット対応しており、Mixed Reality 250が追加され、HoloLensとMRヘッドセット用アプリのSharingを学べます。

今後

HoloLensのARだけでなくMRヘッドセットでVR環境もできるようになりました。 MRヘッドセットはシースルーやジェスチャーがないなどHoloLensと体験の違いはありますが、PC接続のためHoloLensよりも高負荷をかけられることがメリットになります。

年末にリリースが予定されているモーションコントローラーが出てからが本番ですね。 f:id:kaorun55:20170809113257j:plain

HoloLens案件の打ち合わせ時に使ってる動画

自分がHoloLens案件で打ち合わせに行くときに使ってる動画をまとめます。 公式のYoutubeにいくつか載っており、公式の事例かつ自分が体験したもの中心にを紹介しています。あとはお客さんの業種や打ち合わせの流れで、公式以外のものも紹介したりしています。

順番は話の流れ。

Skype:遠隔サポート

HoloLensを買えば実現できる基本的な事例ですが、いままでだと研究対象にもなっていた事例です。

HoloLensを装着した人とPCの人ととのSkypeで、HoloLens装着者の視界が見えるので遠隔でサポートできます。ここでは簡単なSkype単体を使った電気工事の事例ですが、あとで紹介するthyssenkruppのエレベーターのようにアプリに組み込んで(おそらく独自に実装して)業務のサポートツールとして使うこともできます。

www.youtube.com

VOVLO:車のショールーム

表示するモデルの大きさに対する流れの作り方、センサーデータのシミュレーションの話をするときに使っています。

動画ではわかりづらい重要な要素がいくつかあります。

  • 視野角の問題について、小さいものは近くに、大きなものは遠くに置くことである程度軽減できる(運用で回避)。
  • 実物大の車は遠くに置くことで、まずは全体を見せる。そのあとで自分が近づくまたは引き寄せることで局所に視線を集中させて視野の狭さを軽減させる。
  • 手元に表示する場合には、小さなモデルを表示させる。これによって視野から外れることを防ぐ。
  • センサーについて、ただ動いているだけではなくHoloLensを装着してる人をセンシングしている。人が後ろから前に動くことで反応するセンサーが変わる。

www.youtube.com

thyssenkrupp:エレベーターのメンテナンス

IoTやDeep Learning/Machine Learning、スマートグラスと話をつなげるときに使っています。

いくつかの要素の複合体です。

  • 実際のメンテナンスに先立ってメンテナンスのシミュレーションを行う。
  • エレベーターの情報(センサーデータ)が視野内に表示される(IoTへ話をつなげる)
  • エレベーターの点検箇所が表示される(Deep Learning/Machine Learningへ話をつなげる)
  • 空間を使って点検項目チェックリスト、チュートリアル、センサーデータ、点検箇所が表示されている(スマートグラスとの比較)
  • メンテナンス中に判断に困った場合にはテレビ電話機能で遠隔サポートを求める

www.youtube.com

thyssenkrupp:階段昇降機

HoloLensを使った計測事例です。計測や精度の話をするときに使っています。

  • マーカーを使って計測を行う
  • 精度は指一本分くらい(精度が出る場合には1cm以内に収まっている)
  • 状況の閲覧はタブレットで行う(コラボレーティブ・コンピューティングへ話をつなげる)

www.youtube.com

Lowe's:キッチンシミュレーション

キッチンのリフォームシミュレーションです。実際に店舗でも使われているようです。

店舗訪問前、店舗見学中、店舗側の情報解析の3つに分かれており、ビジネス的な要素がかなり強いです。

  • 店舗訪問前
    • pinterrestから好みの写真をLowe'sのサイトに送ることで、リフォーム候補をMachine Learningで抽出する
  • 店舗見学中
    • 冷蔵庫やシンク、壁紙などをお好みでカスタマイズできます
    • 中央のアイランドキッチンも自分の身長や好みに合わせて、高さや大きさを調整できます
  • 店舗側の情報解析
    • 顧客がHoloLensで見たときの頭の位置や視線の先を解析して、興味や売り上げとの相関を分析する(たくさん見ている、滞在しているところは興味があるなど)

www.youtube.com

Trimble:BIM/建築系CAD

今現在引き合いの多い建築向け動画です。

BIMや3D CADで設計した建築データを、建築中の場所に重畳させる、配管を通してメンテナンスに活用するといった、3D CADデータをより長期的に活用する方法について示されています。

www.youtube.com

小柳建設:建設工程管理

こちらも建設向け動画です。

建設対象のモデル、工程、記録などがすべてHoloLens内に入っています。

橋のスケーリングを変更できるので、設計データと実際の建設物との大きさのイメージがリンクされるので教育目的への活用も期待できます。

www.youtube.com

HoloPortation:リアルタイム遠隔コミュニケーション

さまざまな要素により現在の実現は難しいですが、よく話にでます。

リルタイムで3Dデータを再構築し、遠隔コミュニケーションに使用します。

www.youtube.com

Holographic Capture:3D動画

より現実的なところで3D動画です。

HologramsのバレリーナやBuild 2017でのシルクドソレイユのパフォーマンスなどに使われています。

後処理型ですが、各フレームごとにメッシュ情報とテクスチャを持っており、3Dの動画といえる状態になっています。

www.youtube.com

まとめ

おおよそ上記の動画で説明しています。

分野もさまざま用途のさまざまですが、分野にとらわれず要素を分解して組み立てると多くの方面に使えると思っています。

Tokyo HoloLens ミートアップ vol.4を開催しました。

f:id:kaorun55:20170715182507j:plain

7/15(土)に「Tokyo HoloLens ミートアップ vol.4」を開催しました。 hololens.connpass.com

今回はスタッフ含めて146人の参加となり、前回よりも多くの方にお越しいただけた印象です。 また試験的に司会など担当をいままでと変えてみました(直前にいろいろありましたが、元々そういう話をしてました)。

スタッフとして参加してくれた方も20人ほどとなり、ミートアップ以外にできることも模索していこうと思います。

第1回 IPABセミナー Mixed Realityとその産業応用

同日、となりのセミナールームBにて「第1回 IPABセミナー Mixed Realityとその産業応用」も開催されており、ぼくはそちらにてHoloLensの概要のお話をしていました。

第1回 IPABセミナー Mixed Realityとその産業応用 — IPAB

こちらは参加者が大学の先生などアカデミックな方だったので、ミートアップとはまた違った話ができました。 途中でセミナー参加者の方にもミートアップを覗いてもらい雰囲気を体感してもらいました。

あわせてよみたい

togetter.com

www.wantedly.com

HoloLensでのアプリからのファイル書き込み

HoloLensでのファイル書き込みについて紹介します。 HoloLensのファイルアクセスはUWP環境になるので、さまざま設定や制約があります。アクセスできるフォルダは下記を参照してください。

とはいえ、Device PortalのFile Explorerからアクセスできる方が何かと便利なので、必然的に「カメラロール」、「ドキュメント」、「アプリのローカルフォルダ」の3種類になると思います。 f:id:kaorun55:20170304201241p:plain

それぞれの特長をまとめます。これらを踏まえて決めればよいかと思います。

  • カメラロール
    • ピクチャーライブラリの権限が必要
    • フォルダが作れない
    • 自動的にOneDriveで同期される
  • ドキュメント
    • 権限のつけ方が特殊
    • 指定した拡張子のファイルのみアクセス可能
  • アプリのローカルフォルダ
    • 権限が不要
    • デプロイごとにファイルが消える

サンプルコード

こちらのリポジトリに置いています。

カメラロール

カメラロールへのファイル書き込みサンプルです。

// カメラロール
// ピクチャライブラリの権限が必要
// フォルダは作れない
{
    var file = await KnownFolders.CameraRoll.CreateFileAsync("test.txt",
                                    CreationCollisionOption.ReplaceExisting);
    using (var stream = await file.OpenStreamForWriteAsync())
    {
        var bytes = System.Text.Encoding.UTF8.GetBytes(@"テストてすとtest");
        await stream.WriteAsync(bytes, 0, bytes.Length);
    }
}

権限はUnityエディター上で「PuctureLibrary」をチェックします。

f:id:kaorun55:20170304201922p:plain

UWPプロジェクトの上書きなどで権限がうまく入らない場合には「Package.appxmanifest」の「ピクチャライブラリ」を直接チェックしてください。

f:id:kaorun55:20170304202015p:plain

ドキュメント

ドキュメントへのファイル書き込みサンプルです。

// ドキュメントフォルダ
// 1. Package.appxmanifestを開き
//    「宣言」から「ファイルの種類の関連付け」を行い、書き込むファイルの拡張を追加する
// 2. Package.appxmanifestを「コードを表示」で開き下記を追加する
//     <uap:Capability Name="documentsLibrary" />
{
    var folder = await KnownFolders.DocumentsLibrary.CreateFolderAsync("DocumentLibraryTest", 
                                                        CreationCollisionOption.OpenIfExists);
    var file = await folder.CreateFileAsync("test.txt", CreationCollisionOption.ReplaceExisting);

    using (var stream = await file.OpenStreamForWriteAsync())
    {
        var bytes = System.Text.Encoding.UTF8.GetBytes(@"テストてすとtest");
        await stream.WriteAsync(bytes, 0, bytes.Length);
    }
}

ドキュメントフォルダへのアクセス権限付与

ドキュメントフォルダへのアクセス権限は「Package.appxmanifest」への設定と、ファイル関連付けの2つを行います。

Package.appxmanifestの設定

Package.appxmanifestを「コードを表示」で開き下記を追加します。

<uap:Capability Name="documentsLibrary" />

f:id:kaorun55:20170304202853p:plain

ファイル関連付け

Package.appxmanifestを開き「宣言」から「ファイルの種類の関連付け」を行い、書き込むファイルの拡張を追加します。

f:id:kaorun55:20170304202724p:plain

アプリのローカルフォルダ

特に権限の必要もなく書き込めます。ただし、デプロイごとにファイルが初期化されます。 ファイルは「User Files\LocalAppData\<アプリ名>\LocalState」 以下に作成されます。

// ローカルフォルダー
// 「User Files\LocalAppData\<アプリ名>\LocalState」 以下にできる
{
    var folder = await ApplicationData.Current.LocalFolder.CreateFolderAsync(
                        "DocumentLibraryTest", CreationCollisionOption.OpenIfExists);
    var file = await folder.CreateFileAsync("test.txt", CreationCollisionOption.ReplaceExisting);

    using (var stream = await file.OpenStreamForWriteAsync())
    {
        var bytes = System.Text.Encoding.UTF8.GetBytes(@"テストてすとtest");
        await stream.WriteAsync(bytes, 0, bytes.Length);
    }
}

HoloLensのUnity/UWPでasync/awaitを使う

HoloLensはUnityでアプリを作りますが、Unityエディターから直接実行ファイルを生成するのではなく、一度UWPへ変換してVisual Studioでビルド後にHoloLens実機に配置、実行する流れになります。

このため、Unityの.NET 3.5とUWPのコードが共存することになります。特に問題になるのが、UWPではasync/awaitを多用しますが、Unityの環境ではC#のバージョン的にそもそもasync/awaitが使えないため、コードの多くがこれを想定していません。

ここではUnityのアプリでasync/awaitを使う方法について紹介します。またasync/awaitでマルチスレッドになるので、同期の方法についても合わせて紹介します。おかしなところがあったら教えてください。

UWPではないUnityでのasync/awaitはこちらが詳しいです。

 

サンプルプログラム

UWPにビルドしたコード上でasync/awaitを使う方法を2つ紹介します。

  1. Task.Run()内でasync/awaitする(UnityEngine.WSA.Application.InvokeOnAppThreadは後述します)
  2. StartCoroutine()してyield return new WaitWhile()する

リポジトリはこちら

ちなみにUWP内のみコードを有効にするには #if UNITY_UWP をつけます。他にもいくつか定義がありますが、UWPビルドのどこかたタイミングで有効になるので、ビルドエラーになる場合もあります(細かくは調べていません)。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;

#if UNITY_UWP
using System.Threading.Tasks;
#endif

public class AsycnAwaitTest : MonoBehaviour {
    public TextMesh textMeshAynsc;
    public TextMesh textMeshCoroutine;

    // Use this for initialization
    void Start() {
#if UNITY_UWP
        // Task.Runでasyncする
        Task.Run(async () => {
            UnityEngine.WSA.Application.InvokeOnAppThread(()=>{
                textMeshAynsc.text = "Task.Run before : " + Time.time;
            }, true);

            await Task.Delay(5000);

            UnityEngine.WSA.Application.InvokeOnAppThread(() => {
                textMeshAynsc.text = "Task.Run after  : " + Time.time;
            }, true);
        });

        StartCoroutine(HeavyTask());
#endif
    }

    private IEnumerator HeavyTask()
    {
#if UNITY_UWP
        // WaitWhileでまつ
        textMeshCoroutine.text = "Task.Run before : " + Time.time;

        var task = Task.Delay(5000);
        yield return new WaitWhile( () => !task.IsCompleted);

        textMeshCoroutine.text = "Task.Run after  : " + Time.time;
#else
        yield return null;
#endif
    }
}

Task.Run()内でasync/awaitする

Task.Run()で非同期タスクを起こし、この中のメソッドをasyncで定義すればその中ではawaitが使えます。これがシンプルだと思います。

StartCoroutine()してyield return new WaitWhile()する

StartCoroutine()で非同期処理を開始します。 コルーチンはasyncにできずawaitが使えないので、非同期メソッドのTaskを受け取りyield return new WaitWhile()で待ちます。従来のコードとの整合をとりつつ非同期メソッドを使う感じでしょうか。

マルチスレッド

上記2つの最大の違いはTask.Run()の場合はマルチスレッド、StartCoroutine()の場合はシングルスレッドになります(スレッドを生成せずメインスレッドを分割する)。

これによって何が変わるかというとTask.Run()内ではGameObjectへのアクセスができなくなります。WPFなどと同様にUIのオブジェクトはメインスレッドのみアクセスが可能です。そのため、ここで使っている3D TextのTextMeshをTask.Run()内で直接触ると例外が発生します。通常はSynchronizationContextで制御しますが、Unityにはこの仕組みがありません。

ではどうするかというと、UnityEngine.WSA.Application.InvokeOnAppThread()を使います。これによってアプリスレッド(Unityのメインスレッド)で処理されます。

もう一つ、UnityEngine.WSA.Application.InvokeOnUIThread()というのもありますが、こちらはXAMLのメインスレッドのようです。

ドキュメントはこちら docs.unity3d.com