Skip to content

Commit

Permalink
Fix mjSpec colab after changing the default behavior of attach to be …
Browse files Browse the repository at this point in the history
…a shallow copy.

PiperOrigin-RevId: 724375710
Change-Id: I5fac7d24c1d0b1ad4d427c021022c47620accf53
  • Loading branch information
quagla authored and copybara-github committed Feb 7, 2025
1 parent c1ecc50 commit 06758e3
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 6 deletions.
14 changes: 8 additions & 6 deletions doc/python.rst
Original file line number Diff line number Diff line change
Expand Up @@ -547,16 +547,18 @@ It is possible to combine multiple specs by using attachments. The following opt
the reference to the attached body, which should be identical to the body used as input.
- Attach a frame from the child spec to a body in the parent spec: ``body.attach_frame(frame, prefix, suffix)``,
returns the reference to the attached frame, which should be identical to the frame used as input.
- Attach a child spec to a site in the parent spec: ``spec.attach(child_spec, site=site_name_or_obj)``, returns the
reference to a frame, which is the attached worldbody transformed into a frame. The site must belong to the child
spec. Prefix and suffix can also be specified as keyword arguments.
- Attach a child spec to a site in the parent spec: ``parent_spec.attach(child_spec, site=site_name_or_obj)``, returns
the reference to a frame, which is the attached worldbody transformed into a frame. The site must belong to the
child spec. Prefix and suffix can also be specified as keyword arguments.
- Attach a child spec to a frame in the parent spec: ``parent_spec.attach(child_spec, frame=frame_name_or_obj)``,
returns the reference to a frame, which is the attached worldbody transformed into a frame. The frame must belong to
the child spec. Prefix and suffix can also be specified as keyword arguments.

Attaching does not copy, so all the child references are still valid in the parent and therefore modifying the child will
modify the parent. This is not true for the attach :ref:`attach<body-attach>` and :ref:`replicate<replicate>`
meta-elements in MJCF, which create deep copies while attaching.
The default behavior of attaching is to not copy, so all the child references (except for the worldbody) are still valid
in the parent and therefore modifying the child will modify the parent. This is not true for the attach
:ref:`attach<body-attach>` and :ref:`replicate<replicate>` meta-elements in MJCF, which create deep copies while
attaching. However, it is possible to override the default behavior by setting ``spec.copy_during_attaching`` to
``True``. In this case, the child spec is copied and the references to the child will not point to the parent.

.. code-block:: python
Expand Down
3 changes: 3 additions & 0 deletions python/mjspec.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,7 @@
" \"\"\"Constructs a creature with `num_legs` legs.\"\"\"\n",
" rgba = random_state.uniform([0, 0, 0, 1], [1, 1, 1, 1])\n",
" spec = mj.MjSpec.from_string(creature_model)\n",
" spec.copy_during_attach = True\n",
"\n",
" # Attach legs to equidistant sites on the circumference.\n",
" spec.worldbody.first_geom().rgba = rgba\n",
Expand Down Expand Up @@ -672,6 +673,7 @@
"#@title Humanoid with arms replaced by legs.{vertical-output: true}\n",
"\n",
"spec = mj.MjSpec.from_file(humanoid_file)\n",
"spec.copy_during_attach = True\n",
"\n",
"# Get the torso, arm, and leg bodies\n",
"arm_left = spec.find_body('upper_arm_left')\n",
Expand Down Expand Up @@ -781,6 +783,7 @@
"\n",
"humanoid = mj.MjSpec.from_file(humanoid_file)\n",
"spec = mj.MjSpec()\n",
"spec.copy_during_attach = True\n",
"\n",
"# Delete all key frames to avoid name conflicts\n",
"while humanoid.keys:\n",
Expand Down

0 comments on commit 06758e3

Please sign in to comment.