目次: OpenPilot
最近はOSSの運転支援ソフトウェアOpenPilotのコードを見ています。今日はOpenPilotのビルドと実行方法について調べます。ソースコードはGitHubから入手できます(リンク)。
OpenPilotは全自動運転とはいかないまでもADAS+αの機能を実現するシステムです。OpenPilot用のデバイスが市販されており、既存のADASシステム搭載車のCAN通信回線に割り込ませる形で後付します。自動運転レベルでいえばレベル2(常に人間が見ている前提)だと思います。突然止まっても害はありませんし、OpenPilotがおかしな制御信号を出しても既存ADASシステムが受け付けないはずです。たぶん……。
ソースコードの他にUbuntuの環境、Pythonの環境のセットアップが必要です。私はDebian Testingで試しましたが、特にこだわりがなければUbuntu 24.04 LTSを使うと良いと思います。
$ cd openpilot $ git submodule update --init --recursive $ ./tools/install_ubuntu_dependencies.sh $ python3 -m venv .venv $ source .venv/bin/activate $ ./tools/install_python_dependencies.sh $ scons -j8
主にPythonとC++で実装されています。車用と銘打ったソフトウェアがPythonを使っているのは割と驚きでした……。
ビルドできましたが我が家には専用デバイスもありませんし、車も古いのでADAS付きではありません。そんな私はどうしたら良いのでしょうか?大丈夫、デモモードがあります。デモモードを動作させるには端末を2つ使います。
#### 1つ目の端末 $ ./tools/replay/replay #### 2つ目の端末 $ ./selfdrive/ui/ui
なぜかreplayはCUIで、uiはGUIです。まあそれはどうでも良いとして、replay側はこのような表示になるはずです。
デモモードではあるもののデータ自体は実際の車で走行したデータを再現しているはずです(たぶん)。しばらくするとCar Fingerprint: TOYOTA COROLLA TSS2 2019と出ますから、カローラと接続してこのデータを作ったのでしょう。もう一方のui側はこのような表示になるはずです。
アメリカのどこかのハイウェイ?でしょうか。しばらく見ていると車線変更を行ったりする様子が見えると思います。
デモモードでは全ての機能が動作する訳ではありませんが、特殊な機器なしでもある程度動作させることができるため、内部を解析する際の手助けになるでしょう。なかなか便利ですね。
目次: Linux
先日(2024年10月1日の日記参照)のUbuntu 22とxrdpの組み合わせで起きるエラーですが、Ubuntu 20で再現できるかやってみました。グラフィクスは種類が違いますがAMDのGPU(Radeon RX 6900 XT)です。条件は同様でgdm3は終了させてxrdpのみ起動しています。
結論から言うと再現しました。以下が通常時のログです。正常に画面が表示されます。
gnome-session-binary[2712263]: DEBUG(+): Enabling debugging gnome-session-binary[2712263]: GLib-DEBUG(+): posix_spawn avoided (fd close requested) gnome-session-binary[2712263]: GLib-GIO-DEBUG(+): _g_io_module_get_default: Found default implementation dconf (DConfSettingsBackend) for ‘gsettings-backend’ gnome-session-binary[2712263]: WARNING: Error creating FIFO: File exists
ログにはデバッグ有効であること以外は特に何も出ません。FIFOが作れない警告が出ます、これは何だろう?まあいいか。
次にcard0とrenderD128をリネームしてアクセスできないようにして試しました。画面は真っ黒になってすぐに切断されます。Ubuntu 20.04 LTSでも再現するんですね。ログは下記のようになりました。
gnome-session-binary[2712010]: DEBUG(+): Enabling debugging gnome-session-binary[2712010]: GLib-DEBUG(+): posix_spawn avoided (fd close requested) gnome-session-is-accelerated: No hardware 3D support. gnome-session-check-accelerated: GL Helper exited with code 256 amdgpu_device_initialize: amdgpu_get_auth (1) failed (-1) amdgpu_device_initialize: amdgpu_get_auth (1) failed (-1) ** (gnome-session-check-accelerated-gles-helper:2712146): WARNING **: 14:44:50.573: eglInitialize() failed gnome-session-check-accelerated: GLES Helper exited with code 256 gnome-session-binary[2712010]: DEBUG(+): hardware acceleration check failed: Child process exited with code 1 gnome-session-binary[2712010]: GLib-DEBUG(+): setenv()/putenv() are not thread-safe and should not be used after threads are created gnome-session-binary[2712010]: GLib-DEBUG(+): posix_spawn avoided (fd close requested) gnome-session-is-accelerated: No hardware 3D support. gnome-session-check-accelerated: GL Helper exited with code 256 amdgpu_device_initialize: amdgpu_get_auth (1) failed (-1) amdgpu_device_initialize: amdgpu_get_auth (1) failed (-1) ** (gnome-session-check-accelerated-gles-helper:2712203): WARNING **: 14:44:55.610: eglInitialize() failed gnome-session-check-accelerated: GLES Helper exited with code 256 gnome-session-binary[2712010]: WARNING: software acceleration check failed: Child process exited with code 1 gnome-session-binary[2712010]: CRITICAL: We failed, but the fail whale is dead. Sorry....
前回も見かけたamdgpu_get_auth()のエラーが出て止まりました。AMDのGPUの場合、エラーが起きると止まってしまう疑いが強まりました。本当はエラーが起きたらソフトウェアレンダリングにフォールバックしてほしいんですけど、そうならないようです……。
デバイスファイルが/dev/driに全く存在しなくてもamdgpu_get_auth()が怒ってくるところを見ると、X.orgはPCのグラフィクスの種類(VirtualBoxなのかAMDのGPUなのか)を最初から決め打ちにしているんですね。
目次: Linux
昨日(2024年10月1日の日記参照)のUbuntu 22とxrdpの組み合わせで起きるエラーですが、VirtualBox 7.0.18で再現できるかやってみました。グラフィクスはVMSVGAを選択しています。VMSVGAは/dev/driの下にcard0とrenderD128が生成されるようです。ちなみにgdm3は終了させてxrdpのみ起動しています。
ちなみに結論から言っておくと再現しません。以下が通常時のログです。正常に画面が表示されます。
gnome-session-binary[2774]: DEBUG(+): Enabling debugging gnome-session-binary[2774]: GLib-GIO-DEBUG(+): _g_io_module_get_default: Found default implementation dconf (DConfSettingsBackend) for ‘gsettings-backend’
ログにはデバッグ有効であることと、libEGLが何かしら見つけて反応しています。それ以外は特に何も出ません。
次にcard0とrenderD128をリネームしてアクセスできないようにして試しました。しかし正常に画面が表示されます。えぇー?ログは下記のようになりました。
gnome-session-binary[4319]: DEBUG(+): Enabling debugging gnome-session-check-accelerated: GL Helper exited with code 512 libEGL warning: DRI2: failed to authenticate gnome-session-check-accelerated: GLES Helper exited with code 512 gnome-session-binary[4319]: GLib-GIO-DEBUG(+): _g_io_module_get_default: Found default implementation dconf (DConfSettingsBackend) for ‘gsettings-backend’
AMDのGPUでも見かけたfailed to authenticateが出ています。が、エラーは無視されるんでしょうか?謎の動きですね。
目次: Linux
WindowsからUbuntu 22.04 LTSのxrdpに接続すると真っ黒な画面しか出ず、すぐに接続が切断されてしまう問題に遭遇しました。どこでクラッシュしているか調べるため、xrdpがGNOMEを起動するところまでを追いかけると下記のようになっていました。
/etc/xrdp/startwm.sh exec /bin/sh /etc/X11/Xsession /etc/X11/Xsession.d/99x11-common_start /usr/bin/ssh-agent /usr/bin/im-launch x-session-manager /usr/bin/x-session-manager /usr/libexec/gnome-session-binary
スクリプトx-session-managerを書き換えてgnome-session-binaryの引数に--debugを足すと、GNOMEはより詳細なメッセージを出力します。メッセージはホームディレクトリの.xsession-errorsに記録されます。GNOMEのエラーメッセージは下記です。
** (gnome-session-check-accelerated-gles-helper:3301100): WARNING **: 13:50:04.884: eglInitialize() failed gnome-session-check-accelerated: GLES Helper exited with code 256 gnome-session-binary[3300977]: DEBUG(+): hardware acceleration check failed: Child process exited with code 1 gnome-session-binary[3300977]: GLib-DEBUG(+): setenv()/putenv() are not thread-safe and should not be used after threads are created gnome-session-binary[3300977]: GLib-DEBUG(+): posix_spawn avoided (fd close requested) gnome-session-is-accelerated: No hardware 3D support. gnome-session-check-accelerated: GL Helper exited with code 256 ★★ここでエラーが発生している amdgpu_device_initialize: amdgpu_get_auth (1) failed (-1) amdgpu_device_initialize: amdgpu_get_auth (1) failed (-1) ** (gnome-session-check-accelerated-gles-helper:3301174): WARNING **: 13:50:09.927: eglInitialize() failed gnome-session-check-accelerated: GLES Helper exited with code 256 gnome-session-binary[3300977]: WARNING: software acceleration check failed: Child process exited with code 1 gnome-session-binary[3300977]: CRITICAL: We failed, but the fail whale is dead. Sorry....
エラーメッセージ曰くamdgpu_get_auth()が失敗しています。関数名から推測するにAMDのGPUが装着されているマシンでしか発生しないエラーなのかもしれません。この関数は何者なのかDRMのソースコード(Mesa/libdrmのソースコードリポジトリへのリンク)を見ると、
// drm/amdgpu/amdgpu_device.c
/**
* Get the authenticated form fd,
*
* \param fd - \c [in] File descriptor for AMD GPU device
* \param auth - \c [out] Pointer to output the fd is authenticated or not
* A render node fd, output auth = 0
* A legacy fd, get the authenticated for compatibility root
*
* \return 0 on success\n
* >0 - AMD specific error code\n
* <0 - Negative POSIX Error code
*/
static int amdgpu_get_auth(int fd, int *auth)
{
int r = 0;
drm_client_t client = {};
if (drmGetNodeTypeFromFd(fd) == DRM_NODE_RENDER)
*auth = 0;
else {
client.idx = 0;
r = drmIoctl(fd, DRM_IOCTL_GET_CLIENT, &client); //★★エラーを返すのはこの関数だけ★★
if (!r)
*auth = client.auth;
}
return r;
}
// drm/xf86drm.c
/**
* Call ioctl, restarting if it is interrupted
*/
drm_public int
drmIoctl(int fd, unsigned long request, void *arg)
{
int ret;
do {
ret = ioctl(fd, request, arg); //★★drmIoctl()はioctl()が返すエラーをそのまま返す★★
} while (ret == -1 && (errno == EINTR || errno == EAGAIN));
return ret;
}
ソースコードから推測するにグラフィクス系のデバイスファイルにioctl()しようとして失敗しているものと思われます。
XのグラフィックスはDRI(Direct Rendering Infrastructure)と呼ばれるインタフェースを経由してGPUを使用します。Xとカーネルの間にはlibDRMがおり、libDRMはLinuxカーネルのDRM(Direct Rendering Manager)を使用してGPUにアクセスします。DRMのデバイスファイルは/dev/driディレクトリの下にありますが、名前がDRIだったりDRMだったりして謎ですね。グラフィクス周りはあまり詳しくなくて理由はわかりません……。
# ls /dev/dri/* -la crw-rw-rw-+ 1 root video 226, 0 4月 30 15:00 /dev/dri/card0 crw-rw-rw-+ 1 root render 226, 128 4月 30 15:00 /dev/dri/renderD128
上記のようにキャラクタデバイス/dev/dri/card0と/dev/dri/renderD128のパーミッションを0666にしたところエラーが出なくなりました。今回はこの2つのデバイスファイルで解決しましたが、他のデバイスファイルにもアクセスしていた場合はさらに調査が必要かもしれません。グラフィクス系のエラーは簡単に調べる方法がないのが辛いですね。
ちなみにこの症状はQEMUだと再現しません。card0のパーミッションを0000にするとlibEGLがエラーになるのですが、なぜかGNOMEはエラーを無視して起動してしまいます。AMDのときだけなんで止まるんでしょうか。いまいち釈然としません……。
クラッキングでぶっ壊されてしまったニコニコ動画が復活し、シン・ニコニコ動画になって帰ってきました。いちユーザーとしては嬉しい気分でいっぱいです。
しかし前と比べて困ったことが起きていて、BizHawkで出力した動画をシン・ニコニコ動画にアップロードしようとすると「この動画の映像形式には対応していません」とエラーが出てしまって投稿できません。試行錯誤の末、解決方法を見つけたのでメモしておきます。
端的に言えば原因はピクセルフォーマットでした。BizHawkは特に何も言わないとYUV444で出力しますが、ニコニコ動画はYUV420でないと受け付けてくれないようです。どこにもそんな制約は書いていないため、仕様か?バグか?どちらともわかりません。
YUV420にする方法ですけども、BizHawkの出力設定を[Custom]にして、下記のようにピクセルフォーマットを明示的に指定すればYUV420で出力してくれました。
-c:a aac -c:v libx264 -preset ultrafast -pix_fmt yuv420p -f mp4
もしすでにYUV444で出力済みの動画ならば、ffmpegを使って再エンコードすれば良いです。
$ ffmpeg -i input.mp4 \ -vcodec libx264 -vb 2048000 -r 60 -s 1280x720 -pix_fmt yuv420p \ -acodec aac -ar 44100 -ab 192000 output.mp4
動画ビットレート(-vb)、フレームレート(-r)、動画サイズ(-s)は元の動画に応じて調整してください。
< | 2024 | > | ||||
<< | < | 10 | > | >> | ||
日 | 月 | 火 | 水 | 木 | 金 | 土 |
- | - | 1 | 2 | 3 | 4 | 5 |
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 | - | - |
合計:
本日: