2023年01月31日(火) [長年日記]
■ [dev] ROS2でFast-DDSの設定を変更する
ROS2というミドルウェアを使っている。現在の最新のリリースバージョンは「Humble」。
ROS2で通信回りの動作をカスタマイズしようとすると、その下位レイヤであるDDSの設定を変更しなければならなくなる(ROS2のAPIとして整備されていないことが多い)。
ROS2でのFast DDS設定変更方法
ROS2が使うDDSの実装は変更できるが、現在のデフォルトはFast DDSである。ROS2においてFast DDSの設定を変更する方法は次のドキュメントに書かれている。
- Unlocking the potential of Fast DDS middleware (ROS 2 Documentation)
- 16.1. Configuring Fast DDS in ROS 2 (eProsima Fast DDS Documentation)
やることは次の通り。
- Fast DDSの設定を書いたXMLファイルを作成する。XMLファイルについては11. XML profilesに説明があり、色々な設定ができる。
- 環境変数 FASTRTPS_DEFAULT_PROFILES_FILE にXMLファイルのパスを設定する。
- 環境変数 RMW_FASTRTPS_USE_QOS_FROM_XML を 1 に設定する。
XMLファイル使用時に発生するエラーとその解決方法
しかし、ドキュメントに例示されているXMLファイルを用意してもエラーになってしまう!
発生するエラーは次の2種類。
- eprosima::fastcdr::exception::NotEnoughMemoryException 例外が投げられて終了する
- 次のようなエラーメッセージがたくさん出力される
[RTPS_READER_HISTORY Error] Change payload size of '68' bytes is larger than the history payload size of '35' bytes and cannot be resized. -> Function can_change_be_added_nts
困っていたが、試行錯誤の結果次のようにすると解決することが分かった。
- 前者のエラーは、XMLにis_default_profile属性をtrueに設定した<data_writer>を記述してその中で<historyMemoryPolicy>をPREALLOCATED以外に設定すれば解決する。
- 後者のエラーは、XMLにis_default_profile属性をtrueに設定した<data_reader>を記述してその中で<historyMemoryPolicy>をPREALLOCATED以外に設定すれば解決する。
つまり、次のようなXMLファイルを用意すればいい。
<?xml version="1.0" encoding="UTF-8" ?> <profiles xmlns="http://www.eprosima.com/XMLSchemas/fastRTPS_Profiles"> <data_writer profile_name="default writer profile" is_default_profile="true"> <historyMemoryPolicy>PREALLOCATED_WITH_REALLOC</historyMemoryPolicy> </data_writer> <data_reader profile_name="default reader profile" is_default_profile="true"> <historyMemoryPolicy>PREALLOCATED_WITH_REALLOC</historyMemoryPolicy> </data_reader> <!-- 以下に必要な設定を追加する --> </profiles>
なお、<data_writer>は<publisher>、<data_reader>は<subscriber>とも書ける。Fast DDSのドキュメントは全体的に<data_writer>, <data_reader> を使うように書き換えられているようなので、こちらを使うべきなのだと思う。
ドキュメントを修正してもらう
ドキュメントの通りにやってエラーになるのはおかしいので、修正するpull requestを出した。
- Add "default subscriber profile" to the XML example in the README (ros2/rmw_fastrtps)
- Fix FastDDS-Configuration.rst to work (ros2/ros2_documentation)
そうしたら、最新版(Rolling)ではエラーにならないと言われてしまった。
調べると、Fast DDS 2.9.0で
Default memory management policy set to PREALLOCATED_WITH_REALLOC_MEMORY_MODE (#3108)
というBehavior changesが入っていて、恐らくこの変更によりRollingではエラーにならないのだと思う。
まとめ
- ROS2の現状のリリース版でFast DDSの設定を変更する際には、XMLファイルにis_default_profile属性がtrueの<data_writer>と<data_reader>を記述してそれぞれのhistoryMemoryPolicyをPREALLOCATED以外に設定する必要がある。
- Fast DDSのバージョンが2.9.0以降であれば上の設定をしなくてもよくなりそう。自分では未確認。