はじめに
ROS 2のDDS通信とネイティブのDDS通信を混在させる方法を紹介する。
本記事ではROS 2のrclcpp/rclpyを介さず、DDS APIを直接利用する通信を「ネイティブDDS」と呼ぶ。
ネイティブDDSを使っているロボットとして、Unitree GO2やG1がある。Unitree公式のSDK (unitree_sdk2)を使って、ROS 2ノードを作成したい場合、ネイティブDDS通信とROS 2 DDS通信を一つのノードに混在させる必要がある。
動作確認環境
-
Ubuntu 22.04 x86_64/arm64
-
ROS 2 Humble
- Cyclone DDS
- ros-humble-cyclonedds 0.10.5-2jammy.20260213.230758
- ros-humble-rmw-cyclonedds-cpp 1.3.4-1jammy.20260217.034014
- Fast DDS
- ros-humble-fastcdr 1.0.29-1jammy.20260213.225749
- ros-humble-fastrtps 2.6.11-1jammy.20260214.005144
- ros-humble-fastrtps-cmake-module 2.2.4-1jammy.20260214.004026
- ros-humble-rmw-fastrtps-cpp 6.2.10-1jammy.20260217.033625
- ros-humble-rmw-fastrtps-shared-cpp 6.2.10-1jammy.20260217.033034
- ros-humble-rosidl-typesupport-fastrtps-c 2.2.4-1jammy.20260214.020147
- ros-humble-rosidl-typesupport-fastrtps-cpp 2.2.4-1jammy.20260214.015657
- Cyclone DDS
-
DDS
- Cyclone DDS (unitree_sdk2)
方法
ROS 2のCyclone DDS/Fast DDSと、UnitreeのCyclone DDSで通信の可否を検証した。
まとめ
| ROS 2 DDS | ネイティブDDS | ROS 2とネイティブDDSのドメインID※ | 結果 |
|---|---|---|---|
| Cyclone DDS | Cyclone DDS | 同じ | × |
| Cyclone DDS | Cyclone DDS | 違う | 〇 |
| Fast DDS | Cyclone DDS | 同じ | 〇 |
| Fast DDS | Cyclone DDS | 違う | 〇 |
※ここでいうドメインIDとは、ROS 2のROS_DOMAIN_IDと、
Unitree SDKのChannelFactoryInitialize(domain_id)で指定するDDSドメインIDを指す。
方法1.ROS 2通信とDDS通信でドメインIDを別にする
ROS 2通信とDDS通信のドメインIDを別にすると、本記事の検証環境では通信できた。同一ドメインIDだとDDS通信の初期化関数(ChannelFactoryInitialize(domain_id))で以下の例外になることがUnitree SDKのissue13に挙げられている。
[rmw_cyclonedds_cpp]: rmw_create_node: failed to create domain, error Precondition Not Met or [ChannelFactory] create domain error. msg: Occurred upon initialisation of a cyclonedds.domain.Domain
方法2.同じドメインIDを使う場合は、DDSベンダーを変える
同じドメインIDを使いたい場合は、DDSベンダーを別にすることで上記のDDSの初期化時のエラーを回避できた。ただし、ROS 2のService/ActionはDDSトピックだけでなくDDS固有機能にも依存しているため、ベンダー間では正常動作しない場合がある。詳細は過去の以下記事を参照。
考察
同じドメインIDでエラーとなる原因
推測だが、ROS 2のrmw_cyclonedds_cppとUnitree SDKがそれぞれ独立してCyclone DDSのParticipantやDomainを初期化しようとすることで、同一プロセス内で競合が発生している可能性がある。
まとめ
ROS 2のDDS通信とネイティブのDDS通信を混在させる方法を2つ紹介した。
- 方法1.ROS 2通信とDDS通信でドメインIDを別にする
- 方法2.同じドメインIDを使う場合は、DDSベンダーを変える
方法2は制約があるので、特別な理由がなければ、方法1(ドメインIDを分離)を推奨する。
Unitree SDKを利用したROS 2ノード開発時に、本記事の内容が参考になれば幸いである。
参考