tinysim 0.0.4__py3-none-any.whl → 0.0.5__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. tinysim/__init__.py +7 -2
  2. tinysim/_tk_base.py +20 -2
  3. tinysim/_widget_base.py +41 -0
  4. tinysim/flappy/__init__.py +5 -3
  5. tinysim/flappy/tk.py +10 -34
  6. tinysim/flappy/widget.py +9 -38
  7. tinysim/frogger/__init__.py +21 -4
  8. tinysim/frogger/tk.py +12 -28
  9. tinysim/frogger/widget.py +8 -37
  10. tinysim/mountain_car/__init__.py +17 -12
  11. tinysim/mountain_car/tk.py +9 -27
  12. tinysim/mountain_car/widget.py +8 -37
  13. tinysim/tinyspace.py +68 -0
  14. tinysim/topdown_driving/__init__.py +16 -18
  15. tinysim/topdown_driving/tk.py +13 -38
  16. tinysim/topdown_driving/track_0.json +1 -753
  17. tinysim/topdown_driving/widget.py +8 -42
  18. {tinysim-0.0.4.dist-info → tinysim-0.0.5.dist-info}/METADATA +5 -6
  19. {tinysim-0.0.4.dist-info → tinysim-0.0.5.dist-info}/RECORD +35 -35
  20. {tinysim-0.0.4.dist-info → tinysim-0.0.5.dist-info}/WHEEL +1 -1
  21. tinysim_mujoco/gl_viewer.py +36 -11
  22. tinysim_mujoco/manipulation/__init__.py +19 -5
  23. tinysim_mujoco/manipulation/push_env.py +268 -0
  24. tinysim_mujoco/manipulation/push_env_cam.py +274 -0
  25. tinysim_mujoco/manipulation/xmls/panda.xml +59 -16
  26. tinysim_mujoco/manipulation/xmls/scene.xml +0 -3
  27. tinysim_mujoco/manipulation/xmls/table.xml +17 -13
  28. tinysim_mujoco/notebook_viewer.py +3 -6
  29. tinysim_mujoco/unitree_a1/__init__.py +7 -10
  30. tinysim_warp/__init__.py +108 -0
  31. tinysim_warp/cart_pole/__init__.py +44 -200
  32. tinysim_warp/quadruped/__init__.py +23 -160
  33. tinysim_warp/simple_quadruped/__init__.py +20 -91
  34. tinysim_warp/simple_quadruped/simple_quadruped.urdf +0 -9
  35. tinysim/simple_amr/__init__.py +0 -0
  36. tinysim/simple_amr/example_maps.py +0 -121
  37. tinysim/simple_amr/sim.js +0 -430
  38. tinysim/simple_amr/styles.css +0 -54
  39. tinysim/simple_amr/widget.py +0 -73
  40. {tinysim-0.0.4.dist-info → tinysim-0.0.5.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,274 @@
1
+ import numpy as np
2
+ from PIL import Image as PILImage
3
+
4
+ try:
5
+ import mujoco
6
+
7
+ from . import ManipulationBaseEnv
8
+ except ImportError:
9
+ raise ImportError(
10
+ "Mujoco is not properly installed. Install using `pip install tinysim[mujoco]`"
11
+ )
12
+
13
+ _FLOAT_EPS = np.finfo(np.float64).eps
14
+ _EPS4 = _FLOAT_EPS * 4.0
15
+
16
+
17
+ class ManipulationEnvV1:
18
+
19
+ def __init__(self, **kwargs):
20
+ kwargs["use_d405_camera"] = True
21
+ self.env = ManipulationBaseEnv(**kwargs)
22
+ self._model = self.env.model
23
+ self._data = self.env.data
24
+ self.frame_skip = 25
25
+ self.dt = self._model.opt.timestep * self.frame_skip
26
+
27
+ self._body_name2id = {}
28
+ for body_id in range(self._model.nbody):
29
+ name = mujoco.mj_id2name(self._model, mujoco.mjtObj.mjOBJ_BODY, body_id)
30
+ if name is not None:
31
+ self._body_name2id[name] = body_id
32
+
33
+ self.joint_names = []
34
+ for j in range(self._model.njnt):
35
+ name = mujoco.mj_id2name(self._model, mujoco.mjtObj.mjOBJ_JOINT, j)
36
+ if name is not None:
37
+ self.joint_names.append(name)
38
+
39
+ distance_threshold = 0.05
40
+ self.neutral_joint_values = np.array(
41
+ [0.00, 0.41, 0.00, -1.85, 0.00, 2.26, 0.79]
42
+ )
43
+
44
+ self.current_step = 0
45
+ self.maximum_episode_steps = 128
46
+ self.distance_threshold = distance_threshold
47
+
48
+ self.goal = self.get_site_xpos(self._model, self._data, "goal_site").copy()
49
+ self.initial_object_pos = self.get_site_xpos(
50
+ self._model, self._data, "obj_site"
51
+ ).copy()
52
+ free_joint_index = self.joint_names.index("obj_joint")
53
+ self.arm_joint_names = self.joint_names[:free_joint_index][0:7]
54
+ # self.gripper_joint_names = self.joint_names[:free_joint_index][7:9]
55
+ self.set_joint_neutral()
56
+ self.reset_mocap_welds(self._model, self._data)
57
+ mujoco.mj_forward(self._model, self._data)
58
+
59
+ def reset_mocap_welds(self, model, data):
60
+ if model.nmocap > 0 and model.eq_data is not None:
61
+ for i in range(model.eq_data.shape[0]):
62
+ if model.eq_type[i] == mujoco.mjtEq.mjEQ_WELD:
63
+ model.eq_data[i, :7] = np.array([0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0])
64
+ mujoco.mj_forward(model, data)
65
+
66
+ def reset_mocap2body_xpos(self, model, data):
67
+ if model.eq_type is None or model.eq_obj1id is None or model.eq_obj2id is None:
68
+ return
69
+ for eq_type, obj1_id, obj2_id in zip(
70
+ model.eq_type, model.eq_obj1id, model.eq_obj2id
71
+ ):
72
+ if eq_type != mujoco.mjtEq.mjEQ_WELD:
73
+ continue
74
+
75
+ mocap_id = model.body_mocapid[obj1_id]
76
+ if mocap_id != -1:
77
+ # obj1 is the mocap, obj2 is the welded body
78
+ body_idx = obj2_id
79
+ else:
80
+ # obj2 is the mocap, obj1 is the welded body
81
+ mocap_id = model.body_mocapid[obj2_id]
82
+ body_idx = obj1_id
83
+
84
+ assert mocap_id != -1
85
+ data.mocap_pos[mocap_id][:] = data.xpos[body_idx]
86
+ data.mocap_quat[mocap_id][:] = data.xquat[body_idx]
87
+
88
+ def mocap_set_action(self, model, data, action):
89
+ if model.nmocap > 0:
90
+ action, _ = np.split(action, (model.nmocap * 7,))
91
+ action = action.reshape(model.nmocap, 7)
92
+ pos_delta = action[:, :3]
93
+ quat_delta = action[:, 3:]
94
+ self.reset_mocap2body_xpos(model, data)
95
+ data.mocap_pos[:] = data.mocap_pos + pos_delta
96
+ data.mocap_quat[:] = data.mocap_quat + quat_delta
97
+
98
+ def ctrl_set_action(self, model, data, action):
99
+ if model.nmocap > 0:
100
+ _, action = np.split(action, (model.nmocap * 7,))
101
+
102
+ if len(data.ctrl) > 0:
103
+ for i in range(action.shape[0]):
104
+ if model.actuator_biastype[i] == 0:
105
+ data.ctrl[i] = action[i]
106
+ else:
107
+ idx = model.jnt_qposadr[model.actuator_trnid[i, 0]]
108
+ data.ctrl[i] = data.qpos[idx] + action[i]
109
+
110
+ def step(self, action):
111
+ self.current_step += 1
112
+ # just move the end effector in x, y, z
113
+ pos_ctrl = action.copy() * 0.05 # scale action
114
+ rot_ctrl = [
115
+ 1.0,
116
+ 0.0,
117
+ 0.0,
118
+ 0.0,
119
+ ]
120
+ action = np.concatenate([pos_ctrl, rot_ctrl])
121
+
122
+ self.ctrl_set_action(self._model, self._data, action)
123
+ self.mocap_set_action(self._model, self._data, action)
124
+
125
+ self.env.step(n_frames=self.frame_skip)
126
+ obs = self._get_obs()
127
+ terminated = self._is_success(obs["achieved_goal"], self.goal)
128
+ truncated = self.current_step >= self.maximum_episode_steps
129
+ reward = self.compute_reward(obs["achieved_goal"], self.goal)
130
+ return obs, reward, terminated, truncated, {}
131
+
132
+ def mat2euler(self, mat):
133
+ mat = np.asarray(mat, dtype=np.float64)
134
+ cy = np.sqrt(mat[..., 2, 2] * mat[..., 2, 2] + mat[..., 1, 2] * mat[..., 1, 2])
135
+ condition = cy > _EPS4
136
+ euler = np.empty(mat.shape[:-1], dtype=np.float64)
137
+ euler[..., 2] = np.where(
138
+ condition,
139
+ -np.arctan2(mat[..., 0, 1], mat[..., 0, 0]),
140
+ -np.arctan2(-mat[..., 1, 0], mat[..., 1, 1]),
141
+ )
142
+ euler[..., 1] = np.where(
143
+ condition,
144
+ -np.arctan2(-mat[..., 0, 2], cy),
145
+ -np.arctan2(-mat[..., 0, 2], cy),
146
+ )
147
+ euler[..., 0] = np.where(
148
+ condition, -np.arctan2(mat[..., 1, 2], mat[..., 2, 2]), 0.0
149
+ )
150
+ return euler
151
+
152
+ def get_site_xpos(self, model, data, name):
153
+ site_id = mujoco.mj_name2id(model, mujoco.mjtObj.mjOBJ_SITE, name)
154
+ return data.site_xpos[site_id]
155
+
156
+ def get_site_xvelp(self, model, data, name):
157
+ site_id = mujoco.mj_name2id(model, mujoco.mjtObj.mjOBJ_SITE, name)
158
+ jacp = self.get_site_jacp(model, data, site_id)
159
+ xvelp = jacp @ data.qvel
160
+ return xvelp
161
+
162
+ def get_site_jacp(self, model, data, site_id):
163
+ jacp = np.zeros((3, model.nv))
164
+ mujoco.mj_jacSite(model, data, jacp, None, site_id)
165
+ return jacp
166
+
167
+ def _get_obs(self) -> dict:
168
+ ee_position = self.get_site_xpos(self._model, self._data, "tip").copy()
169
+ ee_velocity = (
170
+ self.get_site_xvelp(self._model, self._data, "tip").copy() * self.dt
171
+ )
172
+ object_position = self.get_site_xpos(self._model, self._data, "obj_site").copy()
173
+ object_rotation = self.mat2euler(
174
+ self.get_site_xmat(self._model, self._data, "obj_site")
175
+ )
176
+
177
+ frame = self.env.d405_viewer.capture_frame()
178
+ img = np.array(PILImage.fromarray(frame).resize((64, 64))).transpose(2, 0, 1)
179
+
180
+ return {
181
+ "observation_cap": img,
182
+ "observation": np.concatenate(
183
+ [
184
+ ee_position,
185
+ ee_velocity,
186
+ object_position,
187
+ object_rotation,
188
+ ]
189
+ ).copy(),
190
+ "achieved_goal": object_position.copy(),
191
+ "desired_goal": self.goal.copy(),
192
+ }
193
+
194
+ def set_joint_qpos(self, model, data, name, value):
195
+ """Set the joint positions (qpos) of the model."""
196
+ joint_id = mujoco.mj_name2id(model, mujoco.mjtObj.mjOBJ_JOINT, name)
197
+ joint_addr = model.jnt_qposadr[joint_id]
198
+ # All joints are assumed to be of type mjJNT_HINGE in this environment
199
+ data.qpos[joint_addr] = value
200
+
201
+ def set_object_qpos(self, model, data):
202
+ joint_id = mujoco.mj_name2id(model, mujoco.mjtObj.mjOBJ_JOINT, "obj_joint")
203
+ joint_addr = model.jnt_qposadr[joint_id]
204
+ data.qpos[joint_addr : joint_addr + 3] = np.array(self.initial_object_pos)
205
+ # reset orientation
206
+ data.qpos[joint_addr + 3 : joint_addr + 7] = np.array([1.0, 0.0, 0.0, 0.0])
207
+
208
+ def _sample_goal(self):
209
+ goal = np.array([0.3, 0.0, 0.0])
210
+ return goal
211
+
212
+ def goal_distance(self, goal_a, goal_b):
213
+ assert goal_a.shape == goal_b.shape
214
+ return np.linalg.norm(goal_a - goal_b, axis=-1)
215
+
216
+ def compute_reward(self, achieved_goal, desired_goal, info=None):
217
+ d = self.goal_distance(achieved_goal, desired_goal)
218
+ # give reward for the end effector being close to the object
219
+ ee_position = self.get_site_xpos(self._model, self._data, "tip")
220
+ object_position = self.get_site_xpos(self._model, self._data, "obj_site")
221
+ ee_object_distance = np.linalg.norm(ee_position - object_position, axis=-1)
222
+
223
+ # the arm tries to cheat by moving the object with the side of the gripper
224
+ # negative ward if the arm contacts the ground with
225
+ effector_distance_reward = -0.1 * (ee_object_distance > 0.05).astype(np.float32)
226
+
227
+ # todo: check correctness
228
+ # give some reward if the cube is moving towards the goal
229
+ object_velocity = self.get_site_xvelp(self._model, self._data, "obj_site")
230
+ goal_direction = desired_goal[0] - object_position
231
+ goal_direction /= np.linalg.norm(goal_direction) + 1e-8
232
+ velocity_towards_goal = np.dot(object_velocity, goal_direction)
233
+ velocity_reward = max(0.0, velocity_towards_goal)
234
+
235
+ reward = -d + effector_distance_reward + velocity_reward
236
+ return reward
237
+
238
+ # sparse
239
+ # return -(d > self.distance_threshold).astype(np.float32)
240
+
241
+ def _is_success(self, achieved_goal, desired_goal):
242
+ d = self.goal_distance(achieved_goal, desired_goal)
243
+ return (d < self.distance_threshold).astype(np.float32)
244
+
245
+ def set_joint_neutral(self):
246
+ for name, value in zip(self.arm_joint_names, self.neutral_joint_values):
247
+ self.set_joint_qpos(self._model, self._data, name, value)
248
+
249
+ def _reset_sim(self) -> bool:
250
+ self.set_joint_neutral()
251
+ self.set_object_qpos(self._model, self._data)
252
+ mujoco.mj_forward(self._model, self._data)
253
+
254
+ def reset(self, **kwargs):
255
+ self.current_step = 0
256
+ self._reset_sim()
257
+ obs = self._get_obs()
258
+
259
+ # self.env.step(n_frames=self.frame_skip)
260
+ # frame = self.env.viewer.capture_frame()
261
+ # import matplotlib.pyplot as plt
262
+ # plt.imsave("debug_frame.png", frame)
263
+ # raise Exception("Debug")
264
+ return obs, {}
265
+
266
+ def get_site_xmat(self, model, data, name: str):
267
+ site_id = mujoco.mj_name2id(model, mujoco.mjtObj.mjOBJ_SITE, name)
268
+ return data.site_xmat[site_id].reshape(3, 3)
269
+
270
+ def get_body_state(self, name):
271
+ body_id = self._body_name2id[name]
272
+ body_xpos = self._data.xpos[body_id]
273
+ body_xquat = self._data.xquat[body_id]
274
+ return np.concatenate([body_xpos, body_xquat])
@@ -52,7 +52,6 @@
52
52
  <material class="panda" name="green" rgba="0 1 0 1"/>
53
53
  <material class="panda" name="light_blue" rgba="0.039216 0.541176 0.780392 1"/>
54
54
 
55
- <!-- Collision meshes -->
56
55
  <mesh name="link0_collision" file="link0.stl"/>
57
56
  <mesh name="link1_collision" file="link1.stl"/>
58
57
  <mesh name="link2_collision" file="link2.stl"/>
@@ -65,7 +64,6 @@
65
64
  <mesh name="link7_collision" file="link7.stl"/>
66
65
  <mesh name="hand_collision" file="hand.stl"/>
67
66
 
68
- <!-- Visual meshes -->
69
67
  <mesh file="link0_0.obj"/>
70
68
  <mesh file="link0_1.obj"/>
71
69
  <mesh file="link0_2.obj"/>
@@ -128,6 +126,15 @@
128
126
  <worldbody>
129
127
  <light name="top" pos="0 0 2" mode="trackcom"/>
130
128
  <camera name="front_cam" pos="1.1 0 0.5" xyaxes="0 1 0 -0.4 0 0.7"/>
129
+
130
+ <!-- Added -->
131
+ <body mocap="true" name="panda_mocap" pos="0.6 0 0.4">
132
+ <geom conaffinity="0" contype="0" pos="0 0 0" rgba="0 0.5 0 0.7" size="0.005 0.005 0.005" type="box"></geom>
133
+ <geom conaffinity="0" contype="0" pos="0 0 0" rgba="0 0.5 0 0.1" size="0.5 0.005 0.005" type="box"></geom>
134
+ <geom conaffinity="0" contype="0" pos="0 0 0" rgba="0 0.5 0 0.1" size="0.005 0.5 0.001" type="box"></geom>
135
+ <geom conaffinity="0" contype="0" pos="0 0 0" rgba="0 0.5 0 0.1" size="0.005 0.005 0.5" type="box"></geom>
136
+ </body>
137
+
131
138
  <body name="link0" childclass="panda">
132
139
  <inertial mass="0.629769" pos="0 0 0"
133
140
  fullinertia="0.00315 0.00388 0.004285 8.2904e-7 0.00015 8.2299e-6"/>
@@ -146,17 +153,17 @@
146
153
  <body name="link1" pos="0 0 0.333">
147
154
  <inertial mass="4.970684" pos="0.003875 0.002081 -0.04762"
148
155
  fullinertia="0.70337 0.70661 0.0091170 -0.00013900 0.0067720 0.019169"/>
149
- <joint name="joint1" range="-2.8973 2.8973"/>
156
+ <joint name="joint1" range="-2.8973 2.8973" /> <!-- Here -->
150
157
  <geom material="white" mesh="link1" class="visual"/>
151
158
  <geom mesh="link1_collision" class="collision"/>
152
159
  <body name="link2" quat="1 -1 0 0">
153
160
  <inertial mass="0.646926" pos="-0.003141 -0.02872 0.003495"
154
161
  fullinertia="0.0079620 2.8110e-2 2.5995e-2 -3.925e-3 1.0254e-2 7.04e-4"/>
155
- <joint name="joint2" range="-1.7628 1.7628"/>
162
+ <joint name="joint2" range="-1.7628 1.7628" /> <!-- Here -->
156
163
  <geom material="white" mesh="link2" class="visual"/>
157
164
  <geom mesh="link2_collision" class="collision"/>
158
165
  <body name="link3" pos="0 -0.316 0" quat="1 1 0 0">
159
- <joint name="joint3" range="-2.8973 2.8973"/>
166
+ <joint name="joint3" range="-2.8973 2.8973" /> <!-- Here -->
160
167
  <inertial mass="3.228604" pos="2.7518e-2 3.9252e-2 -6.6502e-2"
161
168
  fullinertia="3.7242e-2 3.6155e-2 1.083e-2 -4.761e-3 -1.1396e-2 -1.2805e-2"/>
162
169
  <geom mesh="link3_0" material="white" class="visual"/>
@@ -167,7 +174,7 @@
167
174
  <body name="link4" pos="0.0825 0 0" quat="1 1 0 0">
168
175
  <inertial mass="3.587895" pos="-5.317e-2 1.04419e-1 2.7454e-2"
169
176
  fullinertia="2.5853e-2 1.9552e-2 2.8323e-2 7.796e-3 -1.332e-3 8.641e-3"/>
170
- <joint name="joint4" range="-3.0718 -0.0698"/>
177
+ <joint name="joint4" range="-3.0718 -0.0698" /> <!-- Here -->
171
178
  <geom mesh="link4_0" material="white" class="visual"/>
172
179
  <geom mesh="link4_1" material="white" class="visual"/>
173
180
  <geom mesh="link4_2" material="black" class="visual"/>
@@ -176,7 +183,7 @@
176
183
  <body name="link5" pos="-0.0825 0.384 0" quat="1 -1 0 0">
177
184
  <inertial mass="1.225946" pos="-1.1953e-2 4.1065e-2 -3.8437e-2"
178
185
  fullinertia="3.5549e-2 2.9474e-2 8.627e-3 -2.117e-3 -4.037e-3 2.29e-4"/>
179
- <joint name="joint5" range="-2.8973 2.8973"/>
186
+ <joint name="joint5" range="-2.8973 2.8973" /> <!-- Here -->
180
187
  <geom mesh="link5_0" material="black" class="visual"/>
181
188
  <geom mesh="link5_1" material="white" class="visual"/>
182
189
  <geom mesh="link5_2" material="white" class="visual"/>
@@ -186,7 +193,8 @@
186
193
  <body name="link6" quat="1 1 0 0">
187
194
  <inertial mass="1.666555" pos="6.0149e-2 -1.4117e-2 -1.0517e-2"
188
195
  fullinertia="1.964e-3 4.354e-3 5.433e-3 1.09e-4 -1.158e-3 3.41e-4"/>
189
- <joint name="joint6" range="-0.0175 3.7525"/>
196
+ <joint name="joint6" range="-0.0175 3.7525" /> <!-- Here -->
197
+
190
198
  <geom mesh="link6_0" material="off_white" class="visual"/>
191
199
  <geom mesh="link6_1" material="white" class="visual"/>
192
200
  <geom mesh="link6_2" material="black" class="visual"/>
@@ -208,7 +216,7 @@
208
216
  <body name="link7" pos="0.088 0 0" quat="1 1 0 0">
209
217
  <inertial mass="7.35522e-01" pos="1.0517e-2 -4.252e-3 6.1597e-2"
210
218
  fullinertia="1.2516e-2 1.0027e-2 4.815e-3 -4.28e-4 -1.196e-3 -7.41e-4"/>
211
- <joint name="joint7" range="-2.8973 2.8973"/>
219
+ <joint name="joint7" range="-2.8973 2.8973" /> <!-- Here -->
212
220
  <geom mesh="link7_0" material="white" class="visual"/>
213
221
  <geom mesh="link7_1" material="black" class="visual"/>
214
222
  <geom mesh="link7_2" material="black" class="visual"/>
@@ -226,9 +234,13 @@
226
234
  <geom mesh="hand_3" material="white" class="visual"/>
227
235
  <geom mesh="hand_4" material="off_white" class="visual"/>
228
236
  <geom mesh="hand_collision" class="collision"/>
237
+
229
238
  <geom name="hand_capsule_collision" type="capsule" class="collision" size="0.04 0.06" quat="1 1 0 0" pos="0 0 0.03"/>
230
- <site name="gripper" pos="0 0 0.1"/>
231
- <site name="tip" pos="0 0 0.1034"/>
239
+
240
+ <!-- These are the red circles between the fingers -->
241
+ <site name="gripper" pos="0 0 0.1" rgba="1 0 0 1"/>
242
+ <site name="tip" pos="0 0 0.1034" rgba="1 0 0 1" />
243
+
232
244
  <body name="camera_d405" pos="0.05 0.0 0.066021" quat="0.6644633 0.2418451 -0.2418451 -0.6644633">
233
245
  <geom class="visual" mesh="d405"/>
234
246
  <geom class="collision" type="box" size=".018 .018 .01" pos="0 0 -0.01" group="4"/>
@@ -237,9 +249,9 @@
237
249
  sensorsize="0.003896 0.00214" focal="0.00193 0.00193"/>
238
250
  </body>
239
251
  </body>
240
- <body name="left_finger" pos="0 0 0.0584">
252
+ <body name="left_finger" pos="0 0.0 0.0584"> <!-- Changed -->
241
253
  <inertial mass="0.015" pos="0 0 0" diaginertia="2.375e-6 2.375e-6 7.5e-7"/>
242
- <joint name="finger_joint1" class="finger" range="0 0.04"/>
254
+ <!-- <joint name="finger_joint1" class="finger"/> -->
243
255
  <geom mesh="finger_0" material="off_white" class="visual"/>
244
256
  <geom mesh="finger_1" material="black" class="visual"/>
245
257
  <geom name="finger_left_collision" mesh="finger_0" class="collision"/>
@@ -248,9 +260,9 @@
248
260
  <geom name="lf3_collision" class="fingertip_collision_3"/>
249
261
  <geom name="lfp_collision" class="fingertip_pad_collision_6"/>
250
262
  </body>
251
- <body name="right_finger" pos="0 0 0.0584" quat="0 0 0 1">
263
+ <body name="right_finger" pos="0 0.0 0.0584" quat="0 0 0 1"> <!-- Changed -->
252
264
  <inertial mass="0.015" pos="0 0 0" diaginertia="2.375e-6 2.375e-6 7.5e-7"/>
253
- <joint name="finger_joint2" class="finger" range="0 0.04"/>
265
+ <!-- <joint name="finger_joint2" class="finger"/> -->
254
266
  <geom mesh="finger_0" material="off_white" class="visual"/>
255
267
  <geom mesh="finger_1" material="black" class="visual"/>
256
268
  <geom name="finger_right_collision" mesh="finger_0" class="collision"/>
@@ -270,10 +282,41 @@
270
282
  </body>
271
283
  </worldbody>
272
284
 
273
- <equality>
285
+ <!-- <equality>
274
286
  <joint joint1="finger_joint1" joint2="finger_joint2" solimp="0.95 0.99 0.001" solref="0.005 1"/>
287
+ </equality> -->
288
+ <equality>
289
+ <weld body1="panda_mocap" body2="hand" solimp="0.9 0.95 0.001" solref="0.02 1"></weld>
275
290
  </equality>
276
291
 
292
+ <!-- Actuators for the panda robot -->
293
+
294
+ <!-- <actuator>
295
+ <general class="panda" name="actuator1" joint="joint1" kp="870" forcerange="-87 87" ctrlrange="-2.9671 2.9671"/>
296
+ <general class="panda" name="actuator2" joint="joint2" kp="870" forcerange="-87 87" ctrlrange="-1.8326 1.8326"/>
297
+ <general class="panda" name="actuator3" joint="joint3" gainprm="3500" biasprm="0 -3500 -350"/>
298
+ <general class="panda" name="actuator4" joint="joint4" gainprm="3500" biasprm="0 -3500 -350" ctrlrange="-3.0718 -0.0698"/>
299
+ <general class="panda" name="actuator5" joint="joint5" gainprm="2000" biasprm="0 -2000 -200" forcerange="-12 12"/>
300
+ <general class="panda" name="actuator6" joint="joint6" gainprm="2000" biasprm="0 -2000 -200" forcerange="-12 12" ctrlrange="-0.0175 3.7525"/>
301
+ <general class="panda" name="actuator7" joint="joint7" gainprm="2000" biasprm="0 -2000 -200" forcerange="-12 12"/>
302
+ </actuator> -->
303
+
304
+ <actuator>
305
+ <position class="panda" name="actuator1" joint="joint1" kv="870" kp="870" forcerange="-87 87" ctrlrange="-2.9671 2.9671"/>
306
+ <position class="panda" name="actuator2" joint="joint2" kv="870" kp="870" forcerange="-87 87" ctrlrange="-1.8326 1.8326"/>
307
+ <position class="panda" name="actuator3" joint="joint3" kv="870" kp="870" forcerange="-87 87" ctrlrange="-2.9671 2.9671"/>
308
+ <position class="panda" name="actuator4" joint="joint4" kv="870" kp="870" forcerange="-87 87" ctrlrange="-3.1416 0.0"/>
309
+ <position class="panda" name="actuator5" joint="joint5" kv="120" kp="120" forcerange="-12 12" ctrlrange="-2.9671 2.9671"/>
310
+ <position class="panda" name="actuator6" joint="joint6" kv="120" kp="120" forcerange="-12 12" ctrlrange="-0.0175 3.7525"/>
311
+ <position class="panda" name="actuator7" joint="joint7" kv="120" kp="120" forcerange="-12 12" ctrlrange="-2.9671 2.9671"/>
312
+ </actuator>
313
+
314
+
315
+ <!-- <actuator>
316
+ <general name="r_gripper_finger_joint" joint="finger_joint1" class="panda" gainprm="500 0 0" biasprm="0 -500 -10" forcerange="-120 120" ctrlrange="0 0.04"/>
317
+ <general name="l_gripper_finger_joint" joint="finger_joint2" class="panda" gainprm="500 0 0" biasprm="0 -500 -10" forcerange="-120 120" ctrlrange="0 0.04"/>
318
+ </actuator> -->
319
+
277
320
  <contact>
278
321
  <exclude body1="link0" body2="link1"/>
279
322
  </contact>
@@ -2,20 +2,17 @@
2
2
  <include file="panda.xml"/>
3
3
  <include file="table.xml"/>
4
4
  <statistic center="0 0 0.1" extent="0.8"/>
5
-
6
5
  <visual>
7
6
  <headlight diffuse="0.6 0.6 0.6" ambient="0.3 0.3 0.3" specular="0 0 0"/>
8
7
  <rgba haze="0.15 0.25 0.35 1"/>
9
8
  <global azimuth="120" elevation="-20"/>
10
9
  </visual>
11
-
12
10
  <asset>
13
11
  <texture type="skybox" builtin="gradient" rgb1="0.3 0.5 0.7" rgb2="0 0 0" width="512" height="3072"/>
14
12
  <texture type="2d" name="groundplane" builtin="checker" mark="edge" rgb1="0.2 0.3 0.4" rgb2="0.1 0.2 0.3"
15
13
  markrgb="0.8 0.8 0.8" width="300" height="300"/>
16
14
  <material name="groundplane" texture="groundplane" texuniform="true" texrepeat="5 5" reflectance="0.2"/>
17
15
  </asset>
18
-
19
16
  <worldbody>
20
17
  <light pos="0 0 1.5" dir="0 0 -1" directional="true"/>
21
18
  <geom name="floor" size="0 0 0.05" type="plane" material="groundplane" contype="1" conaffinity="1"/>
@@ -5,10 +5,8 @@
5
5
  specular="0.2"
6
6
  shininess="0.2"/>
7
7
  </asset>
8
-
9
8
  <worldbody>
10
- <body name="table" pos="0.55 0 0">
11
-
9
+ <!-- <body name="table" pos="0.55 0 0">
12
10
  <geom name="table_top"
13
11
  type="box"
14
12
  size="0.25 0.35 0.02"
@@ -16,22 +14,28 @@
16
14
  material="table_wood"
17
15
  contype="1"
18
16
  conaffinity="1"/>
19
-
20
17
  <geom name="leg_fl" type="box" size="0.025 0.025 0.25" pos=" 0.22 0.32 0.25"/>
21
18
  <geom name="leg_fr" type="box" size="0.025 0.025 0.25" pos=" 0.22 -0.32 0.25"/>
22
19
  <geom name="leg_bl" type="box" size="0.025 0.025 0.25" pos="-0.22 0.32 0.25"/>
23
20
  <geom name="leg_br" type="box" size="0.025 0.025 0.25" pos="-0.22 -0.32 0.25"/>
21
+ </body> -->
22
+ <!-- <body name="box1" pos="0.35 0 0.60">
23
+ <joint type="free" damping="0.01" name="obj_joint"/>
24
+ <site name="obj_site" pos="0 0 0" size="0.01" type="sphere"/>
25
+ <geom name="box1_geom"
26
+ type="box"
27
+ size="0.02 0.02 0.02"
28
+ rgba="0.8 0.2 0.2 1"
29
+ friction="1" condim="6"/>
30
+ </body> -->
31
+ <body name="obj" pos="0.6 0.0 0.05" quat="1 0 0 0">
32
+ <joint type="free" damping="0.01" name="obj_joint"/>
33
+ <geom name="obj_geom" mass="0.1" type="box" size="0.03 0.03 0.03" rgba="0.5 0.7 0.5 1" friction="1" condim="6"/>
34
+ <site name="obj_site" pos="0 0 0" size="0.01" type="sphere"/>
24
35
  </body>
25
36
 
26
- <body name="box1" pos="0.35 0 0.60">
27
- <freejoint/>
28
- <geom name="box1_geom"
29
- type="box"
30
- size="0.05 0.05 0.05"
31
- rgba="0.8 0.2 0.2 1"
32
- density="200"
33
- contype="1"
34
- conaffinity="1"/>
37
+ <body name="goal_site" pos="0.3 0.0 0.0" quat="1 0 0 0">
38
+ <site name="goal_site" pos="0 0 0" size="0.05" type="sphere" rgba="0 1 0 0.5"/>
35
39
  </body>
36
40
  </worldbody>
37
41
  </mujoco>
@@ -1,19 +1,16 @@
1
- import numpy as np
2
1
  import mujoco
2
+ import numpy as np
3
3
  from IPython.display import display
4
4
  from PIL import Image as PILImage
5
5
 
6
6
 
7
7
  class NotebookViewer:
8
- def __init__(self, model, data):
8
+ def __init__(self, model, data, width=640, height=480):
9
9
  self.model = model
10
10
  self.data = data
11
- self.width = 640
12
- self.height = 480
13
-
14
11
  self.cam = mujoco.MjvCamera()
15
12
  self.opt = mujoco.MjvOption()
16
- self.renderer = mujoco.Renderer(model, self.height, self.width, max_geom=500)
13
+ self.renderer = mujoco.Renderer(model, height, width, max_geom=500)
17
14
 
18
15
  self.cam.azimuth = 90
19
16
  self.cam.elevation = -25
@@ -4,6 +4,7 @@ import numpy as np
4
4
 
5
5
  try:
6
6
  import mujoco
7
+
7
8
  from ..gl_viewer import GLViewer
8
9
  from ..notebook_viewer import NotebookViewer
9
10
  except ImportError:
@@ -50,9 +51,6 @@ class UnitreeA1BaseEnv:
50
51
  if self.viewer:
51
52
  self.viewer.render()
52
53
 
53
- def close(self):
54
- self.viewer.close()
55
-
56
54
  def reset(self):
57
55
  mujoco.mj_resetData(self.model, self.data)
58
56
  self.data.qpos[0:3] = [0.0, 0.0, 0.3]
@@ -77,6 +75,7 @@ class UnitreeA1BaseEnv:
77
75
  class UnitreeA1WalkEnv:
78
76
  def __init__(self, reward_weights, cost_weights, **kwargs):
79
77
  self.env = UnitreeA1BaseEnv(**kwargs)
78
+ self.viewer = self.env.viewer
80
79
  self.frame_skip = 20
81
80
  self.obs_dim = 45
82
81
  self._previous_observation = np.zeros(self.obs_dim, dtype=np.float32)
@@ -165,14 +164,14 @@ class UnitreeA1WalkEnv:
165
164
  action_diff_penalty = np.sum(np.abs(action - self.prev_action))
166
165
  action_sym = self.action_sym()
167
166
 
168
- Positive_rewards = (
167
+ rewards = (
169
168
  tracking_lin_vel_reward * self.reward_weights["linear_vel_tracking"]
170
169
  + tracking_ang_vel_reward * self.reward_weights["angular_vel_tracking"]
171
170
  + self.is_healthy * self.reward_weights["healthy"]
172
171
  + self.feet_air_time_reward * self.reward_weights["feet_airtime"]
173
172
  )
174
173
 
175
- Negative_rewards = (
174
+ neg_rewards = (
176
175
  self.torque_cost * self.cost_weights["torque"]
177
176
  + action_diff_penalty * self.cost_weights["action_rate"]
178
177
  + lin_vel_z_penalty * self.cost_weights["vertical_vel"]
@@ -180,11 +179,9 @@ class UnitreeA1WalkEnv:
180
179
  + action_sym * self.cost_weights["action_sym"]
181
180
  + self.acceleration_cost * self.cost_weights["joint_acceleration"]
182
181
  + self.orientation_cost * self.cost_weights["orientation"]
183
- + self.default_joint_position_cost
184
- * self.cost_weights["default_joint_position"]
182
+ + self.default_joint_pos_cost * self.cost_weights["default_joint_pos"]
185
183
  )
186
- reward = Positive_rewards - Negative_rewards
187
- return reward
184
+ return rewards - neg_rewards
188
185
 
189
186
  def _tracking_velocity_penalty(self, lin_vel, ang_vel):
190
187
  lin_vel_error = np.sum(np.abs(self.target_lin_vel[0] - lin_vel[0]))
@@ -235,7 +232,7 @@ class UnitreeA1WalkEnv:
235
232
  return np.square(roll) + np.square(pitch)
236
233
 
237
234
  @property
238
- def default_joint_position_cost(self):
235
+ def default_joint_pos_cost(self):
239
236
  joint_pos = self.env.get_joint_data()
240
237
  soft_joint_limits_low = self.joint_limits_low * 0.9
241
238
  soft_joint_limits_high = self.joint_limits_high * 0.9