Oculus RiftのルームスケールとKinect v2を同時に使用した時に困った話のメモ
不正確な情報が多い記事なので、参考程度に留めてください。
問題の要約
現象
Kinect v2のフレームレートが著しく低下する現状が発生しました。
同時にOculus Rift側では3台のセンサーを用いてルームスケール機能を使用していました。
原因
恐らくUSB帯域不足による問題だと判明しました。
USBを接続するホストコントローラーには使用できる帯域に制限があるため、それを超えたデータ転送を行えないということらしいです(多分)。
参考: USB 2.0と3.0について知っておくべき10のポイント - page4 - builder by ZDNet Japan
以下の通り、RiftとKinectそれぞれで多くの帯域を使用するとのことでした。
If you connect three Oculus sensors—each sending and managing a ton of data locally—you can run into problems when they try to send more data than the USB host controller can handle.
(意訳) 3台のセンサーを繋いで制限以上のデータを送ろうとすると問題が発生しうる。
Oculus Roomscale: Balancing Bandwidth on USB | Oculus
Kinect for Windows v2 センサーは、USB コントローラーの USB3 帯域幅をかなり消費します。
Windows アプリが Kinect for Windows v2 センサーで機能しない
解決方法
- ホストコントローラーに接続するUSBを減らす
- ホストコントローラーを追加し、接続先を分散させる
- (Riftではなく) HTC Viveを使用する
以下でそれぞれについて説明します。
(1,2について) ホストコントローラーの種類
EHCI(Enhanced Host Controller Interface)がUSB 2.0対応、xHCI(Extensible Host Controller Interface)がUSB 3.0対応だそうです。
[デバイスマネージャー] > [ユニバーサルシリアルパスコントローラー]で確認すると、僕のPCにはxHCIが1つとEHCIが2つ接続されているようです。xHCIがEHCIの機能を内包しているかどうかが分からなかったのですが、少なくとも3.0に対応しているxHCIが1台なので、現状で接続先を分散させる対処は恐らくできません。
参考: USB ホスト コントローラー ‐ 通信用語の基礎知識
(3について) HTC Viveのルームスケール
Oculus Riftのルームスケールは、Rift本体から飛ばした赤外線を、周囲に設置したセンサーで認識することで実現しています。そのため、センサーが受け取った情報が取得するためにセンサーとPCを接続する必要があります。
対するHTC Viveですが、こちらはセンサーから飛ばした赤外線を本体で認識する仕組みになっています。この違いにより、Viveのセンサーに必要な接続は、電源供給のためのACアダプターのみとなります。そのため、今回のようなUSB帯域を圧迫するような問題は解決できると思います。
問題発生から解決までの経緯
UnityでVR Supportを有効にしてKinectを使用したのデモシーンを動かしている時に、問題が発生。
Riftのポジトラが有効な時とそうでない的で、Kinectのフレームレートがめちゃめちゃ変わるんだけど、なんなんすかね…。ポジトラ圏外でのfpsが150くらいでで、圏内にはいると400くらいまで上がってる。Kinect側が勝手にフレームレート下げてる気がするなぁ。
— Nakaji Kohki (@kohki_nakaji) 2017年1月27日
コードを辿って行くと、KinectのSDKより下の層で更新がされていない模様。原因について考えます。
FPS計測してみた。Kinectの仕様上のFPSが30(暗所で15fps)で、自分の計測結果と同様だった。でもポジトラ有効時にはFPSは1~5程度しかでない。PC全体の処理速度は落ちてないからSDKとかでフレームレート下げてる気がするけど、そんな情報全然出て来ない…。
— Nakaji Kohki (@kohki_nakaji) 2017年1月27日
赤外線混線してる的な話か?ポジトラがFPS下がるきっかけだと思ってたけど、CV1は本体から赤外線だしてるから、それをKinectが拾うタイミングかも。でも精度下がるならまだしも、フレームレート下がるのはよく分からんな。
— Nakaji Kohki (@kohki_nakaji) 2017年1月27日
ここで天からの助けがきました。
@kohki_nakaji もしかしてUSB帯域限界だったりしません?
— 絵麻さんを養って幸せな家庭を築く (@izm) 2017年1月27日
原因が判明。
@izm 確認しました!コーヒーです!!!!☕️☕️☕️
— Nakaji Kohki (@kohki_nakaji) 2017年1月27日
色々教えてもらいました。
@kohki_nakaji https://t.co/iTEhvUflfx
— 絵麻さんを養って幸せな家庭を築く (@izm) 2017年1月27日
こんな感じの記事がOculus本家から出るくらいには、帯域を食います…
@kohki_nakaji 良くあるッス…(僕も帯域で死んだことあります)
— 絵麻さんを養って幸せな家庭を築く (@izm) 2017年1月27日
絵麻さんを養って幸せな家庭を築く (@izm) | Twitter さん、本当にありがとうございました🙏
余談
Rift Sensor 2台とKinect v2の構成にしても、時々どちらかのセンサーが効かなくなったりしました。USBを挿し直すことで解消したりもするのですが、Rift Sensorでは表示される正常に動作していない警告が、Kinectは自動的にフレームレートが下げるだけで表示してくれない問題がありました。そこで、Kinectの骨格情報が更新される頻度を監視しアラートを出すことで対応しました。
参考: 環境
PC
- OS: Windows 10 Home
- バージョン: 1607
- OSビルド: 14393.693
- プロセッサ: Intel® Core™ i7-4790K CPU @ 4.00GHz 4.00GHz
- 実装RAM: 16.0G
- 電源: 700W/AC
- USB 2.0 - 4ポート (背面2 + 前面2)
- USB 3.0 - 6ポート (背面4 + 前面2)
ヘッドセット
- Oculus Rift CV1 (HDMI + USB 3.0)
- Sensor - 3台 (USB 3.0*2 + USB 2.0)
モーションセンサ
- Kinect v2 (USB 3.0)