dm_control

repository·main·Indexed 26 days ago

https://github.com/google-deepmind/dm_control

Google DeepMind's software stack for physics-based simulation and Reinforcement Learning environments, built on top of the MuJoCo physics engine. It includes PyMJCF for manipulating MJCF models, a locomotion task library for building walker and arena environments, and a Blender plugin for exporting kinematic trees, geometry, and materials to MuJoCo.

Tokens
13.6K
Snippets
36
Records
77
Agent score
88%

What's inside dm_control

  1. Overview of the Locomotion task library

    main

    The dm_control.locomotion package provides reusable components for defining control tasks related to locomotion. It is designed to help users build environments involving walkers (detached bodies that move), arenas (the surroundings), and tasks (specifications for observations, rewards, initialization, and termination logic).

    New users should explore the examples/ subdirectory for preconfigured Reinforcement Learning (RL) environments associated with various research papers, which can serve as templates for custom environments.

  2. Use PyMJCF to manipulate MuJoCo MJCF models

    main

    PyMJCF provides a Python object model for MuJoCo's XML-based MJCF physics modeling language, similar to how the JavaScript DOM works for HTML. It allows for easy interaction, modification, and composition of MJCF models. A key feature is the ability to compose multiple separate MJCF models into a larger one, with automatic handling of name disambiguation and prefixing to prevent collisions.

    from dm_control import mjcf
    
    class Arm:
      def __init__(self, name):
        self.mjcf_model = mjcf.RootElement(model=name)
        self.upper_arm = self.mjcf_model.worldbody.add('body', name='upper_arm')
        self.shoulder = self.upper_arm.add('joint', name='shoulder', type='ball')
        self.upper_arm.add('geom', name='upper_arm', type='capsule',
                           pos=[0, 0, -0.15], size=[0.045, 0.15])
    
        self.forearm = self.upper_arm.add('body', name='forearm', pos=[0, 0, -0.3])
        self.elbow = self.forearm.add('joint', name='elbow',
                                      type='hinge', axis=[0, 1, 0])
        self.forearm.add('geom', name='forearm', type='capsule',
                         pos=[0, 0, -0.15], size=[0.045, 0.15])
    
    class UpperBody:
      def __init__(self):
        self.mjcf_model = mjcf.RootElement()
        self.mjcf_model.worldbody.add(
            'geom', name='torso', type='box', size=[0.15, 0.045, 0.25])
        left_shoulder_site = self.mjcf_model.worldbody.add(
            'site', size=[1e-6]*3, pos=[-0.15, 0, 0.25])
        right_shoulder_site = self.mjcf_model.worldbody.add(
            'site', size=[1e-6]*3, pos=[0.15, 0, 0.25])
    
        self.left_arm = Arm(name='left_arm')
        left_shoulder_site.attach(self.left_arm.mjcf_model)
    
        self.right_arm = Arm(name='right_arm')
        right_shoulder_site.attach(self.right_arm.mjcf_model)
    
    body = UpperBody()
    physics = mjcf.Physics.from_mjcf_model(body.mjcf_model)
  3. Use the Ant MJCF model for locomotion

    main
    The Ant MJCF model is a modified version of Philipp Moritz's original Ant model, specifically designed to be used as a walker within the dm_control.locomotion module. Note that because substantial modifications have been made to the original model, it should be treated as a distinct entity from the version found in pcmoritz/mujoco-control-ant.
  4. Quickstart: Run a locomotion environment episode

    main

    To use a preconfigured locomotion environment, you can build the environment using an example module, retrieve its action_spec to understand the control input bounds, and then step through the environment using random actions. This follows the standard dm_control environment interface.

    from dm_control import composer
    from dm_control.locomotion.examples import basic_cmu_2019
    import numpy as np
    
    # Build an example environment.
    env = basic_cmu_2019.cmu_humanoid_run_walls()
    
    # Get the `action_spec` describing the control inputs.
    action_spec = env.action_spec()
    
    # Step through the environment for one episode with random actions.
    time_step = env.reset()
    while not time_step.last():
      action = np.random.uniform(action_spec.minimum, action_spec.maximum,
                                 size=action_spec.shape)
      time_step = env.step(action)
      print("reward = {}, discount = {}, observations = {}.".format(
          time_step.reward, time_step.discount, time_step.observation))
  5. Quickstart with DeepMind MuJoCo Multi-Agent Soccer Environment

    main

    To use the DeepMind MuJoCo Multi-Agent Soccer environment, use dm_control.locomotion.soccer.load() to instantiate the environment. You can specify parameters such as team_size, time_limit, and walker_type. The environment returns a timestep object via reset() and step(), which contains rewards, discounts, and observations for all players.

    import numpy as np
    from dm_control.locomotion import soccer as dm_soccer
    
    # Instantiates a 2-vs-2 BOXHEAD soccer environment with episodes of 10 seconds
    # each. Upon scoring, the environment reset player positions and the episode
    # continues. In this example, players can physically block each other and the
    # ball is trapped within an invisible box encapsulating the field.
    env = dm_soccer.load(team_size=2,
                         time_limit=10.0,
                         disable_walker_contacts=False,
                         enable_field_box=True,
                         terminate_on_goal=False,
                         walker_type=dm_soccer.WalkerType.BOXHEAD)
    
    # Retrieves action_specs for all 4 players.
    action_specs = env.action_spec()
    
    # Step through the environment for one episode with random actions.
    timestep = env.reset()
    while not timestep.last():
      actions = []
      for action_spec in action_specs:
        action = np.random.uniform(
            action_spec.minimum, action_spec.maximum, size=action_spec.shape)
        actions.append(action)
      timestep = env.step(actions)
    
      for i in range(len(action_specs)):
        print(
            "Player {}: reward = {}, discount = {}, observations = {}.".format(
                i, timestep.reward[i], timestep.discount, timestep.observation[i]))
  6. Migrate from dm_control.mujoco.wrapper.mjbindings.types to mujoco

    main
    Starting with version 1.0.0, dm_control.mujoco.wrapper.mjbindings.types is deprecated and should no longer be used. Replace types from this module with their equivalents in the mujoco module. For example, replace types.MJRRECT with mujoco.MjrRect.
  7. Model geometry and materials for MuJoCo

    main

    MuJoCo uses parametric primitives and a specific Phong lighting model. The exporter handles Blender meshes by converting them to MuJoCo's native .msh format.

    Geometry and Meshes

    • Format: The exporter outputs .msh files. Since MuJoCo 2.1.2 supports .obj, it is recommended to convert .msh files to .obj using the msh2obj.py utility.
    • Submeshes: Because MuJoCo supports only one material per mesh, the exporter divides Blender meshes into submeshes based on face material assignments.
    • Caution (Inertia): Subdividing meshes into submeshes can change the calculated convex hull, which affects the mass and inertia properties in MuJoCo.
    • Double-sided materials: Using double-sided materials causes the exporter to duplicate faces with reverse winding orders. This affects physical properties like mass and inertia.
    • Scaling: The exporter resets scaling transforms on all bones and meshes to ensure affine reference frame transformations. This modifies your scene; you may need to manually undo this if you wish to keep your Blender scaling.
  8. Attach models to create compositional scenes in PyMJCF

    main

    You can attach a child model to a parent model to create complex scenes. When attaching a model to a site, PyMJCF creates an "attachment frame" (an empty body) in the parent model at the site's position and orientation. The contents of the child model's <worldbody> are then placed inside this frame.

    Important constraints:

    • Element Ownership: Elements of child models do not appear when traversing through the parent model.
    • Attachment Frame Contents: To maintain good modeling practices, the only allowed direct children of an attachment frame are <joint> and <inertial>. Other elements should be added to the <worldbody> of the attached model itself.
    • Single Attachment: A model can only be attached once. To use multiple copies of the same model, use copy.deepcopy or a class constructor to create new instances.
    import mjcf
    
    arena = mjcf.RootElement()
    arena.worldbody.add('geom', name='ground', type='plane', size=[10, 10, 1])
    
    robot = mjcf.from_xml_file('robot.xml')
    arena.attach(robot)
  9. Replace mjlib with mujoco module (Optional)

    main

    To make code more concise, you can replace dm_control.mujoco.wrapper.mjbindings.mjlib and its associated enums or constants with the mujoco module directly. All mujoco functions accept both the old and new enum values.

    # Before 1.0.0
    import dm_control.mujoco.wrapper.mjbindings
    mjlib = mjbindings.mjlib
    
    mjlib.mj_objectVelocity(
        physics.model.ptr, physics.data.ptr,
        enums.mjtObj.mjOBJ_SITE,
        site_id, vel, 0)
    
    # After 1.0.0
    import mujoco
    
    mujoco.mj_objectVelocity(
        physics.model.ptr, physics.data.ptr,
        mujoco.mjtObj.mjOBJ_SITE,
        site_id, vel, 0)