Skip to content

Commit 37ff575

Browse files
angli66Jiayuan-Gu
andauthored
Support set_local_pose in StereoDepthSensor (#112)
* Support local pose for StereoDepthSensor * support set_local_pose in StereoDepthSensor * minor fix --------- Co-authored-by: Jiayuan-Gu <jigu@eng.ucsd.edu>
1 parent 96b7906 commit 37ff575

File tree

5 files changed

+53
-34
lines changed

5 files changed

+53
-34
lines changed

docs/source/tutorial/rendering/depth_sensor.rst

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -67,18 +67,18 @@ Optionally, you can mount the sensor to an existing actor:
6767
::
6868

6969
sensor_config = StereoDepthSensorConfig()
70-
sensor = StereoDepthSensor('sensor', scene, sensor_config, mount=actor)
70+
sensor = StereoDepthSensor('sensor', scene, sensor_config, mount=actor, pose=Pose()) # pose is relative to mount
7171

72-
After mounting to an actor, the sensor will move along with it. Calling ``set_pose`` from either the sensor or the actor will move the two entities together.
72+
After mounting to an actor, the sensor will move along with it. Calling ``sensor.set_local_pose`` can adjust the relative pose to the mounted actor.
7373

74-
``sensor`` behaves very similar to a camera. You can ``set_pose`` and ``take_picture`` just like working with a camera. What's more, you can ``compute_depth`` and
75-
``get_pointcloud`` on the sensor:
74+
``sensor`` behaves very similar to a camera. You can ``set_pose`` (or ``set_local_pose`` when mounted) and ``take_picture`` just like working with a camera.
75+
In addtion to these basic functions, you can ``compute_depth`` and ``get_pointcloud`` on the sensor:
7676

7777
.. literalinclude:: ../../../../examples/rendering/rt_stereodepth.py
7878
:dedent: 0
7979
:lines: 90-95
8080

81-
One important differences between camera and ``sensor`` is that while camera will only take picture of an RGB image, ``sensor`` will take another pair
81+
One important difference between camera and ``sensor`` is that while camera will only take picture of an RGB image, ``sensor`` will take another pair
8282
of infrared images, which will be used to compute depth. After calling ``take_picture``, the RGB image and infrared images will be saved within ``sensor``.
8383
Calling ``sensor.get_rgb`` and ``sensor.get_ir`` will return the pictures in ndarray form. Let's take a look at them:
8484

@@ -144,13 +144,14 @@ If depth is the only needed data and RGB data is not needed, you can specify ``i
144144
This can save the time for rendering RGB image.
145145

146146

147-
As mentioned above, the final depth map generated by ``StereoDepthSensor`` will be transformed into RGB camera frame. It will be of the same resolution and frame as of the RGB
148-
camera. This feature can be used to achieve fast downsampling/upsampling. All you need is to specify the ``rgb_resolution`` of the ``StereoDepthSensorConfig`` as the final
147+
As mentioned above, the final depth map generated by ``StereoDepthSensor`` will be transformed into RGB camera frame. It will be of the same resolution and frame as of the
148+
RGB camera. This feature can be used to achieve fast downsampling/upsampling. All you need is to specify the ``rgb_resolution`` of the ``StereoDepthSensorConfig`` as the final
149149
resolution you want to sample on, and ``StereoDepthSensor`` will do that for you on the GPU. In this way, you don't need to attach any slow CPU resampling function to it.
150150

151-
In general, lowering ``rt_samples_per_pixel`` for renderer, ``ir_resolution`` of sensor config and ``max_disp`` of sensor config are all good ways to enhance computation
152-
speed. However, note that these changes might also have effect on the output depth map. You can freely adjust the parameters until you find the settings that satisfies
153-
your need.
151+
In general, lowering ``rt_samples_per_pixel`` for renderer, ``ir_resolution`` of sensor config and ``max_disp`` of sensor config are all good ways to enhance computation
152+
speed. For example, try changing the ``rt_samples_per_pixel`` in our script from ``32`` to ``8``. You might find that we can get almost as good results as before while
153+
``sensor.take_picture`` now runs much faster. However, note that these changes generally will have some effect (trade quality with speed) on the output depth map. You can freely
154+
adjust the parameters until you find the settings that satisfies your need.
154155

155156

156157
Seamless transfer to other GPU libraries

examples/rendering/rt_stereodepth.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ def main():
8787

8888
sensor_config = StereoDepthSensorConfig()
8989
sensor = StereoDepthSensor('sensor', scene, sensor_config)
90-
sensor.set_pose(Pose([-0.13732728, 0.13584249, 0.82386769],[0.84667092, -0.01287458, 0.53195302, -0.00292851]))
90+
sensor.set_pose(Pose([-0.13732728, 0.13584249, 0.82386769], [0.84667092, -0.01287458, 0.53195302, -0.00292851]))
9191

9292
scene.step()
9393
scene.update_render()

manualtest/rt_stereodepth.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ def main():
8787

8888
sensor_config = StereoDepthSensorConfig()
8989
sensor = StereoDepthSensor('sensor', scene, sensor_config)
90-
sensor.set_pose(Pose([-0.13732728, 0.13584249, 0.82386769],[0.84667092, -0.01287458, 0.53195302, -0.00292851]))
90+
sensor.set_pose(Pose([-0.13732728, 0.13584249, 0.82386769], [0.84667092, -0.01287458, 0.53195302, -0.00292851]))
9191

9292
scene.step()
9393
scene.update_render()

manualtest/rt_stereodepth2.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,7 @@ def main():
102102
])
103103
sensor_config.max_disp = 96 # Max disparity for stereo matching
104104
sensor = StereoDepthSensor('sensor', scene, sensor_config)
105-
sensor.set_pose(
106-
Pose([-0.28, -0.28, 0.46], [0.8876263, -0.135299, 0.3266407, 0.2951603]))
105+
sensor.set_pose(Pose([-0.28, -0.28, 0.46], [0.8876263, -0.135299, 0.3266407, 0.2951603]))
107106

108107
# Warm up
109108
scene.step()

python/py_package/sensor/stereodepth.py

Lines changed: 39 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,15 @@ class StereoDepthSensor(SensorEntity):
121121
parameters. The computed depth map will be presented in RGB camera frame.
122122
"""
123123

124-
def __init__(self, sensor_name: str, scene: Scene, config: StereoDepthSensorConfig, mount: Optional[Actor] = None):
124+
def __init__(self, sensor_name: str, scene: Scene, config: StereoDepthSensorConfig, mount: Optional[Actor] = None, pose: Optional[Pose] = None):
125+
"""
126+
:param sensor_name: name of the sensor.
127+
:param scene: scene that the sensor is attached to.
128+
:param config: configuration of the sensor.
129+
:param mount: optionally mount the sensor to an actor. If mounted, the sensor will move along with the actor.
130+
:param pose: If not mounted, this will be the global pose for the sensor. Otherwise, it will be the local pose relative to the mounted actor.
131+
"""
132+
125133
super().__init__()
126134

127135
# Basic configuration
@@ -169,15 +177,19 @@ def __init__(self, sensor_name: str, scene: Scene, config: StereoDepthSensorConf
169177
self._config.median_filter_size != 7:
170178
raise TypeError("Median filter size choices are 1, 3, 5, 7")
171179

172-
# Pose
180+
# self._pose is global if not mounted and local if mounted
173181
self._mount = mount
174-
self._alight = self._scene.add_active_light(
175-
pose=Pose(), color=[0, 0, 0], fov=1.57, tex_path=self._config.light_pattern)
176-
if self._mount is None:
182+
if pose is None:
177183
self._pose = Pose()
178184
else:
185+
self._pose = pose
186+
187+
# Active Light
188+
self._alight = self._scene.add_active_light(
189+
pose=Pose(), color=[0, 0, 0], fov=1.57, tex_path=self._config.light_pattern)
190+
if self._mount is not None:
179191
self._alight.set_parent(self._mount, keep_pose=False)
180-
self._alight.set_local_pose(Pose())
192+
self._alight.set_local_pose(self._pose)
181193

182194
# Cameras
183195
self._cam_rgb = None
@@ -201,10 +213,7 @@ def __init__(self, sensor_name: str, scene: Scene, config: StereoDepthSensorConf
201213
ir_size, rgb_size = self._config.ir_resolution, self._config.rgb_resolution
202214
ir_intrinsic = self._config.ir_intrinsic.astype(float)
203215
rgb_intrinsic = self._config.rgb_intrinsic.astype(float)
204-
if self._mount is None:
205-
rgb_pose = self._pose
206-
else:
207-
rgb_pose = self._mount.get_pose()
216+
rgb_pose = self._cam_rgb.get_pose()
208217
rgb_extrinsic = self._pose2cv2ex(rgb_pose)
209218
l_extrinsic = self._pose2cv2ex(rgb_pose * self._config.trans_pose_l)
210219
r_extrinsic = self._pose2cv2ex(rgb_pose * self._config.trans_pose_r)
@@ -258,16 +267,26 @@ def compute_depth(self):
258267

259268
def set_pose(self, pose: Pose):
260269
"""
261-
Note: If mount exists, setting sensor's pose will also have effect on the mounted actor.
270+
Set the global pose of the sensor. Call set_local_pose instead of set_pose if mount exists.
262271
"""
263272
if self._mount is None:
264273
self._pose = pose
265-
self._alight.set_pose(self._pose)
266-
self._cam_rgb.set_local_pose(self._pose)
267-
self._cam_ir_l.set_local_pose(self._pose * self._config.trans_pose_l)
268-
self._cam_ir_r.set_local_pose(self._pose * self._config.trans_pose_r)
274+
self._alight.set_pose(pose)
275+
self._cam_rgb.set_local_pose(pose)
276+
self._cam_ir_l.set_local_pose(pose * self._config.trans_pose_l)
277+
self._cam_ir_r.set_local_pose(pose * self._config.trans_pose_r)
269278
else:
270-
self._mount.set_pose(pose)
279+
raise RuntimeError("cannot set_pose when sensor is mounted, use set_local_pose instead")
280+
281+
def set_local_pose(self, pose: Pose):
282+
"""
283+
If mount exists, set local pose of the sensor relative to mounted actor. Otherwise, set global pose of the sensor.
284+
"""
285+
self._pose = pose
286+
self._alight.set_local_pose(pose)
287+
self._cam_rgb.set_local_pose(pose)
288+
self._cam_ir_l.set_local_pose(pose * self._config.trans_pose_l)
289+
self._cam_ir_r.set_local_pose(pose * self._config.trans_pose_r)
271290

272291
def set_ir_noise(self, ir_speckle_noise: float, ir_thermal_noise: float):
273292
"""
@@ -350,7 +369,7 @@ def get_pose(self):
350369
if self._mount is None:
351370
return copy(self._pose)
352371
else:
353-
return copy(self._mount().get_pose())
372+
return copy(self._mount.get_pose() * self._pose)
354373

355374
def get_rgb(self):
356375
rgb = self._cam_rgb.get_color_rgba()[..., :3].clip(0, 1)
@@ -421,13 +440,13 @@ def _create_cameras(self):
421440
self._cam_ir_r.set_local_pose(self._pose * self._config.trans_pose_r)
422441
else:
423442
self._cam_rgb = self._scene.add_mounted_camera(
424-
f"{self.name}", self._mount, Pose(), *self._config.rgb_resolution, 0.78, 0.001, 100)
443+
f"{self.name}", self._mount, self._pose, *self._config.rgb_resolution, 0.78, 0.001, 100)
425444

426445
self._cam_ir_l = self._scene.add_mounted_camera(
427-
f"{self.name}_left", self._mount, self._config.trans_pose_l, *self._config.ir_resolution, 0.78, 0.001, 100)
446+
f"{self.name}_left", self._mount, self._pose * self._config.trans_pose_l, *self._config.ir_resolution, 0.78, 0.001, 100)
428447

429448
self._cam_ir_r = self._scene.add_mounted_camera(
430-
f"{self.name}_right", self._mount, self._config.trans_pose_r, *self._config.ir_resolution, 0.78, 0.001, 100)
449+
f"{self.name}_right", self._mount, self._pose * self._config.trans_pose_r, *self._config.ir_resolution, 0.78, 0.001, 100)
431450

432451
self._cam_rgb.set_perspective_parameters(
433452
0.1, 100.0,

0 commit comments

Comments
 (0)