fix link of mj_forward on tutorial
This commit is contained in:
+307
-294
@@ -8,11 +8,11 @@
|
|||||||
"source": [
|
"source": [
|
||||||
"\n",
|
"\n",
|
||||||
"\n",
|
"\n",
|
||||||
"# \u003ch1\u003e\u003ccenter\u003eTutorial \u003ca href=\"https://colab.research.google.com/github/google-deepmind/mujoco/blob/main/python/tutorial.ipynb\"\u003e\u003cimg src=\"https://colab.research.google.com/assets/colab-badge.svg\" width=\"140\" align=\"center\"/\u003e\u003c/a\u003e\u003c/center\u003e\u003c/h1\u003e\n",
|
"# <h1><center>Tutorial <a href=\"https://colab.research.google.com/github/google-deepmind/mujoco/blob/main/python/tutorial.ipynb\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" width=\"140\" align=\"center\"/></a></center></h1>\n",
|
||||||
"\n",
|
"\n",
|
||||||
"This notebook provides an introductory tutorial for [**MuJoCo** physics](https://github.com/google-deepmind/mujoco#readme), using the native Python bindings.\n",
|
"This notebook provides an introductory tutorial for [**MuJoCo** physics](https://github.com/google-deepmind/mujoco#readme), using the native Python bindings.\n",
|
||||||
"\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\".\n",
|
"**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\".\n",
|
||||||
"\n",
|
"\n",
|
||||||
"\n",
|
"\n",
|
||||||
"\n",
|
"\n",
|
||||||
@@ -38,9 +38,9 @@
|
|||||||
"id": "_UbO9uhtBSX5"
|
"id": "_UbO9uhtBSX5"
|
||||||
},
|
},
|
||||||
"source": [
|
"source": [
|
||||||
"\u003e \u003cp\u003e\u003csmall\u003e\u003csmall\u003eCopyright 2022 DeepMind Technologies Limited.\u003c/small\u003e\u003c/p\u003e\n",
|
"> <p><small><small>Copyright 2022 DeepMind Technologies Limited.</small></p>\n",
|
||||||
"\u003e \u003cp\u003e\u003csmall\u003e\u003csmall\u003eLicensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except in compliance with the License. You may obtain a copy of the License at \u003ca href=\"http://www.apache.org/licenses/LICENSE-2.0\"\u003ehttp://www.apache.org/licenses/LICENSE-2.0\u003c/a\u003e.\u003c/small\u003e\u003c/small\u003e\u003c/p\u003e\n",
|
"> <p><small><small>Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except in compliance with the License. You may obtain a copy of the License at <a href=\"http://www.apache.org/licenses/LICENSE-2.0\">http://www.apache.org/licenses/LICENSE-2.0</a>.</small></small></p>\n",
|
||||||
"\u003e \u003cp\u003e\u003csmall\u003e\u003csmall\u003eUnless required by applicable law or agreed to in writing, software distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.\u003c/small\u003e\u003c/small\u003e\u003c/p\u003e"
|
"> <p><small><small>Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.</small></small></p>"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -107,7 +107,7 @@
|
|||||||
"try:\n",
|
"try:\n",
|
||||||
" print('Checking that the installation succeeded:')\n",
|
" print('Checking that the installation succeeded:')\n",
|
||||||
" import mujoco\n",
|
" import mujoco\n",
|
||||||
" mujoco.MjModel.from_xml_string('\u003cmujoco/\u003e')\n",
|
" mujoco.MjModel.from_xml_string('<mujoco/>')\n",
|
||||||
"except Exception as e:\n",
|
"except Exception as e:\n",
|
||||||
" raise e from RuntimeError(\n",
|
" raise e from RuntimeError(\n",
|
||||||
" 'Something went wrong during installation. Check the shell output above '\n",
|
" 'Something went wrong during installation. Check the shell output above '\n",
|
||||||
@@ -135,7 +135,7 @@
|
|||||||
"\n",
|
"\n",
|
||||||
"# Graphics and plotting.\n",
|
"# Graphics and plotting.\n",
|
||||||
"print('Installing mediapy:')\n",
|
"print('Installing mediapy:')\n",
|
||||||
"!command -v ffmpeg \u003e/dev/null || (apt update \u0026\u0026 apt install -y ffmpeg)\n",
|
"!command -v ffmpeg >/dev/null || (apt update && apt install -y ffmpeg)\n",
|
||||||
"!pip install -q mediapy\n",
|
"!pip install -q mediapy\n",
|
||||||
"import mediapy as media\n",
|
"import mediapy as media\n",
|
||||||
"import matplotlib.pyplot as plt\n",
|
"import matplotlib.pyplot as plt\n",
|
||||||
@@ -164,12 +164,12 @@
|
|||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"xml = \"\"\"\n",
|
"xml = \"\"\"\n",
|
||||||
"\u003cmujoco\u003e\n",
|
"<mujoco>\n",
|
||||||
" \u003cworldbody\u003e\n",
|
" <worldbody>\n",
|
||||||
" \u003cgeom name=\"red_box\" type=\"box\" size=\".2 .2 .2\" rgba=\"1 0 0 1\"/\u003e\n",
|
" <geom name=\"red_box\" type=\"box\" size=\".2 .2 .2\" rgba=\"1 0 0 1\"/>\n",
|
||||||
" \u003cgeom name=\"green_sphere\" pos=\".2 .2 .2\" size=\".1\" rgba=\"0 1 0 1\"/\u003e\n",
|
" <geom name=\"green_sphere\" pos=\".2 .2 .2\" size=\".1\" rgba=\"0 1 0 1\"/>\n",
|
||||||
" \u003c/worldbody\u003e\n",
|
" </worldbody>\n",
|
||||||
"\u003c/mujoco\u003e\n",
|
"</mujoco>\n",
|
||||||
"\"\"\"\n",
|
"\"\"\"\n",
|
||||||
"model = mujoco.MjModel.from_xml_string(xml)"
|
"model = mujoco.MjModel.from_xml_string(xml)"
|
||||||
]
|
]
|
||||||
@@ -181,8 +181,8 @@
|
|||||||
},
|
},
|
||||||
"source": [
|
"source": [
|
||||||
"The `xml` string is written in MuJoCo's [MJCF](http://www.mujoco.org/book/modeling.html), which is an [XML](https://en.wikipedia.org/wiki/XML#Key_terminology)-based modeling language.\n",
|
"The `xml` string is written in MuJoCo's [MJCF](http://www.mujoco.org/book/modeling.html), which is an [XML](https://en.wikipedia.org/wiki/XML#Key_terminology)-based modeling language.\n",
|
||||||
" - The only required element is `\u003cmujoco\u003e`. The smallest valid MJCF model is `\u003cmujoco/\u003e` which is a completely empty model.\n",
|
" - The only required element is `<mujoco>`. The smallest valid MJCF model is `<mujoco/>` which is a completely empty model.\n",
|
||||||
" - All physical elements live inside the `\u003cworldbody\u003e` which is always the top-level body and constitutes the global origin in Cartesian coordinates.\n",
|
" - All physical elements live inside the `<worldbody>` which is always the top-level body and constitutes the global origin in Cartesian coordinates.\n",
|
||||||
" - We define two geoms in the world named `red_box` and `green_sphere`.\n",
|
" - We define two geoms in the world named `red_box` and `green_sphere`.\n",
|
||||||
" - **Question:** The `red_box` has no position, the `green_sphere` has no type, why is that?\n",
|
" - **Question:** The `red_box` has no position, the `green_sphere` has no type, why is that?\n",
|
||||||
" - **Answer:** MJCF attributes have *default values*. The default position is `0 0 0`, the default geom type is `sphere`. The MJCF language is described in the documentation's [XML Reference chapter](https://mujoco.readthedocs.io/en/latest/XMLreference.html).\n",
|
" - **Answer:** MJCF attributes have *default values*. The default position is `0 0 0`, the default geom type is `sphere`. The MJCF language is described in the documentation's [XML Reference chapter](https://mujoco.readthedocs.io/en/latest/XMLreference.html).\n",
|
||||||
@@ -442,12 +442,12 @@
|
|||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"xml = \"\"\"\n",
|
"xml = \"\"\"\n",
|
||||||
"\u003cmujoco\u003e\n",
|
"<mujoco>\n",
|
||||||
" \u003cworldbody\u003e\n",
|
" <worldbody>\n",
|
||||||
" \u003cgeom name=\"red_box\" type=\"box\" size=\".2 .2 .2\" rgba=\"1 0 0 1\"/\u003e\n",
|
" <geom name=\"red_box\" type=\"box\" size=\".2 .2 .2\" rgba=\"1 0 0 1\"/>\n",
|
||||||
" \u003cgeom name=\"green_sphere\" pos=\".2 .2 .2\" size=\".1\" rgba=\"0 1 0 1\"/\u003e\n",
|
" <geom name=\"green_sphere\" pos=\".2 .2 .2\" size=\".1\" rgba=\"0 1 0 1\"/>\n",
|
||||||
" \u003c/worldbody\u003e\n",
|
" </worldbody>\n",
|
||||||
"\u003c/mujoco\u003e\n",
|
"</mujoco>\n",
|
||||||
"\"\"\"\n",
|
"\"\"\"\n",
|
||||||
"# Make model and data\n",
|
"# Make model and data\n",
|
||||||
"model = mujoco.MjModel.from_xml_string(xml)\n",
|
"model = mujoco.MjModel.from_xml_string(xml)\n",
|
||||||
@@ -466,7 +466,7 @@
|
|||||||
"source": [
|
"source": [
|
||||||
"Hmmm, why the black pixels?\n",
|
"Hmmm, why the black pixels?\n",
|
||||||
"\n",
|
"\n",
|
||||||
"**Answer:** For the same reason as above, we first need to propagate the values in `mjData`. This time we'll call [`mj_forward`](https://mujoco.readthedocs.io/en/latest/APIreference.html#mj-forward), which invokes the entire pipeline up to the computation of accelerations i.e., it computes $\\dot x = f(x)$, where $x$ is the state. This function does more than we actually need, but unless we care about saving computation time, it's good practice to call `mj_forward` since then we know we are not missing anything.\n",
|
"**Answer:** For the same reason as above, we first need to propagate the values in `mjData`. This time we'll call [`mj_forward`](https://mujoco.readthedocs.io/en/latest/APIreference/APIfunctions.html#mj-forward), which invokes the entire pipeline up to the computation of accelerations i.e., it computes $\\dot x = f(x)$, where $x$ is the state. This function does more than we actually need, but unless we care about saving computation time, it's good practice to call `mj_forward` since then we know we are not missing anything.\n",
|
||||||
"\n",
|
"\n",
|
||||||
"We also need to update the `mjvScene` which is an object held by the renderer describing the visual scene. We'll later see that the scene can include visual objects which are not part of the physical model."
|
"We also need to update the `mjvScene` which is an object held by the renderer describing the visual scene. We'll later see that the scene can include visual objects which are not part of the physical model."
|
||||||
]
|
]
|
||||||
@@ -503,13 +503,13 @@
|
|||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"xml = \"\"\"\n",
|
"xml = \"\"\"\n",
|
||||||
"\u003cmujoco\u003e\n",
|
"<mujoco>\n",
|
||||||
" \u003cworldbody\u003e\n",
|
" <worldbody>\n",
|
||||||
" \u003clight name=\"top\" pos=\"0 0 1\"/\u003e\n",
|
" <light name=\"top\" pos=\"0 0 1\"/>\n",
|
||||||
" \u003cgeom name=\"red_box\" type=\"box\" size=\".2 .2 .2\" rgba=\"1 0 0 1\"/\u003e\n",
|
" <geom name=\"red_box\" type=\"box\" size=\".2 .2 .2\" rgba=\"1 0 0 1\"/>\n",
|
||||||
" \u003cgeom name=\"green_sphere\" pos=\".2 .2 .2\" size=\".1\" rgba=\"0 1 0 1\"/\u003e\n",
|
" <geom name=\"green_sphere\" pos=\".2 .2 .2\" size=\".1\" rgba=\"0 1 0 1\"/>\n",
|
||||||
" \u003c/worldbody\u003e\n",
|
" </worldbody>\n",
|
||||||
"\u003c/mujoco\u003e\n",
|
"</mujoco>\n",
|
||||||
"\"\"\"\n",
|
"\"\"\"\n",
|
||||||
"model = mujoco.MjModel.from_xml_string(xml)\n",
|
"model = mujoco.MjModel.from_xml_string(xml)\n",
|
||||||
"data = mujoco.MjData(model)\n",
|
"data = mujoco.MjData(model)\n",
|
||||||
@@ -573,9 +573,9 @@
|
|||||||
"# Simulate and display video.\n",
|
"# Simulate and display video.\n",
|
||||||
"frames = []\n",
|
"frames = []\n",
|
||||||
"mujoco.mj_resetData(model, data) # Reset state and time.\n",
|
"mujoco.mj_resetData(model, data) # Reset state and time.\n",
|
||||||
"while data.time \u003c duration:\n",
|
"while data.time < duration:\n",
|
||||||
" mujoco.mj_step(model, data)\n",
|
" mujoco.mj_step(model, data)\n",
|
||||||
" if len(frames) \u003c data.time * framerate:\n",
|
" if len(frames) < data.time * framerate:\n",
|
||||||
" renderer.update_scene(data)\n",
|
" renderer.update_scene(data)\n",
|
||||||
" pixels = renderer.render()\n",
|
" pixels = renderer.render()\n",
|
||||||
" frames.append(pixels)\n",
|
" frames.append(pixels)\n",
|
||||||
@@ -590,7 +590,7 @@
|
|||||||
"source": [
|
"source": [
|
||||||
"Hmmm, the video is playing, but nothing is moving, why is that?\n",
|
"Hmmm, the video is playing, but nothing is moving, why is that?\n",
|
||||||
"\n",
|
"\n",
|
||||||
"This is because this model has no [degrees of freedom](https://www.google.com/url?sa=D\u0026q=https%3A%2F%2Fen.wikipedia.org%2Fwiki%2FDegrees_of_freedom_(mechanics)) (DoFs). The things that move (and which have inertia) are called *bodies*. We add DoFs by adding *joints* to bodies, specifying how they can move with respect to their parents. Let's make a new body that contains our geoms, add a hinge joint and re-render, while visualizing the joint axis using the visualization option object `MjvOption`."
|
"This is because this model has no [degrees of freedom](https://www.google.com/url?sa=D&q=https%3A%2F%2Fen.wikipedia.org%2Fwiki%2FDegrees_of_freedom_(mechanics)) (DoFs). The things that move (and which have inertia) are called *bodies*. We add DoFs by adding *joints* to bodies, specifying how they can move with respect to their parents. Let's make a new body that contains our geoms, add a hinge joint and re-render, while visualizing the joint axis using the visualization option object `MjvOption`."
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -602,16 +602,16 @@
|
|||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"xml = \"\"\"\n",
|
"xml = \"\"\"\n",
|
||||||
"\u003cmujoco\u003e\n",
|
"<mujoco>\n",
|
||||||
" \u003cworldbody\u003e\n",
|
" <worldbody>\n",
|
||||||
" \u003clight name=\"top\" pos=\"0 0 1\"/\u003e\n",
|
" <light name=\"top\" pos=\"0 0 1\"/>\n",
|
||||||
" \u003cbody name=\"box_and_sphere\" euler=\"0 0 -30\"\u003e\n",
|
" <body name=\"box_and_sphere\" euler=\"0 0 -30\">\n",
|
||||||
" \u003cjoint name=\"swing\" type=\"hinge\" axis=\"1 -1 0\" pos=\"-.2 -.2 -.2\"/\u003e\n",
|
" <joint name=\"swing\" type=\"hinge\" axis=\"1 -1 0\" pos=\"-.2 -.2 -.2\"/>\n",
|
||||||
" \u003cgeom name=\"red_box\" type=\"box\" size=\".2 .2 .2\" rgba=\"1 0 0 1\"/\u003e\n",
|
" <geom name=\"red_box\" type=\"box\" size=\".2 .2 .2\" rgba=\"1 0 0 1\"/>\n",
|
||||||
" \u003cgeom name=\"green_sphere\" pos=\".2 .2 .2\" size=\".1\" rgba=\"0 1 0 1\"/\u003e\n",
|
" <geom name=\"green_sphere\" pos=\".2 .2 .2\" size=\".1\" rgba=\"0 1 0 1\"/>\n",
|
||||||
" \u003c/body\u003e\n",
|
" </body>\n",
|
||||||
" \u003c/worldbody\u003e\n",
|
" </worldbody>\n",
|
||||||
"\u003c/mujoco\u003e\n",
|
"</mujoco>\n",
|
||||||
"\"\"\"\n",
|
"\"\"\"\n",
|
||||||
"model = mujoco.MjModel.from_xml_string(xml)\n",
|
"model = mujoco.MjModel.from_xml_string(xml)\n",
|
||||||
"data = mujoco.MjData(model)\n",
|
"data = mujoco.MjData(model)\n",
|
||||||
@@ -626,9 +626,9 @@
|
|||||||
"\n",
|
"\n",
|
||||||
"frames = []\n",
|
"frames = []\n",
|
||||||
"mujoco.mj_resetData(model, data)\n",
|
"mujoco.mj_resetData(model, data)\n",
|
||||||
"while data.time \u003c duration:\n",
|
"while data.time < duration:\n",
|
||||||
" mujoco.mj_step(model, data)\n",
|
" mujoco.mj_step(model, data)\n",
|
||||||
" if len(frames) \u003c data.time * framerate:\n",
|
" if len(frames) < data.time * framerate:\n",
|
||||||
" renderer.update_scene(data, scene_option=scene_option)\n",
|
" renderer.update_scene(data, scene_option=scene_option)\n",
|
||||||
" pixels = renderer.render()\n",
|
" pixels = renderer.render()\n",
|
||||||
" frames.append(pixels)\n",
|
" frames.append(pixels)\n",
|
||||||
@@ -643,7 +643,7 @@
|
|||||||
"id": "Ymv-tvWCpl6V"
|
"id": "Ymv-tvWCpl6V"
|
||||||
},
|
},
|
||||||
"source": [
|
"source": [
|
||||||
"Note that we rotated the `box_and_sphere` body by 30° around the Z (vertical) axis, with the directive `euler=\"0 0 -30\"`. This was made to emphasize that the poses of elements in the [kinematic tree](https://www.google.com/url?sa=D\u0026q=https%3A%2F%2Fen.wikipedia.org%2Fwiki%2FKinematic_chain) are always with respect to their *parent body*, so our two geoms were also rotated by this transformation.\n",
|
"Note that we rotated the `box_and_sphere` body by 30° around the Z (vertical) axis, with the directive `euler=\"0 0 -30\"`. This was made to emphasize that the poses of elements in the [kinematic tree](https://www.google.com/url?sa=D&q=https%3A%2F%2Fen.wikipedia.org%2Fwiki%2FKinematic_chain) are always with respect to their *parent body*, so our two geoms were also rotated by this transformation.\n",
|
||||||
"\n",
|
"\n",
|
||||||
"Physics options live in `mjModel.opt`, for example the timestep:"
|
"Physics options live in `mjModel.opt`, for example the timestep:"
|
||||||
]
|
]
|
||||||
@@ -682,9 +682,9 @@
|
|||||||
"\n",
|
"\n",
|
||||||
"frames = []\n",
|
"frames = []\n",
|
||||||
"mujoco.mj_resetData(model, data)\n",
|
"mujoco.mj_resetData(model, data)\n",
|
||||||
"while data.time \u003c duration:\n",
|
"while data.time < duration:\n",
|
||||||
" mujoco.mj_step(model, data)\n",
|
" mujoco.mj_step(model, data)\n",
|
||||||
" if len(frames) \u003c data.time * framerate:\n",
|
" if len(frames) < data.time * framerate:\n",
|
||||||
" renderer.update_scene(data, scene_option=scene_option)\n",
|
" renderer.update_scene(data, scene_option=scene_option)\n",
|
||||||
" pixels = renderer.render()\n",
|
" pixels = renderer.render()\n",
|
||||||
" frames.append(pixels)\n",
|
" frames.append(pixels)\n",
|
||||||
@@ -698,12 +698,12 @@
|
|||||||
"id": "FsxDDgXBqg_J"
|
"id": "FsxDDgXBqg_J"
|
||||||
},
|
},
|
||||||
"source": [
|
"source": [
|
||||||
"We could also have done this in XML using the top-level `\u003coption\u003e` element:\n",
|
"We could also have done this in XML using the top-level `<option>` element:\n",
|
||||||
"```xml\n",
|
"```xml\n",
|
||||||
"\u003cmujoco\u003e\n",
|
"<mujoco>\n",
|
||||||
" \u003coption gravity=\"0 0 10\"/\u003e\n",
|
" <option gravity=\"0 0 10\"/>\n",
|
||||||
" ...\n",
|
" ...\n",
|
||||||
"\u003c/mujoco\u003e\n",
|
"</mujoco>\n",
|
||||||
"```"
|
"```"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -750,7 +750,7 @@
|
|||||||
"source": [
|
"source": [
|
||||||
"# Example: Simulating free bodies with the self-inverting \"tippe-top\"\n",
|
"# Example: Simulating free bodies with the self-inverting \"tippe-top\"\n",
|
||||||
"\n",
|
"\n",
|
||||||
"A free body is a body with a [free joint](https://www.google.com/url?sa=D\u0026q=https%3A%2F%2Fmujoco.readthedocs.io%2Fen%2Flatest%2FXMLreference.html%3Fhighlight%3Dfreejoint%23body-freejoint) having 6 DoFs, i.e., 3 translations and 3 rotations. We could give our `box_and_sphere` body a free joint and watch it fall, but let's look at something more interesting. A \"tippe top\" is a spinning toy which flips itself ([video](https://www.youtube.com/watch?v=kbYpVrdcszQ), [Wikipedia](https://en.wikipedia.org/wiki/Tippe_top)). We model it as follows:"
|
"A free body is a body with a [free joint](https://www.google.com/url?sa=D&q=https%3A%2F%2Fmujoco.readthedocs.io%2Fen%2Flatest%2FXMLreference.html%3Fhighlight%3Dfreejoint%23body-freejoint) having 6 DoFs, i.e., 3 translations and 3 rotations. We could give our `box_and_sphere` body a free joint and watch it fall, but let's look at something more interesting. A \"tippe top\" is a spinning toy which flips itself ([video](https://www.youtube.com/watch?v=kbYpVrdcszQ), [Wikipedia](https://en.wikipedia.org/wiki/Tippe_top)). We model it as follows:"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -762,32 +762,32 @@
|
|||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"tippe_top = \"\"\"\n",
|
"tippe_top = \"\"\"\n",
|
||||||
"\u003cmujoco model=\"tippe top\"\u003e\n",
|
"<mujoco model=\"tippe top\">\n",
|
||||||
" \u003coption integrator=\"RK4\"/\u003e\n",
|
" <option integrator=\"RK4\"/>\n",
|
||||||
"\n",
|
"\n",
|
||||||
" \u003casset\u003e\n",
|
" <asset>\n",
|
||||||
" \u003ctexture name=\"grid\" type=\"2d\" builtin=\"checker\" rgb1=\".1 .2 .3\"\n",
|
" <texture name=\"grid\" type=\"2d\" builtin=\"checker\" rgb1=\".1 .2 .3\"\n",
|
||||||
" rgb2=\".2 .3 .4\" width=\"300\" height=\"300\"/\u003e\n",
|
" rgb2=\".2 .3 .4\" width=\"300\" height=\"300\"/>\n",
|
||||||
" \u003cmaterial name=\"grid\" texture=\"grid\" texrepeat=\"8 8\" reflectance=\".2\"/\u003e\n",
|
" <material name=\"grid\" texture=\"grid\" texrepeat=\"8 8\" reflectance=\".2\"/>\n",
|
||||||
" \u003c/asset\u003e\n",
|
" </asset>\n",
|
||||||
"\n",
|
"\n",
|
||||||
" \u003cworldbody\u003e\n",
|
" <worldbody>\n",
|
||||||
" \u003cgeom size=\".2 .2 .01\" type=\"plane\" material=\"grid\"/\u003e\n",
|
" <geom size=\".2 .2 .01\" type=\"plane\" material=\"grid\"/>\n",
|
||||||
" \u003clight pos=\"0 0 .6\"/\u003e\n",
|
" <light pos=\"0 0 .6\"/>\n",
|
||||||
" \u003ccamera name=\"closeup\" pos=\"0 -.1 .07\" xyaxes=\"1 0 0 0 1 2\"/\u003e\n",
|
" <camera name=\"closeup\" pos=\"0 -.1 .07\" xyaxes=\"1 0 0 0 1 2\"/>\n",
|
||||||
" \u003cbody name=\"top\" pos=\"0 0 .02\"\u003e\n",
|
" <body name=\"top\" pos=\"0 0 .02\">\n",
|
||||||
" \u003cfreejoint/\u003e\n",
|
" <freejoint/>\n",
|
||||||
" \u003cgeom name=\"ball\" type=\"sphere\" size=\".02\" /\u003e\n",
|
" <geom name=\"ball\" type=\"sphere\" size=\".02\" />\n",
|
||||||
" \u003cgeom name=\"stem\" type=\"cylinder\" pos=\"0 0 .02\" size=\"0.004 .008\"/\u003e\n",
|
" <geom name=\"stem\" type=\"cylinder\" pos=\"0 0 .02\" size=\"0.004 .008\"/>\n",
|
||||||
" \u003cgeom name=\"ballast\" type=\"box\" size=\".023 .023 0.005\" pos=\"0 0 -.015\"\n",
|
" <geom name=\"ballast\" type=\"box\" size=\".023 .023 0.005\" pos=\"0 0 -.015\"\n",
|
||||||
" contype=\"0\" conaffinity=\"0\" group=\"3\"/\u003e\n",
|
" contype=\"0\" conaffinity=\"0\" group=\"3\"/>\n",
|
||||||
" \u003c/body\u003e\n",
|
" </body>\n",
|
||||||
" \u003c/worldbody\u003e\n",
|
" </worldbody>\n",
|
||||||
"\n",
|
"\n",
|
||||||
" \u003ckeyframe\u003e\n",
|
" <keyframe>\n",
|
||||||
" \u003ckey name=\"spinning\" qpos=\"0 0 0.02 1 0 0 0\" qvel=\"0 0 0 0 1 200\" /\u003e\n",
|
" <key name=\"spinning\" qpos=\"0 0 0.02 1 0 0 0\" qvel=\"0 0 0 0 1 200\" />\n",
|
||||||
" \u003c/keyframe\u003e\n",
|
" </keyframe>\n",
|
||||||
"\u003c/mujoco\u003e\n",
|
"</mujoco>\n",
|
||||||
"\"\"\"\n",
|
"\"\"\"\n",
|
||||||
"model = mujoco.MjModel.from_xml_string(tippe_top)\n",
|
"model = mujoco.MjModel.from_xml_string(tippe_top)\n",
|
||||||
"renderer = mujoco.Renderer(model)\n",
|
"renderer = mujoco.Renderer(model)\n",
|
||||||
@@ -804,12 +804,12 @@
|
|||||||
},
|
},
|
||||||
"source": [
|
"source": [
|
||||||
"Note several new features of this model definition:\n",
|
"Note several new features of this model definition:\n",
|
||||||
"1. A 6-DoF free joint is added with the `\u003cfreejoint/\u003e` clause.\n",
|
"1. A 6-DoF free joint is added with the `<freejoint/>` clause.\n",
|
||||||
"2. We use the `\u003coption/\u003e` clause to set the integrator to the 4th order [Runge Kutta](https://en.wikipedia.org/wiki/Runge%E2%80%93Kutta_methods). Runge-Kutta has a higher rate of convergence than the default Euler integrator, which in many cases increases the accuracy at a given timestep size.\n",
|
"2. We use the `<option/>` clause to set the integrator to the 4th order [Runge Kutta](https://en.wikipedia.org/wiki/Runge%E2%80%93Kutta_methods). Runge-Kutta has a higher rate of convergence than the default Euler integrator, which in many cases increases the accuracy at a given timestep size.\n",
|
||||||
"3. We define the floor's grid material inside the `\u003casset/\u003e` clause and reference it in the `\"floor\"` geom.\n",
|
"3. We define the floor's grid material inside the `<asset/>` clause and reference it in the `\"floor\"` geom.\n",
|
||||||
"4. 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 behavior to occur.\n",
|
"4. 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 behavior to occur.\n",
|
||||||
"5. 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, which introduces the symmetry-breaking required for the flipping.\n",
|
"5. 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, which introduces the symmetry-breaking required for the flipping.\n",
|
||||||
"6. We define a `\u003ccamera\u003e` in our model, and then render from it using the `camera` argument to `update_scene()`.\n",
|
"6. We define a `<camera>` in our model, and then render from it using the `camera` argument to `update_scene()`.\n",
|
||||||
"Let us examine the state:\n"
|
"Let us examine the state:\n"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -850,9 +850,9 @@
|
|||||||
"# Simulate and display video.\n",
|
"# Simulate and display video.\n",
|
||||||
"frames = []\n",
|
"frames = []\n",
|
||||||
"mujoco.mj_resetDataKeyframe(model, data, 0) # Reset the state to keyframe 0\n",
|
"mujoco.mj_resetDataKeyframe(model, data, 0) # Reset the state to keyframe 0\n",
|
||||||
"while data.time \u003c duration:\n",
|
"while data.time < duration:\n",
|
||||||
" mujoco.mj_step(model, data)\n",
|
" mujoco.mj_step(model, data)\n",
|
||||||
" if len(frames) \u003c data.time * framerate:\n",
|
" if len(frames) < data.time * framerate:\n",
|
||||||
" renderer.update_scene(data, \"closeup\")\n",
|
" renderer.update_scene(data, \"closeup\")\n",
|
||||||
" pixels = renderer.render()\n",
|
" pixels = renderer.render()\n",
|
||||||
" frames.append(pixels)\n",
|
" frames.append(pixels)\n",
|
||||||
@@ -884,7 +884,7 @@
|
|||||||
"\n",
|
"\n",
|
||||||
"# Simulate and save data\n",
|
"# Simulate and save data\n",
|
||||||
"mujoco.mj_resetDataKeyframe(model, data, 0)\n",
|
"mujoco.mj_resetDataKeyframe(model, data, 0)\n",
|
||||||
"while data.time \u003c duration:\n",
|
"while data.time < duration:\n",
|
||||||
" mujoco.mj_step(model, data)\n",
|
" mujoco.mj_step(model, data)\n",
|
||||||
" timevals.append(data.time)\n",
|
" timevals.append(data.time)\n",
|
||||||
" angular_velocity.append(data.qvel[3:6].copy())\n",
|
" angular_velocity.append(data.qvel[3:6].copy())\n",
|
||||||
@@ -933,38 +933,38 @@
|
|||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"chaotic_pendulum = \"\"\"\n",
|
"chaotic_pendulum = \"\"\"\n",
|
||||||
"\u003cmujoco\u003e\n",
|
"<mujoco>\n",
|
||||||
" \u003coption timestep=\".001\"\u003e\n",
|
" <option timestep=\".001\">\n",
|
||||||
" \u003cflag energy=\"enable\" contact=\"disable\"/\u003e\n",
|
" <flag energy=\"enable\" contact=\"disable\"/>\n",
|
||||||
" \u003c/option\u003e\n",
|
" </option>\n",
|
||||||
"\n",
|
"\n",
|
||||||
" \u003cdefault\u003e\n",
|
" <default>\n",
|
||||||
" \u003cjoint type=\"hinge\" axis=\"0 -1 0\"/\u003e\n",
|
" <joint type=\"hinge\" axis=\"0 -1 0\"/>\n",
|
||||||
" \u003cgeom type=\"capsule\" size=\".02\"/\u003e\n",
|
" <geom type=\"capsule\" size=\".02\"/>\n",
|
||||||
" \u003c/default\u003e\n",
|
" </default>\n",
|
||||||
"\n",
|
"\n",
|
||||||
" \u003cworldbody\u003e\n",
|
" <worldbody>\n",
|
||||||
" \u003clight pos=\"0 -.4 1\"/\u003e\n",
|
" <light pos=\"0 -.4 1\"/>\n",
|
||||||
" \u003ccamera name=\"fixed\" pos=\"0 -1 0\" xyaxes=\"1 0 0 0 0 1\"/\u003e\n",
|
" <camera name=\"fixed\" pos=\"0 -1 0\" xyaxes=\"1 0 0 0 0 1\"/>\n",
|
||||||
" \u003cbody name=\"0\" pos=\"0 0 .2\"\u003e\n",
|
" <body name=\"0\" pos=\"0 0 .2\">\n",
|
||||||
" \u003cjoint name=\"root\"/\u003e\n",
|
" <joint name=\"root\"/>\n",
|
||||||
" \u003cgeom fromto=\"-.2 0 0 .2 0 0\" rgba=\"1 1 0 1\"/\u003e\n",
|
" <geom fromto=\"-.2 0 0 .2 0 0\" rgba=\"1 1 0 1\"/>\n",
|
||||||
" \u003cgeom fromto=\"0 0 0 0 0 -.25\" rgba=\"1 1 0 1\"/\u003e\n",
|
" <geom fromto=\"0 0 0 0 0 -.25\" rgba=\"1 1 0 1\"/>\n",
|
||||||
" \u003cbody name=\"1\" pos=\"-.2 0 0\"\u003e\n",
|
" <body name=\"1\" pos=\"-.2 0 0\">\n",
|
||||||
" \u003cjoint/\u003e\n",
|
" <joint/>\n",
|
||||||
" \u003cgeom fromto=\"0 0 0 0 0 -.2\" rgba=\"1 0 0 1\"/\u003e\n",
|
" <geom fromto=\"0 0 0 0 0 -.2\" rgba=\"1 0 0 1\"/>\n",
|
||||||
" \u003c/body\u003e\n",
|
" </body>\n",
|
||||||
" \u003cbody name=\"2\" pos=\".2 0 0\"\u003e\n",
|
" <body name=\"2\" pos=\".2 0 0\">\n",
|
||||||
" \u003cjoint/\u003e\n",
|
" <joint/>\n",
|
||||||
" \u003cgeom fromto=\"0 0 0 0 0 -.2\" rgba=\"0 1 0 1\"/\u003e\n",
|
" <geom fromto=\"0 0 0 0 0 -.2\" rgba=\"0 1 0 1\"/>\n",
|
||||||
" \u003c/body\u003e\n",
|
" </body>\n",
|
||||||
" \u003cbody name=\"3\" pos=\"0 0 -.25\"\u003e\n",
|
" <body name=\"3\" pos=\"0 0 -.25\">\n",
|
||||||
" \u003cjoint/\u003e\n",
|
" <joint/>\n",
|
||||||
" \u003cgeom fromto=\"0 0 0 0 0 -.2\" rgba=\"0 0 1 1\"/\u003e\n",
|
" <geom fromto=\"0 0 0 0 0 -.2\" rgba=\"0 0 1 1\"/>\n",
|
||||||
" \u003c/body\u003e\n",
|
" </body>\n",
|
||||||
" \u003c/body\u003e\n",
|
" </body>\n",
|
||||||
" \u003c/worldbody\u003e\n",
|
" </worldbody>\n",
|
||||||
"\u003c/mujoco\u003e\n",
|
"</mujoco>\n",
|
||||||
"\"\"\"\n",
|
"\"\"\"\n",
|
||||||
"model = mujoco.MjModel.from_xml_string(chaotic_pendulum)\n",
|
"model = mujoco.MjModel.from_xml_string(chaotic_pendulum)\n",
|
||||||
"renderer = mujoco.Renderer(model, 480, 640)\n",
|
"renderer = mujoco.Renderer(model, 480, 640)\n",
|
||||||
@@ -1011,7 +1011,7 @@
|
|||||||
"render_time = 0\n",
|
"render_time = 0\n",
|
||||||
"n_steps = 0\n",
|
"n_steps = 0\n",
|
||||||
"for i in range(n_frames):\n",
|
"for i in range(n_frames):\n",
|
||||||
" while data.time * framerate \u003c i:\n",
|
" while data.time * framerate < i:\n",
|
||||||
" tic = time.time()\n",
|
" tic = time.time()\n",
|
||||||
" mujoco.mj_step(model, data)\n",
|
" mujoco.mj_step(model, data)\n",
|
||||||
" sim_time += time.time() - tic\n",
|
" sim_time += time.time() - tic\n",
|
||||||
@@ -1240,26 +1240,26 @@
|
|||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"free_body_MJCF = \"\"\"\n",
|
"free_body_MJCF = \"\"\"\n",
|
||||||
"\u003cmujoco\u003e\n",
|
"<mujoco>\n",
|
||||||
" \u003casset\u003e\n",
|
" <asset>\n",
|
||||||
" \u003ctexture name=\"grid\" type=\"2d\" builtin=\"checker\" rgb1=\".1 .2 .3\"\n",
|
" <texture 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",
|
" rgb2=\".2 .3 .4\" width=\"300\" height=\"300\" mark=\"edge\" markrgb=\".2 .3 .4\"/>\n",
|
||||||
" \u003cmaterial name=\"grid\" texture=\"grid\" texrepeat=\"2 2\" texuniform=\"true\"\n",
|
" <material name=\"grid\" texture=\"grid\" texrepeat=\"2 2\" texuniform=\"true\"\n",
|
||||||
" reflectance=\".2\"/\u003e\n",
|
" reflectance=\".2\"/>\n",
|
||||||
" \u003c/asset\u003e\n",
|
" </asset>\n",
|
||||||
"\n",
|
"\n",
|
||||||
" \u003cworldbody\u003e\n",
|
" <worldbody>\n",
|
||||||
" \u003clight pos=\"0 0 1\" mode=\"trackcom\"/\u003e\n",
|
" <light pos=\"0 0 1\" mode=\"trackcom\"/>\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",
|
" <geom name=\"ground\" type=\"plane\" pos=\"0 0 -.5\" size=\"2 2 .1\" material=\"grid\" solimp=\".99 .99 .01\" solref=\".001 1\"/>\n",
|
||||||
" \u003cbody name=\"box_and_sphere\" pos=\"0 0 0\"\u003e\n",
|
" <body name=\"box_and_sphere\" pos=\"0 0 0\">\n",
|
||||||
" \u003cfreejoint/\u003e\n",
|
" <freejoint/>\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",
|
" <geom name=\"red_box\" type=\"box\" size=\".1 .1 .1\" rgba=\"1 0 0 1\" solimp=\".99 .99 .01\" solref=\".001 1\"/>\n",
|
||||||
" \u003cgeom name=\"green_sphere\" size=\".06\" pos=\".1 .1 .1\" rgba=\"0 1 0 1\"/\u003e\n",
|
" <geom name=\"green_sphere\" size=\".06\" pos=\".1 .1 .1\" rgba=\"0 1 0 1\"/>\n",
|
||||||
" \u003ccamera name=\"fixed\" pos=\"0 -.6 .3\" xyaxes=\"1 0 0 0 1 2\"/\u003e\n",
|
" <camera name=\"fixed\" pos=\"0 -.6 .3\" xyaxes=\"1 0 0 0 1 2\"/>\n",
|
||||||
" \u003ccamera name=\"track\" pos=\"0 -.6 .3\" xyaxes=\"1 0 0 0 1 2\" mode=\"track\"/\u003e\n",
|
" <camera name=\"track\" pos=\"0 -.6 .3\" xyaxes=\"1 0 0 0 1 2\" mode=\"track\"/>\n",
|
||||||
" \u003c/body\u003e\n",
|
" </body>\n",
|
||||||
" \u003c/worldbody\u003e\n",
|
" </worldbody>\n",
|
||||||
"\u003c/mujoco\u003e\n",
|
"</mujoco>\n",
|
||||||
"\"\"\"\n",
|
"\"\"\"\n",
|
||||||
"model = mujoco.MjModel.from_xml_string(free_body_MJCF)\n",
|
"model = mujoco.MjModel.from_xml_string(free_body_MJCF)\n",
|
||||||
"renderer = mujoco.Renderer(model, 400, 600)\n",
|
"renderer = mujoco.Renderer(model, 400, 600)\n",
|
||||||
@@ -1311,7 +1311,7 @@
|
|||||||
"\n",
|
"\n",
|
||||||
"# simulate and render\n",
|
"# simulate and render\n",
|
||||||
"for i in range(n_frames):\n",
|
"for i in range(n_frames):\n",
|
||||||
" while data.time \u003c i/120.0: #1/4x real time\n",
|
" while data.time < i/120.0: #1/4x real time\n",
|
||||||
" mujoco.mj_step(model, data)\n",
|
" mujoco.mj_step(model, data)\n",
|
||||||
" renderer.update_scene(data, \"track\", options)\n",
|
" renderer.update_scene(data, \"track\", options)\n",
|
||||||
" frame = renderer.render()\n",
|
" frame = renderer.render()\n",
|
||||||
@@ -1430,36 +1430,36 @@
|
|||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"MJCF = \"\"\"\n",
|
"MJCF = \"\"\"\n",
|
||||||
"\u003cmujoco\u003e\n",
|
"<mujoco>\n",
|
||||||
" \u003casset\u003e\n",
|
" <asset>\n",
|
||||||
" \u003ctexture name=\"grid\" type=\"2d\" builtin=\"checker\" rgb1=\".1 .2 .3\"\n",
|
" <texture name=\"grid\" type=\"2d\" builtin=\"checker\" rgb1=\".1 .2 .3\"\n",
|
||||||
" rgb2=\".2 .3 .4\" width=\"300\" height=\"300\" mark=\"none\"/\u003e\n",
|
" rgb2=\".2 .3 .4\" width=\"300\" height=\"300\" mark=\"none\"/>\n",
|
||||||
" \u003cmaterial name=\"grid\" texture=\"grid\" texrepeat=\"6 6\"\n",
|
" <material name=\"grid\" texture=\"grid\" texrepeat=\"6 6\"\n",
|
||||||
" texuniform=\"true\" reflectance=\".2\"/\u003e\n",
|
" texuniform=\"true\" reflectance=\".2\"/>\n",
|
||||||
" \u003cmaterial name=\"wall\" rgba='.5 .5 .5 1'/\u003e\n",
|
" <material name=\"wall\" rgba='.5 .5 .5 1'/>\n",
|
||||||
" \u003c/asset\u003e\n",
|
" </asset>\n",
|
||||||
"\n",
|
"\n",
|
||||||
" \u003cdefault\u003e\n",
|
" <default>\n",
|
||||||
" \u003cgeom type=\"box\" size=\".05 .05 .05\" /\u003e\n",
|
" <geom type=\"box\" size=\".05 .05 .05\" />\n",
|
||||||
" \u003cjoint type=\"free\"/\u003e\n",
|
" <joint type=\"free\"/>\n",
|
||||||
" \u003c/default\u003e\n",
|
" </default>\n",
|
||||||
"\n",
|
"\n",
|
||||||
" \u003cworldbody\u003e\n",
|
" <worldbody>\n",
|
||||||
" \u003clight name=\"light\" pos=\"-.2 0 1\"/\u003e\n",
|
" <light name=\"light\" pos=\"-.2 0 1\"/>\n",
|
||||||
" \u003cgeom name=\"ground\" type=\"plane\" size=\".5 .5 10\" material=\"grid\"\n",
|
" <geom name=\"ground\" type=\"plane\" size=\".5 .5 10\" material=\"grid\"\n",
|
||||||
" zaxis=\"-.3 0 1\" friction=\".1\"/\u003e\n",
|
" zaxis=\"-.3 0 1\" friction=\".1\"/>\n",
|
||||||
" \u003ccamera name=\"y\" pos=\"-.1 -.6 .3\" xyaxes=\"1 0 0 0 1 2\"/\u003e\n",
|
" <camera name=\"y\" pos=\"-.1 -.6 .3\" xyaxes=\"1 0 0 0 1 2\"/>\n",
|
||||||
" \u003cbody pos=\"0 0 .1\"\u003e\n",
|
" <body pos=\"0 0 .1\">\n",
|
||||||
" \u003cjoint/\u003e\n",
|
" <joint/>\n",
|
||||||
" \u003cgeom/\u003e\n",
|
" <geom/>\n",
|
||||||
" \u003c/body\u003e\n",
|
" </body>\n",
|
||||||
" \u003cbody pos=\"0 .2 .1\"\u003e\n",
|
" <body pos=\"0 .2 .1\">\n",
|
||||||
" \u003cjoint/\u003e\n",
|
" <joint/>\n",
|
||||||
" \u003cgeom friction=\".33\"/\u003e\n",
|
" <geom friction=\".33\"/>\n",
|
||||||
" \u003c/body\u003e\n",
|
" </body>\n",
|
||||||
" \u003c/worldbody\u003e\n",
|
" </worldbody>\n",
|
||||||
"\n",
|
"\n",
|
||||||
"\u003c/mujoco\u003e\n",
|
"</mujoco>\n",
|
||||||
"\"\"\"\n",
|
"\"\"\"\n",
|
||||||
"n_frames = 60\n",
|
"n_frames = 60\n",
|
||||||
"height = 300\n",
|
"height = 300\n",
|
||||||
@@ -1474,7 +1474,7 @@
|
|||||||
"# simulate and render\n",
|
"# simulate and render\n",
|
||||||
"mujoco.mj_resetData(model, data)\n",
|
"mujoco.mj_resetData(model, data)\n",
|
||||||
"for i in range(n_frames):\n",
|
"for i in range(n_frames):\n",
|
||||||
" while data.time \u003c i/30.0:\n",
|
" while data.time < i/30.0:\n",
|
||||||
" mujoco.mj_step(model, data)\n",
|
" mujoco.mj_step(model, data)\n",
|
||||||
" renderer.update_scene(data, \"y\")\n",
|
" renderer.update_scene(data, \"y\")\n",
|
||||||
" frame = renderer.render()\n",
|
" frame = renderer.render()\n",
|
||||||
@@ -1500,51 +1500,51 @@
|
|||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"MJCF = \"\"\"\n",
|
"MJCF = \"\"\"\n",
|
||||||
"\u003cmujoco\u003e\n",
|
"<mujoco>\n",
|
||||||
" \u003casset\u003e\n",
|
" <asset>\n",
|
||||||
" \u003ctexture name=\"grid\" type=\"2d\" builtin=\"checker\" rgb1=\".1 .2 .3\"\n",
|
" <texture name=\"grid\" type=\"2d\" builtin=\"checker\" rgb1=\".1 .2 .3\"\n",
|
||||||
" rgb2=\".2 .3 .4\" width=\"300\" height=\"300\" mark=\"none\"/\u003e\n",
|
" rgb2=\".2 .3 .4\" width=\"300\" height=\"300\" mark=\"none\"/>\n",
|
||||||
" \u003cmaterial name=\"grid\" texture=\"grid\" texrepeat=\"1 1\"\n",
|
" <material name=\"grid\" texture=\"grid\" texrepeat=\"1 1\"\n",
|
||||||
" texuniform=\"true\" reflectance=\".2\"/\u003e\n",
|
" texuniform=\"true\" reflectance=\".2\"/>\n",
|
||||||
" \u003c/asset\u003e\n",
|
" </asset>\n",
|
||||||
"\n",
|
"\n",
|
||||||
" \u003cworldbody\u003e\n",
|
" <worldbody>\n",
|
||||||
" \u003clight name=\"light\" pos=\"0 0 1\"/\u003e\n",
|
" <light name=\"light\" pos=\"0 0 1\"/>\n",
|
||||||
" \u003cgeom name=\"floor\" type=\"plane\" pos=\"0 0 -.5\" size=\"2 2 .1\" material=\"grid\"/\u003e\n",
|
" <geom name=\"floor\" type=\"plane\" pos=\"0 0 -.5\" size=\"2 2 .1\" material=\"grid\"/>\n",
|
||||||
" \u003csite name=\"anchor\" pos=\"0 0 .3\" size=\".01\"/\u003e\n",
|
" <site name=\"anchor\" pos=\"0 0 .3\" size=\".01\"/>\n",
|
||||||
" \u003ccamera name=\"fixed\" pos=\"0 -1.3 .5\" xyaxes=\"1 0 0 0 1 2\"/\u003e\n",
|
" <camera name=\"fixed\" pos=\"0 -1.3 .5\" xyaxes=\"1 0 0 0 1 2\"/>\n",
|
||||||
"\n",
|
"\n",
|
||||||
" \u003cgeom name=\"pole\" type=\"cylinder\" fromto=\".3 0 -.5 .3 0 -.1\" size=\".04\"/\u003e\n",
|
" <geom name=\"pole\" type=\"cylinder\" fromto=\".3 0 -.5 .3 0 -.1\" size=\".04\"/>\n",
|
||||||
" \u003cbody name=\"bat\" pos=\".3 0 -.1\"\u003e\n",
|
" <body name=\"bat\" pos=\".3 0 -.1\">\n",
|
||||||
" \u003cjoint name=\"swing\" type=\"hinge\" damping=\"1\" axis=\"0 0 1\"/\u003e\n",
|
" <joint name=\"swing\" type=\"hinge\" damping=\"1\" axis=\"0 0 1\"/>\n",
|
||||||
" \u003cgeom name=\"bat\" type=\"capsule\" fromto=\"0 0 .04 0 -.3 .04\"\n",
|
" <geom name=\"bat\" type=\"capsule\" fromto=\"0 0 .04 0 -.3 .04\"\n",
|
||||||
" size=\".04\" rgba=\"0 0 1 1\"/\u003e\n",
|
" size=\".04\" rgba=\"0 0 1 1\"/>\n",
|
||||||
" \u003c/body\u003e\n",
|
" </body>\n",
|
||||||
"\n",
|
"\n",
|
||||||
" \u003cbody name=\"box_and_sphere\" pos=\"0 0 0\"\u003e\n",
|
" <body name=\"box_and_sphere\" pos=\"0 0 0\">\n",
|
||||||
" \u003cjoint name=\"free\" type=\"free\"/\u003e\n",
|
" <joint name=\"free\" type=\"free\"/>\n",
|
||||||
" \u003cgeom name=\"red_box\" type=\"box\" size=\".1 .1 .1\" rgba=\"1 0 0 1\"/\u003e\n",
|
" <geom name=\"red_box\" type=\"box\" size=\".1 .1 .1\" rgba=\"1 0 0 1\"/>\n",
|
||||||
" \u003cgeom name=\"green_sphere\" size=\".06\" pos=\".1 .1 .1\" rgba=\"0 1 0 1\"/\u003e\n",
|
" <geom name=\"green_sphere\" size=\".06\" pos=\".1 .1 .1\" rgba=\"0 1 0 1\"/>\n",
|
||||||
" \u003csite name=\"hook\" pos=\"-.1 -.1 -.1\" size=\".01\"/\u003e\n",
|
" <site name=\"hook\" pos=\"-.1 -.1 -.1\" size=\".01\"/>\n",
|
||||||
" \u003csite name=\"IMU\"/\u003e\n",
|
" <site name=\"IMU\"/>\n",
|
||||||
" \u003c/body\u003e\n",
|
" </body>\n",
|
||||||
" \u003c/worldbody\u003e\n",
|
" </worldbody>\n",
|
||||||
"\n",
|
"\n",
|
||||||
" \u003ctendon\u003e\n",
|
" <tendon>\n",
|
||||||
" \u003cspatial name=\"wire\" limited=\"true\" range=\"0 0.35\" width=\"0.003\"\u003e\n",
|
" <spatial name=\"wire\" limited=\"true\" range=\"0 0.35\" width=\"0.003\">\n",
|
||||||
" \u003csite site=\"anchor\"/\u003e\n",
|
" <site site=\"anchor\"/>\n",
|
||||||
" \u003csite site=\"hook\"/\u003e\n",
|
" <site site=\"hook\"/>\n",
|
||||||
" \u003c/spatial\u003e\n",
|
" </spatial>\n",
|
||||||
" \u003c/tendon\u003e\n",
|
" </tendon>\n",
|
||||||
"\n",
|
"\n",
|
||||||
" \u003cactuator\u003e\n",
|
" <actuator>\n",
|
||||||
" \u003cmotor name=\"my_motor\" joint=\"swing\" gear=\"1\"/\u003e\n",
|
" <motor name=\"my_motor\" joint=\"swing\" gear=\"1\"/>\n",
|
||||||
" \u003c/actuator\u003e\n",
|
" </actuator>\n",
|
||||||
"\n",
|
"\n",
|
||||||
" \u003csensor\u003e\n",
|
" <sensor>\n",
|
||||||
" \u003caccelerometer name=\"accelerometer\" site=\"IMU\"/\u003e\n",
|
" <accelerometer name=\"accelerometer\" site=\"IMU\"/>\n",
|
||||||
" \u003c/sensor\u003e\n",
|
" </sensor>\n",
|
||||||
"\u003c/mujoco\u003e\n",
|
"</mujoco>\n",
|
||||||
"\"\"\"\n",
|
"\"\"\"\n",
|
||||||
"model = mujoco.MjModel.from_xml_string(MJCF)\n",
|
"model = mujoco.MjModel.from_xml_string(MJCF)\n",
|
||||||
"renderer = mujoco.Renderer(model, 480, 480)\n",
|
"renderer = mujoco.Renderer(model, 480, 480)\n",
|
||||||
@@ -1587,7 +1587,7 @@
|
|||||||
"\n",
|
"\n",
|
||||||
"# simulate and render\n",
|
"# simulate and render\n",
|
||||||
"for i in range(n_frames):\n",
|
"for i in range(n_frames):\n",
|
||||||
" while data.time \u003c i/fps:\n",
|
" while data.time < i/fps:\n",
|
||||||
" mujoco.mj_step(model, data)\n",
|
" mujoco.mj_step(model, data)\n",
|
||||||
" times.append(data.time)\n",
|
" times.append(data.time)\n",
|
||||||
" sensordata.append(data.sensor('accelerometer').data.copy())\n",
|
" sensordata.append(data.sensor('accelerometer').data.copy())\n",
|
||||||
@@ -1658,16 +1658,16 @@
|
|||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"xml = \"\"\"\n",
|
"xml = \"\"\"\n",
|
||||||
"\u003cmujoco\u003e\n",
|
"<mujoco>\n",
|
||||||
" \u003cworldbody\u003e\n",
|
" <worldbody>\n",
|
||||||
" \u003clight name=\"top\" pos=\"0 0 1\"/\u003e\n",
|
" <light name=\"top\" pos=\"0 0 1\"/>\n",
|
||||||
" \u003cbody name=\"box_and_sphere\" euler=\"0 0 -30\"\u003e\n",
|
" <body name=\"box_and_sphere\" euler=\"0 0 -30\">\n",
|
||||||
" \u003cjoint name=\"swing\" type=\"hinge\" axis=\"1 -1 0\" pos=\"-.2 -.2 -.2\"/\u003e\n",
|
" <joint name=\"swing\" type=\"hinge\" axis=\"1 -1 0\" pos=\"-.2 -.2 -.2\"/>\n",
|
||||||
" \u003cgeom name=\"red_box\" type=\"box\" size=\".2 .2 .2\" rgba=\"1 0 0 1\"/\u003e\n",
|
" <geom name=\"red_box\" type=\"box\" size=\".2 .2 .2\" rgba=\"1 0 0 1\"/>\n",
|
||||||
" \u003cgeom name=\"green_sphere\" pos=\".2 .2 .2\" size=\".1\" rgba=\"0 1 0 1\"/\u003e\n",
|
" <geom name=\"green_sphere\" pos=\".2 .2 .2\" size=\".1\" rgba=\"0 1 0 1\"/>\n",
|
||||||
" \u003c/body\u003e\n",
|
" </body>\n",
|
||||||
" \u003c/worldbody\u003e\n",
|
" </worldbody>\n",
|
||||||
"\u003c/mujoco\u003e\n",
|
"</mujoco>\n",
|
||||||
"\"\"\"\n",
|
"\"\"\"\n",
|
||||||
"model = mujoco.MjModel.from_xml_string(xml)\n",
|
"model = mujoco.MjModel.from_xml_string(xml)\n",
|
||||||
"renderer = mujoco.Renderer(model)\n",
|
"renderer = mujoco.Renderer(model)\n",
|
||||||
@@ -1717,7 +1717,7 @@
|
|||||||
"# Shift nearest values to the origin.\n",
|
"# Shift nearest values to the origin.\n",
|
||||||
"depth -= depth.min()\n",
|
"depth -= depth.min()\n",
|
||||||
"# Scale by 2 mean distances of near rays.\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",
|
"# Scale to [0, 255]\n",
|
||||||
"pixels = 255*np.clip(depth, 0, 1)\n",
|
"pixels = 255*np.clip(depth, 0, 1)\n",
|
||||||
"\n",
|
"\n",
|
||||||
@@ -1888,7 +1888,7 @@
|
|||||||
"\n",
|
"\n",
|
||||||
"def add_visual_capsule(scene, point1, point2, radius, rgba):\n",
|
"def add_visual_capsule(scene, point1, point2, radius, rgba):\n",
|
||||||
" \"\"\"Adds one capsule to an mjvScene.\"\"\"\n",
|
" \"\"\"Adds one capsule to an mjvScene.\"\"\"\n",
|
||||||
" if scene.ngeom \u003e= scene.maxgeom:\n",
|
" if scene.ngeom >= scene.maxgeom:\n",
|
||||||
" return\n",
|
" return\n",
|
||||||
" scene.ngeom += 1 # increment ngeom\n",
|
" scene.ngeom += 1 # increment ngeom\n",
|
||||||
" # initialise a new capsule, add it to the scene using mjv_makeConnector\n",
|
" # initialise a new capsule, add it to the scene using mjv_makeConnector\n",
|
||||||
@@ -1908,7 +1908,7 @@
|
|||||||
"\n",
|
"\n",
|
||||||
"def modify_scene(scn):\n",
|
"def modify_scene(scn):\n",
|
||||||
" \"\"\"Draw position trace, speed modifies width and colors.\"\"\"\n",
|
" \"\"\"Draw position trace, speed modifies width and colors.\"\"\"\n",
|
||||||
" if len(positions) \u003e 1:\n",
|
" if len(positions) > 1:\n",
|
||||||
" for i in range(len(positions)-1):\n",
|
" for i in range(len(positions)-1):\n",
|
||||||
" rgba=np.array((np.clip(speeds[i]/10, 0, 1),\n",
|
" rgba=np.array((np.clip(speeds[i]/10, 0, 1),\n",
|
||||||
" np.clip(1-speeds[i]/10, 0, 1),\n",
|
" np.clip(1-speeds[i]/10, 0, 1),\n",
|
||||||
@@ -1928,13 +1928,13 @@
|
|||||||
"mujoco.mj_resetData(model, data)\n",
|
"mujoco.mj_resetData(model, data)\n",
|
||||||
"mujoco.mj_forward(model, data)\n",
|
"mujoco.mj_forward(model, data)\n",
|
||||||
"\n",
|
"\n",
|
||||||
"while data.time \u003c duration:\n",
|
"while data.time < duration:\n",
|
||||||
" # append data to the traces\n",
|
" # append data to the traces\n",
|
||||||
" positions.append(data.geom_xpos[data.geom(\"green_sphere\").id].copy())\n",
|
" positions.append(data.geom_xpos[data.geom(\"green_sphere\").id].copy())\n",
|
||||||
" times.append(data.time)\n",
|
" times.append(data.time)\n",
|
||||||
" speeds.append(get_geom_speed(model, data, \"green_sphere\"))\n",
|
" speeds.append(get_geom_speed(model, data, \"green_sphere\"))\n",
|
||||||
" mujoco.mj_step(model, data)\n",
|
" mujoco.mj_step(model, data)\n",
|
||||||
" if len(frames) \u003c data.time * framerate:\n",
|
" if len(frames) < data.time * framerate:\n",
|
||||||
" renderer.update_scene(data)\n",
|
" renderer.update_scene(data)\n",
|
||||||
" modify_scene(renderer.scene)\n",
|
" modify_scene(renderer.scene)\n",
|
||||||
" pixels = renderer.render()\n",
|
" pixels = renderer.render()\n",
|
||||||
@@ -1966,88 +1966,88 @@
|
|||||||
"source": [
|
"source": [
|
||||||
"#@title Load the \"dominos\" model\n",
|
"#@title Load the \"dominos\" model\n",
|
||||||
"dominos_xml = \"\"\"\n",
|
"dominos_xml = \"\"\"\n",
|
||||||
"\u003cmujoco\u003e\n",
|
"<mujoco>\n",
|
||||||
" \u003casset\u003e\n",
|
" <asset>\n",
|
||||||
" \u003ctexture type=\"skybox\" builtin=\"gradient\" rgb1=\".3 .5 .7\" rgb2=\"0 0 0\" width=\"32\" height=\"512\"/\u003e\n",
|
" <texture type=\"skybox\" builtin=\"gradient\" rgb1=\".3 .5 .7\" rgb2=\"0 0 0\" width=\"32\" height=\"512\"/>\n",
|
||||||
" \u003ctexture name=\"grid\" type=\"2d\" builtin=\"checker\" width=\"512\" height=\"512\" rgb1=\".1 .2 .3\" rgb2=\".2 .3 .4\"/\u003e\n",
|
" <texture name=\"grid\" type=\"2d\" builtin=\"checker\" width=\"512\" height=\"512\" rgb1=\".1 .2 .3\" rgb2=\".2 .3 .4\"/>\n",
|
||||||
" \u003cmaterial name=\"grid\" texture=\"grid\" texrepeat=\"2 2\" texuniform=\"true\" reflectance=\".2\"/\u003e\n",
|
" <material name=\"grid\" texture=\"grid\" texrepeat=\"2 2\" texuniform=\"true\" reflectance=\".2\"/>\n",
|
||||||
" \u003c/asset\u003e\n",
|
" </asset>\n",
|
||||||
"\n",
|
"\n",
|
||||||
" \u003cstatistic meansize=\".01\"/\u003e\n",
|
" <statistic meansize=\".01\"/>\n",
|
||||||
"\n",
|
"\n",
|
||||||
" \u003cvisual\u003e\n",
|
" <visual>\n",
|
||||||
" \u003cglobal offheight=\"2160\" offwidth=\"3840\"/\u003e\n",
|
" <global offheight=\"2160\" offwidth=\"3840\"/>\n",
|
||||||
" \u003cquality offsamples=\"8\"/\u003e\n",
|
" <quality offsamples=\"8\"/>\n",
|
||||||
" \u003c/visual\u003e\n",
|
" </visual>\n",
|
||||||
"\n",
|
"\n",
|
||||||
" \u003cdefault\u003e\n",
|
" <default>\n",
|
||||||
" \u003cgeom type=\"box\" solref=\".005 1\"/\u003e\n",
|
" <geom type=\"box\" solref=\".005 1\"/>\n",
|
||||||
" \u003cdefault class=\"static\"\u003e\n",
|
" <default class=\"static\">\n",
|
||||||
" \u003cgeom rgba=\".3 .5 .7 1\"/\u003e\n",
|
" <geom rgba=\".3 .5 .7 1\"/>\n",
|
||||||
" \u003c/default\u003e\n",
|
" </default>\n",
|
||||||
" \u003c/default\u003e\n",
|
" </default>\n",
|
||||||
"\n",
|
"\n",
|
||||||
" \u003coption timestep=\"5e-4\"/\u003e\n",
|
" <option timestep=\"5e-4\"/>\n",
|
||||||
"\n",
|
"\n",
|
||||||
" \u003cworldbody\u003e\n",
|
" <worldbody>\n",
|
||||||
" \u003clight pos=\".3 -.3 .8\" mode=\"trackcom\" diffuse=\"1 1 1\" specular=\".3 .3 .3\"/\u003e\n",
|
" <light pos=\".3 -.3 .8\" mode=\"trackcom\" diffuse=\"1 1 1\" specular=\".3 .3 .3\"/>\n",
|
||||||
" \u003clight pos=\"0 -.3 .4\" mode=\"targetbodycom\" target=\"box\" diffuse=\".8 .8 .8\" specular=\".3 .3 .3\"/\u003e\n",
|
" <light pos=\"0 -.3 .4\" mode=\"targetbodycom\" target=\"box\" diffuse=\".8 .8 .8\" specular=\".3 .3 .3\"/>\n",
|
||||||
" \u003cgeom name=\"floor\" type=\"plane\" size=\"3 3 .01\" pos=\"-0.025 -0.295 0\" material=\"grid\"/\u003e\n",
|
" <geom name=\"floor\" type=\"plane\" size=\"3 3 .01\" pos=\"-0.025 -0.295 0\" material=\"grid\"/>\n",
|
||||||
" \u003cgeom name=\"ramp\" pos=\".25 -.45 -.03\" size=\".04 .1 .07\" euler=\"-30 0 0\" class=\"static\"/\u003e\n",
|
" <geom name=\"ramp\" pos=\".25 -.45 -.03\" size=\".04 .1 .07\" euler=\"-30 0 0\" class=\"static\"/>\n",
|
||||||
" \u003ccamera name=\"top\" pos=\"-0.37 -0.78 0.49\" xyaxes=\"0.78 -0.63 0 0.27 0.33 0.9\"/\u003e\n",
|
" <camera name=\"top\" pos=\"-0.37 -0.78 0.49\" xyaxes=\"0.78 -0.63 0 0.27 0.33 0.9\"/>\n",
|
||||||
"\n",
|
"\n",
|
||||||
" \u003cbody name=\"ball\" pos=\".25 -.45 .1\"\u003e\n",
|
" <body name=\"ball\" pos=\".25 -.45 .1\">\n",
|
||||||
" \u003cfreejoint name=\"ball\"/\u003e\n",
|
" <freejoint name=\"ball\"/>\n",
|
||||||
" \u003cgeom name=\"ball\" type=\"sphere\" size=\".02\" rgba=\".65 .81 .55 1\"/\u003e\n",
|
" <geom name=\"ball\" type=\"sphere\" size=\".02\" rgba=\".65 .81 .55 1\"/>\n",
|
||||||
" \u003c/body\u003e\n",
|
" </body>\n",
|
||||||
"\n",
|
"\n",
|
||||||
" \u003cbody pos=\".26 -.3 .03\" euler=\"0 0 -90.0\"\u003e\n",
|
" <body pos=\".26 -.3 .03\" euler=\"0 0 -90.0\">\n",
|
||||||
" \u003cfreejoint/\u003e\n",
|
" <freejoint/>\n",
|
||||||
" \u003cgeom size=\".0015 .015 .03\" rgba=\"1 .5 .5 1\"/\u003e\n",
|
" <geom size=\".0015 .015 .03\" rgba=\"1 .5 .5 1\"/>\n",
|
||||||
" \u003c/body\u003e\n",
|
" </body>\n",
|
||||||
"\n",
|
"\n",
|
||||||
" \u003cbody pos=\".26 -.27 .04\" euler=\"0 0 -81.0\"\u003e\n",
|
" <body pos=\".26 -.27 .04\" euler=\"0 0 -81.0\">\n",
|
||||||
" \u003cfreejoint/\u003e\n",
|
" <freejoint/>\n",
|
||||||
" \u003cgeom size=\".002 .02 .04\" rgba=\"1 1 .5 1\"/\u003e\n",
|
" <geom size=\".002 .02 .04\" rgba=\"1 1 .5 1\"/>\n",
|
||||||
" \u003c/body\u003e\n",
|
" </body>\n",
|
||||||
"\n",
|
"\n",
|
||||||
" \u003cbody pos=\".24 -.21 .06\" euler=\"0 0 -63.0\"\u003e\n",
|
" <body pos=\".24 -.21 .06\" euler=\"0 0 -63.0\">\n",
|
||||||
" \u003cfreejoint/\u003e\n",
|
" <freejoint/>\n",
|
||||||
" \u003cgeom size=\".003 .03 .06\" rgba=\".5 1 .5 1\"/\u003e\n",
|
" <geom size=\".003 .03 .06\" rgba=\".5 1 .5 1\"/>\n",
|
||||||
" \u003c/body\u003e\n",
|
" </body>\n",
|
||||||
"\n",
|
"\n",
|
||||||
" \u003cbody pos=\".2 -.16 .08\" euler=\"0 0 -45.0\"\u003e\n",
|
" <body pos=\".2 -.16 .08\" euler=\"0 0 -45.0\">\n",
|
||||||
" \u003cfreejoint/\u003e\n",
|
" <freejoint/>\n",
|
||||||
" \u003cgeom size=\".004 .04 .08\" rgba=\".5 1 1 1\"/\u003e\n",
|
" <geom size=\".004 .04 .08\" rgba=\".5 1 1 1\"/>\n",
|
||||||
" \u003c/body\u003e\n",
|
" </body>\n",
|
||||||
"\n",
|
"\n",
|
||||||
" \u003cbody pos=\".15 -.12 .1\" euler=\"0 0 -27.0\"\u003e\n",
|
" <body pos=\".15 -.12 .1\" euler=\"0 0 -27.0\">\n",
|
||||||
" \u003cfreejoint/\u003e\n",
|
" <freejoint/>\n",
|
||||||
" \u003cgeom size=\".005 .05 .1\" rgba=\".5 .5 1 1\"/\u003e\n",
|
" <geom size=\".005 .05 .1\" rgba=\".5 .5 1 1\"/>\n",
|
||||||
" \u003c/body\u003e\n",
|
" </body>\n",
|
||||||
"\n",
|
"\n",
|
||||||
" \u003cbody pos=\".09 -.1 .12\" euler=\"0 0 -9.0\"\u003e\n",
|
" <body pos=\".09 -.1 .12\" euler=\"0 0 -9.0\">\n",
|
||||||
" \u003cfreejoint/\u003e\n",
|
" <freejoint/>\n",
|
||||||
" \u003cgeom size=\".006 .06 .12\" rgba=\"1 .5 1 1\"/\u003e\n",
|
" <geom size=\".006 .06 .12\" rgba=\"1 .5 1 1\"/>\n",
|
||||||
" \u003c/body\u003e\n",
|
" </body>\n",
|
||||||
"\n",
|
"\n",
|
||||||
" \u003cbody name=\"seasaw_wrapper\" pos=\"-.23 -.1 0\" euler=\"0 0 30\"\u003e\n",
|
" <body name=\"seasaw_wrapper\" pos=\"-.23 -.1 0\" euler=\"0 0 30\">\n",
|
||||||
" \u003cgeom size=\".01 .01 .015\" pos=\"0 .05 .015\" class=\"static\"/\u003e\n",
|
" <geom size=\".01 .01 .015\" pos=\"0 .05 .015\" class=\"static\"/>\n",
|
||||||
" \u003cgeom size=\".01 .01 .015\" pos=\"0 -.05 .015\" class=\"static\"/\u003e\n",
|
" <geom size=\".01 .01 .015\" pos=\"0 -.05 .015\" class=\"static\"/>\n",
|
||||||
" \u003cgeom type=\"cylinder\" size=\".01 .0175\" pos=\"-.09 0 .0175\" class=\"static\"/\u003e\n",
|
" <geom type=\"cylinder\" size=\".01 .0175\" pos=\"-.09 0 .0175\" class=\"static\"/>\n",
|
||||||
" \u003cbody name=\"seasaw\" pos=\"0 0 .03\"\u003e\n",
|
" <body name=\"seasaw\" pos=\"0 0 .03\">\n",
|
||||||
" \u003cjoint axis=\"0 1 0\"/\u003e\n",
|
" <joint axis=\"0 1 0\"/>\n",
|
||||||
" \u003cgeom type=\"cylinder\" size=\".005 .039\" zaxis=\"0 1 0\" rgba=\".84 .15 .33 1\"/\u003e\n",
|
" <geom type=\"cylinder\" size=\".005 .039\" zaxis=\"0 1 0\" rgba=\".84 .15 .33 1\"/>\n",
|
||||||
" \u003cgeom size=\".1 .02 .005\" pos=\"0 0 .01\" rgba=\".84 .15 .33 1\"/\u003e\n",
|
" <geom size=\".1 .02 .005\" pos=\"0 0 .01\" rgba=\".84 .15 .33 1\"/>\n",
|
||||||
" \u003c/body\u003e\n",
|
" </body>\n",
|
||||||
" \u003c/body\u003e\n",
|
" </body>\n",
|
||||||
"\n",
|
"\n",
|
||||||
" \u003cbody name=\"box\" pos=\"-.3 -.14 .05501\" euler=\"0 0 -30\"\u003e\n",
|
" <body name=\"box\" pos=\"-.3 -.14 .05501\" euler=\"0 0 -30\">\n",
|
||||||
" \u003cfreejoint name=\"box\"/\u003e\n",
|
" <freejoint name=\"box\"/>\n",
|
||||||
" \u003cgeom name=\"box\" size=\".01 .01 .01\" rgba=\".0 .7 .79 1\"/\u003e\n",
|
" <geom name=\"box\" size=\".01 .01 .01\" rgba=\".0 .7 .79 1\"/>\n",
|
||||||
" \u003c/body\u003e\n",
|
" </body>\n",
|
||||||
" \u003c/worldbody\u003e\n",
|
" </worldbody>\n",
|
||||||
"\u003c/mujoco\u003e\n",
|
"</mujoco>\n",
|
||||||
"\"\"\"\n",
|
"\"\"\"\n",
|
||||||
"model = mujoco.MjModel.from_xml_string(dominos_xml)\n",
|
"model = mujoco.MjModel.from_xml_string(dominos_xml)\n",
|
||||||
"data = mujoco.MjData(model)\n",
|
"data = mujoco.MjData(model)\n",
|
||||||
@@ -2070,9 +2070,9 @@
|
|||||||
"# Simulate and display video.\n",
|
"# Simulate and display video.\n",
|
||||||
"frames = []\n",
|
"frames = []\n",
|
||||||
"mujoco.mj_resetData(model, data) # Reset state and time.\n",
|
"mujoco.mj_resetData(model, data) # Reset state and time.\n",
|
||||||
"while data.time \u003c duration:\n",
|
"while data.time < duration:\n",
|
||||||
" mujoco.mj_step(model, data)\n",
|
" mujoco.mj_step(model, data)\n",
|
||||||
" if len(frames) \u003c data.time * framerate:\n",
|
" if len(frames) < data.time * framerate:\n",
|
||||||
" renderer.update_scene(data, camera='top')\n",
|
" renderer.update_scene(data, camera='top')\n",
|
||||||
" pixels = renderer.render()\n",
|
" pixels = renderer.render()\n",
|
||||||
" frames.append(pixels)\n",
|
" frames.append(pixels)\n",
|
||||||
@@ -2091,15 +2091,15 @@
|
|||||||
"#@title Render from moving camera\n",
|
"#@title Render from moving camera\n",
|
||||||
"duration = 3 # (seconds)\n",
|
"duration = 3 # (seconds)\n",
|
||||||
"\n",
|
"\n",
|
||||||
"# find time when box is thrown (speed \u003e 2cm/s)\n",
|
"# find time when box is thrown (speed > 2cm/s)\n",
|
||||||
"throw_time = 0.0\n",
|
"throw_time = 0.0\n",
|
||||||
"mujoco.mj_resetData(model, data)\n",
|
"mujoco.mj_resetData(model, data)\n",
|
||||||
"while data.time \u003c duration and not throw_time:\n",
|
"while data.time < duration and not throw_time:\n",
|
||||||
" mujoco.mj_step(model, data)\n",
|
" mujoco.mj_step(model, data)\n",
|
||||||
" box_speed = np.linalg.norm(data.joint('box').qvel[:3])\n",
|
" box_speed = np.linalg.norm(data.joint('box').qvel[:3])\n",
|
||||||
" if box_speed \u003e 0.02:\n",
|
" if box_speed > 0.02:\n",
|
||||||
" throw_time = data.time\n",
|
" throw_time = data.time\n",
|
||||||
"assert throw_time \u003e 0\n",
|
"assert throw_time > 0\n",
|
||||||
"\n",
|
"\n",
|
||||||
"def mix(time, t0=0.0, width=1.0):\n",
|
"def mix(time, t0=0.0, width=1.0):\n",
|
||||||
" \"\"\"Sigmoidal mixing function.\"\"\"\n",
|
" \"\"\"Sigmoidal mixing function.\"\"\"\n",
|
||||||
@@ -2144,9 +2144,9 @@
|
|||||||
"slowdown = 4 # 4x slow-down\n",
|
"slowdown = 4 # 4x slow-down\n",
|
||||||
"mujoco.mj_resetData(model, data)\n",
|
"mujoco.mj_resetData(model, data)\n",
|
||||||
"frames = []\n",
|
"frames = []\n",
|
||||||
"while data.time \u003c duration:\n",
|
"while data.time < duration:\n",
|
||||||
" mujoco.mj_step(model, data)\n",
|
" mujoco.mj_step(model, data)\n",
|
||||||
" if len(frames) \u003c data.time * framerate * slowdown:\n",
|
" if len(frames) < data.time * framerate * slowdown:\n",
|
||||||
" cam.distance, cam.azimuth, cam.elevation, cam.lookat = cam_motion()\n",
|
" cam.distance, cam.azimuth, cam.elevation, cam.lookat = cam_motion()\n",
|
||||||
" renderer.update_scene(data, cam)\n",
|
" renderer.update_scene(data, cam)\n",
|
||||||
" pixels = renderer.render()\n",
|
" pixels = renderer.render()\n",
|
||||||
@@ -2167,10 +2167,23 @@
|
|||||||
},
|
},
|
||||||
"gpuClass": "premium",
|
"gpuClass": "premium",
|
||||||
"kernelspec": {
|
"kernelspec": {
|
||||||
"display_name": "Python 3",
|
"display_name": "Python 3 (ipykernel)",
|
||||||
|
"language": "python",
|
||||||
"name": "python3"
|
"name": "python3"
|
||||||
|
},
|
||||||
|
"language_info": {
|
||||||
|
"codemirror_mode": {
|
||||||
|
"name": "ipython",
|
||||||
|
"version": 3
|
||||||
|
},
|
||||||
|
"file_extension": ".py",
|
||||||
|
"mimetype": "text/x-python",
|
||||||
|
"name": "python",
|
||||||
|
"nbconvert_exporter": "python",
|
||||||
|
"pygments_lexer": "ipython3",
|
||||||
|
"version": "3.10.12"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nbformat": 4,
|
"nbformat": 4,
|
||||||
"nbformat_minor": 0
|
"nbformat_minor": 4
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user