UnitreeGo2を触っています。
第3弾はWebRTC接続で開発!ついに開発っぽいことします。
第1弾は公式アプリ
第2弾はハード回り
WebRTC接続で開発とは?
Pythonを使ってお手軽に開発できます。
参考
公式で環境が用意されているわけではなく、第三者がSDKのようなものを作っています。
2番目のlegion1581さんのunitree_webrtc_connectを使っていきます。
取得できる情報
| 機能 | 説明 |
|---|---|
| LowState(低レベル状態) | IMU(RPY)・全モーターの角度/温度/ロスト・バッテリー状態・脚荷重・電源電圧 |
| SportModeState(動作状態) | 位置・速度・歩行タイプ・ヨー速度・障害物距離・脚位置/速度 |
| MultipleState(複合状態) | ボディ高さ・速度レベル・音量・輝度・UWBスイッチ・障害物回避スイッチ |
| LiDAR 点群 | 3D ボクセルマップデータ(圧縮形式) |
| カメラ映像 | リアルタイム映像ストリーム(H.264) |
| ロボットのマイク音声 | リアルタイム音声ストリーム(48kHz ステレオ PCM) |
操作できるもの
| 機能 | 説明 |
|---|---|
| スポーツモード制御 | 前進・後退・ジャンプ・ダンス・ハンドスタンドなど多数の動作コマンド |
| VUI(LED・輝度・音量) | LED カラー/フラッシュ・輝度の調整・スピーカー音量の変更 |
| 障害物回避 | 障害物回避サービスのオン/オフ切替 |
| スピーカーへの音声送信 | MP3・インターネットラジオ・WAV のストリーミング再生 |
| AudioHub | 音声ファイルのアップロード・UUID 管理・再生 |
| デバイス探索 | マルチキャストでシリアル番号から IP を自動検索 |
ちなみに公式アプリもWebRTC接続しているそうです。
またWebRTC経由の開発は、R&D版ではなくてもできます。
目的
私が作りたいものとしては、犬ロボをデモ展示するとき、お客さんに触ってもらう用のインターフェースを作りたいです。
公式アプリだと動き回る危険な動きも触れてしまいますし、英語だし・・・
なので、お客さんが触っても大丈夫なモーションだけをボタンにしたり、アプリ内でも見られるようなLiDAR取得の点群やカメラ映像をダッシュボード的に表示してこんな情報を取れますよと見せたり、写真撮影などの機能を抜き出したものを作ろうと思っています。
環境
本体:Go2 EDU
Go2 Hardware Version:v2.0
Go2 Software Version:v1.1.15
unitree_webrtc_connect:2.1.2(2026/8/14ver)
PC:Windows11 WSL2 Ubuntu26.04
実行環境:VSCode内ターミナル
準備
https://github.com/legion1581/unitree_webrtc_connect
をクローンして以下を実行
sudo apt update
sudo apt install -y python3-pip portaudio19-dev
pip install unitree_webrtc_connect
AES-128key取得
Go2本体のソフトウェアバージョンが1.1.15以上の場合、接続にAES-128keyが必要です。
バージョンはアプリで接続して、data>robot dogで見れます。
基本的にアップデートして使うと思うのでこれは必要ですね。
このリポジトリをVSCodeで開いてその中のターミナルで以下を実行しました。UnitreeGoアプリで登録したメールアドレスとパスワードが必要です。
unitree-fetch-aes-key --email you@example.com --password '...'
ちなみにこの時点ではまだGo2とPCはつながっていません。Go2がそばになくてもできます。
接続方法
接続方法はアプリと同じく、AP Mode、STA-L Mode (Local Network)、STA-T Mode (Remote)があります。
AP Mode
インターネットがいらない代わりに、Go2のWiFiにPCを直接つなぐ必要があります。その間はPCでSlack等のやり取りができないので、メインPCで作業するなら別のモードがおすすめです。専用端末でやるとき向け。
スマホアプリでAP Mode接続の画面に行き、Create Hot Spotのような画面が出たら、PC側にもこのようなネットワークが表示されるので、アプリで最初に設定しておいたパスワードを入れて接続します。
スマホアプリは落としましょう(※1台しか同時接続できないため)。
このIPは必ず192.168.12.1になっているようで、webrtc_driver.pyの中にハードコードで書かれています。
接続チェック用に作ったオリジナルコードでも接続できることが確認できました。
ちなみにPCをこのWiFiにつながずにAP接続のコードを実行すると以下のようなエラーが出ます。
Robot at 192.168.12.1 is not exposing a signaling port (tried 9991, 8081). Check the IP / power / Wi-Fi network / firewall on the robot.
STA-L Mode (Local Network)
今回は基本これでやります。
任意のWiFiにGo2もPCもつなぎます。
公式アプリでGo2をWiFiモードでつなぎます。
コード内でIPアドレスを書く必要があるので、アプリのDevice>Data>Network informationのwlan0のIPを確認してメモします。
アプリを落とします。
同じWiFiにPCもつなぎます。
サンプルコード内のこのIPの部分を自分のモノに書き換えます。
この方式だと私の環境ではPC側のWiFiが自動で切り替わった時に途切れてしまうというデメリットがありました。
STA-T Mode (Remote)
UnitreeのTURN server経由でつないで、同じWiFiでなくとも遠隔操作できるようです。でも遠隔でGo2の電源を入れる方法はおそらくなさそうなので、どういうときに使うのでしょうね。
補足1:アプリを落とそう
Go2は1台としか同時接続できないので、公式アプリとの接続を切るためにアプリを落とす必要があります。
しかしGo2をAP ModeにしたりWiFiモードにしたりするのは公式アプリが必須なので、公式アプリでそれぞれのモードにしたのち、アプリを落とすという運用になります。
ただ、どこまで継続するか分かりませんが、本体の電源を切って、また電源を入れたあと、公式アプリ接続はせずに、そのままPCからSTA-L Mode接続できました。毎回アプリから設定する必要はなく、基本的には前の設定が残っているようです。
補足2:毎回接続する必要あり
コード実行時に接続しても、実行が終わると接続が切れます。なので接続だけのpyファイルを作っても意味がなく、各機能実行のためのPythonコード内で毎回接続するコードを書く必要があります。
補足3:example内での接続コードについて
リポジトリのexampleに各種機能のサンプルがあります。
デフォルトの接続方法はSTA-L Mode (Local Network)ですが、他の接続方法もコメントアウトで書いています。
しかしいずれもAES-128keyを使った接続方法では書いてないので、自分で足す必要があります。
# 接続方式を選択(使用するものをコメント解除)
# conn = UnitreeWebRTCConnection(WebRTCConnectionMethod.LocalSTA, ip=ROBOT_IP, aes_128_key=AES_128_KEY)
# conn = UnitreeWebRTCConnection(WebRTCConnectionMethod.LocalSTA, serialNumber="B42D2000XXXXXXXX", aes_128_key=AES_128_KEY)
# conn = UnitreeWebRTCConnection(WebRTCConnectionMethod.Remote, serialNumber="B42D2000XXXXXXXX", username="email@gmail.com", password="pass")
# conn = UnitreeWebRTCConnection(WebRTCConnectionMethod.LocalAP, aes_128_key=AES_128_KEY)
サンプル実行
ではさっそく実行します。全部やってみます!
接続の部分のコードやIPは各自で変更している前提です。また私はAIに頼んでコメントやプリント部分は日本語にしています。
audio
音声に関するサンプルコード。Go2のスピーカーやマイクを活用した機能が試せます。
internet_radio/stream_radio.py
インターネットラジオのURLをストリーミングしてロボットのスピーカーで再生します。オンラインのラジオ局を指定することで、ロボットがスピーカーになります。
→最初av.error.HTTPServerError: [Errno 1482175992] Server returned 5XX Server Error reply: 'http://nashe1.hostingradio.ru:80/ultra-128.mp3'
というエラーが出ました。デフォルトのラジオのURLにアクセスできなかったようなので、別のネット上のmp3のURLに置き換えたところ無事動きました。
live_audio/live_recv_audio.py
ロボットのマイク音声をリアルタイムで受信し、PCのスピーカーから出力します。ロボットの周囲の音をPC側で聞くことができます。
→モーターによる雑音が聞こえますが、無事取れました。
mp3_player/play_mp3.py
ローカルに保存されているMP3ファイルをロボットのスピーカーで再生します。
→25行目にmp3へのファイルパスがありますが、音声ファイル自体は配置されていないので自分で用意して配置し、名前を変えます。無事再生されました。
mp3_player/webrtc_audio_player.py
WAVファイルをロボットにアップロードし、UUIDで管理・再生します。AudioHub APIを使用することで、複数の音声ファイルを管理できます。
→audioopというプラグインがないとエラーが出ます。audioop-ltsを入れます。またmp3のファイル名も自分で用意たものに変えましょう。またsudo apt install -y ffmpegでffmpegも必要でした。
もろもろ環境がそろったら、このようなバイナリ変換が行われアップロードされ、終わると音が再生されました。
またすでにアップロードしているAudio(公式アプリからのアップロードも含む)の一覧も表示されていました。
今のサンプルコードだとその既存の音を選んで再生することはできないようなので、AIに頼んで選択して再生するコードも作ってもらいました
save_audio/save_audio_to_file.py
ロボットのマイク音声を指定秒数録音してWAVファイルに保存します。デフォルトでは5秒です。周囲の音を記録したい場合に使用します。
→無事録音できました。

data_channel
データチャンネル経由で取得できる各種センサーデータや制御機能のサンプル
lidar/lidar_stream.py
LIDARボクセルマップデータを受信してターミナルに生データを出力します。3D空間認識の基礎データを確認できます。
→ロボットを伏せ状態にしているとこの状態のまま進みませんでした。
立ち姿勢にしてから実行すると生データが取れました。
lidar/plot_lidar_stream.py
LIDARの3D点群をFlask + Three.jsでブラウザ表示します。CSVへの書き出し・読み込みにも対応しており、可視化されたLIDARデータをインタラクティブに確認できます。
→http://127.0.0.1:8080/で以下のように表示されました!
ただ途中で止まってしまいます。コード的には止める処理はなさそう。
またこれは人間は映らないそうです。
lowstate/lowstate.py
IMU(RPY)・全モーターの角度/温度・バッテリー状態・脚荷重・電源電圧をリアルタイム表示します。ロボットの低レベルな状態を監視するのに便利です。
→とれました。
multiplestate/multiplestate.py
ボディ高さ・輝度・速度レベル・UWBスイッチ・音量などの複合ステータスをリアルタイム表示します。ロボットの現在の設定状態を一覧で確認できます。
→この状態のままとなり情報がとれませんでした。
取れない情報が含まれていたようです。コードを変更
Go2 マルチプルロボットステータス
===================
輝度: 0
障害物回避: 有効
UWBスイッチ: オン
音量: 7/10
===================
obstacles_avoid/obstacles_avoid.py
障害物回避のオン/オフ・状態照会と、WASDキーによるリアルタイム操縦を行います。障害物回避機能の動作確認や、キーボードでの操作練習に使えます。
→動きました。キーボード操作で動きますね。停止は怖いのでやっていません。
障害物回避 — コマンドを選択:
1: 有効化
2: 無効化
3: 現在の状態を照会
4: 操縦 (WASD / 矢印キー / j,lで旋回 — スペース=停止, q=終了)
q: 終了
コマンド: 🕒 Robot Connection Mode : 📡 STA-L (14:25:16)
3
状態: 有効 (code=0)
コマンド: 4
ドライブモード — キーで移動:
W / ↑ = 前進 S / ↓ = 後退
A / ← = 左ストレイフ D / → = 右ストレイフ
J = 左旋回 L = 右旋回
Space = 停止 Q / Esc = ドライブモード終了
[後退] lx=0.0 ly=-0.9 rx=0.0
sportmode/sportmode.py
ノーマル/AIモードの切り替え、前進・後退・Hello動作・逆立ちを順に実行します。基本的な動作コマンドをシーケンシャルに試せます。
→逆立ち等が怖いので未実施。実行する際は気を付けてください。
sportmode_mcf/sportmode_mcf.py
MCFモードの全APIメソッド(40種以上)をインタラクティブメニューで操作します。ファームウェア1.1.7以降で使用可能で、より高度な動作を試すことができます。
→APIの番号を選んで送信するとその通りに動きます。
APIメソッドは以下
利用可能なコマンド:
0: Damp 1001 モーター無効化
1: BalanceStand 1002 バランス起立
2: StopMove 1003 全移動停止
3: StandUp 1004 起立
4: StandDown 1005 伏せ
5: RecoveryStand 1006 転倒後の回復起立
6: Euler 1007 ボディのオイラー角設定 (roll, pitch, yaw)
7: MoveForward 1008 前進 (vx)
8: MoveSideways 1008 横移動 (vy)
9: MoveRotate 1008 回転移動 (vyaw)
10: Sit 1009 座る
11: RiseSit 1010 座りから起き上がる
12: SpeedLevel 1015 速度レベル設定 (int)
13: Hello 1016 ハローのジェスチャー
14: Stretch 1017 ストレッチ
15: ContinuousGait 1019 連続歩行 (int flag)
16: Content 1020 コンテントのジェスチャー
17: Dance1 1022 ダンス1
18: Dance2 1023 ダンス2
19: GetSpeedLevel 1026 速度レベル照会
20: SwitchJoystick 1027 ジョイスティック切り替え (on/off)
21: Pose 1028 ポーズモード開始 (終了はStopMoveで)
22: Scrape 1029 スクレイプ
23: FrontFlip 1030 前方フリップ
24: FrontJump 1031 前方ジャンプ
25: FrontPounce 1032 前方飛びかかり
26: GetState 1034 ロボット状態照会
27: Heart 1036 ハートのジェスチャー
28: StaticWalk 1061 静的歩行 (on/off)
29: TrotRun 1062 トロット走行 (on/off)
30: EconomicGait 1063 省エネ歩行 (on/off)
31: HandStand 2044 逆立ち (on/off)
32: LeftFlip 2041 左フリップ
33: BackFlip 2043 バックフリップ
34: FreeWalk 2045 フリーウォーク (on/off)
35: FreeBound 2046 フリーバウンド (on/off)
36: FreeJump 2047 フリージャンプ (on/off)
37: FreeAvoid 2048 フリー回避 (on/off)
38: ClassicWalk 2049 クラシック歩行 (on/off)
39: BackStand 2050 後方起立 (on/off)
40: CrossStep 2051 クロスステップ (on/off)
41: SetAutoRecovery 2054 自動回復設定 (on/off)
42: GetAutoRecovery 2055 自動回復照会
43: LeadFollow 2056 引っ張り追従 (on/off)
44: SwitchAvoidMode 2058 回避モード切り替え (on/off)
q: 終了
コマンド番号: 🕒 Robot Connection Mode : 📡 STA-L (14:35:17)
4
-> StandDown 戻りコード: code=0
コマンド番号: 3
-> StandUp 戻りコード: code=0
ヒント: StandUp後はジョイントがロックされる場合があります — Move/ジェスチャーコマンドの前にBalanceStand (1002) を実行してください。
コマンド番号: 10
-> Sit 戻りコード: code=0
sportmodestate/sportmodestate.py
IMU・位置・速度・歩行タイプ・障害物距離などスポーツモードの全ステータスをリアルタイム表示します。動作中のロボットの状態を詳細に把握できます。
→表示されました。
Go2 ロボットステータス
===================
モード: 0
進捗: 0
歩行タイプ: 0
脚上げ高さ: 0 m
位置: [-0.418824, -0.68366, 0.31363]
ボディ高さ: 0.330914 m
速度: [0.009529, -0.007053, -0.018982]
ヨー速度: 0.012783
障害物距離: [0, 0, 0, 0]
脚の荷重: [0, 0, 0, 0]
脚位置(ボディ基準): [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
脚速度(ボディ基準): [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
-------------------
IMU - クォータニオン: [0.651525, 0.00574, -0.021911, -0.758289]
IMU - ジャイロスコープ: [-0.012783, 0.006392, 0.012783]
IMU - 加速度計: [0.269348, 0.403423, 9.56723]
IMU - RPY: [0.040729, -0.019847, -1.722371]
IMU - 温度: 80°C
vui/vui.py
LED輝度を0〜10で変化させ、LEDカラー変更・フラッシュ、スピーカー音量を制御します。視覚的・聴覚的なフィードバックをカスタマイズできます。
→ライトの色や音量が変わりました。
現在の輝度レベルを取得中...
現在の輝度レベル: 0
輝度を0から10に増加中...
輝度レベル: 0/10
輝度レベル: 1/10
🕒 Robot Connection Mode : 📡 STA-L (14:51:56)
輝度レベル: 2/10
輝度レベル: 3/10
輝度レベル: 4/10
輝度レベル: 5/10
輝度レベル: 6/10
輝度レベル: 7/10
輝度レベル: 8/10
輝度レベル: 9/10
輝度レベル: 10/10
輝度を10から0に減少中...
輝度レベル: 10/10
輝度レベル: 9/10
輝度レベル: 8/10
輝度レベル: 7/10
輝度レベル: 6/10
輝度レベル: 5/10
輝度レベル: 4/10
輝度レベル: 3/10
輝度レベル: 2/10
輝度レベル: 1/10
輝度レベル: 0/10
LEDの色を5秒間紫に変更中...
LEDの色をシアンに変更してフラッシュ(サイクル: 1000ms)...
現在の音量レベルを取得中...
現在の音量レベル: 7/10
音量を50%(5/10)に設定中...
video
カメラ映像に関するサンプル
camera_stream/display_video_channel.py
ロボットのカメラ映像をOpenCVウィンドウにリアルタイム表示します。ロボットの視点からの映像を確認でき、遠隔監視やデバッグに役立ちます。
→sudo apt install -y libsm6 libxext6で必要なライブラリを入れます。
その後無事ライブ映像が取れました。遅延も少ないですね。
自作アプリ
やっと本題です。デモに使いたい機能だけを組み合わせたUI付きアプリを作ります。
UIはWebで作ります。
考えている機能は3つ
- 取れる情報を全部まとめて表示したダッシュボード
- その場で動く系のモーションを集めた動かしてみようのコーナー
- 撮影してみようのコーナー(カメラからのリアルタイム映像があって、撮影ボタンを押すと結果が表示される)
トップ画面に3つの機能へ続くボタンがある感じです。
ずっとGo2のそばにいるわけでもないので、とりあえずロボットに接続しなくてもUIはhttp://localhost:8080/dashboardで見えるようにして、いろいろ細かいUI修正をしながら作りました。
そしていざ実機で実行。
無事動きました。
- ダッシュボード
負荷もロボットを軽く上から抑えるとちゃんと数値が変化しました。荷重数値の単位はニュートンのようです。(1kgの重さ ≒ 9.8N)
- モーション再生
タップするとモーションが再生されます。お座りをした状態では、ダンス1は動かないという事象もありました。一度起き上がりを押すと、無事ダンス1も動きました。各モーションが終わったら一度基本姿勢に戻るというように変更しました。
- カメラ撮影
リアルタイム映像が見れて、タップすると撮影した静止画がPCにダウンロードできます。
- ライト・音量操作
追加でライトの色を変えたり、音を流すUIも作りました。水色なんてあったんですね!ちゃんと水色に光りました。また点滅させると例えば青だったら青⇔水色で点滅するみたいに色によって、何色+何色で点滅するというのが決まっていました。
またライトの明るさ調整が効くのは白色のみです。公式アプリでもそうですが、明るさ調整すると元が何色でも白色になります。かなりまぶしいので直視しないようにしてください。
スマホ実行環境(未実施)
スマホ単体で実行できるようにしたかったのですが、簡単にはできなさそうです。
R&D版なのでJetsonはついているため、ロボット本体でサーバーを立てて動かすこともできますが、R&D版の要素を使わずに開発できるのがWebRTCのうれしいところだったのに…という気持ちです。
AndroidならTermuxというアプリを使えばPythonを実行できるようですが、未知の領域すぎます。
最後に
独自UIで操作という目的は達成できました。
展示で使うにはもう少し環境の工夫が必要かもしれません。




























