diff --git a/docs/source/unitree_g1.mdx b/docs/source/unitree_g1.mdx
index 39bd7832b..2e615085e 100644
--- a/docs/source/unitree_g1.mdx
+++ b/docs/source/unitree_g1.mdx
@@ -12,36 +12,59 @@ The Unitree G1 humanoid is now supported in LeRobot! You can teleoperate, train
## Part 1: Getting Started
-### Install LeRobot on Your Machine
+### Install the Unitree SDK
+
+Follow the [unitree_sdk2_python installation guide](https://github.com/unitreerobotics/unitree_sdk2_python#installation). Tested with `unitree_sdk2py==1.0.1` and `cyclonedds==0.10.2`:
```bash
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 unitree_sdk2_python
+pip install -e .
+cd ..
+```
+
+### Install LeRobot
+
+```bash
+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.
+
+
### Test the Installation (Simulation)
+The simulation environment has its own dependencies. Check the Simulation environment dependencies: [Unitree G1 Mujoco EnvHub](https://huggingface.co/lerobot/unitree-g1-mujoco/tree/main).
+
+```bash
+pip install mujoco loguru msgpack msgpack-numpy
+```
+
```bash
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}}' \
- --display_data=true
+ --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
```
-This will launch a [MuJoCo sim instance](https://huggingface.co/lerobot/unitree-g1-mujoco/tree/main) for the G1.
+This will launch a [MuJoCo sim instance](https://huggingface.co/lerobot/unitree-g1-mujoco/tree/main) for the G1. You can connect a gamepad to your machine before launching in order to control the robot's locomotion in sim. We support both [HolosomaLocomotionController](https://github.com/amazon-far/holosoma) and [GrootLocomotionController](https://github.com/NVlabs/GR00T-WholeBodyControl) via `--robot.controller`.
- Press `9` to release the robot
- Press `7` / `8` to increase / decrease waist height
-### Connect to the Robot
+### Connect to the Physical Robot
The G1's Ethernet IP is fixed at `192.168.123.164`. Your machine must have a static IP on the same subnet: `192.168.123.x` where `x ≠ 164`.
@@ -59,37 +82,11 @@ ssh unitree@192.168.123.164
# Password: 123
```
-### Install LeRobot on the G1
+### Share Internet via Ethernet
-From the robot:
+The G1 needs internet access to clone repos and install packages. Share your laptop's connection over Ethernet:
-```bash
-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 .
-git clone https://github.com/huggingface/lerobot.git
-cd lerobot
-pip install -e '.[unitree_g1]'
-```
-
-> **Note:** The Unitree SDK requires CycloneDDS v0.10.2. See the [Unitree SDK docs](https://github.com/unitreerobotics/unitree_sdk2_python) for details.
-
----
-
-## Part 2: Enable WiFi on the Robot
-
-Wi-Fi connectivity is blocked by default on the G1. To activate:
-
-```bash
-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
-```
-
-**On your laptop** (share internet via Ethernet):
+**On your laptop:**
```bash
sudo sysctl -w net.ipv4.ip_forward=1
@@ -100,7 +97,7 @@ sudo iptables -A FORWARD -i wlp132s0f0 -o enp131s0 -m state --state RELATED,ESTA
sudo iptables -A FORWARD -i enp131s0 -o wlp132s0f0 -j ACCEPT
```
-**On the G1** (set default route through your laptop):
+**On the G1:**
```bash
sudo ip route del default 2>/dev/null || true
@@ -111,6 +108,45 @@ echo "nameserver 8.8.8.8" | sudo tee /etc/resolv.conf
ping -c 3 8.8.8.8
```
+### Install the Unitree SDK on the G1
+
+Follow the [unitree_sdk2_python installation guide](https://github.com/unitreerobotics/unitree_sdk2_python#installation):
+
+```bash
+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 ..
+```
+
+### Install LeRobot on the G1
+
+```bash
+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.
+
+
+### (Optional) Enable WiFi on the Robot
+
+For wireless SSH access, you can enable WiFi on the G1 (it's blocked by default):
+
+```bash
+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
+```
+
**Connect to a WiFi network:**
```bash
@@ -125,7 +161,7 @@ sudo nmcli connection up "YourNetwork"
ip a show wlan0
```
-You can now SSH over WiFi:
+You can then SSH over WiFi instead of Ethernet:
```bash
ssh unitree@
@@ -134,18 +170,23 @@ ssh unitree@
---
-## Part 3: Teleoperation & Locomotion
+## Part 2: Teleoperation & Locomotion
### Run the Robot Server
-On the robot:
+On the robot (from `~/lerobot`):
```bash
+cd ~/lerobot
python src/lerobot/robots/unitree_g1/run_g1_server.py --camera
```
### Run the Locomotion Policy
+You can run the teleoperation client from your laptop over Ethernet, over WiFi (experimental), or directly on the robot itself. Mind potential latency introduced by your network.
+
+**From your laptop:**
+
```bash
lerobot-teleoperate \
--robot.type=unitree_g1 \
@@ -158,13 +199,13 @@ lerobot-teleoperate \
--robot.controller=HolosomaLocomotionController
```
-We support both [HolosomaLocomotionController](https://github.com/amazon-far/holosoma) and [GrootLocomotionController](https://github.com/NVlabs/GR00T-WholeBodyControl).
+We support both [GrootLocomotionController](https://github.com/NVlabs/GR00T-WholeBodyControl) and [HolosomaLocomotionController](https://github.com/amazon-far/holosoma) via `--robot.controller`.
---
-## Part 4: Loco-Manipulation with the Homunculus Exoskeleton
+## Part 3: Loco-Manipulation with the Homunculus Exoskeleton
-We provide a loco-manipulation solution via the Homunculus Exoskeleton — an open-source 7 DoF exoskeleton for whole-body control. Assembly instructions [here](https://github.com/nepyope/hmc_exo).
+We provide a loco-manipulation solution via the Homunculus Exoskeleton — an open-source 7 DoF exoskeleton for whole-body control. Check it out [here](https://github.com/nepyope/hmc_exo).
### Calibrate
@@ -205,7 +246,7 @@ Example dataset: [nepyope/unitree_box_move_blue_full](https://huggingface.co/dat
---
-## Part 5: Training & Inference
+## Part 4: Training & Inference
### Train
diff --git a/pyproject.toml b/pyproject.toml
index aed846f43..e85d695df 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -119,14 +119,13 @@ gamepad = ["lerobot[pygame-dep]", "hidapi>=0.14.0,<0.15.0"]
hopejr = ["lerobot[feetech]", "lerobot[pygame-dep]"]
lekiwi = ["lerobot[feetech]", "pyzmq>=26.2.1,<28.0.0"]
unitree_g1 = [
- "unitree-sdk2==1.0.1",
+ # "unitree-sdk2==1.0.1",
"pyzmq>=26.2.1,<28.0.0",
"onnxruntime>=1.16.0,<2.0.0",
- "pin>=3.0.0,<4.0.0",
+ "onnx>=1.16.0,<2.0.0",
"meshcat>=0.3.0,<0.4.0",
"lerobot[matplotlib-dep]",
"lerobot[pygame-dep]",
- "casadi>=3.6.0,<4.0.0",
]
reachy2 = ["reachy2_sdk>=1.0.15,<1.1.0"]
kinematics = ["lerobot[placo-dep]"]
diff --git a/src/lerobot/utils/import_utils.py b/src/lerobot/utils/import_utils.py
index cae445e06..2b26b2302 100644
--- a/src/lerobot/utils/import_utils.py
+++ b/src/lerobot/utils/import_utils.py
@@ -74,7 +74,7 @@ _peft_available = is_package_available("peft")
_scipy_available = is_package_available("scipy")
_reachy2_sdk_available = is_package_available("reachy2_sdk")
_can_available = is_package_available("python-can", "can")
-_unitree_sdk_available = is_package_available("unitree-sdk2", "unitree_sdk2py")
+_unitree_sdk_available = is_package_available("unitree-sdk2py", "unitree_sdk2py")
_pygame_available = is_package_available("pygame")