ROS2の単一ターゲット内での複数nodeの実行

[ROS2関係トップページへ](https://qiita.com/NeK/items/7ac0f4ec10d51dbca084)

ここでは単一ターゲット内で複数のノードを実行するプログラムの作成を行う．
[Geoffrey BIGGS:ROS2のAPIの使い方](https://gbiggs.github.io/rosjp_ros2_intro/ros2_basics.html)にある図が分かりやすい．また[公式のAPI](http://docs.ros2.org/crystal/api/rclcpp/index.html)のExecutorsの部分も参考に．

ここでは[ROS2における共有ライブラリ](https://qiita.com/NeK/items/fb5dac0158497c1ff77f)で作成した二つのノード(MinimalComp1とMinimalComp2)を用いてSingle threadおよびMulti threadのプログラムを作成する．

# 準備

```bash:terminal
$ cd ~/ros2_studies_ws/
$ ros2 pkg create minimal_executor
```

# Single/Multi threadのプロジェクト
作成物:[github.com](https://github.com/nek009/minimal_executor)

- src/single_main.cpp
- src/multi_main.cpp

## プログラム:single_main.cpp

```c++:single_main.cpp
#include <rclcpp/rclcpp.hpp>
#include "minimal_comp/minimal_comp_node1.hpp"
#include "minimal_comp/minimal_comp_node2.hpp"

int main(int argc, char * argv[]){
  rclcpp::init(argc,argv);
  rclcpp::executors::SingleThreadedExecutor exec;

  auto node1 = std::make_shared<minimal_comp::MinimalCompNode1>();
  exec.add_node(node1);
  auto node2 = std::make_shared<minimal_comp::MinimalCompNode2>();
  exec.add_node(node2);

  exec.spin();
  rclcpp::shutdown();
  return 0;
}
```

### 概要
rclcpp::executorsが実行をコントロールするもの．今回はsingle threadなのでSingleThreadedExecutor型．
複数のノードを作成し，add_nodeで登録し，最後にspin関数を呼び出す．

## プログラム:multi_main.cpp

```c++:multi_main.cpp
#include <rclcpp/rclcpp.hpp>
#include "minimal_comp/minimal_comp_node1.hpp"
#include "minimal_comp/minimal_comp_node2.hpp"

int main(int argc, char * argv[]){
  rclcpp::init(argc,argv);
  rclcpp::executors::MultiThreadedExecutor exec;

  auto node1 = std::make_shared<minimal_comp::MinimalCompNode1>();
  exec.add_node(node1);
  auto node2 = std::make_shared<minimal_comp::MinimalCompNode2>();
  exec.add_node(node2);

  exec.spin();
  rclcpp::shutdown();
  return 0;
}
```

### 概要
single threadと同じ．multi threadの場合，MultiThreadedExecutor型となる．

# package.xmlとCMakeLists.txt
普通のROS2と同じ．
ここでは共有ライブラリを使用しているので，その記述部分が増えている．
追加部分のみ抜粋．

## package.xml
ここでpackage format=3になっているが，編集した記憶なし．
dashingからros2 pkg createで作成する時のデフォルトが3になったのかな？

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

## CMakeLists.txt

```CMakeLists.txt
find_package(rclcpp REQUIRED)
find_package(minimal_comp REQUIRED)

add_executable(minimal_exec_single
  src/single_main.cpp
)
ament_target_dependencies(minimal_exec_single
  rclcpp
  minimal_comp
)

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

add_executable(minimal_exec_multi
  src/multi_main.cpp
)
ament_target_dependencies(minimal_exec_multi
  rclcpp
  minimal_comp
)

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

install(TARGETS
  minimal_exec_single
  minimal_exec_multi
  DESTINATION lib/${PROJECT_NAME}
)
```

### 概要
共有ライブラリ使用のためのtarget_include_directoriesが増えているが通常通り．

# ビルド・実行
## ビルド
```bash:terminal
$ cd ~/ros2_studies_ws/
$ colcon build --symlink-install --packages-select minimal_executor
$ . install/setup.bash
```

共有ライブラリがビルドしてあるものとする．まだしていなければ，--packages-selectに共有ライブラリのパッケージも一緒にしていしてやる．

## 実行
このプログラムでは，singleでもmultiでも結果は変わらないけど．

### Single thread
```bash:terminal
$ cd ~/ros2_studies_ws/
$ . install/setup.bash
$ ros2 run minimal_executor minimal_exec_single
```

### Multi thread
```bash:terminal
$ cd ~/ros2_studies_ws/
$ . install/setup.bash
$ ros2 run minimal_executor minimal_exec_multi
```