Skip to content

Commit e7f839e

Browse files
committed
refactor(camera): hardware camera with composition and digit as camera
- each camera can be configured individually - HardwareCameraSet uses HardwareCamera interface with composition instead of inheritance - BaseCameraConfig moved to cpp - removed digit camera set wrapper as camera set wrapper is used now
1 parent 9bd3618 commit e7f839e

21 files changed

Lines changed: 427 additions & 422 deletions

pyproject.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ dependencies = ["websockets>=11.0",
1111
"numpy",
1212
"typer~=0.9",
1313
"gymnasium~=0.29.1",
14-
"pydantic_yaml~=1.3",
1514
"absl-py~=2.1",
1615
"etils[epath]>=1.7.0",
1716
"glfw~=2.7",

python/examples/env_cartesian_control.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ def main():
6767
robot_cfg=default_fr3_sim_robot_cfg(),
6868
collision_guard=False,
6969
gripper_cfg=default_fr3_sim_gripper_cfg(),
70-
camera_set_cfg=default_mujoco_cameraset_cfg(),
70+
cameras=default_mujoco_cameraset_cfg(),
7171
max_relative_movement=0.5,
7272
relative_to=RelativeTo.LAST_STEP,
7373
)

python/examples/env_cartesian_control_digit.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
default_mujoco_cameraset_cfg,
1414
)
1515

16+
from python.rcs.camera.hw import HardwareCameraSet
17+
1618
logger = logging.getLogger(__name__)
1719
logger.setLevel(logging.INFO)
1820

@@ -57,8 +59,8 @@ def main():
5759
control_mode=ControlMode.CARTESIAN_TQuat,
5860
robot_cfg=default_fr3_hw_robot_cfg(),
5961
collision_guard="lab",
62+
camera_set=HardwareCameraSet(default_digit({"digit_0": "D21182"})),
6063
gripper_cfg=default_fr3_hw_gripper_cfg(),
61-
digit_set=default_digit({"digit_0": "D21182"}),
6264
max_relative_movement=0.5,
6365
relative_to=RelativeTo.LAST_STEP,
6466
)
@@ -68,7 +70,7 @@ def main():
6870
robot_cfg=default_fr3_sim_robot_cfg(),
6971
collision_guard=False,
7072
gripper_cfg=default_fr3_sim_gripper_cfg(),
71-
camera_set_cfg=default_mujoco_cameraset_cfg(),
73+
cameras=default_mujoco_cameraset_cfg(),
7274
max_relative_movement=0.5,
7375
relative_to=RelativeTo.LAST_STEP,
7476
)

python/examples/env_cartesian_control_tilburg.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ def main():
6666
robot_cfg=default_fr3_sim_robot_cfg(),
6767
collision_guard=False,
6868
gripper_cfg=default_fr3_sim_gripper_cfg(),
69-
camera_set_cfg=default_mujoco_cameraset_cfg(),
69+
cameras=default_mujoco_cameraset_cfg(),
7070
max_relative_movement=0.5,
7171
relative_to=RelativeTo.LAST_STEP,
7272
)

python/examples/env_joint_control.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ def main():
6868
collision_guard=False,
6969
robot_cfg=default_fr3_sim_robot_cfg(),
7070
gripper_cfg=default_fr3_sim_gripper_cfg(),
71-
camera_set_cfg=default_mujoco_cameraset_cfg(),
71+
cameras=default_mujoco_cameraset_cfg(),
7272
max_relative_movement=np.deg2rad(5),
7373
relative_to=RelativeTo.LAST_STEP,
7474
)

python/examples/fr3.py

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from rcs._core.common import RobotPlatform
88
from rcs._core.hw import FR3Config, IKSolver
99
from rcs._core.sim import CameraType
10-
from rcs.camera.sim import SimCameraConfig, SimCameraSet, SimCameraSetConfig
10+
from rcs.camera.sim import SimCameraConfig, SimCameraSet
1111
from rcs.control.fr3_desk import FCI, ContextManager, Desk, load_creds_fr3_desk
1212
from rcs.envs.creators import get_urdf_path
1313

@@ -80,11 +80,22 @@ def main():
8080

8181
# add camera to have a rendering gui
8282
cameras = {
83-
"default_free": SimCameraConfig(identifier="", type=int(CameraType.default_free)),
84-
"wrist": SimCameraConfig(identifier="wrist_0", type=int(CameraType.fixed)),
83+
"default_free": SimCameraConfig(
84+
identifier="",
85+
type=CameraType.default_free,
86+
resolution_width=1280,
87+
resolution_height=720,
88+
frame_rate=20,
89+
),
90+
"wrist": SimCameraConfig(
91+
identifier="wrist_0",
92+
type=CameraType.fixed,
93+
resolution_width=640,
94+
resolution_height=480,
95+
frame_rate=30,
96+
),
8597
}
86-
cam_cfg = SimCameraSetConfig(cameras=cameras, resolution_width=1280, resolution_height=720, frame_rate=20)
87-
camera_set = SimCameraSet(simulation, cam_cfg) # noqa: F841
98+
camera_set = SimCameraSet(simulation, cameras) # noqa: F841
8899
simulation.open_gui()
89100

90101
else:

python/rcs/_core/sim.pyi

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,9 @@ class Sim:
8484

8585
class SimCameraConfig(rcs._core.common.BaseCameraConfig):
8686
type: CameraType
87+
def __init__(
88+
self, identifier: str, frame_rate: int, resolution_width: int, resolution_height: int, type: CameraType = ...
89+
) -> None: ...
8790

8891
class SimCameraSet:
8992
def __init__(self, sim: Sim, cameras: dict[str, SimCameraConfig], render_on_demand: bool = True) -> None: ...

python/rcs/camera/digit_cam.py

Lines changed: 25 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,36 @@
11
from digit_interface.digit import Digit
2-
from rcs.camera.hw import BaseHardwareCameraSet, HWCameraSetConfig
2+
from rcs._core.common import BaseCameraConfig
3+
from rcs.camera.hw import HardwareCamera
34
from rcs.camera.interface import CameraFrame, DataFrame, Frame
45

56

6-
class DigitConfig(HWCameraSetConfig):
7-
"""
8-
Configuration for the DIGIT device.
9-
This class is used to define the settings for the DIGIT device.
10-
"""
11-
12-
stream_name: str = "QVGA" # options: "QVGA" (60 and 30 fps), "VGA" (30 and 15 fps)
13-
14-
15-
class DigitCam(BaseHardwareCameraSet):
7+
class DigitCam(HardwareCamera):
168
"""
179
This module provides an interface to interact with the DIGIT device.
1810
It allows for connecting to the device, changing settings, and retrieving information.
1911
"""
2012

21-
def __init__(self, cfg: DigitConfig):
22-
self._cfg = cfg
23-
super().__init__()
13+
def __init__(self, cameras: dict[str, BaseCameraConfig]):
14+
self.cameras = cameras
15+
self._camera_names = list(self.cameras.keys())
2416
self._cameras: dict[str, Digit] = {}
25-
self.initalize(self.config)
2617

27-
def initalize(self, cfg: HWCameraSetConfig):
18+
def open(self):
2819
"""
2920
Initialize the digit interface with the given configuration.
3021
:param cfg: Configuration for the DIGIT device.
3122
"""
32-
for name, serial in cfg.name_to_identifier.items():
33-
digit = Digit(serial, name)
23+
for name, camera in self.cameras.items():
24+
digit = Digit(camera.identifier, name)
3425
digit.connect()
3526
self._cameras[name] = digit
3627

37-
def _poll_frame(self, camera_name: str) -> Frame:
28+
@property
29+
def camera_names(self) -> list[str]:
30+
"""Returns the names of the cameras in this set."""
31+
return self._camera_names
32+
33+
def poll_frame(self, camera_name: str) -> Frame:
3834
"""Polls the frame from the camera with the given name."""
3935
digit = self._cameras[camera_name]
4036
frame = digit.get_frame()
@@ -45,6 +41,13 @@ def _poll_frame(self, camera_name: str) -> Frame:
4541

4642
return Frame(camera=cf)
4743

48-
@property
49-
def config(self) -> DigitConfig:
50-
return self._cfg
44+
def close(self):
45+
"""
46+
Closes the connection to the DIGIT device.
47+
"""
48+
for digit in self._cameras.values():
49+
digit.disconnect()
50+
self._cameras = {}
51+
52+
def config(self, camera_name) -> BaseCameraConfig:
53+
return self.cameras[camera_name]

0 commit comments

Comments
 (0)