MoriKen's Journal

MoriKen's Journal

アラサー社会人博士による徒然日記。技術についてつらつら。だけだとコンテンツが貧弱なので、会社公認で大学院博士課程に進学した経緯や、独学でTOEICを475→910にしたノウハウを共有します。

【ROS 2】ament と catkin の混合(→ catment)について(公式文書和訳)

Sponsored Link

ROS 2 公式文書(英語) 日本語訳シリーズです。

本ブログの日本語翻訳版のトップページは以下のリンクを参照下さい。

www.moriken254.com

※2019/05/11 現在のものです。

背景

かつて rosbuild というビルドシステムがありました。それから catkin と呼ばれるものもできました。最近導入されたものは ament と呼ばれるもので、いつか catkin に取って代わるかもしれません。

これら 3 つのツールはすべて「メタビルドシステム」と見なすことができます。他のビルドシステム(CMake、Python setuptools など)の上に配置され、特に複数のパッケージにまたがる依存関係を管理するときや単一のワークスペースに複数のパッケージをビルドするときに、これらのビルドシステムを使いやすくするための追加機能を提供してくれます。

これらの各メタビルドシステムは、2 つのことを行います。

  1. 一般的なタスクを単純化するために使用できるAPI(例:CMake)を基盤となるビルドシステムに追加します(たとえば、実行可能ファイルをビルドするときに依存パッケージによってエクスポートされるすべてのフラグを指定する)。通常、コアのメタビルドシステムの外部のパッケージによる追加のAPIのインジェクションを可能にするためのフックがあります。
    • rosbuildmk/cmake.mkrosbuild_init()rosbuild_add_executable()など
    • catkincatkin_package()catkin_install_python() など
    • amentament_target_dependencies()ament_export_dependencies()ament_package() など
  2. パッケージでいっぱいのワークスペースで依存関係の順序で反復し、それぞれをビルドしてインストールするために使用できるツールを提供します。
    • rosbuildrosmake
    • catkincatkin buildcatkin_makecatkin_make_isolated など
    • amentament build

これらのシステムすべてを結び付ける共通のスレッドは、コードをパッケージに分割することです。各パッケージには、マニフェストファイル(manifest.xml または package.xml)が含まれています。このマニフェストは、メタビルドシステムの API とビルドツールの両者が機能するために(いくつかの例外を除いて)必要となります。

仮定

  1. 私たちは通常、メタビルドシステムの 2 つの特長(API とビルドツール)を組み合わせることを考えていますが、そうである必要はありません。
    • パッケージ内で使用される API とパッケージを反復処理するツールは、パッケージマニフェストがそれらの間のインタフェースを形成しているため、ほぼ独立していると見なすことができます。rosmake が(cmakemake に渡される適切なフラグを使って)、 catkin パッケージが入っているワークスペースを反復処理し、依存関係の順序でそれらにステップインして、それぞれのルーチン(mkdir build; cd build; cmake ..; make install)を実行するように変更できないのは、原則として理由はありません。
  2. あるメタビルドシステムから別のビルドシステムへ移行するのに必要な労力は最小限にすべきです。

    • rosbuild からcatkin` への大量移行は困難で、多くのユーザにとって依然として悩ましい点です。新機能にアクセスできるようにする、開発者に変更を加えるよう依頼することは合理的なのですが、その変更のため新しいシステムの有効性が損なわれるような影響は可能な限り最小化すべきです。これは、古いシステムが広く使用されている場合に特に当てはまります。
    • 導かれる知見:新しいメタビルドシステムへの移行は、よっぽど正当な理由がない限り、要求されるべきではありません。
      • 開発者が新しいシステムによって提供される機能を特に欲さないのであれば、古いシステムでは解決不能なレベルの問題がない限り(例えば rosbuild のインソースビルドパターンや「インストール」ステップがない等)、そのパッケージを無理に新しいシステムに移行すべきではありません。
  3. 相互運用性は良いことです。

    • 可能であれば(すべての組み合わせが実用的ではない)、開発者は、異なる側面を混在させることを含めて、メタビルドシステムを混在させることができます(つまり、あるシステムの構築ツールと別のシステムのAPIを使用)。このようなミキシングおよびマッチングは、開発者が1つのメタビルドシステム(ROSとcatkinなど)を使用する大規模な既存のコードベースを、別のメタビルドシステムを使用するコードベースによって提供される新しいライブラリとツール(ROS2など)と組み合わせる場合に特に重要です。 amentと)理想的には、そのような組み合わせは、どちらのコードベースでも使用されるAPIへの変更を必要とせずに、またどのビルダーツールを使用するかを開発者に指示することなく実行できます。

    • 導かれる知見:ワークスペースは均一である必要はありません。

      • catkinament の両パッケージをワークスペース内に入っていて、しかも依存関係は両方向にあるような状況だとしても、使用するビルダツールがそれらを両方をビルドできる仕様であれば、それができない理由はありません(要は、両方入っていてもビルドできるでしょってこと)。パッケージ(少なくとも CMake 管理パッケージ)間の主要なインターフェースはそれらの CMake 設定ファイルです。その設定ファイルが標準プロトコル(foo_LIBRARIESの設定など)に従っている限り、誰がファイルを書いたかは関係ありません。 catkinament によって自動生成されたりすることもありますし、自作パッケージでプレーンな CMake を使いたい開発者が手で直接書いた設定ファイルであることもあります。しかも、後者の自作設定ファイル内で、更にcatkinament に依存されているパッケージを記述している場合もあるくらいです。

実験的な実装によるユースケース

ROS 2 ワークスペースに ROS パッケージを追加して ament build でビルドする

既存の ROS パッケージを ROS 2 ワークスペースに追加し、その ROS パッケージを catkin から ament に(またはその逆に)移行したくない状況を仮定としましょう。これを可能にする 2 つのパッチがあります。

  • ament_package:フォーマット 2 を要求する代わりに、フォーマット 1 のパッケージマニフェストのサポートを追加します。この変更は、catkinamentに厳密には関係しません。というのも、フォーマット 2 はしばらく前から存在し、catkin がそれをサポートしているので、開発者が既にcatkin側のマニフェストを更新できる状況でうす。しかし、フォーマット1を使用する大量の ROS コードがありますので、それをサポートする必要があります。この実装は、たとえば、さまざまな種類の依存タグ、およびフォーマット 1 と 2 の間でタグがどのように異なるかを推論することによって改善できます。
  • ament_tools:新しい catkin ビルドタイプを ament に追加します。この実装は catkin パッケージを普通の cmake パッケージと同じように扱うだけで、うまくいきます。今後もっと洗練されたものになるでしょう。

  • 使用例

    1. 上記のブランチを使用して、通常どおり ROS 2 コードを入手してください。
    2. ワークスペースに catkin ROS パッケージを追加して、それらのすべての依存関係が満たされていることを確認します(ワークスペースに存在するか、適切なセットアップシェルファイルを使用して他の場所にインストールされます)。
    3. 通常どおりにビルドします(例:./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_packageament_toolscatkin ブランチにいるとしましょう。そのワークスペースに 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:同じデモですが、amentcatkin も使用しないきれいな CMakeLists.txtを持ち、ROS の外部でも普通に使えるように適切なものをエクスポートする、手入力で生成された fooConfig.cmake ファイルを提供するパッケージがあります。

catkin_make_isolated による ROS 2 パッケージの構築

すでに ROS と catkin に精通しており、ROS 2 を試すことに興奮しているそこのあなた。ament について学ぶ気なんて起きないかも知れませんね。そんなあなたに、catkin_make_isolated を使ってすべてをビルドできる機能があれば、良いと思いませんか?これを可能にするパッチがあるのです。

  • catkin:ビルドタイプが ament_* であることを宣言しているパッケージのサポートを追加しました。この実装はそのような各パッケージをビルドするために ament を要求します。 ament_cmake パッケージはプレーンな cmake パッケージとして扱うことができますが(amentcatkin サポートを追加したときのように)、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 がリリースできるようになり、その結果リリースされるものはファーム上に構築できるようになるはずです。このユースケースを有効にするために必要に応じて bloomros_buildfarm に変更を加えることができます。

翻訳元文書

index.ros.org

関連文書

www.moriken254.com

www.moriken254.com