ROS講座123 UnityでROSと通信する


環境

この記事は以下の環境で動いています。

項目
CPU Core i5-8250U
Ubuntu 18.04
ROS Melodic
Gazebo 9.0.0
python 2.7.17

Unityの動作環境は以下です。

項目
ホストマシン Windows10
Unity 2019.4

インストールについてはROS講座02 インストールを参照してください。
またこの記事のプログラムはgithubにアップロードされています。ROS講座11 gitリポジトリを参照してください。

概要

これまでQtやブラウザでUIを作ってきましたが、今回はスマホで操作することを目標にしてUnityで作ってみます。
Unityはゲーム作成の統合開発環境で、ゲームで必要な3DCGや物理演算などの処理がを簡単に扱うことが出来ます。UnityはWindows/Mac/CentOSをサポートしていますが、今回はWindows上で開発します。
Unity本体だけでも基本的なゲームを作成することが出来ますが、アセットという追加のソフトウェアパッケージで処理や画像などの素材を追加することが出来ます。アセットはUnityのアセットストアで有償/無償で配布しています。無償の物でもクオリティーが高く便利なものがたくさんあります。今回はROSと通信ができる「ROS#」というアセットを使用します。
またUnityはマルチプラットフォームで実行できることが特徴です。Windowsの統合開発環境上でその場でプレビューすることができて、もちろんそれをWindowsアプリとしてリリースすることもがきます。それ以外にもAndroidやiPoneアプリとしてリリースすることもできます(ただしiPnone用のアプリ作成はMac上でのみ可能)。
Unityでは基本的にC#で開発を行います。UnityではC#プログラムを「スクリプト」と呼びます。
Unity自体に関する説明は長くなってしまうので、入門書にありそうな部分は説明を省きます。

ROS#について

UnityとROSの間を通信するためのUnityのアセットとしてROS#があります。これはC#で書かれたRosBridgeのクライアントでUnityでです。このアセットはUnityのアセットストアで配布しているものではなくgithubのページからダウンロードしてUnityでインポートします。
ROS#はrosbridge_serverがjson形式にしたrostopicをwebsocket通信でやり取りをすることでUnityとROSを接続します。

インストール(on Windows)

Unity本体のインストール

Unityのダウンロードページからダウンロードします。UnityHubはUnityのバージョンなどの管理ツールで最初は「UnityHub」をダウンロードします。「UnityHub」から「Unity本体」をダウンロードします。最新のROS#の推奨バージョンの2019.4を入れます。
後々必要なのでUnity本体のダウンロードの時に「Android Build Support」にチェックを入れてください。

プロジェクトの作成

UnityHubの「新規作成」から新しいプロジェクトを作成します。名前は何でも構いません。テンプレートは「3D」を選びます。

ROS#アセットのプロジェクトへのインストール

  1. github上のリリースページから「RosSharp.unitypackage」をダウンロードしてローカルに保存します。
  2. メニューバーの「Assets」->「Import Package」->「Custom Package...」を選んで出てくるウィンドウで「RosSharp.unitypackage」を選択します。

  3. 出てくるウィンドウですべての項目にチェックが入っていることを確認して「import」 を押す。

Unity上の操作(on Windows)

今回はROSからのimageのsubscribeとjoyのpublishを目標にします。

RosConnectorの設置

  • 「Hierarchy」ウィンドウの「+マーク」->「Create Empty」で空のGameObjectを作成して、RosConnectorと名前を変えます。

  • 「Project」ウィンドウのAssets/RosSharp/Scripts/RosBridgeClient/RosCommuncation/RosConnector.csをRosConnectorにアタッチします。

    • このスクリプトの「Ros Bridge Server Url」フィールドの値を{ROSを実行するPCのIPアドレス}:{Rosbridgeのポート}にします。

Imageのsubscribe

  • まず画像を表示するためのplaneを追加します。「Hierarchy」ウィンドウの「+マーク」->「3D Object」->「Plane」を選択します

  • 位置(0,1,0)と姿勢(90,0,180)を調節します

  • 「Project」ウィンドウのAssets/RosSharp/Scripts/RosBridgeClient/RosCommuncation/ImageSubscriber.csをRosConnectorにアタッチします。

    • 「Topic」を「/head_camera/image_raw/compressed」と指定します。
    • 「Mesh Renderer」の横の三角形のマークをクリックして出てくる画面で先ほど作成したplaneを選択します。

Joyのpublish

  • 「Project」ウィンドウのAssets/RosSharp/Scripts/RosBridgeClient/RosCommuncation/JoyPublisher.csをRosConnectorにアタッチします。
    • 「Topic」を/unity/joyとします。
  • 「Project」ウィンドウのAssets/RosSharp/Scripts/RosBridgeClient/MessageHandling/JoyAxisReader.csをRosConnectorにアタッチします。
    • 「Name」を「Horizontal」とします。
  • もう1つ「Project」ウィンドウのAssets/RosSharp/Scripts/RosBridgeClient/MessageHandling/JoyAxisReader.csをRosConnectorにアタッチします。
    • 「Name」を「Vertical」とします。

実行

ネットワーク構成

ROSを実行するUbuntuPCとUnityを実行するWindowsPCが同一セグメント上にいるとします。
以下UbuntuPCのIPアドレスを「192.168.2.105」とします

ROSの実行(on Ubuntu)

シミュレーションを起動します。

ターミナル1(gazeboの起動)
roslaunch sim3_lecture base_world.launch 
ターミナル1(rosbridgeの起動)
roslaunch rosbridge_server rosbridge_websocket.launch

以下のようにgazwboが立ち上がります。

Unityの実行(on Windows)

UnityEditorのplay(上部中央の三角形のボタン)を押します。

設置したPlaneにカメラの画像が写っています。またROSでrostopic echo /unity/joyとすると、Unity側画面でのキーボードの上下左右ボタンの入力が反映されます。

コメント

このサンプルではpublish側でで不具合があるために動かない可能性があります。これの場合は以下の修正が必要です。

Assets/RosSharp/Scripts/RosBridgeClient/RosCommuncation/JoyPublisher.csの修正
protected override void Start()
{
    System.Threading.Thread.Sleep(3000); // 追加
    base.Start();
    InitializeGameObject();
    InitializeMessage();
}

参考

目次ページへのリンク

ROS講座の目次へのリンク