LeRobot documentation

Unitree G1

You are viewing main version, which requires installation from source. If you'd like regular pip install, checkout the latest stable version (v0.6.1).
Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Unitree G1

يُؤيَّد الروبوت humanoid Unitree G1 في LeRobot. يمكنك إجراء التشغيل عن بُعد، وتدريب سياسات locomanipulation، واختبارها في المحاكاة، وغير ذلك. كما يُؤيَّد كلا المتغيرين بـ 29 و 23 درجة حرية (DoF).

اختيار التجسيد

تختار فئة UnitreeG1 تعريفات مفاصلها من خلال UnitreeG1Config.embodiment. القيمة الافتراضية هي g1_29؛ وبالتالي تحتفظ التكوينات الحالية بسلوك G1-29. اختر تخطيط 23-DoF باستخدام --robot.embodiment=g1_23 أو في Python:

from lerobot.robots.unitree_g1 import UnitreeG1Config

config = UnitreeG1Config(embodiment="g1_23", is_simulation=False)
القدرةG1-29G1-23
إعداد مشترك وميزات الإجراء/الملاحظة29 مفصلًا في الجسم، 14 مفصلًا في الذراعين23 مفصلًا للجسم، 10 مفاصل للذراعين
تخطيط أمر DDS/التغذية الراجعة29 فتحات نشطة29 فتحة بمفاصل غائبة تُترك غير نشطة
محاكاة MuJoCoمدعومغير مدعوم بعد؛ مخطط لنموذج أصلي
متحكمات الحركةGR00T وHolosomaGR00T وHolosoma
متحكم الجسم الكامل SONICمدعومغير مدعوم؛ تتطلب السياسة 29 درجة حرية
تعويض الجاذبيةمدعوم، غير مفعّل افتراضيًاغير مدعوم بعد؛ الحركيات الأصلية مخطط لها

تستخدم كلتا النسختين نفس تخطيط رسالة DDS المكوّن من 29 خانة. تستخدم G1-29 جميع الخانات الـ 29، بينما تستخدم G1-23 23 خانة وتُبقي الخانات الست المخصصة للمفاصل غير الموجودة غير نشطة. لذلك تبقى متجهات kp وkd وdefault_positions بطول 29 عنصراً وتُفهرس حسب خانة DDS. خانات الذراع النشطة في G1-23 هي 15..19 و22..26. لا تحتوي الخانات 13, 14, 20, 21, 27, 28 على مفصل نشط؛ ويجب أن تكون قيم الإعداد الخاصة بها صفراً. يتم استبعادها من ميزات الإجراء/الملاحظة، ولا يُعاد ترقيمها. تُصفَّر إدخالات الأوامر غير النشطة والمحجوزة قبل نشر رسالة G1-23. يجب أن تكون تجاوزات الكسب الصريحة قيماً نهائية وغير سالبة، وأن تستخدم نفس التخطيط المتناثر. الكسب الافتراضي مشترك بين النسختين عبر اسم المفصل، لذا تستخدم المفاصل الفيزيائية المتطابقة كسباً متطابقاً بينما تبقى خانات G1-23 غير الموجودة صفراً.

لا يُدعم بعد محاكاة MuJoCo الأصلية لـ G1-23. يؤدي اختيار تجسيد G1-23 مع تفعيل المحاكاة إلى فشل قبل تهيئة النقل. من المخطط توفير نموذج MuJoCo أصلي لـ G1-23 في إصدار مستقبلي.


الجزء 1: البدء

قم بتثبيت وحدة تطوير Unitree

اتبع دليل تثبيت unitree_sdk2_python. تم الاختبار باستخدام unitree_sdk2py==1.0.1 وcyclonedds==0.10.2:

conda create -y -n lerobot python=3.12
conda activate lerobot
git clone https://github.com/unitreerobotics/unitree_sdk2_python.git
cd unitree_sdk2_python
pip install -e .
cd ..

تثبيت LeRobot

conda install ffmpeg -c conda-forge
conda install -c conda-forge "pinocchio>=3.0.0,<4.0.0"
git clone https://github.com/huggingface/lerobot.git
cd lerobot
pip install -e '.[unitree_g1]'
For now, pinocchio must be installed from conda-forge (not pip) to include the CasADi bindings needed for arm IK.

اختبار التثبيت (محاكاة)

لبيئة المحاكاة تبعياتها الخاصة. تحقق من تبعيات بيئة المحاكاة: Unitree G1 Mujoco EnvHub.

pip install mujoco loguru msgpack msgpack-numpy
lerobot-teleoperate \
  --robot.type=unitree_g1 \
  --robot.is_simulation=true \
  --teleop.type=unitree_g1 \
  --teleop.id=wbc_unitree \
  --robot.cameras='{"global_view": {"type": "zmq", "server_address": "localhost", "port": 5555, "camera_name": "head_camera", "width": 640, "height": 480, "fps": 30, "warmup_s": 5}}' \
  --display_data=true \
  --robot.controller=GrootLocomotionController

سيؤدي هذا إلى تشغيل محاكاة MuJoCo لروبوت G1. يمكنك توصيل جهاز تحكم باللعبة بجهازك قبل التشغيل للتحكم في حركة الروبوت داخل المحاكاة. ندعم كلًا من HolosomaLocomotionController و GrootLocomotionController عبر --robot.controller.

  • اضغط على 9 لإطلاق الروبوت
  • اضغط على 7 / 8 لزيادة / تقليل ارتفاع الخصر

اختيار الطرف النهائي

--robot.end_effector يحدد ما تحمله الأذرع: dex1 للمقابض المتوازية (وهو الافتراضي)، أو dex3 لليد ذات الأصابع الثلاث، أو dummy للمعصمين العاريين. في المحاكاة، يختار هذا الخيار نموذج MuJoCo، الذي يحدد محركات الأصابع والكاميرات التي يحملها المشهد — حيث تُركَّب كاميرات المعصم على الطرف الفعّال، لذا فإن dummy يحتوي فقط على head_camera.

lerobot-teleoperate \
  --robot.type=unitree_g1 \
  --robot.is_simulation=true \
  --robot.end_effector=dex3 \
  --teleop.id=wbc_unitree \
  --robot.controller=GrootLocomotionController

تنشر المحاكاة كاميرات النموذج عبر ZMQ على المنفذ --robot.sim_camera_port (5555 افتراضيًا)، وهو المكان الذي تقرأ منه الكاميرات zmq المحددة في --robot.cameras الصور. مرّر --robot.sim_publish_images=false لفتح نافذة MuJoCo التفاعلية بدلاً من ذلك: فالمحاكاة تعرض إما كاميراتها أو نافذتها، وليس كليهما معًا، لأن سياقات العرض دون شاشة تنتمي إلى الخيط الذي أنشأها وليس إلى عارض الصور. يحدد --robot.sim_onscreen هذا الاختيار صراحةً بدلاً من تركه للكاميرات، ويُرفض طلب كلا الخيارين معًا؛ اضبطه مع --robot.sim_publish_images على false لعرض أيٍّ منهما، وهو ما يمكن لجهاز بلا شاشة فعله.

الاتصال بالروبوت الفعلي

عنوان IP الخاص بشبكة الإيثرنت لجهاز G1 ثابت عند 192.168.123.164. يجب أن يكون لجهازك عنوان IP ثابت في نفس الشبكة الفرعية: 192.168.123.x حيث x ≠ 164.

# Replace 'enp131s0' with your ethernet interface name (check with `ip a`)
sudo ip addr flush dev enp131s0
sudo ip addr add 192.168.123.200/24 dev enp131s0
sudo ip link set enp131s0 up

الاتصال بالروبوت عبر SSH

ssh unitree@192.168.123.164
# Password: 123

مشاركة الإنترنت عبر إيثرنت

تحتاج G1 إلى الوصول إلى الإنترنت لاستنساخ المستودعات وتثبيت الحزم. شارك اتصال حاسوبك المحمول عبر كابل Ethernet:

على حاسوبك المحمول:

sudo sysctl -w net.ipv4.ip_forward=1

# Replace wlp132s0f0 with your WiFi interface name
sudo iptables -t nat -A POSTROUTING -o wlp132s0f0 -s 192.168.123.0/24 -j MASQUERADE
sudo iptables -A FORWARD -i wlp132s0f0 -o enp131s0 -m state --state RELATED,ESTABLISHED -j ACCEPT
sudo iptables -A FORWARD -i enp131s0 -o wlp132s0f0 -j ACCEPT

على G1:

sudo ip route del default 2>/dev/null || true
sudo ip route add default via 192.168.123.200 dev eth0
echo "nameserver 8.8.8.8" | sudo tee /etc/resolv.conf

# Verify
ping -c 3 8.8.8.8

تثبيت وحدة تطوير Unitree على G1

اتبع دليل تثبيت unitree_sdk2_python:

conda create -y -n lerobot python=3.12
conda activate lerobot
git clone https://github.com/unitreerobotics/unitree_sdk2_python.git
cd unitree_sdk2_python
python -m pip install -e .
cd ..

تثبيت LeRobot على G1

git clone https://github.com/huggingface/lerobot.git
cd lerobot
conda install -c conda-forge "pinocchio>=3.0.0,<4.0.0"
python -m pip install -e '.[unitree_g1]'
For now, pinocchio must be installed from conda-forge (not pip) to include the CasADi bindings needed for arm IK.

(اختياري) تفعيل الواي فاي على الروبوت

للوصول عبر SSH لاسلكيًا، يمكنك تفعيل WiFi على G1 (إنه محظور افتراضيًا):

sudo rfkill unblock all
sudo ip link set wlan0 up
sudo nmcli radio wifi on
sudo nmcli device set wlan0 managed yes
sudo systemctl restart NetworkManager

الاتصال بشبكة واي فاي:

nmcli device wifi list

sudo nmcli connection add type wifi ifname wlan0 con-name "YourNetwork" ssid "YourNetwork"
sudo nmcli connection modify "YourNetwork" wifi-sec.key-mgmt wpa-psk
sudo nmcli connection modify "YourNetwork" wifi-sec.psk "YourPassword"
sudo nmcli connection modify "YourNetwork" connection.autoconnect yes
sudo nmcli connection up "YourNetwork"

ip a show wlan0

يمكنك بعد ذلك استخدام SSH عبر WiFi بدلاً من Ethernet:

ssh unitree@<ROBOT_WIFI_IP>
# Password: 123

الجزء 2: التشغيل عن بُعد والحركة

تشغيل خادم الروبوت

على الروبوت (من ~/lerobot):

cd ~/lerobot
python src/lerobot/robots/unitree_g1/run_g1_server.py --camera

تشغيل سياسة الحركة

يمكنك تشغيل عميل التشغيل عن بُعد من جهازك المحمول عبر إيثرنت، أو عبر واي فاي (تجريبي)، أو مباشرة على الروبوت نفسه. انتبه إلى أي زمن استجابة محتمل قد يضيفه شبكتك.

من حاسوبك المحمول:

lerobot-teleoperate \
  --robot.type=unitree_g1 \
  --robot.is_simulation=false \
  --robot.robot_ip=<ROBOT_IP> \
  --teleop.type=unitree_g1 \
  --teleop.id=wbc_unitree \
  --robot.cameras='{"global_view": {"type": "zmq", "server_address": "<ROBOT_IP>", "port": 5555, "camera_name": "head_camera", "width": 640, "height": 480, "fps": 30}}' \
  --display_data=true \
  --robot.controller=HolosomaLocomotionController

ندعم كلًا من GrootLocomotionController و HolosomaLocomotionController عبر --robot.controller.


الجزء 3: التلاعب الحركي باستخدام الهيكل الخارجي هومونكولوس

نوفر حلاً للتحكم في الحركة والتلاعب عبر هيكل Homunculus الخارجي — وهو هيكل خارجي مفتوح المصدر بـ 7 درجات حرية للتحكم في الجسم بالكامل. يمكنك الاطلاع عليه هنا.

المعايرة

lerobot-calibrate \
  --teleop.type=unitree_g1 \
  --teleop.left_arm_config.port=/dev/ttyACM1 \
  --teleop.right_arm_config.port=/dev/ttyACM0 \
  --teleop.id=exo

أثناء المعايرة، حرّك كل مفصل عبر نطاقه الكامل. بعد الضبط، ضع المفصل في وضع محايد واضغط n للمتابعة.

تسجيل مجموعة بيانات

lerobot-record \
  --robot.type=unitree_g1 \
  --robot.is_simulation=true \
  --robot.cameras='{"global_view": {"type": "zmq", "server_address": "localhost", "port": 5555, "camera_name": "head_camera", "width": 640, "height": 480, "fps": 30}}' \
  --teleop.type=unitree_g1 \
  --teleop.left_arm_config.port=/dev/ttyACM1 \
  --teleop.right_arm_config.port=/dev/ttyACM0 \
  --teleop.id=exo \
  --dataset.repo_id=your-username/dataset-name \
  --dataset.single_task="Test" \
  --dataset.num_episodes=2 \
  --dataset.episode_time_s=5 \
  --dataset.reset_time_s=5 \
  --dataset.push_to_hub=true \
  --dataset.streaming_encoding=true \
  --dataset.encoder_threads=2

ملاحظة: احذف --teleop.left_arm_config.port و--teleop.right_arm_config.port إذا كنت تستخدم عصا التحكم فقط.

مجموعة بيانات مثال: nepyope/unitree_box_move_blue_full


الجزء 4: التدريب والاستدلال

تدريب

python src/lerobot/scripts/lerobot_train.py \
  --dataset.repo_id=your-username/dataset-name  \
  --policy.type=pi05 \
  --output_dir=./outputs/pi05_training \
  --job_name=pi05_training \
  --policy.repo_id=your-username/your-repo-id \
  --policy.pretrained_path=lerobot/pi05_base \
  --policy.compile_model=true \
  --policy.gradient_checkpointing=true \
  --trackio.enable=true \
  --policy.dtype=bfloat16 \
  --policy.freeze_vision_encoder=false \
  --policy.train_expert_only=false \
  --steps=3000 \
  --policy.device=cuda \
  --batch_size=32

الاستدلال باستخدام RTC

يمكن لسياسة مُدرَّبة متوافقة استخدام RTC أثناء الاستدلال محليًا:

lerobot-rollout \
  --strategy.type=base \
  --policy.path=your-username/your-repo-id \
  --policy.device=cuda \
  --robot.type=unitree_g1 \
  --robot.is_simulation=false \
  --robot.controller=HolosomaLocomotionController \
  --robot.cameras='{"global_view": {"type": "zmq", "server_address": "<ROBOT_IP>", "port": 5555, "camera_name": "head_camera", "width": 640, "height": 480, "fps": 30}}' \
  --task="task_description" \
  --duration=1000 \
  --fps=30 \
  --inference.type=rtc

لا تُعلن متحكمات الحركة من طراز G1 عن عقد الهدف المحفوظ الذي تستخدمه آلية الانتظار القابلة للاسترداد في rollout. وبالتالي، بعد بدء الحركة، يؤدي استنفاد مخزن الإجراءات إلى عطل نهائي بدلاً من انتظار فترة سماح. كما تنطبق مهلات الطلبات وحدود عمر الملاحظات. تحقق من أن المقطع القابل للاستخدام من السياسة يغطي زمن استجابة الاستدلال قبل استخدام هذه الوصفة؛ راجع الانتظار والميزانيات المحلية لـ RTC. يتمتع SONIC بعقد رمز محفوظ منفصل موصوف أدناه.


الجزء 5: SONIC التحكم في الجسم الكامل (سياسات الرموز الكامنة)

ينقل LeRobot الآن نصف المفكّك من حزمة النشر الكاملة للجسم SONIC الخاصة بـ NVIDIA على شكل SonicWholeBodyController. بدلاً من إصدار أوامر للمفاصل، تُخرج السياسة رمز حركة كامنًا بأبعاد 64 (latent motion token) (motion_token.{i}.pos) في كل نبضة؛ ثم يحوّل مفكّك SONIC ذلك الرمز مع سجلّ الإدراك الذاتي الأخير إلى إجراء متبقّي يُقاس ويُضاف إلى وضعية الوقوف، مما ينتج أهدافًا لمواقع المفاصل بتردد 50 هرتز لجميع درجات الحرية الـ 29.

يحمّل المُتحكّم مُفكّك ONNX الخاص به وجميع ثوابت النشر (كسب PD، وdefault_angles، وaction_scale، والرمز المحايد) من lerobot/sonic_decoder. كما يتضمن المستودع مُفكّكًا مُقطّراً منخفض الكمون، يمكن اختياره عبر حجة policy_type="low_latency" الخاصة بالمُتحكّم (القيمة الافتراضية هي "default").

الاختبار في المحاكاة

يمكن لأي سياسة لإخراج الرموز تم تدريبها على رموز حركة SONIC (مثل nepyope/sonic_walk) تشغيلها:

lerobot-rollout \
  --strategy.type=base \
  --policy.path=nepyope/sonic_walk \
  --policy.device=cuda \
  --robot.type=unitree_g1 \
  --robot.is_simulation=true \
  --robot.controller=SonicWholeBodyController \
  --robot.cameras='{"ego_view": {"type": "zmq", "server_address": "localhost", "port": 5555, "camera_name": "head_camera", "width": 640, "height": 480, "fps": 30, "warmup_s": 15}}'

التشغيل على الروبوت الفعلي

شغّل خادم سياسة الاستدلال عن بُعد على جهاز GPU، وأبقِ جسر الروبوت ومفك SONIC وعميل rollout على G1 Jetson. لا تعبر عبر الشبكة سوى مقاطع رموز بحجم 64 بُعدًا؛ بينما يبقى المفك وحلقة rt/lowcmd ذات التردد 50 هرتز على متن الجهاز.

قم بتثبيت الإضافة البعيدة على كلا الجهازين. احتفظ بإضافة Unitree على G1:

# GPU machine
python -m pip install -e '.[remote]'

# G1 Jetson
python -m pip install -e '.[unitree_g1,remote]'

على جهاز وحدة معالجة الرسوميات، ابدأ خادم السياسة من جذر المستودع. الملف الشخصي المُدار يطابق nepyope/sonic_walk؛ انسخ نقطة التفتيش الخاصة به وعقد الميزات وحدّثهما معًا لسياسة أخرى.

lerobot-policy-server \
  --config_path=examples/remote_inference/unitree_g1_sonic.yaml

على G1، حافظ على تشغيل الجسر والكاميرا:

python src/lerobot/robots/unitree_g1/run_g1_server.py --camera

ثم ابدأ عميل النشر في طرفية G1 ثانية، مع استبدال <GPU_MACHINE_IP>:

lerobot-rollout \
  --strategy.type=base \
  --inference.type=remote \
  --inference.endpoint=tcp/<GPU_MACHINE_IP>:7447 \
  --inference.deployment=g1-sonic \
  --inference.semantics=unitree-g1-sonic-motion-token-v1 \
  --inference.encoding=jpeg \
  --inference.action_starvation_grace_s=1.0 \
  --robot.type=unitree_g1 \
  --robot.is_simulation=false \
  --robot.robot_ip=127.0.0.1 \
  --robot.controller=SonicWholeBodyController \
  --robot.cameras='{"ego_view": {"type": "zmq", "server_address": "127.0.0.1", "port": 5555, "camera_name": "head_camera", "width": 640, "height": 480, "fps": 30, "warmup_s": 5}}' \
  --task='walk forward' \
  --fps=30 \
  --return_to_initial_position=false \
  --interactive=true

اكتب /start فقط بعد أن يصبح G1 جاهزًا للحركة. تعلن SONIC عن دعم الانتظار لأن إعادة إرسال آخر رمز مكتمل يحافظ على توازن فك الترميز المدمج. قبل أول نتيجة سياسة، يرسل rollout رمز فك الترميز المحايد. إذا نفد مخزن الإجراءات، يُكرر آخر رمز مُطبَّق لمدة لا تتجاوز action_starvation_grace_s (ثانية واحدة في الأعلى)؛ وإذا لم يصل تنبؤ جديد، يخطئ rollout ويتبع مسار الإيقاف/القطع المهيأ له. تبقى متحكمات حركة G1 غير مدعومة لأن سرعات عصا التحكم الخاصة بها لا يمكن الاحتفاظ بها بهذه الطريقة.

تعطّل الوصفة خاصية العودة إلى الموضع الأولي: فالتدرّج عبر فضاء الرموز الكامنة في SONIC ليس مسارًا فيزيائيًا مُتحقَّقًا منه للعودة إلى الموضع الأصلي. تجنّب استخدام /reset لنفس السبب، إذ سيعيد الرمز إلى قيمته عند وقت الاتصال. لا يزال /stop يغلق الجلسة عن بُعد ويقطع الاتصال بالروبوت عبر مسار إيقاف تشغيل المتحكم القياسي.

مع SonicWholeBodyController، تكون حالة الملاحظة هي صدى الرمز ذي الأبعاد الـ 64 بدلاً من مواضع المفاصل الـ 29، لذا يجب أن يكون نقطة التفتيش المتوافقة مدرّبة ضد تلك الحالة. عند الاتصال، تُقارب الروبوت المفاصل مع default_angles الخاص بفك الترميز قبل أن يتولى المتحكم السيطرة.


موارد إضافية


آخر تحديث: يوليو 2026

Update on GitHub