VSCode+Docker+ROSで開発環境を構築する

こんにちは、@ryu_softwareです。普段は業務で自律移動ロボットのソフトウェアをいじってます。
以前のアドベントカレンダーで[こんなの](https://qiita.com/ryu_software/items/d13a70aacfc6a71cacdb)書きました。久しぶりの参加になります。

今回は僕が普段使ってる開発環境について、皆さんにとって参考になるかどうかは微妙かもしれませんが構築方法と使い方についてのメモを残そうと思います。


# 開発環境について
最近kineticやらmelodicやら、ROS2やらなんやらでいろんな開発環境を用意しなきゃいけなくてそうしてると自分のPCの環境を汚しかねない(最悪ぶち壊す)なぁと思っていて、色々テストしたりちょっと開発する時に必要な複数の開発環境をDockerを用いて使い分けていました。Dockerfileを分けておけばローカルの環境を汚さずに色々テストできるので結構便利でした。
僕は普段の開発において、最近Visual Studio Codeを使用していて、Remote Containerという拡張機能をセットで用いることで、立ち上げたDockerコンテナにアタッチしてコンテナ内のフォルダにVSCodeからアクセスができるようになるので、VSCode+Dockerをセットで使用するとホストマシンの環境を特にいじることなく、Docker単体で使用していると割と困るエディタやUI周りも困らずに普通に開発出来ます。
<img width="634" alt="スクリーンショット 2019-12-12 20.29.51.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60952/09862787-ec0c-e867-2d6c-050bf1f4546d.png">

# 環境構築
## VSCode Insiderのインストール及びRemote Containerのインストール
Visual Studio Codeとは別で、Visual Studio Code Insidersというのがあります。Insiders版は通常のStable版と違い、先行機能などが試せるバージョンらしいです。Remote Containerを使用しようとした時にStable版だとうまくできず、Insiders版を使用したらうまくいったので今回こちらを使用します。
通常版とInsiders版は別々にインストールし、設定ファイルや拡張機能なども別々で管理することが可能なので、用途で使い分けることが可能です。以下のサイトでdebファイルを落としてインストールしてください。
https://code.visualstudio.com/insiders/

インストールが完了したら、Remote Containerをインストールします。左側タブのExtensionsの検索窓から「Remote Development」と入力し、一番上に来たものをインストールしてください。これで完了です。

## テスト
実際にDockerコンテナを立ち上げてVSCodeからファイルを開いてみます。今回choreonoid_ros_pkgを使用するためのDockerfileを用意したので、そちらを使いテストしてみます。テストに使用したホストのマシン環境はubuntu 16.04、nvidia-docker2を使用しています。引っ張ってきているDockerイメージはCUDA9.2入りのubuntu16.04ですがここに関しては各々の環境に合わせて修正した上で使用します。

```
$ git clone https://github.com/RyuYamamoto/choreonoid_ros_docker -b kinetic
```
以下のコマンドでDockerfileをビルドします。

```
$ cd choreonoid_ros_docker
$ docker build -t ros_test .
```
初回は暫く時間がかかります。のんびり待ちましょう。  
ビルドが完了したら、実際に起動してみます。まずはホストのマシンでVSCode Insidersを立ち上げます。次にVSCode Insider上のターミナルを立ち上げ(VSCode上じゃなくても大丈夫です)、Dockerコンテナを立ち上げます。

```
$ ./run.sh
```

次に立ち上げたDockerコンテナにVSCodeから接続します。左下に以下のようなアイコンがあると思います。
<img width="292" alt="スクリーンショット 2019-12-12 18.13.21.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60952/b00835b5-81f1-53b8-b0e5-af06ba559ec7.png">
こちらをクリックすると上部にいろいろ出てきます。この中から「Remote-Containers: Attach to Running Container...」を選択し、先ほど立ち上げたDockerコンテナを指定すると新規でWindowが立ち上がり、接続が始まります。初回は少し時間がかかります。
![Screenshot from 2019-12-12 15-13-31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60952/a4f6c29f-0db0-0ebe-0ec2-2aae79f1eea5.png)
接続が完了すると左側のタブにOpen Folderとありますので、そちらをクリックするとコンテナ内のフォルダを選択できるようになります。僕はここでcatkin_ws/srcを選択して開いています。この時点で自由にコンテナ内のファイルを編集することが可能になります。ROSの拡張プラグインを入れていれば、ビルドやlaunchファイルの起動も容易にできるようになります。
catkin buildを行いたい場合は、Ctrl+Shift+bを押すと上部に「catkin: make」と出てくるので選択するとターミナルが立ち上がり、catkin buildが実行されます。rosrunやroslaunchに関してはコマンド入力の方が圧倒的に早いのでそっちでやりましょう。試しにターミナルを立ち上げてchoreonoidを起動するlaunchファイルをコマンドにより起動してみます。

```
$ roslaunch choreonoid_ros choreonoid.launch
```
choreonoidが立ち上がればOKです。
![Screenshot from 2019-12-13 07-51-33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60952/6a088a67-41ab-2369-62fd-8c49a5e662f7.png)
  

立ち上がらない場合はnvidiaドライバーが入ってないとか、使用するDockerイメージのCUDAのバージョンが違うとかだと思うので確認してみてください。

僕は普段はコンテナ内でVSCodeを立ち上げたらその中でターミナルを立ち上げ、ROSのコマンド実行やらなんやらをその中で行なっています。複数ターミナルの管理に関してはtmuxを使って管理したりしています。
またcatkin buildやノード、launchファイルの実行など、VSCodeのROSプラグインをインストールしていればコマンドを叩かないでも実行することが可能になります([こちら](https://opensource-robotics.tokyo.jp/?p=3007)を参照)。

## まとめ
とりあえず僕の普段の開発環境についての話を書いてみました。まぁ使いやすいかどうかはおいてといて、それぞれDockerfileを用意すればROS2でもその他のものもPCの環境を汚さずに動かせて、VSCodeを併用することにより開発・デバッグも全てコンテナ及びエディタ上で比較的快適にできたので個人的には割といいかなと思ったりしています。

### メモ
今回Dockerコンテナはターミナルから立ち上げ、VSCode上からコンテナにアタッチして使用する、という手順で行いましたが、Dockerコンテナ自体ももちろんRemote Containerの機能で立ち上げることができます。ただGUIを使う場合、xhost等の設定が必要になるかと思うんですがその設定がRemote Containerの設定ファイルで出来ず、GUIを使う場合はターミナルからシェルスクリプトを叩いて起動しています。何か方法があるのか...。