masato-ka's diary

日々思ったこととか、やったことの備忘録。

DockerだけでROS2を開発できるコマンドラインツールを作った

1.この記事について

DockerだけでROS2の開発をするコマンドラインツールを作ったので、その使い方などを簡単にまとめた記事になる。

こんなコマンドが公式であったら嬉しいけどもっと賢いベストプラクティスがきっとあると思うので教えてほしい。

demo

2. モチベーション

次に計画しているプロジェクトに向けて、ナウでヤングなROS2に手を出してみた。インストールは簡単になっているが、多くの依存関係をローカルにインストールしたくない。AWS RoboMakerも検証してみたが、簡単にROS環境が手に入るとはいえ、インスタンスの起動時間が気になってしまう。そこでローカルに環境は構築せずに、DockerのみでROS2開発ができる環境を考えてみた。

3. DockerによるROS2開発で目指したこと。

Dockerを使ってROS2を動かす方法は種々紹介されているが、自分が目指した条件は以下の3点だ。大きな思いとしては可能な限りローカル環境で開発する場合と違いを出したくないということ。

  1. ROSのパッケージはローカル環境に置きたい - ローカルIDEなどリッチな環境を使いたい。
  2. 起動したコンテナは使い捨てる - コンテナを保持して管理する手間を増やしたくない。
  3. ネイティブと同じようなGUI環境(Gazebo, Rviz2)を起動できる - いちいちデスクトップ表示させてそこから起動とかしたくない。

4. 作ったツールの紹介

前述の条件をみたすROS2コンテナの使い方を検証して、コマンドラインツール化した。以下のリポジトリをクローンして、開発用Dockerイメージのビルド、そのイメージ名をros2-docker.shに指定してパスを通すだけで利用できる。

github.com

ros2-docker.shを使うことで、指定したローカルのワークスペースに対してros2コマンドやcolconを複雑な設定なしにDockerコンテナ内で閉じて実行することができる。任意のCI環境で使うとすごい便利じゃないかなと思ってる。

パッケージを作ってビルドしてみる。

新しくパッケージを作ってビルドする方法はこんな感じ。ローカルにROSのワークスペースを掘って、ワークスペース名を指定してcreateを実行するだけ。ros2-docker.shはrobo_wsをボリュームマウントしたdockerコンテナを作り、ros2 createに引数を渡して実行する。

>mkdir -p robo_ws/src
>ros2-docker.sh robo_ws create --build-type ament_python --node-name hello_node robo_pkg

これをビルド実行する場合はこのまま

>ros2-docker.sh robo_ws build
>ros20docker.sh robo_ws run robo_pkg hello_node

とすると、install/setup.shのsourceなど含めてよろしくやってくれる。

Moveit2のデモを動かしてみる。

もうちょっと複雑かつ、GUIの起動を伴うアプリケーションの場合をみてみる。

  • MoveIt2のサンプルを実行する場合

MoveIt2のリポジトリ群をvcsコマンドでチェクアウトしてくる。ちなみにvcsコマンドの実装をサボったため、 チェックアウトしたフォルダを手動でsrcフォルダ配下へ移動させている。

>mkdir -p moveit_ws/src
>curl wget https://raw.githubusercontent.com/ros-planning/moveit2/main/moveit2.repos -O moveit_ws/.rosintall
>ros2-docker moveit_ws vcs
>mv moveit_ws/* moveit_ws/src

ros2-docker.shは必ずコンテナを捨ててしまうため、rosdepしてもリセットされてしまう。そこで-oオプションで新しいDockerイメージ名を指定して、依存関係を解決したDockerイメージを作成する。結局イメージは管理しないといけないけどそこは妥協。

>ros2-docker -t moveit_depends_image moveit_ws rosdep install -r --from-paths . --ignore-src --rosdistro foxy -y

依存関係を解決したDockerイメージ名を-iオプションで指定してビルドを実行する。ちなみに私のMacBook pro 2020(Core i5)だと3時間くらいビルドにかかった。

>ros2-docker -i moveit_depends_image moveit_ws build --event-handlers desktop_notification- status- --cmake-args -DCMAKE_BUILD_TYPE=Release

run_moveit_cpp.launch.pyを実行する。実行時にros2-docker.shへ-gオプションを渡すとX Windowの仮想ディスプレイを立ち上げて、VNCサーバーを起動する。適当なVNCツールを使ってlocalhost:5900版へアクセスする。

>ros2-docker -i moveit_depends_image -g moveit_ws launch run_moveit_cpp run_moveit_cpp.launch.py

VNCで黒い画面しか表されない場合は画面の表示位置がおかしいので、moveit_ws/install/run_moveit_cpp/share/run_moveit_cpp/launch/run_moveit_cpp.rvizをローカルのエディタで開いてWindow GeometryのXとYの値を0に設定する。

5. 現段階の制限事項

制限事項として以下3点、今後順次対応する予定でいる。

  1. 現段階だとDockerコンテナからハードウェアへアクセスする種々の設定はできない。
  2. vcsコマンドはワークスペースディレクトリ直下の.rosinstallファイル決め打ちで処理する
  3. デバッガなどは使えない。

6. まとめ

ROS2はroscoreの廃止やノード間の通信を自己解決してくれるので、ROS1よりもDockerで扱いやすくなっている。とはいえ、本格的な開発をDockerでやるのは無理がある感もある。お試しで遊んでみたり、CIやテスト環境、本番環境へのデプロイなど重宝する場面はあるだろう。 もしこんな風にしたら?や、これやる必要ないよ、みたいなコメントがあると嬉しい。