Slide 1

Slide 1 text

箱庭(Hakoniwa) Unity 合同会社箱庭ラボ 森崇

Slide 2

Slide 2 text

はじめに • この資料では、Unityを箱庭アセットとして利⽤するための情報を整理してい ます。 • ロボットを動かすためのUnityの構造 • 箱庭があると何が嬉しくなるのか • 箱庭が提供する機能(フレームワーク) • 箱庭でのロボット設計・実装⽅法 2

Slide 3

Slide 3 text

ロボットを動かすためのUnityの構造 • Unity上でロボットを動かすには以下の3レベルがあります 1. UnityのRigidBodyやArticulationBodyをアタッチしてロボットを動かす 2. UnityのC#スクリプトでロボットを制御する 3. Unity外のプログラム(Python/C++⾔語など)で、Unity上のロボットを制御する • 外部プログラムの実⾏環境 ︓OS上のプロセス、マイコンシミュレータ上のRTOSタスク等 • 外部プログラムとの通信⽅式︓共有メモリ、MQTT、UDP/TCP、、、 レベル1 RigidBody 等 レベル2 RigidBody 等 Unityの C#スクリプト レベル3 RigidBody 等 Unityの C#スクリプト プログラムの実⾏環境 通信スタック 通信⽅式 通信スタック

Slide 4

Slide 4 text

箱庭があると何が嬉しくなるのか 共通機能 (TOPPERS/箱庭) RigidBody等 Unityの C#スクリプト プログラムの 実⾏環境 箱庭 通信スタック 通信⽅式 (UDP/MQTT/共有メモリ…) 箱庭 通信スタック 箱庭API(様々なプログラミング⾔語) 箱庭API(C#) Unity向け箱庭 シミュレーション実⾏ タイミング制御 C++版 箱庭コア機能 Unity上のロボット ロボット制御プログラム • レベル3向けの共通機能の作成が不要になる︕

Slide 5

Slide 5 text

箱庭が提供する機能(フレームワーク) [凡例] Unityランタイム 箱庭ランタイム 機能 箱庭通信機能 箱庭PDU API 箱庭コンフィグ ローダー Unityエディタ 箱庭コンフィグ ジェネレータ 箱庭ロボット 箱庭コンフィグ ファイル (json) 箱庭PDU 定義ファイル (json/offset) 箱庭PDU ファイル⽣成 箱庭ロボット 箱庭ロボット 箱庭ロボット Callback Read/Write ユーザが作成する 成果物 箱庭が提供する機能 (フレームワーク) 箱庭が提供する 外部ツール 外部ファイル Unityの機能

Slide 6

Slide 6 text

箱庭PDU API 箱庭ランタイム機能 箱庭コンフィグ ローダー 箱庭Unity側のアーキテクチャと内部設計(1/2) WorldController AssetConfigLoader <> MonoBehaviour 箱庭コンフィグファイル (json) <> ISimulationController HakoAsset SimulationController HakoRpcAsset SimulationController <> IInsideAssetController <> 箱庭ロボット実装 <> IPduReader/Writer

Slide 7

Slide 7 text

箱庭コンフィグ ローダー PDUデータ PDU通信プロトコル 箱庭Unity側のアーキテクチャと内部設計(2/2) <> 箱庭ロボット実装 <> IPduReader/Writer Pdu ShmReader/Writer <> IIOReader/Writer RawPduReader/Writer RawPduReader/Writer Convertor Reader/Writer Connector RpcReader/Writer HakoMqtt PduChannel Connector Reader/Writer Channel HakoAsset SimulationController 箱庭コンフィグファイル (json) 箱庭PDU定義ファイル (json/offset)

Slide 8

Slide 8 text

箱庭Unityアセットのランタイム機能 • コントロールフロー • 全体的な処理の流れ • 箱庭ロボット内部の流れ • 実装イメージ • レーザスキャナ • カメラセンサ • 差動モーター • ロボット

Slide 9

Slide 9 text

Unity処理 箱庭共通処理 (WorldController) 箱庭Unityアセットの全体的な処理の流れ Start() FixedUpdate() コール バック 箱庭内のロボット処理 (コールバック関数) Initialize() DoActuation() CopySensing DataToPdu() アクチュエータ⽤ データ受信 センサ データ送信 ロボット処理実⾏ アクチュエータ⽤ データ(PDU) センサデータ(PDU) IInsideAssetController

Slide 10

Slide 10 text

箱庭ロボットの内部処理 RobotPartsRoot IInsideAssetController インタフェース実装 【役割】 すべてのセンサ/アクチュエータ の処理を実⾏する親⽟ 【補⾜】 ロボット組み⽴て時には、 本Unityスクリプトを必ず アタッチしないといけない DoActuation() CopySensing DataToPdu() IRobotPartsController IRobotPartsSensor UpdateSensor Values() DoControl() IRobotPartsActuator IRobotPartsMotor SetTargetVelocity() IRobotPartsPincherFinger UpdateGrip() IRobotPartsController(インタフェース) 【役割】 アクチュエータの制御コントローラ⽤のインタフェース 【インタフェース仕様】 DoControl()関数実装では、PDUデータを取得し、 アクチュエータ指⽰値を関係するアクチュエータに伝達する IRobotPartsSensor(インタフェース) 【役割】 センサ⽤のインタフェース 【インタフェース仕様】 UpdateSensorValues()関数実装では、センシング 処理を実⾏し、取得したデータをPDUに保存する IRobotPartsActuator(インタフェース) 【役割】 アクチュエータ⽤の共通インタフェース IRobotPartsMotor(インタフェース) 【役割】 モーター制御⽤のインタフェース 【インタフェース仕様】 SetTargetVeolcity()関数実装では、指⽰値に 従って、モーターの物理挙動を実現する • RobotPartsRootがアクチュエータ/センサ部品群を統括し、処理実⾏する • 各種アクチュエータ/センサはインタフェース化されているため、RobotPartsRootは再利⽤可能 • 箱庭部品として、アクチュエータ/センサのプロトタイプ実装クラスを⽤意している

Slide 11

Slide 11 text

[凡例] イベント関数インタフェース視点での全体像 IRobotParts IRobotPartsSensor IRobotPartsTouchSensor IRobotPartsMotorSensor IRobotPartsActuator IRobotPartsMotor IRobotPartsPincherFinger IRobotPartsController RobotParts Root <> FixedUpdate() Unity向け箱庭 シミュレーション実⾏ タイミング制御 IInsideAssetController インタフェース実装 インタフェース継承 処理呼び出し インタフェース インスタンス

Slide 12

Slide 12 text

IRobotPartsSensor インスタンス例 ロボットルート <> RobotPartsRoot レーザスキャナ <> Laserscanner カメラセンサ <> CameraSensor IRobotPartsController IRobotPartsAcuator 左モーター <> WheelMotor 右モーター <> WheelMotor <> DifferentialMotorController

Slide 13

Slide 13 text

RobotPartsRoot

Slide 14

Slide 14 text

IRobotPartsController︓ DifferentialMotorController

Slide 15

Slide 15 text

IRobotPartsActuator︓ WheelMotor

Slide 16

Slide 16 text

IRobotPartsSensor︓ Laserscanner

Slide 17

Slide 17 text

IRobotPartsSensor︓ CameraSensor

Slide 18

Slide 18 text

箱庭Unityアセットの通信機能 • PDU通信データの特徴 • PDU通信データのライフサイクル • PDU通信データの初期化 • PDU通信データの読み込み • PDU通信データの書き込み • PDU通信データのAPIクラス • Pdu/IPduReadOperation/IPduWriteOperation/IPduReader/IPduWriter • サンプル実装

Slide 19

Slide 19 text

PDU通信データの特徴 • C#クラスとして、キー・バリューで任意のデータ型を管理できます • 階層構造の構造体や配列などROS IDLで定義できる全ての型表現が可能です • jsonファイルで定義されたPDUデータを⼊⼒して、Pduクラスをインスタンス化します • ⾃分でPDUデータのクラスを作成する必要はありません • PDUデータは、箱庭のPDUアクセスAPIでアクセスできます • 受信⽤のPDUデータ • 箱庭ランタイム機能が⾃動的にデータ受信してバッファリングします • 受信タイミングは、全てのロボットのシミュレーション実⾏直前に、⼀括バッファリングします • 送信⽤のPDUデータ • 箱庭ランタイム機能が⾃動的にデータ送信します • 送信タイミングは、全てのロボットのセンシングデータを書き込みした後に⼀括送信します

Slide 20

Slide 20 text

PDU通信データのライフサイクル 箱庭共通処理 (WorldController) Start() FixedUpdate() DoActuation() CopySensing DataToPdu() アクチュエータ⽤ データ受信 センサ データ送信 ロボット処理実⾏ 箱庭内のロボット処理 (コールバック関数) 箱庭コンフィグ ファイル (json) 箱庭PDU 定義ファイル (json/offset) 受信Pdu インスタンス 送信Pdu インスタンス インスタンス化

Slide 21

Slide 21 text

PDU通信データのAPIクラス Pdu <> IPduReadOperation <> IPduWriteOperation Dictionary Dictionary Dictionary Dictionary 構造体メンバ毎に キー・バーリュー形式で 任意のデータを管理 IPduReader IPduWriter

Slide 22

Slide 22 text

サンプル実装(初期化処理) ■IPduReader/Writerを取得するための親⽟オブジェクト(pdu_io)を取得 ■IPduReaderの取得⽅法(Pduの名前を指定して取得) ■IPduWriterの取得⽅法(Pduの名前を指定して取得) IPduReader/Writerは、箱庭が⾃動的にローディング済みなので、 ロボットの初期化処理で、そのインスタンスを取得するだけでOK。 ⼿順は、以下の3ステップ。

Slide 23

Slide 23 text

サンプル実装(I/O) ■IPduReaderでのPDUデータ読み込み IPduReader/Writerを使⽤して、PDUデータの読み書きをする

Slide 24

Slide 24 text

サンプル実装(I/O) ■IPduWriterでのPDUデータ書き込み IPduReader/Writerを使⽤して、PDUデータの読み書きをする

Slide 25

Slide 25 text

箱庭Unityアセットのコンフィグ機能 • コンフィグファイルの種類と役割 • コンフィグファイルの⽣成⽅法 • コンフィグに関するインタフェースの実装 • ロボットの配置とスクリプトの割り当て • コンフィグファイルの⽣成

Slide 26

Slide 26 text

コンフィグファイルの種類と役割 • core_config.json • 通信ポートの定義 • 箱庭通信⽤のPDUデータ定義 • ロボットとPDUデータの関係定義 • hakoniwa_path.json • 外部コンポーネントとの連携するためのファイルパスを定義 • custom.json • ロボットのI/O⽅法 • 各I/Oで使うデータと型 • LoginRobot.json (現状未使⽤) • ロボットの位置情報

Slide 27

Slide 27 text

コンフィグファイルの⽣成⽅法(1/3) • コンフィグに関するインタフェースの実装 • ロボットのルートスクリプトでは、以下の2種類のインタフェースを実装してください。 • IRobotPartsConfig • GetRoboPartsConfig() • 実装例 • IRobotParts • getRosConfig() • 上記関数は、GetRoboPartsConfig()の戻り値から⾃動計算可能ですが、 • 現時点では、まだその辺りの整理が仕切れていません…。 • 実装例 • 本実装内容が、core_config.json と custom.json に反映されます。

Slide 28

Slide 28 text

コンフィグファイルの⽣成⽅法(2/3) • ロボットの配置とスクリプトの割り当て 1. ロボットは必ず prefab 化してください 2. ロボットには、HakoAssetRootというタグを割り当ててください 3. ロボットには、RoboPartsSettingsとRobotPartsRootスクリプトを割り当ててください 4. ロボットは必ずヒエラルキービューのHakoniwa/Robot配下に配置してください 必ずOnをチェック してください

Slide 29

Slide 29 text

コンフィグファイルの⽣成⽅法(3/3) • コンフィグファイルの⽣成 • 全ての設定が完了したら、必ず、コンフィグファイルを⽣成してください。 • Generate • 本番⽤ • GenerateDebug • テスト⽤

Slide 30

Slide 30 text

箱庭でのロボット設計・実装⽅法 • 箱庭でのロボット設計内容 • テスト向けシーン • デバッグ⽅法 • エラーハンドリングとロギング

Slide 31

Slide 31 text

箱庭でのロボット設計内容 • 箱庭を利⽤する上で必要な設計検討項⽬は以下のとおりです。 • 通信データの検討 • 作成するロボットのPDUデータの種類とデータ型 • 対象PDUデータを標準のROSデータ型で対応するか新規作成するかの検討も必要 • 対象PDUデータの通信⽅式(推奨︓共有メモリ⽅式) • 共有メモリ、UDP通信、MQTT通信から選択する • 送信対象となるPDUデータの送信周期 • ロボット物理挙動の再現⽅法検討 • 箱庭のサンプル実装が参考になると思います。 • Unityでのロセンサ/アクチュエータの実装⽅式検討 • 箱庭のサンプル実装が参考になると思います。

Slide 32

Slide 32 text

テスト向けシーン • ロボットの構造が複雑になる場合、Unity単体でテストする⽅が効率的です • 箱庭には、テスト向けシーンがあります。 • Workシーンです。ここで、GenerateDebugしてシミュレーションすることで簡単にお試しできます。 • PDUデータの通信は、Unity内のメモリで送受信できます。 • ロボットのテストドライバを作成することで、基本的な機能確認が可能になります。 • 参照 32

Slide 33

Slide 33 text

テスト向けシーンでの動作チェック 33 https://www.youtube.com/watch?v=dlz-60bH4x8

Slide 34

Slide 34 text

デバッグ⽅法 • ロボットのデバッグ⽅法として⼀番単純なやり⽅は、 • Unityのデバッグログ出⼒をすることです。 • 例︓UnityのDebug APIをそのまま利⽤できます。 34

Slide 35

Slide 35 text

エラーハンドリングとロギング • エラーハンドリング • 基本的にはロボット側のエラーチェックをお願いします。 • 問題ある場合は、解析に必要な情報をログ出⼒してください。 • 復旧不可能な場合は、例外をスローしてください。 • ロギング • 箱庭側で単純なロガーを⽤意しています。 • SimpleLogger • 実装例︓SimpleLogger.Get().Log(Level.ERROR, e); • ログファイル︓ • hakonwia_core.logがUnityプロジェクト直下に⾃動的に出⼒されます。 35