概要
VRで環境整えようとして、ドリフト現象が解決困難と悟り、別方式で構築するまでの経緯を紹介
VR環境の導入
以前購入したスマホ用のゴーグルをVRモードにして使用。
SteamのゲームをVRでプレイするには、SteamVRを起動してVRゴーグルとの連携が必要になる。そしてVRゴーグルの連携には専用のソフトが必要。

ここではVRidgeとIvryを試用してみた。以下はそれぞれの比較表である。
| VRidge | Ivry | |
|---|---|---|
| 品質 | 👍 | 👎 |
| 安定性 | アクティブが切り替わったり、何らかのイベントが起こるとたまに落ちる。 再起動である程度緩和される | 不安定というか、信用性は低い。 何も操作しなくても唐突に落ちることがある。(おま環?) |
| 復帰性 | やや手間。 Steamが丸ごと落ちることがあり、SteamVRの再起動含めて少し手間がある | VRidgeよりはマシ。 Steamごと落ちることはない。 SteamVRの再起動は必要 |
| 機能性 | 豊富。 コントローラーのバインディングやトラッキング設定、画質設定など、細かく調節できる。 外部センサーによるポジショントラッキングを追加可能 | はっきりいってしょぼい。 主に使うのは画質設定くらい。 |
| 総合評価 | 100点満点とは言わないが、及第点レベル | 落第 |
安定性の部分のところを重視し、機能性の優位さも考えてVRidgeを選択した。
SteamでVridgeを購入し、スマホ側にはVRidgeアプリを導入し、USB接続で使用することにした。
TIPVRidgeを買うときはセールを狙うと、いいぞ。
USB接続の場合、USBテザリングでPCと接続することになるので、スマホ側のネットを無効にしておくことを推奨する。
NOTEUSBでの接続トラブル
スマホ側に入っていたVPNによるネットワークフィルタアプリが邪魔してた。VRidgeを対象外にして解消できた。
このフィルタでブロックされているとVRidge側ではなんのエラーもでないので、USB接続で悩んでいる人はネットワーク通信をブロックするアプリが入っていないか確かめてみよう。
スマホVRの宿命(ドリフト現象)との対決
前回の記事でも触れていた、VRゴーグルのドリフト現象について色々と調査した。
スマホVRは根本的にドリフトが発生するらしい。
ピッチ、ロールは加速度センサー、重力センサーで測定でき、そこの計測結果は原理的にずれることがない。
だがヨーはジャイロで計測している。ジャイロはセンサーの構造的に一意の基準点がない。なので正面を向いてもずれてしまいやすい。
NOTEヨーの方向は水平方向の角度しか変化しないため垂直方向の動きがなく、重力によるセンサーが利用できない、という解釈。
ならばとVRidgeのトラッキングソースをfreetrackという外部のトラッキング情報を使うモードで、ジャイロセンサーを使わない方向でVRをプレイしようと考えたのだが、結果としては失敗に終わった。
VRidgeをfreetrackのみのモードにすると、ゴーグル内の画面が普通の四角いディスプレイで表示される。そして向きを変えると四角い画面そのものが移動する。freetrack側の入力を変化させると、画面内がスクロールされる動きになる。
つまりfreetrackのみにしても、スマホの動き自体は切ることができない。それでは結局ジャイロセンサーの呪縛からは解き放たれないので意味がない。
6dofにすれば緩和されるというような情報もあったが、これも効果はなかった。
スマホのセンサーと組み合わせるモードは使えるが、xyzの移動のみがfreetrackの対象となる。これはスマホのセンサーでは3dof、freetrackでxyzの軸を追加して6dof化するための機能である。
そしてこのモードはドリフト現象を是正するためのものではない。
3dofは回転のみのトラッキング、6dofは回転+移動がトラッキングできるもの。トラッキングの軸の種類が多いか少ないかの違いだけで、6dofでもトラッキングはドリフトは発生する。
悪あがき
ドリフト現象そのものは抑えることができないので、随時位置リセットをかける方向を模索。
理屈としては真正面を向いたときに位置リセットをすれば、その時点でドリフトによるズレが解消される。これを自動的に行えればドリフトを気にする時間が減るはずと考えた。
正面を向いた時に視点リセットのショートカットを自動入力するスクリプトを組んでみた。opentrackのログ出力を有効にし、そのcsvで入力のyawの値を監視し、yawが1度以下-1度以上の時にキーを入力させるというスクリプトである。
が、実際に使用してみて運用上無視できない挙動になったので没となった。
挙動について
視点がずれていない時にリセットされても大した影響はない。しかし少しでもずれている時にリセットが行われると、視点がいきなり中央に飛ぶことになる。
微妙なズレでも視点がいきなり飛ぶと結構面食らいプレイに支障が出る。またロールやピッチもヨー方向の正面を向いた時点のもので固定されてしまうので、結局手動リセットが必要だったりした。
そのまま埋もれさせておくのもあれなのでここで供養する。しかし今から考えるとfreepieで作ったほうがスマートな気が
スクリプト
import timeimport osimport pandas as pdimport ioimport winsoundfrom pynput.keyboard import Controller, Key
def send_shortcut(): """指定のショートカットキーを送信""" keyboard = Controller() with keyboard.pressed(Key.ctrl): with keyboard.pressed(Key.shift): keyboard.press(Key.f11) keyboard.release(Key.f11) print("ショートカットキーを送信しました") winsound.MessageBeep(winsound.MB_OK) time.sleep(10)
def check_last_row(csv_file, last_line_hash): """CSVの最後の行の5列目をチェック""" try: # 最後の行のみ読み込む with open(csv_file, 'rb') as f: f.seek(-1024, os.SEEK_END) # ファイル末尾付近を読み取る(適宜調整) lines = f.readlines() last_line = lines[-1].decode('utf-8')
# ハッシュ値を計算して変更を検出 current_hash = hash(last_line) if current_hash == last_line_hash: return last_line_hash # 変更なし
# 最後の行をDataFrameに変換して処理 last_row = pd.read_csv(io.StringIO(last_line), header=None) if len(last_row.columns) < 5: print("CSVに5列目が存在しません。") return current_hash
last_value = last_row.iloc[0, 4] # 5列目を取得
# 条件をチェック if -1 < last_value < 1: send_shortcut() print(f"条件を満たしました: 最後の行の5列目の値は {last_value} です。")
return current_hash
except FileNotFoundError: print("指定されたCSVファイルが見つかりません。") except pd.errors.EmptyDataError: print("CSVファイルが空です。") except Exception as e: print(f"エラーが発生しました: {e}") return last_line_hash
def main(): csv_file_path = "tracklog.csv" # CSVファイルのパスを指定 last_line_hash = None # 最後の行の状態を記録 polling_interval = 0.1 # ポーリング間隔(秒)
print("監視を開始します。停止するにはCtrl+Cを押してください。") while True: last_line_hash = check_last_row(csv_file_path, last_line_hash) time.sleep(polling_interval)
if __name__ == "__main__": main()spacedesk+opentrackでのHMD環境の構築
opentrackの設定をいじっていて、これのみであればドリフト現象はほぼ起きないことが確認された。そこから本題であるトラッキングつきのHMDによるプレイ環境を思いつく。
この方式は、180度のディスプレイをセットして6dofでプレイできる環境を擬似的に再現するものである。でかいディスプレイによるプレイ環境を整えるという点では、一応コスパや配置的なメリットはある・・はず。
VRではないので立体表示はできないが、基本的にドリフトが起こらず相対的にプレイ環境への不満は少なくなる。
HMDの準備
opentrackのarucoでトラッキングするため、arucoマーカーをHMDに貼り付ける。

マーカーの向きがopentrackのgithubのreadmeやwikiに明確に指示されていないためか、他所様の記事でも向きがバラバラだったりする。自分は長い白線を下にして、Y軸を反転させることでopentrackのタコの動きとマーカの動きが一致した。

とりあえずタコの動きと同じになるよう調整できれば、マーカーの向きはどうでもいいのだ。
spacedeskの設定
デフォルトだとfps30になっている。見づらいのでfps60へ
必要に応じて画質を調整。ふっるいスマホだと画質と解像度を下げないとfpsが保てない
参考までに、zenfone3での設定は以下の通り


カメラの設置
LED付きの60fpsを出せるwebカメラをハンコン台に設置した。背面をタッチすることでLEDの色温度を変えられる
ケネックス (K’NEX) という玩具で試作。いずれ3Dプリンターで代わりを作る予定。



NOTEarucoでトラッキングする場合、以下を気をつけるといい
- カメラ位置を高めにするかマーカーまでの距離を近づけないないと、ピッチングの精度が低下する
- 部屋を暗めにして、マーカーには光が当たるようにすることで認識が安定する
- ガンマやコントラストを設定で上げて、認識率を上げる
ちなみに60fpsのカメラでないと安定しないというのが巷での見解。だが意図的に30fpsに設定したりして挙動を確かめてみたものの、違いを実感できなかった。
カメラ設定
露出の自動調整を切り、露出を下げることでfpsが保てるようになる
ガンマを多少上げる。ledの色はどれでもいい
なおopentrackに直接設定すると、カメラの露出設定が毎度自動になってしまうので、OBSの仮想カメラを経由して設定している


トラッキングのマッピング
基本的には入力と出力を1:1で設定。ロールとY軸は細かくトラッキングされすぎるとプレイしにくいので、デッドゾーンを多めにしている。






レースゲームでは最低限ヨーがあればいい。Z軸もあると視界の範囲の調整がしやすくなる
シートに後頭部を押し付けた状態で合わせて視野角を合わせておき、トラッキングセンターもそこに合わせることで、視野範囲のシミュレートがよりリアルに近づくはず
視点リセットの設定
opentrackの中央に戻すショートカットを設定しておく。

ドリフトが発生しないといえど、HMDの初期位置は一定ではないのでゲーム開始時にリセットできるようにする。
一緒にコントローラー側にもショートカットを入力できるようにしておくといい。
自分はマクロでVRidgeの視点リセットと一緒に設定している。

freepieによるヘッドトラッキングのみの場合
スマホ側でfreepieを起動しspacedeskも起動すればセットアップできるので手軽。
android8でのfreepie imu導入方法
opentrack内にあるfreepieのapkは、andorid9以降でないとインストールできない。
zenfone3はandroid8で止まっているので、別の方法を探した。
freepie公式のgithubで、最新releaseのインストーラーをダウンロードし、インストールする
なおインストールしたソフトウェアに用はない。必要なのはインストールされたディレクトリにあるapkファイルである。
com.freepie.android.imu.apkをandroid端末にコピーしてインストールする

opentrack側の設定
inputをfreepieにしてtrackerの設定を開く。
ロールとピッチの軸が入れ違いになっていたので以下のように修正。

add to axisが多分端末の向きを指定するものだと思う。よくわからなかったのでトライアンドエラーでこの値になった。
回転方向も逆だったので、出力設定でinvertする

プレイの様子(動画)
所感
まず最初に、ゴーグルのレンズに曇り止めが必須。2Dのレンズは大きいためかなり曇りやすいらしい。
発進前にシートに深く座って視点をリセットさせることで、ドリフトは発生せず道中でリセットを掛ける必要はない。
プレイ感はやはりVRほど没入感はないが、相対的に解像度は上なのでディテールがはっきりし、プレイのしやすさは圧倒的に上である。トラッキングによりRのきついコーナーで出口が見やすくなるのは、この方式の最大のメリットと言えよう。
今回arucoでのトラッキングにより、ポジショントラッキングも有効になっている。
ぶっちゃけなくてもそんなに支障はなさそうだが、奥行き(Z軸)のトラッキングは有用で、姿勢を前に乗り出すことで路面やApexにズームできたり、
逆にストレートでは道幅確認のために姿勢を後ろに倒してズームアウトしたりの調節が自然にできる。なので、レースゲーでもポジトラはあったらあったで便利、という印象である。
なおVRでも触れたバックした時の恐怖感は、HMDでもあまり変わらなかった。
webカメラ→opentrackと経由するものが多いためか、トラッキングされるまで微妙にラグがある。視野角やマッピングの設定で多少影響は緩和できる。VRだとスマホのセンサーでダイレクトに画面が動くため、ラグが少ない。
まとめ
VRとは一長一短で、どちらにも優れている面と劣っている面がある。
| VR(3dof) | HMD+トラッキング(6dof) | |
|---|---|---|
| コスト | ソフト:1000円 | ソフト:0円 webカメラ:2000~5000円 |
| ドリフト現象 | 発生する | 発生しない |
| ラグ | なし | あり |
| 設定難易度 | 低い | 高い |
| 解像度 | 低い | 高い |
| 没入感 | 高い | 低い |
| 向いてる用途 | フィットネス系 (ドリフトが発生しても影響が少ないため) | プレイ時に位置が固定されるタイプのゲーム |
ゴーグルやスマホ、webカメラの用意は必要だがソフトは無料なので、予算が少ないのなら試してみる価値はある。ただ、実際にやってみて沼感を感じた。
トラッキングの手法や、トラッキングのマッピングをどこまで妥協するかなどの線引に正解がないので、こだわろうと思えば思うほど時間を消費してしまう。
プレイ体験に置いては、レースゲームだとVRよりも2Dのほうが路面状況が視認しやすく、プレイしやすかった。ラグを差し引いても真面目にタイムアタックするなら2Dに軍配が上がるだろう。
自分から言えることとしては
- 自分のプレイスタイルに合っているか
- こだわりすぎない
この点に気をつけて、自分にあったプレイ環境と設定を見つけてみてほしい。