ROS2プロジェクトの作成

【[ROS2関係トップページへ](https://qiita.com/NeK/items/7ac0f4ec10d51dbca084)】
【[ROS2レクチャー:初級 -ROS1 style-](https://qiita.com/NeK/items/74e4bb9d1530e22a63fc)】
【[ROS2レクチャー:初級 -class style-](https://qiita.com/NeK/items/14db31ff784a0bfafe3d)】

【前:[ROS2に関する基本情報:初級 -ROS1 style-]】
【前:[ROS2に関する基本情報:初級 -class style-]】
【次:[ROS2最小構成プログラム:初級 -ROS1 style-]】
【次:[ROS2最小構成プログラム:初級 -class style-]】

* [ROS2プロジェクトの作成(humble以降の本ページ)]

[ROS2に関する基本情報:初級 -ROS1 style-]:https://qiita.com/NeK/items/ef40cf01637c2b98b4ec
[ROS2に関する基本情報:初級 -class style-]:https://qiita.com/NeK/items/cd88fa49747f2a8b8392
[ROS2最小構成プログラム:初級 -ROS1 style-]:https://qiita.com/NeK/items/c9ba8aa3a005087762e2
[ROS2最小構成プログラム:初級 -class style-]:https://qiita.com/NeK/items/d98a20e1c93993e06b7a
[ROS2プロジェクトの作成(humble以降の本ページ)]:https://qiita.com/NeK/items/067bc227f706d7b8a2f3

# 概要
ROS2プログラミングの第一歩として，プロジェクトの作成，ビルドを行う．

2024/07/23:[ワークスペース・プロジェクトについて](#ワークスペース・プロジェクトについて)で[構成についての基本的な考え方](##構成についての基本的な考え方)を追加
2020/07/24:[ワークスペース・プロジェクトについて](#ワークスペース・プロジェクトについて)で「公式と異なるけど本シリーズでの考え方」を追加
2020/06/26:[ワークスペース・プロジェクトについて](#ワークスペース・プロジェクトについて)の【ros2 pkg createが行うこと】の詳細部分に追記

# ワークスペース・プロジェクトについて
## 構成についての基本的な考え方
一つのワークスペースにすべてのプロジェクト(パッケージ)を入れるのではなく，作りたいもの=ワークスペース，作りたいものの部品・関係するもの=パッケージと考える．そしワークスペースは作りたいものに応じて複数存在，一つのワークスペースの中には関係するプロジェクト(パッケージ)のみ，という構成をスタンダードとする．

## やってみよう
"ROS2勉強用"を目的としたワークスペースを作成する．ディレクトリ名をros2_studies_ws/とし，このワークスペースに他の練習用プロジェクトも全て入れることとする．ワークスペースはmkdirで普通に作成する．また練習用のパッケージ名をros2_testとする．こちらは[ros2 pkg createコマンド]で作成する．

```bash:terminal
$ mkdir -p ~/ros2_studies_ws/
$ cd ~/ros2_studies_ws/
$ ros2 pkg create ros2_test --build-type ament_cmake --dependencies rclcpp
```

ros2のコマンドは以下のページに詳しい．
- [Introspection with command line tools](https://index.ros.org/doc/ros2/Tutorials/Introspection-with-command-line-tools/)

<details>
<summary>ros2 pkg createが行うこと</summary><div>
ros2 pkg createは必要なディレクトリ・ファイルの雛形を作成するもので，手動で作成したりgithubから持ってきても問題ない．このコマンドによって作成されるものは以下のとおり．ただし，githubから持ってきた場合，package nameなどちゃんと修正しないといけない．

```ディレクトリ構造
ros2_studies_ws/
└ ros2_test/
  ├ CMakeLists.txt
 ├ package.xml
  ├ include/
  │ └ ros2_test/
  └ src/
```

このもととなるのはCMakeの推奨ディレクトリ構造である．[An Introduction to Modern CMake](https://cliutils.gitlab.io/modern-cmake/)の[How to structure your project](https://cliutils.gitlab.io/modern-cmake/chapters/basics/structure.html)は一読の価値あり．
</div></details>

<details>
<summary>includeディレクトリについて</summary><div>

[ament_cmake User Documentation](https://docs.ros.org/en/humble/How-To-Guides/Ament-CMake-Documentation.html)によると[パッケージ名]/include/[パッケージ名]/のディレクトリには外部公開する機能に関するヘッダを入れる．共有ライブラリで使用する．外部公開しないものはsrc/以下に入れる．「何を外部に公開し何を公開しないか」を意識しよう．
</div></details>

<details>
<summary>公式と異なるけど本シリーズでの考え方</summary><div>

[公式のチュートリアル](https://docs.ros.org/en/galactic/Tutorials/Creating-Your-First-ROS2-Package.html)では，ワークスペース(~/dev_ws/)にsrcディレクトリ(~/dev_ws/src)を作成し，その中にパッケージを作成する方法が推奨となっている．今回の場合に当てはめるとディレクトリ構成は以下のようになる．

```ディレクトリ構造
ros2_studies_ws/
└ src/
   └ ros2_test/
     ├ CMakeLists.txt
     ├ package.xml
     ├ include/
     │ └ ros2_test/
     └ src/
```

コンパイル後はワークスペース直下には，`src/`, `build/`, `install/`のみとなって余計なものが入らない，というのは分かる．しかし`src/`が二か所あるのが気になる．自分のすっきりする方法としては以下の通り．

1. 推奨通りワークスペース直下も`src/`，パッケージの中身も`src/`とする
1. ワークスペース直下には`src/`ではなく`packages/`とか`pkgs/`とする
1. ワークスペース直下に直接パッケージを配置する

色々な人との共同作業を考えると推奨通りにしておく方がよいと思うが，個人的には2か3かな．
ここでは3とする．理由は，面倒だから＆公式のgithubのプロジェクトをパッと見て推奨通りになってなさそうだったから(2021/7/24)．2でもいいかも(2024/07/30)
</div></details>

## package.xmlとCMakeLists.txtの観察
以下，自動生成された両ファイルの一部抜粋．

```package.xml
<package format="3">
  <name>ros2_test</name>
  <version>0.0.0</version>
  <desciption>TODO: Package description</description>
  <maintainer email="hoge@gmail.com">hoge</maintainer>
  <license>TODO: License declaration</license>
  ...
  <depend>rclcpp</depend>
```

1行目:xmlの書き方のバージョンを指定．
2行目:パッケージ名
3行目:バージョン．編集するたび増やしていく．
4行目:一応自由記載
5行目:メンテナス者．複数指定する場合，<maintainer ...の行をコピペして増やす．
6行目:パッケージのライセンス．
8行目:ros2 pkg createの--dependenciesで指定した依存関係のあるパッケージがdependタグに記載される．複数指定した場合は複数行にわたり記載される．

まずはメンテナンス者として自分のメアド・名前を書き込んでおく．

```CMakeLists.txt
project(ros2_test)
...
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
...
ament_package()
```

1行目:CMakeLists.txtの場合，パッケージ名がpackageではなくprojectとして指定されている．cmakeの仕様．
3行目:指定したコンパイラが記載される．
4行目:ros2 pkg createの--dependenciesで指定した依存関係のあるパッケージがdependタグに記載される．複数指定した場合は複数行にわたり記載される．
6行目:CMakeLists.txt内の設定をもとにamentのビルド用設定を行う．CMakeLists.txtの最後に一回だけ呼び出される．

## ビルド
プログラムを作成していないけどビルドコマンドを実行してみる．
ビルドはワークスペースのトップディレクトリで[colcon build]．

```bash:terminal
$ cd ~/ros2_studies_ws/
$ colcon build
$ . install/local_setup.bash
```

3行目の. install/local_setup.bashはgalactic以降の推奨．以前はsetup.bashだった．どちらも使えるが，意味は[ROS2のsetup.*とlocal_setup.*](https://qiita.com/NeK/items/868bfba543100badbf16)を参照．

### より実用的なビルドコマンド
上記2行目のビルドコマンドであるが，より実用的なものは以下のような引数をとることが多い．


```bash:terminal
$ colcon build --symlink-install
```
```bash:terminal
$ colcon build --symlink-install --packages-up-to ros2_test
```

* --symlink-install
    * 可能な限りリンクを使用して2重にファイルをつくらない？
* --packages-up-to [package1 package2 ...]
    * 指定されたパッケージとそれに依存関係のあるパッケージのみをビルドする．
    * 複数指定する場合にはスペース区切りとする．

詳しくは[colcon build]を参照のこと．

### test
ビルドができたら，直後に(`install/local_setup.bash`前でもok)以下のコマンドでテストができる．

```bash:terminal
$ colcon test
```



[ROS2コマンド一覧]:https://qiita.com/NeK/items/33d62c61fc1a8c0c233e
[ros2 pkg createコマンド]:https://qiita.com/NeK/items/33d62c61fc1a8c0c233e#ros2-pkg-create
[colcon build]:https://qiita.com/NeK/items/33d62c61fc1a8c0c233e#colcon-build

【前:[ROS2に関する基本情報:初級 -ROS1 style-]】
【前:[ROS2に関する基本情報:初級 -class style-]】
【次:[ROS2最小構成プログラム:初級 -ROS1 style-]】
【次:[ROS2最小構成プログラム:初級 -class style-]】