🪄

クラウドサーバーで物理エンジン環境設定忘備録1

に公開

最近、ロボティクス関連論文の実装コードを動かそうとしたのですが、手元の4GBVRAMではこころもとないため、GOOGLE COLABも検討しましたが、PYTHONやCUDAのVERSIONなども論文とほぼ近い環境で安定させたかったため、AWS EC2環境にpyenv(論文の実装コードではcondaを使うことのほうが多いようですが)にいれました。そして動かすとエラーがでてきます。私はUbuntu24.04でクラウド環境(AWS EC2)です。

RuntimeError: Create window failed: Renderer does not support display.

つまり render_human() が X11 付きのウィンドウを開こうとしたけど、Ubuntu 24.04 の headless サーバ(GUI なし)ではディスプレイが無いためクラッシュしています。

なので以下のパッケージをいれました。

# apt install libgl1 libglvnd0 libegl1 libgles2 libopengl0
# apt install libglu1-mesa libxext6 libx11-6 libxcb1 libxau6 libxdmcp6

これでこれで PyBullet, MuJoCo, ManiSkill, RoboFactory 系の OpenGL/EGL 依存はだいたい解決しするはずで、HEADLESSで動作して上記エラーは解消ですと思いきやまた同じエラー!

よくよく調べるとこのコードはManiSkillを利用しており、ManiSkill / SAPIEN には GUI なしレンダリングのモードがあります。
この場合、PYTHONコード内でrender_human() が使われていると GUI ウィンドウを開てしまうようです。一方、render() や render(mode="rgb_array") は EGL/OpenGL offscreen で動くそうなので
ソースコード側の該当箇所を修正しないといけない。面倒だなー!、それが原因で別の問題誘発しないかなど何とかソースコード改修は回避したかったので、仮想DISPLAYを使う方法があるようでした!

# apy install xvfb

よしこれで

xvfb-run -s "-screen 0 1024x768x24" python [your PYTHON CODE]

これでエラーは解決でめでたし、めでたしなのですが、少し物足りません。DISPLAYがあればシミュレーション下見えるのだけれども、ここではそれが見えません。VNCなどで仮想DISPLAYにアクセスする方法もあるらしいのですが、今回はインターアクティブにコマンド物理エンジンシミュレーター上でこちらからコマンドだすだけではないのでとりあえず動きだけ見たいだけでしたので動画として保存できないか考えました。(またインターアクティブにやる場合はどうしても仮想DISPLAYを直接アクセスできないと厳しいのでその方法は別記事で書きます。)

画像、音声、動画などの操作に優れたffmpegというライブラリーをインストールします。

# apt install ffmpeg

しして以下のBASHに仮想DISPLAYを用意してその録画をffmpegにさせるようにしその中で先ほどにpythonを実行するものをBASHとしてまとめます。

OUT="/tmp/lift_barrier_$(date +%Y%m%d_%H%M%S).mp4"
mkdir -p /opt/records
# 仮想ディスプレイ起動(1280x720, 24bit)
Xvfb :99 -screen 0 1280x720x24 &
XVFB_PID=$!
export DISPLAY=:99
# 画面録画を開始(フレームレート30, H.264で保存)
ffmpeg -y -f x11grab -draw_mouse 0 \
  -video_size 1280x720 -framerate 30 -i :99.0 \
  -vcodec libx264 -pix_fmt yuv420p -preset veryfast -crf 23 \
  "$OUT" &
FFMPEG_PID=$!
# 実行(可視化コマンド)
python [you PYTHON 可視化コード] 
# 録画停止&後片付け
kill -INT $FFMPEG_PID
wait $FFMPEG_PID
kill $XVFB_PID
echo "Saved: $OUT"

一応動きがMP4で保存されてます。

シミュレーション画面から入力としてコマンドを送るなどが必要になるとやはりどうしてもDISPLAYにはアクセスが必要になりますが、クラウドのLINUX系のサーバーにはデフォルトでは設定がないのでDISPLEYにアクセスするとこまで記述します。
https://zenn.dev/takeofuture/articles/d1fa352e1d3bd8

Discussion