Open14

【期間限定】SO-101セットアップ新手順まとめ【後で消す】

なでぃーにきなでぃーにき

ファームウェア更新は確認すること

手順の中でも説明しますが、とにかくモーターのファームウェア更新は確認してください。

なでぃーにきなでぃーにき

全体感

新手順は下記のようになっています。

1. ジョイントの組み立て
   - 各モーターの片側だけに結線してモーター同士は結線しない状態で組み立てる
2. ポート検索
3. モーター初期化
    - ID6から順々にモーターを結線して初期化
4. キャリブレーション
5. (テレオペレーション)

ここらへんは以前とそこまで変わりませんが、ジョイントの組み立て後に結線するのは面倒です。
※ 特にID5のモーター
ここでは以下のように手順を一部変えて紹介します。

1. ポート検索
2. モーター初期化
    - ID6から順々にモーターを結線して初期化
3. ジョイントの組み立て
   - モーター同士を結線した状態で組み立てる
4. キャリブレーション
5. (テレオペレーション)
なでぃーにきなでぃーにき

0. 事前準備

uvのインストール

下記コマンドでインストールしましょう。

# Linux or MacOS
curl -LsSf https://astral.sh/uv/install.sh | sh

# Windows
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
なでぃーにきなでぃーにき

1. ポート検索

以前の手順とはスクリプトの配置箇所が違うことに注意してください。

こちらのスクリプトではアームを接続した状態、切断した状態を比較してどのポートにアームが接続されているかを確認します。
フォロワーアームのモーターバスを接続した状態で下記を実行しましょう。

uv run python lerobot/find_port.py

下記表示が出たらアームの接続を切断してEnterを押下しましょう。

Finding all available ports for the MotorsBus.
Ports before disconnecting: ['/dev/ttyACM1', '/dev/ttyACM0']
Remove the USB cable from your MotorsBus and press Enter when done.

接続/切断が上手くいくと下記のように表示します。

The port of this MotorsBus is '/dev/ttyACM1'
Reconnect the USB cable.

ここで表示した/dev/ttyACM1がアームのポートなのでメモしておいてください。
※上記はWSLでの実行結果、Windowsならば COM3、Macならば/dev/tty.usbmodem...のようになるはず

リーダーアームのモーターバスも同様にポートを確認してください。

なでぃーにきなでぃーにき

旧手順ではポート確認の後に設定ファイルの変更が必要でしたが、新手順ではなくなっています。

なでぃーにきなでぃーにき

2. モーター初期化

フォロワーアームのモーターバスを接続して下記スクリプトを実行してください。

uv run python -m lerobot.setup_motors \
    --robot.type=so101_follower \
    --robot.port={先ほどメモしたフォロワーアームのポート}

※ Windows のコマンドプロンプトで実行するときは改行をしないようにしてください。(以降の説明では省略します)

スクリプト実行後、下記動画のようにID6のモーターからID1のモーターまで結線してEnter押下を繰り返してください。
※ グリップから根元へと接続していくイメージです。
https://huggingface.co/docs/lerobot/so101#setup-motors-video

リーダーアームのモーターバスを接続して下記スクリプトを実行してください。

python -m lerobot.setup_motors \
    --teleop.type=so101_leader \
    --teleop.port={先ほどメモしたリーダーアームのポート}

※ 新スクリプトでは基本的にフォロワーアームの引数はrobot..., リーダーアームの引数はteleop...となっていることに注意してください。
※ フォロワーアーム用のスクリプトをコピーしてポートだけ変える横着をするとミスります。(ソースは私)

なでぃーにきなでぃーにき

4. キャリブレーション

旧手順とは違い、4つのポジションを取る形ではなくなっています

フォロワーアームのモーターバスを接続して下記スクリプトを実行してください。

uv run python -m lerobot.calibrate \
    --robot.type=so101_follower \
    --robot.port={先ほどメモしたフォロワーアームのポート} \
    --robot.id={IDは何でもいいのですが我々が作ったアームは素晴らしいはずなので、特にこだわりがなければmy_awesome_follower_armをつけるのがおススメです}

手順としては下記です。

  1. 下記の表示が出たらミドルポジションにアームを合わせてEnterを押下します。
    Running calibration of my_awesome_follower_arm SO101Follower
    Move my_awesome_follower_arm SO101Follower to the middle of its range of motion and press ENTER....
    
    ミドルポジションは下記のようにID3のモーターあたりで90度に曲げて前方に伸ばす感じです。
  2. 下記表示が出たらは各モーターを可動域いっぱい動かしましょう。
    各モーターを動かすとPOSの値が動いて、各モーターの最大(MAX), 最小(MIN)の可動域を表示します。
    -------------------------------------------
    NAME            |    MIN |    POS |    MAX
    shoulder_pan    |   2038 |   2045 |   2047
    shoulder_lift   |   1210 |   1220 |   2047
    elbow_flex      |   2047 |   2831 |   2831
    wrist_flex      |   2047 |   2048 |   2048
    wrist_roll      |   2045 |   2046 |   2048
    gripper         |   2043 |   2043 |   2048
    
    ※ 全体を動かすと、どのモーターを動かしたかわからなくなるのでID6のグリッパーのみを動かすところから始めてID1の根元のモーターを動作させることをおススメします。
  3. 各モーターの可動域すべて動作させたらEnterを押下します。

上記実行後、キャリブレーションデータをユーザーのキャッシュ(Linuxなら ~/.cache/huggingface/lerobot/calibration/robots/so101_follower/{ID}.json)に書き出します。

実際のキャリブレーションのイメージは下記動画を参照してください。
https://huggingface.co/docs/lerobot/so101#calibration-video

リーダーアームのモーターバスを接続して下記スクリプトを実行してください。

uv run python -m lerobot.calibrate \
    --teleop.type=so101_leader \
    --robot.port={先ほどメモしたリーダーアームのポート} \
    --robot.id={IDは何でもいいのですが我々が作ったアームは素晴らしいはずなので、特にこだわりがなければmy_awesome_leader_armをつけるのがおススメです}

フォロワーアームと同様の操作を行ってください。
こちらのキャリブレーションデータもユーザーのキャッシュ(Linuxなら ~/.cache/huggingface/lerobot/calibration/teleoperators/so101_leader/my_awesome_leader_arm.json)に書き出します。

なでぃーにきなでぃーにき

5. (テレオペレーション)

ここまで実行していれば下記でテレオペレーションが可能になります!
おめでとうございます!

uv run python -m lerobot.teleoperate \
    --robot.type=so101_follower \
    --robot.port={先ほどメモしたフォロワーアームのポート} \
    --robot.id={先ほどキャリブレーションしたフォロワーアームのID} \
    --teleop.type=so101_leader \
    --teleop.port={先ほどメモしたリーダーアームのポート} \
    --teleop.id={先ほどキャリブレーションしたリーダーアームのID}
なでぃーにきなでぃーにき

6. (カメラセットアップ)

普通のカメラが手元になかったのでIntel Realsenseについて記述します。

カメラを接続して下記スクリプトを実行してください。

uv run python lerobot/find_cameras.py realsense

下記のように出てくるのでId、width、height、fpsをメモしておきましょう。

--- Detected Cameras ---
Camera #0:
  Name: Intel RealSense D435
  Type: RealSense
  Id: XXXXXXXXXXXX
  Firmware version: 5.16.0.1
  Usb type descriptor: 2.1
  Physical port: /sys/devices/platform/vhci_hcd.0/usb1/1-3/1-3:1.0/video4linux/video0
  Product id: 0B07
  Product line: D400
  Default stream profile:
    Stream_type: Color
    Format: rgb8
    Width: 640
    Height: 480
    Fps: 15
--------------------
なでぃーにきなでぃーにき

7. (カメラ付きテレオペレーション)

uv run python -m lerobot.teleoperate \
    --robot.type=so101_follower \
    --robot.port={先ほどメモしたフォロワーアームのポート} \
    --robot.id={先ほどキャリブレーションしたフォロワーアームのID} \
    --robot.cameras="{ front: {type: intelrealsense, serial_number_or_name: XXXXXXX, width: 640, height: 480, fps: 15}}" \
    --teleop.type=so101_leader \
    --teleop.port={先ほどメモしたリーダーアームのポート} \
    --teleop.id={先ほどキャリブレーションしたリーダーアームのID} \
    --display_data=true

※ robot.camerasはそれぞれIntel RealsenseのId、width、height、fpsで置き換えます。
実行すると下記のようにカメラ画像 / アーム情報が出るGUIが立ち上がります。

終了するときはGUI左上の「Quit」でGUIを閉じてから、スクリプト実行中のCtr + Cを押下してください。

なでぃーにきなでぃーにき

8. (データセット作成)

デフォルトのデータセット作成ではhuggingfaceにアップロードするところまでがセットです。
huggingfaceにアカウントがない, とりあえずデータセット作りたい方向けに下記スクリプトの実行をお勧めします。

uv run python -m lerobot.record \
    --robot.type=so101_follower \
    --robot.port={先ほどメモしたフォロワーアームのポート} \
    --robot.id={先ほどキャリブレーションしたフォロワーアームのID} \
    --robot.cameras="{ front: {type: intelrealsense, serial_number_or_name: XXXXXXX, width: 640, height: 480, fps: 15}}" \
    --teleop.type=so101_leader \
    --teleop.port={先ほどメモしたリーダーアームのポート} \
    --teleop.id={先ほどキャリブレーションしたリーダーアームのID} \
    --display_data=true \
    --dataset.repo_id={huggingfaceのユーザー名/huggingfaceのデータセット名。適切なものがない場合はmy_awesome_user/my_awesome_record_testのようにしましょう}\
    --dataset.num_episodes=2 \
    --dataset.episode_time_s=30 \
    --dataset.reset_time_s=30 \
    --dataset.single_task="{撮影するタスク名。寿司を握る、缶を掴む、等}" \
    --dataset.push_to_hub=false

引数のdataset...がデータセットにかかわる部分です。
huggingfaceにアップロードしたい場合は--dataset.push_to_hub=falseを削除してください。
-dataset.repo_id{huggingfaceのユーザー名/huggingfaceのデータセット名}の表記です。
実際にhuggingfaceにアップロードする際には適切な{huggingfaceのユーザー名/huggingfaceのデータセット名}を設定してください。

上記を実行後は先ほどのカメラ付きテレオペレーションと同様の画面が出ます。
その後は下記手順で

  1. いい声の男性がデータセットを撮るように掛け声をくれます。
    dataset.episode_time_sで指定した30秒間特定のタスクを撮りましょう。
  2. いい声の男性が環境を元に戻すように掛け声をくれます。
    dataset.reset_time_sで指定した30秒間で元の環境に戻しましょう。
  3. 上記をdataset.num_episodesで指定した2回繰り返します。

上記データをキャッシュ(Linuxなら ~/.cache/huggingface/lerobot/{huggingfaceのユーザー名}/{huggingfaceのデータセット名})に出力します。

これでデータセット完成です!

適宜パラメータを変更しながらデータセットをどんどん作成しましょう!

{huggingfaceのユーザー名}/{huggingfaceのデータセット名}は同じものを再利用できないことには注意してください。