0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【ROS 2 Jazzy × Unity 6】WSL2とUnityでService通信を実装する

0
Posted at

はじめに

ROS 2 と Unity を使ったデジタルツインの学習として、前回は Publisher / Subscriber を利用したTopic通信を実装しました。

動作確認

実際に Unity と ROS 2 でサービス通信を行った様子です。

今回は一歩進めて、UnityからROS 2のServiceを呼び出す通信を実装します。

構成は以下です。

Windows
┌─────────────────────┐
│ Unity 6             │
│ SimpleClient        │
└──────────┬──────────┘
           │
           │ TCP
           ▼
WSL2
┌─────────────────────┐
│ ROS-TCP-Endpoint    │
└──────────┬──────────┘
           │
           │ ROS 2
           ▼
┌─────────────────────┐
│ ROS 2 Jazzy         │
│ simple_server       │
└─────────────────────┘

実装中には、

Connection to 127.0.0.1:10000 failed

というエラーにも遭遇しました。

この記事では、Service通信の実装方法と、このエラーの原因・解決方法までまとめます。


環境

OS       : Windows + WSL2
Ubuntu   : Ubuntu 24.04
ROS 2    : Jazzy
Unity    : Unity 6.3 LTS
通信      : ROS-TCP-Connector / ROS-TCP-Endpoint

ROS 2 ワークスペース:

~/chapter2_ws

ROS 2 Serviceとは

ROS 2 のTopic通信は、

Publisher
    ↓
Topic
    ↓
Subscriber

という形でデータを配信します。

一方、Service通信は、

Client
   │
   │ Request
   ▼
Server
   │
   │ Response
   ▼
Client

という Request / Response型 の通信です。

今回はUnityから、

r = 2.0
h = 3.0

をROS 2へ送り、ROS 2側で処理した結果をUnityへ返します。


Service定義

今回使用するサービスは、

CalculateCylinderVolume.srv

です。

float64 r
float64 h
---
float64 v

--- より上がRequest、下がResponseです。

Request
├─ r
└─ h

Response
└─ v

ROS 2側で定義を確認します。

cd ~/chapter2_ws

source /opt/ros/jazzy/setup.bash
source install/setup.bash

ros2 interface show chapter2_interfaces/srv/CalculateCylinderVolume

以下のように表示されればOKです。

float64 r
float64 h
---
float64 v

Unityへ .srv を取り込む

Unityの上部メニューから、

Robotics
→ Generate ROS Messages

を開きます。

ROS message path にROS 2ワークスペースの、

chapter2_ws/src

を設定します。

WindowsからWSL2を参照する場合、今回の環境では、

\\wsl.localhost\Ubuntu-24.04\home\tokot\chapter2_ws\src

でした。

重要なのは、

chapter2_interfaces

そのものではなく、

chapter2_ws/src

を指定することです。

正しく読み込めると、

src
└─ chapter2_interfaces
   └─ srv
      └─ CalculateCylinderVolume.srv

が表示されます。


.srv からC#クラスを生成する

ROS Message Browserで、

CalculateCylinderVolume.srv

を確認し、

Build 1 srv

を実行します。

これにより、

CalculateCylinderVolume.srv
        ↓
Message Generation
        ↓
CalculateCylinderVolumeRequest.cs
CalculateCylinderVolumeResponse.cs

というUnity用のC#クラスが自動生成されます。

ROS 2独自のService型をUnityから扱えるようにするための重要な処理です。


Unity側にSimpleClientを作る

Hierarchyで、

Create Empty

を実行し、

SimpleClient

というGameObjectを作成します。

続いて、

Assets/Scripts/SimpleClient.cs

を作成します。

コードは以下です。

using UnityEngine;
using Unity.Robotics.ROSTCPConnector;
using RosMessageTypes.Chapter2Interfaces;

public class SimpleClient : MonoBehaviour
{
    private ROSConnection ros;

    private const string ServiceName = "calculate_cylinder_volume";

    void Start()
    {
        ros = ROSConnection.GetOrCreateInstance();

        ros.RegisterRosService<
            CalculateCylinderVolumeRequest,
            CalculateCylinderVolumeResponse
        >(ServiceName);

        CalculateCylinderVolumeRequest request =
            new CalculateCylinderVolumeRequest();

        request.r = 2.0;
        request.h = 3.0;

        Debug.Log("Request送信: r = 2.0, h = 3.0");

        ros.SendServiceMessage<CalculateCylinderVolumeResponse>(
            ServiceName,
            request,
            CalculateCylinderVolumeCallback
        );
    }

    private void CalculateCylinderVolumeCallback(
        CalculateCylinderVolumeResponse response)
    {
        Debug.Log("Response受信: V = " + response.v);
    }
}

作成したスクリプトをHierarchyの、

SimpleClient

へアタッチします。


前回のSimplePublisherをOFFにする

Topic通信の学習で作成していた、

SimplePublisher

が動作していると、

No registered publisher on topic /simple_topic

というエラーが発生する場合がありました。

今回はService通信だけを検証したいため、

SimplePublisher → OFF
SimpleClient    → ON

としました。

複数の通信処理を実装している場合、検証対象以外を一時的にOFFにするとトラブルを切り分けやすくなります。


WSL2のIPアドレスを確認する

Ubuntuで以下を実行します。

hostname -I

今回の環境では、

172.27.114.122

でした。

WSL2のIPは再起動などで変化する場合があるため、接続できない場合は再確認します。


ROS-TCP-Endpointを起動する

ターミナル①で、

cd ~/chapter2_ws

source /opt/ros/jazzy/setup.bash
source install/setup.bash

続いて、

ros2 run ros_tcp_endpoint default_server_endpoint \
  --ros-args -p ROS_IP:=172.27.114.122

を実行します。

成功すると、

[UnityEndpoint]: Starting server on 172.27.114.122:10000

のように表示されます。

このターミナルは終了せず、そのまま待機させます。


UnityのROS Settingsを設定

Unityで、

Robotics
→ ROS Settings

を開きます。

設定:

Protocol       : ROS2
ROS IP Address : 172.27.114.122
ROS Port       : 10000

ROS 2側のService Serverを起動

別のWSL2ターミナルを開きます。

cd ~/chapter2_ws

source /opt/ros/jazzy/setup.bash
source install/setup.bash

Service Serverを起動します。

ros2 run chapter2 simple_server

この状態でUnityをPlayします。

起動順は、

① ROS-TCP-Endpoint
        ↓
② ROS 2 simple_server
        ↓
③ Unity Play

です。


通信の流れ

今回構築した通信は以下です。

Unity
SimpleClient
   │
   │ Request
   │
   │ r = 2.0
   │ h = 3.0
   ▼
ROS-TCP-Connector
   │
   │ TCP
   ▼
ROS-TCP-Endpoint
   │
   │ ROS 2 Service
   ▼
ROS 2
simple_server
   │
   │ 計算
   ▼
Response
   │
   ▼
Unity Console

Unity Consoleに、

Request送信: r = 2.0, h = 3.0
Response受信: V = ...

と表示されればService通信成功です。


ハマったポイント:Connection refused

今回発生したエラーがこちらです。

Connection to 127.0.0.1:10000 failed
System.Net.Sockets.SocketException

一方、ROS-TCP-Endpoint側を見ると、

Starting server on 172.27.114.122:10000

となっていました。

構成を図にすると、

Unity

127.0.0.1:10000
      │
      │ 接続
      ▼
      ×


WSL2

172.27.114.122:10000
      │
      └─ ROS-TCP-Endpoint

となっており、Unityが間違ったIPへ接続していました。

そこで、

hostname -I

でWSL2のIPを確認し、

Unity
→ Robotics
→ ROS Settings
→ ROS IP Address

を、

172.27.114.122

へ変更しました。

Windows上のUnityとWSL2上のROS 2を接続する場合、IPアドレスの設定は特に注意が必要です。


ハマったポイント:No registered publisher

もう1つ発生したのが、

No registered publisher on topic /simple_topic

というエラーです。

原因はService通信ではなく、以前作成した、

SimplePublisher

でした。

Service通信の検証時は、

SimplePublisher → OFF
SimpleClient    → ON

として、処理を切り分けました。


TopicとServiceの使い分け

Topicは、

Publisher
    ↓
Topic
    ↓
Subscriber

という通信です。

センサ情報などの継続的なデータ配信に向いています。

LiDAR
Camera
Odometry
Robot State
/cmd_vel

などが代表例です。

一方Serviceは、

Client
   ↓ Request
Server
   ↓ Response
Client

という通信です。

「何か処理を依頼し、その結果を返してもらう」という処理に向いています。

ロボット初期化
設定取得
状態取得
計算処理
装置への単発指示

などです。


まとめ

今回、

Unity
      ↓
ROS-TCP-Connector
      ↓
TCP/IP
      ↓
ROS-TCP-Endpoint
      ↓
ROS 2 Service

という通信構成を実装しました。

Topic通信だけでなくService通信も扱えるようになることで、Unityを単なる3D表示ツールではなく、ROS 2と双方向に処理をやり取りするアプリケーションとして利用できます。

今後、

Unity
+
ROS 2
+
Gazebo
+
AMR
+
Mission Controller

という構成でデジタルツインを作っていく場合にも、今回のService通信は重要な基礎になります。

次は逆方向となる、

ROS 2
   │
   │ Request
   ▼
Unity
   │
   │ Response
   ▼
ROS 2

ROS 2 → Unity のService通信を実装してみます。


タグ

ROS2
Unity
WSL2
Robotics
DigitalTwin
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?