
Unitree G1 を動かす前の基本をまとめてみた
こんにちは、atsuです。
Unitree G1を初めて開発する方に向けて、腕やハンドを動かすコードを書く前の基本のところをまとめます。具体的には、ハードウェアの概要、ネットワークでつなぐ方法、安全な最初の一歩、操作モードの考え方についてです。
本記事では、すべて、G1が立った状態、安全クレーンに繋がれた状態で確認しております。電源投入や軌道シーケンスはモデルやファームウェアによって異なるため、公式ドキュメントとリモコン操作に従ってください。本記事は「G1を起動後に、ネットワークとSDKでつなぐところ」から扱います。
開発環境
本記事では、次の環境で確認しています。
| 環境 | |
|---|---|
| 開発側 PC(本記事の確認環境) | DGX Spark(GB10 / aarch64), Ubuntu 24.04.4 LTS, Python 3.12.3, CUDA 13.0 |
G1 の開発用オンボード(192.168.123.164) |
NVIDIA Jetson Orin NX, Ubuntu 20.04.6 LTS, JetPack 5.1.1(L4T R35.3.1), Python 3.8.10 |
| 接続 | 有線。192.168.123.x のサブネット(開発用 Jetson は .164。ほかにも制御用のオンボード計算機が同サブネットに居ます) |
1点だけ補足します。
- 開発側のPCは、DGX Spark(aarch64)を使って確認しておりますが、unitree_sdk2pyの使い方自体は変わりません。
G1のハードウェアの概要
G1は、29自由度の構成でした。
| 部位 | 自由度 | lowcmd index |
|---|---|---|
| 脚(左右) | 12 | 0–11 |
| 腰(Yaw / Roll / Pitch) | 3 | 12–14 |
| 左腕 | 7 | 15–21 |
| 右腕 | 7 | 22–28 |
腰が可動 3 自由度ある点は、上半身だけを使うときも保持の対象になるので覚えておくとよいです。
センサ・ハンドまわりで、本検証で使ったものは次のとおりです。
- 頭部カメラ:Intel RealSense D435i
- LiDAR:Livox Mid360
- ハンド: Inspire RH56(オプション。左右で別系統)
ハンドや全身の細かい仕様は個体・構成で変わるので、手元の機体の構成を確認してください。
ネットワークでつなぐ
G1 の通信は、既定で 192.168.123.x(Unitree 既定サブネット) を使います。開発用 PC をこのサブネットの固定 IP(マスク 255.255.255.0)にして、有線でつなぎます。USB-LAN アダプタを使う場合は、その NIC を 192.168.123.x に設定します。
つなぎ方を図にすると、こうなります。
通信ミドルウェアは、CycloneDDSで192.168.123.x を持つ 1 枚の NIC に束ねるています。複数 NIC や誤った NIC を指定すると、相手が見つからない(discovery が失敗する)ことがあります。
接続の確認は、コマンドで段階的に行うのが分かりやすいです。
# 1) ロボットとつながっている NIC を探す(192.168.123.x を持つもの/挿したばかりの USB-LAN)
ip -o -4 addr show
# 2) 開発PC をこのサブネットに置く(例: ホスト .99。ロボットの IP と衝突しない値にする)
sudo ip addr add 192.168.123.99/24 dev <NIC名> # 一時設定(再起動で消える)
# 3) ロボットに ping が通るか確認(IP は機体・設定で異なる。例として .164)
ping -c 3 192.168.123.164
Python SDK(unitree_sdk2py)は、公式リポジトリから入れます。インストール元が unitreerobotics の公式リポジトリであることを確認してください(よく似た名前の偽リポジトリを避けるため)。CycloneDDS のビルドを含むので、手順は README に従ってください。
git clone https://github.com/unitreerobotics/unitree_sdk2_python.git
cd unitree_sdk2_python
pip install -e . # 前提・詳細は README に従う
SDK の初期化はこれだけです。
from unitree_sdk2py.core.channel import ChannelFactoryInitialize
ChannelFactoryInitialize(0, "eth0") # 第2引数 = 192.168.123.x を持つ NIC 名
eth0 は環境依存です。USB-LAN だと enxXXXX 等になるので、固定名を直書きせず、192.168.123.x を持つインターフェースを自動検出するようにしておくと、別の機体・アダプタでも動きます。
G1の状態を読む
G1を動かす前に、まずG1の関節の状態を読むのが安全で確実です。状態を読むだけならロボットは動きません。
import time
from unitree_sdk2py.core.channel import ChannelSubscriber, ChannelFactoryInitialize
from unitree_sdk2py.idl.unitree_hg.msg.dds_ import LowState_
ChannelFactoryInitialize(0, "eth0")
st = {}
def on(m):
st["q"] = [m.motor_state[i].q for i in range(35)] # 関節角(rad)
ChannelSubscriber("rt/lowstate", LowState_).Init(on, 10)
time.sleep(1.0) # DDS discovery を待つ
print("右腕(22-28):", [round(st["q"][i], 3) for i in range(22, 29)])
これが読めれば、ネットワークと SDK は正しくつながっています。逆に、いつまでも値が来ない場合は NIC の設定か開始直後の待ち時間(DDS discovery)を見直します。
操作モード(FSM)の基本
G1 は内部に状態(FSM)を持っていて、どのモードにいるかで、できることが変わります。腕を自分のコードで動かす(arm_sdk)には、立っている状態の Lock Stand(LED 青、Main Operation Control) に入れておく必要があります。ここがズレていると、コードを送っても腕は反応しません。
リモコンでの大まかな流れは次のとおりです(詳細・最新は公式に従ってください)。
- 減衰(L2+B)→ ロックスタンド(L2+UP)
- この状態で
rt/arm_sdkから腕を制御する
モードの移り変わりを図にすると、こうなります。
注意点として、減衰(damping)やゼロトルク、吊り下げの状態では、腕の制御は有効になりません。低レベル制御とメインの操作制御は排他なので、「デバッグ系のモードに入れたら腕が動かない」というときは、まずモードを確認します。
安全について
G1実機のソフト開発を行う上で気をつけていることです。
- 安全クレーンを使う。立位の G1 は、保持が外れると倒れます。
- 退避・非常停止したい場合。減衰(L2+B)はその場でトルクを切るだけなので、安全クレーンとつながっていない場合、立位のまま放置すると倒れます。もし安全クレーンと接続いていなくて、緊急時のときは、balance squat(L2+B)でG1の膝を曲げて低く安定させるのがおすすめです。
- 状態の観測だけなら安全です。まず状態を読んで確認し、動かす操作は段階的に検証してます。
まとめ
G1と開発PCをつないで、状態を読んで、モードを理解することができました。本記事がG1をはじめて動かすときの参考になれば幸いです。









