refactor(cameras): realsense config arg serial_number_or_name
This commit is contained in:
@@ -66,7 +66,7 @@ class RealSenseCamera(Camera):
|
|||||||
from lerobot.common.cameras import ColorMode
|
from lerobot.common.cameras import ColorMode
|
||||||
|
|
||||||
# Basic usage with serial number
|
# Basic usage with serial number
|
||||||
config = RealSenseCameraConfig(serial_number="1234567890") # Replace with actual SN
|
config = RealSenseCameraConfig(serial_number_or_name="1234567890") # Replace with actual SN
|
||||||
camera = RealSenseCamera(config)
|
camera = RealSenseCamera(config)
|
||||||
camera.connect()
|
camera.connect()
|
||||||
|
|
||||||
@@ -82,7 +82,7 @@ class RealSenseCamera(Camera):
|
|||||||
|
|
||||||
# Example with depth capture and custom settings
|
# Example with depth capture and custom settings
|
||||||
custom_config = RealSenseCameraConfig(
|
custom_config = RealSenseCameraConfig(
|
||||||
serial_number="1234567890", # Replace with actual SN
|
serial_number_or_name="1234567890", # Replace with actual SN
|
||||||
fps=30,
|
fps=30,
|
||||||
width=1280,
|
width=1280,
|
||||||
height=720,
|
height=720,
|
||||||
@@ -99,7 +99,7 @@ class RealSenseCamera(Camera):
|
|||||||
depth_camera.disconnect()
|
depth_camera.disconnect()
|
||||||
|
|
||||||
# Example using a unique camera name
|
# Example using a unique camera name
|
||||||
name_config = RealSenseCameraConfig(name="Intel RealSense D435") # If unique
|
name_config = RealSenseCameraConfig(serial_number_or_name="Intel RealSense D435") # If unique
|
||||||
name_camera = RealSenseCamera(name_config)
|
name_camera = RealSenseCamera(name_config)
|
||||||
# ... connect, read, disconnect ...
|
# ... connect, read, disconnect ...
|
||||||
```
|
```
|
||||||
@@ -117,12 +117,10 @@ class RealSenseCamera(Camera):
|
|||||||
|
|
||||||
self.config = config
|
self.config = config
|
||||||
|
|
||||||
if config.name is not None: # NOTE(Steven): Do we want to continue supporting this?
|
if isinstance(config.serial_number_or_name, int):
|
||||||
self.serial_number = self._find_serial_number_from_name(config.name)
|
self.serial_number = str(config.serial_number_or_name)
|
||||||
elif config.serial_number is not None:
|
|
||||||
self.serial_number = str(config.serial_number)
|
|
||||||
else:
|
else:
|
||||||
raise ValueError("RealSenseCameraConfig must provide either 'serial_number' or 'name'.")
|
self.serial_number = self._find_serial_number_from_name(config.serial_number_or_name)
|
||||||
|
|
||||||
self.fps = config.fps
|
self.fps = config.fps
|
||||||
self.color_mode = config.color_mode
|
self.color_mode = config.color_mode
|
||||||
|
|||||||
@@ -40,9 +40,7 @@ class RealSenseCameraConfig(CameraConfig):
|
|||||||
fps: Requested frames per second for the color stream.
|
fps: Requested frames per second for the color stream.
|
||||||
width: Requested frame width in pixels for the color stream.
|
width: Requested frame width in pixels for the color stream.
|
||||||
height: Requested frame height in pixels for the color stream.
|
height: Requested frame height in pixels for the color stream.
|
||||||
name: Optional human-readable name to identify the camera.
|
serial_number_or_name: unique serial number or human-readable name to identify the camera.
|
||||||
serial_number: Optional unique serial number to identify the camera.
|
|
||||||
Either name or serial_number must be provided.
|
|
||||||
color_mode: Color mode for image output (RGB or BGR). Defaults to RGB.
|
color_mode: Color mode for image output (RGB or BGR). Defaults to RGB.
|
||||||
use_depth: Whether to enable depth stream. Defaults to False.
|
use_depth: Whether to enable depth stream. Defaults to False.
|
||||||
rotation: Image rotation setting (0°, 90°, 180°, or 270°). Defaults to no rotation.
|
rotation: Image rotation setting (0°, 90°, 180°, or 270°). Defaults to no rotation.
|
||||||
@@ -54,8 +52,7 @@ class RealSenseCameraConfig(CameraConfig):
|
|||||||
- Only 3-channel color output (RGB/BGR) is currently supported.
|
- Only 3-channel color output (RGB/BGR) is currently supported.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
name: str | None = None
|
serial_number_or_name: int | str
|
||||||
serial_number: int | None = None
|
|
||||||
color_mode: ColorMode = ColorMode.RGB
|
color_mode: ColorMode = ColorMode.RGB
|
||||||
use_depth: bool = False
|
use_depth: bool = False
|
||||||
rotation: Cv2Rotation = Cv2Rotation.NO_ROTATION # NOTE(Steven): Check if draccus can parse to an enum
|
rotation: Cv2Rotation = Cv2Rotation.NO_ROTATION # NOTE(Steven): Check if draccus can parse to an enum
|
||||||
@@ -75,8 +72,3 @@ class RealSenseCameraConfig(CameraConfig):
|
|||||||
raise ValueError(
|
raise ValueError(
|
||||||
f"`rotation` is expected to be in {(Cv2Rotation.NO_ROTATION, Cv2Rotation.ROTATE_90, Cv2Rotation.ROTATE_180, Cv2Rotation.ROTATE_270)}, but {self.rotation} is provided."
|
f"`rotation` is expected to be in {(Cv2Rotation.NO_ROTATION, Cv2Rotation.ROTATE_90, Cv2Rotation.ROTATE_180, Cv2Rotation.ROTATE_270)}, but {self.rotation} is provided."
|
||||||
)
|
)
|
||||||
|
|
||||||
if bool(self.name) and bool(self.serial_number):
|
|
||||||
raise ValueError(
|
|
||||||
f"One of them must be set: name or serial_number, but {self.name=} and {self.serial_number=} provided."
|
|
||||||
)
|
|
||||||
|
|||||||
@@ -51,13 +51,13 @@ def mock_rs_config_enable_device_bad_file(rs_config_instance, sn):
|
|||||||
|
|
||||||
def test_abc_implementation():
|
def test_abc_implementation():
|
||||||
"""Instantiation should raise an error if the class doesn't implement abstract methods/properties."""
|
"""Instantiation should raise an error if the class doesn't implement abstract methods/properties."""
|
||||||
config = RealSenseCameraConfig(serial_number=42)
|
config = RealSenseCameraConfig(serial_number_or_name=42)
|
||||||
_ = RealSenseCamera(config)
|
_ = RealSenseCamera(config)
|
||||||
|
|
||||||
|
|
||||||
@patch("pyrealsense2.config.enable_device", side_effect=mock_rs_config_enable_device_from_file)
|
@patch("pyrealsense2.config.enable_device", side_effect=mock_rs_config_enable_device_from_file)
|
||||||
def test_connect(mock_enable_device):
|
def test_connect(mock_enable_device):
|
||||||
config = RealSenseCameraConfig(serial_number=42)
|
config = RealSenseCameraConfig(serial_number_or_name=42)
|
||||||
camera = RealSenseCamera(config)
|
camera = RealSenseCamera(config)
|
||||||
|
|
||||||
camera.connect(warmup=False)
|
camera.connect(warmup=False)
|
||||||
@@ -66,7 +66,7 @@ def test_connect(mock_enable_device):
|
|||||||
|
|
||||||
@patch("pyrealsense2.config.enable_device", side_effect=mock_rs_config_enable_device_from_file)
|
@patch("pyrealsense2.config.enable_device", side_effect=mock_rs_config_enable_device_from_file)
|
||||||
def test_connect_already_connected(mock_enable_device):
|
def test_connect_already_connected(mock_enable_device):
|
||||||
config = RealSenseCameraConfig(serial_number=42)
|
config = RealSenseCameraConfig(serial_number_or_name=42)
|
||||||
camera = RealSenseCamera(config)
|
camera = RealSenseCamera(config)
|
||||||
camera.connect(warmup=False)
|
camera.connect(warmup=False)
|
||||||
|
|
||||||
@@ -76,7 +76,7 @@ def test_connect_already_connected(mock_enable_device):
|
|||||||
|
|
||||||
@patch("pyrealsense2.config.enable_device", side_effect=mock_rs_config_enable_device_bad_file)
|
@patch("pyrealsense2.config.enable_device", side_effect=mock_rs_config_enable_device_bad_file)
|
||||||
def test_connect_invalid_camera_path(mock_enable_device):
|
def test_connect_invalid_camera_path(mock_enable_device):
|
||||||
config = RealSenseCameraConfig(serial_number=42)
|
config = RealSenseCameraConfig(serial_number_or_name=42)
|
||||||
camera = RealSenseCamera(config)
|
camera = RealSenseCamera(config)
|
||||||
|
|
||||||
with pytest.raises(ConnectionError):
|
with pytest.raises(ConnectionError):
|
||||||
@@ -85,7 +85,7 @@ def test_connect_invalid_camera_path(mock_enable_device):
|
|||||||
|
|
||||||
@patch("pyrealsense2.config.enable_device", side_effect=mock_rs_config_enable_device_from_file)
|
@patch("pyrealsense2.config.enable_device", side_effect=mock_rs_config_enable_device_from_file)
|
||||||
def test_invalid_width_connect(mock_enable_device):
|
def test_invalid_width_connect(mock_enable_device):
|
||||||
config = RealSenseCameraConfig(serial_number=42, width=99999, height=480, fps=30)
|
config = RealSenseCameraConfig(serial_number_or_name=42, width=99999, height=480, fps=30)
|
||||||
camera = RealSenseCamera(config)
|
camera = RealSenseCamera(config)
|
||||||
|
|
||||||
with pytest.raises(ConnectionError):
|
with pytest.raises(ConnectionError):
|
||||||
@@ -94,7 +94,7 @@ def test_invalid_width_connect(mock_enable_device):
|
|||||||
|
|
||||||
@patch("pyrealsense2.config.enable_device", side_effect=mock_rs_config_enable_device_from_file)
|
@patch("pyrealsense2.config.enable_device", side_effect=mock_rs_config_enable_device_from_file)
|
||||||
def test_read(mock_enable_device):
|
def test_read(mock_enable_device):
|
||||||
config = RealSenseCameraConfig(serial_number=42, width=640, height=480, fps=30)
|
config = RealSenseCameraConfig(serial_number_or_name=42, width=640, height=480, fps=30)
|
||||||
camera = RealSenseCamera(config)
|
camera = RealSenseCamera(config)
|
||||||
camera.connect(warmup=False)
|
camera.connect(warmup=False)
|
||||||
|
|
||||||
@@ -103,7 +103,7 @@ def test_read(mock_enable_device):
|
|||||||
|
|
||||||
|
|
||||||
def test_read_before_connect():
|
def test_read_before_connect():
|
||||||
config = RealSenseCameraConfig(serial_number=42)
|
config = RealSenseCameraConfig(serial_number_or_name=42)
|
||||||
camera = RealSenseCamera(config)
|
camera = RealSenseCamera(config)
|
||||||
|
|
||||||
with pytest.raises(DeviceNotConnectedError):
|
with pytest.raises(DeviceNotConnectedError):
|
||||||
@@ -112,7 +112,7 @@ def test_read_before_connect():
|
|||||||
|
|
||||||
@patch("pyrealsense2.config.enable_device", side_effect=mock_rs_config_enable_device_from_file)
|
@patch("pyrealsense2.config.enable_device", side_effect=mock_rs_config_enable_device_from_file)
|
||||||
def test_disconnect(mock_enable_device):
|
def test_disconnect(mock_enable_device):
|
||||||
config = RealSenseCameraConfig(serial_number=42)
|
config = RealSenseCameraConfig(serial_number_or_name=42)
|
||||||
camera = RealSenseCamera(config)
|
camera = RealSenseCamera(config)
|
||||||
camera.connect(warmup=False)
|
camera.connect(warmup=False)
|
||||||
|
|
||||||
@@ -122,7 +122,7 @@ def test_disconnect(mock_enable_device):
|
|||||||
|
|
||||||
|
|
||||||
def test_disconnect_before_connect():
|
def test_disconnect_before_connect():
|
||||||
config = RealSenseCameraConfig(serial_number=42)
|
config = RealSenseCameraConfig(serial_number_or_name=42)
|
||||||
camera = RealSenseCamera(config)
|
camera = RealSenseCamera(config)
|
||||||
|
|
||||||
with pytest.raises(DeviceNotConnectedError):
|
with pytest.raises(DeviceNotConnectedError):
|
||||||
@@ -131,7 +131,7 @@ def test_disconnect_before_connect():
|
|||||||
|
|
||||||
@patch("pyrealsense2.config.enable_device", side_effect=mock_rs_config_enable_device_from_file)
|
@patch("pyrealsense2.config.enable_device", side_effect=mock_rs_config_enable_device_from_file)
|
||||||
def test_async_read(mock_enable_device):
|
def test_async_read(mock_enable_device):
|
||||||
config = RealSenseCameraConfig(serial_number=42, width=640, height=480, fps=30)
|
config = RealSenseCameraConfig(serial_number_or_name=42, width=640, height=480, fps=30)
|
||||||
camera = RealSenseCamera(config)
|
camera = RealSenseCamera(config)
|
||||||
camera.connect(warmup=False)
|
camera.connect(warmup=False)
|
||||||
|
|
||||||
@@ -148,7 +148,7 @@ def test_async_read(mock_enable_device):
|
|||||||
|
|
||||||
@patch("pyrealsense2.config.enable_device", side_effect=mock_rs_config_enable_device_from_file)
|
@patch("pyrealsense2.config.enable_device", side_effect=mock_rs_config_enable_device_from_file)
|
||||||
def test_async_read_timeout(mock_enable_device):
|
def test_async_read_timeout(mock_enable_device):
|
||||||
config = RealSenseCameraConfig(serial_number=42, width=640, height=480, fps=30)
|
config = RealSenseCameraConfig(serial_number_or_name=42, width=640, height=480, fps=30)
|
||||||
camera = RealSenseCamera(config)
|
camera = RealSenseCamera(config)
|
||||||
camera.connect(warmup=False)
|
camera.connect(warmup=False)
|
||||||
|
|
||||||
@@ -163,7 +163,7 @@ def test_async_read_timeout(mock_enable_device):
|
|||||||
|
|
||||||
|
|
||||||
def test_async_read_before_connect():
|
def test_async_read_before_connect():
|
||||||
config = RealSenseCameraConfig(serial_number=42)
|
config = RealSenseCameraConfig(serial_number_or_name=42)
|
||||||
camera = RealSenseCamera(config)
|
camera = RealSenseCamera(config)
|
||||||
|
|
||||||
with pytest.raises(DeviceNotConnectedError):
|
with pytest.raises(DeviceNotConnectedError):
|
||||||
@@ -182,7 +182,7 @@ def test_async_read_before_connect():
|
|||||||
)
|
)
|
||||||
@patch("pyrealsense2.config.enable_device", side_effect=mock_rs_config_enable_device_from_file)
|
@patch("pyrealsense2.config.enable_device", side_effect=mock_rs_config_enable_device_from_file)
|
||||||
def test_rotation(mock_enable_device, rotation):
|
def test_rotation(mock_enable_device, rotation):
|
||||||
config = RealSenseCameraConfig(serial_number=42, rotation=rotation)
|
config = RealSenseCameraConfig(serial_number_or_name=42, rotation=rotation)
|
||||||
camera = RealSenseCamera(config)
|
camera = RealSenseCamera(config)
|
||||||
camera.connect(warmup=False)
|
camera.connect(warmup=False)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user