Ros-sharpを使って、UnityとROSで通信する方法をご紹介します。
テスト環境:
- Robovie-Z with Pi4 running ROS Melodic
- Win10 with Unity v2019.4.16.f1
- Ros-sharp v1.6
ROSのセットアップ方法は、ここで紹介してます。

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で通信してみた」でした。
これができるということは…
「あんなことや、こんなこと」も!?



