ヴェズルフェルニルの研究ノート

座右の銘「ただ一人犀の角のように歩め」的な研究活動ノート

stella_vslam | Dockerによるビルドと動作確認〔Mac編〕

前記事で行ったDockerによるstella_vslamのビルドを動作確認をMac上でもやってみた。

blog.ketus-ix.work

結論から先に書くと、PangolinViewer版stella_vslamはビルドはできるが動作させることはできなかった。

stella_vslamのドキュメントサイトにもMacはNGだと記載されている。

stella-cv.readthedocs.io

SocketViewer版stella_vslamはビルドも動作確認も問題なくできる。ただし、Dockerコンテナの起動方法がUbuntuの場合とは異なっている。

PangolinViewer版stella_vslamはNGだが、記録として、作業内容を書いておく。

PangolinViewer版stella_vslamのビルドと動作確認

Dockerイメージのビルド

前記事のコマンドによって、PangolinViewer版stella_vslam Dockerイメージのビルドは問題なくできる。

ただし、Docker Engineのメモリ・リソース制限をデフォルト値より大きくしておく必要がある。Docker Desktopの場合は、下の画面からその設定値を変更できる。

おおよそ14GB以上なら、本Dockerイメージをビルドできるようだ。

Dockerコンテナの起動

当然ながら、ビルド生成したDockerコンテナの起動は問題なくできる。本コンテナを起動するコマンドは前記事と同じ。

Dockerコンテナの動作確認

PangolinViewer版stella_vslamはX GUIを利用しているプログラムなので、MacにもX Window Systemが必要だ。MacX Window System XQuartzがインストールされていることが前提条件となる。

X GUI利用DockerコンテナをMac上で起動する方法が下のリンクにまとめられている。

blog.aoirint.com

このページに記載されているすべての方法を試したが、ダメだった。

コンテナ内のstella_vslamプログラムがホスト側Xディスプレイの存在を認識できても、ほとんんどのケースで下のようなエラーが出力されて停止してしまう。

libGL error: No matching fbConfigs or visuals found
libGL error: failed to load driver: swrast
X11 Error: BadValue (integer parameter out of range for operation)
terminate called after throwing an instance of 'std::runtime_error'
  what():  Pangolin X11: Failed to create an OpenGL context

MacOpenGLリダイレクトを有効にする下のコマンドを実行済みの状態でもダメだ。

% defaults write org.macosforge.xquartz.X11 enable_iglx -bool true

もしかすると、stella_vslam側で使われているOpenGLMac側の同バージョンが関係しているのかもしれない。

上の参照ページに記載されている各方法を試した際のstella_vslamプログラムの挙動を観ていると、「socatを使う方法(UnixソケットをTCPにリレーする方法)」が上手くいく可能性が高そうな感触はあるんだけど。

DockerコンテナのXディスプレイ出力先をMacホストではなく仮想マシンなどの他のPCへリダイレクトすると動くかもしれないが、それではMac上で動いているとは言えないだろう。

また時間があったら、本問題にトライしてみようと思っている。

SocketViewer版stella_vslamのビルドと動作確認

Dockerイメージのビルド

前記事のコマンドによって、SocketViewer版stella_vslam Dockerイメージ(stella_vslam本体とsocket-viewer)のビルドは問題なくできる。

Dockerコンテナの起動

socket-viewer

% docker run --rm -it --name stella_vslam-viewer -p 3001:3001 stella_vslam-viewer
WebSocket: listening on *:3000
HTTP server: listening on *:3001

Macでsocket-viewerを起動する場合は、-p 3001:3001オプションを付加してコンテナを起動する。これは、DockerコンテナのTCPポートをホスト側へポートフォワードする設定だ。

ここで、Webブラウザからhttp://localhost:3001/へアクセスする。

そして、socket-viewerコンテナが起動している状態で下のコマンドを実行する。

% docker inspect stella_vslam-viewer | grep -m 1 \"IPAddress\" | sed 's/ //g' | sed 's/,//g'
"IPAddress":"172.17.0.2"

このコマンドによって、socket-viewerコンテナのIPアドレスを知ることができる。

stella_vslam本体

stella_vslam本体コンテナは以下のコマンドによって起動する(--net=hostオプションは不要)。

% docker run --rm -it --name stella_vslam-socket \
    --volume ~/VSLAM/Docker/stella_vslam/vocab:/vocab:ro \
    --volume ~/VSLAM/Docker/stella_vslam/dataset:/dataset:ro \
    stella_vslam-socket
root@f3eb6409feb7:/stella_vslam_examples/build# 

Dockerコンテナでの動作確認

stella_vslam本体コンテナ(stella_vslam-socket)が起動したら、下のコマンドを実行する。

  • コンテナ stella_vslam-socket
# ls /
bin   dataset  etc   lib    lib64  ...   ...   ...   stella_vslam           sys   usr   vocab
...   ...   ...   ...   ...  ...   ...   ...   ...   stella_vslam_examples  tmp   var
# echo -e "SocketPublisher:\n  server_uri: \"http://172.17.0.2:3000\"" >> /stella_vslam/example/aist/equirectangular.yaml
# cat /stella_vslam/example/aist/equirectangular.yaml
....    ....
....    ....
SocketPublisher:
  server_uri: "http://172.17.0.2:3000"

これは、stella_vslamのコンフィグレーションファイルにsocket-viewerコンテナ(stella_vslam-viewer)のURIIPアドレスとWebSocketサーバーのポート番号)設定値を追加している。

上の操作が済んだら、同コンテナ内でstella_vslamプログラムを起動すれば、Webブラウザのウィンドウにグラフィック描画画面が表示されるはずだ。

  • コンテナ stella_vslam-socket
# At the /stella_vslam_examples/build directory
# pwd
/stella_vslam_examples/build
# ls /
bin   dataset  etc   lib    lib64  ...   ...   ...   stella_vslam           sys   usr   vocab
...   ...   ...   ...   ...  ...   ...   ...   ...   stella_vslam_examples  tmp   var
# ./run_video_slam \
    -v /vocab/orb_vocab.fbow \
    -m /dataset/aist_living_lab_1/video.mp4 \
    -c /stella_vslam/example/aist/equirectangular.yaml \
    --frame-skip 3 \
    --no-sleep \
    --map-db-out map.msg \
    --viewer socket_publisher

-cオプションで指定するコンフィグレーションファイルは、上記の操作で書き換えたものでなければならない。