Docker+ROSの環境をWindows10PROで整える


書いた理由

Docker+ROSで開発する人は多くいて、懇切丁寧なチュートリアルがDockerHubのROSのリポジトリにも書いてありますが、私のようにまったくDocker使ったことない人には、Dockerの使い方やコマンドからメモっておかないと使えません(泣)
3日経ったらやり方を忘れてしまうと思って備忘録代わりに書いておきます。

環境

Windows10Pro
HomeエディションではHyperVを使用できなかったため、アップグレードして使用しました。

想定する使い方

WindowsのDockerコンテナにハードウェアをマウントすることは2020/01/26現在は無理のようです。
WindowsPCとJetson-nanoを無線LANでつなぎ、ハードウェアの集まるJetson-nanoとROSでデータを交換しながら開発する。
最終的にはJetson-nano単独で動かしますが、開発だけでも大きなPCでできれば楽ができます。

Docker+ROSの環境で開発したい

Jetson-nanoにつないだ小さなディスプレイで開発するのが大変になってきたので、Windows10をProにアップグレードしてDocker DeskTopを使うことにしました。
DonkeyCar用にAnacondaの環境が入っているので、競合を回避するのが目的です。
また、DockerHubのリポジトリを持ってくることで環境構築の負担を減らすのが目的です。
もともと仮想マシンでUbuntuを入れてみましたが、うまく動かないのでDockerに宗旨替えしました。

Docker Desktopのインストール

https://www.docker.com/products/docker-desktop
公式のマニュアルに沿ってインストールします。
Windows10Proじゃないと、HyperVが動かないので使えません。
HyperVを有効にして再起動したらあっさり動きました。
GUIでDockerHubのユーザーIDとかを設定しておきます。

ROSのイメージをPULLしてみる

適当なディレクトリを作って、コマンドを開いて、
docker pull ros
これでDockerHubからROSのリポジトリを引っ張れました。
バージョンを指定するときは、
docker pull ros:melodic
とかするとOK。

ROSのイメージの中で作業する

docker run -it --name test ros
pullしたコンテナイメージを動かし、コンテナの中で作業できます。

-it コンテナのSTDINにアタッチし疑似ターミナルを割り当て
-name ホスト名を決めてコンテナ起動

ROSコンテナにtoolをインストール

catkin buildが動かないので、ツールは公式イメージに入っていないらしいです。
コンテナの中でツールをインストールします。
sudo apt install python-catkin-tools
では何故かインストールできなかったので、apt-getを使いました。

ROS
sudo apt-get update
sudo apt-get install python-catkin-tools

で、セットアップ完了。

ROS
mkdir -p catkin_ws/src/
cd ..
catkin build

これでパッケージのビルドができるようになりました。

exit で抜けることができます。抜けてもコンテナは動作している状態です。
再度、開始とアタッチをするなら

command
docker start test
docker attach test

コンテナイメージのバックアップ

exitした後、タグをつけてイメージを保存します。

command
docker commit test ros:ros-test

このタグを使って新しいイメージを起動します。名前は先ほど使ったtestを使うとコンテナ名が重複するのでNG。

command
docker run -it --name build ros:ros-test

DockerHubにリポジトリを登録する

DockerHubに保存するため、新しいリポジトリを作成します。
docker commit build tkumazawa/ros:build と打ち込んで実行し、イメージを確認します。
tkumazawaは私のDocker HubのIDです。rosがリポジトリ名。buildがタグです。タグはver1.0などとしたほうがいいかもしれません。

command
> docker commit build tkumazawa/ros:build
> docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
tkumazawa/ros       build               2ff967da7a65        30 seconds ago      1.28GB
ros                 ros-build           2edba62b8053        22 hours ago        1.28GB

整ったらDockerHubにPUSHします。

command
>docker push tkumazawa/ros
The push refers to repository [docker.io/tkumazawa/ros]
8493815d0ca4: Pushed
372ede2259c3: Pushed
9e4af5cbf92b: Pushed
5d0ac2ca4dca: Mounted from library/ros
b0264d2ecd66: Mounted from library/ros
dc1e02c4e5b2: Mounted from library/ros
93928f93457b: Mounted from library/ros
95c9f2e4b310: Mounted from library/ros
5dfc22a79953: Mounted from library/ros
deb603bf064b: Mounted from library/ros
f5a315154171: Mounted from library/ros
55388b609b06: Mounted from library/ros
f55aa0bd26b8: Mounted from library/ros
1d0dfb259f6a: Mounted from library/ros
21ec61b65b20: Mounted from library/ros
43c67172d1d1: Mounted from library/ros
build: digest:

これでDockerで整えた環境をDockerHubに保存してバックアップすることができます。

実際にDocker+ROSで動かす方法はここを参考にしました。
Docker + ROS(kinetic)でチュートリアル

コンテナの削除がめんどくさい

やっているうちに大量のコンテナとイメージがメモリを圧迫しています。
ROSのコンテナが複数起動しているので、どうにもなりません。
で、「Docker実践入門」という本を教科書にしてますが、bashだと
docker rm $(docker ps -qa)で済むんですよね?
Windowsで同じことやろうとしたら、

command
#停止中コンテナの全消去
for /f "usebackq" %x in (`docker ps -aq`) do docker rm %x
#起動中コンテナも停止中コンテナも全消去
for /f "usebackq" %x in (`docker ps -aq`) do docker rm -f %x
#未参照のイメージを全消去
for /f "usebackq" %x in (`docker images -q`) do docker rmi %x

参考にしたのはこちら。
WindowsのDockerで溜まったコンテナやイメージを削除する

コンテナを消し終わったら、タグ付きでコミットしたイメージを消去。
怖いので一個ずつ消す。
docker rmi ros:ros-test
これやったら根っこから全部消える。もう一回、DockerHubからとってくるならOK。
docker rmi ros

VSCodeでDockerコンテナにリモート接続する

編集するときにいちいちエディタをコンテナにインストールするのが面倒だと思っていたらVSCodeにRemote Containersなる拡張を発見。
microsoft/vscode-remote-release

インストールして左下の隅っこをクリックするとメニューが開くので、Remote-Containers: Attach to running Container で接続したい対象を選択できます。
まず、先ほどDockerHubにpushしたイメージからコンテナを起動します。
docker run -it --name ros-wk tkumazawa/ros

先ほど立ち上げたros-wkを選択すると、新しいVSCodeのウィンドウが立ち上がるので、フォルダを選択して起動。
確かに中身が見えます。

GitHubからコンテナの中にリポジトリをcloneする

githubから編集中の自分のROSのパッケージをcloneします。
https://github.com/kumaxxp/ros_rc_package.git
これで、コンテナの中にgithubの内容を取り込んで編集できそうです。
ただし、GitHistoryやGitLensは無効で動きませんでした。なにか制限がかかっているようです。
VSCode標準のgit機能は問題なく使えます。githubへのpushもできますが、いちいちパスワードとIDを打ち込むのは面倒ですね。
かといってしょっちゅう生成と削除を繰り返す前提のコンテナイメージのssh-keyを登録するのもどうかと思いますので、その辺りは悩ましいところです。
とりあえずcatkin buildしてみます。

ROS
# catkin build
----------------------------------------------------
Profile:                     default
Extending:             [env] /opt/ros/melodic
Workspace:                   /root/catkin_ws
----------------------------------------------------
Build Space:        [exists] /root/catkin_ws/build
Devel Space:        [exists] /root/catkin_ws/devel
Install Space:      [unused] /root/catkin_ws/install
Log Space:          [exists] /root/catkin_ws/logs
Source Space:       [exists] /root/catkin_ws/src
DESTDIR:            [unused] None
----------------------------------------------------
Devel Space Layout:          linked
Install Space Layout:        None
----------------------------------------------------
Additional CMake Args:       None
Additional Make Args:        None
Additional catkin Make Args: None
Internal Make Job Server:    True
Cache Job Environments:      False
----------------------------------------------------
Whitelisted Packages:        None
Blacklisted Packages:        None
----------------------------------------------------
Workspace configuration appears valid.
----------------------------------------------------
[build] Found '1' packages in 0.0 seconds.
[build] Updating package table.
Starting  >>> ros_rc_package
Finished  <<< ros_rc_package                [ 4.5 seconds ]
[build] Summary: All 1 packages succeeded!
[build]   Ignored:   None.
[build]   Warnings:  None.
[build]   Abandoned: None.
[build]   Failed:    None.
[build] Runtime: 4.5 seconds total.
[build] Note: Workspace packages have changed, please re-source setup files to use them.

とりあえず、パッケージは問題なくbuildできたみたいです。
pythonで記述したものは実行するとエラーが確実に出るのでここでは動かせない

ROS
# . ~/catkin_ws/devel/setup.bash
# rospack list
...
ros_rc_package /root/catkin_ws/src/ros_rc_package
...

setupの後、パッケージのリストを出力させると、パッケージは登録されていました。

続くかも

Dockerを使った機能の作成方法を、全部メモしてみました。
記述したコマンドをアレンジして使えば、とりあえずWindowsでDocker+ROS開発は問題なく実施できるかと思われます。