Skip to content

Commit 4c8f288

Browse files
Merge pull request #664 from squarefk/support-multi-cameras
Support multiple cameras
2 parents b80631c + 6cf6b0e commit 4c8f288

5 files changed

Lines changed: 19 additions & 10 deletions

File tree

docs/algorithms/demonstrations.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ We provide teleoperation utilities that allow users to control the robots with i
77
- `directory:` path to a folder for where to store the pickle file of collected demonstrations
88
- `environment:` name of the environment you would like to collect the demonstrations for
99
- `device:` either "keyboard" or "spacemouse" or "dualsense" or "mjgui"
10+
- `renderer:` Mujoco's builtin interactive viewer (mjviewer) or OpenCV viewer (mujoco)
11+
- `camera:` Pass multiple camera names to enable multiple views. Note that the "mujoco" renderer must be enabled when using multiple views, while "mjviewer" is not supported.
1012

1113
See the [devices page](https://robosuite.ai/docs/modules/devices.html) for details on how to use the devices.
1214

robosuite/environments/base.py

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,9 @@ class MujocoEnv(metaclass=EnvMeta):
6363
has_renderer (bool): If true, render the simulation state in
6464
a viewer instead of headless mode.
6565
has_offscreen_renderer (bool): True if using off-screen rendering.
66-
render_camera (str): Name of camera to render if `has_renderer` is True. Setting this value to 'None'
66+
render_camera (str or list of str): Name of camera to render if `has_renderer` is True. Setting this value to 'None'
6767
will result in the default angle being applied, which is useful as it can be dragged / panned by
68-
the user using the mouse
68+
the user using the mouse. When a list of strings is provided, it will render from multiple camera angles.
6969
render_collision_mesh (bool): True if rendering collision meshes
7070
in camera. False otherwise.
7171
render_visual_mesh (bool): True if rendering visual meshes
@@ -110,6 +110,8 @@ def __init__(
110110
self.has_renderer = has_renderer
111111
# offscreen renderer needed for on-screen rendering
112112
self.has_offscreen_renderer = (has_renderer and renderer != "mjviewer") or has_offscreen_renderer
113+
if render_camera is not None and isinstance(render_camera, str):
114+
render_camera = [render_camera]
113115
self.render_camera = render_camera
114116
self.render_collision_mesh = render_collision_mesh
115117
self.render_visual_mesh = render_visual_mesh
@@ -179,7 +181,8 @@ def initialize_renderer(self):
179181
from robosuite.renderers.viewer import MjviewerRenderer
180182

181183
if self.render_camera is not None:
182-
camera_id = self.sim.model.camera_name2id(self.render_camera)
184+
assert len(self.render_camera) == 1, "Only one camera can be specified for mjviewer"
185+
camera_id = self.sim.model.camera_name2id(self.render_camera[0])
183186
else:
184187
camera_id = None
185188
self.viewer = MjviewerRenderer(env=self, camera_id=camera_id, **self.renderer_config)
@@ -323,8 +326,11 @@ def _reset_internal(self):
323326

324327
# Set the camera angle for viewing
325328
if self.render_camera is not None:
326-
camera_id = self.sim.model.camera_name2id(self.render_camera)
327-
self.viewer.set_camera(camera_id)
329+
camera_ids = []
330+
for cam in self.render_camera:
331+
camera_id = self.sim.model.camera_name2id(cam)
332+
camera_ids.append(camera_id)
333+
self.viewer.set_camera(camera_ids)
328334

329335
elif self.renderer == "mjviewer":
330336
self.initialize_renderer()

robosuite/environments/manipulation/manipulation_env.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,9 @@ class ManipulationEnv(RobotEnv):
5959
6060
has_offscreen_renderer (bool): True if using off-screen rendering
6161
62-
render_camera (str): Name of camera to render if `has_renderer` is True. Setting this value to 'None'
62+
render_camera (str or list of str): Name of camera to render if `has_renderer` is True. Setting this value to 'None'
6363
will result in the default angle being applied, which is useful as it can be dragged / panned by
64-
the user using the mouse
64+
the user using the mouse. When a list of strings is provided, it will render from multiple camera angles.
6565
6666
render_collision_mesh (bool): True if rendering collision meshes in camera. False otherwise.
6767

robosuite/environments/robot_env.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,9 @@ class RobotEnv(MujocoEnv):
5353
5454
has_offscreen_renderer (bool): True if using off-screen rendering
5555
56-
render_camera (str): Name of camera to render if `has_renderer` is True. Setting this value to 'None'
56+
render_camera (str or list of str): Name of camera to render if `has_renderer` is True. Setting this value to 'None'
5757
will result in the default angle being applied, which is useful as it can be dragged / panned by
58-
the user using the mouse
58+
the user using the mouse. When a list of strings is provided, it will render from multiple camera angles.
5959
6060
render_collision_mesh (bool): True if rendering collision meshes in camera. False otherwise.
6161

robosuite/scripts/collect_human_demonstrations.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,9 +237,10 @@ def gather_demonstrations_as_hdf5(directory, out_dir, env_info):
237237
)
238238
parser.add_argument(
239239
"--camera",
240+
nargs="*",
240241
type=str,
241242
default="agentview",
242-
help="Which camera to use for collecting demos",
243+
help="List of camera names to use for collecting demos. Pass multiple names to enable multiple views. Note: the `mujoco` renderer must be enabled when using multiple views; `mjviewer` is not supported.",
243244
)
244245
parser.add_argument(
245246
"--controller",

0 commit comments

Comments
 (0)