>   >  Unityでつくるインタラクティブコンテンツ:第13回:《HUMANIC DOME》
第13回:《HUMANIC DOME》

第13回:《HUMANIC DOME》

今回は、弊社が制作に協力したNTTドコモと乃村工藝社NOMLABによる次世代のつながり体験装置《HUMANIC DOME》の実装について紹介します。

TEXT_高田稔則 / Toshinori Takata(Codelight
EDIT_小村仁美 / Hitomi Komura(CGWORLD)

体験者の脈拍・呼吸などのデータを集約・解析し
緊張状態に応じた空模様を投影

こんにちは、高田です。先日、「xArm 7」というロボットアームを購入しました。クラウドファンディングで申し込んでから1年以上待ちましたが、ようやく到着しました。本体を設置する台などは含まれていないので、まず台の制作から始めています。


さて、弊社では、2019年11月12日(火)から12月15日(日)に東京・初台にあるNTTインターコミュニケーション・センター [ICC]で開催された『リサーチ・コンプレックス NTT R&D @ICC 拡張展示「コミュニケーションの再考」』の展示作品の1つ「《HUMANIC DOME》」の制作に協力しました。株式会社NTTドコモ様と乃村工藝社グループのイノベーション・ラボラトリー「NOMLAB(ノムラボ)」様が共同制作した次世代のつながり体験装置です。

作品のコンセプトや詳細は以下のNOMLABのサイトを見ていただくとして、今回はどのようにコンテンツの実装を行なったか紹介したいと思います。

NTTドコモとの協業にみる『次世代コミュニケーション』 | 望月 美那 | プランナー
www.nomlab.jp/jp/nomlog/detail/30

このコンテンツはIoT機器からのセンシングデータをIoTアクセス制御エンジン※(以下、クラウドとする)で集約させたものを解析し、気持ちや関係性を評価してリアルタイムに空模様としてスクリーンに表示させるものです。空はCGでリアルタイムレンダリングを行い、実装はUnity2019.2で行いました。

IoTアクセス制御エンジン:NTTドコモが開発した様々なメーカーのIoTデバイスを制御管理できるクラウド基盤

使用した機器は以下のようになっています。
1. 脈拍、呼吸、圧力などを取得するセンサ
2. センサの値をクラウドへアップロードするルータ
3. クラウドからデータを取得して感情を評価するPC
4. レンダリングとサウンド再生を行う演出PC

センサ類は写真のような椅子に設置してあり、体験者に座ってもらうことでコンテンツが始まります。


NTTドコモ+乃村工藝社NOMLAB《HUMANIC DOME》2019年
撮影:木奥恵三、写真提供:NTTインターコミュニケーション・センター[ICC]

この椅子をドーム内に設置し、プロジェクタで映像を投影します。


写真提供:乃村工藝社NOMLAB

弊社では、クラウドからのデータ取得と評価、結果をレンダリングするプログラムの開発を行いました。

クラウドから取得されるデータはセンサからの生データで、それをどのように解釈するかはコンテンツ側の実装によります。評価された結果は、晴れや雨など8つの空模様に割り当てられます。空のレンダリングにはアセットストアのEnviroを使用しました。


上映されるコンテンツより。体験者から得たデータを解析し、体験者の緊張状態を天気の変化(縦軸)で表す。続いて、過去の別の体験者のデータとの類似度を解析し、それを空の時間帯の変化(横軸)として表示する

Enviroは手軽に美しい空をレンダリングできる使いやすいアセットです。以前の記事でこのプラグインを使ってTouchDesignerとの連携を紹介しました。その時点ではUnityで空だけレンダリングを行い、TouchDesignerでエフェクトを加え全体のシーケンスを組み上げるつもりで進めていましたが、特別なエフェクトをかける必要がなくなったので、全てをUnityで完結させることにしました。


●Enviroを使う上で気になったこと

センシングされた結果によって天気と時間を滑らかに変化させる必要があります。Enviroは設定したパラメータをいくつかプリセットとして保持し、それを切り替えることで天気の変化を表現することができます。この遷移はとても上手く機能するのですが、BGMも天気に合わせて変化させようと調整しているとき、どうしてもタイミングが取りにくかったためEnviro遷移部分の実装を調べてみることにしました。

Enviro - Sky and Weather\Enviro Standard\EnviroSky.csをみると以下のような式がUpdate関数中に書かれています。

cloudsConfig.cirrusAlpha = Mathf.Lerp(cloudsConfig.cirrusAlpha, i.cloudsConfig.cirrusAlpha, speed);

speedはインスペクタから指定した変化にかかる時間にdeltaTimeを乗算した値です。変化にかける時間を10とすると60fpsのときdeltaTimeは0.016程度になるためspeedは0.16になります。1から0に値を変化させようとすると、以下のグラフのような変化を取ります。0に近づくほど変化量が少なくなるため、遷移しきる時間を制御することが難しいことがわかりました。


変化時間を明確に指定できる関数に変更したかったのですが、いたるところでこの式が使われているため今回はパラメータの調整で乗り切りました。根本的な対応は今後の課題としたいと思っています。

●場面管理

今回のコンテンツは大きく5つの場面でひとつの体験を作っています。
1. 待機
2. 導入ムービー再生
3. 個人の状態の可視化
4. 他の体験者とのデータの類似度の可視化
5. エンディング

通常ほとんどのコンテンツでは何かしらの場面をもっていて、場面を管理する方法でプログラムの作り方が変わってきます。状態は場面だけにとどまらないのですが、様々な状態を管理することを「ステート管理」と呼びます。

ステート管理には様々な方法が考えられていますが、今回初めて使用したIceMilkTeaのステート管理のしくみが非常に使いやすかったので紹介します。Sinoaさんが公開しているIceMilkTeaというフレームワークの一部として公開されています。

IceMilkTea/StateMachine.cs at develop · Sinoa/IceMilkTea · GitHub
https://github.com/Sinoa/IceMilkTea/blob/develop/Program/Runtime/Core/UnitCode/PureCsharp/StateMachine.cs

1ファイルのみで実装が完結しておりスクリプトだけで利用可能なこと、ライセンスが緩いことなど使い勝手が良く、すでに2つ別のコンテンツでも利用させていただきました。以下の記事に使用方法が詳しく書かれています。

ステートマシン実装の決定版ImtStateMachineについて語り尽くす
https://qiita.com/BelColo/items/a94c9ccc2d5174dc29a3

●クラウドからのデータ処理

クラウドからのデータ取得はnodeのプラグインとcurlの例が用意されていましたが、慣れているPythonで作成することにしました。プログラムはNVIDIAのJetson AGX Xavier上で動かしました。これはNVIDIAが開発しているAIなどのEdge処理を行うための強力なGPUを搭載しているコンピュータです。


今回はXavierの得意としているGPUによる処理は一切使わず、単なるLinuxマシンとして使用しました。Xavierを選択したのは筐体が小さく、Pythonスクリプトさえ動けば良かったのと、以前機械学習の案件で使ったきりで放置していたので活用の場として良いと考えたからです。今後より高度な評価処理をGPUを使って高速に行えるようになると良いな、という想いも込められています。

普段開発にはVisual Studio Code(VSCode)を使っているのですが、XavierはARMアーキテクチャを採用しているため配布されているLinux版のVSCodeを動かすことはできません。コード補完の効かないエディタで開発するのは効率が悪いので何とか動かせないかと思いましたが、どうも自前でビルドする必要があるようです。さすがにそれは面倒なので、調べたところVSCodeのSSH FSというエディタ拡張が便利でした。


このエディタ拡張を使うとローカルファイルを編集するのと同じ感覚で、リモートのファイルをSSH経由で編集可能になります。

また、久しぶりにLinux環境を使うにあたり、Pythonの環境構築についても調べ直し、評判の良さそうなPipenvを使うことにしました。


Python側では評価した値をOSC(Open Sound Control)を使って演出用のプログラムが動いているPCに送ります。Pythonからの送信にはpython-oscを使いました、以下のように書くだけで送信できます。

from pythonosc.udp_client import SimpleUDPClient
client = SimpleUDPClient("127.0.0.1", 9000)
client.send_message("/address", [0, 1])

受信はお馴染みのOscJackです(OscJackの設定についてはこちらを参照)。

●動作の監視

Pythonスクリプトには体験が終わるごとにSlackにメッセージが送られるようにbotを仕込みました。


アプリの登録が終わってトークン文字列を取得できれば、以下のように書くだけでメッセージをSlackに送ることができます。

import slack
slack_bot = slack.WebClient(token="トークン文字列")
slack_bot.chat_postMessage(channel='#watch', text="メッセージ文字列")

下記はメッセージを受信した様子です。

会期直前に思いついて組み込みましたが、きちんと動いていることが確認できる安心感は大きかったです。普段インターネット接続環境がないことが多いので、他のコンテンツではなかなか仕込めないのが残念です。

クラウドから取得したデータの可視化やドームへの投影、ICCでの展示など普段あまりできない内容の案件だったのでとても楽しく開発を行うことができました。

なお、本作品は来年1月23日(木)・24日(金)に開催される『DOCOMO Open House 2020』でバージョンアップ版を公開する予定です。お時間があればぜひ体験していただければと思います。

Credit.

プロトタイプ名:《HUMANIC DOME》
制作者:NTTドコモ、乃村工藝社

Profile.

高田稔則/Toshinori Takata(Codelight)
Codelight株式会社 代表取締役・インタラクションエンジニア
フリーランス、株式会社TBSテレビ等で映画CG制作、株式会社ソニー・コンピュータエンタテインメント(現 ソニー・インタラクティブエンタテインメント)でPS4のOSD開発などを経て2006年にCodelight株式会社を設立。インタラクティブコンテンツの制作を中核として、製造業向けのプロトタイプ開発なども行う
www.codelight.co.jp




その他の連載