フィジカルAIの実機はWindowsだけで動く|誰でもできるフィジカルAI 第4回:SO-ARM101ロボットアームのセットアップとテレオペ

フィジカルAIの実機はWindowsだけで動く|誰でもできるフィジカルAI 第4回:SO-ARM101ロボットアームのセットアップとテレオペ

第1回でVLMとVLAの違いを整理し、第2回でVLMを自宅PCで動かし、第3回ではVLA「π0.5」をシミュレーション上で成功率100%で動かしました。今回はいよいよ実機です。

先に結論を書きます。Amazonで買えるロボットアーム2本を、WSL2もUbuntuも使わず、Windowsだけでテレオペ(遠隔操作)まで動かせました。 リーダーアームを手で動かすと、フォロワーアームがほぼ遅延なく同じ動きを再現する。開封からここまで、詰まった時間を含めて約2時間です。

第3回はシミュレーションのためにWSL2(Windows上のLinux)が必要でした。今回は逆です。実機の制御はWindowsのコマンドプロンプトだけで完結します。Ubuntuは今も研究者の標準ですが、フィジカルAIが本当に民主化していくなら、Windowsでそのまま動くことは大きな武器です。今回それを自分の手で確かめました。

この記事では、キット選びから、Windowsでのセットアップ、キャリブレーション、カメラ2台つきのテレオペ動作確認までを、実際に詰まった4つのポイントと一緒に書きます。

使った環境は、Windows 11 Pro、AMD Ryzen 9 9950X3D、RTX 5090(VRAM 32GB)、メモリ64GBです。第3回まではRTX 3090でしたが、第6回の学習に備えてPCを新調しました。ただし今回の工程にGPUはほぼ関係ないので、ゲーミングPCクラスなら同じことができます。

今回のゴール(3つ)

  • LeRobot対応の実機ロボットアーム(リーダー+フォロワー)を用意する
  • WSL2なし、Windowsだけでセットアップとキャリブレーションを完了する
  • カメラ2台の映像つきテレオペで、リーダーの動きにフォロワーが追従するところまで確認する

3つ目まで通れば、第5回でやる「人が操縦してお手本データを貯める」の土台が完成します。

買ったのは SO-ARM101 の組立済みキット(約8万円)

購入したのは Hiwonder の「SO-ARM101 AIロボットアームキット Advanced Kit」です。Amazonで81,598円でした。

SO-ARM101は、第1回で紹介した約100ドルアーム「SO-100」の後継にあたる、LeRobot公式対応のオープンソースアームです。リーダー(操作用の黒アーム)とフォロワー(作業用の白アーム)の2本セットで、磁気エンコーダ付きのバスサーボが計12個、グリッパー先端のカメラと環境用カメラの2台が付属します。

Amazonには4つのグレードがあります。

グレード価格内容
DIY Kit¥51,198サーボ・部品のみ(3Dプリントパーツなし)
Starter Kit¥70,398部品一式(自分で組み立て)
Standard Kit¥75,198部品一式+カメラ等
Advanced Kit¥81,5983Dプリントパーツ付属・組立済・カメラ2台込み

私は迷わず組立済みのAdvancedにしました。理由は過去の経験です。サーボモーターを自分で組み立てると、調整で苦労するし、組み立ての最中に壊すことも普通にあります。カメラも、自前のUSBカメラを流用できるとはいえ、付属でセットになっているものなら相性の検証が要りません。3万円の差額は「組み立てと相性調整に溶ける時間」を買う値段です。 本題はアームの組み立てではなく、その先の模倣学習なので、ここで時間を使う理由がありません。

マニュアルはどれが正か:QRコードの一式とWebマニュアルの関係

届いた説明書のQRコードを読むと、Google Driveの共有フォルダに飛びます。中身は、PDFマニュアル(全30ページ)、工程ごとのYouTube動画リンク集、ソースコード(lerobot.zip)、サーボ設定ツール、3Dモデル一式です。

一方、Webにも公式マニュアルがあります。見比べた結論はこうです。

  • PDFマニュアルとWeb版マニュアルは完全に同一内容。Web版はPDFのWeb公開版
  • ただしQR一式には、Web版にない実物が入っている。特に重要なのが動作検証済みスナップショットの lerobot.zip

LeRobotは開発が速く、GitHubの最新版は依存関係が頻繁に変わります。付属のlerobot.zipはメーカーが動作検証したバージョン固定版なので、素直にこれを使うのが「マニュアル通り」であり、Windowsでの依存関係トラブルを避ける保険にもなります。 手順書はPDF(またはWeb版)、コードは付属zip、迷ったら付属動画、という三点セットで進めます。

もうひとつ意外だったのは、このマニュアルがUbuntu前提ではないことです。本文に「以降の手順はUbuntuもWindowsも同じ。ここではWindowsを例に進める」と明記され、スクリーンショットもコマンドプロンプトとデバイスマネージャーです。実機制御はUSBシリアル通信なので、WSL2を挟むとかえってUSBの受け渡し設定(usbipd)が必要になり面倒になります。実機はWindowsネイティブが素直です。

接続とCOMポートの固定:どっちのアームがどのポートか

アーム2本にはそれぞれ電源アダプタとUSBケーブルがあります。ここで大事なのは、1本ずつ接続して、どのアームがどのポートに割り当てられたかを特定することです。

まずフォロワー(白)だけ電源とUSBをつなぎ、デバイスマネージャーの「ポート (COM と LPT)」を開きます。「USB-Enhanced-SERIAL CH343 (COM3)」が現れました。

ドライバは自動で当たり、手動インストールは不要でした。次にリーダー(黒)をつなぐと COM4 が増えます。

このままCOM3/COM4でも動きますが、マニュアルは以降の全コマンドを「リーダー=COM22、フォロワー=COM24」で書いています。合わせておくと再現が楽です。デバイスマネージャーで各ポートを右クリック→プロパティ→「ポートの設定」→「詳細設定」→「COMポート番号」で変更できます。なお同じ画面にある「ビット/秒: 9600」などの値は変更不要です。実際の通信速度はLeRobot側が直接指定するので、ここの表示値は使われません。

USBポートが足りない場合の割り当ても書いておきます。私の環境ではアーム2台・カメラ2台の計4ポートが必要で、直挿しできるポートが足りませんでした。答えはこうです。

  • カメラ2台 → PC本体に直挿し(公式が「2台をハブ経由にするな」と明記。映像は帯域を食い合うため)
  • アーム2台 → USBハブ経由でOK(シリアル通信は帯域をほぼ使わない。モーター電力も専用アダプタから取る)

実際、アームはハブ経由で最後まで問題なく動きました。

Windows側の環境構築:conda環境とlerobot.zip

マニュアル通りMiniconda(私はAnaconda導入済みなのでそのまま流用)で仮想環境を作ります。コマンドプロンプトで次を実行します。

conda create -n lerobot python=3.10.18 ffmpeg=7.1.1 -c conda-forge
conda activate lerobot

ffmpegのバージョン指定は、データ収集時の動画エンコード(libsvtav1対応)のためのマニュアル指定です。

次に、付属の lerobot.zip をデスクトップに展開し、依存パッケージを入れます。

cd C:\Users\hidek\Desktop\lerobot
pip install -e ".[feetech]"

.[feetech] は「このフォルダのLeRobotを、Feetechサーボのドライバ込みで入れる」という意味です。PyTorchなど数GBのダウンロードが走り、最後に Successfully installed lerobot-0.3.4 が出れば完了です。なおマニュアルのコマンドには中国向けミラー指定(-i https://pypi.tuna…)が付いていますが、日本からは外して素のPyPIで問題ありません。

ここまでで、ハードの認識とソフトの準備が完了です。組立済みキットなので、マニュアル3.5節の「サーボID設定」は丸ごとスキップできます(DIYキット向けの工程で、IDは工場設定済みです)。

キャリブレーションとは何か:制限ではなく「翻訳合わせ」

テレオペの前に、両アームのキャリブレーションが必要です。これはリーダーとフォロワーが「同じ物理姿勢のとき、同じ数値になる」ように合わせる作業です。

各サーボは関節の角度を0〜4095の数値で報告しますが、組み付けの個体差で、同じ姿勢でも生の数値はアームごとにバラバラです。そこで、基準姿勢と可動域の端から端を一度記録して、数値を正規化します。テレオペも、この後の模倣学習も、すべてこの正規化された数値の上で動きます。キャリブレーションは動作範囲を制限するための機能ではなく、2本のアーム(さらには他人のロボットやデータセット)との間で姿勢の「翻訳」を合わせる機能です。 だから可動域は常に本当の端から端まで記録します。

コマンドはフォロワーから。

lerobot-calibrate --robot.type=so101_follower --robot.port=COM24 --robot.id=my_awesome_follower_arm

実行するとサーボの力が抜けて手で動かせるようになり、2段階の操作をします。

  1. 「中間姿勢にしてEnter」:アームをまっすぐ上に立てて、グリッパーが正面を向く姿勢にしてEnter。この瞬間の姿勢が全関節の「中心=2047」として記録される
  2. 「全関節を可動域いっぱい動かせ」:6関節すべてを端から端までゆっくり動かす。画面の表(MIN/POS/MAX)がリアルタイム更新されるので、確認してEnterで保存

リーダーも同じです(robotがteleopに変わる点だけ注意)。

lerobot-calibrate --teleop.type=so101_leader --teleop.port=COM22 --teleop.id=my_awesome_leader_arm

結果は C:\Users\hidek.cache\huggingface\lerobot\calibration\ 以下にJSONで保存され、次回からは再計測不要です。

……と、手順だけ書くと簡単ですが、私はここで3回やり直しました。ここからが本題の詰まりポイントです。

詰まり1:MAXに「32931」という異常値が出る

1回目のキャリブレーション結果がこれです。

NAME            |    MIN |    POS |    MAX
shoulder_pan    |    747 |   2040 |   3319
elbow_flex      |      0 |   2045 |  32932

肘(elbow_flex)のMAXが32932。エンコーダは1回転を0〜4095で表すので、明らかに範囲外です。やり直しても、ほぼ同じ値(32931)が再現しました。

種明かしをすると、32768(2の15乗)を超えた値は「負の位置の読み」です。つまり肘が基準の0をまたいで逆側に回り込み、-163が32931として記録されていました。

原因は最初の「中間姿勢」でした。付属のYouTube動画では、アームを直立させずにキャリブレーションを始めており、マニュアルPDFの図(直立姿勢)と食い違っています。 私は動画に従って折りたたみ気味の姿勢でEnterを押していました。中間姿勢が偏っていると、関節を端まで動かしたときに数値が0をまたぎ、符号が反転します。

対処は原理で覚えるのが確実です。Enterを押した瞬間の姿勢が「中心」になるのだから、全関節が両方向に均等に動ける姿勢、つまり直立が正しい。MIN/MAXに32768以上の値が見えたら、初期姿勢を疑ってやり直してください。

詰まり2:gripperを動かし忘れてValueError

2回目はこう怒られました。

ValueError: Some motors have the same min and max values:
['gripper']

グリッパーの爪の開閉を動かし忘れて、min=maxのまま保存しようとしたためです。「全関節を動かす」にはグリッパーの開閉(リーダーなら手元のトリガー)も含まれます。Enterで確定する前に、表の全行が「0〜4095の範囲内で MIN < POS < MAX」になっていることを目視確認する。このひと手間で2回分のやり直しを防げます。

詰まり3:テレオペでフォロワーが直立しない

キャリブレーションを終えてテレオペを起動すると、今度はリーダーを直立させてもフォロワーがほぼ水平のまま、という症状が出ました。

両アームのキャリブレーション結果を並べると、犯人が見えます。

elbow_flex  リーダー:   553〜4134(幅3581 ≒ 315°)
elbow_flex  フォロワー: 1903〜4122(幅2219 ≒ 195°)

2本は同じ機構なので、関節の可動域はほぼ同じ幅になるはずです。リーダーの315°は3Dプリント部品の構造上あり得ない値で、キャリブレーション中に肘を余計に回り込ませた数値を拾っていました。

テレオペは「リーダーの可動域の中で今何%の位置か」を「フォロワーの可動域の同じ%」に写します。片方の可動域が1.6倍広く記録されていると、同じ姿勢が全く別の%になり、角度が大きくズレます。左右で対応する関節の幅(MAX−MIN)が揃っているかは、キャリブレーション品質のいちばん簡単な健全性チェックです。

リーダーだけ再キャリブレーションし(各関節は自然に止まる位置まで、押し込まない)、幅が2208とフォロワーと一致した時点で、テレオペはピタリと揃いました。

詰まり4:再起動するとグリッパー(ID6)だけ消える

もうひとつ、再現性のあるエラーに当たりました。テレオペをCtrl+Cで終了して再実行すると、こうなります。

RuntimeError: FeetechMotorsBus motor check failed on port 'COM24':
Missing motor IDs:
  - 6 (expected model: 777)

フォロワーの6番=グリッパーのサーボだけがバスから応答しない。電源アダプタを挿し直すと直るが、また再発する、という症状です。

サーボは数珠つなぎ配線なので最初はケーブルの緩みを疑いましたが、決め手は別でした。グリッパーが閉じ切った位置にさらに「閉じろ」という指令が行くと、モーターに電流が流れ続けて過負荷保護が働き、電源を入れ直すまで応答しなくなります。実際、キャリブレーションをやり直してグリッパーの可動域が正しく記録されてからは、一度も再発しなくなりました。末端のサーボだけが消えたら、過負荷保護か配線の緩み。第一手は電源の入れ直しです。

テレオペ本番:ほぼ遅延なしで追従する

キャリブレーションが正しければ、テレオペは1コマンドです。

python -m lerobot.teleoperate --robot.type=so101_follower --robot.port=COM24 --robot.id=my_awesome_follower_arm --teleop.type=so101_leader --teleop.port=COM22 --teleop.id=my_awesome_leader_arm

起動した瞬間、フォロワーはリーダーの現在姿勢まで一気に動きます。リーダーを直立付近で持ってから実行し、フォロワーの周囲30cmは物をどかしておいてください。

動き出せば、リーダーを持つ手の動きを、フォロワーが体感でほぼ遅延なく再現します。第2回でVLMに座標を1つ出させるのに12〜33秒かかっていたことを思うと、この即応性は別世界です(テレオペはAI推論を挟まない、ただの姿勢転送なので当然ではあります)。グリッパーもトリガーで開閉できます。

カメラ2台をつなぐ:NVIDIA仮想カメラの罠

次にカメラです。グリッパーカメラ(手先視点)と環境カメラ(俯瞰)をPCに直挿しして、認識を確認します。

lerobot-find-cameras opencv

検出されたカメラの静止画が outputs\captured_images に保存されます。ここで私の環境では4台検出されました。実カメラは2台なのに、です。

内訳は、既設のWebカメラが1台、そして同一の映像が2つ。後者の正体はNVIDIA Broadcastの仮想カメラで、実カメラの映像を複製してもう1台として列挙していました。カメラのindex番号は当てにせず、保存された静止画を見て「どのindexがどのカメラか」を確定させてください。 私の環境ではグリッパーカメラがindex 1、環境カメラがindex 2でした。

環境カメラの画角も2点直しました。90°横倒しに付けていたのを正立させたのと、リーダー(黒アーム)が映り込んでいたのを、フォロワーの作業範囲だけが主役になる向きに変えた点です。後者は次回への布石で、マニュアルのデータ収集の章に「映像にはアームの動きだけ。手や人を映すな」という注意があります。テレオペ中はリーダーの位置に必ず自分の手があるので、リーダーが画角に入る=学習データに手が映り込む、になるわけです。

映像つきテレオペのコマンドがこれです(1行です)。

python -m lerobot.teleoperate --robot.type=so101_follower --robot.port=COM24 --robot.id=my_awesome_follower_arm --robot.cameras="{ fixed: {type: opencv, index_or_path: 2, width: 640, height: 480, fps: 30}, handeye: {type: opencv, index_or_path: 1, width: 640, height: 480, fps: 30}}" --teleop.type=so101_leader --teleop.port=COM22 --teleop.id=my_awesome_leader_arm --display_data=true

–display_data=true を付けると、rerunというビューアが立ち上がり、2台のカメラ映像と、全関節の観測値(observation)・指令値(action)のグラフがリアルタイムで流れます。この画面は眺めていて気づきがあります。いま流れている「2つの映像+関節の数値列」こそが、第5回でそのまま学習データセットになる中身です。 VLAが何を入力に学習するのかが、目の前で可視化されています。

終了と再開の作法

終了には順番があります。Ctrl+Cを押した瞬間に全サーボの力が抜ける設定(disable_torque_on_disconnect)がデフォルトなので、フォロワーが高い姿勢のままだとバタンと倒れます。

  1. リーダーを操作して、フォロワーを机に寝かせた低い姿勢にする
  2. コマンドを打ったターミナル側で Ctrl+C(rerunのウィンドウではなく)
  3. rerunは右上の×で閉じるだけ(表示専用のアプリなので、いつ閉じても影響なし)
  4. 両アームの電源アダプタを抜く

後日再開するときは、ターミナルで conda activate lerobot と cd C:\Users\hidek\Desktop\lerobot をやり直すだけです。キャリブレーションは保存されているので、テレオペのコマンド1発で動きます。

まとめ

  • Amazonで買えるSO-ARM101(組立済みAdvanced Kit、81,598円)で、実機のフィジカルAI環境が自宅に作れる。組立済み+カメラ付属は「調整に溶ける時間」を3万円で買う判断。シミュレーションと違い、実機制御はWSL2不要でWindowsだけで完結する。
  • 手順の本体はシンプル。COMポート固定(リーダー22/フォロワー24)→ conda環境 → 付属lerobot.zipをpip install → 両アームのキャリブレーション → テレオペ。付属のlerobot.zipは検証済みバージョン固定版なので、GitHub最新版より確実。
  • 詰まりどころは4つ。32768超の値が出たら初期姿勢ミス(符号反転)/グリッパーの動かし忘れ/左右の関節の幅(MAX−MIN)の不一致がズレの正体/末端サーボだけ消えたら過負荷保護。この4つを知っていれば、キャリブレーションのやり直しは1回で済む。
  • テレオペの追従はほぼ遅延なし。rerunに流れる「2カメラの映像+関節数値」が、次回そのまま模倣学習のデータセットになる。実機を買う前に第3回のシミュレーションで見極め、買ってからは今回の手順で1日で動く——この順番が投資リスクの少ない入り方。

第5回では、このテレオペを使って人がお手本を実演し、模倣学習用のデータセットを収集します。今回と同じく、詰まった所も含めて正直に書きます。

「自社の作業をロボットに覚えさせたいが、機材選定から実装までの道筋を一緒に整理してほしい」という方は、無料の30分オンライン診断で交通整理できます。実機とシミュレーションのどちらから始めるべきかも、技術顧問として率直にお話しします。

この記事の技術を、現場で実装したい方へ

AI×IoTの技術顧問として、月額契約で継続伴走しています。PoC設計・技術判断・組織設計・ベンダー管理・実装支援まで、現場で動くまで一緒に進めます。受託開発(請負)ではありません。

AI技術顧問サービスの詳細無料30分オンライン診断料金一覧

About The Author

Hideki
東京大学発AIスタートアップでロボット開発室室長・画像解析室室長・動画解析室室長を務め、画像認識関連のAI特許を在籍中に3件取得。その後、KDDIグループでプロダクトリーダーとして自然言語処理パッケージの自社開発を経て、現在はAGRIST株式会社の執行役員CTO 兼 VPoEとして、農業の人手不足解決に向けた収穫ロボットの開発組織を統括しています。AI・ハード・エレキ・通信・クラウド・IoTまでを一気通貫で設計できる視点を強みに、性能だけでなく「感動やワクワク体験」までデザインできるロボットの研究を進めています。並行して、AI coordinatorとして企業のAI導入・教育機関のAI授業・地域の技術相談を月額契約で継続伴走しています。

LEAVE A REPLY

*
*
* (公開されません)