Skip to content

Commit 70e7774

Browse files
authored
Merge pull request #189 from utn-mi/juelg/refactor-camera
Refactor the Camera Stack
2 parents 6203369 + e7f839e commit 70e7774

23 files changed

+501
-486
lines changed

pyproject.toml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,7 @@ dependencies = ["websockets>=11.0",
1010
"requests~=2.31",
1111
"numpy",
1212
"typer~=0.9",
13-
"pydantic~=2.6",
1413
"gymnasium~=0.29.1",
15-
"pydantic_yaml~=1.3",
1614
"absl-py~=2.1",
1715
"etils[epath]>=1.7.0",
1816
"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/common.pyi

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import numpy
1010
import pybind11_stubgen.typing_ext
1111

1212
__all__ = [
13+
"BaseCameraConfig",
1314
"FR3",
1415
"FrankaHandTCPOffset",
1516
"Gripper",
@@ -35,6 +36,13 @@ __all__ = [
3536
M = typing.TypeVar("M", bound=int)
3637
N = typing.TypeVar("N", bound=int)
3738

39+
class BaseCameraConfig:
40+
frame_rate: int
41+
identifier: str
42+
resolution_height: int
43+
resolution_width: int
44+
def __init__(self, identifier: str, frame_rate: int, resolution_width: int, resolution_height: int) -> None: ...
45+
3846
class Gripper:
3947
def get_normalized_width(self) -> float: ...
4048
def get_parameters(self) -> GripperConfig: ...

python/rcs/_core/sim.pyi

Lines changed: 5 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ __all__ = [
1515
"Sim",
1616
"SimCameraConfig",
1717
"SimCameraSet",
18-
"SimCameraSetConfig",
1918
"SimGripper",
2019
"SimGripperConfig",
2120
"SimGripperState",
@@ -83,35 +82,21 @@ class Sim:
8382
def step(self, k: int) -> None: ...
8483
def step_until_convergence(self) -> None: ...
8584

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

9191
class SimCameraSet:
92-
def __init__(self, sim: Sim, cfg: SimCameraSetConfig) -> None: ...
92+
def __init__(self, sim: Sim, cameras: dict[str, SimCameraConfig], render_on_demand: bool = True) -> None: ...
9393
def buffer_size(self) -> int: ...
9494
def clear_buffer(self) -> None: ...
9595
def get_latest_frameset(self) -> FrameSet | None: ...
9696
def get_timestamp_frameset(self, ts: float) -> FrameSet | None: ...
9797
@property
9898
def _sim(self) -> Sim: ...
9999

100-
class SimCameraSetConfig:
101-
cameras: dict[str, SimCameraConfig]
102-
max_buffer_frames: int
103-
resolution_height: int
104-
resolution_width: int
105-
def __init__(self) -> None: ...
106-
@property
107-
def frame_rate(self) -> int:
108-
"""
109-
The frame rate in which the cameras render in Hz. If set to zero, the camera frames will render on demand and without fixed rate which takes away compute effort.
110-
"""
111-
112-
@frame_rate.setter
113-
def frame_rate(self, arg0: int) -> None: ...
114-
115100
class SimGripper(rcs._core.common.Gripper):
116101
def __init__(self, sim: Sim, cfg: SimGripperConfig) -> None: ...
117102
def get_parameters(self) -> SimGripperConfig: ...

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)