2026年7月12日日曜日

Unitree G1 の PC1 オペレーション・コントロール計算機に関する調査報告

 # Unitree G1 の PC1 オペレーション・コントロール計算機に関する調査報告


## エグゼクティブサマリー


Unitree G1 の **PC1** は、公開資料上では「Operation and Control Computing Unit」または「Motion Control Computing Unit」に相当し、**Unitree 標準の歩行・姿勢制御を実行する専用計算機**として扱われています。Unitree の公式資料は、PC1 を**一般ユーザー非公開**と明記しており、二次開発は Jetson Orin NX を載せた **PC2** で行う前提です。公式資料では PC2 の IP を **192.168.123.164** として公開し、G1 のオンボード計算機との疎通確認には **192.168.123.161** へ ping する手順を案内しています。これに、第三者の逆解析・実機観察が一致しており、**PC1=192.168.123.161 の運動制御用ホスト**、**PC2=192.168.123.164 の開発用ホスト**という理解はかなり強いです。 citeturn11search2turn12search2turn54search0turn13view0turn48view0


ただし、**PC1 の SoC・メモリ・ストレージ・OS は Unitree が公式に詳細公開していません。** 公式に確認できるのは「8-core high-performance CPU」であることと、PC1 が非公開であることまでです。一方、2025 年の Unitree G1 逆解析レポートでは、胸部メイン PCB 上の主プロセッサを **Rockchip RK3588**、メモリを **8GB 級 LPDDR4/5**、ストレージを **eMMC**、OS を **Linux 5.10.176-rt86+ with PREEMPT_RT** と報告しており、写真付きの teardown でもヒートシンク付き SoC 領域・JST 系コネクタ・電源 MOSFET 群・大容量コンデンサが確認されています。これは**かなり有力な実測系証拠**ですが、**公式未確認**なので本報告では **中〜高信頼の観測値**として扱います。 citeturn9search3turn31view0turn48view3turn46view2turn47view1


ソフトウェア面では、公開 SDK と逆解析結果の整合が高く、PC1 側には少なくとも **basic_service**、**ai_sport**、**state_estimator**、**motion_switcher**、**robot_state**、**ros_bridge** などのサービス群が存在する可能性が高いです。とくに **basic_service** は逆解析で **“Low-level motor control and hardware interface”** と説明され、**ai_sport** は **“AI-based motion control and sports movements”** と記述されています。これらは、ユーザーが PC2 から SDK 経由で呼ぶ **LocoClient** の高レベル API と、公開 DDS トピック **rt/lowcmd / rt/lowstate / rt/secondary_imu / rt/arm_sdk** の間をつなぐ、**PC1 内の実制御スタック**である可能性が高いです。 citeturn49view3turn32view1turn20view1turn25search3turn16search3


公開情報から**確実に言えること**は、PC1 の標準歩行制御アルゴリズムそのものは**非公開**だという点です。SDK が公開しているのは、主として **高レベルの FSM/速度/姿勢 API** と、**低レベルの関節コマンド API** です。低レベル API は関節ごとに **q, dq, kp, kd, tau** を設定でき、G1 の足首は **PR / AB** の 2 モードを備えています。これにより、少なくとも **PD+フィードフォワード・トルク** 型の下位サーボ入力を受ける設計であることは強く示唆されますが、**PC1 内部で Unitree 標準歩行が PID 主体なのか、モデルベースなのか、MPC/WBC/インピーダンス主体なのか**は、公式には明かされていません。 citeturn40search1turn38search2turn38search0turn22view1


制御周期についても、**公開された標準 ai_sport の内部周期は非公開**です。ただし、Unitree の G1 低レベルサンプルは **2 ms 周期**で recurrent thread を起動しており、**500 Hz** の low-level command writer を前提にしています。さらに、複数の G1 実機論文は、外部あるいはオンボードの研究用ポリシーが **50 Hz** で推論し、**200 Hz / 250 Hz / 500 Hz** の low-level interface へ接続していると報告しています。したがって、**G1 の関節レベル制御インターフェースが少なくとも数百 Hz 級で使われている**ことは確認できますが、**それが stock PC1 標準歩行の内部ループそのものか**は区別して扱う必要があります。 citeturn18view1turn22view2turn29search5turn29search6turn29search10turn53search1


## ハードウェア


公式資料から直接読める PC1 ハードウェア情報はきわめて少なく、G1-EDU のオンボード構成は **PC1 + PC2** の 2 計算機で、**PC1 は Unitree motion control 専用・非公開**、PC2 は **Jetson Orin NX**, 8-core Arm Cortex-A78AE, 16GB メモリ, 2TB ストレージ, IP **192.168.123.164** とされています。つまり、Jetson は**標準歩行を走らせる PC1 そのものではなく**、ユーザー開発用の **PC2** です。これは、以前から流通していた「G1 は Jetson 搭載」という見方と整合しますが、**その Jetson は標準歩行制御の主計算機ではない**、というのが重要な点です。 citeturn11search2turn12search2


PC1 の中身については、第三者の teardown/逆解析が非常に重要です。そこで報告された胸部メイン PCB の写真では、**大型ヒートシンクで覆われた SoC/CPU 複合部**、**FORESEE eMMC**、**SK hynix の LPDDR4/5 RAM**、**Wi‑Fi/Bluetooth モジュール**、**複数の PMIC** が示され、SoC として **Rockchip RK3588** が読み取られています。また、同レポートはプラットフォーム全体を **ARMv8 / 8GB RAM / eMMC / ETH・Wi‑Fi・BT / Linux 5.10.176-rt86+** と記述しています。公式裏取りはないため断定は避けるべきですが、**G1 PC1 が RK3588 系 ARM64 ボードである可能性は高い**と評価できます。 citeturn31view0turn48view3


ボードレベルの構成としては、chest cover を開けた写真で **アクティブ冷却ファン**、**JST 系多ピンコネクタ**、**電源分配回路**、**モータドライバ・センサ接続点** が確認されます。別の close-up では、**電源 MOSFET クラスタ**、**センサ IF コネクタ**、**高電流系の配線と絶縁材**、**大容量コンデンサ** が見えます。これにより、少なくとも胸部のメイン基板が **演算 + 電源配分 + 下位ハードウェア接続ハブ** を兼ねていることはかなり有力です。ただし、**各関節ドライバが基板上集中実装か、関節内分散実装か、ハイブリッド構成か**は公開資料だけでは確定できません。 citeturn31view0turn46view2turn47view1


G1 の関節モータについて公式に確認できるのは、**Unitree 自社開発モータ**、**最大トルク 120 N·m**、**中空軸**、**デュアルエンコーダ**という点です。公式資料は「デュアルエンコーダにより、より正確な位置・速度フィードバックを実現」と述べていますが、**絶対/相対、シングルターン/マルチターン、磁気/光学**といったエンコーダ種別は公開していません。したがって、**“デュアルエンコーダ” は高信頼**、**具体的方式は未公開**という整理が妥当です。 citeturn11search2turn53search0


公開されている外部インターフェースは、主に **PC2 側あるいはロボット外部デバッグ用の電気インターフェース**です。公式 G1 Developer Guide は、右側に**関節モータ・センサ周辺機器・Ethernet を接続する electrical interfaces** があると説明しています。さらに Unitree 文書のミラーでは、**Debug C = USB‑C(Jetson debug UART)**、**Custom port = 24V・UART1・I2C2**、**USB 3.0 Type‑C/Type‑A**, **USB 2.0 Type‑A**, **2+8 port = Ethernet 1G**, **2+4 ports = head/waist camera 向け 2Gb Ethernet** などの記述が見られます。これらは**ユーザーアクセス可能なロボット側配線情報**として有用ですが、**PC1 の専用コネクタ公開資料ではない**ことに注意が必要です。 citeturn43search6turn24search0turn6view1


### 公称値と観測値の比較


| 項目 | 公式・公開資料で確認できること | 観測・逆解析で見えたこと | 信頼度 |

|---|---|---|---|

| PC1 の位置づけ | PC1 は Operation/Motion Control Computing Unit、非公開、Unitree motion control 専用。PC2 のみ二次開発可。 citeturn11search2turn12search2 | 192.168.123.161 が G1 MCU / motion control 側、192.168.123.164 が開発側という実機観測が複数一致。 citeturn54search0turn13view0turn48view0 | 高 |

| PC1 の CPU/SoC | 「8-core high-performance CPU」以上は公式非公開。 citeturn9search3turn12search2 | RK3588, ARMv8, 8GB RAM, eMMC, Wi‑Fi/BT との逆解析報告。 citeturn31view0turn48view3 | 中〜高 |

| PC1 の OS | 公式非公開。 | Linux 5.10.176-rt86+ with PREEMPT_RT と観測。 citeturn48view3 | 中 |

| PC2 | Jetson Orin NX, 16GB, 2TB, 192.168.123.164。 citeturn11search2turn12search2 | 実機ドキュメントや外部ツール群も 164 を前提。 citeturn13view0turn12search5 | 高 |

| 胸部メイン基板 | 公式詳細なし。 | 大型ヒートシンク、JST 多ピン、電源 MOSFET、センサ IF、アクティブ冷却、電源分配が写真で確認。 citeturn46view2turn47view1turn31view0 | 中〜高 |

| 関節モータ | 自社開発・120 N·m・中空軸・デュアルエンコーダ。 citeturn11search2turn53search0 | エンコーダ方式やドライバ実装位置は公開未確認。 | 高 / 低 |

| 外部コネクタ | 右側に各種 electrical interface。 citeturn24search0turn43search6 | ミラー文書では USB・1GbE・24V/UART/I2C の pinout が記載。 citeturn6view1 | 中 |


## ソフトウェアとファームウェア


PC1 のソフトウェア構成は、公開 SDK の API 群と、第三者逆解析で得られたサービスアーキテクチャがかなりよく噛み合います。逆解析では、G1 の内部に **master_service** が存在し、その配下に **priority → initialization → runtime** という順序でサービスを起動する構成が示されています。起動シーケンスには **net-init, ota-box, ota-update**、続いて **pd-init, lo-multicast, upper_bluetooth, iox-roudi, basic_service**、その後に **motion_switcher, state_estimator, robot_state, ai_sport, ros_bridge, dex3_service_l/r** などが並びます。これは、**PC1 が単なる一枚板ではなく、リアルタイム Linux 上の複数常駐サービス群で歩行・状態推定・ハードウェア抽象化を構成している**ことを示唆します。 citeturn49view1turn49view2


そのなかで最も重要なのは、**basic_service** と **ai_sport** です。逆解析では **basic_service = “Low-level motor control and hardware interface”**、**ai_sport = “AI-based motion control and sports movements”** と説明されています。さらに **state_estimator** と **motion_switcher** が周辺に置かれているため、公開 API から見た PC1 の役割は、ざっくり言えば **basic_service が各関節・IMU・リモコンなどの生ハードウェア I/O と下位サーボを担当し、state_estimator が状態推定、ai_sport が Unitree 標準歩行/姿勢制御、motion_switcher がそのモード切替を担う**という分担に見えます。これは公式がアルゴリズムを明かしていない部分を**最もよく説明する整合的なモデル**です。 citeturn49view3turn32view1turn20view1


リアルタイム実装については、公式は RTOS 名を出していません。逆解析ではカーネルが **PREEMPT_RT 適用の Linux 5.10.176-rt86+** とされており、**PC1 のメイン制御 OS は Linux 系の RT-preempt 構成**である可能性が高いです。したがって、PC1 を「RTOS ベースの専用コントローラ」というより、**RT-preempt Linux 上で master_service と各制御サービスを走らせる構成**と見るのが妥当です。一方で、**各関節ドライブ内部のファームウェアや補助 MCU が別 RTOS を持つか**は公開情報からはわかりません。 citeturn48view3


ブート過程についても、公式のブートローダ説明はありません。ただ、逆解析で **master_service.json**, **/unitree/var/run/master_service.sock**, **startup_sequence**, **service_protections**, RPC handlers が見えているため、少なくとも Linux 起動後は **master_service がサービス起動と監視を引き受ける supervisor** と理解できます。これは「ブートローダ → Linux kernel → master_service → 初期化コマンド → basic_service/iox-roudi → runtime services」という構造を強く示唆します。 citeturn48view3turn49view0turn49view2turn49view4


## 通信とプロトコル


G1 の低レベル通信で公式に明言されているのは、**DDS ベース**であることです。G1 の Basic Services Interface は「low-level communication は DDS protocol を使う」と説明し、G1 の DDS Services Interface では **rt/lowstate**, **rt/lowcmd**, **rt/secondary_imu**, **rt/lf/secondary_imu** などのトピックを公開しています。SDK 側の G1 サンプルもこれに一致しており、**rt/lowcmd へ LowCmd_ を publish、rt/lowstate と rt/secondary_imu を subscribe** する実装です。 citeturn27search1turn25search3turn16search4


公開されたメッセージ構造から、**LowCmd_** の上位レベルには少なくとも **mode_pr**, **mode_machine**, **motor_cmd[]**, **crc** があり、各 **MotorCmd_** には **mode, q, dq, tau, kp, kd** が存在します。G1 の公式文書は **mode_pr** を「Parallel mechanism (ankle and waist) control mode, 0:PR, 1:AB」と説明しており、SDK サンプルも各関節に対して **q / dq / kp / kd / tau_ff** を設定し、最後に CRC32 を付けて送っています。つまり、**公開 low-level API の最終入力は “関節目標位置 + 目標速度 + P/D ゲイン + フィードフォワードトルク”** です。 citeturn38search2turn40search1turn22view1


受信側の **LowState_** には、SDK 実例から見る限り **imu_state**, **motor_state[]**, **wireless_remote[40]**, **mode_machine**, **crc** が含まれます。IMUState は公式に **quaternion, gyroscope, accelerometer, rpy, temperature** を持つと記されており、SDK サンプルは motor state から **mode, q, dq, tau_est, temperature[2], vol, sensor[2], motorstate, reserve[4]** を読んでいます。したがって、外部から見える PC1 の公開状態インターフェースは、**姿勢推定に必要な IMU と、関節の実位置・実速度・推定トルク・温度・電圧・センサフラグ・エラー状態**を含んでいます。 citeturn39search1turn22view3turn22view4


逆解析ベースでは、PC1 の通信ミドルウェアは **DDS/Iceoryx shared memory + ROS 2 Foxy + CycloneDDS 0.10.2 + WebRTC + BLE + MQTT/OTA** の混成です。内部 IPC として **/dev/shm/iceoryx_***、Unix socket として **/unitree/var/run/master_service.sock** と **/unitree/var/run/ota_boxed.sock**、ネットワークでは **DDS/RTPS の base ports 7400/7401**, **WebRTC signaling 8081**, さらに OTA/telemetry 系ポートが観測されています。これにより、**PC2 → PC1 の制御コマンド経路は主に DDS/RTPS** と理解できます。 citeturn48view2turn48view3turn48view0


一方で、ユーザーが知りたい **EtherCAT / CAN / RS‑485 / SPI / I2C / UART** のうち、**PC1 から関節へ向かう内部バス種別は公開されていません。** 公式・逆解析のどちらにも、G1 の内部モータバスを EtherCAT や CAN と断定できる根拠は見当たりません。公開されているのは、あくまでロボット外部向けデバッグ・拡張としての **Ethernet / USB / UART / I2C** であり、オプション手系では RS485 互換性を示す資料もありますが、それを **PC1 の内部サーボバス** に直結させる証拠はありません。したがって、**内部モータバスは未公開**、**UART/I2C は外部拡張側で確認**、**RS485 は手系アクセサリで確認**という整理が最も厳密です。 citeturn6view1turn45search7


```mermaid

flowchart LR

    A[外部PC / アプリ] -->|SSH・ビルド・SDK実行| B[PC2 開発計算機<br/>Jetson Orin NX<br/>192.168.123.164]

    B -->|DDS rt/lowcmd| C[PC1 オペレーション・コントロール計算機<br/>192.168.123.161 推定]

    B -->|DDS rt/arm_sdk| C

    B -->|LocoClient RPC / 高レベルAPI| C

    C -->|state_estimator| D[状態推定]

    C -->|ai_sport| E[標準歩行・姿勢制御]

    C -->|basic_service| F[低レベルモータI/F]

    D --> E

    E --> F

    F -->|公開非開示の内部バス/電力配分| G[関節モータ電子部]

    G --> H[アクチュエータ]

    H -->|dual encoders / motor states| G

    G -->|q dq tau_est temperature vol sensor motorstate| F

    F -->|DDS rt/lowstate| C

    C -->|DDS rt/lowstate / rt/secondary_imu| B

```


上図のうち、**PC2=Jetson Orin NX**, **PC1 は motion control 専用で非公開**, **公開 DDS topics は rt/lowcmd / rt/lowstate / rt/secondary_imu / rt/arm_sdk**, **基本サービス群は ai_sport / state_estimator / motion_switcher / basic_service** という部分は資料で裏づけられています。一方、**PC1→関節の内部バス種別**は未公開なので、図でも「公開非開示」と明記しました。 citeturn11search2turn16search4turn25search3turn32view1turn49view3


## 制御アーキテクチャ


G1 の stock controller の内部アルゴリズムは非公開ですが、公開 API と SDK サンプルから **階層制御構造**はかなり見えます。上位では **LocoClient** が FSM, balance mode, swing height, stand height, velocity, arm task, speed mode を操作し、API として **Damp, Start, Squat, Sit, StandUp, ZeroTorque, StopMove, HighStand, LowStand, Move, BalanceStand, ContinuousGait, WaveHand, ShakeHand** などが定義されています。これは、PC1 標準制御が**有限状態機械とパラメトリックな姿勢/速度コマンド**で外部へサービス化されていることを示します。 citeturn18view2turn20view0turn20view1


低レベルでは、関節ごとに **q, dq, kp, kd, tau** を指定できるため、少なくとも外部 API 観点では **PD + feedforward torque** 型の下位制御則です。G1 のサンプル `g1_ankle_swing_example.cpp` では、29 モータ版モデルに対して Kp/Kd の配列が明示され、`LowCommandWriter()` が **mode=1**, **tau/q/dq/kp/kd**, **CRC32** を送信しています。ここで使われる Kp/Kd はあくまで**サンプルの設定値**であり、Unitree 標準歩行の内部ゲインそのものではありませんが、**外部から与えられる low-level interface の粒度**としては十分に重要です。 citeturn18view0turn22view1


G1 の足首は **並列機構**で、公式文書は **PR mode** と **AB mode** の 2 制御モードを認めています。SDK 側でも `mode_pr` が `LowCmd_` のトップレベルに存在し、サンプルコードは **PR = Series control for Pitch/Roll joints**, **AB = Parallel control for A/B joints** として扱っています。つまり、少なくとも足首まわりには**関節空間の見せ方を切り替える抽象化層**があり、PC1 側がこれを解釈して下位のモータコマンドへ写像していることになります。 citeturn38search0turn38search2turn18view0


上半身側では **rt/arm_sdk** が独特です。G1 の arm SDK サンプルは、腕・腰の関節に対して同じ `LowCmd_` 形式で **q/dq/kp/kd/tau** を送りつつ、**kNotUsedJoint の q 値を “weight” として使う**実装になっています。Unitree 公式の `xr_teleoperate` Wiki は、この weight によって **“actual command = motion control command × (1 - weight) + rt/arm_sdk user command × weight”** という混合になると説明しており、PC1 内部では**標準全身モーションとユーザー上半身制御のブレンド**が行われていることがわかります。 arm SDK サンプル自体の制御周期は **0.02 s = 50 Hz** です。 citeturn25search0turn51view0turn52view0


さらに G1 には、通常の `rt/lowcmd` による完全低レベル制御とは別に、**LocoClient::SwitchToUserCtrl()** でユーザー制御へ移行し、**rt/user_lowcmd** へ送る第三の経路が公開 SDK から確認できます。`SwitchToInternalCtrl()` では **LAST / PASSIVE / WALKRUN** が指定できるため、PC1 標準歩行とユーザー低レベル制御の**排他的な制御権移譲**が設計されていると見られます。これは PC1 が**常に制御 arbitration の中心**にいることを示す重要な痕跡です。 citeturn19view0turn19view1turn45search5


### 制御周期とアルゴリズムに関する公開・観測比較


| 項目 | 公開 SDK / 公式資料 | 論文・観測 | 評価 |

|---|---|---|---|

| G1 low-level SDK 送信周期 | `g1_ankle_swing_example` は **control_dt = 0.002 s**、2 ms recurrent thread。 citeturn18view1turn22view2 | 実質 **500 Hz** の low-level command loop。 | 高 |

| Arm SDK 送信周期 | `g1_arm7_sdk_dds_example` は **control_dt = 0.02 s**。 citeturn52view0 | 実質 **50 Hz**。 | 高 |

| 実機研究での high-level policy | 公式 stock ai_sport の内部周期は非公開。 | 多くの論文が **50 Hz** 推論。 citeturn29search5turn29search6turn29search10turn29search14turn53search1 | 中〜高 |

| 実機研究での low-level interface | 公式 stock ai_sport の内部周期は非公開。 | **200 Hz**, **250 Hz**, **500 Hz** の報告が混在。 citeturn29search10turn53search1turn29search5turn29search14 | 中 |

| アルゴリズム公開度 | 高レベル FSM / 低レベル q,dq,kp,kd,tau API は公開。 citeturn20view1turn40search1 | stock 歩行が PID / WBC / MPC / model-based のどれかは非公開。研究用外付け制御では RL・whole-body tracking・impedance/WBC 系が多数。 citeturn29search6turn29search8turn53search12 | 高 / 低 |


なお、公式サイトで **dexterous hand は force-position hybrid control** と記されているため、**手系では力・位置のハイブリッド制御**が少なくとも Unitree の公開表現として存在します。しかし、これをそのまま **歩行中の PC1 標準ロコモーション制御則**へ外挿することはできません。歩行側の制御理論は依然として非公開です。 citeturn34search6


## 安全機構


G1 の安全は、公開情報を見る限り **ハード故障保護、モード排他、サービス監視、ユーザー緊急介入**が重なった多層構造です。もっとも明示的なのは、**運動制御サービスの競合を避ける排他設計**です。Unitree の low-level control クイックスタートは、**main motion control service must be disabled** と書いており、理由として「low-level control example も motion control service として振る舞い、両者が同じ関節へ制御信号を送って衝突する」ことを挙げています。G1 の debug mode 説明でも、**debug mode は motion control program からの相反信号送信を止めるため**のものだと説明されています。これは、PC1 内に**制御権の仲裁層**があり、競合が明確な失敗モードとして認識されていることを示します。 citeturn43search12turn43search13turn18view1


リモコン系の安全操作も公開されています。公式 quick_start では、**L2 + B** が想定外状態での **emergency stop 的な damped mode** への移行として案内されますが、その結果 **バランスを失って倒れる**可能性があると明示されています。また、**L2 + A** で debug 用の **position mode / diagnostic pose** に入る旨も示されています。つまり、G1 の安全停止は「立位保持のまま停止」ではなく、少なくとも一部モードでは **減衰/脱力寄りの安全遷移**です。これは人型ロボットらしい重要な設計上の制約です。 citeturn38search5turn42search0


通信データ面では、公開 SDK 実装が **CRC32** を low-level frame と state frame の両方で扱っています。受信サンプルは CRC mismatch を検出するとそのフレームをエラーとして捨てます。また、`motorstate()` が非ゼロの関節についてエラーログを出力しており、少なくとも外部 API では**関節エラーの観測点**が設けられています。さらに state には **temperature**, **vol**, **sensor**, **motorstate** が含まれるので、PC1 側は温度異常・センサ異常・モータ状態異常などを下位層から受け取れる設計です。 citeturn21search0turn22view3turn22view4


サービス監視の観点では、逆解析された `service_protections` が興味深いです。そこでは **basic_service** が **ai_sport / state_estimator / robot_state** を保護対象に持ち、**iox-roudi** が **basic_service / ros_bridge** を保護し、**robot_state** が **motion_switcher** を保護する設定が見えます。加えて、セキュリティアーキテクチャとして **service monitoring & auto-restart**, **maximum 30 protection restarts** が記載されています。これは、公開文書に “watchdog” という単語こそないものの、**少なくともソフトウェア監視型 watchdog / supervisor** が存在することを示す有力証拠です。反面、**独立したハードウェア watchdog** や **安全 PLC / STO** の公開証拠は見当たりません。 citeturn49view3turn48view1turn48view4


## 開発者インターフェース


G1 で公開されている主要な開発者向け入口は、まず **PC2 への SSH / SDK 実行**です。公式資料は、G1-EDU の二次開発用計算機 PC2 に **192.168.123.164** でアクセスし、初期アカウント **unitree / 123** を使う旨を案内しています。また G1 との疎通確認として **ping 192.168.123.161** を行わせているため、SDK ハンドブック上も **外部 PC → PC2 → PC1/robot network** という使い方を前提にしていることがわかります。 citeturn12search2turn54search0


高レベル API としては、`unitree_sdk2` 内の **`unitree::robot::g1::LocoClient`** が中心です。このクラスは **GetFsmId / GetFsmMode / GetBalanceMode / GetSwingHeight / GetStandHeight / SetFsmId / SetBalanceMode / SetSwingHeight / SetStandHeight / SetVelocity / SetTaskId / SetSpeedMode / SwitchToUserCtrl / SwitchToInternalCtrl** を提供し、その sugar API として **Damp, Start, Squat, Sit, StandUp, ZeroTorque, StopMove, HighStand, LowStand, Move, BalanceStand, ContinuousGait, WaveHand, ShakeHand** などを定義しています。G1 の「標準歩行・標準姿勢」へアクセスしたい限り、PC1 に対する最も重要な公開 API はこれです。 citeturn18view2turn20view0turn20view1


DDS レベルでは、少なくとも次のエンドポイントが確認できます。**`rt/lowcmd`** は全関節低レベル制御、**`rt/lowstate`** は低レベル状態、**`rt/secondary_imu`** と **`rt/lf/secondary_imu`** は機体 IMU、**`rt/arm_sdk`** は上半身関節の混合制御、そして公開 SDK と実機開発記事から **`rt/user_lowcmd`** がユーザー制御モード用に存在します。これらの topic 群は、**PC1 が標準制御を走らせながら、どの層でユーザーへ割り込み点を与えるか**をかなり明瞭に表しています。 citeturn16search3turn25search3turn16search4turn17view2turn45search5


上半身の開発者インターフェースはやや特殊で、`rt/arm_sdk` では **17 個の制御対象関節**に対して `LowCmd_` を送りつつ、**未使用関節スロット `kNotUsedJoint` の q 値を blend weight** として使います。公式 Wiki によれば、この weight は **標準モーションとユーザーコマンドの線形混合率**です。つまり、G1 の arm SDK は「低レベルコマンドを雑に上書きする」のではなく、**PC1 内部標準動作に対して混合制御として差し込む**よう設計されています。これは PC1 の役割が単なる motor packet forwarder ではないことをよく示しています。 citeturn25search0turn51view0turn52view0


診断・更新の公開窓口としては、逆解析により **master_service RPC** が **GetServiceState / ListServiceState / StartService / StopService / RestartService / ReloadService** を持つこと、**OTA 更新系サービス `ota_box` / `ota_update`** と **`/unitree/var/run/ota_boxed.sock`** があることが確認されています。これらは一般ユーザー向け正式 API 文書ではありませんが、**PC1 内部でサービス運用・更新・再起動のための制御平面が存在する**ことを示します。加えて、一部外部ドキュメント系では PC2 側 webserver から ROS2 サービスの有効化・無効化とログ取得が可能と記述されていますが、これは販売店統合環境に依存する可能性があるため、本報告では参考情報にとどめます。 citeturn48view3turn49view4turn48view0turn13view0


## ギャップと検証方法


現時点で最大のギャップは、**PC1 標準歩行制御の中身が非公開**であることです。公開資料からは **サービス名**, **API**, **トピック**, **周辺サービス構造**, **入力出力の信号形式**までは追えますが、**実際に ai_sport が PID 主体なのか、モデルベースの whole-body controller なのか、MPC なのか、学習ベースなのか**は判断不能です。公式で “AI-based motion control” という表現はありますが、それ以上のアルゴリズム開示はありません。したがって、**制御理論そのものは現時点で非公開**と明確に書くべきです。 citeturn32view1turn20view1


同様に、**PC1→関節の内部バス**、**ガルバニック絶縁の有無**、**ハードウェア watchdog**, **ブート ROM / U-Boot / secure boot**, **各関節ドライブの OS/RTOS**, **エンコーダの方式**, **IMU の具体型番**, **安全インターロック回路**は、今回見つかった公開ソースでは確認できません。とくに EtherCAT/CAN/RS‑485 といったバス種別は、ユーザーが欲しがりやすい一方で、G1 では**公開証拠が乏しい**項目です。ここは「不明」と書くのが最も厳密です。 citeturn31view0turn48view3turn6view1


このギャップを埋めるための**安全で正当な検証方法**としては、まず **所有機体での受動観測**が有効です。具体的には、PC2 から **DDS participant と topic を列挙**し、`rt/lowstate` の publish rate と jitter を測る、`rt/lowcmd` を無送信時/送信時で分けて**パケットキャプチャ**を取る、`SwitchToUserCtrl()` 前後のトピック挙動を比較する、といった方法です。これで **PC2→PC1 の公開制御面**はかなり明確になります。 citeturn16search4turn20view1turn45search5


ハードウェア確認については、**ベンダ許可・保証条件確認のうえで**、胸部カバーを開けて **SoC / RAM / eMMC の型番写真を採る**、コネクタ近傍のシルク印刷を記録する、電源部の絶縁距離や DC/DC 段を観察する、といった**非破壊の目視検査**が第一選択です。逆解析レポートの写真と突き合わせれば、RK3588 仮説や電源配分構造の再確認ができます。 **eMMC の直接吸い出しやデバッグ UART/JTAG の利用は、ベンダ許諾・法令・契約・安全性・保証への影響を十分確認したうえでのみ検討**すべきで、本報告ではそれ以上の手順化はしません。 citeturn46view2turn47view1turn31view0


最後に、今回の調査で特に価値が高かった優先ソースを、**リンク付きの索引**として挙げます。**Unitree G1 Developer Guide**、**Quick Development**、**Basic Services Interface**、**DDS Services Interface**、**G1 Robot Ankle Joint Control Modes**、**`unitree_sdk2` の `g1_loco_client.hpp` / `g1_ankle_swing_example.cpp` / `g1_arm7_sdk_dds_example.cpp`**、**Unitree 公式 `xr_teleoperate` Wiki**、そして **arXiv の G1 reverse-engineering / cybersecurity report** が、PC1 を追ううえで最重要でした。これらを相互参照すると、**PC1 の役割・公開 API・非公開境界・観測された実装**が最もよく見えてきます。 citeturn12search2turn54search0turn27search1turn25search3turn38search0turn17view0turn17view1turn17view2turn25search0turn31view0

Unitree公式から「G1の16GB RAMを、認識に何GB、LLMに何GB、制御に何GB」という標準配分表は公開されていません。

 公開されているのは主に、

  • ハードウェア仕様
  • DDSやSDKのインターフェース
  • 用途別の公式リポジトリ
  • 学習・実機展開の手順

までです。アプリ構成やメモリ配分は開発者側に委ねられています。G1の公式開発資料も、運動制御用コンピュータとJetson開発用コンピュータを分け、Jetson側の仕様を示していますが、CPU・GPU・RAMの利用割合までは規定していません。

Unitree公式が公開している「標準に近いもの」

ファイル/リポジトリの分け方が、実質的な標準構成になっています。

G1内部
├─ Unitree純正モーション制御
│  └─ 立位・歩行・関節安定化
│
└─ Jetson上のユーザーアプリ
   ├─ unitree_sdk2 / ROS 2
   │  └─ DDS通信
   ├─ xr_teleoperate
   │  └─ 遠隔操作・データ収集
   ├─ unitree_lerobot
   │  └─ 模倣学習・推論
   ├─ unitree_rl_lab
   │  └─ RLポリシーの学習・実機展開
   └─ 独自の認識・計画プログラム

Unitree自身も、RL、XR遠隔操作、模倣学習を別プロジェクトとして公開しています。つまり、ひとつの巨大な「G1自律AI」ではなく、必要な機能をモジュールとして組み合わせる設計です。

論文でよく見られる標準構成

G1を使った最近の研究では、次のような階層構造がかなり一般的です。

高レベル
VLM・LLM・タスクプランナー
10~数Hz
        ↓
中レベル
動作生成・経路計画・操作ポリシー
10~50Hz
        ↓
低レベル
RL全身ポリシーまたはWBC
50~100Hz程度
        ↓
関節制御
PD・トルク制御
数百Hz以上

ここで重要なのは、高レベルAIと姿勢制御を分けることです。

LLMやVLMは、

  • 何を取るか
  • どこへ行くか
  • 次に何をするか

を決めます。

全身制御ポリシーは、

  • 足をどこへ出すか
  • 腰や腕をどう動かすか
  • バランスをどう保つか

を決めます。

最新のG1研究でも、VLMによる上位計画と、リアルタイム全身コントローラを別層にする構成が採用されています。HANDOFFはVLM駆動の上位エージェントと、歩行・操作・転倒復帰を統合した低位コントローラを分離しています。

DemoHLMも、高レベルの操作ポリシーと、低レベルの汎用全身コントローラを階層化しています。

ダンスや全身模倣の場合

ダンスでは、次の構成が典型的です。

参照モーション
        ↓
モーション追跡ポリシー
        ↓
関節目標
        ↓
PD制御

ExBody 2は、人間の参照モーションを入力し、RLで学習した単一の全身追跡ポリシーがG1を安定させながら動きを再現します。

つまり、モーションファイルをそのままモーターへ送るのではなく、

録画モーション
+
学習済み安定化コントローラ

として実行します。

自律作業の場合

物を運ぶ、ドアを開ける、棚へ置くといった作業では、

カメラ・深度
    ↓
認識モデル
    ↓
タスク計画
    ↓
手先・歩行目標
    ↓
全身制御ポリシー
    ↓
関節制御

という構成になります。

2026年のULTRAは、視覚などの入力から高レベル目標を受け、モーション追跡だけではなく、目標条件付きの全身動作をG1上で生成する構成を示しています。

一方、ULCは上半身と下半身を別々に制御せず、ひとつの統合ポリシーで歩行と両腕操作を扱う方式を提案しています。つまり、階層分割が一般的ではあるものの、どこまで統合するかは現在も研究対象です。

RAMの現実的な按配

これはUnitree公式値ではありませんが、Jetson Orin NX 16GBで組む場合の現実的な一例です。

OS・CUDA・基本サービス       2~4GB
ROS 2・DDS・センサー処理     1~2GB
カメラ・深度・SLAM           2~5GB
物体認識モデル               1~3GB
全身RLポリシー               数十~数百MB
小型LLM・VLM                 残りの数GB
安全余裕                     2GB前後

全身RLポリシー自体は、LLMほど巨大ではありません。姿勢制御用ネットワークは比較的小さく、むしろカメラ画像、SLAM、VLM、LLMのほうがRAMとGPUを大きく消費します。

そのため実際の設計では、

姿勢制御を最優先
↓
センサー処理と認識
↓
余裕があればローカルLLM

という順になります。

大型LLMを無理に機体内へ置くより、

G1機体内
├─ 姿勢制御
├─ 認識
├─緊急停止
└─ 短期計画

外部PC・サーバー
└─ 大型VLM・LLM・長期記憶

と分けるほうが実用的です。

まとめ

Unitreeが公式に示しているのは、固定された資源配分ではなく、機能別の部品とインターフェースです。

公式に公開
├─ Jetsonの仕様
├─ DDS通信
├─ 高/低レベルSDK
├─ RL学習・展開環境
├─ XR遠隔操作
└─ 模倣学習環境

公式には非公開
├─ 推奨RAM配分
├─ 推奨GPU配分
├─ 標準的な自律判断アーキテクチャ
└─ 純正モーション制御内部

論文上の現在の標準に最も近いのは、

LLM/VLMは低頻度の意味判断、認識モデルは知覚、RLまたはWBCは高速な全身制御、PDは最終関節制御

という階層型です。

ただし、上半身・下半身を分けるか、ひとつの統合ポリシーにするか、モーション生成と追跡を分けるかは、まだ決着していません。G1はちょうど、その「標準按配」を研究している最中のプラットフォームと言えます。

2026年7月11日土曜日

ブラウザで使えるロボットシミュレータ調査(日本語版)

 


結論

Unitree G1をブラウザ上で動かしたい場合、大きく3つの選択肢があります。

① MuJoCo WASM(最もおすすめ)

もし

  • G1のMJCFをそのまま使いたい
  • 本格的な物理シミュレーションをしたい

ならこれがベストです。

現在Google公式のMuJoCoにはJavaScript/WebAssembly版があります。

特徴

  • MJCF対応
  • URDF対応
  • STL・OBJも読める
  • G1公式MJCFをそのまま利用可能
  • ブラウザだけで動作可能

ただし、

「アップロード画面」

などは自分で少し作る必要があります。


② Three.js + URDFLoader(最も簡単)

もし

「G1をブラウザで表示したい」

だけならこれが一番簡単です。

特徴

  • URDF対応
  • ドラッグ&ドロップ対応
  • 関節スライダー
  • Three.jsだけで動く

ただし

物理シミュレーションはありません。

つまり

  • ポーズ変更
  • 可視化
  • GUI

向けです。


③ Three.js + Rapier

中間的な選択肢です。

特徴

  • WebAssembly物理
  • 軽量
  • 高速
  • Three.jsと相性が良い

しかし

URDFやMJCFを直接読む機能はありません。

自分で

  • 関節
  • 剛体
  • コライダ

を作る必要があります。


クラウド型シミュレータ

ブラウザで見えていても、

実際にはサーバで動いているものがあります。

例えば

  • Isaac Sim
  • Gazebo
  • Webots.cloud

です。

これは

ブラウザ
      ↓
GPUサーバ
      ↓
シミュレーション

という構成になります。


ONNXは動く?

結論

はい。

現在は

ONNX Runtime Web

があります。

つまり

ブラウザ
    ↓
ONNX Runtime
    ↓
推論

ができます。

対応

  • WASM
  • WebGPU
  • WebGL
  • WebNN

G1との相性

これはかなり重要です。

Unitree公式のG1には

  • URDF
  • MJCF

の両方が最初から付属しています。

つまり

G1
 ↓
MJCF
 ↓
MuJoCo WASM

という流れが非常に自然です。


比較表

システム物理URDFMJCFブラウザのみおすすめ度
MuJoCo WASM★★★★★★★★★★
Three.js + URDFLoader☆☆☆☆☆×★★★★☆
Three.js + Rapier★★★★☆★★★★☆
Ammo.js★★★★☆××★★★☆☆
PhysX WASM★★★★☆××★★★☆☆
Webots.cloud★★★★☆×クラウド★★★☆☆
Gazebo + GzWeb★★★★★×クラウド★★☆☆☆
Isaac Sim★★★★★クラウド★★★★☆

もしG1をブラウザで動かすなら

レポートでは次の順番を推奨しています。

① MuJoCo WASM

MJCFアップロード

↓

ブラウザ内FSへ保存

↓

mj_loadXML()

↓

物理開始

↓

ONNX追加

もっとも自然な構成です。


② Three.js URDFLoader

URDF読込

↓

OrbitControl

↓

スライダー

↓

ポーズ変更

完成まで数時間程度。


③ Rapier

Three.js

↓

Rapier

↓

剛体生成

↓

関節生成

↓

ONNX

物理を少し入れたいならこれ。


レポート全体の最終結論

調査では次のようにまとめられています。

本格的なG1シミュレーション
MuJoCo WASM

すぐ表示したい
Three.js + URDFLoader

軽量な物理付き
Three.js + Rapier

ヒトガタの表記法

 ヒト型モデルには、世界共通の「人体部位の書き方」が一つあるわけではありません。

実際には、次の4層が重なっています。

  1. ファイル形式:階層・座標・アニメーションをどう保存するか
  2. 骨格構造:どの骨がどの骨の子か
  3. 人体セマンティクス:その骨が「左上腕」「骨盤」など何を意味するか
  4. 命名規則LeftUpperArmupper_arm.Lなど、実際の文字列

このうち、ファイル構造は厳密ですが、骨の名前は多くの場合、暗黙知や制作会社の規約です。VRMやUnity Humanoidのように、人体部位を明示的に規定する仕組みを重ねると、初めて意味まで標準化されます。


代表的な形式

形式主な用途厳密に決まるもの人体部位名
FBXMaya、Blender、Unityなどの受け渡しノード、骨格、スキン、アニメーション原則自由
glTF/GLBWeb、ゲーム、リアルタイム表示ノード階層、関節配列、ウェイト、バインド行列原則自由
VRM人型アバターglTF構造+人体ボーンの意味規定あり
USD/UsdSkel映画・大規模制作パイプラインSkeleton、Joint、Animation、Skin binding部位の意味は原則自由
Unity Humanoidリターゲティング人体部位へのマッピング規定あり
URDFロボットlink、joint、軸、可動範囲、質量原則自由
MJCFMuJoCo物理シミュレーションbody、joint、geom、actuator、sensor原則自由

FBX

FBXは幅広い3Dデータ交換用の形式です。Autodeskも、Maya、3ds Max、MotionBuilderなどの間で3D資産を交換するための形式として位置づけています。人体専用ではないため、骨名をLeftArmにするかupper_arm.Lにするかは、作成者やツールの規約に依存します。

glTF/GLB

glTFでは、ノード階層、ローカル変換、スキンに使用する関節配列、逆バインド行列などが厳密に定義されています。関節は特別な骨オブジェクトではなく、通常のノードをskin.jointsから参照する形です。

しかし、ノードのnameは表示・アプリケーション利用向けの任意文字列であり、一意である保証さえありません。つまりLeftUpperArmと書く義務はありません。

VRM

VRMはglTFの上に、人型であるという意味情報を追加した形式です。

VRM 1.0では、少なくとも次のような人体スロットが定義されます。

hips
spine
head

leftUpperArm
leftLowerArm
leftHand

rightUpperArm
rightLowerArm
rightHand

leftUpperLeg
leftLowerLeg
leftFoot

rightUpperLeg
rightLowerLeg
rightFoot

これらには必須・任意の区別があります。したがってVRMでは、単に骨が存在するだけでなく、「このノードは左上腕である」というマッピングが必要です。

重要なのは、実際のノード名そのものが必ずleftUpperArmである必要はなく、VRMの左上腕スロットに正しく登録されていることです。

USD/UsdSkel

UsdSkelは、スケルトン、スキニングされたメッシュ、関節アニメーションをDCCツール間で交換するためのUSDスキーマです。関節順序、階層、バインド、アニメーションなどを扱えますが、「この関節は人体の左肘」という普遍的な人体辞書を強制するものではありません。

Unity Humanoid

Unity Humanoidはファイル形式ではなく、読み込んだ骨格を人体部位に割り当てる意味付けレイヤーです。

Unityは、

Hips
Spine
Chest
Neck
Head
LeftUpperArm
LeftLowerArm
LeftHand
LeftUpperLeg
LeftLowerLeg
LeftFoot

などをHumanBodyBonesとして厳密に列挙しています。指についてもLeftThumbProximalのような標準スロットがあります。

元のFBX内で骨がBip001_L_Armという名前でも、Unity上でLeftUpperArmに割り当てればHumanoidとして扱えます。


人体部位の名前はどこまで標準なのか

1. 解剖学的な語彙はかなり共通

よく使われる語はおおむね共通しています。

hips / pelvis      骨盤
spine              背骨
chest              胸部
neck               首
head                頭

shoulder            肩
upperArm            上腕
lowerArm            前腕
hand                手

upperLeg            大腿
lowerLeg            下腿
foot                足
toes                つま先

ただし、これは語彙として共通しているだけで、文字列の書式までは統一されていません。

同じ左上腕でも、次のような名前が存在します。

LeftUpperArm
left_upper_arm
upper_arm.L
L_UpperArm
Arm_L
mixamorig:LeftArm
J_Bip_L_UpperArm
DEF-upper_arm.L

意味はほぼ同じですが、別の文字列です。


左右の書き方

代表的な方式は3種類あります。

接頭辞

L_UpperArm
R_UpperArm
LeftUpperArm
RightUpperArm

接尾辞

UpperArm_L
UpperArm_R
upper_arm.L
upper_arm.R

名前空間付き

Character01:LeftArm
mixamorig:LeftArm

左右は原則として、画面を見ている人からではなく、キャラクター本人から見た左右です。


G1の命名規則

G1は人体リグというよりロボット記述なので、名前がより機械的です。

left_hip_pitch_joint

分解すると、

left   左側
hip    股関節
pitch  前後回転
joint  関節

です。

left_hip_pitch_link

なら、

left   左側
hip    股関節付近
pitch  pitch関節の先にある部品
link   剛体

となります。

G1のURDFでは、pelvisからleft_hip_pitch_jointを通ってleft_hip_pitch_linkへ接続され、その次にroll、yaw、kneeと続きます。これは人体部位だけでなく、機械的な回転軸まで名前に含める方式です。

CGリグなら、

LeftUpperLeg
LeftLowerLeg
LeftFoot

程度で済ませるところを、ロボットでは、

left_hip_pitch_joint
left_hip_roll_joint
left_hip_yaw_joint
left_knee_joint

のように、自由度ごとに分割します。


厳密さの段階

ファイル構文:厳密

JSON、XML、ノード番号、親子参照、行列の個数などは厳密です。

たとえばglTFでは、skin.jointsの順序とinverseBindMatricesの順序が一致しなければなりません。

親子構造:厳密

Hips
└─ Spine
   └─ Chest

という接続関係はデータとして明示されます。

親のワールド変換と子のローカル変換を掛け合わせて、子のワールド位置を求めます。glTFでも、子のグローバル変換は親のグローバル変換と自身のローカル変換の積として定義されています。

人体としての意味:形式による

  • FBX単体:ほぼ暗黙
  • glTF単体:ほぼ暗黙
  • USD単体:パイプライン依存
  • VRM:明示的
  • Unity Humanoid:明示的
  • URDF:人体としての意味は基本的に命名者依存

実際の名前:多くは慣習

LeftUpperArmでなければならない、という世界共通規則はありません。

したがって、実務では名前だけで判定せず、

名前
親子関係
左右の位置
骨の向き
人体マッピング

を組み合わせて判定します。


主な留意点

座標系

形式やソフトによって、上方向、前方向、右手系・左手系が異なります。

glTFは右手系で、+Yが上、+Zが前、距離単位はメートル、角度はラジアンです。

読み込み時に座標変換されると、左右反転、180度回転、巨大化・極小化などが起きます。

BoneとJointは同じではない

CGではboneが身体の区間を表すことがあります。

UpperArm bone

ロボットではjointが回転中心、linkが硬い部品です。

shoulder_joint
    ↓
upper_arm_link

したがって、

CGのbone ≒ URDFのlink

と単純に一対一対応させると、少しずれます。

RootとHipsを分ける

よくある構造は、

Root
└─ Hips
   ├─ LeftLeg
   ├─ RightLeg
   └─ Spine

です。

Rootはキャラクター全体の移動用、Hipsは身体の骨盤運動用です。これを同じノードにすると、歩行アニメーションの移動と腰の揺れを分離しにくくなります。

TポーズとAポーズ

同じ骨名でも、初期姿勢やボーン軸が違えば、アニメーションをそのまま移植できません。

リターゲティングでは、

  • 初期姿勢
  • 骨のローカル軸
  • 手足の長さ
  • 肩幅
  • 骨盤高
  • バインド行列

が重要です。名前が一致するだけでは不十分です。

補助骨

実際のリグには人体部位以外も含まれます。

upper_arm_twist
forearm_twist
breast
skirt
hair
weapon_socket
ik_hand
pole_knee

これらはVRMやUnityの基本人体スロットに割り当てられない場合があります。無理に人体ボーンとして扱わず、追加ノードとして保持します。

同名骨

glTFでは名前の一意性は保証されません。Boneという名前が複数存在することも仕様上可能です。プログラムで扱う場合は、名前だけではなくノード番号や完全な階層パスを使用した方が安全です。


実務向けの命名案

人型リグを自分で設計するなら、次の順序に統一すると読みやすくなります。

側_部位_区分_役割

例:

left_arm_upper_bone
left_arm_lower_bone
left_hand_bone

left_arm_ik_ctrl
left_elbow_pole_ctrl

left_hip_pitch_joint
left_thigh_link

CGリグなら、

root
hips
spine_01
spine_02
chest
neck
head

upper_arm.L
forearm.L
hand.L

ロボットなら、

left_shoulder_pitch_joint
left_shoulder_pitch_link
left_elbow_joint
left_forearm_link

が分かりやすいでしょう。

要するに、ファイル形式は骨格を厳密に保存するが、その骨が人体の何であるかは必ずしも保証しない。VRMやUnity Humanoidは、その空白を人体部位マッピングで埋める仕組みです。


順番には2種類あります。

1. 骨格としての順番

人体リグでは通常、中心から末端へ並べます。

Root
└─ Hips / Pelvis
   ├─ Spine
   │  └─ Chest
   │     ├─ Neck
   │     │  └─ Head
   │     ├─ LeftShoulder
   │     │  └─ LeftUpperArm
   │     │     └─ LeftLowerArm
   │     │        └─ LeftHand
   │     └─ RightShoulder
   │        └─ RightUpperArm
   │           └─ RightLowerArm
   │              └─ RightHand
   ├─ LeftUpperLeg
   │  └─ LeftLowerLeg
   │     └─ LeftFoot
   │        └─ LeftToes
   └─ RightUpperLeg
      └─ RightLowerLeg
         └─ RightFoot
            └─ RightToes

原則は、

体幹 → 近位 → 遠位

です。

つまり、

肩 → 上腕 → 前腕 → 手
股関節 → 大腿 → 下腿 → 足

という順番になります。

2. ファイルに書かれる順番

こちらは形式によって異なりますが、必ずしも人体順である必要はありません

たとえばglTFでは、ノードが配列に入っています。

{
  "nodes": [
    { "name": "Head" },
    { "name": "Hips", "children": [2] },
    { "name": "Spine", "children": [0] }
  ]
}

配列上は、

Head
Hips
Spine

の順でも、参照関係によって、

Hips
└─ Spine
   └─ Head

という階層になります。

つまり、配列順より親子参照のほうが重要です。

G1のREADMEの順番

G1の表示は、おそらく深さ優先探索の前順走査です。

簡単にいうと、

  1. 親を書く
  2. 最初の子を末端まで書く
  3. 一段戻る
  4. 次の兄弟を書く

という順番です。

pelvis
    左脚を末端まで
    右脚を末端まで
    torso
        左腕を末端まで
        右腕を末端まで

図にすると、

pelvis
├─ left leg
├─ right leg
└─ torso
   ├─ left arm
   └─ right arm

ですが、文字では、

pelvis
left leg全部
right leg全部
torso
left arm全部
right arm全部

と一直線に並びます。

左右はどちらが先か

これは世界共通ではありません。

よくあるのは、

Left → Right

ですが、

Right → Left

の形式もあります。

左右の順番は、骨格の意味には影響しません。親子関係が正しければよいからです。

ただし、次の場合は順番が重要です。

  • アニメーションのチャンネル配列
  • スキンウェイトのジョイント番号
  • 逆バインド行列
  • MuJoCoのアクチュエータ配列
  • 独自プログラムが番号を前提にしている場合

人体部位名の語順

名前の中の順番にも代表的な型があります。

Unity型

LeftUpperArm

順番は、

左右 → 位置 → 部位

です。

Left + Upper + Arm

snake_case型

left_upper_arm

同じく、

左右 → 位置 → 部位

です。

Blender型

upper_arm.L

順番は、

部位 → 左右

です。

ロボット型

left_hip_pitch_joint

順番は、

左右 → 部位 → 運動軸 → 種類

です。

分解すると、

left
hip
pitch
joint

になります。

リンクなら、

left_hip_pitch_link

です。

実務でおすすめの順番

CGリグなら、

部位_区分.左右

または、

左右_区分_部位

を一貫して使います。

例:

upper_arm.L
lower_arm.L
hand.L

あるいは、

left_upper_arm
left_lower_arm
left_hand

ロボットなら、

左右_部位_軸_種別

が分かりやすいです。

left_shoulder_pitch_joint
left_shoulder_pitch_link
left_elbow_joint
left_forearm_link

要するに、骨格の順番は中心から末端、ファイル上の順番は形式依存、名前の語順は規約依存です。特にG1の一覧は、「親から最初の枝を末端までたどる深さ優先順」と読むのが正確です。