WSL2 で ROS2 Humble をインストールする方法

　こんにちは。この記事では **WSL のセットアップ、Ubuntu のインストールから ROS2 のインストール、ROS2 の基礎に触れるところまで** 初心者でもわかりやすく解説することを試みています。
　この記事をすべて読むことで、

- **WSL の基礎的な使用方法**
- **ROS2 をインストールする方法**
- **ROS2 の基本的な使用方法**
- **簡易的なトラブルシューティング**

を学び、理解することができるでしょう。この記事は **初心者むけ** の記事です。上級者（経験者）の方も初心に戻って参考として読んでいただけると励みになります。

# もくじ

- [はじめに](#はじめに)
    - [WSL とは](#wsl-とは)
    - [Linux とは](#linux-とは)
    - [Ubuntu とは](#ubuntu-とは)
    - [ROS2 とは](#ros2-とは)
- [0. PowerShell を開く方法](#0-powershell-を開く方法)
- [1. WSL2 をインストールする方法](#1-wsl2-をインストールする方法)
    - [1.1. WSL をインストールする](#11-wsl-をインストールする)
    - [1.2. Ubuntu の初期設定をする](#12-ubuntu-の初期設定をする)
    - [1.3. WSL の Ubuntu にログイン、ログアウトする方法](#13-wsl-の-ubuntu-にログインログアウトする方法)
- [2. WSL の基本的な使用方法](#2-wsl-の基本的な使用方法)
    - [2.1. WSL Ubuntu にログインする](#21-wsl-ubuntu-にログインする)
    - [2.2. WSL Ubuntu からログアウトする](#22-wsl-ubuntu-からログアウトする)
    - [2.3. WSL をシャットダウンする](#23-wsl-をシャットダウンする)
    - [2.4. WSL の状態を確認する](#24-wsl-の状態を確認する)
    - [2.5. WSL でインストールした Ubuntu をアンインストールする](#25-wsl-でインストールした-ubuntu-をアンインストールする)
    - [2.6. WSL でインストールした Ubuntu を初期化する方法](#26-wsl-でインストールした-ubuntu-を初期化する方法)
    - [2.7. WSL でログインするときに起動するデフォルト OS を変更する方法](#27-wsl-でログインするときに起動するデフォルト-os-を変更する方法)
- [3. WSL 上に ROS2 をインストールする](#3-wsl-上に-ros2-をインストールする)
- [4. ROS2 に触れてみる](#4-ros2-に触れてみる)
    - [4.1. ROS2 をシステムに反映させる](#41-ros2-をシステムに反映させる)
    - [4.2. サンプルプログラムを実行してトピックの通信をしてみよう](#42-サンプルプログラムを実行してトピックの通信をしてみよう)
    - [4.3. サンプルプログラムを実行してトピックの通信をしてみよう（その２）](#43-サンプルプログラムを実行してトピックの通信をしてみようその２)
    - [4.4. チャレンジしてみよう](#44-チャレンジしてみよう)
- [おわりに](#おわりに)

# はじめに
　ここで改めて WSL、Linux、Ubuntu、ROS2 とはなにかを説明しましょう。この４つの単語の意味を最低限理解することがこの記事を読み進める重要な要素になります。難しいものだと思うかもしれません。実際難しいと感じるかもしれません。ただ、それは決して恥ずかしいことではなく **時間をかけてあなたのペースで理解していくことがもっとも重要なのです。**

## WSL とは
<img width=35%><img width=30% src="https://static.wikia.nocookie.net/logopedia/images/5/5a/Windows_Subsystem_for_Linux_icon.png/revision/latest?cb=20240306141837" />
<img width=42.5%><font color="silver"> ***WSL のロゴ***</font>

　**WSL** は、$\text{Windows Subsystem for Linux}$ の略で、Windows 上で Linux 系 OS を実行することができる Windows に標準搭載されているシステムです。WSL を使うことで Linux の環境のコンピューターを新たに手に入れたり、使用しているコンピューターに新たな OS として組み込まなくても **Windows と共存した環境として Linux を使うことができます。**
　Linux でしかできない作業を Windows PC でしたいときにとても重宝するシステムですね。これを使うことでバーチャルマシンソフトウェアなどをわざわざインストールする必要がなくなります！
　詳しく知りたい方は [**公式サイト**](https://learn.microsoft.com/ja-jp/windows/wsl/about) でわかりやすく WSL について解説しているので読んでみてください。

## Linux とは
<img width=35%><img width=30% src="https://seeklogo.com/images/L/linux-logo-704D6BB91C-seeklogo.com.png" />
<img width=42.5%><font color="silver"> ***Linux のロゴ***</font>

　**Linux** は Windows、macOS、Android、iOS と同じ $\text{OS}$ の一種です。デスクトップコンピューター上で見かける Windows や Apple の MacBook などで使われる macOS に次いで第3勢力として名を出している OS です。
　Linux の最大の特徴は、Windows や macOS と違い **無料でつかえる**、**どんなコンピューターでも動く**、**オープンソースである**、**とにかく軽量** であることです。
　Windows には様々なアプリやサポート機能が標準でインストールされており、かつ Windows をあらたにインストールするには **料金がかかります** が、Linux は **無料でインストールすることができて**、**必要最低限の機能** しか搭載されていません。よって軽量で低スペックなコンピューターでも軽快に動作します。
　まっさらな環境で作業できるため開発者が好むオペレーティングシステムです。一方必要な機能は **自作するか**、**自力でインストールする** 必要があり、ほかの OS と比べハードルが高いため、パソコンに疎い人には忌避されている OS でもあります。
　この記事でインストール、使用する ROS2 も基本的に Linux 上で動作することを前提とされています。

::: note
　Linux はシンボルとして **上記のようなペンギン** が使われます。ちなみにこのペンギンには名前がついており、$\text{Tax}$（タックス）といいます。
:::

## Ubuntu とは
<img width=35%><img width=30% src="https://upload.wikimedia.org/wikipedia/commons/7/76/Ubuntu-logo-2022.svg" />
<img width=42.5%><font color="silver"> ***Ubuntu のロゴ***</font>

　**Ubuntu** とは、（ウブンツ）と読み、Linux OS の **ディストリビューションのひとつ** です。
　Linux はオープンソース。つまり **誰でも改造できる OS** なので、何人もの開発者が Linux をベースとした自作の OS を世に複数提供しています。Ubuntu はその中で **最も安定して完成度の高い Linux 系列 OS** と言えます。このように、**Linux をベースとして派生した OS** たちを **ディストリビューション または ディストロ** といいます。
　Ubuntu のほかに有名なディストロは以下の通りです。

- **Debian（デヴィアン）**
    Ubuntu を含めたディストログループです。Debian 系 OS とまとめられることもあります。Debian 系列の OS は **世界中のボランティアが作ったすべてフリー、オープンソースで、だれでも無償で使用、改造することができる** OS です。マイクロコンピューターで有名な Raspberry Pi（ラズベリーパイ）も Debian 系列の OS で動作します。
- **Red Hat**
　Red Hat（レッドハット）は RedHat社が開発したディストロです。商用 Linux とも呼ばれており、この系列の Linux を多くの会社が利用しており、なかでも有名な Cent OS（セントオーエス）はことしサポート終了するとして話題になっています。

## ROS2 とは
<img width=35%><img width=30% src="https://contentsviewer.work/Master/ROS2/Images/ROS2.png" />
<img width=42.5%><font color="silver"> ***ROS2 のロゴ***</font>

　**ROS2** とは、$\text{Robot Operating System 2}$ の略で、**"ロスツー"** と呼びます。名前に "オペレーティングシステム" と書いてありますが、Linux や Windows のことを指す OS とは違い、**ロボットを制御（オペレート）するシステムをまとめたミドルウェア** です。
　名前の通り、ROS1（端に ROS という）も存在し、2025 年にサポートが終了します。ROS は開発者が効率的にロボットを開発できるために作成された Linux 同様オープンでフリーなソフトウェアです。とても盛んに開発が行われており、有志が作成したパッケージをインストールすることで簡単にロボットにインテリジェントな機能を実装することができます。
　また、開発言語が Python と C++ をサポートしているため比較的簡単に参入することができます。とくに ROS2 をベースに動くロボットは世界中に商用利用として開発されており、ROS2 を学ぶことでロボット開発で将来エンジニアとして働くことも期待できます。

---

　ROS2 の主な機能として **相互通信** があります。リアルタイムで複数のプログラム（ノード）間でデータをやり取りすることで簡単に高度なロボットオペレートを実装することができます。

### ROS で動いている、動かせるロボットたち
　ここでは ROS で動いている、または動かせるロボットを紹介します。

- **Pepper**
    <img width=30% src="https://robotstart.info/wp-content/uploads/2019/05/pepper.png" />
　Pepper（ペッパー）は SoftBank Robotics（アルデバラン） が開発した広報用ロボットです。両手を滑らかに動かして腹部のディスプレイにコンテンツを表示することができます。日本ではかなり有名なロボットですね。一度は見たことがあるのではないでしょうか？
 　このロボットは無線通信で ROS による制御ができますが、古いロボットなので ROS2 には完全にサポートしていません。有志が ROS2 版のシステムを開発中とのうわさが。。。

- **ルンバ**
    <img width=30% src="https://m.media-amazon.com/images/I/61YU1rC5cYL._AC_SL1000_.jpg" />
    　お掃除ロボットとして有名なルンバも ROS で動かすことができます。厳密にいうと **ルンバ 980 シリーズより前のモデル** を制御することができます。現在販売されているルンバ i、s、j、コンボシリーズは外部からハッキング、制御することは今のところできません。
    
- **LOVOT**
    <img width=30% src="https://lovot.life/_nuxt/lovot2_pc.Bbafavld.webp" />
    LOVOT（らぼっと）は日本が開発したセラピーロボットです。愛くるしいしぐさで人を癒してくれます。実態はなかでROSが動作してナビゲーションを実装しています。

- **Kachaka**
    <img width=30% src="https://kachaka.life/_next/static/chunks/images/_next/static/media/about-store-item-kachaka.2f7d7c69_640.webp" />
    kachaka（カチャカ）はルンバに似ていますが荷物を運んでくれるサービスロボットです。こちらも公式から ROS2 で kachaka を制御できるよう API が公開されています。

- **TELLO**
    <img width=30% src="https://se-cdn.djiits.com/tpc/uploads/carousel/image/e372d1db0837cb440fba7bdb8d6526f2@origin.jpg" />
    ドローン老舗メーカー DJI が販売している教育用ドローンです。こちらも ROS をつかってハイレベルな制御を行うことができます。安価なので比較的低いハードルで開発することができます。
    
- **Spot**
    <img width=30% src="https://www.generationrobots.com/19651-product_cover/payload-boston-dynamics-spot-arm.jpg" />
    アクロバティックなロボットアクションを見せつけることで有名な Boston Dynamics が開発した犬型ロボットです。こちらも ROS で動かすための API が用意されています。
    
---

　それではさっそく Windows で ROS2 開発をするための第１歩を歩んでいきましょう！！！

# 0. <font color="blue">PowerShell</font> を開く方法
　WSL2 をセットアップしたり、Ubuntu や ROS2 を使うために <font color="blue">**PowerShell**</font> を使用します。PowerSell はコマンドを入力する場所で、通常皆さんがマウスカーソルでボタンをクリックしたりコンテンツをドラッグ＆ドロップしたたりする作業をすべてコマンド（命令文）で作業させることができます。これにより素早くファイルを編集、移動させたり、通常の方法では変更できないコンピューターの設定を変更したり、通常の方法では利用できないシステムの拡張やインストールを行うことができます。ここではそのような作業をふんだんに行いますのでこれを機に PowerShell の使用になれておきましょう。
　Windows キーを押すか、タスクバーの **Windows アイコン** をクリックして **スタートメニュー** を開きます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729782/1325d1a3-f08e-db7e-6b56-e4bbf6d6d58d.png" />
　スタートメニューの検索バーに **PowerShell** と入力すると、PowerShell アプリが候補として表示されます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729782/ef47cdd8-91ac-e57c-ed5a-45f72d99d961.png" />
　この状態で **エンターキーを押す** か、候補として挙がっている PowerShell アプリの **「開く」** をクリックすると、下の画像のような黒いウィンドウが表示されます。これが PowerShell です。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729782/3a38344f-ce2e-92ae-de74-b7e140373196.png" />
　このとき、PowerShell に
 ```
 PS C:\Users\USERNAME>
 ```
が表示されているのがわかるでしょう。ここが **コマンドを入力するところ** です。

::: note
　私（筆者）のコンピューターアカウント名が **`nakag`** なので、`USERNAME` の部分が `nakag` になっています。ここはお使いのコンピューターにサインインしているアカウント名が入るため人によって名前が異なります。
:::

これで **WSL2 をセットアップする準備が整いました。**

# 1. <font color="blue">WSL2</font> をインストールする方法
::: note alert
## WSL のデフォルトディストリビューションの変更について（2024/10/1 確認）
　WSL でインストールされるデフォルト Ubuntu ディストリビューションが <font color="red">**Ubuntu 22.04 から Ubuntu 24.04 に変更されました。**</font> ここでは <font color="red">**Ubuntu 22.04**</font> を使用します。
:::

::: note warn
# 事前確認と事前準備
　WSL をインストールする前に、以下の項目の確認と準備を実施しましょう。
## ネットワークの確認
　作業を始める前に <font color="red">**お使いのコンピューターがインターネットに接続されているか**</font> 確認してください！インターネットに接続されていないと以降の作業ができません。

## ストレージの確認
　作業を始める前にお使いのコンピューターに <font color="red">**十分な空き容量**</font> があるかどうか確認してください。ストレージの確認は、「設定」を開いて、「システム」の「ストレージ」を開き、この画面で現在のストレージの空き容量がわかります。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729782/7847977b-9eb3-23ea-fced-815829400d95.png" />

## VScode をインストールする
　VScode とはプログラム専用のエディタです。このアプリをインストールしておくことで今後の作業がとてもスムーズになります。以下の記事を参考に VScode をインストールしてください。
 
- [**Windows に VSCode をインストールする**](https://qiita.com/GAI-313/items/f3d4722ebeda5ea195d1)

## Hyper-V を有効にする
　お使いのコンピューターで実機ロボットを接続したい場合、Hyper-V という機能を使って WSL 内で利用する Ubuntu OS がネットワークに正常にアクセスできるようにしなければなりません。お使いのコンピューターが Windows HOME エディションの場合、以下の記事を参考に Hyper-V を有効にしてください。

- [**Windows 11 Home で Hyper-V を有効にする方法**](https://qiita.com/GAI-313/items/a3ac77676a513d74e2a6)

## 仮想インターフェースを作成する
　仮想インタ＝フェースを作ることでネットワーク経由でお使いのコンピューターで実機ロボットをWSL 内で利用する Ubuntu OS から接続することができるようになります。以下の記事を参考に仮想インターフェースを作成してください。

- [**仮想インターフェースを Hyper-V で作成する**](https://qiita.com/GAI-313/items/0f734c0d06b55d58b08b)

## .wslconfig を作成する
　仮想インターフェースなどの変更内容を WSL に反映させるために `.wslconfig` というファイルを書く必要があります。以下の記事を参考に .wslconfig を作成してください。

- [**WSL にホストの IP アドレスを使用できるようにする方法**](https://qiita.com/GAI-313/items/0f734c0d06b55d58b08b)
:::

## 1.1. WSL をインストールする
　WSL2 をインストールするには PowerShell を使用します。[前回のセクションを参考](#0-powershell-を開く方法) にして PowerShell を開いてください。
　PowerShell に以下のコマンドを入力してください。このコマンドは使用しているコンピューターに WSL をインストールするコマンドです。
```
wsl --install -d Ubuntu-22.04
```
コマンドを入力するとこのように入力したコマンドが `>` の後に表示されます。
<img src="https://funakamome.com/i/a773eacbfafa88344f16bd8ebda6f9eb.png" />

　入力したコマンドが間違っていないことを確認して、**エンターキー** を押してください。すると入力されたコマンドが実行されます。インストール中は PowerShell にこのような進捗が表示されます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729782/51e82c22-99ba-4a76-d1f6-e6c21becbb82.png" />

::: note
　ネットワークの状況によって時間がかかることがあります。作業が終わるまでしばらくお待ちください。

---

　また、インストール中にこのような確認画面が表示されることがあるので、表示された場合は  **「はい」** をクリックしてください。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729782/802ea5ca-ce00-983b-357c-5d94ef16f8db.jpeg" />

---

人によっては以下のように Ubuntu のインストールが完了するとすぐに初期設定プロンプトが表示されることがあります。この場合は下の作業（コンピューターの再起動）はスキップして次のセクション [**1.2. Ubuntu の初期設定をする**](#12-ubuntu-の初期設定をする) に進んでください。
<img src='https://i.imgur.com/YyuX8VA.jpeg'/>
:::

　作業が終わるとこのように **`Ubuntu はインストールされました`** と表示されます。これが表示されたら WSL のインストールが完了し、お使いのコンピューターの Windows 内に Ubuntu がインストールされたことを表しています。プロンプトに表示されている指示に従いコンピューターを再起動してください。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729782/87653f4a-35f3-f0f2-7f78-3c13591cf6ce.png" />

## 1.2. Ubuntu の初期設定をする
　コンピュータを再起動し、ログインすると **自動的に PowerShell が起動します。** このとき PowerShell 上で **Ubuntu 用アカウントを作成するよう促されます。**
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729782/a638e193-c829-8844-75f0-fa0a23704714.png" />
```
Enter new UNIX username:
```
のところで Ubuntu で使用するユーザー名を入力してください。このユーザ名は新規登録なので好きな名前で構いません。
　わたしの場合は `gai` という名前で登録しました。名前を確定したい場合は **エンターキー** を押します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729782/0c7cdfd6-4e44-a729-fd51-9c21daa86800.png" />
　ユーザー名を確定すると、今度は
 ```
 New password:
 ```
 という入力欄が表示されます。ここに Ubuntu ユーザーアカウント用のパスワードを設定してください。パスワードを入力しても <font color="red">**画面に入力したパスワードは表示されません。誤字脱字に気をつけて入力してください。**</font>
 　パスワードを入力し、エンターキーを押したら、
```
Retype new password:
```
と **再度パスワード入力が求められます。** 先ほど入力したのと同じパスワードを入力してエンターキーを押してください。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729782/234a1305-8508-4915-e7e3-119b3a2c4917.png" />
　新規ユーザ名とパスワードを入力し、`この操作を正しく終了しました。` と表示されたら Ubuntu および WSL のインストールは成功です！
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729782/7bac67e4-14b6-34f3-d496-d3621e1a0284.png" />
　しばらくすると、このように PowerShell のプロンプト部分が変化したら、WSL 内の Ubuntu にログインしたことを示しています。Windows にいる時は、プロンプトの末尾が `>` ですが、Ubuntu にいる時は `$` になっています。加えて、WSL Ubuntu にログインしている場合、プロンプトは **緑色** になります。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729782/bd64ee70-ca85-5c84-bdda-6f1f0eeea6f4.png" />

---

::: note alert
初期設定で設定したパスワードは **忘れないように気を付けましょう。**
:::

## 1.3. WSL の Ubuntu にログイン、ログアウトする方法
　WSL Ubuntu からログアウトしたい場合は、Ubuntu にログインしているシェル上で
```
exit
```
と入力してエンターキーを押すか、キーボードショートカット「Control + D」を行います。するとこのように `logout` というメッセージが表示されプロンプトが元の PowerShell に戻ります。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729782/515269f2-3f91-303b-7377-333cc40132eb.png" />

　もう一度ログインしたい場合は以下のコマンドを PowerShell 上で実行します。
```
wsl ~
```

::: note warn
もし、上記のコマンド `wsl ~` で WSL にインストールされた Ubuntu にログインしたとき、以下のように **緑色のプロンプトに変化しない** 場合、トラブルシューティング [**WSL Ubuntu ログイン時にルートとしてログインしてしまう**](#1t0-wsl-ubuntu-ログイン時にルートとしてログインしてしまう) を参照してください。
<img src='https://i.imgur.com/MxV3W59.jpeg'/>
:::

## 1.t0. WSL Ubuntu ログイン時にルートとしてログインしてしまう
　通常、WSL にログインするときは以下のコマンドを使います。
```
wsl ~
```
　このとき、初期設定のときに設定したユーザー名で WSL 内の Ubuntu にログインされ、Ubuntu をそのユーザーとしてアクセスできるようになります。しかしながら、場合によってシステムがコマンド `wsl ~` を実行したときに誰がログインするのか理解できなくなり **root ユーザー** としてログインしてしまうことがあります。

::: note
**root ユーザー** について知りたい方は [**こちらのサイトが詳しく解説しています。**](https://wa3.i-3-i.info/word18989.html)
:::

　これは好ましくありません。最も簡単な解決方法はあなたが Ubuntu にログインしたい場合以下のコマンドを使いログインすることがです。すると、初期設定で作成したユーザーとしてログインされるはずです。
```
wsl -d Ubuntu-22.04
```

::: note
この問題が上記のコマンドで解決したならば、今後あなたはこの記事内で「WSL Ubuntu にログインしてください」という部分で上記のコマンドを実行するようにしてください。
:::

# 2. WSL の基本的な使用方法
## 2.1. WSL Ubuntu にログインする
　WSL にログインには、PowerShell を起動して、以下のコマンドを実行してください。
```
wsl ~
```
## 2.2. WSL Ubuntu からログアウトする
　前回も説明しましたが、WSL にログインしている PowerShell で
```
exit
```
と入力してエンターキーを押すか、キーボードショートカット「Control + D」を行います。

## 2.3. WSL をシャットダウンする
　WSL からログアウトしてもバックグラウンド上で WSL はスリープ状態で待機しています。ゲームや動画編集などの重い作業をしたい時にプロセス領域を確保するため WSL をシャットダウンすることで完全に WSL を止めることができます。
　PowerShell を開き以下のコマンドを実行します。
```
wsl --shutdown
```
::: note alert
　このコマンドを実行するとログイン中の WSL が停止し、WSL 上で保存していないコンテンツは **全て削除される恐れがあります。** 事前に WSL 上での作業を終えているかどうか確認しましょう。
:::

## 2.4. WSL の状態を確認する
　WSL 上にインストールされている Linux の状態を確認したい場合、以下のコマンドを実行します。
```
wsl -l -v
```
　このコマンドを実行すると、以下のような結果が表示されます。
```
  NAME      STATE           VERSION
* Ubuntu    Stopped         2
```
　これは **Ubuntu OS が Stopped（シャットダウン）している状態** を示しています。以下のように `STATE` 項目が **Running** になっている場合、その Linux は裏でまだ起動していることを示しています。
```
  NAME      STATE           VERSION
* Ubuntu    Running         2
```

## 2.5. WSL でインストールした Ubuntu をアンインストールする
　何らかの問題で WSL を再インストールしたい時の方法を解説します。
　PowerShell を開き、WSL 上で起動しているシステムを以下のコマンドを実行して全て停止させます。
```
wsl --shutdown
```
　次に以下のコマンドを実行して WSL 上にインストールされた Linux の状態を確認します。
```
wsl -l -v
```
　WSL 上の Linux が停止していることを確認したら、**設定アプリ** を起動して、**アプリ** の項目を開いてください。**インストールされているアプリ** にこのコンピューター上にインストールされているすべてのアプリが表示されています。 WSL でインストールした Linux OS がアプリとして表示されているので、「アンインストール」をクリックして Linux を削除することができます。

::: note alert
Linux をアンインストールすると、Linux 上の全てのデータが消えます。
:::

　再度 PowerShell を開いて、以下のコマンドを実行して WSL 上にインストールされた Linux の状態を確認します。
```
wsl -l -v
```
すると、このように WSL 上にインストールされている Linux が存在しないというエラーが表示されます。
```
Linux 用 Windows サブシステムにインストールされているディストリビューションはありません。

使用可能なディストリビューションを一覧表示するには、'wsl.exe --list --online' を使用します
インストールするには 'wsl.exe --install <Distro>' と指定します。

ディストリビューションは、Microsoft Storeにアクセスしてインストールすることもできます:
https://aka.ms/wslstore
Error code: Wsl/WSL_E_DEFAULT_DISTRO_NOT_FOUND
```
## 2.6. WSL でインストールした Ubuntu を初期化する方法
　インストールした Ubuntu を初期化したい場合、PowerShell 上で以下のコマンドを実行してください。
```
wsl --unregister Ubuntu
```
::: note warn
このコマンドは Windows ホスト上で実行するコマンドであり、Ubuntu 内で実行するコマンドではありません。
:::
```
登録解除。
この操作を正しく終了しました。
```
このようなメッセージが表示されたら初期化成功です。

## 2.7. WSL でログインするときに起動するデフォルト OS を変更する方法
　例えば、お使いのコンピューターに Docker がインストールされている場合、以下のコマンドを実行するとこのように２つのディストリビューションが表示されます。
```
wsl -l -v
```
```
  NAME              STATE           VERSION
* docker-desktop    Stopped         2
  Ubuntu-22.04      Stopped         2
```
　これをみると **`docker-desktop`** に `*` がついているのがわかるでしょう。この `*` がついているディストリビューションがログインコマンド `wsl ~` などで起動されるディストリビューションになります。この記事ではディストリビューション **Ubuntu-22.04** をインストールして、今後もこのディストリビューションを使いますから、上記の状態では好ましくありません。この場合、以下のコマンドで起動時に選択されるデフォルトのディストリビューションを指定することができます。
```
wsl -s <ディストリビューション名>
```
**Ubuntu-22.04** をデフォルトにしたい場合は以下のコマンドを実行します。
```
wsl -s Ubuntu-22.04
```
`この操作を正しく終了しました。` というメッセージが表示されたら、もう一度 `wsl -l -v` コマンドを実行して確認してみると、`*` が選択したディストリビューションに移動しているのが確認できます。
```
  NAME              STATE           VERSION
* Ubuntu-22.04      Stopped         2
  docker-desktop    Stopped         2
```

# 3. WSL 上に ROS2 をインストールする
　WSL Ubuntu にログインして、ROS2 のインストールを行いましょう。以下のコマンドをはじめに実行してください。このコマンドは Ubuntu にインストール可能なアプリやパッケージ一覧を更新します。
```bash
sudo apt update
```
　エンターキーを押すと
```
[sudo] password for ユーザー名:
```
　とパスワードの入力が求められるので WSL をインストールした時に設定したパスワードを入力してください。
　しばらくの間ログが表示されます。プロンプト（`$`）が表示されるまでお待ちください。
 　更新が終わったら以下のコマンドを実行してください。このコマンドは ROS2 をインストールする時に必要なパッケージをインストールします。
```bash
sudo apt install curl gnupg lsb-release net-tools
```
　このコマンドを実行すると、途中で
```
Do you want to continue? [Y/n]
```
 というメッセージが表示されることがあります。これが表示されたら **エンターキーを押す** か、**yキー** を押してください。すると指定されたパッケージがインストールされます。

::: note
### **`/sbin/ldconfig.real: /usr/lib/wsl/lib/libcuda.so.1 is not a symbolic link`** というエラーが発生した場合
　`apt install ...` コマンドを実行した時に以下のようなエラーメッセージが表示されることがあります。
```
 /sbin/ldconfig.real: /usr/lib/wsl/lib/libcuda.so.1 is not a symbolic link
```
　このエラーは WSL 上の Ubuntu で見られるエラーで、以下のコマンドを実行すると解決します。

> 以下のコマンドは3行一度にコピペして実行するのではなく **1行ずつコピペして実行してください。**

```
cd /usr/lib/wsl/lib/
sudo rm libcuda.so libcuda.so.1
sudo ln -s libcuda.so.1.1 libcuda.so.1
sudo ln -s libcuda.so.1 libcuda.so
sudo ldconfig; cd
```
:::

　次に、以下のコマンドを実行して ROS2 の GPG キーをダウンロードします。
```bash
sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg
```
　続いて、ダウンロードした GPG キーを以下のコマンドを実行してシステムに登録します。これをするkとで使用しているオペレーティングシステムに ROS2 をインストールする準備が整います。
```bash
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
```
　システムに ROS2 をインストールするために必要なキーを読み込ませたので、再度以下のコマンドを実行して更新を行います。
```
sudo apt update
```
　これで ROS2 をインストールするすべての準備が整いました。以下のコマンドを実行して ROS2 をインストールします。
```
sudo apt install ros-humble-desktop
```
`Do you want to continue? [Y/n]` というメッセージが表示されたら **エンターキーを押す** か、**yキー** を押してインストールを行ってください。

::: note
ROS2 のインストールには **少し時間がかかります。** お茶でも飲んでまちましょう。
:::

<a id="4"></a>
# 4. ROS2 に触れてみる
　ROS2 はざっくり説明すると主にロボットを制御するためのメッセージデータを相互通信するシステムです。ここではその相互通信（Pub&Sub 通信：パブ、サブ通信）のサンプルを実行して動作確認してみましょう。

<a id="4-1"></a>
## 4.1. ROS2 をシステムに反映させる
　ROS2 をインストールしても、すぐに ROS2 を使えるわけではありません。以下のコマンドは ROS2 で通信されているデータ **（トピック）**  の一覧を表示するものですが、このように実行するとエラーが出てしまいます。
```bash
$ ros2 topic list
ros2: command not found
```
::: note
`〇〇: command not found` というエラーは、○○というコマンドが存在しないため実行することができないという意味です。
:::
　ROS2 を使用するためには、使用前に以下のコマンドを実行して ROS2 をシステムに反映させる必要があります。
```bash
source /opt/ros/humble/setup.bash
```
上のコマンド実行して、もう一度トピック一覧を表示するコマンドを実行してみましょう。
```
ros2 topic list
```
すると以下のような結果が表示されるでしょう。
```
/parameter_events
/rosout
```
この結果の意味は、`parameter_events` と `rosout` という名前のトピックが現在通信（発行）されていることを示しています。これで ROS2 を使用することができるようになりました。
　しかし、気を付けなければならないことがあります。今開いているシェルでコマンド `source /opt/ros/humble/setup.bash` を実行したとして、新たに開いた PowerShell 上で WSL に入って新規プロンプト上でROS2関連のコマンドを実行しても `ros2: command not found` が表示されてしまいます。新規プロンプトを開くたびに `source /opt/ros/humble/setup.bash` を実行してROS2 が使用できるようにしましょう。

 <a id="4-2"></a>
## 4.2. サンプルプログラムを実行してトピックの通信をしてみよう
　サンプルプログラムを実行して、ROS2 の Pub&Sub 通信に触れてみましょう。以下のコマンドを実行すると、ROS2 が用意しているサンプルプログラムを実行することができます。
```
ros2 run demo_nodes_cpp talker
```
::: note
### 確認
`source /opt/ros/humble/setup.bash` をしましたか？
:::

　このコマンドの意味を解説すると、**`demo_nodes` というパッケージにある `talker` というプログラムを実行します**
　ROS2 では `talker` のような１つのプログラムのことを <font color=blue>**ノード**</font> と呼びます。そして複数のノードをまとめたものを <font color=red>**パッケージ**</font> といいます。

---
サンプルプログラムを実行すると、このように以下のログが表示されます。
```
$ ros2 run demo_nodes_cpp talker
[INFO] [1727364205.649051866] [talker]: Publishing: 'Hello World: 1'
[INFO] [1727364206.649026192] [talker]: Publishing: 'Hello World: 2'
[INFO] [1727364207.649036919] [talker]: Publishing: 'Hello World: 3'
[INFO] [1727364208.648988946] [talker]: Publishing: 'Hello World: 4'
[INFO] [1727364209.649195972] [talker]: Publishing: 'Hello World: 5'
...
...
```
このままサンプルプログラムを実行しているシェルを放置して、新たなシェルを開きましょう。Windows 11 の場合、PowerShell 上のタブバーに **" + "** アイコンがあるのでこれをクリックしてください。すると新規タブが開いて新たな PowerShell が開きます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729782/6096e5f6-093a-3ffd-c381-246aaf7c5702.png" />

::: note
### Windows10 の場合
　Windows10 をお使いの場合、このタブ機能はありません。***「スタートメニュー」*** から PowerShell を新たに起動してください。
:::

　新規 PowerShell で WSL Ubuntu にログインし、`source /opt/ros/humble/setup.bash` を実行して ROS2 を反映させたら以下のコマンドを実行してください。
```bash
ros2 topic list
```
　すると、以下のような結果が表示されるでしょう。
```
/chatter
/parameter_events
/rosout
```
`ros2 run demo_nodes_cpp talker` を実行すると新たに **`chatter`** という名前のトピックが発行されているのがわかります。この発行されているトピックでどのようなデータが飛んでいるのか見てみましょう。
　発行されているトピック内のデータを参照するには、以下のコマンドを使います。
 ```
 ros2 topic echo <トピック名>
 ```
 ここでは `chatter` という名前のトピックを見たいので、以下のようなコマンドを実行します。
 　ここ気を付けなければならないのは、**トピック名の指定は必ず文頭に `/` を置く必要があります。** `ros2 topic echo chatter` と実行してもエラーが表示され、トピックを参照することができません。
 ```
 ros2 topic echo /chatter
 ```
 　実行すると、このようにトピック内のデータを見ることができます。
```
data: 'Hello World: 788'
---
data: 'Hello World: 789'
---
data: 'Hello World: 790'
---
data: 'Hello World: 791'
---
data: 'Hello World: 792'
---
data: 'Hello World: 793'
---
...
```
　このようにサンプルプログラムのログと比較するとリアルタイムでサンプルコードが発行しているトピックを受信していることがわかります。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729782/5b696aad-6ccc-8c47-08e8-bd3661adc92f.png" />

　このようにサンプルプログラム `talker` のように、トピックを発行するプログラムもといノードのことを <font color="red">**パブリッシャー（ $\text{Publisher}$ ：配信者）**</font> といい、パブリッシャーからのトピックを受信してトピックの中身を参照するプログラムもといノードのことを <font color="blue">**サブスクライバー（ $\text{Subscriber}$ ：購読者）**</font> といいます。
　今回コマンドを使いパブリッシャーからのトピックを参照しましたが、このようなトピックを購読、参照することを <font color="blue">**サブスクライブする（ $\text{Subscribe}$ する）**</font> といいます。一方トピックを配信することを <font color="red">**パブリッシュする（ $\text{Publish}$ する）**</font> といいます。
　今 `talker` というノードを実行してパブリッシャーを起動しています。そして先ほどはパブリッシュされているトピックをサブスクライブ（購読した）しましたよね。今度はパブリッシャーの対となるノード、サブスクライバーを実行してみましょう。サンプルプログラムでは `listener` というサブスクライバーノードがあります。以下のコマンドを **パブリッシャーが起動しているシェル以外のシェル** で実行してみましょう。
```bash
ros2 run demo_nodes_cpp listener
```
　`listener` ノードを実行すると、以下のようなログが表示されます。
```
[INFO] [1727366394.146037015] [listener]: I heard: [Hello World: 2088]
[INFO] [1727366395.146243695] [listener]: I heard: [Hello World: 2089]
[INFO] [1727366396.146081276] [listener]: I heard: [Hello World: 2090]
[INFO] [1727366397.145840356] [listener]: I heard: [Hello World: 2091]
[INFO] [1727366398.146166336] [listener]: I heard: [Hello World: 2092]
[INFO] [1727366399.145575416] [listener]: I heard: [Hello World: 2093]
[INFO] [1727366400.145775802] [listener]: I heard: [Hello World: 2094]
...
```
　このようにパブリッシャーからパブリッシュされているトピックをサブスクライブしていることがわかります。ためしにパブリッシャーノードを止めてみましょう。プログラムを停止するには、プログラムが動いているシェル上でキーボードショートカットキー **「Control + C」** を行います。普段ではこのショートカットキーはコンテンツをコピーするものですが、**プログラムが動作しているシェル上では動作しているプログラムを停止するショートカットとして機能します。**
　このように、「Control + C」を行われたタイミングで **`^C`** と表示され、プログラムが停止することがわかります。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729782/a47616e6-b1d2-e526-e534-2bb66993ada5.png" />

　パブリッシャーが停止すると、このようにサブスクライバーの更新も止まります。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729782/b952518d-08a7-8466-23b8-74c8d78b4764.png" />

<a id="4-3"></a>
## 4.3. サンプルプログラムを実行してトピックの通信をしてみよう（その２）
　もうちょっと発展的な作業に取り掛かりましょう。先ほどは `demo_nodes_cpp` というサンプルコードをまとめたパッケージを使い ROS2 の基礎に触れました。このサンプルパッケージ以外にももうひとつ **`turtlesim`（タートル・シム）** というサンプルパッケージがあります。
　以下のコマンドを実行して　**turtlesim** を起動しましょう。
```bash
ros2 run turtlesim turtlesim_node
```
　起動に成功すると、このようにカメが真ん中にいる画面が表示されます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729782/cbbe15d3-d896-695e-283f-eb4ec32c4839.png" />

::: note
ひとによって表示されるカメのデザインが変わります。カメのデザインは起動するたびにランダムに変わります。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729782/956313bc-26dd-9d6e-6099-1a02c244059a.png" width=200 /><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729782/0394ee52-3b37-fe05-323a-ef186c768c57.png" width=200 /><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729782/088d641d-3812-d45d-f7f5-593704cef2d7.png" width=200 />
:::
　別のシェルで現在パブリッシュされているトピックを見てみましょう。
```
ros2 topic list
```
すると、新たに **`turtle1`** から始まるトピックがいくつか表示されているのがわかるでしょう。
　ここで問題が発生します。現状 `ros2 topic list` コマンドを実行しただけでは、公開されているトピックがパブリッシュされているトピックなのかサブスクライブされることを期待しているトピックなのかがわかりません。
　どういうことかというと、前回は `talker` というノードを実行したら `chatter` という１つのトピックが公開されました。これは実行してわかる通りこのトピックは **明らかにパブリッシュされているトピック** だとわかります。しかしながら今回のように複数のトピックが飛ぶかう状況では **サブスクライブされることを期待しているトピック** というものが存在します。要はそのトピックを発行しているノードがそのトピックを通じてサブスクライブすることを期待しているわけですね。
 　作業を始める前にこのトピックの関係を特定してみましょう。方法として、現在起動しているノードの情報を取得してなんのトピックをパブリッシュし、なんのトピックをサブスクライブしているかを特定します。
　まず以下のコマンドを実行して現在どんなノードが起動しているのか確認しましょう。
```
ros2 node list
```
　実行するとこのようにノード名が表示されます。
```
/turtlesim
```
　紛らわしいことに `ros2 run turtlesim turtlesim_node` で `turtlesim_node` という名前のノードが表示されるはずですが `turtlesim` と表示されていますね。このようにコマンドで起動するノード名と `ros2 node list` で取得されるノード名が **必ずしも同じ名前であるわけではないので** 注意してください。ただ見てわかる通り明らかに `turtlesim_node` であることは名前の共通点で特定できますね。。。
　現在起動しているノード名を特定したところで以下のコマンドを実行してください。
```
ros2 node info /turtlesim
```
　このコマンドは `turtlesim` という名前のノードの情報を表示するコマンドです。このコマンドを実行すると、指定したノードが **どのようなトピックなどをパブリッシュ、サブスクライブしているか** がわかります。
 このコマンドの実行結果は以下のような構造になっています。
```
/turtlesim
  Subscribers:
    ...
  Publishers:
    ...
  Service Servers:
    ...
  Service Clients:
    ...
  Action Servers:
    ...
  Action Clients:
    ...
```
　今注目してほしいのは **`Subscribers`** と **`Publishers`** という項目です。この２つの項目の部分でなんのトピック名で購読しているのか、なんのトピック名でデータを発行しているのかがわかります。
　以下のノード情報は、前回実行した `talker` ノードの情報です。
```
/talker
  Subscribers:
    /parameter_events: rcl_interfaces/msg/ParameterEvent
  Publishers:
    /chatter: std_msgs/msg/String
    /parameter_events: rcl_interfaces/msg/ParameterEvent
    /rosout: rcl_interfaces/msg/Log
  Service Servers:
    /talker/describe_parameters: rcl_interfaces/srv/DescribeParameters
    /talker/get_parameter_types: rcl_interfaces/srv/GetParameterTypes
    /talker/get_parameters: rcl_interfaces/srv/GetParameters
    /talker/list_parameters: rcl_interfaces/srv/ListParameters
    /talker/set_parameters: rcl_interfaces/srv/SetParameters
    /talker/set_parameters_atomically: rcl_interfaces/srv/SetParametersAtomically
  Service Clients:

  Action Servers:

  Action Clients:
```
　見てほしいのは以下の部分です。
```
/talker
  Subscribers:
    /parameter_events: rcl_interfaces/msg/ParameterEvent
  Publishers:
    /chatter: std_msgs/msg/String
    /parameter_events: rcl_interfaces/msg/ParameterEvent
    /rosout: rcl_interfaces/msg/Log
```
　この部分の読み方を説明すると、ここでは

**購読しているトピック**
- $\text{/parameter_events}$

**配信しているトピック**
- $\text{/chatter}$
- $\text{/parameter_events}$
- $\text{/rosout}$

ということを示しています。これら一覧から、前回触れたトピック $\text{/chatter}$ の部分だけ切り抜いてみると、このような情報が書かれています。
```
  Publishers:
    /chatter: std_msgs/msg/String
```
　$\text{/chatter}$ という名前のトピックをパブリッシュしているんだなということはわかりますが、その横にある $\text{std_msgs/msg/String}$ とは何でしょうか？
　正解はそのトピックの **メッセージタイプ（型）** です。簡単に言うとそのトピックの形式を表していて、$\text{/chatter}$ というトピックは $\text{std_msgs/msg/String}$ という形式のデータである、つまり **文字列型** のデータをもつトピックであることを示しています。

::: note
$\text{String}$ （ストリング）とは日本語で **"文字列"** を意味します。
そして $\text{chatter}$ （チャッター）は日本語で **"おしゃべりする人"** を意味します。$\text{chat}$ の名詞形になりますね。
:::

---

　さて、話を戻して `turtlesim` ノードのサブスクライブトピックを見ると、$\text{/turtle1/cmd_vel}$ というトピックを購読することがわかるでしょう。このトピックは $\text{geometry_msgs/msg/Twist}$ というメッセージで構成されているのがわかります。この **`Twist`** 型のトピックは簡単に説明すると **ロボットを移動させるためのトピック** です。つまり、このトピックに値を入れることでロボットを動かすことができるのです。
　以下のコマンドを実行すると、このように画面上のカメが $\text{x}$ 軸方向に移動します。
```
ros2 topic pub /turtle1/cmd_vel geometry_msgs/msg/Twist "{linear: {x: 1.0}}"
```
<img src="https://i.imgur.com/uwmPujg.gif" />

　以下のコマンドのように、`x:` 以降の `1.0` を負の値にしてを実行すると、画面上のカメが $\text{x}$ 軸の負の方向に移動します。
```
ros2 topic pub /turtle1/cmd_vel geometry_msgs/msg/Twist "{linear: {x: -1.0}}"
```
<img src="https://i.imgur.com/Ql8Q4xz.gif" />

　以下のコマンドのように `x:` を `y:` に変更することで、、このように画面上のカメが $\text{y}$ 軸方向に移動します。
```
ros2 topic pub /turtle1/cmd_vel geometry_msgs/msg/Twist "{linear: {y: 1.0}}"
ros2 topic pub /turtle1/cmd_vel geometry_msgs/msg/Twist "{linear: {y: -1.0}}"
```
<img src="https://i.imgur.com/eaCk9r9.gif" />

　このように、`x:` と `y:` を同時に指定してパブリッシュすることもできます。それぞれの値を変えるとカメの動きが変化します。
```
ros2 topic pub /turtle1/cmd_vel geometry_msgs/msg/Twist "{linear: {x: 1.0, y: 1.0}}"
```
<img src="https://i.imgur.com/50uKl6y.gif" />

**`linear`** を **`angular`** に変更し、`z:` に任意の値をいれて実行するとカメが旋回します。
```
ros2 topic pub /turtle1/cmd_vel geometry_msgs/msg/Twist "{angular: {z: 1.0}}"
```
<img src="https://i.imgur.com/lhW0cmg.gif" />


**`linear`** と **`angular`** 両方の値を入れて実行するとカメが複数のベクトルに対応した動作を行います。ここでは `linear: x:` と `angular: z:` に値をいれるとカメが円を描きます。。
```
ros2 topic pub /turtle1/cmd_vel geometry_msgs/msg/Twist "{angular: {z: 1.0}}"
```
<img src="https://i.imgur.com/ag3rZ9S.gif" />

::: note
### `geometry_msgs/msg/Twist` を扱うときに気を付けること
　$\text{geometry_msgs/msg/Twist}$ 形式のトピックにコマンドからデータをパブリッシュするとき、以下のようにフィールドの記述に気を付けてください。**フィールドと値の間に半角スペースがないとエラーになります。**

 - **正しいメッセージの書き方**
    以下のコマンドのようにフィールド `z:` と値 `1.0` の間に半角スペースがあるとうまくいきます。
```
ros2 topic pub /turtle1/cmd_vel geometry_msgs/msg/Twist "{angular: {z: 1.0}}"
```
 以下のコマンドのようにフィールド `angular:` と値 `{z: 1.0}}` の間に半角スペースがあるとうまくいきます。
```
ros2 topic pub /turtle1/cmd_vel geometry_msgs/msg/Twist "{angular: {z: 1.0}}"
```
 - **正しくないメッセージの書き方**
    以下のコマンドのようにフィールド `z:` と値 `1.0` の間に半角スペースがないとエラーが出ます。
```
ros2 topic pub /turtle1/cmd_vel geometry_msgs/msg/Twist "{angular: {z:1.0}}"
```
以下のコマンドのようにフィールド `angular:` と値 `{z: 1.0}}` の間に半角スペースがないとうまくいきません。
```
ros2 topic pub /turtle1/cmd_vel geometry_msgs/msg/Twist "{angular:{z: 1.0}}"
```
```
Failed to populate field: 'Vector3' object has no attribute 'z:1.0'
```
:::

<a id="4-4"></a>
## 4.4. チャレンジしてみよう
　今日学んだことをうまく活用して以下の作業に挑戦してみてください！

- `/turtle1/cmd_vel` トピックをパブリッシュして速度 $\text{0.5}$ で斜め右下へカメを動かす
- `/turtle1/cmd_vel` トピックをパブリッシュして速度 $\text{0.1}$ で反時計回りにカメを動かす。このとき **円を描くこと**。
- トピック `/turtle1/pose` の使い方を調べてみましょう。

<a id="fin"></a>
# おわりに
　この記事では

 - PowerShell の開き方
 - WSL のインストール方法と使用方法
 - WSL Ubuntu の起動方法とセットアップ方法
 - ROS2 のインストール方法
 - ROS2 の基礎的な使用方法
 - ROS2 の用語とその意味について

を学びました。この記事だけ読んで知識を付けるのではなく、ここで学んだことをさらに深堀するためにほかのサイトなどで検索をかけて調べて、**自己解決能力** を高めることがとても大事です。皆さん。これからもロボット開発を頑張ってください！