diff --git a/dimos/hardware/test_webcam.py b/dimos/hardware/test_webcam.py index d51cc41924..e6d26d2b8d 100644 --- a/dimos/hardware/test_webcam.py +++ b/dimos/hardware/test_webcam.py @@ -43,14 +43,17 @@ def test_basic(): def test_module(): dimos = start(1) # Deploy ColorCameraModule, not Webcam directly - camera_module = dimos.deploy(ColorCameraModule) + camera_module = dimos.deploy( + ColorCameraModule, + hardware=lambda: Webcam(camera_index=4, frequency=30, stereo_slice="left"), + ) camera_module.image.transport = LCMTransport("/image", Image) camera_module.start() test_transport = LCMTransport("/image", Image) test_transport.subscribe(print) - time.sleep(2) + time.sleep(60) print("shutting down") camera_module.stop() diff --git a/dimos/hardware/webcam.py b/dimos/hardware/webcam.py index e733356a94..c45cb59515 100644 --- a/dimos/hardware/webcam.py +++ b/dimos/hardware/webcam.py @@ -18,7 +18,7 @@ from abc import ABC, abstractmethod, abstractproperty from dataclasses import dataclass, field from functools import cache -from typing import Any, Callable, Generic, Optional, Protocol, TypeVar +from typing import Any, Callable, Generic, Optional, Protocol, TypeVar, Literal import cv2 import numpy as np @@ -62,6 +62,7 @@ class WebcamConfig(CameraConfig): frequency: int = 10 camera_info: CameraInfo = field(default_factory=CameraInfo) frame_id_prefix: Optional[str] = None + stereo_slice: Optional[Literal["left", "right"]] = None # For stereo cameras class Webcam(ColorCameraHardware[WebcamConfig]): @@ -155,6 +156,15 @@ def capture_frame(self) -> Image: frame_id=self._frame("camera"), # Standard frame ID for camera images ts=time.time(), # Current timestamp ) + + if self.config.stereo_slice in ("left", "right"): + image.frame_id = self._frame(f"camera_stereo_{self.config.stereo_slice}") + half_width = image.width // 2 + if self.config.stereo_slice == "left": + image = image.crop(0, 0, half_width, image.height) + else: + image = image.crop(half_width, 0, half_width, image.height) + return image def _capture_loop(self):