1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

lekiwi のキャリブレーションとテレオペ

1
Last updated at Posted at 2026-01-24

lekiwi のキャリブレーションとテレオペ

はじめに

以下を参考にさせていただきました。貴重な情報のご提供に感謝いたします。
やってみると、エラーがたくさん出ました。
エラー対応で初めてわかったこともあり、忘れないように記録します。

LerobotでLekiwiを使用する方法

LeRobot LeKiwi 入門 (3) - キャリブレーションとテレオペレーション

前提は conda で 仮想環境を構築済みであり、作業ディレクトリが ~/lerobot です。バージョンは、lerobot 0.4.x です。

念のために、Ubuntu 22.04 での手順例をしめします。

conda create -y -n lerobot python=3.10
conda activate lerobot
git clone https://github.com/huggingface/lerobot.git ~/lerobot
conda install ffmpeg -c conda-forge
cd ~/lerobot
pip install -e ".[lekiwi,feetech,zeromq]"

なぜか、zeromq がインストールできませんでしたが、あらためて以下を実行したらインストールできました。

pip install -e ".[zeromq]"

もし、pytorch のバージョン不整合関係でトラブルが起きたら、以下を試してもいいかもしれません(私の場合は、これでトラブルが解消しました)。

pip install torch==2.7.1 torchvision==0.22.1 torchaudio==2.7.1

その後、以下を実行。

python - << 'EOF' import torch, torchvision, torchaudio print(torch.__version__) print(torchvision.__version__) print(torchaudio.__version__) EOF

無事に以下が表示されました。

 2.7.1+cpu 0.22.1 2.7.1

サーボモータにID書き込み

まず、以下のコマンドで、サーボモータドライバの USBポートを調べます。
USBケーブルをPCまたはラズパイにつなぎ、以下を実行します。メッセージにしたがって、ケーブルを外して ENTER を押すと、/dev/ttyACM0 のような表示がでます。

lerobot-find-port

表示が出たら、USBケーブルを接続します。
アクセス権付与のため、以下を実行します。 ttyACM0 の部分は表示された値に置き換えてください。

sudo chmod 666 /dev/ttyACM0

サーボモータを必ず1つずつ接続します。最初は 6 番です。以下を実行します。メッセージにしたがい ENTER を押したら、6番を外して 5番をつなぎ ENTER を押します。同様に、4番、3番、2番、1番、9番、8番、7番 の順に繰り返します。この順番を間違えたら、最初からやり直します。

lerobot-setup-motors \
    --robot.type=lekiwi \
    --robot.port=/dev/ttyACM0

キャリブレーション(ラズパイ)

USBカメラ2台を接続してから、キャリブレーションを開始します。
以下で、キャリブレーションを実施しました。このプログラムは、
/home/###/lerobot/src/lerobot/scripts の中にあります。以下にあります。### はユーザー名です。

lerobot-calibrate \
    --robot.type=lekiwi \
    --robot.id=my_awesome_kiwi

結果は以下の通り。キャリブレーションだけでカメラ使わないのに、何故かカメラの認識をやっています。
つまり、カメラ2台の USBをつないでおかないと実行時にエラーが出ます。

...
INFO 2026-01-22 17:12:00 a_opencv.py:180 OpenCVCamera(/dev/video0) connected.
INFO 2026-01-22 17:12:01 a_opencv.py:180 OpenCVCamera(/dev/video2) connected.
INFO 2026-01-22 17:12:01 i/lekiwi.py:125 my_awesome_kiwi LeKiwi connected.

続きの画面で、ENTER を押します。

Press ENTER to use provided calibration file associated with the id my_awesome_kiwi, or type 'c' and press ENTER to run calibration: c
INFO 2026-01-22 17:13:53 i/lekiwi.py:141 
Running calibration of my_awesome_kiwi LeKiwi

ここで、アームを初期位置に支え持ち、ENTER を押すと、キャリブレーションが開始されます。各サーボの動かせる限界まで手で動かします。動かしている間、サーボの角度の変化が表示されます。

Move robot to the middle of its range of motion and press ENTER....
Move all arm joints except '['arm_wrist_roll', 'base_left_wheel', 'base_back_wheel', 'base_right_wheel']' sequentially through their entire ranges of motion.
Recording positions. Press ENTER to stop...

-------------------------------------------
-------------------------------------------
NAME            |    MIN |    POS |    MAX4
arm_shoulder_pan |    738 |   2179 |   33649
arm_shoulder_lift |    874 |   1842 |   3299
arm_elbow_flex  |    847 |   2215 |   3039
arm_wrist_flex  |    905 |   2040 |   3203
arm_gripper     |   2037 |   2038 |   3480

ENTER で止めると、以下のようにキャリブレーションの結果が保存され、終了処理が実施されます。

Calibration saved to /home/pi/.cache/huggingface/lerobot/calibration/robots/lekiwi/my_awesome_kiwi.json
INFO 2026-01-22 17:16:22 i/lekiwi.py:408 Base motors stopped
INFO 2026-01-22 17:16:22 a_opencv.py:541 OpenCVCamera(/dev/video0) disconnected.
INFO 2026-01-22 17:16:22 a_opencv.py:541 OpenCVCamera(/dev/video2) disconnected.
INFO 2026-01-22 17:16:22 i/lekiwi.py:417 my_awesome_kiwi LeKiwi disconnected.

よく見ると、さっきの一番上の arm_shoulder_pan の MAX が 33649 と表示されています。ENTER の前までは、3364 だったのが、ひと桁増えています。
NAME | MIN | POS | MAX4
arm_shoulder_pan | 738 | 2179 | 33649

キャリブレート結果が正常かどうか不安だったので、cat で確認しました。### はユーザー名です。

cat /home/###/.cache/huggingface/lerobot/calibration/robots/lekiwi/my_awesome_kiwi.json

保存されていた .json ファイルの中身は以下で、特に問題ありませんでした。

{
    "arm_shoulder_pan": {
        "id": 1,
        "drive_mode": 0,
        "homing_offset": -2002,
        "range_min": 738,
        "range_max": 3364
    },
    "arm_shoulder_lift": {
        "id": 2,
        "drive_mode": 0,
        "homing_offset": -1014,
        "range_min": 874,
        "range_max": 3299
    },
    "arm_elbow_flex": {
        "id": 3,
        "drive_mode": 0,
        "homing_offset": 1168,
        "range_min": 847,
        "range_max": 3039
    },
    "arm_wrist_flex": {
        "id": 4,
        "drive_mode": 0,
        "homing_offset": -2044,
        "range_min": 905,
        "range_max": 3203
    },
    "arm_wrist_roll": {
        "id": 5,
        "drive_mode": 0,
        "homing_offset": -2002,
        "range_min": 0,
        "range_max": 4095
    },
    "arm_gripper": {
        "id": 6,
        "drive_mode": 0,
        "homing_offset": 925,
        "range_min": 2037,
        "range_max": 3480
    },
    "base_left_wheel": {
        "id": 7,
        "drive_mode": 0,
        "homing_offset": 0,
        "range_min": 0,
        "range_max": 4095
    },
    "base_back_wheel": {
        "id": 8,
        "drive_mode": 0,
        "homing_offset": 0,
        "range_min": 0,
        "range_max": 4095
    },
    "base_right_wheel": {
        "id": 9,
        "drive_mode": 0,
        "homing_offset": 0,
        "range_min": 0,
        "range_max": 4095
    }
}

キャリブレーション(PC)

こちらは、USBカメラ不要なこともあり、スムーズにできました。

python -m lerobot.calibrate \
    --teleop.type=so101_leader \
    --teleop.port=/dev/ttyACM0 \ 
    --teleop.id=my_awesome_leader_arm

ラズパイをホストにして、PCからリモートでテレオペ

まず、ラズパイで以下を実行し、ラズパイの IP (192.168.###.### みたいな4種類の数字列)を調べます。

hostname -I

次に、PC側の準備です。以下で、PCにつないだサーボコントローラの情報を確認します。今回は、/dev/ttyACM0 でした。

lerobot-find-port

PCの examples/lekiwi/teleoperate.py を書き換えます。
変更するのは、remote_ip の行と port の行です。それぞれ、調べた内容で書き換えます

robot_config = LeKiwiClientConfig(
    remote_ip="192.168.###.###",
    id="my_awesome_kiwi"
)

teleop_arm_config = SO100LeaderConfig(
    port="/dev/ttyACM0", 
    id="my_awesome_leader_arm"
)

なお、この examples/lekiwi/teleoperate.py は以下のように実行します。

python examples/lekiwi/teleoperate.py

ホストにうまくつながらない場合、以下を試してみます。

python examples/lekiwi/teleoperate.py     --robot.address=192.168.###.###

実行時にエラーがでる場合があります。

ModuleNotFoundError: No module named 'zmq'

この場合、以下を実行しました。

curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
python get-pip.py
...
Successfully installed packaging-26.0 pip-25.3 wheel-0.46.2

ただし、以下のエラーが出る可能性があります。

ERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.
lerobot 0.4.3 requires packaging<26.0,>=24.2, but you have packaging 26.0 which is incompatible.

その場合は、以下でなんとかなるはずです(私はなんとかなりました)

python -m pip install "packaging<26.0,>=24.2"
...
Successfully installed packaging-25.0

ここまでくれば、以下をすれば、pyzmqのインストールも大丈夫です。

python -m pip install pyzmq
...
Successfully installed pyzmq-27.1.0

ラズパイのホストプログラムはカメラをチェックするので、認識するか以下で事前に確認しました。

python3 - << 'EOF'
import cv2, time
cap = cv2.VideoCapture("/dev/video2")
time.sleep(2)
ret, frame = cap.read()
print("ret:", ret)
cap.release()

結果は、以下で False でした。

[ WARN:0@12.243] global cap_v4l.cpp:1049 tryIoctl VIDEOIO(V4L2:/dev/video0): select() timeout.
ret: False

USBを指し直して、もう一回実行すると、今度は True で大丈夫そうです。

video0 ret: True

満を持して、ラズパイのホストプログラムを起動します。

python -m lerobot.robots.lekiwi.lekiwi_host     --robot.id=my_awesome_kiwi     --robot.port=/dev/ttyACM0

ところが、こんなエラーが。id=6 のグリッパーの接続の問題のようです。

ConnectionError: Failed to write 'Lock' on id_=6 with '1' after 1 tries. [TxRxResult] Incorrect status packet!

しかし、コネクタを指し直すと、エラーがでなくなったので、気を取り直してラズパイのホストプログラムを実行しました。ところが、USBカメラの認識問題でエラーです。

[ WARN:0@10.374] global cap_v4l.cpp:1049 tryIoctl VIDEOIO(V4L2:/dev/video0): select() timeout.
...
RuntimeError: OpenCVCamera(/dev/video0) read failed (status=False).

USBを指し直すとエラーが出ない場合もあるのですが、不安定だったので、カメラを探さないオプション --robot.cameras={} をつけて、ラズパイで実行しました。

python -m lerobot.robots.lekiwi.lekiwi_host   --robot.id=my_awesome_kiwi   --robot.port=/dev/ttyACM0   --robot.cameras={}

実行時の画面表示は以下で、カメラ関係のエラーはでなくなりました。ただし、タイムアウト設定が 0.5秒(500mS)と短く、その間にPCのプログラム examples/lekiwi/teleoperate.py を起動できませんでした。その結果、このホストプログラムは、PCからのコマンドを受け付けることができず、終了しました。

WARNING:root:No command available
...
WARNING:root:No command available
WARNING:root:Command not received for more than 500 milliseconds. Stopping the base.
Cycle time reached.
Shutting down Lekiwi Host.

ラズパイのホストプログラム実行後に、PC側を実行しましたが、ホストのタイムアウトに間に合いませんでした。

PCのプログラムにもタイムアウト時間が設定されており、PCのプログラムを先に立ち上げると、ラズパイ(ホスト)が立ち上がる前にPC側が先にタイムアウトします。

仕方がないので、ホストプログラムのタイムアウト設定を変更します。ホストプログラムは、同じホルダー内にある config_lekiwi.py を参照しており、その中の以下の部分を書き換えて、タイムアウトを5秒(5000ms)にしました。

    # Watchdog: stop the robot if no command is received for over 0.5 seconds.
    # watchdog_timeout_ms: int = 500
    watchdog_timeout_ms: int = 5000

ラズパイで、再び以下を実行し、いそいでPC側のプログラムも実行しました。

python -m lerobot.robots.lekiwi.lekiwi_host   --robot.id=my_awesome_kiwi   --robot.port=/dev/ttyACM0   --robot.cameras={}

つながりました!!!
実行時の画面表示は以下で、タイムアウトが5秒(5000ms)になり、接続できました。ただし、30秒で Cycle time に到達し、プログラムは自動的に終了しました。

WARNING:root:No command available
...
...
WARNING:root:Command not received for more than 5000 milliseconds. Stopping the base.
WARNING:root:No command available
...
...WARNING:root:No command available
Cycle time reached.
Shutting down Lekiwi Host.

60秒つなぎたい場合は、 config_lekiwi.py の以下の部分の 30 を 60 書き換えます。

    # Duration of the application
    connection_time_s: int = 30

車両を動かす場合は、キーボードを使います。
w: 前進、s:後退、a:左進、d:右進、z:左回転、x:右回転
r:速度up、f:速度down

速度は以下の3種類です。

速度モード 直線速度 (m/s) 回転速度 (deg/s)
高速 0.4 90
中速 0.25 60
低速 0.1 30

なお、実行時に rerun が自動的に起動していますので、確認ください。

終わりに

やる前は簡単に動くと思っていましたが、やり始めると色々トラブルが発生して、結構苦しみました。
最後のタイムアウト問題が一番の難関でした。最終的には、無事に動いたのでよかったです。

追記

その後、古いノートPCに入れ替えました。PC接続のリーダーアームでラズパイ接続のフォロワーアームをテレオペできたのですが、キーボードで車両を動かすことができませんでした。

色々調べて試行錯誤したところ、マウスの動きを画面に反映させたり、ウィンドウを描画したりする「ディスプレイサーバー」の問題であることがわかりました。

ログイン画面の右下にある「歯車アイコン」でWayland から X11(X.Org)へ切り替えることで、キーボードでの車両コントロールができるようになりました。古いPCでうまく動作しない場合は、試してみるとよいかもしれません。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?