水曜日, 7月 23, 2025
水曜日, 7月 23, 2025
- Advertisment -
ホームニューステックニュースLeRobot SO-101 テレオペから学習データ取得まで

LeRobot SO-101 テレオペから学習データ取得まで


LeRobot SO-101

お手伝いしていた「Hamamatsu Micro Maker Faire 2025」の目玉展示LeRobot SO-101。Seeedさんからお借りすることができました。

ひとまずテレオペ(遠隔操作)で動かすところから、学習データを取得するところまでやってみました。LeRobot SO-101に関しては、ネットにそれなりに情報あるの見かけてたので簡単だろうと思っていましたが、やってみたらそれなりに色々大変でした。ハードウェアはやっぱりハードですね。

ハードウェアとしては組み立て済みのLeRobot SO-101と制御するPCとして、これまたSeeedさんからの貸与品であるところのSeeed reComputer J4012(Jetson Orin NX 16GB)を使用しています。

reComputer(Jetson)のセットアップに関しては、以下記事を参照してください。

https://zenn.dev/karaage0703/articles/04ca258a89a50e

今回はJetsonを使いましたが、普通のLinux PCやMacでもほぼ同じ流れでセットアップできると思います。

リポジトリ動作確認

まずは以下リポジトリで基本的なセットアップをします。公式リポジトリとnpakaさんの記事を参考にしました。

https://github.com/huggingface/lerobot

https://note.com/npaka/n/nd886658ffd4c

リポジトリをクローンします。

$ git clone https://github.com/huggingface/lerobot.git
$ cd lerobot

必要なパッケージをインストールしておきます。以下はLinuxのケースですので、他のOSの場合は公式リポジトリを参考によしなにしてください。

$ sudo apt-get install cmake build-essential python3-dev pkg-config libavformat-dev libavcodec-dev libavdevice-dev libavutil-dev libswscale-dev libswresample-dev libavfilter-dev

Pythonのパッケージ管理、公式はminicondaを推奨していますが、uvを使いたかったのでuvでセットアップしました(なお、lerobot公式はuvでのセットアップをわざわざrevertしたりしているのでuvに対応する気はないようです)。uvのセットアップに関しては以下記事参照してください。

https://zenn.dev/karaage0703/articles/029b45ff78bc57

uvをセットアップしたらlerobotディレクトリ以下で以下実行します。

続いて、以下でデータセットの可視化を試します。

$ uv run python -m lerobot.scripts.visualize_dataset \
    --repo-id lerobot/pusht \
    --episode-index 0

以下のようなメッセージが出て、失敗することもあります。

huggingface_hub.errors.LocalEntryNotFoundError: An error happened while trying to locate the file on the Hub and we cannot find the requested files in the local cache. Please check your connection and try again or make sure your Internet connection is on.
error: Failed to fetch: `https://pypi.org/simple/debugpy/`
  Caused by: request or response body error
  Caused by: error reading a body from connection
  Caused by: connection reset

めげずに何回か実行すると、成功しました。以下のように表示されます。

ロボットキャリブレーション

続いてロボットのキャリブレーションをします。なお、この後使うので最初に説明しておきますが、2つのロボットのうち、レバーがついて人が操作するロボット(写真だと黒いロボット)がLeader。 人の操作に追従して動くロボット(写真の白いロボット)がFollowerとなります。

ロボットのキャリブレーションは、以下の公式サイトとnpakaさんのサイトを参考に実施しました。

https://huggingface.co/docs/lerobot/so101

https://note.com/npaka/n/n88bb52573d90

まずはロボットとPCをUSB-Cで接続して、以下コマンドを実行します。

$ uv run python -m lerobot.find_port

以下のメッセージが出てきます。

Finding all available ports for the MotorsBus.
Ports before disconnecting: ['/dev/ttyACM0', '/dev/ttyGS0', '/dev/ttyTHS2', '/dev/ttyTHS1', '/dev/ttyTCU0', '/dev/ttyS3', '/dev/ttyS2', '/dev/ttyS1', (略) '/dev/ttyAMA0']
Remove the USB cable from your MotorsBus and press Enter when done.

最後に、USBケーブルを抜けと指示があるので、指示のとおり、PCからコネクタを抜いて、Enterキーを押します。すると、以下のようにデバイス名(以下の場合は/dev/ttyACM0)が取得できます。USB接続前後で、デバイス名の差分を取得して、接続したデバイスを特定するスクリプトのようですね。

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

今回は、ttyACM0に特定できました、Linuxの場合は以下のようにパーミッション設定すると、モータをソフトから制御できるようになります(Macの場合は多分不要)。

ただ、このように毎回デバイス名確認して、パーミッション設定するのはめんどうですし、間違いのもとですね。Linuxの場合は、udevルールを使うと便利です。udevルールの使い方は以下記事を参照してください。

https://zenn.dev/karaage0703/articles/d6759ea297dbf8

簡単に手順を書いておきます(詳細は上記記事を確認してください)。USB接続前後で以下コマンドを実行して差分を確認します。

USB接続すると、以下が増えていたので以下がモータのUSBシリアルと確定できます。

Bus 001 Device 006: ID 1a86:55d3 QinHeng Electronics USB Single Serial

今回2つのUSBデバイスが同一のため、区別するためにシリアルを確認する必要があります。シリアルを確認するために、以下のコマンドを実行します。

$ lsusb -v -s 001:006 | grep -i serial

シリアルが取得できます。2台のロボット(Leader, Follower)両方でコマンド実行して、シリアル情報を取得しましょう。

Bus 001 Device 008: ID 1a86:55d3 QinHeng Electronics USB Single Serial
  iProduct                2 USB Single Serial
  iSerial                 3 5AA9018069

続いて、以下のudevルールの設定ファイルを編集します。

/etc/udev/rules.d/99-lerobot-serial.rules

今回は、以下のように2つのロボットをそれぞれ設定します。

SUBSYSTEM=="tty", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="55d3", ATTRS{serial}=="5AA9018069", SYMLINK+="usbserial_lerobot_follower", MODE="0666"
SUBSYSTEM=="tty", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="55d3", ATTRS{serial}=="5AA9017941", SYMLINK+="usbserial_lerobot_leader", MODE="0666"

設定を以下コマンドで反映します。

$ sudo udevadm control --reload

USBケーブルを接続しなおします。すると、以下のようにデバイス名が自動で固定されます。パーミッションも自動で設定されます。

$ ls /dev/usbserial*
/dev/usbserial_lerobot_follower  /dev/usbserial_lerobot_leader

このあとはモータにIDを割り振ります。私はIDが設定された組み立て済みのロボットを使用したので、この手順はスキップしました。ここの手順はABEJAさんの記事がとても詳しいので、参考にするのが良いと思います。

https://tech-blog.abeja.asia/entry/so101-assembly-report-202505

モータの設定が終わったらキャリブレーションを実施します。

lerobotディレクトリで以下コマンドでuvの設定をします。

$ uv sync
$ uv pip install "lerobot[feetech]"

以下コマンドを実行して、フォロワーロボットのキャリブレーションを実施します。

$ uv run python -m lerobot.calibrate \
    --robot.type=so101_follower \
    --robot.port=/dev/usbserial_lerobot_follower \
    --robot.id=lerobot_follower

キャリブレーションは、以下の公式の動画やnpakaさんのサイトを参考に実施しました。

https://huggingface.co/docs/lerobot/so101#calibration-video

流れとしては、Middleという全てのモーターの中間位置のポーズを初期姿勢として、1つずつモーターの角度をMin, Maxまで動かすこととなります。一回やると理屈が分かるかと思います。

続いて、同様に以下コマンド実行して、Leaderロボットのキャリブレーションを実施します。

$ uv run python -m lerobot.calibrate \
    --teleop.type=so101_leader \
    --teleop.port=/dev/usbserial_lerobot_leader \
    --teleop.id=lerobot_leader

これでキャリブレーションは完了です。

テレオペレーション(遠隔操作)

キャリブレーションの後は、テレオペをします。

lerobotディレクトリで以下コマンドでuvの設定をします。モータ関係のライブラリを追加でセットアップしています。

$ uv sync
$ uv pip install "lerobot[feetech]"

あとは以下コマンドでテレオペができます。robot.port, teleop.portは、先ほどudevルールで固定したデバイス名を使用しましょう。

$ uv run python -m lerobot.teleoperate \
    --robot.type=so101_follower \
    --robot.port=/dev/usbserial_lerobot_follower \
    --robot.id=lerobot_follower \
    --teleop.type=so101_leader \
    --teleop.port=/dev/usbserial_lerobot_leader \
    --teleop.id=lerobot_leader

https://x.com/karaage0703/status/1947161084525424864

カメラの確認

以下の公式サイトとnpakaさんの記事を参考にしました。

https://huggingface.co/docs/lerobot/cameras

https://note.com/npaka/n/naf5f1cb6981a

カメラはUSBカメラならなんでもよいのですが、今回はロジクール ウェブカメラ C270nを使いました。

lerobotディレクトリで以下コマンドでuvの設定をします。

$ uv sync
$ uv pip install "lerobot[feetech]"

カメラを接続して、以下コマンドを実行します。

$ uv run python -m lerobot.find_cameras opencv

カメラの情報が表示されます。

--- Detected Cameras ---
Camera #0:
  Name: OpenCV Camera @ /dev/video0
  Type: OpenCV
  Id: /dev/video0
  Backend api: V4L2
  Default stream profile:
    Format: 0.0
    Width: 640
    Height: 480
    Fps: 30.0
--------------------

公式サイトのスクリプトを動かします。width, heightだけカメラに合わせて値を修正しています。

from lerobot.cameras.opencv.configuration_opencv import OpenCVCameraConfig
from lerobot.cameras.opencv.camera_opencv import OpenCVCamera
from lerobot.cameras.configs import ColorMode, Cv2Rotation


config = OpenCVCameraConfig(
    index_or_path=0,
    fps=15,
    width=640,
    height=480,
    color_mode=ColorMode.RGB,
    rotation=Cv2Rotation.NO_ROTATION
)


camera = OpenCVCamera(config)
camera.connect()


try:
    for i in range(10):
        frame = camera.async_read(timeout_ms=200)
        print(f"Async frame {i} shape:", frame.shape)
finally:
    camera.disconnect()

以下のように表示されます。

Async frame 0 shape: (480, 640, 3)
Async frame 1 shape: (480, 640, 3)
Async frame 2 shape: (480, 640, 3)

(略)

Async frame 9 shape: (480, 640, 3)

なお、解像度を修正しないと、以下のようなエラーが出ました。

RuntimeError: OpenCVCamera(0) failed to set capture_width=1920 (actual_width=1280, width_success=True).

カメラはRealSenseにも対応しているようですが、本記事では省略します。

カメラ付きテレオペ(遠隔操作)

カメラ付きのテレオペです。以下公式サイトの記事を参照しました。

https://huggingface.co/docs/lerobot/il_robots#teleoperate-with-cameras

コマンドでも動かせるのですが、今回は、APIを使ってプログラムで動かしてみます。

from lerobot.cameras.opencv.configuration_opencv import OpenCVCameraConfig
from lerobot.teleoperators.so101_leader import SO101LeaderConfig, SO101Leader
from lerobot.robots.so101_follower import SO101FollowerConfig, SO101Follower

camera_config = {
    "front": OpenCVCameraConfig(index_or_path=0, width=640, height=480, fps=30)
}

robot_config = SO101FollowerConfig(
    port="/dev/usbserial_lerobot_follower",
    id="lerobot_follower",
    cameras=camera_config
)

teleop_config = SO101LeaderConfig(
    port="/dev/usbserial_lerobot_leader",
    id="lerobot_leader",
)

robot = SO101Follower(robot_config)
teleop_device = SO101Leader(teleop_config)
robot.connect()
teleop_device.connect()

while True:
    observation = robot.get_observation()
    action = teleop_device.get_action()
    robot.send_action(action)

遠隔操作ができます。カメラをつけたことによある違いはよくわかりませんでした。

学習用データ記録

続いてロボットの学習用データの記録です。以下公式記事とnpakaさんの記事を参考にしました。

https://huggingface.co/docs/lerobot/il_robots#record-a-dataset

https://note.com/npaka/n/n2cf72ded6f51

lerobotディレクトリで以下を実行します。

$ uv sync
$ uv pip install "lerobot[feetech]"
$ uv pip install -U "huggingface_hub[cli]"

HuggingFaceにログインします。あらかじめ、HuggingFaceに登録して、トークンを取得しておいてください。

以下の${HUGGINGFACE_TOKEN}にはトークンを入れます。

$ git config --global credential.helper store 
$ uv run huggingface-cli login --token ${HUGGINGFACE_TOKEN} --add-to-git-credential

以下でユーザー名を取得します。

$ HF_USER=$(uv run huggingface-cli whoami | head -n 1)
$ echo $HF_USER

準備ができたら、以下コマンドで学習を記録します。

$ uv run python -m lerobot.record \
    --robot.type=so101_follower \
    --robot.port=/dev/usbserial_lerobot_follower \
    --robot.id=lerobot_follower \
    --teleop.type=so101_leader \
    --teleop.port=/dev/usbserial_lerobot_leader \
    --teleop.id=lerobot_leader \
    --robot.cameras="{ front: {type: opencv, index_or_path: 0, width: 640, height: 480, fps: 30}}" \
    --display_data=true \
    --dataset.repo_id=${HF_USER}/record-test \
    --dataset.episode_time_s=60 \
    --dataset.reset_time_s=10 \
    --dataset.num_episodes=2 \
    --dataset.single_task="Play drum"

こんな感じで記録ができます。

記録が終わると、ローカルの~/.cache/huggingface/lerobot/以下にデータが保存されると同時に、自動的にHugging Faceにもデータがアップされます。

記録はカメラの固定とか準備とか色々下準備が大変です。

自分は記録中ロボットが暴走してしまいました…

https://x.com/karaage0703/status/1947273853878616483

まとめ

LeRobotのソフトウェアの基本的なセットアップからテレオペ、学習データの取得までを一通り実施しました。

最初、ハードウェアの動作確認のところは少し手間取りましたが、動き出すとスムーズでした。テレオペの操作感もよく、結構丈夫なのでハードウェアとしてよくできているなと感じました。これだけ手軽にテレオペしてロボットのデータを取得してHuggingFaceと連携しているのは素晴らしいなと思いました。

今回はデータの取得までだったので、学習したデータから模倣学習させて動かしてみたり、LeRobotは、ROSに対応しているようなので、ROSで動かすとかもやってみても良いかなと思ったりしました。

参考リンク

https://tech-blog.abeja.asia/entry/so101-imitation-learning-202505

https://zenn.dev/rktm/articles/894b2ffccaf11f

https://tech-blog.abeja.asia/entry/so101-carrying-egg-tpu-202507

https://github.com/AgRoboticsResearch/Lerobot_ros2

https://huggingface.co/spaces/NERDDISCO/LeRobot.js

https://robotdrummer.github.io

https://qiita.com/hEnka/items/eb32983492b8e0c88153

https://zenn.dev/karaage0703/articles/04ca258a89a50e

https://zenn.dev/karaage0703/articles/8fe578dba4857a

https://zenn.dev/kimushun1101/articles/ros2-jazzy-pip

https://so101-remote-work.onrender.com/

関連記事

https://karaage.hatenadiary.jp/entry/2023/04/20/073000

https://zenn.dev/karaage0703/books/3be6bad93b0c8e



Source link

Views: 0

RELATED ARTICLES

返事を書く

あなたのコメントを入力してください。
ここにあなたの名前を入力してください

- Advertisment -