Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Control aloha robot natively #316

Merged
merged 45 commits into from
Sep 4, 2024
Merged
Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
01f264e
Add Aloha
Cadene Aug 22, 2024
98e97d5
style
Cadene Aug 22, 2024
eb54a8b
warnings stacklevel=1
Cadene Aug 22, 2024
1cf877d
fix control_robot tests
Cadene Aug 22, 2024
9da4b4e
WIP fix gripper calibration, fix preset aloha
Cadene Aug 27, 2024
998307d
WIP: Add CalibrationMode with LINEAR joints, Use one calibration file…
Cadene Aug 29, 2024
92f9beb
WIP: Reduce complexity of apply_calibration, Add (TODO: test, comment)
Cadene Aug 29, 2024
e7370d8
Merge remote-tracking branch 'origin/main' into user/rcadene/2024_07_…
Cadene Aug 29, 2024
690a57b
Merge remote-tracking branch 'origin/main' into HEAD
Cadene Aug 30, 2024
64d32f2
Add JointOutOfRangeError, Add autocorrect_calibration
Cadene Aug 30, 2024
0cb6fd8
Refactor with
Cadene Aug 31, 2024
e848141
Move busy_wait to utils to fix unit tests
Cadene Aug 31, 2024
60d9aa2
Move get_arm_id to utils to fix unit tests
Cadene Aug 31, 2024
24e30f3
Move get_arm_id to utils to fix unit tests
Cadene Aug 31, 2024
4e650fc
Troubleshooting camera
Cadene Aug 31, 2024
240f2f7
Add Aloha default calibration
Cadene Aug 31, 2024
407f432
Improve comments
Cadene Aug 31, 2024
04ca947
Update default calibration path to aloha_default
Cadene Sep 2, 2024
5ffcfcc
Rename koch extras to dynamixel
Cadene Sep 2, 2024
a8ce9f7
Add more comments
Cadene Sep 2, 2024
bf3c9dc
remove .pkl from tutorial
Cadene Sep 2, 2024
6eb4f73
Improve comments about ranges
Cadene Sep 2, 2024
eb1459b
Add more comments
Cadene Sep 2, 2024
4909c37
use action sent
Cadene Sep 2, 2024
ddccf29
remove isinstance(max_relative_target, float)
Cadene Sep 2, 2024
34a47df
revolute, linear joints, degrees int type remove
Cadene Sep 2, 2024
9c08f1c
fix
Cadene Sep 2, 2024
26364f8
Apply suggestions from code review
Cadene Sep 2, 2024
4a96ef3
Address simon's comment
Cadene Sep 2, 2024
9847643
Update right follower
Cadene Sep 2, 2024
bc63129
Update aloha_default calibration
Cadene Sep 4, 2024
3180a76
remove aloha_defualt from gitlfs
Cadene Sep 4, 2024
0277ead
Add aloha_default calib without gitlfs
Cadene Sep 4, 2024
44306cf
Address jess comments
Cadene Sep 4, 2024
54107dd
add .cache/calibration/aloha_default/*json as files, excluded from gi…
Cadene Sep 4, 2024
e10ddf4
delete
Cadene Sep 4, 2024
3954f63
exclude from gitlfs
Cadene Sep 4, 2024
edb4ff9
retry
Cadene Sep 4, 2024
46cec2c
retry
Cadene Sep 4, 2024
2d0ccb4
retry
Cadene Sep 4, 2024
35efa8d
retry
Cadene Sep 4, 2024
1d2b588
Remove LFS tracking rules for JSON files
Cadene Sep 4, 2024
11ab91c
retry
Cadene Sep 4, 2024
efa7015
readd json
Cadene Sep 4, 2024
ce424d7
Merge branch 'main' into user/rcadene/2024_07_11_control_aloha
Cadene Sep 4, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .cache/calibration/aloha_default/left_follower.json
Git LFS file not shown
3 changes: 3 additions & 0 deletions .cache/calibration/aloha_default/left_leader.json
Git LFS file not shown
3 changes: 3 additions & 0 deletions .cache/calibration/aloha_default/right_follower.json
Git LFS file not shown
3 changes: 3 additions & 0 deletions .cache/calibration/aloha_default/right_leader.json
Git LFS file not shown
2 changes: 1 addition & 1 deletion docker/lerobot-cpu/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ RUN echo "source /opt/venv/bin/activate" >> /root/.bashrc
COPY . /lerobot
WORKDIR /lerobot
RUN pip install --upgrade --no-cache-dir pip
RUN pip install --no-cache-dir ".[test, aloha, xarm, pusht, koch]" \
RUN pip install --no-cache-dir ".[test, aloha, xarm, pusht, dynamixel]" \
--extra-index-url https://download.pytorch.org/whl/cpu

# Set EGL as the rendering backend for MuJoCo
Expand Down
2 changes: 1 addition & 1 deletion docker/lerobot-gpu/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ RUN echo "source /opt/venv/bin/activate" >> /root/.bashrc
COPY . /lerobot
WORKDIR /lerobot
RUN pip install --upgrade --no-cache-dir pip
RUN pip install --no-cache-dir ".[test, aloha, xarm, pusht, koch]"
RUN pip install --no-cache-dir ".[test, aloha, xarm, pusht, dynamixel]"

# Set EGL as the rendering backend for MuJoCo
ENV MUJOCO_GL="egl"
61 changes: 34 additions & 27 deletions examples/7_get_started_with_real_robot.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ This tutorial will guide you through the process of setting up and training a ne

By following these steps, you'll be able to replicate tasks like picking up a Lego block and placing it in a bin with a high success rate, as demonstrated in [this video](https://x.com/RemiCadene/status/1814680760592572934).

Although this tutorial is general and can be easily adapted to various types of robots by changing the configuration, it is specifically based on the [Koch v1.1](https://github.com/jess-moss/koch-v1-1), an affordable robot. The Koch v1.1 consists of a leader arm and a follower arm, each with 6 motors. It can work with one or several cameras to record the scene, which serve as visual sensors for the robot.
This tutorial is specifically made for the affordable [Koch v1.1](https://github.com/jess-moss/koch-v1-1) robot, but it contains additional information to be easily adapted to various types of robots like [Aloha bimanual robot](aloha-2.github.io) by changing some configurations. The Koch v1.1 consists of a leader arm and a follower arm, each with 6 motors. It can work with one or several cameras to record the scene, which serve as visual sensors for the robot.

During the data collection phase, you will control the follower arm by moving the leader arm. This process is known as "teleoperation." This technique is used to collect robot trajectories. Afterward, you'll train a neural network to imitate these trajectories and deploy the network to enable your robot to operate autonomously.

Expand All @@ -29,16 +29,16 @@ For a visual walkthrough of the assembly process, you can refer to [this video t

## 2. Configure motors, calibrate arms, teleoperate your Koch v1.1

First, install the additional dependencies required for Koch v1.1 by running one of the following commands.
First, install the additional dependencies required for robots built with dynamixel motors like Koch v1.1 by running one of the following commands.

Using `pip`:
```bash
pip install -e ".[koch]"
pip install -e ".[dynamixel]"
```

Or using `poetry`:
```bash
poetry install --sync --extras "koch"
poetry install --sync --extras "dynamixel"
```

You are now ready to plug the 5V power supply to the motor bus of the leader arm (the smaller one) since all its motors only require 5V.
Expand Down Expand Up @@ -147,6 +147,7 @@ follower_arm = DynamixelMotorsBus(
Next, update the port values in the YAML configuration file for the Koch robot at [`lerobot/configs/robot/koch.yaml`](../lerobot/configs/robot/koch.yaml) with the ports you've identified:
```yaml
[...]
robot_type: koch
leader_arms:
main:
_target_: lerobot.common.robot_devices.motors.dynamixel.DynamixelMotorsBus
Expand Down Expand Up @@ -174,6 +175,8 @@ follower_arms:
[...]
```

Don't forget to set `robot_type: aloha` if you follow this tutorial with [Aloha bimanual robot](aloha-2.github.io) instead of Koch v1.1

This configuration file is used to instantiate your robot across all scripts. We'll cover how this works later on.

**Connect and Configure your Motors**
Expand Down Expand Up @@ -298,32 +301,37 @@ Alternatively, you can unplug the power cord, which will automatically disable t

*/!\ Warning*: These motors tend to overheat, especially under torque or if left plugged in for too long. Unplug after use.

### b. Teleoperate your Koch v1.1 with KochRobot
### b. Teleoperate your Koch v1.1 with ManipulatorRobot

**Instantiate the KochRobot**
**Instantiate the ManipulatorRobot**

Before you can teleoperate your robot, you need to instantiate the [`KochRobot`](../lerobot/common/robot_devices/robots/koch.py) using the previously defined `leader_arm` and `follower_arm`.
Before you can teleoperate your robot, you need to instantiate the [`ManipulatorRobot`](../lerobot/common/robot_devices/robots/manipulator.py) using the previously defined `leader_arm` and `follower_arm`.

For the Koch robot, we only have one leader, so we refer to it as `"main"` and define it as `leader_arms={"main": leader_arm}`. We do the same for the follower arm. For other robots (like the Aloha), which may have two pairs of leader and follower arms, you would define them like this: `leader_arms={"left": left_leader_arm, "right": right_leader_arm},`. Same thing for the follower arms.
For the Koch v1.1 robot, we only have one leader, so we refer to it as `"main"` and define it as `leader_arms={"main": leader_arm}`. We do the same for the follower arm. For other robots (like the Aloha), which may have two pairs of leader and follower arms, you would define them like this: `leader_arms={"left": left_leader_arm, "right": right_leader_arm},`. Same thing for the follower arms.

You also need to provide a path to a calibration file, such as `calibration_path=".cache/calibration/koch.pkl"`. More on this in the next section.
You also need to provide a path to a calibration directory, such as `calibration_dir=".cache/calibration/koch"`. More on this in the next section.

Run the following code to instantiate your Koch robot:
Run the following code to instantiate your manipulator robot:
```python
from lerobot.common.robot_devices.robots.koch import KochRobot
from lerobot.common.robot_devices.robots.manipulator import ManipulatorRobot

robot = KochRobot(
robot = ManipulatorRobot(
robot_type="koch",
leader_arms={"main": leader_arm},
follower_arms={"main": follower_arm},
calibration_path=".cache/calibration/koch.pkl",
calibration_dir=".cache/calibration/koch",
)
```

**Calibrate and Connect the KochRobot**
The `robot_type="koch"` is used to set the associated settings and calibration process. For instance, we activate the torque of the gripper of the leader Koch v1.1 arm and position it at a 40 degree angle to use it as a trigger.

For the [Aloha bimanual robot](https://aloha-2.github.io), we would use `robot_type="aloha"` to set different settings such as a secondary ID for shadow joints (shoulder, elbow). Specific to Aloha, LeRobot comes with default calibration files stored in in `.cache/calibration/aloha_default`. Assuming the motors have been properly assembled, no manual calibration step is expected. If you need to run manual calibration, simply update `calibration_dir` to `.cache/calibration/aloha`.

**Calibrate and Connect the ManipulatorRobot**

Next, you'll need to calibrate your robot to ensure that the leader and follower arms have the same position values when they are in the same physical position. This calibration is essential because it allows a neural network trained on one Koch robot to work on another.
Next, you'll need to calibrate your Koch robot to ensure that the leader and follower arms have the same position values when they are in the same physical position. This calibration is essential because it allows a neural network trained on one Koch robot to work on another.

When you connect your robot for the first time, the [`KochRobot`](../lerobot/common/robot_devices/robots/koch.py) will detect if the calibration file is missing and trigger the calibration procedure. During this process, you will be guided to move each arm to three different positions.
When you connect your robot for the first time, the [`ManipulatorRobot`](../lerobot/common/robot_devices/robots/manipulator.py) will detect if the calibration file is missing and trigger the calibration procedure. During this process, you will be guided to move each arm to three different positions.

Here are the positions you'll move the follower arm to:

Expand Down Expand Up @@ -354,27 +362,26 @@ The output will look like this:
```
Connecting main follower arm
Connecting main leader arm
Missing calibration file '.cache/calibration/koch.pkl'. Starting calibration procedure.

Running calibration of main follower...

Missing calibration file '.cache/calibration/koch/main_follower.json'
Running calibration of koch main follower...
Move arm to zero position
[...]
Move arm to rotated position
[...]
Move arm to rest position
[...]
Calibration is done! Saving calibration file '.cache/calibration/koch/main_follower.json'

Running calibration of main leader...

Missing calibration file '.cache/calibration/koch/main_leader.json'
Running calibration of koch main leader...
Move arm to zero position
[...]
Move arm to rotated position
[...]
Move arm to rest position
[...]

Calibration is done! Saving calibration file '.cache/calibration/koch.pkl'
Calibration is done! Saving calibration file '.cache/calibration/koch/main_leader.json'
```

*Verifying Calibration*
Expand Down Expand Up @@ -414,7 +421,7 @@ for _ in tqdm.tqdm(range(seconds*frequency)):

*Using `teleop_step` for Teleoperation*

Alternatively, you can teleoperate the robot using the `teleop_step` method from [`KochRobot`](../lerobot/common/robot_devices/robots/koch.py).
Alternatively, you can teleoperate the robot using the `teleop_step` method from [`ManipulatorRobot`](../lerobot/common/robot_devices/robots/manipulator.py).

Run this code to teleoperate:
```python
Expand Down Expand Up @@ -607,10 +614,10 @@ Additionaly, you can set up your robot to work with your cameras.

Modify the following Python code with the appropriate camera names and configurations:
```python
robot = KochRobot(
robot = ManipulatorRobot(
leader_arms={"main": leader_arm},
follower_arms={"main": follower_arm},
calibration_path=".cache/calibration/koch.pkl",
calibration_dir=".cache/calibration/koch",
cameras={
"laptop": OpenCVCamera(0, fps=30, width=640, height=480),
"phone": OpenCVCamera(1, fps=30, width=640, height=480),
Expand Down Expand Up @@ -925,7 +932,7 @@ huggingface-cli upload ${HF_USER}/act_koch_test_${CKPT} \

## 5. Evaluate your policy

Now that you have a policy checkpoint, you can easily control your robot with it using methods from [`KochRobot`](../lerobot/common/robot_devices/robots/koch.py) and the policy.
Now that you have a policy checkpoint, you can easily control your robot with it using methods from [`ManipulatorRobot`](../lerobot/common/robot_devices/robots/manipulator.py) and the policy.

Try this code for running inference for 60 seconds at 30 fps:
```python
Expand Down
10 changes: 9 additions & 1 deletion lerobot/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
print(lerobot.available_real_world_datasets)
print(lerobot.available_policies)
print(lerobot.available_policies_per_env)
print(lerobot.available_robots)
```

When implementing a new dataset loadable with LeRobotDataset follow these steps:
Expand Down Expand Up @@ -182,14 +183,21 @@
itertools.chain(*available_datasets_per_env.values(), available_real_world_datasets)
)

# lists all available policies from `lerobot/common/policies` by their class attribute: `name`.
# lists all available policies from `lerobot/common/policies`
available_policies = [
"act",
"diffusion",
"tdmpc",
"vqbet",
]

# lists all available robots from `lerobot/common/robot_devices/robots`
available_robots = [
"koch",
"koch_bimanual",
"aloha",
]

# keys and values refer to yaml files
available_policies_per_env = {
"aloha": ["act"],
Expand Down
7 changes: 5 additions & 2 deletions lerobot/common/robot_devices/cameras/opencv.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,12 @@
import numpy as np
from PIL import Image

from lerobot.common.robot_devices.utils import RobotDeviceAlreadyConnectedError, RobotDeviceNotConnectedError
from lerobot.common.robot_devices.utils import (
RobotDeviceAlreadyConnectedError,
RobotDeviceNotConnectedError,
busy_wait,
)
from lerobot.common.utils.utils import capture_timestamp_utc
from lerobot.scripts.control_robot import busy_wait

# Use 1 thread to avoid blocking the main thread. Especially useful during data collection
# when other threads are used to save the images.
Expand Down
Loading
Loading