Skip to content

Commit 74f1b17

Browse files
committed
style: fix python linting
1 parent 6c2d895 commit 74f1b17

10 files changed

Lines changed: 41 additions & 35 deletions

File tree

extensions/rcs_realsense/src/rcs_realsense/calibration.py

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@ def __init__(self, camera_name: str):
2121
# base frame to camera, world to base frame
2222
self._extrinsics: np.ndarray[tuple[typing.Literal[4], typing.Literal[4]], np.dtype[np.float64]] | None = None
2323
self.camera_name = camera_name
24-
self.tag_to_world = common.Pose(rpy_vector=[np.pi, 0, -np.pi / 2], translation=[0.145, 0, 0]).pose_matrix()
24+
self.tag_to_world = common.Pose(
25+
rpy_vector=np.array([np.pi, 0, -np.pi / 2]), translation=np.array([0.145, 0, 0])
26+
).pose_matrix()
2527

2628
def calibrate(
2729
self,
@@ -46,13 +48,11 @@ def calibrate(
4648
frames.append(sample.camera.color.data.copy())
4749
print(frames)
4850

49-
last_frame, tag_to_cam = get_average_marker_pose(
50-
frames, intrinsics=intrinsics, calib_tag_id=9, show_live_window=True
51-
)
51+
_, tag_to_cam = get_average_marker_pose(frames, intrinsics=intrinsics, calib_tag_id=9, show_live_window=False)
5252

5353
cam_to_world = self.tag_to_world @ np.linalg.inv(tag_to_cam)
5454
world_to_cam = np.linalg.inv(cam_to_world)
55-
self._extrinsics = world_to_cam
55+
self._extrinsics = world_to_cam # type: ignore
5656
return True
5757

5858
def get_extrinsics(self) -> np.ndarray[tuple[typing.Literal[4], typing.Literal[4]], np.dtype[np.float64]] | None:
@@ -82,8 +82,7 @@ def get_average_marker_pose(
8282
continue
8383

8484
for corner in marker_det.corners:
85-
corner = corner.astype(int)
86-
cv2.circle(frame, tuple(corner), 5, (0, 0, 255), -1)
85+
cv2.circle(frame, tuple(corner.astype(int)), 5, (0, 0, 255), -1)
8786

8887
poses.append(pose)
8988

@@ -92,7 +91,7 @@ def get_average_marker_pose(
9291
camera_matrix = intrinsics[:3, :3]
9392

9493
if show_live_window:
95-
cv2.drawFrameAxes(frame, camera_matrix, None, pose[:3, :3], pose[:3, 3], 0.1)
94+
cv2.drawFrameAxes(frame, camera_matrix, None, pose[:3, :3], pose[:3, 3], 0.1) # type: ignore
9695
# show frame
9796
cv2.imshow("frame", frame)
9897

@@ -107,12 +106,9 @@ def get_average_marker_pose(
107106
cv2.destroyAllWindows()
108107

109108
# calculate the average marker pose
110-
poses = np.array(poses)
111109
avg_pose = np.mean(poses, axis=0)
112110
logger.info(f"Average pose: {avg_pose}")
113111

114-
# paint avg pose on last frame
115-
# cv2.drawFrameAxes(last_frame, camera_matrix, None, avg_pose[:3, :3], avg_pose[:3, 3], 0.1) # type: ignore
116112
return last_frame, avg_pose
117113

118114

extensions/rcs_realsense/src/rcs_realsense/camera.py

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ def __init__(
4848
self.enable_imu = enable_imu
4949
self.cameras = cameras
5050
if calibration_strategy is None:
51-
calibration_strategy = {camera_name: DummyCalibrationStrategy() for camera_name in cameras.keys()}
51+
calibration_strategy = {camera_name: DummyCalibrationStrategy() for camera_name in cameras}
5252
self.calibration_strategy = calibration_strategy
5353
self._logger = logging.getLogger(__name__)
5454
assert (
@@ -123,16 +123,6 @@ def open(self):
123123
def update_available_devices(self):
124124
self._available_devices = self.enumerate_connected_devices(rs.context())
125125

126-
def enable_all_devices(self, enable_ir_emitter: bool = False):
127-
"""
128-
Enable all the Intel RealSense Devices which are connected to the PC
129-
130-
"""
131-
self._logger.debug("%i devices have been found", len(self._available_devices))
132-
133-
for device_info in self._available_devices.values():
134-
self.enable_device(device_info, enable_ir_emitter)
135-
136126
def enable_devices(self, devices_to_enable: dict[str, str], enable_ir_emitter: bool = False):
137127
"""
138128
Enable the Intel RealSense Devices which are connected to the PC
@@ -209,7 +199,7 @@ def enable_device(self, camera_name: str, device_info: RealSenseDeviceInfo, enab
209199
color_intrinsics=color_intrinsics,
210200
depth_intrinsics=depth_intrinsics,
211201
depth_to_color=common.Pose(
212-
translation=depth_to_color.translation, rotation=np.array(depth_to_color.rotation).reshape(3, 3)
202+
translation=depth_to_color.translation, rotation=np.array(depth_to_color.rotation).reshape(3, 3) # type: ignore
213203
),
214204
)
215205

@@ -266,6 +256,7 @@ def to_ts(frame: rs.frame) -> float:
266256

267257
color_extrinsics = self.calibration_strategy[camera_name].get_extrinsics()
268258
depth_to_color = device.depth_to_color
259+
assert depth_to_color is not None, "Depth to color extrinsics not found"
269260
depth_extrinsics = (
270261
color_extrinsics @ depth_to_color.inverse().pose_matrix() if color_extrinsics is not None else None
271262
)
@@ -285,6 +276,7 @@ def to_ts(frame: rs.frame) -> float:
285276
)
286277
elif rs.stream.depth == stream.stream_type():
287278
frame = frameset.get_depth_frame()
279+
assert device.depth_scale is not None, "Depth scale not found"
288280
depth = DataFrame(
289281
data=(to_numpy(frame).astype(np.float64) * device.depth_scale * BaseCameraSet.DEPTH_SCALE).astype(
290282
np.uint16
@@ -345,8 +337,10 @@ def enable_emitter(self, enable_ir_emitter=True):
345337

346338
def calibrate(self) -> bool:
347339
for camera_name in self.cameras:
340+
color_intrinsics = self._enabled_devices[camera_name].color_intrinsics
341+
assert color_intrinsics is not None, f"Color intrinsics for camera {camera_name} not found"
348342
if not self.calibration_strategy[camera_name].calibrate(
349-
intrinsics=self._enabled_devices[camera_name].color_intrinsics,
343+
intrinsics=color_intrinsics,
350344
samples=self._frame_buffer[camera_name],
351345
lock=self._frame_buffer_lock[camera_name],
352346
):

extensions/rcs_realsense/src/rcs_realsense/utils.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
import typing
2+
3+
from rcs.camera.hw import CalibrationStrategy
14
from rcs_realsense.calibration import FR3BaseArucoCalibration
25
from rcs_realsense.camera import RealSenseCameraSet
36

@@ -11,5 +14,5 @@ def default_realsense(name2id: dict[str, str] | None) -> RealSenseCameraSet | No
1114
name: common.BaseCameraConfig(identifier=id, resolution_width=1280, resolution_height=720, frame_rate=30)
1215
for name, id in name2id.items()
1316
}
14-
calibration_strategy = {name: FR3BaseArucoCalibration(name) for name in name2id}
17+
calibration_strategy = {name: typing.cast(CalibrationStrategy, FR3BaseArucoCalibration(name)) for name in name2id}
1518
return RealSenseCameraSet(cameras=cameras, calibration_strategy=calibration_strategy)

extensions/rcs_so101/src/rcs_so101/creators.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import logging
2+
import typing
23
from os import PathLike
34
from pathlib import Path
45
from typing import Type
@@ -15,6 +16,7 @@
1516
from lerobot.common.teleoperators.so101_leader.so101_leader import SO101Leader
1617
from lerobot.common.teleoperators.utils import make_teleoperator_from_config
1718
from rcs.camera.hw import HardwareCameraSet
19+
from rcs.camera.interface import BaseCameraSet
1820
from rcs.camera.sim import SimCameraSet
1921
from rcs.envs.base import (
2022
CameraSetWrapper,
@@ -125,7 +127,9 @@ def __call__( # type: ignore
125127
env = RobotSimWrapper(env, simulation, sim_wrapper)
126128

127129
if cameras is not None:
128-
camera_set = SimCameraSet(simulation, cameras, physical_units=True, render_on_demand=True)
130+
camera_set = typing.cast(
131+
BaseCameraSet, SimCameraSet(simulation, cameras, physical_units=True, render_on_demand=True)
132+
)
129133
env = CameraSetWrapper(env, camera_set, include_depth=True)
130134

131135
if gripper_cfg is not None and isinstance(gripper_cfg, SimGripperConfig):

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ ignore = [
101101
"PT018", # assertion should be broken down into multiple parts
102102
"NPY002",
103103
"G004", # Logging format string does not contain any placeholders
104+
"ARG002",
104105
]
105106

106107
[tool.pylint.format]

python/rcs/camera/digit_cam.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,3 +51,7 @@ def close(self):
5151

5252
def config(self, camera_name) -> BaseCameraConfig:
5353
return self.cameras[camera_name]
54+
55+
def calibrate(self) -> bool:
56+
"""No calibration needed for DIGIT cameras."""
57+
return True

python/rcs/camera/interface.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ class FrameSet:
5050
class BaseCameraSet(Protocol):
5151
"""Interface for a set of cameras for sim and hardware"""
5252

53-
DEPTH_SCALE = 1000
53+
DEPTH_SCALE: int = 1000
5454

5555
def buffer_size(self) -> int:
5656
"""Returns size of the internal buffer."""

python/rcs/camera/sim.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ def _cpp_to_python_frames(self, cpp_frameset: _FrameSet | None) -> FrameSet | No
9090
frames[color_name] = frame
9191
return FrameSet(frames=frames, avg_timestamp=cpp_frameset.timestamp)
9292

93-
def _intrinsics(self, camera_name) -> np.ndarray[tuple[Literal[3, 4]], np.dtype[np.float64]]:
93+
def _intrinsics(self, camera_name) -> np.ndarray[tuple[Literal[3], Literal[4]], np.dtype[np.float64]]:
9494
cam_id = mujoco.mj_name2id(self._sim.model, mujoco.mjtObj.mjOBJ_CAMERA, self.cameras[camera_name].identifier)
9595
fovy = self._sim.model.cam_fovy[cam_id]
9696
fx = fy = 0.5 * self.cameras[camera_name].resolution_height / np.tan(fovy * np.pi / 360)
@@ -102,14 +102,14 @@ def _intrinsics(self, camera_name) -> np.ndarray[tuple[Literal[3, 4]], np.dtype[
102102
]
103103
)
104104

105-
def _extrinsics(self, camera_name) -> np.ndarray[tuple[Literal[4, 4]], np.dtype[np.float64]]:
105+
def _extrinsics(self, camera_name) -> np.ndarray[tuple[Literal[4], Literal[4]], np.dtype[np.float64]]:
106106
cam_id = mujoco.mj_name2id(self._sim.model, mujoco.mjtObj.mjOBJ_CAMERA, self.cameras[camera_name].identifier)
107107
xpos = self._sim.data.cam_xpos[cam_id]
108108
xmat = self._sim.data.cam_xmat[cam_id].reshape(3, 3)
109109

110110
cam = common.Pose(rotation=xmat, translation=xpos)
111111
# put z axis infront
112-
rotation_p = common.Pose(rpy_vector=[np.pi, 0, 0], translation=[0, 0, 0])
112+
rotation_p = common.Pose(rpy_vector=np.array([np.pi, 0, 0]), translation=np.array([0, 0, 0]))
113113
cam = cam * rotation_p
114114

115115
return cam.inverse().pose_matrix()

python/rcs/envs/base.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import copy
44
import logging
55
from enum import Enum, auto
6-
from typing import Annotated, Any, TypeAlias, cast
6+
from typing import Annotated, Any, Literal, TypeAlias, cast
77

88
import gymnasium as gym
99
import numpy as np
@@ -131,7 +131,7 @@ class CameraDataDictType(RCSpaceType):
131131
"frame",
132132
]
133133
intrinsics: Annotated[
134-
np.ndarray,
134+
np.ndarray[tuple[Literal[3], Literal[4]], np.dtype[np.float64]] | None,
135135
gym.spaces.Box(
136136
low=-np.inf,
137137
high=np.inf,
@@ -140,7 +140,7 @@ class CameraDataDictType(RCSpaceType):
140140
),
141141
]
142142
extrinsics: Annotated[
143-
np.ndarray,
143+
np.ndarray[tuple[Literal[4], Literal[4]], np.dtype[np.float64]] | None,
144144
gym.spaces.Box(
145145
low=-np.inf,
146146
high=np.inf,
@@ -646,7 +646,7 @@ def check_depth(depth):
646646
raise ValueError(msg)
647647
return self.include_depth
648648

649-
frame_dict: dict[str, dict[str, np.ndarray]] = {
649+
frame_dict: dict[str, dict[str, CameraDataDictType]] = {
650650
camera_name: (
651651
{
652652
self.RGB_KEY: CameraDataDictType(

python/rcs/envs/creators.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
import logging
2+
import typing
23
from os import PathLike
34
from typing import Type
45

56
import gymnasium as gym
67
import numpy as np
78
from gymnasium.envs.registration import EnvCreator
89
from rcs._core.sim import CameraType
10+
from rcs.camera.interface import BaseCameraSet
911
from rcs.camera.sim import SimCameraConfig, SimCameraSet
1012
from rcs.envs.base import (
1113
CameraSetWrapper,
@@ -87,7 +89,9 @@ def __call__( # type: ignore
8789
env = RobotSimWrapper(env, simulation, sim_wrapper)
8890

8991
if cameras is not None:
90-
camera_set = SimCameraSet(simulation, cameras, physical_units=True, render_on_demand=True)
92+
camera_set = typing.cast(
93+
BaseCameraSet, SimCameraSet(simulation, cameras, physical_units=True, render_on_demand=True)
94+
)
9195
env = CameraSetWrapper(env, camera_set, include_depth=True)
9296

9397
if gripper_cfg is not None and isinstance(gripper_cfg, rcs.sim.SimGripperConfig):

0 commit comments

Comments
 (0)