Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

Use of MjSpec in environment

Aperta
#494 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
5/5
Tempo stimato
Più di una settimana
Idoneità per principianti
20/100
Tipo di issue
Funzionalità
Chiarezza
Da chiarire
Stato di attività
Ferma
Stack tecnologico
python

Direzione di ricerca

Inizia con l'esempio Python fornito e src/rebar_mujoco/environments/xml_files/mujoco.xml, quindi esamina gli entry point di dm_control Environment e il modo in cui viene costruito Physics. Riproduci lo scenario di ricompilazione di MjSpec e determina il percorso di integrazione supportato; il lavoro è completato quando Environment è in grado di gestire chiaramente le modifiche al modello richieste oppure quando sono documentati il limite e l'utilizzo necessario.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

Hello,

I would like to create a RL pipeline in order to find a policy to stack rebars in the most stable way depending on their shape. As I want to stack them, I need to spawn them at one by one. One way (and the easiest for me) would be to use the MjSpec class from mujoco and recompile the model every time I want to spawn a rebar. However, when I wanted to make the environment for the training, I realized that it was not trivial to use this MjSpec feature that I am using with the Physics class...
So my question would be to know if there is an easy way to do it or if I have to rewrite the Environment class?

Thank you

Example

Here is an example of my problem with a simple script.

xml file
<?xml version="1.0" ?>
<mujoco model="coil">
	<extension>
		<plugin plugin="mujoco.elasticity.cable"/>
	</extension>

	<option integrator="implicit" timestep="0.001"/>
	<visual>
        <map force="0.1" zfar="30"/>
        <rgba haze="0.15 0.25 0.35 1"/>
        <quality shadowsize="2048"/>
        <global offwidth="800" offheight="800"/>
    </visual>

	<worldbody>
		<body name="stirrup" pos="0 0 1.005" quat="1 0 0 0">
			<freejoint/>
			<inertial pos="0.28 0.09 0.005" mass="1" diaginertia="0.001 0.001 0.001"/>
			<composite prefix="stirrup0" type="cable" vertex="
				3.061617e-19 5.000000e-03 0.000000e+00 
				5.650000e-01 5.000000e-03 0.000000e+00 
				5.950000e-01 3.500000e-02 0.000000e+00 
				5.950000e-01 1.550000e-01 0.000000e+00 
				5.650000e-01 1.850000e-01 0.000000e+00 
				-9.184851e-19 1.850000e-01 0.000000e+00
			" offset="0 0 0">
				<plugin plugin="mujoco.elasticity.cable">
					<config key="twist" value="5e8"/>
					<config key="bend" value="15e8"/>
					<config key="vmax" value="0"/>
				</plugin>
				<joint kind="main" damping="1" armature="100" stiffness="100" range="0 2"/>
				<geom type="capsule" size=".005" rgba=".8 .2 .1 1"/>
			</composite>
		</body>

	</worldbody>
	<asset>
		<texture type="skybox" builtin="gradient" rgb1="0.3 0.5 0.7" rgb2="0 0 0" width="512" height="3072"/>
		<texture type="2d" name="groundplane" builtin="checker" mark="edge" rgb1="0.2 0.3 0.4" rgb2="0.1 0.2 0.3" markrgb="0.8 0.8 0.8" width="300" height="300"/>
		<material name="groundplane" texture="groundplane" texuniform="true" texrepeat="5 5" reflectance="0.2"/>
	</asset>
	<worldbody>
		<light pos="0 0 3.5" dir="0 0 -1" directional="true"/>
		<geom name="floor" size="0 0 0.05" type="plane" material="groundplane"/>
	</worldbody>
</mujoco>

python code
import sys, os
import time
# Add the parent directory to sys.path
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))

import mujoco
import mujoco.viewer

def display_video(frames, videoname='animation.mp4', framerate=30):
    """Display a list of frames as a video.
    Args:
        frames (list): list of frames to display.
        videoname (str, optional): name of the video. Defaults to 'animation.mp4'.
        framerate (int, optional): # frames per second. Defaults to 30.
    """

    height, width, _ = frames[0].shape
    dpi = 10
    orig_backend = matplotlib.get_backend()
    matplotlib.use('Agg')  # Switch to headless 'Agg' to inhibit figure rendering.
    fig, ax = plt.subplots(1, 1, figsize=(width / dpi, height / dpi), dpi=dpi)
    matplotlib.use(orig_backend)  # Switch back to the original backend.
    ax.set_axis_off()
    ax.set_aspect('equal')
    ax.set_position([0, 0, 1, 1])
    im = ax.imshow(frames[0])
    def update(frame):
      im.set_data(frame)
      return [im]
    interval = 1000/framerate
    anim = animation.FuncAnimation(fig=fig, func=update, frames=frames,
                                   interval=interval, blit=True, repeat=False)
    # return HTML(anim.to_html5_video())
    # Save as MP4
    anim.save(videoname, writer='ffmpeg', fps=framerate)
    plt.close(fig)

def add_body_in_spec(spec):
  """
  Add a body to the mujoco model.
  Args:
    spec: mujoco.MjSpec, the mujoco model specification.
  Returns:
    spec: mujoco.MjSpec, the updated mujoco model specification.
  Note: The body is a classic U-shape stirrup
  TODO: make this process adaptve to every kind of stirrup.
  """
  # plugin2_0 = spec.add_plugin()
  # plugin2_0.instance_name = "compositestirrup0"
  # plugin2_0.active = 1
  body2 = spec.worldbody.add_body()
  # body2 = spec.find_body("stirrup")
  body2.name = "stirrup2"
  body2.pos = [0.5, 0.1, 0.5]
  # body2.quat = [ 0, 0, 0.7071068, 0.7071068 ]
  body2.quat = [0.707107, 0, -0.707107, 0]
  body2.mass = 1
  body2.inertia = [0.001, 0.001, 0.001]
  body2.ipos = [0.28, 0, 0.005]
  joint = body2.add_joint()
  joint.type = mujoco.mjtJoint.mjJNT_FREE

  body2_0 = body2.add_body()
  body2_0.name = "stirrup20B0"
  body2_0.pos = [0, 0.005, 0]
  joint2_0 = body2_0.add_joint()
  joint2_0.name = "stirrup20J0"
  joint2_0.type = mujoco.mjtJoint.mjJNT_BALL
  joint2_0.group = 3
  joint2_0.pos = [0, 0, 0]
  joint2_0.armature = 100
  joint2_0.damping = 1
  joint2_0.stiffness = 100
  joint2_0.range = [0, 2]
  geom2_0 = body2_0.add_geom()
  geom2_0.name = "stirrup2G0"
  geom2_0.size = [0.005, 0.2825, 0]
  geom2_0.pos = [0.2825, 0, 0]
  geom2_0.quat = [0.707107, 0, -0.707107, 0]
  # geom2_0.quat = [1, 0, 0, 0]
  geom2_0.type = mujoco.mjtGeom.mjGEOM_CAPSULE
  geom2_0.rgba = [0.8, 0.2, 0.1, 1]
  site2_0 = body2_0.add_site()
  site2_0.name = "stirrup2S0"
  site2_0.pos = [0, 0, 0]
  site2_0.group = 3

  body2_1 = body2_0.add_body()
  body2_1.name = "stirrup20B1"
  body2_1.pos = [0.565, 0, 0]
  body2_1.quat = [0.92388, 0, 0, 0.382683]
  joint2_1 = body2_1.add_joint()
  joint2_1.name = "stirrup20J1"
  joint2_1.type = mujoco.mjtJoint.mjJNT_BALL
  joint2_1.group = 3
  joint2_1.pos = [0, 0, 0]
  joint2_1.armature = 100
  joint2_1.damping = 1
  joint2_1.stiffness = 100
  joint2_1.range = [0, 2]
  geom2_1 = body2_1.add_geom()
  geom2_1.name = "stirrup2G1"
  geom2_1.size = [0.005, 0.0212132, 0]
  geom2_1.pos = [0.0212132, 0, 0]
  geom2_1.quat = [0.707107, 0, -0.707107, 0]
  geom2_1.type = mujoco.mjtGeom.mjGEOM_CAPSULE
  geom2_1.rgba = [0.8, 0.2, 0.1, 1]
  site2_1 = body2_1.add_site()
  site2_1.name = "stirrup2S1"
  site2_1.pos = [0, 0, 0]
  site2_1.group = 3

  body2_2 = body2_1.add_body()
  body2_2.name = "stirrup20B2"
  body2_2.pos = [0.0424264, 0, 0]
  body2_2.quat = [0.92388, 0, 0, 0.382683]
  joint2_2 = body2_2.add_joint()
  joint2_2.name = "stirrup20J2"
  joint2_2.type = mujoco.mjtJoint.mjJNT_BALL
  joint2_2.group = 3
  joint2_2.pos = [0, 0, 0]
  joint2_2.armature = 100
  joint2_2.damping = 1
  joint2_2.stiffness = 100
  joint2_2.range = [0, 2]
  geom2_2 = body2_2.add_geom()
  geom2_2.name = "stirrup2G2"
  geom2_2.size = [0.005, 0.06, 0]
  geom2_2.pos = [0.06, 0, 0]
  geom2_2.quat = [0.707107, 0, -0.707107, 0]
  geom2_2.type = mujoco.mjtGeom.mjGEOM_CAPSULE
  geom2_2.rgba = [0.8, 0.2, 0.1, 1]
  site2_2 = body2_2.add_site()
  site2_2.name = "stirrup2S2"
  site2_2.pos = [0, 0, 0]
  site2_2.group = 3

  body2_3 = body2_2.add_body()
  body2_3.name = "stirrup20B3"
  body2_3.pos = [0.12, 0, 0]
  body2_3.quat = [0.92388, 0, 0, 0.382683]
  joint2_3 = body2_3.add_joint()
  joint2_3.name = "stirrup20J3"
  joint2_3.type = mujoco.mjtJoint.mjJNT_BALL
  joint2_3.group = 3
  joint2_3.pos = [0, 0, 0]
  joint2_3.armature = 100
  joint2_3.damping = 1
  joint2_3.stiffness = 100
  joint2_3.range = [0, 2]
  geom2_3 = body2_3.add_geom()
  geom2_3.name = "stirrup2G3"
  geom2_3.size = [0.005, 0.0212132, 0]
  geom2_3.pos = [0.0212132, 0, 0]
  geom2_3.quat = [0.707107, 0, -0.707107, 0]
  geom2_3.type = mujoco.mjtGeom.mjGEOM_CAPSULE
  geom2_3.rgba = [0.8, 0.2, 0.1, 1]
  site2_3 = body2_3.add_site()
  site2_3.name = "stirrup2S3"
  site2_3.pos = [0, 0, 0]
  site2_3.group = 3

  body2_4 = body2_3.add_body()
  body2_4.name = "stirrup20B4"
  body2_4.pos = [0.0424264, 0, 0]
  body2_4.quat = [0.92388, 0, 0, 0.382683]
  joint2_4 = body2_4.add_joint()
  joint2_4.name = "stirrup20J4"
  joint2_4.type = mujoco.mjtJoint.mjJNT_BALL
  joint2_4.group = 3
  joint2_4.pos = [0, 0, 0]
  joint2_4.armature = 100
  joint2_4.damping = 1
  joint2_4.stiffness = 100
  joint2_4.range = [0, 2]
  geom2_4 = body2_4.add_geom()
  geom2_4.name = "stirrup2G4"
  geom2_4.size = [0.005, 0.2825, 0]
  geom2_4.pos = [0.2825, 0, 0]
  geom2_4.quat = [0.707107, 0, -0.707107, 0]
  geom2_4.type = mujoco.mjtGeom.mjGEOM_CAPSULE
  geom2_4.rgba = [0.8, 0.2, 0.1, 1]
  site2_4 = body2_4.add_site()
  site2_4.name = "stirrup2S4"
  site2_4.pos = [0, 0, 0]
  site2_4.group = 3

  return spec

if __name__ == '__main__':
  spec = mujoco.MjSpec()
  spec.from_file("src/rebar_mujoco/environments/xml_files/mujoco.xml")
  model = spec.compile()
  data = mujoco.MjData(model)

  framerate = 40  # (Hz)
  timestep = 0.001  # (seconds)
  duration = 5  # (seconds)
  width, height = 500, 500
  renderer = mujoco.Renderer(model, height=height, width=width)
  video_name = "src/rebar_mujoco/tests/tmp/test_mjSpec.mp4"
  scene_option = mujoco.MjvOption()
  frames = []
  frame_count = 0

  camera = mujoco.MjvCamera()
  mujoco.mjv_defaultFreeCamera(model, camera)
  camera.distance = 2.5
  camera.elevation = -20
  # camera.azimuth = -130
  camera.lookat = (0, 0, 0.5)

  add_body_time = 2 # seconds
  add_body = False

  z_pos_vec = []
  
  nb_step = 0
  while nb_step*timestep < duration:
      
    mujoco.mj_step(model, data)

    if nb_step*timestep > add_body_time and not add_body:
      print("Adding body")
      add_body = True
      spec = add_body_in_spec(spec)

      ## Recompile model and data while maintaining the state.
      model, data = spec.recompile(model, data)
      renderer.close()
      renderer = mujoco.Renderer(model, height=height, width=width)

    if frame_count < nb_step*timestep * framerate:
      z_pos_vec.append(data.geom_xpos[-1][2])
      renderer.update_scene(data, camera=camera, scene_option=scene_option)
      frame = renderer.render()
      frames.append(frame)
      frame_count += 1

    nb_step += 1

  display_video(frames, video_name, framerate)
  print(f"Video saved at {video_name}")
  import matplotlib.pyplot as plt
  plt.plot(z_pos_vec)
  plt.show()

Context:

  • Operating system: Ubuntu 20.04
  • MuJoCo version: 3.2.2
Lingua principale
Python
Stelle
4.7k
Fork
765
Metriche di merge delle PR
Nessuna PR unita negli ultimi 30g

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di google-deepmind/dm_control

Tutte le issue di google-deepmind/dm_control

Issue simili

Altre issue su Python

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.