Help us understand the problem. What is going on with this article?

ROS2 package.xmlとCMakeLists.txtのチートシート

ROS2関係トップページへ

ケースごとの代表例の紹介.基本的に関係部分のみ抜粋.
基本的な方針としては一つのパッケージにすべて(ターゲット・ライブラリ・独自メッセージ)を入れるのではなく,なるべく分割する.
関連するものは,まずワークスペースをつくり,その中に「独自メッセージのパッケージ」「ライブラリとなるnode」「ターゲット」と分ける.
それぞれのパッケージ名を以下のようにすることで分かりやすくする.

  • 独自メッセージのパッケージ名
    • ***_msgs
  • ライブラリとなるパッケージ名
    • ***_nodes
  • ターゲットとなるパッケージ名
    • ***

例えば強化学習用のワークスペースだと

  • reinforcement_learning_msgs
  • reinforcement_learning_nodes
  • reinforcement_learning
    • 実行形式だけど,テスト用とかなら以下もあり
      • reinforcement_learning_test

もちろん独自ルール.

ターゲットの作成

rclcppは通常使用するパッケージ.
それ以外のパッケージを使う場合,例としてパッケージ名:packとして書いておく.packとしては,std_msgsなどROS2が用意しているものもあれば自分で作成した独自メッセージのパッケージやライブラリのパッケージなども考えられる.特になければpackに関係する部分はいらない.

package.xml

package.xml
<package format="3">
  <build_depend>rclcpp</build_depend>
  <test_depend>rclcpp</test_depend>
  <exec_depend>rclcpp</exec_depend>

  <build_depend>pack</build_depend>
  <test_depend>pack</test_depend>
  <exec_depend>pack</exec_depend>
</package>

CMakeLists.txt

二つのターゲット(ここではtarget_name_1とtarget_name_2)を作成する場合.一つの場合や三つ以上の場合は,例のようにadd_executableとament_target_dependenciesおよびinstallの中を追加していく.

自作の共有ライブラリを使わない場合.

CmakeLists.txt
find_package(rclcpp REQUIRED)
find_package(pack REQUIRED)

add_executable(target_name_1
  src/main.cpp
#  ... すべてのcppファイルを記述 
)
ament_target_dependencies(target_name_1
  rclcpp
  pack
)

add_executable(target_name_2
  src/main.cpp
#  ... すべてのcppファイルを記述 
)
ament_target_dependencies(target_name_2
  rclcpp
  pack
)

install(TARGETS
  target_name_1
  target_name_2
  DESTINATION lib/${PROJECT_NAME}
)

自作の共有ライブラリ(異なるパッケージ)を使う場合.

自作ライブラリのパッケージ名:packとする.
自作ライブラリのパッケージがexportするincludeファイルを読み込むために以下に関する部分を追加.

  • target_include_directories
CmakeLists.txt
find_package(rclcpp REQUIRED)
find_package(pack REQUIRED)

add_executable(target_name_1
  src/main.cpp
#  ... すべてのcppファイルを記述 
)
ament_target_dependencies(target_name_1
  rclcpp
  pack
)

target_include_directories(target_name_1
  PUBLIC
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
    $<INSTALL_INTERFACE:include>
)

add_executable(target_name_2
  src/main.cpp
#  ... すべてのcppファイルを記述 
)
ament_target_dependencies(target_name_2
  rclcpp
  pack
)

target_include_directories(target_name_2
  PUBLIC
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
    $<INSTALL_INTERFACE:include>
)

install(TARGETS
  target_name_1
  target_name_2
  DESTINATION lib/${PROJECT_NAME}
)

自作の共有ライブラリの作成

package.xml

ライブラリのパッケージを作るには,rclcpp_componentsが必要なのでそれを追加.

package.xml
<package format="3">
  <build_depend>rclcpp</build_depend>
  <exec_depend>rclcpp</exec_depend>
  <test_depend>rclcpp</test_depend>

  <build_depend>rclcpp_components</build_depend>
  <exec_depend>rclcpp_components</exec_depend>
  <test_depend>rclcpp_components</test_depend>

CMakeLists.txt

ライブラリ名:my_libを作成.そのために必要なソースファイルの例をlib1.cppとlib2.cppとする.
ament_export_interfacesで指定しているexport_my_libはinstallのEXPORTで名前つけしているもの.EXPORTでどんなものでも大丈夫なようだけど,通常ライブラリ名の頭にexport_を付けるみたい.

CMakeLists.txt
find_package(rclcpp REQUIRED)
find_package(rclcpp_components REQUIRED)

add_library(my_lib SHARED
  src/my_lib1.cpp
  src/my_lib2.cpp
)
target_compile_definitions(my_lib
  PRIVATE "MY_LIBRARY_BUILDING_LIBRARY"
)
target_compile_options(my_lib PUBLIC -Wall)
ament_target_dependencies(my_lib
  rclcpp
  rclcpp_components
)

target_include_directories(my_lib
  PUBLIC
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
    $<INSTALL_INTERFACE:include>
)

if(NOT WIN32)
  ament_environment_hooks(
    "${ament_cmake_package_templates_ENVIRONMENT_HOOK_LIBRARY_PATH}"
  )
endif()

ament_export_interfaces(export_my_lib HAS_LIBRARY_TARGET)
ament_export_dependencies(rclcpp rclcpp_components)
ament_export_libraries(my_lib)
ament_export_include_directories(include)

install(
  DIRECTORY include/
  DESTINATION include
)
install(TARGETS
  my_lib
  EXPORT export_my_lib
  ARCHIVE DESTINATION lib
  LIBRARY DESTINATION lib
  RUNTIME DESTINATION bin
  INCLUDES DESTINATION include
)

同一パッケージでターゲットと共有ライブラリを作成

異なるパッケージの共有ライブラリを使用してターゲットを作成する場合には,共有ライブラリのパッケージをfind_packageで読み込み,target_include_directoriesで指定した.
同一パッケージの場合,add_libraryで名付けたライブラリ名をtarget_include_directoriesで指定するだけ.

package.xml

ライブラリのパッケージを作るには,rclcpp_componentsが必要なのでそれを追加.

package.xml
<package format="3">
  <build_depend>rclcpp</build_depend>
  <exec_depend>rclcpp</exec_depend>
  <test_depend>rclcpp</test_depend>

  <build_depend>rclcpp_components</build_depend>
  <exec_depend>rclcpp_components</exec_depend>
  <test_depend>rclcpp_components</test_depend>

CMakeLists.txt

CmakeLists.txt
find_package(rclcpp REQUIRED)
find_package(rclcpp_components REQUIRED)

add_library(my_lib SHARED
  src/my_lib1.cpp
  src/my_lib2.cpp
)
target_compile_definitions(my_lib
  PRIVATE "MY_LIBRARY_BUILDING_LIBRARY"
)
target_compile_options(my_lib PUBLIC -Wall)
ament_target_dependencies(my_lib
  rclcpp
  rclcpp_components
)

target_include_directories(my_lib
  PUBLIC
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
    $<INSTALL_INTERFACE:include>
)

if(NOT WIN32)
  ament_environment_hooks(
    "${ament_cmake_package_templates_ENVIRONMENT_HOOK_LIBRARY_PATH}"
  )
endif()

ament_export_interfaces(export_my_lib HAS_LIBRARY_TARGET)
ament_export_dependencies(rclcpp rclcpp_components)
ament_export_libraries(my_lib)
ament_export_include_directories(include)

add_executable(target_name_1
  src/main.cpp
#  ... すべてのcppファイルを記述 
)
ament_target_dependencies(target_name_1
  rclcpp
  my_lib
)

target_include_directories(target_name_1
  PUBLIC
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
    $<INSTALL_INTERFACE:include>
)

install(
  DIRECTORY include/
  DESTINATION include
)
install(TARGETS
  my_lib
  EXPORT export_my_lib
  ARCHIVE DESTINATION lib
  LIBRARY DESTINATION lib
  RUNTIME DESTINATION bin
  INCLUDES DESTINATION include
)

install(TARGETS
  target_name_1
  DESTINATION lib/${PROJECT_NAME}
)

独自メッセージの作成

package.xml

注意点

  • formatは3である必要がある
  • その下の3行を追加する
    • もともとある<buildtool_depend>ament_cmake</buildtool_depend>はそのままに.
package.xml
<package format="3">
  <buildtool_depend>rosidl_default_generators</buildtool_depend>
  <exec_depend>rosidl_default_runtime</exec_depend>
  <member_of_group>rosidl_interface_packages</member_of_group>

CMakeLists.txt

メッセージファイルとして以下のものを例として表示

  • msg/TwoInts.msg
  • srv/CalcTwoFloats.srv

setは中身(複数行可)をラベル付けし${ラベル名}でアクセスしやすくするもの.
setを使わず直接ファイル名をrosidl_generate_interfacesの中に書いてもよい.

CMakeLists.txt
find_package(rosidl_default_generators REQUIRED)

set(msg_files
  "msg/TwoInts.msg"
)
set(srv_files
  "srv/CalcTwoFloats.srv"
)
rosidl_generate_interfaces(${PROJECT_NAME}
  ${msg_files}
  ${srv_files}
)
ament_export_dependencies(rosidl_default_runtime)

同じパッケージでターゲットも作成する場合

例:ターゲット名:my_target
add_executableなどは省略

以上の上,上記のCMakeLists.txtに下記を追加.

CMakeLists.txt
get_default_rmw_implementation(rmw_implementation)
find_package("${rmw_implementation}" REQUIRED)
get_rmw_typesupport(typesupport_impls "${rmw_implementation}" LANGUAGE "cpp")

foreach(typesupport_impl ${typesupport_impls})
  rosidl_target_interfaces(my_target
    ${PROJECT_NAME} ${typesupport_impl}
  )
endforeach()

同じパッケージでライブラリも作成する場合

同じパッケージでターゲットを作成する場合と同様に...とやらない.
現在エラーを解決できない状態.

参考

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした