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:rosmakecatkin: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 コードを入手してください。
- ワークスペースに
catkinROS パッケージを追加して、それらのすべての依存関係が満たされていることを確認します(ワークスペースに存在するか、適切なセットアップシェルファイルを使用して他の場所にインストールされます)。 - 通常どおりにビルドします(例:
./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 に変更を加えることができます。