Skip to content

Commit cd2aff6

Browse files
authored
Merge pull request #221 from tokk-nv/main
Update LeRobot tutorial with real-world robot instructions
2 parents bec54ea + d3f2f5a commit cd2aff6

File tree

2 files changed

+357
-5
lines changed

2 files changed

+357
-5
lines changed
183 KB
Loading

docs/lerobot.md

Lines changed: 357 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22

33
Let's run HuggingFace [`LeRobot`](https://github.com/huggingface/lerobot/) to train Transformer-based [action diffusion](https://diffusion-policy.cs.columbia.edu/) policies and [ACT](https://github.com/tonyzhaozh/act) onboard NVIDIA Jetson. These models learn to predict actions for a particular task from visual inputs and prior trajectories, typically collected during teleoperation or in simulation.
44

5-
<img src="images/lerobot_aloha.gif" style="max-width:500px;">
5+
<video controls autoplay muted style="max-width: 640px">
6+
<source src="https://github.com/user-attachments/assets/1ec6e4f0-0f85-4a8a-85c0-f70019f3405b" type="video/mp4">
7+
</video>
68

79
!!! abstract "What you need"
810

@@ -28,8 +30,358 @@ Let's run HuggingFace [`LeRobot`](https://github.com/huggingface/lerobot/) to tr
2830
git clone https://github.com/dusty-nv/jetson-containers
2931
bash jetson-containers/install.sh
3032
```
31-
32-
## Visualize Datasets
33+
34+
## Work with Real-World Robots - Before starting containers
35+
36+
This section gives the guide on how you can work through the LeRobot official example of [Getting Started with Real-World Robots \(`7_get_started_with_real_robot.md
37+
`\)](https://github.com/huggingface/lerobot/blob/main/examples/7_get_started_with_real_robot.md) on your Jetson.
38+
39+
!!! tip
40+
41+
It's recommended to work on your Jetson in **monitor-attached** mode.
42+
43+
`lerobot` is designed to show camera view in windows and playback TTS audio while capturing dataset, so it is more convenient to setup your Jetson with its monitor (and speakers) attached to Jetson.d
44+
45+
### a. Check `jetson-container`'s location
46+
47+
Through out the course of all the workflows of `lerobot`, we will be generating a lot of data, especially for capturing dataset.
48+
49+
We will clone the `lerobot` directory on host and mount the directory in the container to keep all the data persistant, but first make sure your `jetson-containers` directory is placed on your SSD, not on your eMMC or microSD card.
50+
51+
If you have created the `jetson-containers` directory on eMMC or microSD card (likely the case if you first set up your Jetson device without SSD first and later added SSD), then use the `rsync` command to move the entire directory under SSD mount point.
52+
53+
```bash
54+
rsync -aHAX /home/jetson/jetson-containers/ /ssd/jetson-containers/
55+
```
56+
57+
Then run the installer again.
58+
59+
```bash
60+
bash /ssd/jetson-containers/install.sh
61+
```
62+
63+
### b. Create `lerobot` dir on host
64+
65+
As described above, we will setup the `lerobot` directory under `data` directory of `jetson-containers` for monting it inside the container so that generated data persist.
66+
67+
```bash
68+
cd jetson-containers
69+
./packages/robots/lerobot/clone_lerobot_dir_under_data.sh
70+
./packages/robots/lerobot/copy_overlay_files_in_data_lerobot.sh
71+
```
72+
73+
### c. PulseAudio setup
74+
75+
LeRobot's dataset capture flow (`control_robot.py`) utilizes **Speech Dispatcher** to use espeak TTS, in order to give operators audio queues for notifying the status and signaling the next operation. It's actually very helpful.
76+
77+
Speech Dispatcher utilizes Pulse Audio, so rather than just sharing the `/dev/snd` device when `docker run` (which is good for ALSA), we need to add the following arguments.
78+
79+
```bash
80+
--device /dev/snd \
81+
-e PULSE_SERVER=unix:${XDG_RUNTIME_DIR}/pulse/native \
82+
-v ${XDG_RUNTIME_DIR}/pulse:${XDG_RUNTIME_DIR}/pulse \
83+
```
84+
85+
This is already added to `run.sh` of `jetson-containers`, however, we need to edit `/etc/pulse/default.pa` in order to allow the root user access to the socket file.
86+
87+
88+
```bash
89+
sudo vi /etc/pulse/default.pa
90+
```
91+
92+
Find the section loading `module-native-protomocl-unix` and add `auth-anonymous=1`
93+
94+
```bash
95+
### Load several protocols
96+
.ifexists module-esound-protocol-unix.so
97+
load-module module-esound-protocol-unix auth-anonymous=1
98+
.endif
99+
load-module module-nativ
100+
```
101+
102+
Then restart PulseAudio service to make the config take effect.
103+
104+
```bash
105+
pulseaudio --kill
106+
pulseaudio --start
107+
```
108+
109+
> For troubleshootings or details, please check the [`docs.md`](https://github.com/dusty-nv/jetson-containers/blob/dev/packages/speech/speech-dispatcher/docs.md) of `speech-dispatcher` package.
110+
111+
### d. Set udev rule for ACM devices
112+
113+
It is more convenient if the lerobot programs can always find the device of leader and follower arm with unique names.
114+
115+
For that, we set an udev rule so that arms always get assigned the same device name as following.<br>
116+
This is first done on Jetson host side.
117+
118+
- `/dev/ttyACM_kochleader` : Leader arm
119+
- `/dev/ttyACM_kochfollower` : Follower arm
120+
121+
First only connect the leader arm to Jetson and record the serial ID by running the following:
122+
123+
```bash
124+
ll /dev/serial/by-id/
125+
```
126+
127+
The output should look like this.
128+
129+
```bash
130+
lrwxrwxrwx 1 root root 13 Sep 24 13:07 usb-ROBOTIS_OpenRB-150_BA98C8C350304A46462E3120FF121B06-if00 -> ../../ttyACM1
131+
```
132+
133+
Then edit the first line of `./99-usb-serial.rules` like the following.
134+
135+
You can find the template of this file under `./packages/robots/lerobot` directory.
136+
137+
```
138+
SUBSYSTEM=="tty", ATTRS{idVendor}=="2f5d", ATTRS{idProduct}=="2202", ATTRS{serial}=="BA98C8C350304A46462E3120FF121B06", SYMLINK+="ttyACM_kochleader"
139+
SUBSYSTEM=="tty", ATTRS{idVendor}=="2f5d", ATTRS{idProduct}=="2202", ATTRS{serial}=="00000000000000000000000000000000", SYMLINK+="ttyACM_kochfollower"
140+
```
141+
142+
Now disconnect the leader arm, and then only connect the follower arm to Jetson.
143+
144+
Repeat the same steps to record the serial to edit the second line of `99-usb-serial.rules` file.
145+
146+
```bash
147+
$ ll /dev/serial/by-id/
148+
lrwxrwxrwx 1 root root 13 Sep 24 13:07 usb-ROBOTIS_OpenRB-150_483F88DC50304A46462E3120FF0C081A-if00 -> ../../ttyACM0
149+
$ vi ./packages/robots/lerobot
150+
```
151+
152+
You should have `./99-usb-serial.rules` now looking like this:
153+
154+
```
155+
SUBSYSTEM=="tty", ATTRS{idVendor}=="2f5d", ATTRS{idProduct}=="2202", ATTRS{serial}=="BA98C8C350304A46462E3120FF121B06", SYMLINK+="ttyACM_kochleader"
156+
SUBSYSTEM=="tty", ATTRS{idVendor}=="2f5d", ATTRS{idProduct}=="2202", ATTRS{serial}=="483F88DC50304A46462E3120FF0C081A", SYMLINK+="ttyACM_kochfollower"
157+
```
158+
159+
Finally copy this under `/etc/udev/rules.d/` (of host), and restart Jetson.
160+
161+
```
162+
sudo cp ./99-usb-serial.rules /etc/udev/rules.d/
163+
sudo reboot
164+
```
165+
166+
After reboot, check if we now have achieved the desired fixed simlinks names for the arms.
167+
168+
```bash
169+
ls -l /dev/ttyACM*
170+
```
171+
172+
You should get something like this:
173+
174+
```bash
175+
crw-rw---- 1 root dialout 166, 0 Sep 24 17:20 /dev/ttyACM0
176+
crw-rw---- 1 root dialout 166, 1 Sep 24 16:13 /dev/ttyACM1
177+
lrwxrwxrwx 1 root root 7 Sep 24 17:20 /dev/ttyACM_kochfollower -> ttyACM0
178+
lrwxrwxrwx 1 root root 7 Sep 24 16:13 /dev/ttyACM_kochleader -> ttyACM1
179+
```
180+
181+
### e. (Optional) CSI cameras
182+
183+
If you plan to use CSI cameras (not USB webcams) for data capture, you will use the new `--csi2webcam` options of `jetson-containers`, which exposes V4L2loopback devices that performs like USB webcams (MJPEG) for CSI cameras using Jetson's hardware JPEG encoder.
184+
185+
This feature require some packages to be installed.
186+
187+
```bash
188+
sudo apt update && sudo apt install v4l2loopback-dkms v4l-utils
189+
```
190+
191+
### f. Increse the swap file size
192+
193+
You may ran out of memory when are setting up to perform ACT model training.
194+
195+
```bash
196+
swapoff -a -v
197+
sudo rm /swfile
198+
sudo systemctl disable nvzramconfi
199+
sudo fallocate -l 8G /ssd/8GB.swap
200+
sudo chmod 600 /ssd/8GB.swap
201+
sudo mkswap /ssd/8GB.swap
202+
sudo echo "/ssd/8GB.swap swap swap defaults 0 0" >> /etc/fstab
203+
sudo reboot
204+
```
205+
206+
### g. Starting the `lerobot` container
207+
208+
=== "USB webcams"
209+
210+
```bash
211+
cd jetson-containers
212+
./run.sh \
213+
-v ${PWD}/data/lerobot/:/opt/lerobot/ \
214+
$(./autotag lerobot)
215+
```
216+
217+
=== "CSI cameras"
218+
219+
```bash
220+
cd jetson-containers
221+
./run.sh \
222+
--csi2webcam --csi-capture-res='1640x1232@30' --csi-output-res='640x480@30' \
223+
-v ${PWD}/data/lerobot/:/opt/lerobot/ \
224+
$(./autotag lerobot)
225+
```
226+
227+
## Work with Real-World Robots - Once in container
228+
229+
!!! tip "JupyerLab tip"
230+
231+
Inside the `lerobot` container, JupyterLab server process starts.
232+
233+
You can access with `http://localhost:8888/` (or `http://<IP_ADDRESS>:8888/` from other PC on the same network).
234+
235+
In the `notebooks`, there are some Jupyter notebooks for each segment of the official tutorial [Getting Started with Real-World Robots \(`7_get_started_with_real_robot.md`\)](https://github.com/huggingface/lerobot/blob/main/examples/7_get_started_with_real_robot.md).
236+
237+
![](./images/lerobot_jupyter_notebooks.png)
238+
239+
Please note that some of them (like `notebooks/7-2_real-robot_configure-motors.ipynb`) can be used as a real work notebook to execute python codes and scritps convniently inside the notebook along with instructions (rather than switching to console).
240+
241+
However, keep in mind that you are encouraged to always check the [original official tutorial](https://github.com/huggingface/lerobot/blob/main/examples/7_get_started_with_real_robot.md), and some operation like training is much better executed on console.
242+
243+
!!! tip "Bash history tip"
244+
245+
Inside the container, on the console, you can press ++up++ key to scroll through some of the frequently used commands pre-registered in bash history.
246+
247+
### q. Setup audio
248+
249+
Check if PulseAudio is available.
250+
251+
```bash
252+
pactl info
253+
```
254+
255+
If you need to set the default audio output device, use `set-default-sink`.
256+
257+
```bash
258+
pactl list short sinks
259+
pactl set-default-sink [SINK_NAME_OR_INDEX]
260+
```
261+
262+
### 1. Order and Assemble your Koch v1.1
263+
264+
You can order the Koch v1.1 kits from ROBOTIS. (*Note: they don't come with 3d printed parts*)
265+
266+
- [Follower arm](https://www.robotis.us/koch-v1-1-low-cost-robot-arm-follower/)
267+
- [Leader arm](https://www.robotis.us/koch-v1-1-low-cost-robot-arm-follower/)
268+
269+
TODO:
270+
271+
- [ ] Document Jetson unique hardware setup
272+
- [ ] Share custom 3D print models
273+
274+
### 2. Configure motors, calibrate arms, teleoperate your Koch v1.1
275+
276+
Follow the Jupyter notebook `7-2_real-robot_configure-motors.ipynb`.
277+
278+
### 3. Record your Dataset and Visualize it
279+
280+
You should mostly operate on the container's terminal.
281+
282+
Follow the [official document's section](https://github.com/huggingface/lerobot/blob/main/examples/7_get_started_with_real_robot.md#3-record-your-dataset-and-visualize-it).
283+
284+
!!! tip "Camera config tip"
285+
286+
The official document demonstrates the two camera positions, one at the top ("phone") and the other at directly in front facing the arm ("laptop").
287+
288+
In our trials, this camera placement worked, but we needed to make the camera zoom-up to the scene so that they capture better spacial resolution.
289+
290+
Another thing worth experimenting is the **wrist cam**. More to come later.
291+
292+
!!! tip
293+
294+
If you plan to perfom training on a different machine, `scp` the dataset directory.
295+
296+
=== "To another Jetson"
297+
298+
```bash
299+
scp -r data/lerobot/data/${HF_USER}/koch_test_01/ <USER>@<IP>:/ssd/jetson-containers/data/lerobot/data/${HF_USER}/
300+
```
301+
302+
=== "To other PC"
303+
304+
```bash
305+
scp -r data/lerobot/data/${HF_USER}/koch_test_01/ <USER>@<IP>:/home/<USER>/lerobot/data/${HF_USER}/
306+
```
307+
308+
### 4. Train a policy on your data
309+
310+
You should operate on ther container's terminal.
311+
312+
Follow the [official document's section](https://github.com/huggingface/lerobot/blob/main/examples/7_get_started_with_real_robot.md#4-train-a-policy-on-your-data).
313+
314+
!!! tip
315+
316+
Following commands are registered in Bash history inside the `lerobot` container.
317+
318+
```bash
319+
wandb login
320+
export HF_USER=
321+
python lerobot/scripts/control_robot.py record \
322+
--robot-path lerobot/configs/robot/koch.yaml \
323+
--fps 30 \
324+
--root data \
325+
--repo-id ${HF_USER}/koch_test_$(date +%Y%m%d_%H%M%S) \
326+
--tags tutorial \
327+
--warmup-time-s 5 \
328+
--episode-time-s 30 \
329+
--reset-time-s 30 \
330+
--num-episodes 10
331+
```
332+
333+
!!! tip
334+
335+
If you perform the training on other Jetson or PC, `scp` the outputs directory content back to the orinal Jetson that has the leader and follower arm attached.
336+
337+
```bash
338+
scp -r outputs/train/act_koch_test_01/ <USER>@<IP>:/ssd/jetson-containers/data/lerobot/outputs/train/
339+
```
340+
341+
### 5. Evaluate your policy
342+
343+
You should operate on the container's terminal.
344+
345+
Follow the [official document's section](https://github.com/huggingface/lerobot/blob/main/examples/7_get_started_with_real_robot.md#3-record-your-dataset-and-visualize-it).
346+
347+
!!! tip "Tip for **a. Use `koch.yaml` and our `record` function**"
348+
349+
Modify the command in the bash history to add `-p` arugment to points to the policy checkpoint.
350+
351+
```bash
352+
python lerobot/scripts/control_robot.py record \
353+
--robot-path lerobot/configs/robot/koch.yaml \
354+
--fps 30 \
355+
--root data \
356+
--repo-id ${HF_USER}/koch_test_01 \
357+
--tags tutorial \
358+
--warmup-time-s 5 \
359+
--episode-time-s 30 \
360+
--reset-time-s 30 \
361+
--num-episodes 10 \
362+
-p outputs/train/act_koch_test/checkpoints/last/pretrained_model
363+
```
364+
365+
!!! tip "Tip for **Visualize evaluation afterwards**"
366+
367+
```bash
368+
python lerobot/scripts/visualize_dataset.py \
369+
--root data \
370+
--repo-id ${HF_USER}/eval_koch_test
371+
```
372+
373+
If everything goes well, you should see
374+
375+
<video controls autoplay muted style="max-width: 960px">
376+
<source src="https://github.com/user-attachments/assets/1ec6e4f0-0f85-4a8a-85c0-f70019f3405b" type="video/mp4">
377+
</video>
378+
379+
380+
## Basic Walkthrough
381+
382+
This is from the lerobot top README.md.
383+
384+
### Visualize Datasets
33385

34386
Outside of container, first launch the [rerun.io](https://rerun.io/) visualization tool that LeRobot uses <sup>[[]](https://github.com/huggingface/lerobot/?tab=readme-ov-file#visualize-datasets)</sup>
35387

@@ -49,7 +401,7 @@ jetson-containers run -w /opt/lerobot $(autotag lerobot) \
49401

50402
<img src="images/lerobot_push.jpg" style="max-width:500px;">
51403

52-
## Evaluate a Pretrained Diffusion Policy
404+
### Evaluate a Pretrained Diffusion Policy
53405

54406
This will download and run a pre-trained [diffusion model](https://huggingface.co/lerobot/diffusion_pusht) on the [PushT](https://github.com/huggingface/gym-pusht) environment <sup>[[]](https://github.com/huggingface/lerobot/?tab=readme-ov-file#evaluate-a-pretrained-policy)</sup>
55407

@@ -61,7 +413,7 @@ jetson-containers run -w /opt/lerobot $(autotag lerobot) \
61413
eval.batch_size=10
62414
```
63415

64-
## Train your own ACT Policy
416+
### Train your own ACT Policy
65417

66418
Next, train [ACT](https://github.com/tonyzhaozh/act) on the [Aloha](https://github.com/huggingface/gym-aloha) manipulation environment <sup>[[]](https://github.com/huggingface/lerobot/?tab=readme-ov-file#train-your-own-policy)</sup>
67419

0 commit comments

Comments
 (0)