Merge branch 'main' into aloha_hd5_to_dataset_v2

This commit is contained in:
Claudio Coppola 2025-01-28 13:23:48 +00:00 committed by GitHub
commit 82fefed17c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 40 additions and 9 deletions

View File

@ -54,9 +54,9 @@ Then plug the 12V power supply to the motor bus of the follower arm. It has two
Finally, connect both arms to your computer via USB. Note that the USB doesn't provide any power, and both arms need to be plugged in with their associated power supply to be detected by your computer. Finally, connect both arms to your computer via USB. Note that the USB doesn't provide any power, and both arms need to be plugged in with their associated power supply to be detected by your computer.
*Copy pasting python code* Now you are ready to configure your motors for the first time, as detailed in the sections below. In the upcoming sections, you'll learn about our classes and functions by running some python code in an interactive session, or by copy-pasting it in a python file.
In the upcoming sections, you'll learn about our classes and functions by running some python code, in an interactive session, or by copy-pasting it in a python file. If this is your first time using the tutorial., we highly recommend going through these steps to get deeper intuition about how things work. Once you're more familiar, you can streamline the process by directly running the teleoperate script (which is detailed further in the tutorial): If you have already configured your motors the first time, you can streamline the process by directly running the teleoperate script (which is detailed further in the tutorial):
```bash ```bash
python lerobot/scripts/control_robot.py teleoperate \ python lerobot/scripts/control_robot.py teleoperate \
--robot-path lerobot/configs/robot/koch.yaml \ --robot-path lerobot/configs/robot/koch.yaml \
@ -64,14 +64,43 @@ python lerobot/scripts/control_robot.py teleoperate \
``` ```
It will automatically: It will automatically:
1. Detect and help you correct any motor configuration issues. 1. Identify any missing calibrations and initiate the calibration procedure.
2. Identify any missing calibrations and initiate the calibration procedure. 2. Connect the robot and start teleoperation.
3. Connect the robot and start teleoperation.
### a. Control your motors with DynamixelMotorsBus ### a. Control your motors with DynamixelMotorsBus
You can use the [`DynamixelMotorsBus`](../lerobot/common/robot_devices/motors/dynamixel.py) to communicate with the motors connected as a chain to the corresponding USB bus. This class leverages the Python [Dynamixel SDK](https://emanual.robotis.com/docs/en/software/dynamixel/dynamixel_sdk/sample_code/python_read_write_protocol_2_0/#python-read-write-protocol-20) to facilitate reading from and writing to the motors. You can use the [`DynamixelMotorsBus`](../lerobot/common/robot_devices/motors/dynamixel.py) to communicate with the motors connected as a chain to the corresponding USB bus. This class leverages the Python [Dynamixel SDK](https://emanual.robotis.com/docs/en/software/dynamixel/dynamixel_sdk/sample_code/python_read_write_protocol_2_0/#python-read-write-protocol-20) to facilitate reading from and writing to the motors.
**First Configuration of your motors**
You will need to unplug each motor in turn and run a command the identify the motor. The motor will save its own identification, so you only need to do this once. Start by unplugging all of the motors.
Do the Leader arm first, as all of its motors are of the same type. Plug in your first motor on your leader arm and run this script to set its ID to 1.
```bash
python lerobot/scripts/configure_motor.py \
--port /dev/tty.usbmodem58760432961 \
--brand dynamixel \
--model xl330-m288 \
--baudrate 1000000 \
--ID 1
```
Then unplug your first motor and plug the second motor and set its ID to 2.
```bash
python lerobot/scripts/configure_motor.py \
--port /dev/tty.usbmodem58760432961 \
--brand dynamixel \
--model xl330-m288 \
--baudrate 1000000 \
--ID 2
```
Redo the process for all your motors until ID 6.
The process for the follower arm is almost the same, but the follower arm has two types of motors. For the first two motors, make sure you set the model to `xl430-w250`. _Important: configuring follower motors requires plugging and unplugging power. Make sure you use the 5V power for the XL330s and the 12V power for the XL430s!_
After all of your motors are configured properly, you're ready to plug them all together in a daisy-chain as shown in the original video.
**Instantiate the DynamixelMotorsBus** **Instantiate the DynamixelMotorsBus**
To begin, create two instances of the [`DynamixelMotorsBus`](../lerobot/common/robot_devices/motors/dynamixel.py), one for each arm, using their corresponding USB ports (e.g. `DynamixelMotorsBus(port="/dev/tty.usbmodem575E0031751"`). To begin, create two instances of the [`DynamixelMotorsBus`](../lerobot/common/robot_devices/motors/dynamixel.py), one for each arm, using their corresponding USB ports (e.g. `DynamixelMotorsBus(port="/dev/tty.usbmodem575E0031751"`).

View File

@ -76,6 +76,7 @@ def configure_motor(port, brand, model, motor_idx_des, baudrate_des):
"Error: More than one motor ID detected. This script is designed to only handle one motor at a time. Please disconnect all but one motor." "Error: More than one motor ID detected. This script is designed to only handle one motor at a time. Please disconnect all but one motor."
) )
motor_index = present_ids[0] motor_index = present_ids[0]
break
if motor_index == -1: if motor_index == -1:
raise ValueError("No motors detected. Please ensure you have one motor connected.") raise ValueError("No motors detected. Please ensure you have one motor connected.")
@ -102,6 +103,7 @@ def configure_motor(port, brand, model, motor_idx_des, baudrate_des):
raise OSError("Failed to write baudrate.") raise OSError("Failed to write baudrate.")
print(f"Setting its index to desired index {motor_idx_des}") print(f"Setting its index to desired index {motor_idx_des}")
if brand == "feetech":
motor_bus.write_with_motor_ids(motor_bus.motor_models, motor_index, "Lock", 0) motor_bus.write_with_motor_ids(motor_bus.motor_models, motor_index, "Lock", 0)
motor_bus.write_with_motor_ids(motor_bus.motor_models, motor_index, "ID", motor_idx_des) motor_bus.write_with_motor_ids(motor_bus.motor_models, motor_index, "ID", motor_idx_des)

View File

@ -15,14 +15,14 @@
# limitations under the License. # limitations under the License.
""" Visualize data of **all** frames of any episode of a dataset of type LeRobotDataset. """ Visualize data of **all** frames of any episode of a dataset of type LeRobotDataset.
Note: The last frame of the episode doesnt always correspond to a final state. Note: The last frame of the episode doesn't always correspond to a final state.
That's because our datasets are composed of transition from state to state up to That's because our datasets are composed of transition from state to state up to
the antepenultimate state associated to the ultimate action to arrive in the final state. the antepenultimate state associated to the ultimate action to arrive in the final state.
However, there might not be a transition from a final state to another state. However, there might not be a transition from a final state to another state.
Note: This script aims to visualize the data used to train the neural networks. Note: This script aims to visualize the data used to train the neural networks.
~What you see is what you get~. When visualizing image modality, it is often expected to observe ~What you see is what you get~. When visualizing image modality, it is often expected to observe
lossly compression artifacts since these images have been decoded from compressed mp4 videos to lossy compression artifacts since these images have been decoded from compressed mp4 videos to
save disk space. The compression factor applied has been tuned to not affect success rate. save disk space. The compression factor applied has been tuned to not affect success rate.
Examples: Examples:
@ -199,7 +199,7 @@ def main():
"--repo-id", "--repo-id",
type=str, type=str,
required=True, required=True,
help="Name of hugging face repositery containing a LeRobotDataset dataset (e.g. `lerobot/pusht`).", help="Name of hugging face repository containing a LeRobotDataset dataset (e.g. `lerobot/pusht`).",
) )
parser.add_argument( parser.add_argument(
"--episode-index", "--episode-index",