MoriKen's Journal

MoriKen's Journal

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

【ROS 2】ament_cmake ユーザーズマニュアル(公式文書和訳)

Sponsored Link

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

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

www.moriken254.com

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

ament_cmake は ROS 2 の CMake ベースのパッケージビルドシステムです(全部とは言わないまでも、ほとんどの C/C++ プロジェクトで使用されています)。これは CMake を拡張したもので、パッケージ作成時の便利機能が追加されています。 CMake の基本を知っておくと理解が深まります。公式のチュートリアルも参考になります。

基本

基本的な CMake のアウトラインは、コマンドラインでros2 pkg create <パッケージ名>で作成されます。その後、基本的なビルド情報はpackage.xmlCMakeLists.txtの2つのファイルに集約されます。 colcon がパッケージの正しいビルドの順番を検出したり、必要な依存関係を CI にインストールしたり、さらにリリースに関する情報をbloomで提供できるようにするには、package.xmlにすべての依存関係とメタデータを含めておく必要があります。 CMakeLists.txtには、実行可能ファイルとライブラリをビルドおよびパッケージ化するためのコマンドが含まれています。このページでは主としてそのコマンドについて説明します。

ament チュートリアルも参照してください。←リンク切れ

標準プロジェクト概要

ament パッケージのCMakeLists.txtの基本的な概要は以下の通りです。

cmake_minimum_required(VERSION 3.5)
project(my_project)

ament_package()

projectの引数はパッケージ名になり、package.xmlのパッケージ名と同じでなければなりません。

プロジェクトの設定はament_package()によって行われます。この呼び出しはパッケージごとに1回だけ行う必要があります。 ament_package()は、package.xmlをインストールし、そのパッケージをamentインデックスに登録し、そして CMake のための config(そしておそらくtarget)ファイルをインストールします。これにより、find_package で他のパッケージから検出できるようになります。 ament_package()CMakeLists.txt内の全ての情報を集約して処理をする関数なので、"CMakeLists.txt"の最終行に記述する必要があります。ファイルとディレクトリをコピーするinstall関数によってament_package()を再現することもできますが、ament_package()を最後の呼び出すほう楽です。

ament_packageには追加の引数を与えることができます。

  • CONFIG_EXTRAS:パッケージのクライアントに利用できるようにする追加の CMake ファイル(configure_file() によって展開された.cmakeまたは.cmake.inテンプレート)のリスト。これらの引数を使用する場合の例については、リソースの追加を参照してください。テンプレートファイルの使用方法の詳細については、Cmake の公式文書を参照してください。

  • CONFIG_EXTRAS_POSTCONFIG_EXTRASと同じですが、ファイルが追加される順序が異なります。 CONFIG_EXTRASから生成されたファイルがament_export_*用に生成されたファイルの「前」に含まれるのに対して、CONFIG_EXTRAS_POSTから生成されたファイルはその「後」に含まれます。

ament_packageに追加する代わりに、変数${PROJECT_NAME}_CONFIG_EXTRASおよび${PROJECT_NAME}_CONFIG_EXTRAS_POSTに同じ効果を追加することもできます。唯一の違いは、ファイルが追加される順序が次の通りであることです。

  • CONFIG_EXTRASによって追加されたファイル
  • ${PROJECT_NAME} _CONFIG_EXTRASにアペンドして追加されたファイル
  • ${PROJECT_NAME} _CONFIG_EXTRAS_POSTにアペンドして追加されたファイル
  • CONFIG_EXTRAS_POSTによって追加されたファイル

ファイルとヘッダの追加

ビルドする主なターゲットは2つあります。それぞれadd_libraryadd_executableによってビルドされる、ライブラリと実行可能ファイルです。

ヘッダーファイルの分離と C/C++ での実装では、add_library/add_executableの引数として、必ずしも両ファイルを追加する必要はありません。

以下のベストプラクティスが提案されています。

  • ライブラリをビルドする場合は、クライアントに解放する全ヘッダーをパッケージ名に相当する名前のフォルダ配下のincludeサブディレクトリに格納しておきます。一方、エクスポートしてはいけないファイル(.c / .cppとヘッダファイル)は srcフォルダ内にあります。
  • add_libraryまたはadd_executableの呼び出しでは、cpp ファイルのみを明示的に参照する。
  • 下記のコマンドでヘッダを検出させる:
target_include_directories(my_target
  PUBLIC
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
    $<INSTALL_INTERFACE:include>)

これにより、ビルド時に${CMAKE_CURRENT_SOURCE_DIR}/includeフォルダ内の全てのファイルがパブリックインターフェースに追加され、インストール時に include フォルダ内の全てのファイル(${CMAKE_INSTALL_DIR}からの相対パス)が追加されます。

原則として、両フォルダともincludeフォルダだった場合や、${CMAKE_CURRENT_SOURCE_DIR}および${CMAKE_INSTALL_DIR}直下のフォルダの場合には、ジェネレータ式を使用する必要はありません。ただし、そのような場合でもジェネレータ式を記述しておくのが一般的です。

リソースの追加

パッケージを新しい依存関係に対してリンクするには2つの方法があります。

最初の、そして推奨される方法は ament マクロ であるament_target_dependenciesを使うことです。例として、my_targetを線形代数ライブラリ Eigen3 に対してリンクさせたいとします。

find_package(Eigen3 REQUIRED)
ament_target_dependencies(my_target Eigen3)

これにより、必要なヘッダとライブラリおよびそれらの依存関係を、プロジェクトが検出できるようになります。また、オーバーレイワークスペースを使用するときに、すべての依存関係のインクルードディレクトリが正しく順序付けされていることも保証されます。

2番目の方法はtarget_link_librariesを使うことです。

現代の CMake で推奨される方法は、ターゲットのみを使用し、それらをエクスポートしてリンクすることです。 CMake ターゲットは C++ と同様に名前空間があります。たとえば、Eigen3の場合は、ターゲットとしてEigen3 :: Eigenをを指定します。

少なくともCrystal Clemmysより前までは、ターゲット名がament_target_dependenciesマクロでサポートされていません。場合によっては、target_link_libaries CMake 関数を使う必要があります。 Eigen3 の例では、呼び出しは次のようになります。

find_package(Eigen3 REQUIRED)
target_link_libraries(my_target Eigen3::Eigen)

これには必要なヘッダ、ライブラリ、およびそれらの依存関係も含まれますが、ament_target_dependenciesとは対照的に、オーバーレイワークスペースを使用するときに依存関係を正しく順序付けできない可能性があります。

注意

明示的に必要とされないライブラリをfind_packageすることは不要ですが、別の依存関係(依存A)を持つ依存関係(依存B)を記述する場合には、依存Aを明示的に記述しなければなりません。 その場合、該当するパッケージに対してバグを報告してください。

ライブラリのビルド

再利用可能なライブラリをビルドするとき、それを利用しやすくするために下流のパッケージ用にいくつかの情報をエクスポートする必要があります。

ament_export_interfaces(export_my_library HAS_LIBRARY_TARGET)
ament_export_dependencies(some_dependency)

install(
  DIRECTORY include/
  DESTINATION include
)

install(my_library
  TARGETS my_library
  EXPORT export_my_library
  LIBRARY DESTINATION lib
  ARCHIVE DESTINATION lib
  RUNTIME DESTINATION bin
  INCLUDES DESTINATION include
)

ここでは、includeフォルダーにエクスポートする必要があるヘッダーが含まれているとします。すべてのヘッダを別々のフォルダに入れる必要はないことに注意してください。クライアントが含めるべきヘッダだけを入れてください。

上記のスニペットで起こっていることは以下の通り:

  • ament_export_interfacesマクロは CMake のターゲットをエクスポートします。これは上記ライブラリのクライアントがtarget_link_libraries(client my_library::my_library)構文を使えるようにするために必要です。

  • ament_export_interfacesは、install コマンドにおけるEXPORTという名前の任意のターゲットリストと、環境変数に潜在的な依存ライブラリを登録する追加オプションHAS_LIBRARY_TARGETを取ることができます。

  • ament_export_dependenciesは依存関係を下流のパッケージにエクスポートします。これは、ライブラリのユーザがそれらの依存関係に対してもfind_packageを呼び出さなくてもいいようにするためです。

  • 最初のinstallコマンドは、クライアントに公開するヘッダファイルをインストールするためのものです。

  • 最後の大きなinstallコマンドはライブラリをインストールします。アーカイブとライブラリファイルはlibフォルダにエクスポートされ、ランタイムバイナリはbinフォルダにインストールされ、インストールされたヘッダへのパスもシステムに登録されます。

    • 注意:Windows の dll は(ライブラリではなく)ランタイムとして扱われ、RUNTIME DESTINATIONフォルダにインストールされます。したがって、UNIX ベースのシステムでライブラリを開発する場合でも、RUNTIMEインストールを除外しないことをお勧めします。
  • include directoryに関しては、install コマンドは CMake に情報を追加するだけで、実際には includes フォルダをインストールしません。これは上述のように、install(DIRECTORY <dir> DESTINATION <dest>)によってヘッダをコピーすることによって行われます。

  • install 呼び出しのEXPORT表記にはさらに注意が必要です。これは、my_library ターゲット用の CMake ファイルをインストールします。これはament_export_interfacesの引数とまったく同じ名前で、ライブラリのように名前を付けることもできます。しかし、これよって出力されたライブラリは、 ament_target_dependenciesでインクルードできなくなってしまいます。それとは完全に切り離せるよう、専用のexport_<target>のようなものをエクスポート先に追加することをお勧めします。

  • すべてのインストールパスは、colcon/amentによってすでに正しく設定されているCMAKE_INSTALL_PREFIXからの相対パスです。

使用できる2つの追加機能がありますが、ターゲットベースのインストールには不要です。

ament_export_include_directories(include)
ament_export_libraries(my_library)

最初のマクロは、エクスポートされたインクルードディレクトリをマークします(これは、ターゲットinstallINCLUDES DESTINATIONによって実現されます)。 2番目のマクロは、インストールされているライブラリの場所を示します(これはament_export_interfaceへの呼び出しのHAS_LIBRARY_TARGET引数によって行われます)。

いくつかのマクロは非ターゲットエクスポートに対して異なるタイプの引数を取ることができますが、最近のMakeのための推奨される方法はターゲットを使うことであるので、ここでは カバー しません。これらのオプションのドキュメントはソースコード内に記載してあります。

コンパイラとリンカのオプション

ROS 2 は、少なくともCrystal Clemmysまでは、C++14 および C99 規格に準拠しているコンパイラを対象としています。より新しいバージョンは将来的には見据えていて、こちらで言及されています。したがって、対応する規格に応じた CMake フラグを設定するのが慣例です。

if(NOT CMAKE_C_STANDARD)
  set(CMAKE_C_STANDARD 99)
endif()
if(NOT CMAKE_CXX_STANDARD)
  set(CMAKE_CXX_STANDARD 14)
endif()

コードをきれいに保つために、コンパイラは不正が疑われるコードに対してワーニングを出すべきであり、修正されるべきです。

少なくとも次の警告レベルをカバーすることをお勧めします。

  • Visual Studioの場合:デフォルトのW1警告は保持されます。
  • GCC と Clang の場合:-Wall -Wextra -Wpedantic が必要で、-Wshadow -Werrorが推奨されます(後者はワーニングをエラーと解釈します)。

現代の CMake はターゲットベースでコンパイラのフラグを追加することをお勧めしますが(例:call)、

target_compile_options(my_target PRIVATE -Wall)

現時点では、ディレクトリレベルの関数add_compile_options(-Wall)を使用して、すべての実行可能ファイルおよびテスト用のターゲットベースのコンパイルオプションで行数が増えてしまい、コードが乱れないようにすることをお勧めします。

Windows におけるライブラリのビルド

Linux、Mac、Windows はすべて公式にサポートされているプラ​​ットフォームなので、効果を最大限得るためには、どのパッケージも Windows 上でビルドできるようにする必要があります。 Windows ライブラリフォーマットはシンボルの可視性を強化します。クライアントから使用されるべきすべてのシンボルはライブラリによって明示的にエクスポートされる必要があります(そしてデータシンボルは暗黙的にインポートされる必要があります)。

Clang と GCC ビルドとの互換性を保つために、GCC ウィキ内に記載されているロジックを使用することをお勧めします。 my_libraryというパッケージに使用するには

  • リンク内のロジックをvisibility_control.hppというヘッダーファイルにコピーします。
  • DLLMY_LIBRARYに置き換えます(例については、rviz_rendering の可視性制御を参照してください)。
  • エクスポートする必要があるすべてのシンボル(つまり、クラスまたは関数)に対してマクロ「MY_LIBRARY_PUBLIC」を使用します。
  • プロジェクトCMakeLists.txtで、以下のコマンドを使用します。
target_compile_definitions(my_library PRIVATE "MY_LIBRARY_BUILDING_LIBRARY")

テストと構文チェック

colcon を使ってライブラリをビルドをすることととテストを分離するために、構文チェックとテストへのすべての呼び出しを条件付きでラップします。

if(BUILD_TESTING)
  find_package(ament_gtest)
  ament_add_gtest(<tests>)
endif()

構文チェック

ament によって提供されるすべての構文チェッカは別々に追加することができますが、それらを組み合わせたコマンドを使用することをお勧めします。

find_package(ament_lint_auto REQUIRED)
ament_lint_auto_find_test_dependencies()

これはpackage.xmlで定義されているように構文チェッカを実行します。 ament_lint_commonパッケージで定義されている一連の構文チェッカを使用することをお勧めします。これにより、以下のすべての構文チェッカ実行されます。

  • 著作権文とライセンスヘッダの存在とその正当性を確認する著作権構文チェッカ
  • cppcheck、論理テストも見つけることができるC++ 構文チェッカ
  • cpplint、C++ スタイルの構文チェッカ(例えばコメントスタイル)
  • C++ スタイル構文チェッカ
  • cmake チェッカ
  • XML uncrustify
  • flake8、python ファイル用のスタイルチェッカ
  • pep257、python docstrings のスタイルチェッカ

ament_uncrustifyには、コマンドラインツールが付属しています。これを呼び出すと、スタイルガイドに従ってコードを自動的に再フォーマットできます。

ament_uncrustify --reformat <path_to_source_folders>

テスト

Ament には GTests の設定を簡単にするための CMake マクロが含まれています。下記のように GTest を追加します。

find_package(ament_gtest)
ament_add_gtest(some_test <test_sources>)

これは他のライブラリ(プロジェクトライブラリなど)に対してリンクできる通常のターゲットです。マクロには追加のパラメータがあります。

  • APPEND_ENV:環境変数を追加します。たとえば、次のように呼び出して ament プレフィックスパスに追加できます。
find_package(ament_gtest REQUIRED)
ament_add_gtest(some_test <test_sources>
  APPEND_ENV PATH=some/addtional/path/for/testing/resources)
  • APPEND_LIBRARY_DIRS:実行時にリンカが検出できるようにライブラリを追加します。Windows ではPATH、Linux ではLD_LIBRARY_PATHのような環境変数を設定することでも実現できますが、この場合は呼び出しプラットフォームごとに異なる設定をしなければなりません。
  • ENV:環境変数を設定します(APPEND_ENVと同じ構文)。
  • TIMEOUT:テストタイムアウトを秒単位で設定します。 GTestsのデフォルトは60秒です。
  • SKIP_TEST:このテストをスキップします(コンソール出力に "passed" と表示されます)。
  • SKIP_LINKING_MAIN_LIBRARIES:GTestにリンクしません。
  • WORKING_DIRECTORY:テスト用の作業ディレクトリを設定します。

それ以外のデフォルトの作業ディレクトリはCMAKE_SOURCE_DIRで、これは最上位のCMakeLists.txtのディレクトリとなります。

同様に、GMock を含む GTest を設定するための CMakeマクロがあります。

find_package(ament_gmock REQUIRED)
ament_add_gmock(some_test <test_sources>)

ament_add_gtestと同様に追加パラメータがあります。

ament の拡張

追加のマクロ/関数を ament_cmake に登録し、それを拡張することができます。

ament への関数/マクロの追加

ament を拡張することはしばしば他のパッケージが使えるようにするための機能を追加したいという意図があると思われます。マクロをクライアントパッケージに提供する最善の方法は、それを ament に登録することです。

これは、${PROJECT_NAME}_CONFIG_EXTRAS変数を追加することによって実行できます。これは、次の関数を呼び出した後、ament_package()を呼ぶことで実現できます。

list(APPEND ${PROJECT_NAME}_CONFIG_EXTRAS
  path/to/file.cmake"
  other/pathto/file.cmake"
)

あるいは、ファイルをament_package()で直接追加することもできます。

ament_package(CONFIG_EXTRAS
  path/to/file.cmake
  other/pathto/file.cmake
)

拡張ポイントへの追加

他のパッケージで使用できる機能を追加する単純な設定ファイル以外にも、ament 自体への拡張も可能です。その拡張機能は拡張ポイントを定義する関数で実行されるスクリプトです。 ament 拡張の最も一般的なユースケースは、おそらく rosidl メッセージジェネレータを登録することです。ジェネレータを書くとき、メッセージ/サービス定義パッケージのためのコードを修正することなしにジェネレータですべてのメッセージとサービスを通常生成するのが望ましいです。これは、ジェネレータをrosidl_generate_interfacesの拡張として登録することで可能です。

例として、下記があります。

ament_register_extension(
  "rosidl_generate_interfaces"
  "rosidl_generator_cpp"
  "rosidl_generator_cpp_generate_interfaces.cmake"

これは、パッケージrosidl_generator_cppのマクロrosidl_generator_cpp_generate_interfaces.cmakeを、拡張ポイントrosidl_generate_interfacesに登録するものです。拡張ポイントが実行されると、ここでスクリプトrosidl_generator_cpp_generate_interfaces.cmakeの実行がトリガーされます。もっと正確に言うと、これは関数rosidl_generate_interfacesが実行されるたびにジェネレータを呼び出します。

ジェネレータ用のrosidl_generate_interfaces以外の最も重要な拡張ポイントはament_packageです。これは単にament_package()呼び出しでスクリプトを実行するだけです。この拡張ポイントは、リソースを登録するときに役立ちます(下記参照)。

ament_register_extensionは、必ず3つの引数をとる関数です。

  • extension_point:拡張ポイントの名前(ほとんどの場合、これはament_packageまたはrosidl_generate_interfacesのいずれかになります)
  • package_name:CMake ファイルを含むパッケージの名前(すなわち、ファイルが書き込まれているプロジェクトのプロジェクト名)
  • cmake_filename:拡張ポイントが実行されたときに実行されるcmakeファイル

注意:ament_packagerosidl_generate_interfacesと同じようにカスタム拡張ポイントを定義することは可能ですが、これはほとんど必要ないでしょう。

拡張ポイントの追加

ごくまれに、ament への新しい拡張ポイントを定義したくなることもあるでしょう。

対応するマクロが呼び出されたときにすべての拡張が実行されるように、拡張ポイントをマクロ内に登録できます。以下のように行います。

  • 登録したい拡張の名前(例えばmy_extension_point)を定義して、ファイルとして保存してください。これは拡張ポイントを使うときにament_register_extensionマクロに渡される名前です。
  • 拡張機能を実行するマクロ/関数では、次のように呼び出します。
ament_execute_extensions(my_extension_point)

ament 拡張は、拡張ポイントの名前を含む変数を定義し、それに実行するマクロを入れることによって機能します。 ament_execute_extensionsを呼び出すと、変数に定義されたスクリプトが次々に実行されます。

リソースを追加する

特にプラグインやプラグインを利用するパッケージを開発するときは、ある ROS パッケージから別の ROS パッケージにリソースを追加することが不可欠です(例:プラグイン)。例としては、pluginlib を使ったツール用のプラグインがあります。

これは、ament インデックス(「リソースインデックス」とも呼ばれる)を使用して実現できます。

ament インデックスの説明

設計の詳細については、こちらを参照してください。

原則として、ament インデックスはパッケージの install/share 内のフォルダに含まれています。さまざまな種類のリソースにちなんだ名称のサブフォルダが含まれています。サブフォルダ内では、上記リソースを提供する各パッケージは「マーカファイル」という名で参照されます。ファイルには、リソースを取得するために必要なあらゆるコンテンツが含まれます。(リソースのインストールディレクトリへの相対パスが例。それは単に空の場合もありますが。)

例として、RViz 用の表示プラグインを提供することを検討してください。pluginlib によって読み込まれるmy_rviz_displaysという名前のプロジェクトで RViz プラグインを提供するときは、pluginlib によってインストールおよび使用されるplugin_description.xmlファイルを提供します。プラグインこれを実現するために、plugin_description.xml は次のようにして resource_index にリソースとして登録されます。

pluginlib_export_plugin_description_file(rviz_common plugins_description.xml)

colcon buildを実行すると、my_rviz_displaysファイルを resource_index のサブフォルダrviz_common__pluginlib__pluginにインストールします。 rviz_common 内の Pluginlib モジュールは、プラグインをエクスポートするパッケージについて、rviz_common__pluginlib__pluginという名称の全フォルダから情報を収集することを認識します。 pluginlib モジュール用のマーカーファイルには、plugins_description.xmlファイルへのインストールフォルダへの相対パス(およびマーカファイル名としてのライブラリの名前)が含まれています。この情報を使って、pluginlib はライブラリをロードし、どのプラグインをplugin_description.xmlファイルからロードするかを知ることができます。

2つ目の例として、RViz プラグインがあなた自身のカスタムメッシュを使うようにする可能性を考えてください。メッシュは起動時にロードされるため、プラグインの所有者はそれを処理する必要はありませんが、これは RViz がメッシュについて知っている必要があることを意味します。これを達成するための関数を RViz は備えています。

register_rviz_ogre_media_exports(DIRECTORIES <my_dirs>)

これは、ディレクトリを agre_media リソースとして ament インデックスに登録します。つまり、関数を呼び出すプロジェクト名のファイルをrviz_ogre_media_exportsというサブフォルダーにインストールします。このファイルには、マクロにリストされているディレクトリへのインストールフォルダへの相対パスが含まれています。RViz の起動時、rviz_ogre_media_exportsという名前のすべてのフォルダを検索し、指定された全フォルダにリソースをロードできるようになりました。これらの検索はament_index_cpp(または Python パッケージの場合はament_index_py)を使って行われます。

以下のセクションでは、カスタマイズしたリソースを ament index に追加し、そうするためのベストプラクティスを提供する方法を探ります。

ament インデックスへの問い合わせ

必要ならば、CMake を介して ament インデックスに対してリソースの問い合わせが可能です。これについては、3 つの機能があります。

  • ament_index_has_resource:以下のパラメータで存在する場合、リソースへのプレフィックスパスを取得します。
  • var:出力パラメータ:リソースが存在しない場合はこの変数にFALSEを、存在する場合はリソースへのプレフィックスパスを設定します。
    • resource_type:リソースの種類(例:rviz_common__pluginlib__plugin
  • resource_name:通常resource_type 型のリソースを追加したパッケージの名前に相当するリソースの名前(例:rviz_default_plugins

  • ament_index_get_resource:特定のリソースの内容、すなわち ament インデックス内のマーカファイルの内容を取得する。

  • var:出力パラメータ:リソースマーカファイルが存在する場合はその内容が代入されます。
    • resource_type:リソースの種類(例:rviz_common__pluginlib__plugin
  • resource_name:通常resource_type型のリソースを追加したパッケージの名前に相当するリソースの名前(例:rviz_default_plugins
  • PREFIX_PATH:検索するプレフィックスパス(通常、デフォルトのament_index_get_prefix_path()で十分です)。

リソースが存在しない場合、ament_index_get_resourceはエラーをスローするので、ament_index_has_resourceを使用して確認する必要があるかもしれません。

  • ament_index_get_resources:インデックスから特定の種類のリソースを登録したすべてのパッケージを取得します。
  • var:出力パラメータ:resource_typeのリソースを登録した全てのパッケージ名のリストが代入されます。
    • resource_type:リソースの種類(例:rviz_common__pluginlib__plugin
  • PREFIX_PATH:検索するプレフィックスパス(通常、デフォルトの`ament_index_get_prefix_path() で十分です)。

ament インデックスへの追加

リソースを定義するには、2 ビットの情報が必要です。

  • ユニークなリソース名
  • マーカファイルのレイアウト。これは何でもかまいませんし、空にすることもできます(例えば ROS 2 パッケージをマークする“package”リソースに当てはまります)。

RVizメッシュリソースの場合、対応する選択肢は次のとおりです。

  • リソースの名前として rviz_ogre_media_exports
  • リソースを含むすべてのフォルダへの相対パスをインストールします。これにより、パッケージ内の対応するリソースを使用するためのロジックを記述できるようになります。

パッケージのリソース登録を容易にするには、さらに、pluginlib関数やrviz_ogre_media_exportsなどのマクロや関数を用意する必要があります。

リソースを登録するには、ament関数ament_index_register_resourceを使用します。これによりマーカファイルが作成され、resource_indexにインストールされます。例として、rviz_ogre_media_exportsの対応する呼び出しは以下のとおりです。

ament_index_register_resource(rviz_ogre_media_exports CONTENT ${OGRE_MEDIA_RESOURCE_FILE})

これにより、${PROJECT_NAME}のような名前のファイルが、変数${OGRE_MEDIA_RESOURCE_FILE}で指定された内容で resource_index の中にあるrviz_ogre_media_exportsフォルダにインストールされます。マクロには色々な便利パラメータが用意されています。

  • 最初の(名前なし)パラメータはリソースの名前です。これは、resource_index 内のフォルダの名前になります。
  • CONTENT:文字列としてのマーカファイルの内容。これは相対パスのリストなどです。CONTENTCONTENT_FILEと一緒に使用することはできません。
  • CONTENT_FILE:マーカファイル作成のために使用されるファイルへのパス。ファイルはプレーンファイルでも、configure_file()で展開されたテンプレートファイルでも、どちらでも構いません。CONTENT_FILECONTENTと一緒に使用することはできません。
  • PACKAGE_NAME:リソースをエクスポートしているパッケージ/ライブラリの名前。マーカファイルの名前になります。デフォルトは${PROJECT_NAME}です。
  • AMENT_INDEX_BINARY_DIR:生成された ament インデックスの基底パス。本当に必要な場合以外は、常にデフォルトの${CMAKE_BINARY_DIR}/ament_cmake_indexを使用してください。
  • SKIP_INSTALL:マーカファイルのインストールをスキップします。

パッケージごとに存在するマーカファイルは1つだけなので、cmake 関数/マクロが同じプロジェクトによって 2 回呼び出されると、通常は問題になります。ただし、大規模プロジェクトでは、リソースを登録する呼び出しを分割するのが最善の方法です。

したがって、register_rviz_ogre_media_exports.cmakeなどのリソースを登録するマクロにいくつかの変数のみを設定させることがベストプラクティスとなります。 ament_index_register_resourceの実際の呼び出しは、ament_packageへのament 拡張内で追加できます。プロジェクトごとにament_packageを呼び出すのは 1 回限りでなければならないため、リソースが登録される場所は常に1つのみとなります。 rviz_ogre_media_exportsの場合、これは次のような方針となります。

  • マクロregister_rviz_ogre_media_exportsはフォルダのリストを受け取り、それらをOGRE_MEDIA_RESOURCE_FILEという変数に追加します。

${OGRE_MEDIA_RESOURCE_FILE}が空でない場合、register_rviz_ogre_media_exports_hookという別のマクロがament_index_register_resourceを呼び出します。

register_rviz_ogre_media_exports_hook.cmake は、呼び出しによって3番目のファイル register_rviz_ogre_media_exports_hook-extras.cmakeament 拡張として登録されます。

ament_register_extension("ament_package" "rviz_rendering"
  "register_rviz_ogre_media_exports_hook.cmake")

register_rviz_ogre_media_exports.cmakeおよびregister_rviz_ogre_media_exports_hook-extra.cmakeは、ament_package()CONFIG_EXTRAとして登録されます。

翻訳元文書

index.ros.org

関連文書

www.moriken254.com

www.moriken254.com