Pythonのvenvにpip installでROS2開発環境を簡単にインストールできるようにする

# はじめに
[ROS Advent Calendar 2020](https://qiita.com/advent-calendar/2020/ros) 22日目の記事です。
今年はROS2がだいぶ盛り上がってきており、主要なライブラリのROS2対応等、ROS2への移行も現実的になってきました。来年2021年は、一層ROS2への移行がすすんでいくと思われます(勝手な予想)。

私も、やっとROS2触り始めてますが、使っているOSが18.04と少し古く最新のfoxyが試せない状況です。ソースからビルドしたり、Dockerを使ったりという手もあるのですが、ソースは毎回ビルドする必要がある、Dockerは開発する時にマウントしたりする必要があって権限が少し面倒くさいです。

そこで、
1. root権限なしで任意のディレクトリにインストールでき、簡単に環境の構築と破棄ができる
2. Ubuntu、Mac、Windows、Python3.6-3.9のマルチプラットフォームでROS2が試せる

ことを目指し、PythonのWheelパッケージでROS2をインストールできるようにしたので、紹介します。

確認した環境は以下の通りです。

- Ubuntu 18.04
- Mac OS

# 使い方

## インストール

```bash
# 環境構築
$ python3 --version
Python 3.6.9
$ python3 -m venv venv
$ . ./venv/bin/activate
(venv) $ pip install -U pip

# インストール
(venv) $ pip install --extra-index-url https://rospypi.github.io/simple2 rclpy std_msgs ros2py-init
...(略) ..

# 一度だけ実行
(venv) $ ros2py-init
updated

# そのまま使う場合は一度deactivateして再度activate
(venv) $ deactivate
$ . ./venv/bin/activate
LD_LIBRARY_PATH=....
```

## サンプルを試す(Python)

サンプルコードを取ってくる

```bash
git clone https://github.com/ros2/examples.git
```

新規にターミナルを開きPublisherを実行。

```bash
$ . ./venv/bin/activate
LD_LIBRARY_PATH=....
(venv) $ python examples/rclpy/topics/minimal_publisher/examples_rclpy_minimal_publisher/publisher_member_function.py
[INFO] [1608563828.438826436] [minimal_publisher]: Publishing: "Hello World: 0"
[INFO] [1608563828.931807019] [minimal_publisher]: Publishing: "Hello World: 1"
[INFO] [1608563829.430286609] [minimal_publisher]: Publishing: "Hello World: 2"
[INFO] [1608563829.931504088] [minimal_publisher]: Publishing: "Hello World: 3"
[INFO] [1608563830.430435935] [minimal_publisher]: Publishing: "Hello World: 4"
[INFO] [1608563830.931712417] [minimal_publisher]: Publishing: "Hello World: 5"
[INFO] [1608563831.430346898] [minimal_publisher]: Publishing: "Hello World: 6"
```

新規にターミナルを開きSubscriberを実行。

```bash
$ . ./venv/bin/activate
LD_LIBRARY_PATH=....
(venv) $ python rclpy/topics/minimal_subscriber/examples_rclpy_minimal_subscriber/subscriber_member_function.py
[INFO] [1608563893.706370811] [minimal_subscriber]: I heard: "Hello World: 17"
[INFO] [1608563894.199072027] [minimal_subscriber]: I heard: "Hello World: 18"
[INFO] [1608563894.702395055] [minimal_subscriber]: I heard: "Hello World: 19"
[INFO] [1608563895.202343741] [minimal_subscriber]: I heard: "Hello World: 20"
[INFO] [1608563895.701980945] [minimal_subscriber]: I heard: "Hello World: 21"
[INFO] [1608563896.202263923] [minimal_subscriber]: I heard: "Hello World: 22"
[INFO] [1608563896.701910239] [minimal_subscriber]: I heard: "Hello World: 23"
```

root権限がいらず、ソースからビルドすることもなく、Dockerを使うこともなく、任意の場所にROS2の実行環境が作れました。

# 中身について
Pythonパッケージは、`sys.prefix` を基点として、`include`, `lib`, `share` 等ファイルを配布パッケージに含める事ができます。今回はこれを利用して、ROS2の各パッケージに含まれる全てのファイルをPythonパッケージに入れています。こうすることで、 `sys.prefix`を `/opt/ros/foxy`(AMENT_PREFIX_PATH) のように扱うことができるため、`LD_LIBRARY_PATH` さえ通してしまえば、ROS2の実行環境が構築できます。
C, C++用のincludeファイル、soファイル、`ament_cmake`等も全てインストールされるため、ROS2用のCMakeさえ書けば、この状態でROS2のパッケージもビルド、実行できると思われます(試すことができたらまた紹介します)

Pythonパッケージを作るスクリプトは https://github.com/otamachan/ros2py.git で公開してます。

# おわりに
本当は、 `pip install rviz2` ができるところまで持って行きたかったのですが、少し時間が足りませんでした。ただ、MacOSでも、Ubuntuでもとりあえず簡単にROS2をインストールできるようになったという意味では満足です。
Pythonのwheelは、ビルド済みバイナリを配るという意味では、ほぼaptような事ができるという事、またROS2のビルドが環境を支えている(複雑にしている)[ament_cmake](https://github.com/ament/ament_cmake)を色々覗いて回ることができたのが今回の学びでした。

今後は以下のようなTODOを対応していきたいと思います。

* 普通のROS2パッケージ(C/C++/Python/カスタムメッセージ)のビルド方法確立
* 各種コマンドラインの動作確認
* rviz対応
* Windows対応

Happy Robot Programming!