📑

大阪・関西万博期間限定展示で使用した技術について(UE/rhino/gh/マイコンなど)

に公開

2025年 日本国際博覧会(大阪・関西万博)の期間限定展示、NEDOムーンショット型研究開発事業 「C 4 S ※ 研究開発プロジェクト」(PM:野口貴文・東京大学大学院工学研究科教授)のにおける展示に開発協力いたしました。

概要

2025年9月30日(火)−10月6日(月)期間、「フューチャーライフヴィレッジ」の「地球を救う未来のコンクリート NEDOムーンショット」にて体験できる、「次世代コンクリート構築シミュレートインスタレーション」に開発協力いたしました。

本記事は、開発において用いた技術関連についてまとめたものです。

導入と体験の構想

ご相談頂いた時点で、Rhinoceros/grasshopperによるプロシージャル形状のプログラムができており、プロシージャルプログラムを用いた体験展示を構想する流れになりました。

ご相談を頂いた時点で、UNREAL ENGINE製のアプリケーション用いてRuntimeでMovieRenderQueueを用い画像を出力する仕組みができてました。(Runtime MovieRenderQueue)

以上から、
「体験者にgrasshopperを触ってもらい、できあがった形状を画像にしてお土産として持って帰ってもらう」
という方向性の体験展示構想からスタートしました。

触れている内容

主に、本インスタレーションで使用した下記内容について触れます。

  • UNREAL ENGINEの技術
  • Rhinoceros/grasshopper
  • Aruidino/M5シリーズ(今回はアウトラインだけ)
  • プリンタ(Canon SELPHY CP1500)
  • その他(Ruby/.batによるスクリプト)

※Aruidino/M5シリーズの実装はハマりどころが多かったので、別途記事にします。

本記事でのアプリケーション類バージョンについて

  • UNREAL ENGINE 5.3.1 (C++ PJ)
  • Unreal Datasmith Exporter for Rhino 5.6.1
  • Rhinoceros 8
  • Aruidino IDE 2.3.6
  • Ruby 3.3.9

UNREAL ENGINEの技術部分

rhinoceros/grasshopperで作成した形状を、できる限り速く、データのアウトプット/インプットの煩雑さを避けて体験をしてもらうため、UNREAL ENIGNE(以下UE)のインポート機能であるdatasmithのRuntime機能、「datasmith directlink 」を用い、モデルデータの同期速度とアテンドスタッフのオペレーションを省略する方針で実施しました。

datasmith directlinkの技術使用は下記、公式ドキュメントをご参照ください。
https://dev.epicgames.com/documentation/ja-jp/unreal-engine/using-datasmith-direct-link-in-unreal-engine
※重要な仕様として、datasmith directlinkはUDP通信による同期を行なっています。

datasmith directlinkは、Get Direct Link ProxyノードとOpen Connection with Indexで、配置してある/Spawnする datasmith destination Actorに対して対応DCCツール側のSceneを取り込むことができます。

datasmith directlinkは、datasmithPlugins類有効化後、UEEditor上でのPIEやPreviewでは動作しますが、何もせずPackagingしただけでは動作しません。
C++PJによる、Build.CSへのモジュール記述が必要になります。

モジュール追加箇所は下記の通り

Build.cs

using UnrealBuildTool;

public class MyProjectName : ModuleRules
{
	public MyProjectName(ReadOnlyTargetRules Target) : base(Target)
	{
		PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
	
		PublicDependencyModuleNames.AddRange(new string[] { 
        "Core", 
        "CoreUObject", 
        "Engine", 
        "InputCore", 
        "EnhancedInput",
        // 以下追加
        "Messaging", 
        "Networking",
        "UdpMessaging" 
        // ここまで
        });

		PrivateDependencyModuleNames.AddRange(new string[] {  });

		// 以下コメントにつき省略
	}
}

以上の手順でrhnocerosに限らず、sketchup、revitでもPackagingした.exeでdatasmith directlinkによるリアルタイム同期が実行できます。(未検証ですが、3dsMAXも同様手順でリアルタイム同期が可能なはずです。)

rhinoceros/grasshopperの技術部分

UEとの連携部

前述の通り、UEアプリケーション(以下UEAPP)とrhinnceros/grasshopper(以下、rhino/gh)の同期はdatasmith Directlinkを用いました。
rhino側の準備として、datasmith exporter for rhinoのインストールを済ませ、datasmith メニューが表示される状態にしておき、datasmith directlink connection ウィンドウに同期先が表示されていれば、「同期」ボタンの実行でmeshデータが同期されます。

【参考】Rhino から Datasmith のコンテンツをエクスポートする
https://dev.epicgames.com/documentation/ja-jp/unreal-engine/using-datasmith-with-rhino-in-unreal-engine

ghで構築したプロシージャル形状のままではdatasmith directlinkを用いて同期ができないため、形状をmesh化するBake処理をgh処理の後半に追加していただきました。これにより、Bakeした形状をUEAPPにdatasmith directlinkで同期することが可能になりました。

マイコンとの通信

本体験ではghプラグイン、superserialを用いてマイコンとの接続を行なっています。
superserialプラグイン(コンポーネント)とマイコンの接続は下記の通り、

  • "ON/OFF"とToggle Booleanを接続
  • Arudino/マイコン側で設定したボーレートをPanelコンポーネントで記述し、"Band"に接続
  • マイコンのPC接続ポートをPanelコンポーネントで記述し、"Port"と接続
  • "Received"ポートからマイコンの値が取り出せる


最低限COMポート、ボーレートを設定し、Booleanで有効化すれば値が取得できます。
superserialで取得した値をDivideなどで分割し、ghのSlider等のノード箇所に接続しています。

SuperSerial (by Fabio D'Agnano)
https://www.food4rhino.com/en/app/superserial

Aruidino/M5シリーズ(マイコン)の技術部分

マイコンは

  • 技術記事が豊富
  • 操作系ハードウェアが体験想定に近いものが多い
  • Groveケーブルによる接続が容易
  • 筆者が過去に触った経験がある
  • UEをゲームパッドで操作するため、UE/rhinoの操作媒体混線を避ける意図

などの点からM5シリーズを採用しました。

ジョイスティック操作による形状変異を与える処理部分は、
操作中の信号を全てghが受信して重くなる/フリーズする現象を回避するため
ボタンによる値の保存機構を作成し、値保存が行われた際に値をghに送る処理としています。

また、接続機器の多さからGroveHubをM5stackCore V1.1にStackしPC給電のみで運用する方針を想定していましたが、付属ボトムバッテリを取り外した都合から、PCとマイコンを接続した際に毎回マイコンの電源が落ちてしまう現象が発生していました。
運用面を鑑みてボトムバッテリも追加でStackすることで安全度を高めました。

Aruidino/M5シリーズの実装はハマりどころが多かったので、別途記事にします。

プリンタ(Canon SELPHY CP1500)

構想当初から、お土産を体験者に持って帰ってもらうというコンセプトがありました。
本プリンタで出力される用紙サイズはL版、ちょうど万博パスポートと同じサイズであるため、体験者も違和感なく、持ち帰りやすいだろうということで採用となりました。

他にも、本プリンタは用紙とインク(転写インクカートリッジ)がセットであり、用紙だけが先に切れる/インクだけが先に切れるが起きにくいことからインスタレーションに適すると判断しました。

その他(Ruby/.batによるスクリプト)

UE、rhino/gh、マイコン、プリンタによる仕組みは構築できましたが、インスタレーションでのスタッフ引き継ぎ、ハプニング対応を想定し、ある程度セーフティを設けるためにRubyと.batによる処理を作成しました。

Rubyによる画像展開/移動処理

UEAPPで出力した画像ファイル(.bmp)の保存されるフォルダを監視し、画像ファイルが導入されたことを検知し、フォトアプリで開き、展開から55秒後にフォトアプリを終了し、当該ファイル名にタイムスタンプを付与してからPrintedフォルダに移動する処理を展示期間中裏側で回し続ける運用をとりました。


これにより、UEAPPで出力された画像を探すことなく即座にプリント体制に移行できるため、アテンド者がファイルを触る可能性を下げることができました。
また、この処理にはログ出力機構も設けており、緊急時対応に備えています。

.batでのアプリケーション起動

開発中下記の観点から、.batファイルを用いて必要なアプリケーション/ファイル類を.batファイルにて一括起動する処理を作成しました。

  • datasmith directlinkがrhinoとUEAPPの起動手順により接続ができないことが多かった
  • 起動するアプリケーション、ファイルの多さから起動ミスの予防

.batでのApp起動は特段珍しいものではないのですが、本件ではUEAPPのdatasmith directlink接続のための起動引数追記での起動、rhino/ghの起動〜ファイル展開〜datasmith directlink connextion windowの立ち上げまでを全て一連動作させ、体験に備えました。

rhino/gh関連の立ち上げ処理(.bat)

あらかじめ.batファイル内に実行したいコマンドを準備しておき、.bat実行時にRhino.exeのパスと.ghファイルのパスを取得。
.3dmファイルでRhinoを起動させると同時に、準備しておいた一連のコマンドを渡して自動実行、という処理になります。

.bat
@echo off
setlocal enabledelayedexpansion

rem --- 0. Rhino.exeのパスを自動で取得 ---
for /f "tokens=2 delims==" %%a in ('ftype Rhino8.Document') do (
    set "RhinoCommand=%%a"
)
if not defined RhinoCommand (
    exit /b
)
for %%b in (!RhinoCommand!) do (
    set "RhinoExePath=%%b"
    goto :PathFound
)
:PathFound

rem --- 1. 実行するコマンドを準備 ---
set "grasshopperPart=_Grasshopper _Enter"
for %%G in ("%~dp0*.gh") do (
    set "grasshopperPart=_Grasshopper _Open ""%%G"" _Enter"
    goto :GhFound
)
:GhFound
set "finalCommand=!grasshopperPart! _DatasmithDirectLinkConnections _Enter"

rem --- 2. .3dmファイルを探してRhinoを起動 ---
for %%H in ("%~dp0*.3dm") do (
    start "Rhinoceros" !RhinoExePath! "%%H" /runscript="!finalCommand!"
    goto :end

::end

UEアプリに起動引数を渡して立ち上げ処理(.bat)

起動.batには、UEアプリ(.exe)のUDP通信を有効化する起動引数 -messagingをを渡して立ち上げる処理も含んでいます。(-messagingはハイフンの前に半角スペースが必要です)

.bat
for %%F in ("%~dp0..\*.exe") do (
    if /I not "%%~nxF" == "%~nx0" (
        start "" "%%F" -messaging
        goto :eof
    )
)

起きた問題と解消方法

UEアプリで画像出力する際のUMGスケールが意図したものにならない状況が期日ギリギリで発生していました。
これはUEのUMGの設定を見直せば解決すると思うのですが、熟考する時間が惜しかったため、
UEアプリのPC画面上のピクセルサイズと、実際印刷する際のピクセルサイズ(L版用紙のピクセルサイズ換算)をあわせてしまうという力技で解決しました。

Windowsの標準拡張PowerToysのFancyZonesを用い、PC画面上のUEの配置位置と縦横Pixel比を固定します。
https://learn.microsoft.com/ja-jp/windows/powertoys/fancyzones

ただし、PC自体の最大解像度が1920✕1080で、縦側のPixelが足りない問題が発生しました。
これはHDMIのダミープラグを使い、4K解像度を表示できるようにし、解消しました。

検討したが不採用とした/実現できなかったこと

RubyScriptでフォトアプリにて.bmpを展開後、印刷処理自体もスクリプトで処理したかったのですが、

  • Windows標準のプリント処理経由でスクリプトから印刷すると、用紙サイズが取得できない問題があり、意図したサイズで印刷ができない。
  • フォトアプリからScript経由で印刷をさせることができない。(GUIをハックして印刷する処理が必要)
    以上から人力での印刷に落ち着きました。

まとめ

これまでUE単体のアプリケーションは作ってきた経験は多かったのですが

  • アプリケーション間を連携する実装
  • アプリケーションとハードウェア接続
  • インスタレーションにおけるトラブルを見越した実装
    といった実装で非常に考えることがおおく、学びになりました。(筋力になりました)

特にArudino/マイコン実装ではかなりハマったので別途記事をまとめます。

インタラクティブな開発にご興味ありましたら是非お問い合わせください!

ホロラボのテックブログ

Discussion