WSL2による ROS 2 開発環境

## はじめに

今回の記事では、WSL(Windows Subsystem for Linux)を使用して、Windows端末に ROS 2 の開発環境をインストール方法について記載します。
シミュレータを使用する場合、CPU負荷が高くなり利用は難しかったのですが、WSL2でもCUDAを使用できるようになったことで、仮想環境で ROS 2 を動かしやすくなりました。
仮想環境であれば、開発・動作確認はもちろん、比較的簡単に初期状態からの環境構築確認も行うことができ便利です。
Ubuntuネイティブ環境で開発を行う場合は、「ROS 2 のインストール」記事を参照してください。

:::note info
この記事は[ROSに関する投稿](https://qiita.com/kccs_yoshiteru-imamura/items/ef418e9beb508ac52c5d)の一部です。
目次は[こちら](https://qiita.com/kccs_yoshiteru-imamura/items/ef418e9beb508ac52c5d#目次)
:::

### 対象読者

* ROS 2 の開発を始めようとしているエンジニア

### 前提条件

* 本記事を書くにあたり、使用したハードウェアになります。

|   |環境|
|:--|:---|
|メモリー|32GB|
|CPU|Intel(R) Core(TM) i7-10870H CPU @ 2.20GHz|
|GPU（内蔵ディスプレイ用）|Intel(R) UHD Graphics|
|GPU|NVIDIA GeForce RTX 3070 Laptop GPU|
|GPU専用メモリー|8GB|

* 本記事を書くにあたり、使用したソフトウェアになります。

||バージョン|
|:--|:---|
|ホストOS|Windows10 22H2 (OSビルド 19045.3570)|
|NVIDIAドライバ|Game Ready 546.17|
|CUDA on WSL|12.3|
|WSLディストリビューションベース|Ubuntu 22.04|
|ROS 2|ROS 2 humble|
|シミュレータ|Gazebo Classic 11|
|開発ツール|Visual Studio Code（vscode）|

* 本記事での ROS 2 用WSLディストリビューション環境

||内容|
|:--|:---|
|ディストリビューション名|ros2|
|ディストリビューション作成ディレクトリ|D:\develop\wsl\ros2|
|ユーザー名|kccs|
|ROS 2 開発用ディレクトリ|/home/kccs/ros2_ws|

* コマンドの記述

|プレフィックス|環境|
|:-------------|:---|
|PS >|PowerShell 又は コマンドプロンプト|
|root # <br> kccs $|WSLディストリビューションのターミナル|

## NVIDIAドライバインストール

### NVIDIAドライバインストール

NVIDIAドライバが未インストールの場合は、[NVIDIAのサイト](https://www.nvidia.co.jp/Download/index.aspx?lang=jp)などを参考に、NVIDIAドライバのインストールを行います。

## vscodeインストール

IDEとして、vscodeを使用します。

### vscodeインストール

[Microsoftのサイト](https://code.visualstudio.com/)などを参考に、vscodeのインストールを行います。

### 日本語化

日本語化する場合は、拡張機能の「Japanese Language Pack for Visual Studio Code」をインストールします。

```powershell
PS > code --install-extension ms-ceintl.vscode-language-pack-ja
```

### リモート環境利用設定

WSLリモート環境が使用できるように、拡張機能の「Remote Development」をインストールします。

```powershell
PS > code --install-extension ms-vscode-remote.vscode-remote-extensionpack
```

## WSL2インストール

### WSL2インストール

[Microsoftのサイト](https://learn.microsoft.com/ja-jp/windows/wsl/install)などを参考に、WSL2のインストールを行います。

:::note info
ここでは、「WSL コマンドのインストール」部分のWSL2本体のみをインストールします。
ディストリビューションのインストールなどは、この後実施します。
:::

### WSL環境設定

「%userprofile%\.wslconfig」ファイルを作成します。
ROSシミュレーション環境は、使用するメモリが多くなりがちなため、WSLに割り当てる最大メモリとスワップサイズを設定します。
今回使用したマシンは32GBのメモリがあるので、物理メモリの1/4を割り当てて、スワップには割り当てたメモリの4倍を設定しています。

```ini:%userprofile%\.wslconfig
[WSL2]
memory=8GB
swap=32GB
```

## ディストリビューション準備

ロボット毎に環境を分けたり、やり直しを容易にするために、初期インストールされたディストリビューションから、ROS 2 用のディストリビューションを作成します。

### インストール済みディストリビューションの確認

```powershell
PS > wsl -l -v
```

リストに「Ubuntu-22.04」が表示された場合は、[ディストリビューション初期化](#ディストリビューション初期化)を実行し、表示されていない場合は、[ディストリビューション追加](#ディストリビューション追加)を実行してください。

### ディストリビューション初期化

:::note alert
この操作は、ディストリビューションの内容（データ）が消えます。
残したい場合は、事前にexport importで別のディストリビューションとして移行するか、この作業を飛ばして、[ディストリビューション追加](#ディストリビューション追加)に進んでください。
:::

:::note info
理想的には、初期状態のUbuntu22.04ディストリビューションからの作成をお薦めします。
:::

```powershell
PS > wsl --unregister Ubuntu-22.04
```

### ディストリビューション追加

Ubuntu22.04のディストリビューションをインストールします。

```powershell
PS > wsl --install -d Ubuntu-22.04
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3584613/4b3cfbb9-d711-16ae-00c2-874e8ea16144.png)

別ディストリビューションとして使いたいので、ユーザー名の入力に対して、Ctrl + Cキーを押して、ユーザー登録せずに終了します。

### ROS 2 用ディストリビューション作成

Ubuntu22.04のディストリビューションをエクスポートして、新しいディストリビューションとしてインポートします。

```powershell
PS > D:
PS > cd D:\develop\wsl
PS > wsl --export Ubuntu-22.04 Ubuntu-22.04.tar
PS > wsl --import ros2 ros2 Ubuntu-22.04.tar
```

### ディストリビューション実行（ターミナル起動）

```powershell
PS > wsl -d ros2
```

### ログインユーザー作成

作成したディストリビューションに接続して、作業用ユーザーを作成します。
（本記事では、「kccs」とします。）

```shell
root # adduser kccs
```

```
New password: ←パスワードを入力（sudoするときに入力するパスワードになります）
Retype new password: ←上で入力したパスワードと同じものを再入力
Changing the user information for kccs
Enter the new value, or press ENTER for the default
        Full Name []: ←そのままエンターでOK（入力したければユーザー名を入力）
        Room Number []: ←そのままエンターでOK
        Work Phone []: ←そのままエンターでOK
        Home Phone []: ←そのままエンターでOK
        Other []: ←そのままエンターでOK
Is the information correct? [Y/n] ←エンター
```

### sudoersに登録

作成したユーザーがroot権限の処理ができるようにsudersに登録します。

```shell
root # gpasswd -a kccs sudo
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3584613/06c0478c-0ba5-088b-1fb8-c9743eaf742c.png)

### ディストリビューション起動時の初期設定

WSLでsystemdを有効にし、起動時の既定ユーザーを作成したログインユーザーにします。/etc/wsl.conf ファイルを新規に作成します。

```shell
root # vi /etc/wsl.conf
```

開いたエディタに以下の内容をコピー&ペーストします。

```ini:/etc/wsl.conf
[boot]
systemd=true

[user]
default=kccs
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3584613/7c387859-ec7e-ac81-72c9-1741c81ce1d7.png)

「ESC」キー「:wq」エンターでファイルを保存します。

### ターミナル終了

一度、ディストリビューションのターミナルを終了します。

```shell
root # exit
```

### ディストリビューション終了

起動時設定を有効にするために、ディストリビューションを終了します。

```powershell
PS > wsl -t ros2
```

### 起動確認

再度ディストリビューションを実行し、初期設定が有効になっていることを確認します。

```powershell
PS > wsl -d ros2
```

起動時のユーザーが「kccs」になっていればOKです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3584613/bae2841a-ff62-87b5-86ff-524ac1491cb5.png)

## CUDAインストール

[NVIDIAのサイト](https://docs.nvidia.com/cuda/wsl-user-guide/index.html)などを参考に、WSLディストリビューションにCUDAをインストールします。

:::note info
通常のCUDAではなく、CUDA Support for WSL2をインストールする必要があります。
:::

### 古いGPGキー削除

```bash
kccs $ cd
kccs $ sudo apt-key del 7fa2af80
```

### CUDA Toolkit インストール

[CUDAダウンロードページ](https://developer.nvidia.com/cuda-downloads?target_os=Linux&target_arch=x86_64&Distribution=WSL-Ubuntu&target_version=2.0&target_type=deb_local)にて、Distributionに「WSL-Ubuntu」を選択します。
サイズが大きいのでネットワークが不安定な場合は、Install Typeに「deb(local)」を選択した方が失敗が少ないと思います。
表示されたコマンドをもとに、CUDA Toolkitをインストールします。

```bash
kccs $ wget https://developer.download.nvidia.com/compute/cuda/repos/wsl-ubuntu/x86_64/cuda-wsl-ubuntu.pin
kccs $ sudo mv cuda-wsl-ubuntu.pin /etc/apt/preferences.d/cuda-repository-pin-600
kccs $ wget https://developer.download.nvidia.com/compute/cuda/12.3.1/local_installers/cuda-repo-wsl-ubuntu-12-3-local_12.3.1-1_amd64.deb
kccs $ sudo dpkg -i cuda-repo-wsl-ubuntu-12-3-local_12.3.1-1_amd64.deb
kccs $ sudo cp /var/cuda-repo-wsl-ubuntu-12-3-local/cuda-*-keyring.gpg /usr/share/keyrings/
kccs $ sudo apt-get update
kccs $ sudo apt-get -y install cuda-toolkit-12-3
```

### インストール確認

NVIDIAドライバ及びCUDA Toolkitがインストールされ、WSL2のWSLgでNVIDIA GPUが使用されていることを確認します。

```bash
kccs $ nvidia-smi
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3584613/fc059a28-7857-f26f-56fb-f5af2eb8f1ea.png)

右上の「CUDA Version」は、インストールされているNVIDIAドライバで対応可能な最大CUDAバージョンになります。
今回、12.3をインストールしますので、ここが12.3未満の場合は、より新しいNVIDIAドライバをインストールしてください。
ProcessesにXwaylandが表示されればOKです。

## ROS 2 Humbleインストール

[ROS 2 Humbleのサイト](https://docs.ros.org/en/humble/Installation/Ubuntu-Install-Debians.html)などを参考に、ROS 2 をインストールします。

### ロケール設定

日本語ロケールのja_JP.UTF-8に設定します。

```bash
kccs $ sudo apt install -y language-pack-ja
kccs $ sudo localectl set-locale LANG=ja_JP.UTF-8
kccs $ export LANG=ja_JP.UTF-8
```

### Ubuntu Universe Repository有効化

```bash
kccs $ sudo apt install -y software-properties-common
kccs $ sudo add-apt-repository universe
```

### GPGキー追加

```bash
kccs $ sudo apt update && sudo apt install -y curl
kccs $ sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg
```

### ソースリストにリポジトリを追加

```bash
kccs $ echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu $(. /etc/os-release && echo $UBUNTU_CODENAME) main" | sudo tee /etc/apt/sources.list.d/ros2.list > /dev/null
```

### リポジトリキャッシュ最新化&アップグレード

```bash
kccs $ sudo apt update
kccs $ sudo apt upgrade -y
```

### ROS 2インストール

RVizなどを含むデスクトップ版をインストールします。

```bash
kccs $ sudo apt install -y ros-humble-desktop
```

### ROS 2 開発用ツールインストール

開発に必要な、cmake,git,python3,python3-setuptools,python3-bloom,python3-colcon-common-extensions,python3-rosdep,python3-vcstool,wgetをインストールします。

```bash
kccs $ sudo apt install -y ros-dev-tools
```

## Gazeboインストール

[Gazebo Classicのサイト](https://classic.gazebosim.org/tutorials?tut=install_ubuntu&cat=install#Defaultinstallation:one-liner)などを参考に、Gazeboをインストールします。

### Gazebo Classic 11インストール

```bash
kccs $ sudo sh -c 'echo "deb http://packages.osrfoundation.org/gazebo/ubuntu-stable `lsb_release -cs` main" > /etc/apt/sources.list.d/gazebo-stable.list'
kccs $ wget https://packages.osrfoundation.org/gazebo.key -O - | sudo apt-key add -
kccs $ sudo apt update
kccs $ sudo apt install -y gazebo
kccs $ sudo apt install -y libgazebo-dev
```

### Gazebo ROSインストール

```bash
kccs $ sudo apt install -y ros-humble-gazebo-* ros-humble-joint-state-publisher
```

### OpenGL環境確認ツールインストール

Gazeboそのものには不要ですが、OpenGLの環境を確認するためにツールをインストールします。

```bash
kccs $ sudo apt install -y mesa-utils
```

### レンダリングデバイス確認

```bash
kccs $ glxinfo -B
```

表示された情報の中で、赤枠で囲った部分が、INTELになっている場合は、OpenGLで使用するデバイスをNVIDIAにするために、MESA_D3D12_DEFAULT_ADAPTER_NAME環境変数を設定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3584613/b2f6c413-4aa6-2a03-bbe1-5aeec1241fb8.png)

* 環境変数

```bash
export MESA_D3D12_DEFAULT_ADAPTER_NAME="NVIDIA"
```

* 再起動後も有効になるように、.bashrcに追記します。

```bash
kccs $ echo 'export MESA_D3D12_DEFAULT_ADAPTER_NAME="NVIDIA"' >> ~/.bashr
```

### Gazebo起動確認

```bash
kccs $ gazebo
```

### GPU使用確認

```bash
kccs $ nvidia-smi
```

Processに「gzserver」「gzclient」が表示されれば、GPUレンダリングが使用されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3584613/8846f6bb-a5aa-0b79-fc38-12f3fbeac93f.png)

## その他パッケージインストール

### 分析ツールパッケージ

```bash
kccs $ sudo apt install ros-humble-rqt-*
```

## 開発用ソースディレクトリ作成

開発に使用するワークスペースを準備します。

### ディレクトリ作成

```bash
kccs $ cd
kccs $ mkdir -p ros2_ws/src
kccs $ cd ros2_ws
```

### 依存関係ツール初期化

```bash
kccs $ sudo rosdep init
kccs $ rosdep update
```

### ビルド環境初期構築

```bash
kccs $ source /opt/ros/humble/setup.bash
kccs $ colcon build
```

## 環境変数設定

~/.bashrcに環境変数を追記し、ターミナル起動でHumbleが使用できるようにします。

### CUDA関係追加

```bash
kccs $ echo 'export CUDA_PATH=/usr/local/cuda' >> ~/.bashrc
kccs $ echo 'export LD_LIBRARY_PATH=/usr/local/cuda/lib64:${LD_LIBRARY_PATH}' >> ~/.bashrc
kccs $ echo 'export PATH=/usr/local/cuda/bin:${PATH}' >> ~/.bashrc
```

### ROS 2 関係追加

今回は、ローカル環境のみでの開発を想定して、ローカルのみの設定にします。ローカル以外では、ROS_DOMAIN_IDが同一の場合、同一実行環境として扱われるため、同一ネットワークの端末間で干渉させたくない場合は、端末毎に値を変えます。

```bash
kccs $ echo "export ROS_DOMAIN_ID=0" >> ~/.bashrc
kccs $ echo "export ROS_LOCALHOST_ONLY=1" >> ~/.bashrc
kccs $ echo "source ~/ros2_ws/install/setup.bash" >> ~/.bashrc
```

## 再起動

環境変数などの設定を有効にするために、ディストリビューションを再起動します。

### ターミナル終了

```bash
kccs $ exit
```

### ターミナル開始

```powershell
PS > wsl -d ros2
```

## vscode設定

vscodeでROS開発を行うための準備を行います。

### vscode起動

```bash
kccs $ cd ~/ros2_ws
kccs $ code .
```

初回はディストリビューション内へのインストールが実行されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3584613/0c498878-ef82-b67a-a44b-29236c08c872.png)

### 信頼確認

vscodeが起動すると、作成者の信頼確認画面が表示されます。
「はい、作成者を信頼します」を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3584613/e4625954-3f7d-5edb-bd22-75b2dfeb24cd.png)

### vscode終了

起動したvscodeを一旦終了します。

### ROS操作、Python、C++の開発＆ビルドに必要な拡張機能インストール

```bash
kccs $ code --install-extension ms-vscode.cpptools-extension-pack
kccs $ code --install-extension ms-python.python
kccs $ code --install-extension ms-python.flake8
kccs $ code --install-extension ms-python.autopep8
kccs $ code --install-extension njpwerner.autodocstring
kccs $ code --install-extension ms-iot.vscode-ros
kccs $ code --install-extension mhutchie.git-graph
```

## ワークスペース開発設定

ワークスペースでvscodeを使用してC++,Pythonの開発を行うための設定をします。

### vscode起動

Windowsメニューから「Visual Studio Code」を選択し起動します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3584613/cb40f6e4-165a-3170-4ae9-7dd0c5908fc8.png)

### 起動場所確認

前回起動したワークスペースが開くので、WSL:ros2で開かれていることを確認します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3584613/5f992a0b-66ef-7063-4da5-145a6f2d935e.png)

もし、異なる場所で起動している場合は、ワークスペースを開きなおします。「メニュー」「ファイル」「最近使用した項目を開く」の順に選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3584613/7fd8e8e4-0847-4d76-fbfa-94f67ae141b2.png)

[WSL:ros2]を選択してフォルダーを開きます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3584613/6c788395-25dc-7ccc-056c-47e0bb521d77.png)

### linter / formatterなどの設定

エクスプローラーパネルの空いているところで右クリックし、「新しいフォルダー…」を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3584613/549b3748-7968-26da-5137-1151ac6f356c.png)

「.vscode」と入力し、フォルダーを作成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3584613/d9b20108-2ba0-9bc2-2872-1d3d04788b8d.png)

「.vscode」の上で右クリックし、「新しいファイル…」を選択し、以下の2ファイルを作成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3584613/ac8335c3-02e2-c572-dcfe-a7fa3ce56afa.png)

```json:c_cpp_properties.json
{
    "configurations": [
        {
            "browse": {
                "databaseFilename": "${default}",
                "limitSymbolsToIncludedHeaders": false
            },
            "includePath": [
                "${workspaceFolder}/src/**",
                "/opt/ros/humble/include/**",
                "/usr/include/**"
            ],
            "name": "ROS",
            "intelliSenseMode": "gcc-x64",
            "compilerPath": "/usr/bin/gcc",
            "cStandard": "gnu11",
            "cppStandard": "c++14"
        }
    ],
    "version": 4
}
```

```json:settings.json
{
    "python.analysis.extraPaths": [
        "/opt/ros/humble/lib/python3.10/site-packages",
        "/opt/ros/humble/local/lib/python3.10/dist-packages"
    ],
    "python.autoComplete.extraPaths": [
        "/opt/ros/humble/lib/python3.10/site-packages",
        "/opt/ros/humble/local/lib/python3.10/dist-packages"
    ],
    "C_Cpp.clang_format_style": "Google",
    "editor.formatOnSave": true,
    "editor.formatOnType": true,
    "[cpp]": {
        "editor.tabSize": 2,
    },
    "files.associations": {
        "*.ipp": "cpp",
        "array": "cpp",
        "atomic": "cpp",
        "complex": "cpp",
        "any": "cpp",
        "chrono": "cpp",
        "ratio": "cpp",
        "string_view": "cpp",
        "system_error": "cpp",
        "type_traits": "cpp",
        "fstream": "cpp",
        "functional": "cpp",
        "istream": "cpp",
        "ostream": "cpp",
        "sstream": "cpp",
        "streambuf": "cpp",
        "valarray": "cpp",
        "iosfwd": "cpp"
    },
    "[python]": {
        "editor.defaultFormatter": "ms-python.autopep8",
        "editor.formatOnSave": true
    },
    "autopep8.args": [
        "--max-line-length=120"
    ],
    "flake8.args": [
        "--max-line-length=120",
        "--max-complexity=10"
    ],
    "C_Cpp.intelliSenseEngineFallback": "disabled",
    "C_Cpp.default.compilerPath": "/usr/bin/gcc",
    "ros.distro": "humble"
}
```

## ディストリビューション退避

環境が壊れた場合のリセットや、別の開発環境をすぐに構築するために、各種設定が終わった現時点のディストリビューションをエクスポートして保存しておきます。

### エクスポート

```powershell
PS > D:
PS > cd D:\develop\wsl
PS > wsl --export ros2 ros2.tar
```

出力したtarファイルをインポートすることで、別環境の構築に利用することができます。

## 参考文献

* NVIDIAドライバダウンロードサイト

https://www.nvidia.co.jp/Download/index.aspx?lang=jp

* Visual Studio Code

https://code.visualstudio.com/

* WSL を使用して Windows に Linux をインストールする方法

https://learn.microsoft.com/ja-jp/windows/wsl/install

* CUDA on WSL User Guide

https://docs.nvidia.com/cuda/wsl-user-guide/index.html

* CUDA Toolkit 12.3 Update 1 Downloads

https://developer.nvidia.com/cuda-downloads?target_os=Linux&target_arch=x86_64&Distribution=WSL-Ubuntu&target_version=2.0&target_type=deb_local

* ROS 2 Documentation: Humble

https://docs.ros.org/en/humble/Installation/Ubuntu-Install-Debians.html

* Install Gazebo using Ubuntu packages

https://classic.gazebosim.org/tutorials?tut=install_ubuntu&cat=install#Defaultinstallation:one-liner

## おわりに

以上が ROS 2 humble を使用しWSL上で開発を行うための基本的な環境作成になります。

次回以降では、ノード作成など実際の開発に関する記事を投稿していく予定ですので、お楽しみに！