ブログ@kaorun55

HoloLensやKinectなどのDepthセンサーを中心に書いています。

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

HoloLensとWindows Mixed Reality HMD

「Windows Mixed Reality」(旧「Windows Holographic」)用のデバイスとしてAcerが開発者版のHMDを出すそうです。

www.moguravr.com

shiropen.com

「Windows Holographic」は「Windows Mixed Reality」に名前が変わったようです。

Windows Mixed Realityは$299~という価格でHoloLensの$3,000とはだいぶ違うのですが、値段相応に環境もかなり違います。ということで相違点をまとめてみます Windows Mixed RealityのHMDは想像の範囲でもあるので随時更新します。

HoloLens Windows Mixed Reality HMD
価格 $3,000/$5,000(PC不要) $299~(別途PCが必要)
動作形態 スタンドアロン PC接続
ケーブル なし あり
現実の見え方 シースルー 外界の映像は見えない
パフォーマンス 固定(CPUはAtom) PCに依存
アプリ実行環境 UWP UWP
環境センシング Inside-Out Inside-Out

HoloLens Spectator Viewを試してみた

HoloLensのアプリで装着している人以外がその映像を見るにはMixed Reality Captureを使いますが、遅延があったり無線接続が不安定だったりカメラ画像があまりきれいではなかったりします。

それらを解決する一つの方法として、Spectator Viewというものがリリースされました。

f:id:kaorun55:20170225144532p:plain

Spectator view

試してみて動くところまではできました。右側のカラー映像が結果です。

間違っているところなどあればフィードバックいただけると助かります。 

 

概要

Spectator ViewはHoloLensアプリに第三者視点を提供します。いままでもMixed Reality Captureでできましたが、よりきれいな映像にすることができます。

Spectator Viewの特長をまとめるとこのようになります。

  • カメラ映像はデジタル一眼レフカメラなど高性能なカメラを使用する
  • 表示されるホログラム(オブジェクト)はPCで描画する
  • Sharingアプリのみ対象となる(スタートメニューなどの表示はできない)
  • HoloLensの位置情報のみ実機から取り込む

制約としては下記が考えられます。

  • Sharingを前提とするためスタートメニューやバイナリのみのアプリには使えない。
  • HoloLensが2台以上必要

このことから、開発したアプリを公の場で発表する、プロモーションビデオの撮影という用途になると思います。

 


Microsoft HoloLens: Uses for Spectator View

 

事前準備

必要なソフトウェアやリグのための3Dモデルはこちらにあります。cloneするかHoloLensCompanionKit全体をダウンロードしてください。

github.com

 

必要な機材

f:id:kaorun55:20170225150902p:plain

Spectator Viewには写真の機材が必要です。

  • DSLR:Digital Single Lens Reflex:デジタル一眼レフカメラ
  • Tripod:三脚
  • Hotshoe Fastener:カメラの上につける雲台
  • 3D Printed Adapter:雲台とブラケットをつなげるアダプター
  • Aluminum HoloLens Bracket:アルミで作成されたHoloLensを固定するブラケット

3D Printed Adapter」および「Aluminum HoloLens Bracket」は自分で作る必要があります。

 このほかに下記機材が必要です

  • HDMIケーブル:カメラ映像をキャプチャするためのケーブル
  • HDMIキャプチャーツール:カメラのHDMI出力をPCに取り込むための機材

カメラとレンズは下記を推奨のようです。合わせて約50万円です。

Canon デジタル一眼レフカメラ EOS 5D Mark III ボディ EOS5DMK3

Canon デジタル一眼レフカメラ EOS 5D Mark III ボディ EOS5DMK3

 

 

Canon 単焦点広角レンズ EF14mm F2.8 L II USM フルサイズ対応

Canon 単焦点広角レンズ EF14mm F2.8 L II USM フルサイズ対応

 

Hotshoeはちょっと値段が高い(元のAmazon.comが$6(600円)くらい、Amazon.co.jpが6000円くらい)ので別で買った方がよさそうです。。。

HDMIキャプチャボードは下記のようです(PCIe接続)。約24,000円です。

Blackmagic Design intensity pro 4k ビデオキャプチャボード

Blackmagic Design intensity pro 4k ビデオキャプチャボード

 

 

今回使用した機材

カメラについてはHDMI出力できれば良さそう。キャプチャーボードは最初の写真を見る限りUSB接続でも良さそうということで、下記2つを購入して試しました。両方で約8万円です。

【国内正規品】 GoPro ウェアラブルカメラ HERO5 Black

【国内正規品】 GoPro ウェアラブルカメラ HERO5 Black

 

 

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

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

 

 

ソフトウェアのセットアップ

手順はこちらに詳しく書いてあります。

github.com

必要なソフトウェア

Desktop Video SDKが見つけづらかったので注意してください。下記画像の「Desktop Video 10.8.3 SDK」です。 

f:id:kaorun55:20170225154340p:plain

それぞれインストールを行います。OpenCVは展開してCドライブ直下においてください(「C:\opencv」となるように)。

Caribration

カメラとHoloLensのRGBカメラの位置を合わせるためにキャリブレーションを行います。

「HoloLensCompanionKit\HoloLensCompanionKit-master\SpectatorView\Calibration」にある「Calibration.sln」を開きます。

「dependencies.props」というファイルがあるので、下記2つのパスが通っていることを確認してください。

  • OpenCV:C:\OpenCV\build\x64\vc14
  • BlackMagic SDK:C:\BlackMagic\Blackmagic DeckLink SDK 10.8.3\Win\include

f:id:kaorun55:20170225154712p:plain

実行するとカメラの映像が表示されます。

f:id:kaorun55:20170225155024p:plain

つぎにHoloLensとカメラを配置します。今回はリグがないので、HoloLensの上にGoProをおいているだけです。

f:id:kaorun55:20170225155046p:plain

HoloLensとPCはUSBケーブルで接続します。

Calibrationプロジェクトの「stdafx.h」を開き、デバイスポータルのユーザー名とパスワードを設定します。事前にHoloLensのデバイスポータルをONにして、ユーザー名とパスワードを設定してください。

f:id:kaorun55:20170225182122p:plain

次に キャリブレーションを行います。GitHubにあるキャリブレーションパターンを印刷します。固めのボードに張るとよいと思います。

Caribrationアプリを起動し、キャリブレーションボードを動かします。途中Mixed Reality Captureが起動するので、HoloLensのカメラ撮影時のLEDが点滅します。

f:id:kaorun55:20170225175556p:plain

「C:\Users\<ユーザー名>\Documents\CalibrationFiles」にカメラ画像とHoloLensの画像および「CalibrationData.txt」が生成されます。

f:id:kaorun55:20170225182640p:plain

Compositorのビルド

必要かどうかわかりませんが「HoloLensCompanionKit\SpectatorView\Compositor」をビルドします。HoloLensの実機情報をやりとりする部分です。PC側のCompositorはx64、HoloLensに組み込む側はx86ですので両方のビルドを行い「CopyDLL.cmd」を実行します。

Unityサンプルを起動する

「HoloLensCompanionKit-master\SpectatorView\Samples\SharedHolograms」をUnityで起動します。Holograms-240をベースにSpectator Viewのアドインが入っています。

先ほどの「CalibrationData.txt」をProjectビューに追加します。

f:id:kaorun55:20170225183040p:plain

メニューに「Spectator View」が追加されます。「Compositor」を開くと新しいウィンドウが表示されます。これがSpectator Viewの画面になります。

f:id:kaorun55:20170225183043p:plain

f:id:kaorun55:20170225183041p:plain

「Spectator View」のアドインは「AddIns\HolographicCameraRig」になるようです。

f:id:kaorun55:20170225183044p:plain

ビルド設定から「Run In Backgorund」にチェックします。これで(Unityエディター側の動作だと思いますが)ウィンドウがバックグラウンド状態でも実行されます。

f:id:kaorun55:20170225183045p:plain

Sharingサービスを実行します。

f:id:kaorun55:20170225183046p:plain

ここで表示されるサーバーのIPアドレスを後で使用します。

場合によってはSchemaバージョンエラーが出る場合があります。その場合はオリジナルのHolograms-240やHoloToolkit-UnityにあるSharingServerを使用してください。f:id:kaorun55:20170225184125p:plain

Spectator View(HoloLens)とSharingサーバーのIPアドレスを設定します。

f:id:kaorun55:20170225183047p:plain

まずはエディター上で実行してSharingサーバーに接続できることを確認します。

f:id:kaorun55:20170225183048p:plain

続いてUWPを行い、HoloLensにデプロイします。

HoloLens上でこのアプリを実行し(デバイスポータルから起動すると楽です)、Sharingサーバーに接続されていることを確認します。次にUnityエディター上で実行し、サーバーおよびHoloLensに接続できると、PC上のカメラ位置がHoloLensに同期するようになります。

 

機材が複雑かつ3Dプリントで作成する必要がある、環境構築が煩雑、HoloLensが2台以上必要であることから、なかなか試しづらいですがアプリデモでは必要になってくるかと思います。

自分も3台のHoloLensでMixed Reality Captureを使った第三者視点はやったので。

 

 

デベロッパーズサミット2017で展示、登壇しました

2017年2月16(木)のデベロッパーズサミット2017で展示、登壇してきました。

展示

TMCNベースでPETS、ホロラボ、ショッカソン、HoloEyes 連合で展示をしていました。

HoloLensが目を引くので、休憩時間中は人もたえず、3,4台体制だったので、今回も結構な人数に体験してもらうことができたと思います。

f:id:kaorun55:20170217145611j:plain

f:id:kaorun55:20170217145618j:plain

 

登壇

17:25分からの枠でした。

200-300人くらいでしょうか。おかげさまで満席でした。

最初に聞いてみたところ、HoloLens持ってる人は数人、興味あるけど買ってない人が9割くらい、まだかぶったことがないひとが6割くらいのようです。

 

Togetterのまとめと当日の資料はこちらです。

togetter.com

 

docs.com