diff --git a/dm_control/mujoco/tutorial.ipynb b/dm_control/mujoco/tutorial.ipynb
index 385133ce..689bfc83 100644
--- a/dm_control/mujoco/tutorial.ipynb
+++ b/dm_control/mujoco/tutorial.ipynb
@@ -38,7 +38,7 @@
"source": [
"This notebook provides an overview tutorial of the **MuJoCo** physics simulator, using the `dm_control` Python bindings. It is similar to the notebook in `dm_control/tutorial.ipynb`, but focuses on teaching MuJoCo itself, rather than the additional features provided by the Python package. \n",
"\n",
- "**A Colab runtime with GPU acceleration is required.** If you're using a CPU-only runtime, you can switch using the menu \"Runtime \u003e Change runtime type\"."
+ "**A Colab runtime with GPU acceleration is required.** If you're using a CPU-only runtime, you can switch using the menu \"Runtime > Change runtime type\"."
]
},
{
@@ -93,7 +93,7 @@
"\"\"\")\n",
"\n",
"print('Installing dm_control...')\n",
- "!pip install -q dm_control\u003e=1.0.16\n",
+ "!pip install -q dm_control>=1.0.16\n",
"\n",
"# Configure dm_control to use the EGL rendering backend (requires GPU)\n",
"%env MUJOCO_GL=egl\n",
@@ -269,13 +269,13 @@
"#@title A static model {vertical-output: true}\n",
"\n",
"static_model = \"\"\"\n",
- "\u003cmujoco\u003e\n",
- " \u003cworldbody\u003e\n",
- " \u003clight name=\"top\" pos=\"0 0 1\"/\u003e\n",
- " \u003cgeom name=\"red_box\" type=\"box\" size=\".2 .2 .2\" rgba=\"1 0 0 1\"/\u003e\n",
- " \u003cgeom name=\"green_sphere\" pos=\".2 .2 .2\" size=\".1\" rgba=\"0 1 0 1\"/\u003e\n",
- " \u003c/worldbody\u003e\n",
- "\u003c/mujoco\u003e\n",
+ "\n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ "\n",
"\"\"\"\n",
"physics = mujoco.Physics.from_xml_string(static_model)\n",
"pixels = physics.render()\n",
@@ -312,16 +312,16 @@
"#@title A child body with a joint { vertical-output: true }\n",
"\n",
"swinging_body = \"\"\"\n",
- "\u003cmujoco\u003e\n",
- " \u003cworldbody\u003e\n",
- " \u003clight name=\"top\" pos=\"0 0 1\"/\u003e\n",
- " \u003cbody name=\"box_and_sphere\" euler=\"0 0 -30\"\u003e \n",
- " \u003cjoint name=\"swing\" type=\"hinge\" axis=\"1 -1 0\" pos=\"-.2 -.2 -.2\"/\u003e\n",
- " \u003cgeom name=\"red_box\" type=\"box\" size=\".2 .2 .2\" rgba=\"1 0 0 1\"/\u003e\n",
- " \u003cgeom name=\"green_sphere\" pos=\".2 .2 .2\" size=\".1\" rgba=\"0 1 0 1\"/\u003e\n",
- " \u003c/body\u003e\n",
- " \u003c/worldbody\u003e\n",
- "\u003c/mujoco\u003e\n",
+ "\n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ "\n",
"\"\"\"\n",
"physics = mujoco.Physics.from_xml_string(swinging_body)\n",
"# Visualize the joint axis.\n",
@@ -364,9 +364,9 @@
"# Simulate and display video.\n",
"frames = []\n",
"physics.reset() # Reset state and time\n",
- "while physics.data.time \u003c duration:\n",
+ "while physics.data.time < duration:\n",
" physics.step()\n",
- " if len(frames) \u003c physics.data.time * framerate:\n",
+ " if len(frames) < physics.data.time * framerate:\n",
" pixels = physics.render(scene_option=scene_option)\n",
" frames.append(pixels)\n",
"display_video(frames, framerate)"
@@ -424,7 +424,7 @@
"# Shift nearest values to the origin.\n",
"depth -= depth.min()\n",
"# Scale by 2 mean distances of near rays.\n",
- "depth /= 2*depth[depth \u003c= 1].mean()\n",
+ "depth /= 2*depth[depth <= 1].mean()\n",
"# Scale to [0, 255]\n",
"pixels = 255*np.clip(depth, 0, 1)\n",
"PIL.Image.fromarray(pixels.astype(np.uint8))"
@@ -467,7 +467,7 @@
"box_mat = physics.named.data.geom_xmat['red_box'].reshape(3, 3)\n",
"box_size = physics.named.model.geom_size['red_box']\n",
"offsets = np.array([-1, 1]) * box_size[:, None]\n",
- "xyz_local = np.stack(itertools.product(*offsets)).T\n",
+ "xyz_local = np.stack(list(itertools.product(*offsets))).T\n",
"xyz_global = box_pos[:, None] + box_mat @ xyz_local\n",
"\n",
"# Camera matrices multiply homogenous [x, y, z, 1] vectors.\n",
@@ -514,7 +514,7 @@
"\n",
"def add_visual_capsule(scene, point1, point2, radius, rgba):\n",
" \"\"\"Adds one capsule to an mjvScene.\"\"\"\n",
- " if scene.ngeom \u003e= scene.maxgeom:\n",
+ " if scene.ngeom >= scene.maxgeom:\n",
" return\n",
" scene.ngeom += 1 # increment ngeom\n",
" # initialise a new capsule, add it to the scene using mjv_makeConnector\n",
@@ -534,7 +534,7 @@
"\n",
"def scene_callback(physics, scn):\n",
" \"\"\"Draw position trace, speed modifies width and colours.\"\"\"\n",
- " if len(positions) \u003e 1:\n",
+ " if len(positions) > 1:\n",
" for i in range(len(positions)-1):\n",
" rgba=np.array((np.clip(speeds[i]/10, 0, 1),\n",
" np.clip(1-speeds[i]/10, 0, 1),\n",
@@ -550,13 +550,13 @@
"# Simulate and display video.\n",
"frames = []\n",
"physics.reset() # Reset state and time\n",
- "while physics.data.time \u003c duration:\n",
+ "while physics.data.time < duration:\n",
" # append data to the traces\n",
" positions.append(physics.named.data.geom_xpos[\"green_sphere\"].copy())\n",
" times.append(physics.data.time)\n",
" speeds.append(get_geom_speed(physics, \"green_sphere\"))\n",
" physics.step()\n",
- " if len(frames) \u003c physics.data.time * framerate:\n",
+ " if len(frames) < physics.data.time * framerate:\n",
" camera = mujoco.Camera(physics, max_geom=10000,\n",
" scene_callback=scene_callback)\n",
" pixels = camera.render()\n",
@@ -844,32 +844,32 @@
"#@title The \"tippe-top\" model{vertical-output: true}\n",
"\n",
"tippe_top = \"\"\"\n",
- "\u003cmujoco model=\"tippe top\"\u003e\n",
- " \u003coption integrator=\"RK4\"/\u003e\n",
- "\n",
- " \u003casset\u003e\n",
- " \u003ctexture name=\"grid\" type=\"2d\" builtin=\"checker\" rgb1=\".1 .2 .3\" \n",
- " rgb2=\".2 .3 .4\" width=\"300\" height=\"300\"/\u003e\n",
- " \u003cmaterial name=\"grid\" texture=\"grid\" texrepeat=\"8 8\" reflectance=\".2\"/\u003e\n",
- " \u003c/asset\u003e\n",
- "\n",
- " \u003cworldbody\u003e\n",
- " \u003cgeom size=\".2 .2 .01\" type=\"plane\" material=\"grid\"/\u003e\n",
- " \u003clight pos=\"0 0 .6\"/\u003e\n",
- " \u003ccamera name=\"closeup\" pos=\"0 -.1 .07\" xyaxes=\"1 0 0 0 1 2\"/\u003e\n",
- " \u003cbody name=\"top\" pos=\"0 0 .02\"\u003e\n",
- " \u003cfreejoint/\u003e\n",
- " \u003cgeom name=\"ball\" type=\"sphere\" size=\".02\" /\u003e\n",
- " \u003cgeom name=\"stem\" type=\"cylinder\" pos=\"0 0 .02\" size=\"0.004 .008\"/\u003e\n",
- " \u003cgeom name=\"ballast\" type=\"box\" size=\".023 .023 0.005\" pos=\"0 0 -.015\" \n",
- " contype=\"0\" conaffinity=\"0\" group=\"3\"/\u003e\n",
- " \u003c/body\u003e\n",
- " \u003c/worldbody\u003e\n",
- " \n",
- " \u003ckeyframe\u003e\n",
- " \u003ckey name=\"spinning\" qpos=\"0 0 0.02 1 0 0 0\" qvel=\"0 0 0 0 1 200\" /\u003e\n",
- " \u003c/keyframe\u003e\n",
- "\u003c/mujoco\u003e\n",
+ "\n",
+ " \n",
"\"\"\"\n",
"physics = mujoco.Physics.from_xml_string(tippe_top)\n",
"PIL.Image.fromarray(physics.render(camera_id='closeup'))"
@@ -882,12 +882,12 @@
},
"source": [
"Note several new features of this model definition:\n",
- "0. The free joint is added with the `\u003cfreejoint/\u003e` clause, which is similar to `\u003cjoint type=\"free\"/\u003e`, but prohibits unphysical attributes like friction or stiffness.\n",
- "1. We use the `\u003coption/\u003e` clause to set the integrator to the more accurate Runge Kutta 4th order.\n",
- "2. We define the floor's grid material inside the `\u003casset/\u003e` clause and reference it in the floor geom. \n",
+ "0. The free joint is added with the `` clause, which is similar to ``, but prohibits unphysical attributes like friction or stiffness.\n",
+ "1. We use the `` clause to set the integrator to the more accurate Runge Kutta 4th order.\n",
+ "2. We define the floor's grid material inside the `` clause and reference it in the floor geom. \n",
"3. We use an invisible and non-colliding box geom called `ballast` to move the top's center-of-mass lower. Having a low center of mass is (counter-intuitively) required for the flipping behaviour to occur.\n",
"4. We save our initial spinning state as a keyframe. It has a high rotational velocity around the z-axis, but is not perfectly oriented with the world.\n",
- "5. We define a `\u003ccamera\u003e` in our model, and then render from it using the `camera_id` argument to `render()`.\n",
+ "5. We define a `` in our model, and then render from it using the `camera_id` argument to `render()`.\n",
"Let us examine the state:"
]
},
@@ -928,9 +928,9 @@
"# Simulate and display video.\n",
"frames = []\n",
"physics.reset(0) # Reset to keyframe 0 (load a saved state).\n",
- "while physics.data.time \u003c duration:\n",
+ "while physics.data.time < duration:\n",
" physics.step()\n",
- " if len(frames) \u003c (physics.data.time) * framerate:\n",
+ " if len(frames) < (physics.data.time) * framerate:\n",
" pixels = physics.render(camera_id='closeup')\n",
" frames.append(pixels)\n",
"\n",
@@ -965,7 +965,7 @@
"\n",
"# Simulate and save data\n",
"physics.reset(0)\n",
- "while physics.data.time \u003c duration:\n",
+ "while physics.data.time < duration:\n",
" physics.step()\n",
" timevals.append(physics.data.time)\n",
" angular_velocity.append(physics.data.qvel[3:6].copy())\n",
@@ -1015,40 +1015,40 @@
"source": [
"#@title chaotic pendulum {vertical-output: true}\n",
"chaotic_pendulum = \"\"\"\n",
- "\u003cmujoco\u003e\n",
- "\n",
- " \u003coption timestep=\".001\" \u003e\n",
- " \u003cflag energy=\"enable\" contact=\"disable\"/\u003e\n",
- " \u003c/option\u003e\n",
- " \n",
- " \u003cdefault\u003e\n",
- " \u003cjoint type=\"hinge\" axis=\"0 -1 0\"/\u003e\n",
- " \u003cgeom type=\"capsule\" size=\".02\"/\u003e\n",
- " \u003c/default\u003e\n",
- " \n",
- " \u003cworldbody\u003e\n",
- " \u003clight pos=\"0 -.4 1\"/\u003e\n",
- " \u003ccamera name=\"fixed\" pos=\"0 -1 0\" xyaxes=\"1 0 0 0 0 1\"/\u003e\n",
- " \u003cbody name=\"0\" pos=\"0 0 .2\"\u003e \n",
- " \u003cjoint name=\"root\"/\u003e\n",
- " \u003cgeom fromto=\"-.2 0 0 .2 0 0\" rgba=\"1 1 0 1\"/\u003e\n",
- " \u003cgeom fromto=\"0 0 0 0 0 -.25\" rgba=\"1 1 0 1\"/\u003e\n",
- " \u003cbody name=\"1\" pos=\"-.2 0 0\"\u003e \n",
- " \u003cjoint/\u003e\n",
- " \u003cgeom fromto=\"0 0 0 0 0 -.2\" rgba=\"1 0 0 1\"/\u003e\n",
- " \u003c/body\u003e \n",
- " \u003cbody name=\"2\" pos=\".2 0 0\"\u003e \n",
- " \u003cjoint/\u003e\n",
- " \u003cgeom fromto=\"0 0 0 0 0 -.2\" rgba=\"0 1 0 1\"/\u003e\n",
- " \u003c/body\u003e\n",
- " \u003cbody name=\"3\" pos=\"0 0 -.25\"\u003e\n",
- " \u003cjoint/\u003e\n",
- " \u003cgeom fromto=\"0 0 0 0 0 -.2\" rgba=\"0 0 1 1\"/\u003e\n",
- " \u003c/body\u003e \n",
- " \u003c/body\u003e\n",
- " \u003c/worldbody\u003e\n",
- " \n",
- "\u003c/mujoco\u003e\n",
+ "\n",
+ "\n",
+ " \n",
+ "\n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ "\n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ "\n",
+ "\n",
"\"\"\"\n",
"physics = mujoco.Physics.from_xml_string(chaotic_pendulum)\n",
"\n",
@@ -1093,7 +1093,7 @@
"render_time = 0\n",
"n_steps = 0\n",
"for i in range(n_frames):\n",
- " while physics.data.time * framerate \u003c i:\n",
+ " while physics.data.time * framerate < i:\n",
" tic = time.time()\n",
" physics.step()\n",
" sim_time += time.time() - tic\n",
@@ -1102,7 +1102,7 @@
" frame = physics.render(240, 320, camera_id=\"fixed\")\n",
" render_time += time.time() - tic\n",
" frames.append(frame.copy())\n",
- " \n",
+ "\n",
"# print timing and play video\n",
"print('simulation: {:6.2f} ms/frame ({:5.0f}Hz)'.format(\n",
" 1000*sim_time/n_steps, n_steps/sim_time))\n",
@@ -1168,7 +1168,7 @@
"# finalize plot\n",
"ax[0].set_title('root angle')\n",
"ax[0].set_ylabel('radian')\n",
- "ax[1].set_title('total energy') \n",
+ "ax[1].set_title('total energy')\n",
"ax[1].set_ylabel('Joule')\n",
"ax[1].set_xlabel('second')\n",
"plt.tight_layout()"
@@ -1206,12 +1206,12 @@
"for dt in TIMESTEPS:\n",
" # set timestep, print\n",
" physics.model.opt.timestep = dt\n",
- " \n",
- " # allocate \n",
+ "\n",
+ " # allocate\n",
" n_steps = int(SIM_DURATION / physics.model.opt.timestep)\n",
" sim_time = np.zeros(n_steps)\n",
- " energy = np.zeros(n_steps) \n",
- " \n",
+ " energy = np.zeros(n_steps)\n",
+ "\n",
" # initialize\n",
" with physics.reset_context():\n",
" physics.data.qvel[0] = 9 # root joint velocity\n",
@@ -1225,7 +1225,7 @@
"\n",
" # plot\n",
" ax.plot(sim_time, energy, label='timestep = {:2.2g}ms'.format(1000*dt))\n",
- " \n",
+ "\n",
"# finalize plot\n",
"ax.set_title('energy')\n",
"ax.set_ylabel('Joule')\n",
@@ -1262,13 +1262,13 @@
"for dt in TIMESTEPS:\n",
" # set timestep\n",
" physics.model.opt.timestep = dt\n",
- " \n",
- " # allocate \n",
+ "\n",
+ " # allocate\n",
" n_steps = int(SIM_DURATION / physics.model.opt.timestep)\n",
" sim_time = np.zeros(n_steps)\n",
" energy = np.zeros(n_steps) * np.nan\n",
" speed = np.zeros(n_steps) * np.nan\n",
- " \n",
+ "\n",
" # initialize\n",
" with physics.reset_context():\n",
" physics.data.qvel[0] = 11 # root joint velocity\n",
@@ -1319,31 +1319,31 @@
"#@title 'box_and_sphere' free body: {vertical-output: true}\n",
"\n",
"free_body_MJCF = \"\"\"\n",
- "\u003cmujoco\u003e\n",
- " \u003casset\u003e\n",
- " \u003ctexture name=\"grid\" type=\"2d\" builtin=\"checker\" rgb1=\".1 .2 .3\" \n",
- " rgb2=\".2 .3 .4\" width=\"300\" height=\"300\" mark=\"edge\" markrgb=\".2 .3 .4\"/\u003e\n",
- " \u003cmaterial name=\"grid\" texture=\"grid\" texrepeat=\"2 2\" texuniform=\"true\" \n",
- " reflectance=\".2\"/\u003e\n",
- " \u003c/asset\u003e\n",
- "\n",
- " \u003cworldbody\u003e\n",
- " \u003clight pos=\"0 0 1\" mode=\"trackcom\"/\u003e\n",
- " \u003cgeom name=\"ground\" type=\"plane\" pos=\"0 0 -.5\" size=\"2 2 .1\" material=\"grid\" solimp=\".99 .99 .01\" solref=\".001 1\"/\u003e\n",
- " \u003cbody name=\"box_and_sphere\" pos=\"0 0 0\"\u003e \n",
- " \u003cfreejoint/\u003e\n",
- " \u003cgeom name=\"red_box\" type=\"box\" size=\".1 .1 .1\" rgba=\"1 0 0 1\" solimp=\".99 .99 .01\" solref=\".001 1\"/\u003e\n",
- " \u003cgeom name=\"green_sphere\" size=\".06\" pos=\".1 .1 .1\" rgba=\"0 1 0 1\"/\u003e\n",
- " \u003ccamera name=\"fixed\" pos=\"0 -.6 .3\" xyaxes=\"1 0 0 0 1 2\"/\u003e\n",
- " \u003ccamera name=\"track\" pos=\"0 -.6 .3\" xyaxes=\"1 0 0 0 1 2\" mode=\"track\"/\u003e\n",
- " \u003c/body\u003e\n",
- " \u003c/worldbody\u003e\n",
- "\u003c/mujoco\u003e\n",
+ "\n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ "\n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ "\n",
"\"\"\"\n",
"physics = mujoco.Physics.from_xml_string(free_body_MJCF)\n",
"\n",
"\n",
- "pixels = physics.render(400, 600, \"fixed\") \n",
+ "pixels = physics.render(400, 600, \"fixed\")\n",
"PIL.Image.fromarray(pixels)"
]
},
@@ -1380,7 +1380,7 @@
"\n",
"# simulate and render\n",
"for i in range(n_frames):\n",
- " while physics.data.time \u003c i/120.0: #1/4x real time\n",
+ " while physics.data.time < i/120.0: #1/4x real time\n",
" physics.step()\n",
" frames[i] = physics.render(height, width, camera_id=\"track\", scene_option=options)\n",
"# show video\n",
@@ -1430,14 +1430,14 @@
" acceleration[i] = physics.data.qacc[:]\n",
" # iterate over active contacts, save force and distance\n",
" for j,c in enumerate(physics.data.contact):\n",
- " mjlib.mj_contactForce(physics.model.ptr, physics.data.ptr, \n",
+ " mjlib.mj_contactForce(physics.model.ptr, physics.data.ptr,\n",
" j, forcetorque)\n",
" force[i] += forcetorque[0:3]\n",
" penetration[i] = min(penetration[i], c.dist)\n",
- " # we could also do \n",
+ " # we could also do\n",
" # force[i] += physics.data.qfrc_constraint[0:3]\n",
" # do you see why?\n",
- " \n",
+ "\n",
"# plot\n",
"_, ax = plt.subplots(3, 2, sharex=True, figsize=(7, 10))\n",
"\n",
@@ -1467,12 +1467,12 @@
"mg = physics.named.model.body_mass[\"box_and_sphere\"] * z_gravity\n",
"mg_line = ax[1,1].plot(sim_time, np.ones(n_steps)*mg, label='m*g', linewidth=1)\n",
"ax[1,1].legend()\n",
- " \n",
+ "\n",
"ax[2,1].plot(sim_time, 1000*penetration)\n",
"ax[2,1].set_title('penetration depth')\n",
"ax[2,1].set_ylabel('millimeter')\n",
"ax[2,1].set_xlabel('second')\n",
- " \n",
+ "\n",
"plt.tight_layout()"
]
},
@@ -1495,38 +1495,38 @@
"source": [
"#@title tangential friction and slope: {vertical-output: true}\n",
"MJCF = \"\"\"\n",
- "\u003cmujoco\u003e\n",
- " \u003casset\u003e\n",
- " \u003ctexture name=\"grid\" type=\"2d\" builtin=\"checker\" rgb1=\".1 .2 .3\" \n",
- " rgb2=\".2 .3 .4\" width=\"300\" height=\"300\" mark=\"none\"/\u003e\n",
- " \u003cmaterial name=\"grid\" texture=\"grid\" texrepeat=\"6 6\" \n",
- " texuniform=\"true\" reflectance=\".2\"/\u003e\n",
- " \u003cmaterial name=\"wall\" rgba='.5 .5 .5 1'/\u003e\n",
- " \u003c/asset\u003e\n",
- "\n",
- " \u003cdefault\u003e\n",
- " \u003cgeom type=\"box\" size=\".05 .05 .05\" /\u003e\n",
- " \u003cjoint type=\"free\"/\u003e\n",
- " \u003c/default\u003e\n",
- "\n",
- " \u003cworldbody\u003e\n",
- " \u003clight name=\"light\" pos=\"-.2 0 1\"/\u003e\n",
- " \u003cgeom name=\"ground\" type=\"plane\" size=\".5 .5 10\" material=\"grid\" \n",
- " zaxis=\"-.3 0 1\" friction=\".1\"/\u003e \n",
- " \u003ccamera name=\"y\" pos=\"-.1 -.6 .3\" xyaxes=\"1 0 0 0 1 2\"/\u003e\n",
- " \u003cbody pos=\"0 0 .1\"\u003e\n",
- " \u003cjoint/\u003e\n",
- " \u003cgeom/\u003e\n",
- " \u003c/body\u003e\n",
- " \u003cbody pos=\"0 .2 .1\"\u003e\n",
- " \u003cjoint/\u003e\n",
- " \u003cgeom friction=\".33\"/\u003e\n",
- " \u003c/body\u003e \n",
- " \u003c/worldbody\u003e\n",
- " \n",
- "\u003c/mujoco\u003e\n",
+ "\n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ "\n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ "\n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ "\n",
+ "\n",
"\"\"\"\n",
- "# load \n",
+ "# load\n",
"physics = mujoco.Physics.from_xml_string(MJCF)\n",
"\n",
"n_frames = 60\n",
@@ -1537,7 +1537,7 @@
"# simulate and render\n",
"physics.reset()\n",
"for i in range(n_frames):\n",
- " while physics.data.time \u003c i/30.0:\n",
+ " while physics.data.time < i/30.0:\n",
" physics.step()\n",
" video[i] = physics.render(height, width, \"y\")\n",
"display_video(video)"
@@ -1562,46 +1562,46 @@
"source": [
"#@title bat and piƱata: {vertical-output: true}\n",
"MJCF = \"\"\"\n",
- "\u003cmujoco\u003e\n",
- " \u003casset\u003e\n",
- " \u003ctexture name=\"grid\" type=\"2d\" builtin=\"checker\" rgb1=\".1 .2 .3\" \n",
- " rgb2=\".2 .3 .4\" width=\"300\" height=\"300\" mark=\"none\"/\u003e\n",
- " \u003cmaterial name=\"grid\" texture=\"grid\" texrepeat=\"1 1\" \n",
- " texuniform=\"true\" reflectance=\".2\"/\u003e\n",
- " \u003c/asset\u003e\n",
- "\n",
- " \u003cworldbody\u003e\n",
- " \u003clight name=\"light\" pos=\"0 0 1\"/\u003e\n",
- " \u003cgeom name=\"floor\" type=\"plane\" pos=\"0 0 -.5\" size=\"2 2 .1\" material=\"grid\"/\u003e\n",
- " \u003csite name=\"anchor\" pos=\"0 0 .3\" size=\".01\"/\u003e\n",
- " \u003ccamera name=\"fixed\" pos=\"0 -1.3 .5\" xyaxes=\"1 0 0 0 1 2\"/\u003e \n",
- " \n",
- " \u003cgeom name=\"pole\" type=\"cylinder\" fromto=\".3 0 -.5 .3 0 -.1\" size=\".04\"/\u003e \n",
- " \u003cbody name=\"bat\" pos=\".3 0 -.1\"\u003e\n",
- " \u003cjoint name=\"swing\" type=\"hinge\" damping=\"1\" axis=\"0 0 1\"/\u003e\n",
- " \u003cgeom name=\"bat\" type=\"capsule\" fromto=\"0 0 .04 0 -.3 .04\" \n",
- " size=\".04\" rgba=\"0 0 1 1\"/\u003e\n",
- " \u003c/body\u003e\n",
- " \n",
- " \u003cbody name=\"box_and_sphere\" pos=\"0 0 0\"\u003e \n",
- " \u003cjoint name=\"free\" type=\"free\"/\u003e\n",
- " \u003cgeom name=\"red_box\" type=\"box\" size=\".1 .1 .1\" rgba=\"1 0 0 1\"/\u003e\n",
- " \u003cgeom name=\"green_sphere\" size=\".06\" pos=\".1 .1 .1\" rgba=\"0 1 0 1\"/\u003e\n",
- " \u003csite name=\"hook\" pos=\"-.1 -.1 -.1\" size=\".01\"/\u003e\n",
- " \u003c/body\u003e\n",
- " \u003c/worldbody\u003e\n",
- " \n",
- " \u003ctendon\u003e\n",
- " \u003cspatial name=\"wire\" limited=\"true\" range=\"0 0.35\" width=\"0.003\"\u003e\n",
- " \u003csite site=\"anchor\"/\u003e\n",
- " \u003csite site=\"hook\"/\u003e\n",
- " \u003c/spatial\u003e \n",
- " \u003c/tendon\u003e\n",
- " \n",
- " \u003cactuator\u003e\n",
- " \u003cmotor name=\"my_motor\" joint=\"swing\" gear=\"1\"/\u003e\n",
- " \u003c/actuator\u003e\n",
- "\u003c/mujoco\u003e\n",
+ "\n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ "\n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ "\n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ "\n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ "\n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ "\n",
+ " \n",
+ " \n",
+ " \n",
+ "\n",
"\"\"\"\n",
"physics = mujoco.Physics.from_xml_string(MJCF)\n",
"PIL.Image.fromarray(physics.render(480, 480, \"fixed\") )\n"
@@ -1627,7 +1627,7 @@
"\n",
"# simulate and render\n",
"for i in range(n_frames):\n",
- " while physics.data.time \u003c i/30.0:\n",
+ " while physics.data.time < i/30.0:\n",
" physics.step()\n",
" video[i] = physics.render(height, width, \"fixed\")\n",
"\n",
@@ -1661,7 +1661,7 @@
"physics.reset()\n",
"\n",
"# gravity compensation\n",
- "mg = -(physics.named.model.body_mass[\"box_and_sphere\"] * \n",
+ "mg = -(physics.named.model.body_mass[\"box_and_sphere\"] *\n",
" physics.model.opt.gravity[2])\n",
"physics.named.data.xfrc_applied[\"box_and_sphere\", 2] = mg\n",
"\n",
@@ -1670,7 +1670,7 @@
"\n",
"# simulate and render\n",
"for i in range(n_frames):\n",
- " while physics.data.time \u003c i/30.0:\n",
+ " while physics.data.time < i/30.0:\n",
" physics.step()\n",
" video[i] = physics.render(height, width)\n",
"display_video(video)"
@@ -1698,53 +1698,53 @@
"source": [
"#@title virtual spring-damper: {vertical-output: true}\n",
"MJCF = \"\"\"\n",
- "\u003cmujoco\u003e\n",
- " \u003casset\u003e\n",
- " \u003ctexture name=\"grid\" type=\"2d\" builtin=\"checker\" rgb1=\".1 .2 .3\" \n",
- " rgb2=\".2 .3 .4\" width=\"300\" height=\"300\" mark=\"none\"/\u003e\n",
- " \u003cmaterial name=\"grid\" texture=\"grid\" texrepeat=\"6 6\" \n",
- " texuniform=\"true\" reflectance=\".2\"/\u003e\n",
- " \u003cmaterial name=\"wall\" rgba='.5 .5 .5 1'/\u003e\n",
- " \u003c/asset\u003e\n",
- "\n",
- " \u003coption gravity=\"0 0 0\"\u003e\n",
- " \u003cflag contact=\"disable\"/\u003e\n",
- " \u003c/option\u003e\n",
- "\n",
- " \u003cdefault\u003e\n",
- " \u003cgeom type=\"capsule\" size=\".02 .02 .02\" /\u003e\n",
- " \u003cjoint type=\"hinge\" damping=\".02\"/\u003e\n",
- " \u003c/default\u003e\n",
- "\n",
- " \u003cworldbody\u003e\n",
- " \u003clight name=\"light\" pos=\"0 0 1\"/\u003e\n",
- " \u003cgeom name=\"ground\" type=\"plane\" size=\".5 .5 10\" material=\"grid\"/\u003e \n",
- " \u003ccamera name=\"y\" pos=\"0 -.8 .6\" xyaxes=\"1 0 0 0 1 2\"/\u003e\n",
- " \u003ccamera name=\"x\" pos=\"-.8 0 .6\" xyaxes=\"0 -1 0 1 0 2\"/\u003e\n",
- "\n",
- " \u003cgeom fromto=\"0 0 0 0 0 .2\" /\u003e\n",
- " \u003cbody pos=\"0 0 .2\"\u003e\n",
- " \u003cjoint axis=\"0 0 1\"/\u003e\n",
- " \u003cjoint axis=\"0 1 0\"/\u003e\n",
- " \u003cgeom fromto=\"0 0 0 .2 0 0\" /\u003e\n",
- " \u003cbody pos=\".2 0 0\"\u003e\n",
- " \u003cjoint axis=\"1 0 0\"/\u003e\n",
- " \u003cjoint axis=\"0 1 0\"/\u003e\n",
- " \u003cgeom fromto=\"0 0 0 0 0 .15\" /\u003e\n",
- " \u003cbody pos=\"0 0 .15\"\u003e\n",
- " \u003cjoint axis=\"0 0 1\"/\u003e\n",
- " \u003cjoint axis=\"0 1 0\"/\u003e\n",
- " \u003cgeom fromto=\"0 0 0 .1 0 0\"/\u003e\n",
- " \u003cgeom name=\"fingertip\" type=\"box\" pos=\".1 0 0\" rgba=\"1 0 0 1\" /\u003e\n",
- " \u003c/body\u003e \n",
- " \u003c/body\u003e\n",
- " \u003c/body\u003e\n",
- " \n",
- " \u003cgeom name=\"target\" type=\"box\" rgba=\"0 1 0 1\"/\u003e\n",
- " \n",
- " \u003c/worldbody\u003e\n",
- " \n",
- "\u003c/mujoco\u003e\n",
+ "\n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ "\n",
+ " \n",
+ "\n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ "\n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ "\n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ "\n",
+ " \n",
+ "\n",
+ " \n",
+ "\n",
+ "\n",
"\"\"\"\n",
"physics = mujoco.Physics.from_xml_string(MJCF)\n",
"\n",
@@ -1756,7 +1756,7 @@
"jac_rot = np.zeros((3, physics.model.nv))\n",
"\n",
"n_frames = 50\n",
- "height = 320 \n",
+ "height = 320\n",
"width = 320\n",
"video = np.zeros((n_frames, height, 2*width, 3), dtype=np.uint8)\n",
"\n",
@@ -1769,22 +1769,22 @@
"\n",
"# simulate and render\n",
"for i in range(n_frames):\n",
- " while physics.data.time \u003c i/15.0:\n",
- " \n",
+ " while physics.data.time < i/15.0:\n",
+ "\n",
" # get Jacobian of fingertip position\n",
- " mjlib.mj_jacGeom(physics.model.ptr, \n",
- " physics.data.ptr, \n",
- " jac_pos, \n",
- " jac_rot, \n",
+ " mjlib.mj_jacGeom(physics.model.ptr,\n",
+ " physics.data.ptr,\n",
+ " jac_pos,\n",
+ " jac_rot,\n",
" physics.model.name2id('fingertip', 'geom'))\n",
" # multiply the jacobian by error to get vector in joint space\n",
- " err = (physics.named.data.geom_xpos[\"target\"] - \n",
+ " err = (physics.named.data.geom_xpos[\"target\"] -\n",
" physics.named.data.geom_xpos[\"fingertip\"])\n",
" jnt_err = np.dot(err, jac_pos)\n",
- " \n",
+ "\n",
" # set virutal spring force\n",
" physics.data.qfrc_applied[:] = KP * jnt_err\n",
- " \n",
+ "\n",
" # step\n",
" physics.step()\n",
"\n",