はじめに
ROS2では、主にC++、Pythonの2つ言語で記述することが多いです。これは、ROSのノードを記述する際のクライアントライブラリに依存しています。ROS2のコアチームがこれらの開発を行っていますが、有志によるコミュニティによって、RustやC#などの言語に対応したクライアントノードも作成されています。他にもJavaやJavaScriptなどの言語ともブリッジを介して通信できます。
Roboticsの分野では、実行時間が性能の指標として重視されます。そのため、多くのライブラリ等ではC++が選択されています。この点において、並列性や安全性も良いRustが近年注目を浴びています。今回は、C++、Python、Rustに焦点を当て、(+他の言語もちょっとだけ)どのようなケースでどの言語を選択するか、言語ごとのROS2におけるユースケースを探っていきたいと思います!!
あくまで個人的な意見なので、参考までに。ご意見等はコメントいただけると嬉しいです!!
各言語の特徴
C++
多くのロボット系のライブラリ(ROS2含め)はC++で書かれていることが多いです
長所
- 高速で、低レイヤーを含めた制御性が高い
- リアルタイム性が高い
短所
- メモリ管理が課題ですが、最近ではスマートポインタやRAIIなどで安全面を確保する動きがあります
- 一応ビルドしてライブラリとして配布できますが、エコシステムが依然として古典的で悪い(gitやaptで入手)
- 実行ファイルの依存関係が大きい
Python
長所
短所
- インタプリタで実行するので、速度が課題(特に数値計算など)
- メモリの安全性はありますが、実行時エラーが起こりやすく、テストケースを作成したり、デバッグが大変
- GIL(Global Interpreter Lock)によりマルチスレッド性能が弱いため、並列処理ではプロセス分割が前提
Rust
長所
- コンパイル時にデータ競合を防ぎ、マルチスレッドの安全性が高い
- エラーハンドリングがしやすい
- GC(ガベージコレクション)がないため、C++に並ぶ速度を発揮できる
- Cargoによるパッケージ管理が非常に強力
- 低レイヤーから高レイヤーまで対応できる
短所
- 他の2つに比べて情報源が少ない
- ライブラリの数が少ない
- 公式サポートされておらず、Stableでない
どれを選ぶ??
以上をふまえて、各言語を使う場面を考えてみたいと思います(あくまで筆者の考えです)。
C++を使う場面
- リアルタイム性や計算量が大きいところで極限性能が必要なとき
- ハードウェアとの密結合が必要なとき
- 既存のC++資産を活用したいとき
通信遅延やスループットを考慮すると、性能面ではやはりC++が最速です。しかし、昨今のRustの発展を鑑みると、リソースの制限が厳しいときやハードウェアに近く、C++のライブラリを用いて開発したいときに適していると思います。
Pythonを使う場面
- プロトタイピング
- AI・ML、データ解析、画像処理
- GUI作成
- launch ファイル
AIが関わるときは基本的にPythonで記述することが多くなると思います。リソースや速度を考慮しない場面では、とりあえずPythonでいいかもしれません(AIがコーディングしやすいだろうし)。
Rustを使う場面
- 高信頼・高安全性が求められる
- 並列処理・大規模システム
- 高速かつ安全なロボットソフトウェアを作りたい
使用するツールやライブラリに問題がなければ、Rustで作るのが安全で性能や管理の面でも良いです。特に、クリティカルシステム(自動運転、産業ロボット、インフラシステムなど)をROS2で構築する場合はRustが適しているかもしれません。
その他の言語
以下のものは一例で、他にも色々な言語とROS2を連携できます。組み合わせによっては様々な応用が可能になると思います!
そういえば、Rustと位置付けが近いZigという言語がC++の代替として一時期話題となっていましたね。リリースが安定したらこれらに加わるかもしれませんね!
C#
rclcsといった.NET バインディングのRCLがあります。Unityと相性がいいので、Unityでロボットのシミュレーションが可能です。
Java
JVMやAndroid用のclient libraryや、Zenohを使っても通信できます。Android端末で制御・可視化した場合やJavaのサーバーと連携がしやすいです。
JavaScript
WebSocket Bridgeで通信を行うのが一般的だと思います。Webアプリやクラウドとの連携用途として考えられます。
ROS2の課題
ROS2が複数の言語に対応しているのは、ROS Client Library(RCL)の思想に基づいているからです。共通のRCL機能はC言語インターフェースで提供し、他の言語はこれをラッパーします。これにより、異なる言語でノードを書いてもそれらのノード間で通信が可能となります。しかし、C言語やC++のエコシステムが悪く、ここがROS2のボトルネックになっていることも否めません。他にも以下のような課題が挙げられます。
- リアルタイム性への対応が難しい(DDSが非決定性を持つ)
- DDSによるネットワークの問題(NAT超え、負荷、ベンダー間互換)
- 分散システムにおける挙動の再現性が低い
- 可視化ツールの安定性
- 多すぎる抽象化
- セキュリティが十分ではない(DDS Securityも複雑)
- AIツール周りと相性が悪いときがある
- DDS、シリアライズ、アプリケーションレイヤーなどでのオーバーヘッド
DDSの問題にはZenohなど、一部機能を代替する手段も出ています。最近では、AIとの統合が容易で、データフロー指向であるdora-rsがROS2の代替として注目を浴びています。Pythonで記述したROS2コードと比較して、最大17倍速いそうです。ROS2の課題については、コミュニティでも様々な議論が展開されています。
まとめ
今回はROS2でどの言語を使用するかについて考えてみました。 言語によって一長一短があり、用途によって使用する言語が異なると思いますが、やはりRustの期待値は大きいですね!パッケージ管理ツールをはじめとした多くのツールで高速なRustが採用されています。RosConなど様々なところで今後のROSのアーキテクトに関する議論が進んでいますが、仮にROS3が出る場合、Rustが中核になる可能性も高いと思います!!
各言語の使用場面や用途について、ぜひコメントいただけるとうれしいです!!✨