Skip to content

Commit 35c0567

Browse files
committed
modify opencv renderer to support multiple camera view
1 parent 51cc017 commit 35c0567

1 file changed

Lines changed: 43 additions & 10 deletions

File tree

robosuite/utils/opencv_renderer.py

Lines changed: 43 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
"""
22
opencv renderer class.
33
"""
4-
import cv2
54
import numpy as np
5+
import cv2
6+
import platform
67

78

89
class OpenCVRenderer:
@@ -12,32 +13,64 @@ def __init__(self, sim):
1213
self.height = 800
1314

1415
self.sim = sim
15-
self.camera_name = self.sim.model.camera_id2name(0)
16-
16+
self.set_camera(camera_id=0)
17+
self._window_name = "offscreen render"
18+
self._has_window = False
1719
self.keypress_callback = None
1820

19-
def set_camera(self, camera_id):
21+
def set_camera(self, camera_id=None, camera_name=None):
2022
"""
2123
Set the camera view to the specified camera ID.
24+
2225
Args:
23-
camera_id (int): id of the camera to set the current viewer to
26+
camera_id (int or list): id(s) of the camera to set the current viewer to
27+
camera_name (str or list or None): name(s) of the camera to set the current viewer to
2428
"""
25-
self.camera_name = self.sim.model.camera_id2name(camera_id)
29+
30+
# enforce exactly one arg
31+
assert (camera_id is not None) or (camera_name is not None)
32+
assert (camera_id is None) or (camera_name is None)
33+
34+
if camera_id is not None:
35+
if isinstance(camera_id, int):
36+
camera_id = [camera_id]
37+
self.camera_names = [self.sim.model.camera_id2name(cam_id) for cam_id in camera_id]
38+
else:
39+
if isinstance(camera_name, str):
40+
camera_name = [camera_name]
41+
self.camera_names = list(camera_name)
2642

2743
def render(self):
2844
# get frame with offscreen renderer (assumes that the renderer already exists)
29-
im = self.sim.render(camera_name=self.camera_name, height=self.height, width=self.width)[..., ::-1]
45+
im = [
46+
self.sim.render(camera_name=cam_name, height=self.height, width=self.width)[..., ::-1]
47+
for cam_name in self.camera_names
48+
]
49+
im = np.concatenate(im, axis=1) # concatenate horizontally
3050

3151
# write frame to window
3252
im = np.flip(im, axis=0)
33-
cv2.imshow("offscreen render", im)
53+
cv2.imshow(self._window_name, im)
54+
if (platform.system() != "Darwin") and (not self._has_window):
55+
# move window to top left of screen, and ensure we only move window on creation
56+
cv2.moveWindow(self._window_name, 0, 0)
3457
key = cv2.waitKey(1)
35-
if self.keypress_callback:
58+
if self.keypress_callback is not None:
3659
self.keypress_callback(key)
60+
self._has_window = True
3761

3862
def add_keypress_callback(self, keypress_callback):
3963
self.keypress_callback = keypress_callback
4064

65+
def close_window(self):
66+
"""
67+
Helper method to close the active window.
68+
"""
69+
if self._has_window:
70+
cv2.destroyWindow(self._window_name)
71+
cv2.waitKey(1)
72+
self._has_window = False
73+
4174
def close(self):
4275
"""
4376
Any cleanup to close renderer.
@@ -47,4 +80,4 @@ def close(self):
4780
self.sim = None
4881

4982
# close window
50-
cv2.destroyAllWindows()
83+
self.close_window()

0 commit comments

Comments
 (0)