-
Notifications
You must be signed in to change notification settings - Fork 0
/
utils.py
96 lines (80 loc) · 3.61 KB
/
utils.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
import numpy as np
from gym import error
try:
import mujoco_py
except ImportError as e:
raise error.DependencyNotInstalled("{}. (HINT: you need to install mujoco_py, and also perform the setup instructions here: https://github.com/openai/mujoco-py/.)".format(e))
def robot_get_obs(sim):
"""Returns all joint positions and velocities associated with
a robot.
"""
if sim.data.qpos is not None and sim.model.joint_names:
names = [n for n in sim.model.joint_names if n.startswith('spacecraft')]
return (
np.array([sim.data.get_joint_qpos(name) for name in names]),
np.array([sim.data.get_joint_qvel(name) for name in names]),
)
return np.zeros(0), np.zeros(0)
def ctrl_set_action(sim, action):
"""For torque actuators it copies the action into mujoco ctrl field.
For position actuators it sets the target relative to the current qpos.
"""
if sim.model.nmocap > 0:
_, action = np.split(action, (sim.model.nmocap * 7, ))
if sim.data.ctrl is not None:
for i in range(action.shape[0]):
if sim.model.actuator_biastype[i] == 0:
sim.data.ctrl[i] = action[i]
else:
idx = sim.model.jnt_qposadr[sim.model.actuator_trnid[i, 0]]
sim.data.ctrl[i] = sim.data.qpos[idx] + action[i]
def mocap_set_action(sim, action):
"""The action controls the robot using mocaps. Specifically, bodies
on the robot (for example the gripper wrist) is controlled with
mocap bodies. In this case the action is the desired difference
in position and orientation (quaternion), in world coordinates,
of the of the target body. The mocap is positioned relative to
the target body according to the delta, and the MuJoCo equality
constraint optimizer tries to center the welded body on the mocap.
"""
if sim.model.nmocap > 0:
action, _ = np.split(action, (sim.model.nmocap * 7, ))
action = action.reshape(sim.model.nmocap, 7)
pos_delta = action[:, :3]
quat_delta = action[:, 3:]
reset_mocap2body_xpos(sim)
sim.data.mocap_pos[:] = sim.data.mocap_pos + pos_delta
sim.data.mocap_quat[:] = sim.data.mocap_quat + quat_delta
def reset_mocap_welds(sim):
"""Resets the mocap welds that we use for actuation.
"""
if sim.model.nmocap > 0 and sim.model.eq_data is not None:
for i in range(sim.model.eq_data.shape[0]):
if sim.model.eq_type[i] == mujoco_py.const.EQ_WELD:
sim.model.eq_data[i, :] = np.array(
[0., 0., 0., 1., 0., 0., 0.])
sim.forward()
def reset_mocap2body_xpos(sim):
"""Resets the position and orientation of the mocap bodies to the same
values as the bodies they're welded to.
"""
if (sim.model.eq_type is None or
sim.model.eq_obj1id is None or
sim.model.eq_obj2id is None):
return
for eq_type, obj1_id, obj2_id in zip(sim.model.eq_type,
sim.model.eq_obj1id,
sim.model.eq_obj2id):
if eq_type != mujoco_py.const.EQ_WELD:
continue
mocap_id = sim.model.body_mocapid[obj1_id]
if mocap_id != -1:
# obj1 is the mocap, obj2 is the welded body
body_idx = obj2_id
else:
# obj2 is the mocap, obj1 is the welded body
mocap_id = sim.model.body_mocapid[obj2_id]
body_idx = obj1_id
assert (mocap_id != -1)
sim.data.mocap_pos[mocap_id][:] = sim.data.body_xpos[body_idx]
sim.data.mocap_quat[mocap_id][:] = sim.data.body_xquat[body_idx]