ROS 2 公式文書(英語) 日本語訳シリーズです。
本ブログの日本語翻訳版のトップページは以下のリンクを参照下さい。
※2019/05/11 現在のものです。
背景
かつて rosbuild
というビルドシステムがありました。それから catkin
と呼ばれるものもできました。最近導入されたものは ament
と呼ばれるもので、いつか catkin
に取って代わるかもしれません。
これら 3 つのツールはすべて「メタビルドシステム」と見なすことができます。他のビルドシステム(CMake、Python setuptools など)の上に配置され、特に複数のパッケージにまたがる依存関係を管理するときや単一のワークスペースに複数のパッケージをビルドするときに、これらのビルドシステムを使いやすくするための追加機能を提供してくれます。
これらの各メタビルドシステムは、2 つのことを行います。
- 一般的なタスクを単純化するために使用できるAPI(例:CMake)を基盤となるビルドシステムに追加します(たとえば、実行可能ファイルをビルドするときに依存パッケージによってエクスポートされるすべてのフラグを指定する)。通常、コアのメタビルドシステムの外部のパッケージによる追加のAPIのインジェクションを可能にするためのフックがあります。
rosbuild
:mk/cmake.mk
、rosbuild_init()
、rosbuild_add_executable()
などcatkin
:catkin_package()
、catkin_install_python()
などament
:ament_target_dependencies()
、ament_export_dependencies()
、ament_package()
など
- パッケージでいっぱいのワークスペースで依存関係の順序で反復し、それぞれをビルドしてインストールするために使用できるツールを提供します。
rosbuild
:rosmake
catkin
:catkin build
、catkin_make
、catkin_make_isolated
などament
:ament build
これらのシステムすべてを結び付ける共通のスレッドは、コードをパッケージに分割することです。各パッケージには、マニフェストファイル(manifest.xml
または package.xml
)が含まれています。このマニフェストは、メタビルドシステムの API とビルドツールの両者が機能するために(いくつかの例外を除いて)必要となります。
仮定
- 私たちは通常、メタビルドシステムの 2 つの特長(API とビルドツール)を組み合わせることを考えていますが、そうである必要はありません。
- パッケージ内で使用される API とパッケージを反復処理するツールは、パッケージマニフェストがそれらの間のインタフェースを形成しているため、ほぼ独立していると見なすことができます。
rosmake
が(cmake
とmake
に渡される適切なフラグを使って)、catkin
パッケージが入っているワークスペースを反復処理し、依存関係の順序でそれらにステップインして、それぞれのルーチン(mkdir build; cd build; cmake ..; make install
)を実行するように変更できないのは、原則として理由はありません。
- パッケージ内で使用される API とパッケージを反復処理するツールは、パッケージマニフェストがそれらの間のインタフェースを形成しているため、ほぼ独立していると見なすことができます。
あるメタビルドシステムから別のビルドシステムへ移行するのに必要な労力は最小限にすべきです。
rosbuild から
catkin` への大量移行は困難で、多くのユーザにとって依然として悩ましい点です。新機能にアクセスできるようにする、開発者に変更を加えるよう依頼することは合理的なのですが、その変更のため新しいシステムの有効性が損なわれるような影響は可能な限り最小化すべきです。これは、古いシステムが広く使用されている場合に特に当てはまります。- 導かれる知見:新しいメタビルドシステムへの移行は、よっぽど正当な理由がない限り、要求されるべきではありません。
- 開発者が新しいシステムによって提供される機能を特に欲さないのであれば、古いシステムでは解決不能なレベルの問題がない限り(例えば rosbuild のインソースビルドパターンや「インストール」ステップがない等)、そのパッケージを無理に新しいシステムに移行すべきではありません。
相互運用性は良いことです。
可能であれば(すべての組み合わせが実用的ではない)、開発者は、異なる側面を混在させることを含めて、メタビルドシステムを混在させることができます(つまり、あるシステムの構築ツールと別のシステムのAPIを使用)。このようなミキシングおよびマッチングは、開発者が1つのメタビルドシステム(ROSとcatkinなど)を使用する大規模な既存のコードベースを、別のメタビルドシステムを使用するコードベースによって提供される新しいライブラリとツール(ROS2など)と組み合わせる場合に特に重要です。 amentと)理想的には、そのような組み合わせは、どちらのコードベースでも使用されるAPIへの変更を必要とせずに、またどのビルダーツールを使用するかを開発者に指示することなく実行できます。
導かれる知見:ワークスペースは均一である必要はありません。
catkin
とament
の両パッケージをワークスペース内に入っていて、しかも依存関係は両方向にあるような状況だとしても、使用するビルダツールがそれらを両方をビルドできる仕様であれば、それができない理由はありません(要は、両方入っていてもビルドできるでしょってこと)。パッケージ(少なくとも CMake 管理パッケージ)間の主要なインターフェースはそれらの CMake 設定ファイルです。その設定ファイルが標準プロトコル(foo_LIBRARIES
の設定など)に従っている限り、誰がファイルを書いたかは関係ありません。catkin
やament
によって自動生成されたりすることもありますし、自作パッケージでプレーンな CMake を使いたい開発者が手で直接書いた設定ファイルであることもあります。しかも、後者の自作設定ファイル内で、更にcatkin
やament
に依存されているパッケージを記述している場合もあるくらいです。
実験的な実装によるユースケース
ROS 2 ワークスペースに ROS パッケージを追加して ament build
でビルドする
既存の ROS パッケージを ROS 2 ワークスペースに追加し、その ROS パッケージを catkin から ament に(またはその逆に)移行したくない状況を仮定としましょう。これを可能にする 2 つのパッチがあります。
ament_package
:フォーマット 2 を要求する代わりに、フォーマット 1 のパッケージマニフェストのサポートを追加します。この変更は、catkin
とament
に厳密には関係しません。というのも、フォーマット 2 はしばらく前から存在し、catkin
がそれをサポートしているので、開発者が既にcatkin
側のマニフェストを更新できる状況でうす。しかし、フォーマット1を使用する大量の ROS コードがありますので、それをサポートする必要があります。この実装は、たとえば、さまざまな種類の依存タグ、およびフォーマット 1 と 2 の間でタグがどのように異なるかを推論することによって改善できます。ament_tools
:新しいcatkin
ビルドタイプをament
に追加します。この実装はcatkin
パッケージを普通のcmake
パッケージと同じように扱うだけで、うまくいきます。今後もっと洗練されたものになるでしょう。使用例
- 上記のブランチを使用して、通常どおり ROS 2 コードを入手してください。
- ワークスペースに
catkin
ROS パッケージを追加して、それらのすべての依存関係が満たされていることを確認します(ワークスペースに存在するか、適切なセットアップシェルファイルを使用して他の場所にインストールされます)。 - 通常どおりにビルドします(例:
./src/ament/ament_tools/scripts/ament.by build
)。
ジャジャ~ン!:新しいビルダーツールが使用されているからといって、既存のコードが突然壊れることはありません。
ケース 1:ament build
を使って ROS パッケージをビルドする
新しい ament
ツールがお気に入りになり、catkin
を内部的に使用する既存の ROS パッケージをビルドするのに ament
を使いたくなったとしましょう。これを実行する方法の例を次に示します。ament
を最小インストールしてから、それを使用して ROS catkin
パッケージの入ったワークスペースを構築します。
mkdir -p ~/ament_ws/src cd ~/ament_ws/src git clone https://github.com/osrf/osrf_pycommon.git git clone https://github.com/ament/ament_package.git cd ament_package git checkout catkin cd .. git clone https://github.com/ament/ament_tools.git cd ament_tools git checkout catkin cd ../.. ./src/ament_tools/scripts/ament.py build
それではROSパッケージをビルドしてください。
. $HOME/ament_ws/install/setup.bash cd ~/ros_catkin_ws ament build
ジャジャ~ン:catkin
パッケージを移行することなく、ament build
ツールを使って catkin
パッケージを構築しました。
ケース 2:ROS 2 パッケージで catkin
API を使う
ここでは、まず ROS 2 上ででビルドしていて(ament
API を内部的に使用している)、その後 catkin
API を使用して新しいパッケージを追加したい状況を考えます。
これを機能させるには、catkin
の Python3 のインストールが必要です(バイナリ Debian は Python2.7 を使用します)。これを行う例を次に示します。$HOME/catkin
にインストールします。
# install catkin_pkg git clone https://github.com/ros-infrastructure/catkin_pkg.git cd catkin_pkg git checkout ament python3 setup.py install --prefix $HOME/catkin --single-version-externally-managed --record foo --install-layout deb # install catkin git clone https://github.com/ros/catkin.git cd catkin git checkout ament mkdir build cd build PYTHONPATH=$HOME/catkin/lib/python3/dist-packages/ cmake .. -DCMAKE_INSTALL_PREFIX=$HOME/catkin -DPYTHON_EXECUTABLE=/usr/bin/python3 make install
そのバージョンの catkin を使用するには、$HOME/catkin/setup.bash
ファイルを入手するだけです。
通常の ROS 2 ワークスペースが ~/ros2_ws
にあり、ament_package
とament_tools
の catkin
ブランチにいるとしましょう。そのワークスペースに https://github.com/gerkey/catment から image_tools_catkin
パッケージを追加してください。これは ROS 2 の image_tools
パッケージを単純に移植したもので、ament
API から catkin
API に変更されました。それをビルドするには:
cd ~/ros2_ws . $HOME/catkin/setup.bash ./src/ament/ament_tools/scripts/ament.py build
ジャジャ~ン:ROS 2 の上に新しいパッケージを追加するとき、自作パッケージに対して、どの CMake API を好むかを自由に選ぶことができます。
- 警告:
catkin_package()
の中でCATKIN_DEPENDS
を使用することをコメントアウトしなければなりませんでした。なぜなら、rclcpp
等(ROS 2 で追加されたパッケージ)がcatkin
パッケージではないことで怒られたからです。その制約はなんとかして外してやる必要があります。 - TODO:同じデモですが、
catkin
パッケージに依存するament
パッケージがあります(これは簡単に解決できます)。 - TODO:同じデモですが、
ament
もcatkin
も使用しないきれいな CMakeLists.txtを持ち、ROS の外部でも普通に使えるように適切なものをエクスポートする、手入力で生成されたfooConfig.cmake
ファイルを提供するパッケージがあります。
catkin_make_isolated
による ROS 2 パッケージの構築
すでに ROS と catkin に精通しており、ROS 2 を試すことに興奮しているそこのあなた。ament
について学ぶ気なんて起きないかも知れませんね。そんなあなたに、catkin_make_isolated
を使ってすべてをビルドできる機能があれば、良いと思いませんか?これを可能にするパッチがあるのです。
- catkin:ビルドタイプが
ament_*
であることを宣言しているパッケージのサポートを追加しました。この実装はそのような各パッケージをビルドするためにament
を要求します。ament_cmake
パッケージはプレーンなcmake
パッケージとして扱うことができますが(ament
にcatkin
サポートを追加したときのように)、ament_python
パッケージは普通の Python 呼び出しを必要とする場合があります。そのロジックをcatkin
で再現するのではなく、単にament
に処理させる方が簡単です。またこのパッチでは、buildtool_export_depend
パッケージをビルド時に考慮されるセットに追加します。 - catkin_pkg:このパッチでも、トポロジ順序を計算するときに考慮される
buildtool_export_depend
パッケージをセットに追加します。
ここでは ament build
を呼び出すことになるので、前の例で行ったように、最低限の ament
のインストールも必要になります。
mkdir -p ~/ament_ws/src cd ~/ament_ws/src git clone https://github.com/osrf/osrf_pycommon.git git clone https://github.com/ament/ament_package.git cd ament_package git checkout catkin cd .. git clone https://github.com/ament/ament_tools.git cd ament_tools git checkout catkin cd ../.. ./src/ament_tools/scripts/ament.py build
それから、ament
対応版の catkin
をどこかにインストールする必要があります。
# install catkin_pkg git clone https://github.com/ros-infrastructure/catkin_pkg.git cd catkin_pkg git checkout ament python3 setup.py install --prefix $HOME/catkin --single-version-externally-managed --record foo --install-layout deb # install catkin git clone https://github.com/ros/catkin.git cd catkin git checkout ament mkdir build cd build PYTHONPATH=$HOME/catkin/lib/python3/dist-packages/ cmake .. -DCMAKE_INSTALL_PREFIX=$HOME/catkin -DPYTHON_EXECUTABLE=/usr/bin/python3 make install
それでは ROS 2 パッケージをビルドしてください。
. $HOME/catkin/setup.bash . $HOME/ament_ws/install/setup.bash cd ~/ros2_ws touch src/eProsima/AMENT_IGNORE PYTHONPATH=$PYTHONPATH:/home/gerkey/ros2_ws_catkin/install_isolated/lib/python3.5/site-packages catkin_make_isolated --install
ジャジャ~ン:ROS 2 はお馴染みのツールでビルドできました。
- 警告:
package.xml
ファイルがないため、ワークスペース内のeProsima
パッケージは無視されます。つまり、catkin
はそれらを見ることができません。ament
はそのようなパッケージを扱うための経験則を持っています。- オプション:この経験則を
catkin
に戻します。ワークスペースの外側でpackage.xml
を含まないパッケージのインストールに切り替えます。または、単にそれらの各パッケージに package.xml を追加します(たとえば、fork して編集する等)。
- オプション:この経験則を
ROS と ROS 2 のすべてを一つのワークスペースにまとめて構築する(TODO)
このステップでは、少なくとも以下を含むいくつかのことを整理する必要があります。
- パッケージ名の競合:現在、ROS メッセージパッケージのROS 2 バージョンがあります。geometry2 にも同様のものが含まれてしまっています。この機能を両方のシステムをサポートできる 1 つのパッケージにマージするか、新しいバージョンでは異なる名前とする必要があります。
- メッセージ生成:ROS と ROS 2 には異なるメッセージ生成手順があり、その出力は競合する場合としない場合があります。単一のメッセージパッケージから正しい実体をすべて生成できるようにするには、何らかのうまい方法を実行する必要があります(または、上記のように、新しいメッセージパッケージには別の名前が必要です)。
bloom
を使って ament パッケージをリリースする(TODO)¶
ament
CMake API を使用するパッケージを bloom
がリリースできるようになり、その結果リリースされるものはファーム上に構築できるようになるはずです。このユースケースを有効にするために必要に応じて bloom
とros_buildfarm
に変更を加えることができます。