1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

VRゴーグルでUnitree G1をテレオペしてみた(シミュレーション編)

1
Last updated at Posted at 2026-08-17

はじめに

ここ最近、「Physical AI」という言葉を耳にすることが一気に増えましたね。
これは、AIの知能を現実での行動に結びつけるものです。アメリカの工場などでは、すでにたくさんの導入事例があります。

このPhysical AIにおける大きな課題の一つが「データ取得」です。
例えばLLMは、インターネット上に大量のデータがあります。だからこそ、ここ数年で一気に進化してきた、という背景もありますね。
一方、Physical AIにはそこまで充実したデータがありません。そこで「どこからデータを補うか」が問題になります。その手法の一つが、VRゴーグルなどで自分の動きをロボットに追従させ、そのデータを取る、というものです。
というわけで今回は、そんな"全身テレオペ"をシミュレーション上でやってみました!

はねるG1.gif

こんな感じです笑。ジャンプもお手のもの

基本的には、NVIDIA GR00T-WholeBodyControl 公式 の内容を参考にしています。
公式の想定している環境と少し違ったのもあって、はまりどころがいくつかあったので、その辺含めて話していけたらと思います!
この記事を読むと、VRテレオペの基本的なやり方がわかります。参考程度にどうぞ!


この記事でわかること

  • VRテレオペの全体像 — PICO+モーショントラッカーで、シミュレータ上のG1を全身操作する仕組み
  • 環境構築 — TensorRT・MuJoCo・GEAR-SONIC のビルドと、5プロセスの一括起動スクリプト
  • PICO接続 — XRoboToolkit の設定と、リモートサーバーへ Tailscale で繋ぐ方法
  • ハマりどころ — Lost LowState の正体(DDS)、共有IPの罠、接地(9)の3つ

システム構成

最終的なテレオペレーションの起動構成は以下のようになりました。

レイヤー 中身
VR側 PICO 4 ヘッドセット + コントローラ2 + モーショントラッカー2(足首)+ XRoboToolkit
サーバー側 NVIDIA製GPU 搭載の Ubuntu マシン(今回は会社の遠隔サーバーに Tailscale + NoMachine で接続)
ソフト gear_sonic_deploy:C++ deployバイナリ + MuJoCoシミュレータ + PICO streamer

このGPUですが、NVIDIA製でないとダメなようです(普通のMacのGPUなどは不可)。理由は、このパイプラインが CUDA と TensorRT を使っていて、これらが NVIDIA 専用だからです。

データの流れを図示すると以下のような感じです。


環境

項目 内容
GPU NVIDIA RTX 3090(24GB)
OS Ubuntu 22.04
CUDA / TensorRT CUDA 12.8 / TensorRT 10.13(x86_64はバージョン厳守)
VR PICO 4 + モーショントラッカー×3
接続 Tailscale

先ほどGPUの話をしましたが、NVIDIA製であれば必ずしもこの型番である必要はありません。十分なVRAMがあれば問題なしです。
モーショントラッカーは、足首に2つ・腰に1つの計3つです。

最初はNoMachineで遠隔操作したままテレオペしようとしたのですが、遅延が大きすぎてシミュレータが一瞬で落ちてしまい、断念しました(ログを見たら500msくらいの遅延がありました笑)。


セットアップ

1. リポジトリを取得

まずは GitHub からコードを clone します。

git clone https://github.com/NVlabs/GR00T-WholeBodyControl.git
cd GR00T-WholeBodyControl

# モデルやメッシュなど大きいファイルは Git LFS 管理なので、これも実行しておく
git lfs pull

2. ビルド

続いて deploy プログラムをビルドします。流れは 「依存を入れる → 環境変数を通す → ビルド」の3ステップです。

前提として、先に TensorRT をダウンロードして TensorRT_ROOT を通しておく必要があります(前述のとおりバージョン厳守。x86_64 は 10.13)。これを忘れると、次の setup_env.sh / just build で TensorRT を見つけられず、うまくコードが動きません。

cd gear_sonic_deploy   # clone した GR00T-WholeBodyControl の直下にある deploy フォルダ

# ① ビルドに必要なシステム依存(cmake・各種ライブラリ等)を一括インストール
chmod +x scripts/install_deps.sh   # 実行権限がなければ付与
./scripts/install_deps.sh

# ② TensorRTのパスなど、ビルド/実行に必要な環境変数をまとめてセット
source scripts/setup_env.sh

# ③ ビルド実行(just は make のようなコマンドランナー)
just build

各コマンドがやっていること:

  • install_deps.sh … cmake などのビルドツールや依存ライブラリを apt などでまとめて導入
  • setup_env.sh … TensorRT の場所や各種パスを環境変数に設定(これを忘れるとビルドが TensorRT を見つけられない)
  • just build … just(= make 的なタスクランナー)で C++ の deploy バイナリを生成

ハマりどころ

  • ROS2 が入っていると CycloneDDS が衝突する → ビルド前に export HAS_ROS2=0 を指定して回避(ROS2側のDDSを使わせないようにする)
  • 一部のソースで -fpermissive が必要 → -DCMAKE_CXX_FLAGS="-fpermissive" を付け、厳しめのC++エラーを警告扱いに緩めてビルドを通す

3. モデル取得

python download_from_hf.py   # ONNX policy / encoder / planner を配置

4. DDS設定(※自分がハマったところ)

ここは、僕が一番ハマったポイントです。

まず前提として、通常この設定は必要ありません。 NVIDIA の公式ドキュメントにも、sim(run_sim_loop)と deploy を起動するだけで、両者は CycloneDDS を通じて自動的に見つけ合うということになっています(DDSの設定ファイルなんて登場しません)。DDSはネットワークのマルチキャストを使っていますが、普通のPCならそれが問題なく通るからです。

ところが、僕の環境は少し特殊でした。 会社のリモートサーバー上で作業していたのですが、DDSがまともに使えるネットワークインターフェースが実質 lo(ループバック)だけ、という状況であることが判明しました。しかし lo はマルチキャスト非対応なので、sim と deploy が互いを発見できず、deploy が起動直後に Lost LowState(=ロボの状態が返ってこない)を出して安全停止してしまいました。

同じような状況の人は少ないと思いますが(笑)、解決策を提示しておきます。
解決策は「マルチキャストをやめて、localhost のユニキャストで直接つなぐ」ようCycloneDDSに指示すること。 下のXMLを用意し、環境変数で読み込ませます。

用語ミニ解説

  • マルチキャスト:「誰かいますかー?」とネットワークに一斉に呼びかけて相手を探す方式(1対多)。DDSはデフォルトでこれを使う
  • ユニキャスト:「このアドレスの相手」と1対1で直接指定して通信する方式。相手が分かっていれば確実
  • ループバック(lo / localhost):自分自身へ向かう通信路。外のネットワークには出ず、同じマシンの中だけで完結する

要するに今回は「一斉呼びかけ(マルチキャスト)が使えない環境なので、"相手は同じマシンの localhost にいる" と直接指定(ユニキャスト)し、通信も外に出さず同マシン内(ループバック)で完結させる」設定にした、というわけです。

こんなのは知ってる人がほとんどかも知れませんが、、、
備忘録程度に思っていただけると

~/cyclonedds_localhost.xml
<?xml version="1.0" encoding="UTF-8"?>
<CycloneDDS xmlns="https://cdds.io/config">
  <Domain id="any">
    <General>
      <Interfaces><NetworkInterface name="lo" presence_required="false"/></Interfaces>
      <AllowMulticast>false</AllowMulticast>
    </General>
    <Discovery>
      <ParticipantIndex>auto</ParticipantIndex>
      <Peers><Peer address="localhost"/></Peers>
    </Discovery>
  </Domain>
</CycloneDDS>
# 上のXMLをCycloneDDSに読ませる(後述の起動スクリプト先頭にも入れておくと確実)
export CYCLONEDDS_URI="file://$HOME/cyclonedds_localhost.xml"

この設定を行うことで sim ↔ deploy がループバック経由で発見・通信できるようになり、Lost LowState 問題が解決しました。

5. 一括起動スクリプト

システム構成の「ソフト」の欄をみていただけたら分かると思いますが、PC側で立ち上げなければいけないソフトが多く(deploy,mujocoなど)、全てを毎回自分で立ち上げるのは相当面倒ですよね。
ということで、5つのプロセスを順番に立ち上げるスクリプトを作ってみました。
その一部抜粋を以下に記します。

スクリプト内で使っている .venv_teleop は、リポジトリルートで bash install_scripts/install_pico.sh を実行すると作られるテレオペ用のPython環境(初回のみ)。MuJoCo・XRoboToolkit SDK・Unitree SDK2 などがまとめて入ります。これを作っていないと、下のスクリプトの source .venv_teleop/bin/activate でコケます。

launch_teleop_win.sh(抜粋)
#!/bin/bash
export CYCLONEDDS_URI="file://$HOME/cyclonedds_localhost.xml"

# 起動時に残骸を掃除(ポート衝突防止)
pkill -9 -f run_sim_loop; pkill -9 -f g1_deploy_onnx; pkill -9 -f pico_manager; pkill -9 -f socat
sleep 2

# 1) XRoboToolkit PC Service
gnome-terminal --title="1-service" -- bash -c "/opt/apps/roboticsservice/runService.sh"
# 2) socat(PICOからの接続をローカルへ転送)
gnome-terminal --title="2-socat"   -- bash -c "socat TCP-LISTEN:60061,bind=$(tailscale ip -4),fork,reuseaddr TCP:127.0.0.1:60061"
# 3) MuJoCo
gnome-terminal --title="3-sim"     -- bash -c "source .venv_teleop/bin/activate && python gear_sonic/scripts/run_sim_loop.py"
sleep 10
# 4) deploy(GEAR-SONICポリシー)
gnome-terminal --title="4-deploy"  -- bash -c "cd gear_sonic_deploy && echo y | ./deploy.sh --input-type zmq_manager sim"
sleep 7
# 5) PICO streamer
gnome-terminal --title="5-pico"    -- bash -c "source .venv_teleop/bin/activate && python gear_sonic/scripts/pico_manager_thread_server.py --manager --vis_vr3pt --vis_smpl"

こんな感じですね。自分でも作ってみたかったら、元のNVIDIAの公式ページとこの記事をAIに読み込ませれば作れると思います、笑。
下の画像のような感じで、複数のターミナルの窓とmujocoの画面が立ち上がります(少しみにくいですが)。

Screenshot from 2026-08-17 18-27-16.png


PICO接続

事前準備:PICO側に入れておくもの

PC側の準備はあらかた終わったので、次はPICO側の設定です。
まずテレオペを始める前に、次の2つのソフトを入れておきます。

  • XRoboToolkit(PICOアプリ) … 頭・コントローラ・トラッカーの動きをPCへ送るアプリ。PICOのブラウザからAPKを落として入れます(要・デベロッパーモード)。
    • 対になる形で、サーバー側には PC Service(.deb) を入れて起動しておきます。これが受け口なので、動いていないとPICOは接続できません。
  • Tailscale … 今回はサーバーがリモート(別ネットワーク)にあるため必要でした。公式手順は「PICOとPCを同じWi-Fiに繋いでLAN内のIPを入れる」前提ですが、リモートサーバーだと同じLANに乗れません。そこでPICOとサーバーの両方を Tailscale(同じ tailnet)に入れて、仮想的に同じネットワーク扱いにします。

ローカルにサーバーがある人は Tailscale は不要です。僕は遠隔でサーバーと繋げて作業してたので必要でした。公式の手順通りにPICOとサーバーを同じWi-Fiに繋いで、そのLAN内のIPを入れればOKです。

各インストールの詳細手順は公式が丁寧です: VR Teleop Setup (PICO)

接続と送信の設定

XRoboToolkit(PICOアプリ)側の設定:

設定 値
head ON
controller ON
hand OFF
send ON(これがデータ送信スイッチ。ONで流れ出す)
Pico Motion Tracker Full body(足首トラッカーで全身を追従させるモード)
Remote Vision / Data Collection OFF(今回は不要)

Screenshot_com.xrobotoolkit.client_2026.08.17-18.38.42.072_603 (1).jpeg

設定画面はこんな感じですね。この画像の状態ではセットアップは終わっていないので、ここからモーショントラッカーを接続してpcと繋げていくという感じです。


テレオペ実行

  1. deploy 窓で Init Done を確認 → MuJoCo上でロボットが立つ
  2. MuJoCoの窓をクリックして 9 を押す → ロボットを地面に落とす
  3. コントローラで A+B+X+Y(起動+初回フルキャリブレーション)
  4. 腕をロボの姿勢に合わせて A+X(POSEモード=全身追従)
  5. 体を動かす → ロボットが追従!

2番を忘れると、ロボットの操作が効かず暴れ出します、、、笑
(MuJoCo上ではデフォルトでロボットが宙に浮いており、そのままテレオペすると踏ん張れずにおかしな挙動になります)

主なコントローラ操作

動作 ボタン
起動 / 緊急停止 A+B+X+Y
POSE(全身追従)切替 / リセット A+X
VR_3PT(上半身のみ追従・脚はプランナー) 左スティック押し込み
ハンド開閉 トリガー

結果

シミュレーション上でのVRテレオペ、達成できました!!!
VRゴーグルを被って腕を上げれば G1 も腕を上げ、体を捻れば追従します。

しゃがむG1.gif

画面左上を見るとしっかりログも取れていますね!


まとめ

  • 本質は「deploy.sh ... sim + PICO を XRoboToolkit で繋ぐ」だけ。ではありますが、 DDS 設定・IP・ロボットの接地 などハマりどころがいっぱいありました。とはいえ説明を聞くだけではわからないと思うので、自分でやる時はとりあえずハマってみてください笑
  • 次回は実機( Unitree G1 本体)でのテレオペをやろうと思っています!お楽しみに!

これは余談ですが、姿勢制御が効いていなくて倒れ続けてしまうG1君です

倒れるG1.gif


参考リンク

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?