LeRobot documentation

Telefon

Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Telefon

Robotunuzu telefonunuzla (iOS veya Android) kontrol edin.

Bu kılavuzda şunları öğreneceksiniz:

  • iOS/Android telefonu nasıl bağlanır
  • Telefonun duruşunun robotun uç efektor (EE) hedeflerine nasıl eşlendiği
  • Güvenlik sınırlarını, kavrama kontrolünü ve IK ayarlarını nasıl ayarlayabilirsiniz

Robotunuzu telefonla kontrol etmek için ilgili bağımlılıkları şununla yükleyin:

pip install 'lerobot[phone,kinematics,feetech,core_scripts]'

kinematics, örneklerin kullandığı ters kinematiği; feetech, SO-100/SO-101 motorlarını; core_scripts ise kayıt ve görselleştirme araçlarını içerir.

Başlayın

Desteklenen platformlar

  • iOS: HEBI Mobile I/O uygulamasını (ARKit duruş + düğmeler) kullanır. Önce uygulamayı indirin, açın ve örnekler ağınızda keşfederek telefonun duruşunu ve girdilerini aktaracaktır.
  • Android: teleop paketini (WebXR) kullanır. Python sürecini başlattığınızda yerel bir URL yazdırılır. Bağlantıyı telefonunuzda açın, Başlat'a dokunun ve ardından Move'u kullanarak duruşu (pose) yayınlayın.

Bağlantılar:

Telefon yönlendirmesi ve kontroller

  • Yerleşim: Telefonu ekranı yukarı bakacak ve üst kenarı robot kavrayıcısının yönüyle aynı yöne bakacak şekilde tutun. Bu, kalibrasyonun telefonun çerçevesini robot çerçevesiyle hizalamasını ve hareketin doğal hissedilmesini sağlar; referans için aşağıdaki görseli inceleyin.
  • Etkinleştir/kapat — bu bir acil durdurma anahtarıdır, hareketin tamamı boyunca basılı tutmanız gerekir:
    • iOS: B1 tuşuna basılı tutarak robotu hareket ettirin, bırakınca kolun bulunduğu konumda dondurun. Her basış, telefonu kolun mevcut duruşuna yeniden sabitler; böylece bırakabilir, elinizi rahat bir konuma geri getirebilir, tekrar basıp devam edebilirsiniz — robot zıplamaz.
    • Android: WebXR sayfasındaki Move düğmesiyle aynı.
  • Kavrama kontrolü (etkinleştirme düğmesine basılı tutulup tutulmadığından bağımsız olarak çalışır):
    • iOS: Analog kaydırıcı A3, gripper'ı hız girişi olarak kontrol eder — yukarı iterek açın, aşağı çekerek kapatın, ortada bırakarak sabitleyin.
    • Android: A ve B düğmeleri arttırma/azaltma gibi çalışır (A açar, B kapatır). Hızı GripperVelocityToJoint adımında ayarlayabilirsiniz.
  • Tutuş: Telefonu her iki elinizle tutun, bir başparmağınızı etkinleştirme düğmesinin (B1) üzerinde, diğerini ise kavrama kaydırıcısının (A3) üzerinde tutun; böylece kavrayışı değiştirmeden kolu ve kavrayıcıyı aynı anda sürdürebilirsiniz. Bunu yaparken telefonu düz tutun — duruşu komuttur, bu yüzden hareket sırasında tutuşu değiştirmek robotu hareket ettirir.
  • Robot başlangıç pozisyonu: teleoperate.py, başlangıçta (telefon kalibre edilmeden önce) kolu homing pozisyonuna taşır ve Ctrl+C ile betiğin başladığı anda bulunduğu konuma geri döndürür. Homing komutları, kalibrasyon sırasında set_half_turn_homings() tarafından merkezlenen yarım dönüş değerine her gövde eklemine gönderilir — kalibrasyon şemasında tutulan pozisyon — bu sırada gripper olduğu yerde bırakılır, böylece homing işlemi asla bir şeyin üzerine kapanmaz. Bu önemlidir çünkü hedefler, etkinleştirme düğmesine bastığınız anda kolun bulunduğu konumdan IK ile çözülür — katlanmış veya tamamen uzatılmış bir kolun az alanı kalır ve eklem sınırlarına takılır. Diğer örnek betikler (record.py, evaluate.py, replay.py) kolu homing yapmaz, bu nedenle onları başlatmadan önce kendiniz oraya yerleştirin.
Phone teleop orientation

Adım 1: Platformu seçin

Örnekleri PhoneConfig içinde PhoneOS.IOS veya PhoneOS.ANDROID kullanacak şekilde değiştirin. API tüm platformlarda aynıdır, yalnızca girdi kaynağı farklıdır. Tüm örnekler examples/phone_to_so100/ dizinindedir: teleoperate.py, record.py, replay.py, evaluate.py ve rollout.py.

Teleoperasyon örneği:

from lerobot.teleoperators.phone import Phone, PhoneConfig
from lerobot.teleoperators.phone.config_phone import PhoneOS

teleop_config = PhoneConfig(phone_os=PhoneOS.IOS)  # or PhoneOS.ANDROID
teleop_device = Phone(teleop_config)

Adım 2: Bağlayın ve kalibre edin

Phone(teleop_config) oluşturulduğunda ve connect() çağrıldığında kalibrasyon otomatik olarak istenir. Telefonu yukarıda açıklanan konumda tutun, ardından:

  • iOS: Referans pozisyonu yakalamak için B1 tuşuna basılı tutun.
  • Android: WebXR sayfasında referans pozunu yakalamak için Move düğmesine basın.

Neden kalibre edilir? Mevcut duruşu yakalayarak sonraki duruşların robot hizalı bir çerçevede ifade edilmesini sağlarız. Kontrolü etkinleştirmek için düğmeye tekrar bastığınızda, devre dışıyken telefonunuz yeniden konumlandırıldığında kaymayı önlemek için konum yeniden yakalanır.

Adım 3: Bir örnek çalıştırın

Teleoperasyon yapmak, bir veri seti kaydetmek, bir veri setini yeniden oynatmak veya bir politikayı değerlendirmek için örnek scriptlerden birini çalıştırın.

Tüm betikler, robotunuzun yapılandırıldığını ve kalibre edildiğini (ör. SO-100 takipçi) varsayar.

Robotun URDF dosyasını sağlamanız gerekir. Her örnek ters kinematiği çözer; bu işlem kolun kinematik modelini gerektirir ve URDF, LeRobot ile birlikte dağıtılmaz.

Bu öğreticide kullanılan SO-100/SO-101 için, LeRobot deposunda olduğunuzda SO-ARM100 deposundaki SO101 klasörünü examples/phone_to_so100/ içine kopyalayın, böylece dosya examples/phone_to_so100/SO101/so101_new_calib.urdf konumuna yerleşsin:

git clone --depth 1 https://github.com/TheRobotStudio/SO-ARM100.git /tmp/SO-ARM100
cp -r /tmp/SO-ARM100/Simulation/SO101 examples/phone_to_so100/SO101

Dosyayı başka bir yerde saklıyorsanız veya başka bir kolu kullanıyorsanız, betikleri --urdf ile farklı bir dosyaya yönlendirin.

  • Teleoperasyon için bu örneği çalıştırın ve takipçi kolunuzun seri portunu (bulmak için lerobot-find-port kullanın) iletin:

    cd examples/phone_to_so100
    python teleoperate.py --port /dev/tty.usbmodem5A460814411

    --id, kullanılacak depolanan kalibrasyonu seçer ve --urdf, yukarıdaki URDF dosyasına işaret eder.

Örneği çalıştırdıktan sonra:

  • Android: Betiği başlattıktan sonra, telefonunuzda yazdırılan yerel URL'yi açın, Başlat'a dokunun, ardından Move'u basılı tutun.
  • iOS: Önce HEBI Mobile I/O uygulamasını açın; robotu hareket ettirmek için B1 tuşuna basılı tutun. A3 gripper'ı kontrol eder.

Ayrıca, örneklerde gösterilen işlemci adımlarını düzenleyerek eşlemeyi veya güvenlik sınırlarını özelleştirebilirsiniz. Girdileri yeniden eşleyerek (ör. farklı bir analog giriş kullanarak) veya girdi ile kinematik adımlarını değiştirerek hattı diğer robotlara (ör. LeKiwi) uyarlayabilirsiniz. Bununla ilgili daha fazla bilgi Robotlar ve Teleoperatörler için İşlemciler kılavuzunda yer almaktadır.

  • Bir veri seti kaydetmek için bu örneği çalıştırın; bu işlem mutlak uç efektor gözlemlerini ve eylemlerini kaydeder:

    cd examples/phone_to_so100
    python record.py
  • Kaydedilen bölümleri yeniden oynatmak için bu örneği çalıştırın:

    cd examples/phone_to_so100
    python replay.py
  • Önceden eğitilmiş bir politikayı değerlendirmek için bu örneği çalıştırın:

    cd examples/phone_to_so100
    python evaluate.py

Önemli iş akışı adımları ve seçenekleri

  • Kinematikler birden fazla adımda kullanılır. Kinematiklerimizi işlemek için Pinocchio'nun bir sarmalayıcısı olan Placo kullanıyoruz. Robotun URDF'sini ve hedef çerçevesini geçirerek kinematik nesnesini oluşturuyoruz. target_frame_name değerini gripper çerçevesine ayarlıyoruz.

    kinematics_solver = RobotKinematics(
      urdf_path="./SO101/so101_new_calib.urdf",
      target_frame_name="gripper_frame_link",
      joint_names=list(robot.bus.motors.keys()),
    )
    
  • MapPhoneActionToRobotAction adımı, kalibre edilmiş telefon pozunu ve girdileri hedef deltalar ve gripper komutlarına dönüştürür; adımın çıktısı aşağıda gösterilmektedir.

    action["enabled"] = enabled
    action["target_x"] = pos[1] if enabled else 0.0
    action["target_y"] = -pos[0] if enabled else 0.0
    action["target_z"] = pos[2] if enabled else 0.0
    action["target_wx"] = rotvec[1] if enabled else 0.0
    action["target_wy"] = -rotvec[0] if enabled else 0.0
    action["target_wz"] = rotvec[2] if enabled else 0.0
    action["gripper_vel"] = gripper_vel  # Still send gripper action when disabled
  • EEReferenceAndDelta adımı, hedef deltaları mutlak bir EE pozu isteğine dönüştürür ve etkinleştirme sırasında bir referans saklar; end_effector_step_sizes, EE pozu için adım boyutlarıdır ve hareket hızını değiştirmek için değiştirilebilir.

    EEReferenceAndDelta(
        kinematics=kinematics_solver,
        end_effector_step_sizes={"x": 0.5, "y": 0.5, "z": 0.5},
        motor_names=list(robot.bus.motors.keys()),
        use_latched_reference=True,
    ),
  • EEBoundsAndSafety adımı, EE hareketini bir çalışma alanına sınırlar ve güvenlik sağlamak için büyük EE adım sıçramalarını kontrol eder. end_effector_bounds, EE duruşu için sınırlardır ve çalışma alanını değiştirmek için değiştirilebilir. max_ee_step_m, EE duruşu için adım sınırlarıdır ve güvenlik sınırlarını değiştirmek için değiştirilebilir.

    EEBoundsAndSafety(
        end_effector_bounds={"min": [-1.0, -1.0, -1.0], "max": [1.0, 1.0, 1.0]},
        max_ee_step_m=0.10,
    )
  • GripperVelocityToJoint adımı, mevcut ölçülen durumu kullanarak hız benzeri bir kavrama girişini mutlak kavrama konumuna dönüştürür. speed_factor, hızın çarpıldığı katsayıdır.

    GripperVelocityToJoint(speed_factor=20.0)

Farklı IK başlangıç tahminleri

Kine matik adımlarda farklı IK başlangıç tahminleri kullanıyoruz. Başlangıç tahmini olarak ya mevcut ölçülen eklem konumları ya da önceki IK çözümü kullanılır.

  • Kapalı döngü (kayıt/değerlendirme sırasında kullanılır): IK'nin her karede ölçülen eklem noktalarından başlaması için initial_guess_current_joints=True olarak ayarlanır.

    InverseKinematicsEEToJoints(
        kinematics=kinematics_solver,
        motor_names=list(robot.bus.motors.keys()),
        initial_guess_current_joints=True,  # closed loop
    )
  • Açık döngü (replay'de kullanılır): initial_guess_current_joints=False olarak ayarlanır, böylece IK, ölçülen durumdan değil, önceki IK çözümünden devam eder. Bu, geri besleme olmadan replay sırasında eylem kararlılığını korur.

    InverseKinematicsEEToJoints(
        kinematics=kinematics_solver,
        motor_names=list(robot.bus.motors.keys()),
        initial_guess_current_joints=False,  # open loop
    )

Adımların açıklaması

  • MapPhoneActionToRobotAction: kalibre edilmiş telefon duruşunu ve girdileri hedef deltaları ve bir kavrama komutuna dönüştürür. Hareket, bir etkinleştirme sinyaliyle (iOS'ta B1, Android'de Move) kontrol edilir.
  • EEReferenceAndDelta: etkinleştirildiğinde bir referans EE duruşunu kilitler ve bunu hedef deltalarla birleştirerek her karede mutlak bir istenen EE duruşu üretir. Devre dışı bırakıldığında, son komut verilen duruşu göndermeye devam eder.
  • EEBoundsAndSafety: EE duruşunu bir çalışma alanına sınırlar ve güvenlik için sıçramaları hız sınırlar. Ayrıca action.ee.* özelliklerini de tanımlar.
  • InverseKinematicsEEToJoints: IK ile bir EE duruşunu eklem konumlarına dönüştürür. Kapalı döngü kontrol için initial_guess_current_joints=True önerilir; kararlılık için açık döngü oynatmada False olarak ayarlayın.
  • GripperVelocityToJoint: mevcut ölçülen durumu kullanarak hız benzeri bir gripper girdisini mutlak gripper konumuna entegre eder.
  • ForwardKinematicsJointsToEE: kayıt ve EE durumu üzerinde eğitim için gözlemlenen eklem noktalarından observation.state.ee.* değerlerini hesaplar.

Sorun Giderme

  • iOS algılanamadı: HEBI Mobile I/O'nun açık olduğundan ve laptop/telefonunuzun aynı ağda olduğundan emin olun.
  • Android URL'ine ulaşılamıyor: yerel olarak https yerine http kullandığınızdan, betiğin yazdırdığı tam IP adresini kullandığınızdan ve tarayıcınızın giriş yapmasına izin verip sertifika sorununu yoksaydığından emin olun.
  • Hareket ters gibi hissediyor: eksenleri tek tek kontrol edin, ardından MapPhoneActionToRobotAction içindeki işaret dönüşlerini ayarlayın veya kurulumunuza uygun olacak şekilde eksenleri yer değiştirin.
  • Kol neredeyse hiç hareket etmez veya sınırlarına takılır: orta aralıklı bir başlangıç pozisyonundan yeniden başlatın (yukarıya bakın) — IK, kolun mevcut konfigürasyonundan çözülür.
Update on GitHub