Case Study: Getting Started with LeRobot
Last updated
Last updated
conda activate lerobot
Grant permission
sudo nano /etc/udev/rules.d/50-lerobot.rules
SUBSYSTEMS=="usb", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="55d3", GROUP="users", MODE="0666"
sudo udevadm control --reload-rules
sudo udevadm trigger
Teleoperation demo
python lerobot/scripts/control_robot.py teleoperate \
--robot-path lerobot/configs/robot/koch.yaml
Login to hugging face
huggingface-cli login --token ${HUGGINGFACE_TOKEN} --add-to-git-credential
HF_USER=$(huggingface-cli whoami | head -n 1)
echo $HF_USER
record dataset
python lerobot/scripts/control_robot.py record \
--robot-path lerobot/configs/robot/koch.yaml \
--fps 30 \
--root data \
--repo-id ${HF_USER}/koch_test \
--tags tutorial \
--num-episodes 2 \
--warmup-time-s 5 \
--episode-time-s 30 \
--reset-time-s 30
full 50 episodes!
python lerobot/scripts/control_robot.py record \
--robot-path lerobot/configs/robot/koch.yaml \
--fps 30 \
--root data \
--repo-id ${HF_USER}/koch_place_block \
--tags tutorial \
--num-episodes 50 \
--warmup-time-s 2 \
--episode-time-s 30 \
--reset-time-s 10
Visualize
python lerobot/scripts/visualize_dataset_html.py \
--root data \
--repo-id ${HF_USER}/koch_place_block
Replay
python lerobot/scripts/control_robot.py replay \
--robot-path lerobot/configs/robot/koch.yaml \
--fps 30 \
--root data \
--repo-id ${HF_USER}/koch_place_block \
--episode 0
Training!!
DATA_DIR=data python lerobot/scripts/train.py \
dataset_repo_id=${HF_USER}/koch_place_block \
policy=act_koch_real \
env=koch_real \
hydra.run.dir=outputs/train/act_koch_place_block \
hydra.job.name=act_koch_place_block \
device=cuda \
wandb.enable=true
upload trained model
huggingface-cli upload ${HF_USER}/act_koch_place_block outputs/train/act_koch_place_block/checkpoints/last/pretrained_model
eval
python lerobot/scripts/control_robot.py record \
--robot-path lerobot/configs/robot/koch.yaml \
--fps 30 \
--root data \
--repo-id ${HF_USER}/eval_koch_place_block \
--tags tutorial eval \
--warmup-time-s 5 \
--episode-time-s 30 \
--reset-time-s 30 \
--num-episodes 10 \
-p outputs/train/act_koch_place_block/checkpoints/last/pretrained_model
Teleop Script
import tqdm
from lerobot.common.robot_devices.motors.dynamixel import DynamixelMotorsBus
from lerobot.common.robot_devices.motors.dynamixel import TorqueMode
from lerobot.common.robot_devices.robots.manipulator import ManipulatorRobot
from lerobot.common.robot_devices.cameras.opencv import OpenCVCamera
leader_port = "/dev/ttyACM0"
follower_port = "/dev/ttyACM1"
leader_arm = DynamixelMotorsBus(
port=leader_port,
motors={
# name: (index, model)
"shoulder_pan": (1, "xl330-m077"),
"shoulder_lift": (2, "xl330-m077"),
"elbow_flex": (3, "xl330-m077"),
"wrist_flex": (4, "xl330-m077"),
"wrist_roll": (5, "xl330-m077"),
"gripper": (6, "xl330-m077"),
},
)
follower_arm = DynamixelMotorsBus(
port=follower_port,
motors={
# name: (index, model)
"shoulder_pan": (1, "xl430-w250"),
"shoulder_lift": (2, "xl430-w250"),
"elbow_flex": (3, "xl330-m288"),
"wrist_flex": (4, "xl330-m288"),
"wrist_roll": (5, "xl330-m288"),
"gripper": (6, "xl330-m288"),
},
)
robot = ManipulatorRobot(
robot_type="koch",
leader_arms={"main": leader_arm},
follower_arms={"main": follower_arm},
calibration_dir=".cache/calibration/koch",
cameras={
"laptop": OpenCVCamera(0),
},
)
robot.connect()
follower_arm.write("Torque_Enable", TorqueMode.ENABLED.value)
# # leader_pos = robot.leader_arms["main"].read("Present_Position")
# # follower_pos = robot.follower_arms["main"].read("Present_Position")
# # print(leader_pos)
# # print(follower_pos)
seconds = 120
frequency = 200
for _ in tqdm.tqdm(range(seconds*frequency)):
leader_pos = robot.leader_arms["main"].read("Present_Position")
robot.follower_arms["main"].write("Goal_Position", leader_pos)
# observation, action = robot.teleop_step(record_data=True)
# print(observation["observation.images.laptop"].shape)
# print(observation["observation.images.phone"].shape)
# print(observation["observation.images.laptop"].min().item())
# print(observation["observation.images.laptop"].max().item())
follower_arm.write("Torque_Enable", TorqueMode.DISABLED.value)
robot.disconnect()