Ros-sharpを使って、UnityとROSで通信してみる

Ros-sharpを使って、UnityとROSで通信する方法をご紹介します。

テスト環境:

  • Robovie-Z with Pi4 running ROS Melodic
  • Win10 with Unity v2019.4.16.f1
  • Ros-sharp v1.6

ROSのセットアップ方法は、ここで紹介してます。

Robovie-ZでSDKを使ってROSを動かしてみた
ヴイストン株式会社さんからRobovie-Zをお借りしたので、さっそくSDKを使ってROSを試してみます! Robovie-Zの商品ページはここ Robovie-Z(ロボビーゼット) | ヴイ...

 

1.UnityストアからRos-sharpをインストール

Unityプロジェクトを開く、または新規作成してください。

ツールバーの”Edit”→”Project Settings”から”Player”を開いて、

”Api compatibility Level” を”.Net 4.x”に変更します。
(なぜか設定変更し忘れても動いてました…。)

Unityストアの検索バーに”ROS”と入れて検索すると、2番目に出てきます。

インポートボタンを押して、Assetに追加します。

Unityバージョンが古いと、インポートボタンが無効になっていると思います。

必要に応じてアップデートしてください。

インポートすると、AssetフォルダにRosSharpがついかされます。

ツールバーには”RosBridgeClient”が追加されます。

 

2.Unity上のテストアプリを用意する

空のGameObjectを作ります。

UnityのHirarchyウィンドウ上で右クリック、”Create Empty”を選択

作成したGameObjectにAsset/RosSharp/RosBridgeClient/RosCommunication/RosConnectorをドラッグドロップ

インスペクタウィンドウに、RosCommunicationスクリプトがいるので、

ServerURLをROSが走っているマシンの”IPアドレス:9090”に書き換えます。

Assetフォルダに新しく、スクリプトを作成。

今回は”TestRosSharp”という名前にしました。

コードはこちら、

*このコードはビルドしますが、動作に問題があります。後ほど解説。

using std_msgs = RosSharp.RosBridgeClient.Messages.Standard;
using UnityEngine;
using System.Threading;

namespace RosSharp.RosBridgeClient
{

    public class TestRosSharp : MonoBehaviour
    {
        private RosConnector rosConnector;
        string publication_id;
        string subscription_id;

        // Start is called before the first frame update, here the connection with ROS is established and the tipics are defined
        void Start()
        {
            rosConnector = GetComponent<RosConnector>();
            Debug.Log("Established connection with ros");

            //Thread.Sleep(3000);

            publication_id = rosConnector.RosSocket.Advertise<std_msgs.String>("publication_test");

            subscription_id = rosConnector.RosSocket.Subscribe<std_msgs.String>("/subscription_test", SubscriptionHandler);
        }

        // Update is called once per frame
        void Update()
        {


            if (Input.GetKeyDown(KeyCode.S))            //press S key every time you want to send messages to ROS
            {
                std_msgs.String message = new std_msgs.String
                {
                    data = "Message sent from unity"    //UNITY message for ROS
                };
                rosConnector.RosSocket.Publish(publication_id, message);
                Debug.Log("A message was sent to ROS");
            }

            if (Input.GetKeyDown(KeyCode.C))            //press C key to close the connection
            {
                rosConnector.RosSocket.Close();
                Debug.Log("Closed connection");
            }
        }


        private static void SubscriptionHandler(std_msgs.String message)
        {
            Debug.Log(message.data);                    //print ROS's message to unity
        }
    }
}

ここで拾ったコードを少し変更しました。

I can not send and receive simple data with ROS # – ros-sharp (gitmemory.com)

 

作成したテストスクリプトをGameObjectにドラッグドロップします。

GameObjectのインスペクタを確認して、TestRosSharpスクリプトが追加されていればOK。

 

3.Rosbridge_serverをROSにセットアップ

ワークスペースのソースディレクトリに移動して、

  • rosbridge_suite
  • rosauth

の2つパッケージをリポジトリから展開します。

cd ~/catkin_ws/src
git clone https://github.com/RobotWebTools/rosbridge_suite.git
git clone https://github.com/GT-RAIL/rosauth.git

ワークスペースのルートに戻って、rosdepを使って依存関係を解決し、catkin_makeを実行

cd ~/ros_catkin_ws
rosdep install --from-paths src --ignore-src -r -y
catkin_make

*rosdepを忘れると、rosbridge_serverがうまく動かないことがあります。

*もし後々”twisted”などのパッケージが足りないと出たら、rosdepを忘れてる可能性大です。

*不足パッケージをpip でインストールしてしまうと、互換性のないパッケージバージョンでインストールしてしまう可能性があるので、rosdep を使いましょう。

ここに書いてあります。私もこれで1日はまりました。

Nothing returned from rosbridge webserver · Issue #336 · RobotWebTools/rosbridge_suite · GitHub

 

4.通信してみる

ROSマシンでターミナルを開いて、rosbridge_serverを起動

roslaunch rosbridge_server rosbridge_websocket.launch

ステップ2で作ったUnityアプリを実行すると、

Unityアプリからrosbridge_serverに接続できていることがわかります。

UnityアプリのGameウィンドウをクリックしてキーボードの”S”を押して、

メッセージをPublishします。

ROSのマシンから別のターミナルを開いてトピックを確認してみます。

rostopic list

 

Unityアプリで作成した”/publication_test”と”/subscription_test”が見当たりません。

 

なぜかというと、rosbridge_serverとの接続が完了する前に、

”Advertise”と”Suscribe”が呼ばれているからです。

わたしはこれでまた1日はまってました…。

本当はよくないですが、今回は動作テストなので、Thread.Sleepを使って遅延します。

*ROS-Sharpのリポジトリから最新版のソースを直接Unityに展開した場合は、

ソースが少し変更されてて、こういうこともできます。

if (!rosConnector.IsConnected.WaitOne(SecondsTimeout * 1000))
     Debug.LogWarning("Failed to subscribe: RosConnector not connected");

ただ、リポジトリから最新版のソースを使った場合、今回のコードに必要なオブジェクトが足りないものが出てきて、今回のテストコードはビルドできなくなります。

 

20行目のコメントアウトを外して、

Unityアプリを実行しなおすと。

無事にトピックが見れるようになりました。

 

echoコマンドを使って中身を見てみます。

rostopic echo /publication_test

 

ちゃんとメッセージの中身が見れてます。

 

ROSからUnityアプリへの通信も確認してみましょう。

pubコマンドを使って、メッセージをパブリッシュします。

rostopic pub /subscription_test std_msgs/String "Hello UNITY"

Unityのデバッグウィンドウを確認すると?

ROSからのメッセージがとどいてます!

 

 

以上、「UnityアプリとROSで通信してみた」でした。

これができるということは…
「あんなことや、こんなこと」も!?

タイトルとURLをコピーしました