-
-
Notifications
You must be signed in to change notification settings - Fork 29
/
Copy pathmujoco_base.py
128 lines (103 loc) · 4.67 KB
/
mujoco_base.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
import mujoco as mj
from mujoco.glfw import glfw
class MuJoCoBase():
def __init__(self, xml_path):
# For callback functions
self.button_left = False
self.button_middle = False
self.button_right = False
self.lastx = 0
self.lasty = 0
# MuJoCo data structures
self.model = mj.MjModel.from_xml_path(xml_path) # MuJoCo model
self.data = mj.MjData(self.model) # MuJoCo data
self.cam = mj.MjvCamera() # Abstract camera
self.opt = mj.MjvOption() # visualization options
# Init GLFW, create window, make OpenGL context current, request v-sync
glfw.init()
self.window = glfw.create_window(1200, 900, "Demo", None, None)
glfw.make_context_current(self.window)
glfw.swap_interval(1)
# initialize visualization data structures
mj.mjv_defaultCamera(self.cam)
mj.mjv_defaultOption(self.opt)
self.scene = mj.MjvScene(self.model, maxgeom=10000)
self.context = mj.MjrContext(
self.model, mj.mjtFontScale.mjFONTSCALE_150.value)
# install GLFW mouse and keyboard callbacks
glfw.set_key_callback(self.window, self.keyboard)
glfw.set_cursor_pos_callback(self.window, self.mouse_move)
glfw.set_mouse_button_callback(self.window, self.mouse_button)
glfw.set_scroll_callback(self.window, self.scroll)
def keyboard(self, window, key, scancode, act, mods):
if act == glfw.PRESS and key == glfw.KEY_BACKSPACE:
mj.mj_resetData(self.model, self.data)
mj.mj_forward(self.model, self.data)
def mouse_button(self, window, button, act, mods):
# update button state
self.button_left = (glfw.get_mouse_button(
window, glfw.MOUSE_BUTTON_LEFT) == glfw.PRESS)
self.button_middle = (glfw.get_mouse_button(
window, glfw.MOUSE_BUTTON_MIDDLE) == glfw.PRESS)
self.button_right = (glfw.get_mouse_button(
window, glfw.MOUSE_BUTTON_RIGHT) == glfw.PRESS)
# update mouse position
glfw.get_cursor_pos(window)
def mouse_move(self, window, xpos, ypos):
# compute mouse displacement, save
dx = xpos - self.lastx
dy = ypos - self.lasty
self.lastx = xpos
self.lasty = ypos
# no buttons down: nothing to do
if (not self.button_left) and (not self.button_middle) and (not self.button_right):
return
# get current window size
width, height = glfw.get_window_size(window)
# get shift key state
PRESS_LEFT_SHIFT = glfw.get_key(
window, glfw.KEY_LEFT_SHIFT) == glfw.PRESS
PRESS_RIGHT_SHIFT = glfw.get_key(
window, glfw.KEY_RIGHT_SHIFT) == glfw.PRESS
mod_shift = (PRESS_LEFT_SHIFT or PRESS_RIGHT_SHIFT)
# determine action based on mouse button
if self.button_right:
if mod_shift:
action = mj.mjtMouse.mjMOUSE_MOVE_H
else:
action = mj.mjtMouse.mjMOUSE_MOVE_V
elif self.button_left:
if mod_shift:
action = mj.mjtMouse.mjMOUSE_ROTATE_H
else:
action = mj.mjtMouse.mjMOUSE_ROTATE_V
else:
action = mj.mjtMouse.mjMOUSE_ZOOM
mj.mjv_moveCamera(self.model, action, dx/height,
dy/height, self.scene, self.cam)
def scroll(self, window, xoffset, yoffset):
action = mj.mjtMouse.mjMOUSE_ZOOM
mj.mjv_moveCamera(self.model, action, 0.0, -0.05 *
yoffset, self.scene, self.cam)
def simulate(self):
while not glfw.window_should_close(self.window):
simstart = self.data.time
while (self.data.time - simstart < 1.0/60.0):
mj.mj_step(self.model, self.data)
# get framebuffer viewport
viewport_width, viewport_height = glfw.get_framebuffer_size(
self.window)
viewport = mj.MjrRect(0, 0, viewport_width, viewport_height)
# Update scene and render
mj.mjv_updateScene(self.model, self.data, self.opt, None, self.cam,
mj.mjtCatBit.mjCAT_ALL.value, self.scene)
mj.mjr_render(viewport, self.scene, self.context)
# swap OpenGL buffers (blocking call due to v-sync)
glfw.swap_buffers(self.window)
# process pending GUI events, call GLFW callbacks
glfw.poll_events()
glfw.terminate()
def reset(self, *args, **kwargs):
raise NotImplementedError
def controller(self, *args, **kwargs):
raise NotImplementedError