Skip to content

Commit ed46743

Browse files
allow mounted cameras to be run in parallel simulations
1 parent fd06778 commit ed46743

File tree

1 file changed

+24
-7
lines changed

1 file changed

+24
-7
lines changed

genesis/vis/camera.py

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ def __init__(
9191
self._is_built = False
9292
self._attached_link = None
9393
self._attached_offset_T = None
94+
self._attached_env_idx = None
9495

9596
self._in_recording = False
9697
self._recorded_imgs = []
@@ -124,7 +125,7 @@ def _build(self):
124125
self._is_built = True
125126
self.set_pose(self._transform, self._pos, self._lookat, self._up)
126127

127-
def attach(self, rigid_link, offset_T):
128+
def attach(self, rigid_link, offset_T, env_idx: int | None = None):
128129
"""
129130
Attach the camera to a rigid link in the scene.
130131
@@ -136,9 +137,25 @@ def attach(self, rigid_link, offset_T):
136137
The rigid link to which the camera should be attached.
137138
offset_T : np.ndarray, shape (4, 4)
138139
The transformation matrix specifying the camera's pose relative to the rigid link.
140+
env_idx : int
141+
The environment index this camera should be tied to. Offsets the `offset_T` accordingly. Must be specified if running parallel environments
142+
143+
Raises
144+
------
145+
Exception
146+
If running parallel simulations but env_idx is not specified.
147+
Exception
148+
If invalid env_idx is specified (env_idx >= n_envs)
139149
"""
140150
self._attached_link = rigid_link
141151
self._attached_offset_T = offset_T
152+
if self._visualizer._scene.n_envs > 0 and env_idx is None:
153+
gs.raise_exception("Must specify env_idx when running parallel simulations")
154+
if env_idx is not None:
155+
n_envs = self._visualizer._scene.n_envs
156+
if env_idx >= n_envs:
157+
gs.raise_exception(f"Invalid env_idx {env_idx} for camera, configured for {n_envs} environments")
158+
self._attached_env_idx = env_idx
142159

143160
def detach(self):
144161
"""
@@ -148,6 +165,7 @@ def detach(self):
148165
"""
149166
self._attached_link = None
150167
self._attached_offset_T = None
168+
self._attached_env_idx = None
151169

152170
@gs.assert_built
153171
def move_to_attach(self):
@@ -160,16 +178,15 @@ def move_to_attach(self):
160178
------
161179
Exception
162180
If the camera has not been mounted using `attach()`.
163-
Exception
164-
If the simulation is running in parallel (`n_envs > 0`), which is currently unsupported for mounted cameras.
165181
"""
166182
if self._attached_link is None:
167183
gs.raise_exception(f"The camera hasn't been mounted!")
168-
if self._visualizer._scene.n_envs > 0:
169-
gs.raise_exception(f"Mounted camera not supported in parallel simulation!")
170184

171-
link_pos = self._attached_link.get_pos().cpu().numpy()
172-
link_quat = self._attached_link.get_quat().cpu().numpy()
185+
link_pos = self._attached_link.get_pos(envs_idx=self._attached_env_idx).cpu().numpy()
186+
link_quat = self._attached_link.get_quat(envs_idx=self._attached_env_idx).cpu().numpy()
187+
if self._attached_env_idx is not None:
188+
link_pos = link_pos[0] + self._visualizer._scene.envs_offset[self._attached_env_idx]
189+
link_quat = link_quat[0]
173190
link_T = gu.trans_quat_to_T(link_pos, link_quat)
174191
transform = link_T @ self._attached_offset_T
175192
self.set_pose(transform=transform)

0 commit comments

Comments
 (0)