aptpod Tech Blog

株式会社アプトポッドのテクノロジーブログです

AWS EC2インスタンス間でのROS2通信:FastDDS Discovery Serverによる解決

aptpod Advent Calendar 2024 12月18日の記事を担当します、Roboticsグループの久保田です。

今回は、AWS EC2インスタンス間でのROS2通信を可能にする解決策として、FastDDS Discovery Serverを取り上げます。Discovery Serverは、ROS2のデフォルトのディスカバリープロトコルが抱える課題を克服し、マルチキャストパケットが利用できない環境や、LiDARデータや動画データといった大容量データを扱う高負荷なネットワークでも、効率的かつ信頼性の高い通信を可能にします。

概要

ROS2では通信相手を検出するためにDiscoveryプロトコルを使用します。このDiscoveryプロトコルはマルチキャストパケットを使用しており、ROS1のような単一障害点を持たないという利点があります。

一方で、いくつかの課題があります。

  • 新しいノードが追加されるたびに発生するパケット数が増加し、ネットワーク負荷が高まるため、効率的なスケーリングが困難となる。
  • WiFiネットワーク環境やLiDARデータや動画データなどを通信する高負荷なネットワークでは、通信のパフォーマンスが低下する可能性がある。
  • クラウド環境や一部のネットワーク構成では、マルチキャスト通信がサポートされていない場合がある。
  • WiFiなどの環境では、マルチキャスト通信が安定して動作しないケースが多い。

AWS EC2インスタンス間では、マルチキャストおよびブロードキャスト通信がデフォルトではサポートされていません。これにより、ROS2のデフォルトDiscoveryプロトコルが使用するマルチキャスト通信による相手検出が機能しなくなります。この制限はAWSの仮想プライベートクラウド(VPC)の設計に起因しており、VPC内ではマルチキャストトラフィックが意図的にブロックされています。一方、AWS Transit Gatewayを利用することで、限定的にマルチキャスト通信を有効化することが可能です。ただし、この方法は高度なネットワーク設定を伴い、構成の複雑さが課題となります。これらの理由から、AWS環境でROS2のマルチキャスト通信を実現する際には、設定の複雑さと技術的制約を十分に考慮する必要があります。

そこで、FastDDSがDiscoverプロトコルの代替として用意しているDiscovery Serverを使用します。Discovery Serverは、ROS2ノード間の通信を管理するための集中型サーバーとして機能します。このサーバーは、各ノードのメタデータ(場所、アドレス、ポート情報など)を保存し、他のノードが必要な情報を効率的に取得できるようにします。

Discovery Server

https://docs.ros.org/en/jazzy/_images/ds_explanation.svg

ROS 2におけるDiscovery Serverは、ネットワーク上のノード間の発見と通信を効率化するための集中型メカニズムです。Fast DDSが提供するDiscovery Serverは、従来の分散型Discoveryプロトコルに代わり、クライアント-サーバーアーキテクチャを採用しています。

docs.ros.org

Discovery Serverを使用する以下の利点があります

  • ネットワークトラフィックの削減: デフォルトのDiscoveryプロトコルが生成する大量のマルチキャストトラフィックを削減し、ネットワークの負荷を軽減します。

  • マルチキャスト非対応環境での利用: AWS VPCやその他のマルチキャスト非対応の環境でも動作可能です。

https://docs.ros.org/en/jazzy/_images/discovery_packets.svg

一方で、デメリットも留意する必要はあります

  • 単一障害点のリスク: Discovery Serverは単一障害点となる可能性があり、冗長構成を考慮する必要があります。

  • 負荷の集中: Discovery Serverに負荷が集中するため、適切なリソース(CPU、メモリ、ネットワーク帯域など)を割り当てることが推奨されます。

  • 管理の手間: サーバーの監視や障害対応のために、追加の管理作業が必要となります。

AWS EC2インスタンスで使用する

構成

AWS EC2インスタンス設定

リソースベースのホスト名へ変更

Discovery ServerのIPアドレスをLocal DNSから取得するためにリソースベースのホスト名へ変更しておくと便利です。これにより、DNSリゾルバを利用してIPアドレスを動的に管理できるため、固定IPアドレスの手動設定が不要となります。

「アクション」=> 「インスタンスの設定」=> 「リソースベースの命名オプションを変更」

リソースベースの命名オプションを変更

セキュリティグループでのUDPインバウンドを許可

Discovery Serverとの通信のために、UDPプロトコルのインバウンド通信を許可しておきます。これは、ROS2ノード間でのDiscovery Serverとのメタデータ交換を可能にするために必要です。

「インスタンス」=> 「セキュリティ」タブ=>「セキュリティグループ」=>「インバウンドのルールを編集」

インバウンドのルールを編集

FastDDS設定

Discovery Serverを使用するために、Server/ClientそれぞれにFastDDSの設定が必要です。Fast DDSの設定は、設定ファイルfastrtps-profile.xmlを作成し、環境変数 (FASTRTPS_DEFAULT_PROFILES_FILE) で指定します。

通信相手を検出するため、Discovery ServerのIPアドレス(ホスト名)および使用するポート番号を設定ファイルに記載してください。

Server

fastrtps-profile.xml

<?xml version="1.0" encoding="UTF-8" ?>
<profiles xmlns="http://www.eprosima.com/XMLSchemas/fastRTPS_Profiles">
    <transport_descriptors>
        <transport_descriptor>
            <transport_id>CustomUdpTransport</transport_id>
            <type>UDPv4</type>
        </transport_descriptor>
    </transport_descriptors>

    <participant profile_name="participant_profile" is_default_profile="true">
        <rtps>
            <userTransports>
                <transport_id>CustomUdpTransport</transport_id>
            </userTransports>
            <useBuiltinTransports>false</useBuiltinTransports>

            <prefix>44.53.00.5f.45.50.52.4f.53.49.4d.41</prefix>
            <builtin>
                <discovery_config>
                    <discoveryProtocol>SERVER</discoveryProtocol>
                </discovery_config>
                <metatrafficUnicastLocatorList>
                    <locator>
                        <udpv4>
                            <address>i-05a0c3018209bc88b.ap-northeast-1.compute.internal</address>
                            <port>11811</port>
                        </udpv4>
                    </locator>
                </metatrafficUnicastLocatorList>
            </builtin>

            <sendSocketBufferSize>31457280</sendSocketBufferSize>
            <listenSocketBufferSize>31457280</listenSocketBufferSize>
        </rtps>
    </participant>
</profiles>

Client

fastrtps-profile.xml

<?xml version="1.0" encoding="UTF-8" ?>
<profiles xmlns="http://www.eprosima.com/XMLSchemas/fastRTPS_Profiles">
    <transport_descriptors>
        <transport_descriptor>
            <transport_id>CustomUdpTransport</transport_id>
            <type>UDPv4</type>
        </transport_descriptor>
    </transport_descriptors>

    <participant profile_name="participant_profile" is_default_profile="true">
        <rtps>
            <userTransports>
                <transport_id>CustomUdpTransport</transport_id>
            </userTransports>
            <useBuiltinTransports>false</useBuiltinTransports>

            <builtin>
                <discovery_config>
                    <discoveryProtocol>SUPER_CLIENT</discoveryProtocol>
                    <discoveryServersList>
                        <RemoteServer prefix="44.53.00.5f.45.50.52.4f.53.49.4d.41">
                            <metatrafficUnicastLocatorList>
                                <locator>
                                    <udpv4>
                                        <address>i-05a0c3018209bc88b.ap-northeast-1.compute.internal</address>
                                        <port>11811</port>
                                    </udpv4>
                                </locator>
                            </metatrafficUnicastLocatorList>
                        </RemoteServer>
                    </discoveryServersList>
                </discovery_config>
            </builtin>

            <sendSocketBufferSize>31457280</sendSocketBufferSize>
            <listenSocketBufferSize>31457280</listenSocketBufferSize>
        </rtps>
    </participant>
</profiles>

XMLタグの説明

タグ名 説明
<transport_descriptors> 通信に使用するトランスポートの設定を指定します。
<transport_descriptor> トランスポートの詳細(IDやタイプなど)を設定します。 ここではUDPを指定しています
<participant> ROS2ノードのプロファイル設定を指定します。この設定には、トランスポート、バッファサイズ、Discoveryプロトコルなどが含まれます。
<prefix> Discovery ServerのGUIDをしていします。
<discovery_config> Discovery Serverのプロトコルやサーバー情報を設定します。このタグを使用して通信方式(SERVER/SUPER_CLIENTなど)やリモートサーバーリストを定義します。
<discoveryProtocol> Discovery Serverの動作モードを定義します(例: SERVERはサーバーとして、SUPER_CLIENTはクライアントとして機能)。
<discoveryServersList> Discovery Serverのリストを定義します。これにより、クライアントノードがどのサーバーに接続するかを指定できます。
<metatrafficUnicastLocatorList> メタトラフィック通信に使用するロケータリストを指定します。このロケータリストは、Discovery Serverがクライアントノードと通信するためのIPアドレスやポート番号を定義します。これにより、特定のネットワーク設定に基づいて通信経路を明示的に管理できます。

実行手順

AWS EC2インスタンスを構築後、動作を確認していきます。

Discovery Server起動

Discovery Serverでの通信相手の検出のために、まずDiscovery Serverを起動します。起動時には、ROS DOMAIN IDや通信相手検出の通信のためのポート番号などが設定できます。

$ docker run -it --rm --name ros-server \
    --net=host \
    -e FASTRTPS_DEFAULT_PROFILES_FILE=/tmp/fastrtps-profile.xml \
    -v ./fastrtps-profile.xml:/tmp/fastrtps-profile.xml \
    ros:humble \
    fastdds discovery --server-id 0
### Server is running ###
  Participant Type:   SERVER
  Server ID:          0
  Server GUID prefix: 44.53.00.5f.45.50.52.4f.53.49.4d.41
  Server Addresses:   UDPv4:[0.0.0.0]:11811

ROSトピックをPublish

トピックをPublishするために、FastDDS設定が必要です。環境変数 (FASTRTPS_DEFAULT_PROFILES_FILE) で指定してください。

$ docker run -it --rm --name rospub \
    --net=host \
    -e FASTRTPS_DEFAULT_PROFILES_FILE=/tmp/fastrtps-profile.xml \
    -v ./fastrtps-profile.xml:/tmp/fastrtps-profile.xml \
    ros:humble \
    ros2 topic pub /my_topic std_msgs/msg/String '{data: "hello"}'
publisher: beginning loop
publishing #1: std_msgs.msg.String(data='hello')

publishing #2: std_msgs.msg.String(data='hello')

publishing #3: std_msgs.msg.String(data='hello')

ROSトピックをSubscribe

トピックをSubscribeするために、FastDDS設定が必要です。環境変数 (FASTRTPS_DEFAULT_PROFILES_FILE) で指定してください。

$ docker run -it --rm --name rossub \
    --net=host \
    -e FASTRTPS_DEFAULT_PROFILES_FILE=/tmp/fastrtps-profile.xml \
    -v ./fastrtps-profile.xml:/tmp/fastrtps-profile.xml \
    ros:humble \
    ros2 topic echo /my_topic
data: hello
---
data: hello
---
data: hello
---

SubscribeしたROSトピックが表示され、ROS2通信が問題なく動作しました。Discovery Serverを使うことで、AWS EC2インスタンス間でもROS2通信が実現できることが確認できました。

まとめ

今回は、AWS EC2インスタンス間でのROS2通信を実現する方法として、FastDDS Discovery Serverを活用する手法を紹介しました。このソリューションは、マルチキャストパケットが使用できない環境において有効であるだけでなく、LiDARデータや動画データの通信時にネットワーク負荷を低減する効果も期待できます。ROS2の通信性能や動作環境の最適化を目指す際に、ぜひ参考にしてみてください。