CQ出版のオフ会でSLAMの話でもりあがったので、ORB-SLAM2をdockerで動かせるようにしてみました。
動作環境
PC:VirtualBox 5.2.16
ホストOS: Ubuntu 18.04 LTS Bionic Beaver
導入方法
■ リポジトリをclone します。
git clone https://github.com/ft28/dockernized_orb_slam2.git
cd dockernized_orb_slam2
git submodule update --init --recursive
■ ユーザ設定と、X設定のための環境変数を.bashrc に追加します。
# docker 上で現在のユーザーとグループを使うための設定
export USER_ID=`id -u`
export USER_NAME=`id -nu`
export GROUP_ID=`id -g`
export GROUP_NAME=`id -ng`
# docker 上でx-window を使うための設定
export XSOCK=/tmp/.X11-unix
export XAUTH=/tmp/.docker.xauth
touch $XAUTH
xauth nlist $DISPLAY | sed -e 's/^..../ffff/' | xauth -f $XAUTH nmerge -
■ 設定を反映します。
source ~/.bashrc
■ イメージを作成します。
docker-compose build orb_slam2_ros
■ コンテナを起動します。
docker-compose run orb_slam2_ros
コンテナの仕様
ホストの orb_slam_ros_home 以下を docker 環境内のhomeに、ORB_SLAM2 以下を home 直下にマウントしています。
初めて起動するときに、ROS 環境の初期化とORB_SLAM2のコンパイルを行います。 catkin_ws 以下のファイルをすべて削除すると、再度 ROS環境の初期化とORB_SLAM2のコンパイルが実行されます。詳しくは、entrypoint.sh を参照してください。
docker-compose.ymlでは、実験データは、ホストの/opt/data 以下にあると想定しています。他の場所に置く場合は、docker-compose.yml を修正してください。
サンプルデータ取得
EuRoC Dataset からテスト用にデータをダウンロードします。
# ROS実験用
wget -c http://robotics.ethz.ch/~asl-datasets/ijrr_euroc_mav_dataset/machine_hall/MH_01_easy/MH_01_easy.bag
# 非ROS実験用
wget -c http://robotics.ethz.ch/~asl-datasets/ijrr_euroc_mav_dataset/machine_hall/MH_01_easy/MH_01_easy.zip
ダウンロードしたデータをホストの/opt/data 以下に保存します。zipファイルは解凍しておきます。
ls /opt/data
MH_01_easy.bag mav0
サンプルデータ実行
コンテナ起動します。
docker-compose run orb_slam2_ors
非ROS実行
ORB-SLAM2では、ROSに依存することなく実行することが可能となっています。今回のDockerfileでは、ROS関連パッケージをインストールしていますが、OpenCVとpangolinだけインストールすればORB-SLAM2を動かすことができます。
cd ORB_SLAM2
./Examples/Stereo/stereo_euroc ./Vocabulary/ORBvoc.txt ./Examples/Stereo/EuRoC.yaml /opt/data/mav0/cam0/data /opt/data/mav0/cam1/data ./Examples/Stereo/EuRoC_TimeStamps/MH01.txt
ROS実行
tmux で複数ウィンドウを開いてROSを実行します。xtermを使っても問題ありません。
cd ORB_SLAM2
tmux
# ウィンドウ1でroscore 実行
roscore
# ウィンドウ2でORB_SLAM実行
rosrun ORB_SLAM2 Stereo Vocabulary/ORBvoc.txt Examples/Stereo/EuRoC.yaml true
# ウィンドウ3でbagファイル再生
rosbag play --pause /opt/data/MH_01_easy.bag /cam0/image_raw:=/camera/left/image_raw /cam1/image_raw:=/camera/right/image_raw
ROSの場合も同様に、pangolinで作成された2つの画面が起動します。
web カメラを使ったサンプル
cd ORB_SLAM2
tmux
# ウィンドウ1でroscore 実行
roscore
# ウィンドウ2でORB_SLAM実行
rosrun ORB_SLAM2 Mono Vocabulary/ORBvoc.txt Examples/Stereo/EuRoC.yaml true
# ウィンドウ3でweb カメラ再生
roslaunch ../camera.launch
camera.launch は使っているweb カメラによって修正が必要です。また、EuroC.yml については、使っているカメラのキャリブレーション結果と置き換える必要があります。
発生した問題
OpenGL問題
ホストのX環境が nvidia のドライバで動いている場合に、OpenGLを含むアプリケーションを動かすには、別の方法が必要なようです。
/dev/video0 のパーミッション問題
ホストの /dev/video0 のパーミッションが root:videoなのにdocker上のパーミッションが root:rootになってしまうという問題がありましが、dockerのバージョンを18.06.0-ce にアップデートすることで解決しました。
docker-compose で複数グループ指定
ユーザをvideo グループに所属させたかったのですが、
user: ${USER}:${GROUP}
で指定してしまうと、ホスト上のプライマリグループにしか所属させることができませんでした。docker-compose.yml に add_group オプションを追加すると解決したのですが、docker-compose.ymlでversion 3の場合、この記述はエラーになってしまいます。このため、docker-compose.ymlのversionを2にしています。
guvcview エラー問題
web カメラを docker 上で使えるか確認するためのコマンドとして、guvcview を使っていたのですが、coreを吐いて死んでしまうという問題が置きました。dockerの実行ユーザーをrootにすると動くようになるので、パーミッション関係の問題だと思うのですが、原因はわかりませんでした。
まとめ
dockerでXアプリケーションも動かせることを知って驚きました。デバイス依存が強い場合に、dockerで仮想化する意義がどのくらいあるか少し疑問はありますが、dockerの活用範囲が広げられそうです。
参考リンク
ORB-SLAM2 公式
https://github.com/raulmur/ORB_SLAM2
@nnn112358 さんqiita記事
ROSのORB_SLAM2を動かしてみた。
@Leonardo-mbc さんqiita記事
Docker + ROS(kinetic)でチュートリアル