From 06758e35ab40169b3b01d43f93c97f76b1144362 Mon Sep 17 00:00:00 2001 From: Alessio Quaglino Date: Fri, 7 Feb 2025 09:40:14 -0800 Subject: [PATCH] Fix mjSpec colab after changing the default behavior of attach to be a shallow copy. PiperOrigin-RevId: 724375710 Change-Id: I5fac7d24c1d0b1ad4d427c021022c47620accf53 --- doc/python.rst | 14 ++++++++------ python/mjspec.ipynb | 3 +++ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/doc/python.rst b/doc/python.rst index edf4bf63..925edfad 100644 --- a/doc/python.rst +++ b/doc/python.rst @@ -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` and :ref:`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` and :ref:`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 diff --git a/python/mjspec.ipynb b/python/mjspec.ipynb index 12a3b68e..8ac33640 100644 --- a/python/mjspec.ipynb +++ b/python/mjspec.ipynb @@ -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", @@ -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", @@ -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",