Update opencv and dynamixel (find_port)

This commit is contained in:
Remi Cadene 2024-07-10 18:47:59 +02:00
parent 7411cf2a7a
commit f7a7ed9aa9
4 changed files with 75 additions and 2 deletions

View File

@ -155,7 +155,10 @@ class OpenCVCamera:
python lerobot/common/robot_devices/cameras/opencv.py --images-dir outputs/images_from_opencv_cameras python lerobot/common/robot_devices/cameras/opencv.py --images-dir outputs/images_from_opencv_cameras
``` ```
Example of uage of the class: When an OpenCVCamera is instantiated, if no specific config is provided, the default fps, width, height and color
of the given camera will be used.
Example of usage of the class:
```python ```python
camera = OpenCVCamera(camera_index=0) camera = OpenCVCamera(camera_index=0)
camera.connect() camera.connect()
@ -163,6 +166,18 @@ class OpenCVCamera:
# when done using the camera, consider disconnecting # when done using the camera, consider disconnecting
camera.disconnect() camera.disconnect()
``` ```
Example of changing default fps, width, height and color:
```python
camera = OpenCVCamera(0, fps=30, width=1280, height=720)
camera = connect() # applies the settings, might error out if these settings are not compatible with the camera
camera = OpenCVCamera(0, fps=90, width=640, height=480)
camera = connect()
camera = OpenCVCamera(0, fps=90, width=640, height=480, color="bgr")
camera = connect()
```
""" """
def __init__(self, camera_index: int, config: OpenCVCameraConfig | None = None, **kwargs): def __init__(self, camera_index: int, config: OpenCVCameraConfig | None = None, **kwargs):

View File

@ -1,6 +1,7 @@
import enum import enum
import time import time
from copy import deepcopy from copy import deepcopy
from pathlib import Path
import numpy as np import numpy as np
from dynamixel_sdk import ( from dynamixel_sdk import (
@ -159,6 +160,35 @@ def get_log_name(var_name, fn_name, data_name, motor_names):
return log_name return log_name
def find_available_ports():
ports = []
for path in Path("/dev").glob("tty.usbmodem*"):
ports.append(str(path))
return ports
def find_port():
print("Finding all available ports for the DynamixelMotorsBus.")
ports_before = find_available_ports()
print(ports_before)
print("Remove the usb cable from your DynamixelMotorsBus and press Enter when done.")
input()
time.sleep(0.5)
ports_after = find_available_ports()
ports_diff = list(set(ports_before) - set(ports_after))
if len(ports_diff) == 1:
port = ports_diff[0]
print(f"The port of this DynamixelMotorsBus is {port}.")
print("Reconnect the usb cable.")
elif len(ports_diff) == 0:
raise OSError(f"Could not detect the port. No difference was found ({ports_diff}).")
else:
raise OSError(f"Could not detect the port. More than one port was found ({ports_diff}).")
class TorqueMode(enum.Enum): class TorqueMode(enum.Enum):
ENABLED = 1 ENABLED = 1
DISABLED = 0 DISABLED = 0
@ -179,7 +209,23 @@ class DriveMode(enum.Enum):
class DynamixelMotorsBus: class DynamixelMotorsBus:
# TODO(rcadene): Add a script to find the motor indices without DynamixelWizzard2
""" """
The DynamixelMotorsBus class allows to efficiently read and write to the attached motors. It relies on
the python dynamixel sdk to communicate with the motors. For more info, see the [Dynamixel SDK Documentation](https://emanual.robotis.com/docs/en/software/dynamixel/dynamixel_sdk/sample_code/python_read_write_protocol_2_0/#python-read-write-protocol-20).
A DynamixelMotorsBus instance requires a port (e.g. `DynamixelMotorsBus(port="/dev/tty.usbmodem575E0031751"`)).
To find the port, you can run our utility script:
```bash
python lerobot/common/robot_devices/motors/dynamixel.py
>>> Finding all available ports for the DynamixelMotorsBus.
>>> ['/dev/tty.usbmodem575E0032081', '/dev/tty.usbmodem575E0031751']
>>> Remove the usb cable from your DynamixelMotorsBus and press Enter when done.
>>> The port of this DynamixelMotorsBus is /dev/tty.usbmodem575E0031751.
>>> Reconnect the usb cable.
```
To find the motor indices, use [DynamixelWizzard2](https://emanual.robotis.com/docs/en/software/dynamixel/dynamixel_wizard2).
Example of usage for 1 motor connected to the bus: Example of usage for 1 motor connected to the bus:
```python ```python
motor_name = "gripper" motor_name = "gripper"
@ -194,6 +240,7 @@ class DynamixelMotorsBus:
motors_bus.teleop_step() motors_bus.teleop_step()
# when done, consider disconnecting
motors_bus.disconnect() motors_bus.disconnect()
``` ```
""" """
@ -450,3 +497,8 @@ class DynamixelMotorsBus:
def __del__(self): def __del__(self):
if getattr(self, "is_connected", False): if getattr(self, "is_connected", False):
self.disconnect() self.disconnect()
if __name__ == "__main__":
# Helper to find the usb port associated to all your DynamixelMotorsBus.
find_port()

View File

@ -1,5 +1,7 @@
def make_robot(name): def make_robot(name):
if name == "koch": if name == "koch":
# TODO(rcadene): Add configurable robot from command line and yaml config
# TODO(rcadene): Add example with and without cameras
from lerobot.common.robot_devices.cameras.opencv import OpenCVCamera from lerobot.common.robot_devices.cameras.opencv import OpenCVCamera
from lerobot.common.robot_devices.motors.dynamixel import DynamixelMotorsBus from lerobot.common.robot_devices.motors.dynamixel import DynamixelMotorsBus
from lerobot.common.robot_devices.robots.koch import KochRobot from lerobot.common.robot_devices.robots.koch import KochRobot

View File

@ -3,7 +3,7 @@ import time
import numpy as np import numpy as np
import pytest import pytest
from lerobot.common.robot_devices.motors.dynamixel import DynamixelMotorsBus from lerobot.common.robot_devices.motors.dynamixel import DynamixelMotorsBus, find_port
from lerobot.common.robot_devices.utils import RobotDeviceAlreadyConnectedError, RobotDeviceNotConnectedError from lerobot.common.robot_devices.utils import RobotDeviceAlreadyConnectedError, RobotDeviceNotConnectedError
@ -81,3 +81,7 @@ def test_motors_bus():
time.sleep(1) time.sleep(1)
new_values = motors_bus.read("Present_Position") new_values = motors_bus.read("Present_Position")
assert (new_values == values).all() assert (new_values == values).all()
def test_find_port():
find_port()