Skip to content

Commit 7199f94

Browse files
authored
Suport camera group ids for batch rendering on RT backend (#108)
1 parent dbf8553 commit 7199f94

File tree

6 files changed

+58
-11
lines changed

6 files changed

+58
-11
lines changed

embodichain/lab/gym/envs/base_env.py

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
from embodichain.lab.sim.types import EnvObs, EnvAction
2525
from embodichain.lab.sim import SimulationManagerCfg, SimulationManager
2626
from embodichain.lab.sim.objects import Robot
27-
from embodichain.lab.sim.sensors import BaseSensor
27+
from embodichain.lab.sim.sensors import BaseSensor, Camera
2828
from embodichain.lab.gym.utils import gym_utils
2929
from embodichain.utils import configclass
3030
from embodichain.utils import logger, set_seed
@@ -225,6 +225,17 @@ def get_sensor(self, name: str, **kwargs) -> BaseSensor:
225225

226226
return self.sensors[name]
227227

228+
def add_camera_group_id(self, group_id: int) -> None:
229+
"""Add a camera group ID for rendering.
230+
231+
Args:
232+
group_id: The camera group ID to be added.
233+
"""
234+
if not hasattr(self, "_camera_group_ids"):
235+
self._camera_group_ids: List[int] = []
236+
if self.sim.is_rt_enabled:
237+
self._camera_group_ids.append(group_id)
238+
228239
def _setup_scene(self, **kwargs):
229240
# Init sim manager.
230241
# we want to open gui window when the scene is setup, so init sim manager in headless mode first.
@@ -251,6 +262,13 @@ def _setup_scene(self, **kwargs):
251262

252263
self.sensors = self._setup_sensors(**kwargs)
253264

265+
# Setup camera groups for rendering.
266+
self._camera_group_ids: List[int] = []
267+
if self.sim.is_rt_enabled:
268+
for sensor in self.sensors.values():
269+
if isinstance(sensor, Camera):
270+
self._camera_group_ids.append(sensor.group_id)
271+
254272
def _setup_robot(self, **kwargs) -> Robot:
255273
"""Load the robot agent, setup the controller and action space.
256274
@@ -343,7 +361,7 @@ def _get_sensor_obs(self, **kwargs) -> Dict[str, any]:
343361
fetch_only = False
344362
if self.sim.is_rt_enabled:
345363
fetch_only = True
346-
self.sim.render_camera_group()
364+
self.sim.render_camera_group(self._camera_group_ids)
347365

348366
for sensor_name, sensor in self.sensors.items():
349367
sensor.update(fetch_only=fetch_only)

embodichain/lab/gym/envs/managers/record.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424

2525
from dexsim.utility import images_to_video
2626
from embodichain.lab.gym.envs.managers import Functor, FunctorCfg
27-
from embodichain.lab.sim.sensors.camera import CameraCfg
27+
from embodichain.lab.sim.sensors.camera import CameraCfg, Camera
2828

2929
if TYPE_CHECKING:
3030
from embodichain.lab.gym.envs import EmbodiedEnv
@@ -69,7 +69,7 @@ def __init__(self, cfg: FunctorCfg, env: EmbodiedEnv):
6969
"intrinsics", (600, 600, int(resolution[0] / 2), int(resolution[1] / 2))
7070
)
7171

72-
self.camera = env.sim.add_sensor(
72+
self.camera: Camera = env.sim.add_sensor(
7373
sensor_cfg=CameraCfg(
7474
uid=self._name,
7575
width=resolution[0],
@@ -79,6 +79,10 @@ def __init__(self, cfg: FunctorCfg, env: EmbodiedEnv):
7979
)
8080
)
8181

82+
# Add this camera's group ID to the environment for batch rendering when RT is enabled.
83+
if getattr(env.sim, "is_rt_enabled", False):
84+
env.add_camera_group_id(self.camera.group_id)
85+
8286
self._current_episode = 0
8387
self._frames: List[np.ndarray] = []
8488

embodichain/lab/sim/sensors/camera.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,21 @@ def is_rt_enabled(self) -> bool:
248248
"""
249249
return is_rt_enabled()
250250

251+
@cached_property
252+
def group_id(self) -> int:
253+
"""Get the camera group ID in the dexsim world.
254+
255+
Returns:
256+
int: The camera group ID.
257+
"""
258+
if self.is_rt_enabled:
259+
return self._frame_buffer.get_group_id()
260+
else:
261+
logger.log_warning(
262+
"Camera group ID is only available for Ray Tracing renderer. Returning -1 for non-RT renderer."
263+
)
264+
return -1
265+
251266
def update(self, **kwargs) -> None:
252267
"""Update the sensor data.
253268

embodichain/lab/sim/sim_manager.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -485,14 +485,17 @@ def init_gpu_physics(self) -> None:
485485

486486
self._is_initialized_gpu_physics = True
487487

488-
def render_camera_group(self) -> None:
488+
def render_camera_group(self, group_ids: list[int]) -> None:
489489
"""Render all camera group in the simulation.
490490
491+
Args:
492+
group_ids (list[int]): The list of camera group ids to render.
493+
491494
Note: This interface is only valid when Ray Tracing rendering backend is enabled.
492495
"""
493496

494497
if self.is_rt_enabled:
495-
self._world.render_camera_group()
498+
self._world.render_camera_group(group_ids)
496499
else:
497500
logger.log_warning(
498501
"This interface is only valid when Ray Tracing rendering backend is enabled."

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ dynamic = ["version"]
2626
# Core install dependencies (kept from requirements.txt). Some VCS links are
2727
# specified using PEP 508 direct references where present.
2828
dependencies = [
29-
"dexsim_engine==0.3.9",
29+
"dexsim_engine==0.3.10",
3030
"setuptools>=78.1.1",
3131
"gymnasium>=0.29.1",
3232
"langchain",

tests/gym/envs/test_embodied_env.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -119,12 +119,14 @@
119119
class EmbodiedEnvTest:
120120
"""Shared test logic for CPU and CUDA."""
121121

122-
def setup_simulation(self, sim_device):
122+
def setup_simulation(self, sim_device, enable_rt):
123123
cfg: EmbodiedEnvCfg = config_to_cfg(
124124
METADATA, manager_modules=DEFAULT_MANAGER_MODULES
125125
)
126126
cfg.num_envs = NUM_ENVS
127-
cfg.sim_cfg = SimulationManagerCfg(headless=True, sim_device=sim_device)
127+
cfg.sim_cfg = SimulationManagerCfg(
128+
headless=True, sim_device=sim_device, enable_rt=enable_rt
129+
)
128130

129131
self.env = gym.make(id=METADATA["id"], cfg=cfg)
130132

@@ -162,10 +164,15 @@ def teardown_method(self):
162164

163165
class TestCPU(EmbodiedEnvTest):
164166
def setup_method(self):
165-
self.setup_simulation("cpu")
167+
self.setup_simulation("cpu", enable_rt=False)
168+
169+
170+
class TestCPURT(EmbodiedEnvTest):
171+
def setup_method(self):
172+
self.setup_simulation("cpu", enable_rt=True)
166173

167174

168175
@pytest.mark.skip(reason="Skipping CUDA tests temporarily")
169176
class TestCUDA(EmbodiedEnvTest):
170177
def setup_method(self):
171-
self.setup_simulation("cuda")
178+
self.setup_simulation("cuda", enable_rt=False)

0 commit comments

Comments
 (0)