11
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

ROS2におけるコンポーネントの作成

Last updated at Posted at 2020-07-23

ROS2関係トップページへ
【前:ROS2の共有ライブラリを使用したプログラムの作成
【次:ROS2のコンポーネントの利用

共有ライブラリに更に手を加えてコンポーネントを作成する.
ROS2における共有ライブラリで作成したものを例にコマンド類の説明をする.

  • パッケージ名
    • minimal_comp
  • 共有ライブラリで使用できる機能・クラスを収めたソースファイル
    • minimal_comp_node1.hppと.cpp
      • クラス名:MinimalCompNode1
  • パッケージ共通のnamespace
    • minimal_comp

なぜにコンポーネント?

  • 共有ライブラリとしても使える
    • ひと手間加えるだけで共有ライブラリとしてもコンポーネントとしても使える.
  • ノード単体で起動可能である
    • ターゲットを作成しなくてもよい

特に2点目について説明する.
ROS2の共有ライブラリを使用したプログラムの作成共有ライブラリを使用したプログラムにあるプログラムを再掲する.

minimal_comp_user_main.cpp
#include <rclcpp/rclcpp.hpp>
#include "minimal_comp/minimal_comp_node1.hpp"

int main(int argc, char * argv[]){
  rclcpp::init(argc,argv);
  rclcpp::spin(std::make_shared<minimal_comp::MinimalCompNode1>());
  rclcpp::shutdown();
  return 0;
}

このように共有ライブラリを単に起動するだけのターゲットを考えると,どんな共有ライブラリでも同じプログラムになるけど一々作成しなければならず面倒である.
こんな起動の仕方ならノードを直接起動しても良くない?→それコンポーネント,のイメージである(個人的見解).

コンポーネントの作り方

dependencies

依存関係としてrclcpp_componentsを指定する.
例えば以下のようになる.
コンポーネントはrclcpp::Nodeから継承するので,当然rclcppも必要.

$ ros2 pkg create minimal_comp --build-type ament_cmake --dependencies rclcpp rclcpp_components

パッケージ作成時にdependenciesを付けない場合,以下を手動で書き込む.

package.xml
<package format="3">
  <depend>rclcpp</depend>
  <depend>rclcpp_components</depend>
CMakeLists.txt
find_package(rclcpp REQUIRED)
find_package(rclcpp_components REQUIRED)

CMakeLists.txt

以下は関係する部分を抜き出したものとなる.詳しくはROS2における共有ライブラリCMakeLists.txtを参照のこと.

CMakeLists.txt
add_library(minimal_comp_node SHARED
  src/minimal_comp_node1.cpp
)
rclcpp_components_register_nodes(minimal_comp_node "minimal_comp::MinimalCompNode1")
target_compile_definitions(minimal_comp_node
  PRIVATE "MY_LIBRARY_BUILDING_LIBRARY"
)
target_compile_options(minimal_comp_node PUBLIC -Wall)
ament_target_dependencies(minimal_comp_node
  rclcpp
  rclcpp_components
)

説明

重要となるのは,4行目と11行目(下から2行目)である.
4行目:rclcpp_components_register_nodesによりノードを登録.
11行目:依存関係があるので,ament_target_dependenciesにrclcpp_componentsを追加.

rclcpp_components_register_nodesの使い方は以下の通り.

rclcpp_components_register_nodes([target名] "namespace::クラス名")

ソースファイル

ノードの実装をしている.cppファイル(例だとminimal_comp_node1.cpp)に以下を追記する.

  • #include "rclcpp_components/register_node_macro.hpp"
  • RCLCPP_COMPONENTS_REGISTER_NODE(namespace::クラス名)
    • 一番下,namespaceの定義外に以下を追加
    • 例の場合以下のようになる
      • RCLCPP_COMPONENTS_REGISTER_NODE(minimal_comp::MinimalCompNode1)

注意点

コンポーネントにするノードのコンストラクタは引数としてrclcpp::NodeOptionsの一つしか持てない.
よってROS2における共有ライブラリ共有ライブラリ化する二つのクラスのような以下のクラスだとエラーが起きる.

minimal_comp_node1.hpp
#include <rclcpp/rclcpp.hpp>
#include "minimal_comp/visibility.h" // 同一ディレクトリなら#include "visibility.h"でもok

namespace minimal_comp {

class MinimalCompNode1 : public rclcpp::Node{
public:
  MINIMAL_COMP_PUBLIC
  MinimalCompNode1(
    const std::string &name_space="",
    const rclcpp::NodeOptions& options=rclcpp::NodeOptions()
  );
};

}

解決方法

解決方法は簡単で引数がrclcpp::NodeOptionsの一つとなるコンストラクタを作ってやればよい.
以下の二つ目のコンストラクタで,name_spaceにデフォルト引数を与えないように注意.
これで,name_spaceを引数にとれる共有ライブラリとしてもコンポーネントとしても使用可となる.

minimal_comp_node1.hpp
#include <rclcpp/rclcpp.hpp>
#include "minimal_comp/visibility.h" // 同一ディレクトリなら#include "visibility.h"でもok

namespace minimal_comp {

class MinimalCompNode1 : public rclcpp::Node{
public:
  MINIMAL_COMP_PUBLIC
  MinimalCompNode1(
    const rclcpp::NodeOptions& options=rclcpp::NodeOptions()
  );
  MINIMAL_COMP_PUBLIC
  MinimalCompNode1(
    const std::string& name_space,
    const rclcpp::NodeOptions& options=rclcpp::NodeOptions()
  );
};

}

これを使ってコンポーネント用に作り替えると以下のようになる.
2行目と22行目がコンポーネント登録となる.

minimal_comp_node1.cpp
#include <rclcpp/rclcpp.hpp>
#include "rclcpp_components/register_node_macro.hpp"
#include "minimal_comp/minimal_comp_node1.hpp"

namespace minimal_comp {

MinimalCompNode1::MinimalCompNode1(
  const rclcpp::NodeOptions& options
): MinimalCompNode1("", options)
{}

MinimalCompNode1::MinimalCompNode1(
  const std::string& name_space,
  const rclcpp::NodeOptions& options
): Node("minimal_comp1", name_space, options)
{
  RCLCPP_INFO(this->get_logger(),"minimal comp 1 test");
}

}

RCLCPP_COMPONENTS_REGISTER_NODE(minimal_comp::MinimalCompNode1)

参考

11
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?