Fusic Tech Blog

Fusicエンジニアによる技術ブログ

デジタルツインで個室の利用状況を監視
2023/04/27

デジタルツインで個室の利用状況を監視

こんにちは IoT チームの松山です。

以前、私は オンライン会議スペースを監視する IoT を作りました。
これは、個室に超音波センサーを設置し人がいるかどうかを監視し、 Web と Slack で表示するものです。

  • Web での表示

Web で表示

  • Slack での表示

Slack で表示

Web と Slack だけでも十分わかるとは思うんですが、、、なんかちょっと味気ないかも。

ということで、今回は Unity と React を使って Web 上で 3D 表示してみました!
それがコチラです!!

3D で表示

IoT で取得したリアルタイムな情報をデジタル空間上に表示する!
これぞまさに デジタルツイン

今回の例では Web の方が見やすい気がしないでもないでもないですが、、、3D で表示することで、これまで文字や数字が表示を読む必要があった情報から、見るだけで分かる情報に変え、情報がより活きる! はず。

実装

Unity と React そして、React Unity WebGL を使っています。

流れとしては以下です。

  1. Unity を WebGL で Build

  2. 成果物 (js, wasm, data) の gzip を解いて、React から読めるところに置く

  3. React Unity WebGL で成果物を読み込んで表示

    • 成果物が結構大きいので読み込みに時間かかります

一度だけなら簡単な手順ではありますが、実際には、Unity で実装 → React で確認を繰り返すので、Build 時間と gzip を解く手間で、結構めんどくさいです (自動化したい)。

Unity の実装

Cube をたくさん並べます。。。
(次は、写真から 3D モデルを作るとかやりたい)。

Unity の実装

Unity のコード

Unity で個室の色を変えるコード例を以下に示します。

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

public class Satellite : MonoBehaviour
{

    public void ChangeColor(string status)
    {
        Renderer renderer = this.gameObject.GetComponent<Renderer>();
        Material material = renderer.material;

        switch(status)
        {
            case "occupied":
                material.color = Color.red;
                break;

            case "reserved":
                material.color = Color.yellow;
                break;

            case "vacant":
                material.color = Color.green;
                break;

            default:
                material.color = Color.white;
                break;
        }
    }
}

引数 status に応じて material.color を変える ChangeColor という public メソッドを定義しています。

React のコード

React で Unity を表示する、および、定期的に個室の状況を取得して、Unity に反映させるコード例を以下に示します。

import React, { Fragment, useEffect } from "react";
import { Unity, useUnityContext } from "react-unity-webgl";

const TwinApp: React.FC = () => {
  const { unityProvider, isLoaded, sendMessage } = useUnityContext({
    loaderUrl: "unity/satellite.loader.js",
    dataUrl: "unity/satellite.data",
    frameworkUrl: "unity/satellite.framework.js",
    codeUrl: "unity/satellite.wasm",
  });

  function changeSatelliteColor() {
    fetch('satellite.json')
    .then(response => response.json())
    .then(data => {
      data.statuses.forEach(satellite => {
        sendMessage(satellite.name, "ChangeColor", satellite.status);
      });
    })
    .catch(error => {
      // データの取得が失敗した場合の処理
    });
  }
	
  useEffect(() => {
    if (!isLoaded) {
      return;
    }

    changeSatelliteColor();
    const timer = setInterval(() => {
      changeSatelliteColor();
    }, 10000)

    return () => clearInterval(timer);
  }, [isLoaded])

  return (
    <Fragment>
      <Unity unityProvider={unityProvider} style={{ width: 1024, height: 576 }}/>
    </Fragment>
  )
}

会議室の使用状況 json を fetch して、sendMessage で各会議室オブジェクトの ChangeColor メソッドを呼び出す、という処理を定期的に実行しています。

まとめ

  • React Unity WebGL を使えば Unity で作った 3D を React で簡単に表示できるよ!
Kazuhiro Matsuyama

Kazuhiro Matsuyama

IoT エンジニア (お勉強中)