Ejemplo n.º 1
0
    def draw(self, context, rect):
        """Draws the overlay.

    Args:
      context: A `types.MJRCONTEXT` pointer.
      rect: A `types.MJRRECT`.
    """
        mjlib.mjr_overlay(self.style, self.position, rect,
                          util.to_binary_string(self.title),
                          util.to_binary_string(self.body), context)
def _temporary_vfs(filenames_and_contents):
    """Creates a temporary VFS containing one or more files.

  Args:
    filenames_and_contents: A dict containing `{filename: contents}` pairs.
      The length of each filename must not exceed 98 characters.

  Yields:
    A `types.MJVFS` instance.

  Raises:
    Error: If a file cannot be added to the VFS, or if an error occurs when
      looking up the filename.
    ValueError: If the length of a filename exceeds 98 characters.
  """
    vfs = types.MJVFS()
    mjlib.mj_defaultVFS(vfs)
    for filename, contents in six.iteritems(filenames_and_contents):
        if len(filename) > _MAX_VFS_FILENAME_CHARACTERS:
            raise ValueError(
                _VFS_FILENAME_TOO_LONG.format(
                    length=len(filename),
                    limit=_MAX_VFS_FILENAME_CHARACTERS,
                    filename=filename))
        filename = util.to_binary_string(filename)
        contents = util.to_binary_string(contents)
        _, extension = os.path.splitext(filename)
        # For XML files we need to append a NULL byte, otherwise MuJoCo's parser
        # can sometimes read past the end of the string. However, we should *not*
        # do this for other file types (in particular for STL meshes, where this
        # causes MuJoCo's compiler to complain that the file size is incorrect).
        append_null = extension.lower() == b".xml"
        num_bytes = len(contents) + append_null
        retcode = mjlib.mj_makeEmptyFileVFS(vfs, filename, num_bytes)
        if retcode == 1:
            raise Error("Failed to create {!r}: VFS is full.".format(filename))
        elif retcode == 2:
            raise Error(
                "Failed to create {!r}: duplicate filename.".format(filename))
        file_index = mjlib.mj_findFileVFS(vfs, filename)
        if file_index == -1:
            raise Error("Could not find {!r} in the VFS".format(filename))
        vf = vfs.filedata[file_index]
        vf_as_char_arr = ctypes.cast(vf,
                                     ctypes.POINTER(ctypes.c_char * num_bytes))
        vf_as_char_arr.contents[:len(contents)] = contents
        if append_null:
            vf_as_char_arr.contents[-1] = _NULL
    try:
        yield vfs
    finally:
        mjlib.mj_deleteVFS(vfs)  # Ensure that we free the VFS afterwards.
Ejemplo n.º 3
0
def _get_model_ptr_from_binary(binary_path=None, byte_string=None):
  """Returns a pointer to an mjModel from the contents of a MuJoCo model binary.

  Args:
    binary_path: Path to an MJB file (as produced by MjModel.save_binary).
    byte_string: String of bytes (as returned by MjModel.to_bytes).

    One of `binary_path` or `byte_string` must be specified.

  Returns:
    A `ctypes.POINTER` to a new `mjbindings.types.MJMODEL` instance.

  Raises:
    TypeError: If both or neither of `byte_string` and `binary_path`
      are specified.
  """
  if binary_path is None and byte_string is None:
    raise TypeError(
        "At least one of `byte_string` or `binary_path` must be specified.")
  elif binary_path is not None and byte_string is not None:
    raise TypeError(
        "Only one of `byte_string` or `binary_path` may be specified.")

  _maybe_register_license()

  if byte_string is not None:
    with _temporary_vfs({_FAKE_BINARY_FILENAME: byte_string}) as vfs:
      ptr = mjlib.mj_loadModel(_FAKE_BINARY_FILENAME, vfs)
  else:
    ptr = mjlib.mj_loadModel(util.to_binary_string(binary_path), None)

  # Free resources when the ctypes pointer is garbage collected.
  _create_finalizer(ptr, mjlib.mj_deleteModel)

  return ptr
Ejemplo n.º 4
0
def export_with_assets(mjcf_model, out_dir, out_file_name=None):
    """Saves mjcf.model in the given directory in MJCF (XML) format.

  Creates an MJCF XML file named `out_file_name` in the specified `out_dir`, and
  writes all of its assets into the same directory.

  Args:
    mjcf_model: `mjcf.RootElement` instance to export.
    out_dir: Directory to save the model and assets. Will be created if it does
      not already exist.
    out_file_name: (Optional) Name of the XML file to create. Defaults to the
      model name (`mjcf_model.model`) suffixed with '.xml'.

  Raises:
    ValueError: If `out_file_name` is a string that does not end with '.xml'.
  """
    if out_file_name is None:
        out_file_name = mjcf_model.model + '.xml'
    elif not out_file_name.lower().endswith('.xml'):
        raise ValueError('If `out_file_name` is specified it must end with '
                         '\'.xml\': got {}'.format(out_file_name))
    assets = mjcf_model.get_assets()
    # This should never happen because `mjcf` does not support `.xml` assets.
    assert out_file_name not in assets
    assets[out_file_name] = mjcf_model.to_xml_string()
    if not os.path.exists(out_dir):
        os.makedirs(out_dir)
    for filename, contents in assets.items():
        with open(os.path.join(out_dir, filename), 'wb') as f:
            f.write(util.to_binary_string(contents))
Ejemplo n.º 5
0
def _maybe_register_license(path=None):
    """Registers the MuJoCo license if not already registered.

  Args:
    path: Optional custom path to license key file.

  Raises:
    Error: If the license could not be registered.
  """
    with _REGISTRATION_LOCK:
        global _REGISTERED
        if not _REGISTERED:
            if path is None:
                path = util.get_mjkey_path()
            # TODO(b/176220357): Repeatedly activating a trial license results in
            #                    errors (for example this could happen if
            #                    `mj_activate` was already called by another library
            #                    within the same process). To avoid such errors we
            #                    unconditionally deactivate any active licenses before
            #                    calling `mj_activate`.
            mjlib.mj_deactivate()
            result = mjlib.mj_activate(util.to_binary_string(path))
            if result == 1:
                _REGISTERED = True
                # Internal analytics of mj_activate.
            elif result == 0:
                raise Error("Could not register license.")
            else:
                raise Error(
                    "Unknown registration error (code: {})".format(result))
Ejemplo n.º 6
0
    def render(self, context, viewport, location):
        """Renders the overlay on screen.

    Args:
      context: MjrContext instance.
      viewport: Viewport instance.
      location: Value defined in PanelLocation enum.
    """
        columns = self._model.get_columns()
        if not columns:
            return

        columns = np.asarray(columns)
        left_column = '\n'.join(columns[:, 0])
        right_column = '\n'.join(columns[:, 1])
        mjlib.mjr_overlay(enums.mjtFont.mjFONT_NORMAL, location.value,
                          viewport.mujoco_rect,
                          util.to_binary_string(left_column),
                          util.to_binary_string(right_column), context.ptr)
def _load_xml(filename, vfs_or_none):
    """Invokes `mj_loadXML` with logging/error handling."""
    error_buf = ctypes.create_string_buffer(_ERROR_BUFSIZE)
    model_ptr = mjlib.mj_loadXML(util.to_binary_string(filename), vfs_or_none,
                                 error_buf, _ERROR_BUFSIZE)
    if not model_ptr:
        raise Error(util.to_native_string(error_buf.value))
    elif error_buf.value:
        logging.warning(util.to_native_string(error_buf.value))

    # Free resources when the ctypes pointer is garbage collected.
    _create_finalizer(model_ptr, mjlib.mj_deleteModel)

    return model_ptr
Ejemplo n.º 8
0
  def testFileNameTrimming(self):
    original_filename = (
        'THIS_IS_AN_EXTREMELY_LONG_FILENAME_THAT_WOULD_CAUSE_MUJOCO_TO_COMPLAIN'
        '_THAT_ITS_INTERNAL_LENGTH_LIMIT_IS_EXCEEDED_IF_NOT_TRIMMED_DOWN')
    extension = '.some_extension'
    asset = attribute.Asset(
        contents='', extension=extension, prefix=original_filename)
    vfs_filename = asset.get_vfs_filename()
    self.assertLen(vfs_filename, constants.MAX_VFS_FILENAME_LENGTH)

    vfs = types.MJVFS()
    mjlib.mj_defaultVFS(vfs)
    success_code = 0
    retval = mjlib.mj_makeEmptyFileVFS(
        vfs, util.to_binary_string(vfs_filename), 1)
    self.assertEqual(retval, success_code)
    mjlib.mj_deleteVFS(vfs)
Ejemplo n.º 9
0
  def get_vfs_filename(self):
    """Returns the name of the asset file as registered in MuJoCo's VFS."""
    # Hash the contents of the asset to get a unique identifier.
    hash_string = hashlib.sha1(util.to_binary_string(self.contents)).hexdigest()
    # Prepend the prefix, if one exists.
    if self.prefix:
      prefix = self.prefix
      raw_length = len(prefix) + len(hash_string) + len(self.extension) + 1
      if raw_length > constants.MAX_VFS_FILENAME_LENGTH:
        trim_amount = raw_length - constants.MAX_VFS_FILENAME_LENGTH
        prefix = prefix[:-trim_amount]
      filename = '-'.join([prefix, hash_string])
    else:
      filename = hash_string

    # An extension is needed because MuJoCo's compiler looks at this when
    # deciding how to load meshes and heightfields.
    return filename + self.extension
def save_last_parsed_model_to_xml(xml_path, check_model=None):
    """Writes a description of the most recently loaded model to an MJCF XML file.

  Args:
    xml_path: Path to the output XML file.
    check_model: Optional `MjModel` instance. If specified, this model will be
      checked to see if it is the most recently parsed one, and a ValueError
      will be raised otherwise.
  Raises:
    Error: If MuJoCo encounters an error while writing the XML file.
    ValueError: If `check_model` was passed, and this model is not the most
      recently parsed one.
  """
    if check_model and check_model.ptr is not _LAST_PARSED_MODEL_PTR:
        raise ValueError(_NOT_LAST_PARSED_ERROR)
    error_buf = ctypes.create_string_buffer(_ERROR_BUFSIZE)
    mjlib.mj_saveLastXML(util.to_binary_string(xml_path),
                         _LAST_PARSED_MODEL_PTR, error_buf, _ERROR_BUFSIZE)
    if error_buf.value:
        raise Error(error_buf.value)
Ejemplo n.º 11
0
def _maybe_register_license(path=None):
  """Registers the MuJoCo license if not already registered.

  Args:
    path: Optional custom path to license key file.

  Raises:
    Error: If the license could not be registered.
  """
  global _REGISTERED
  if not _REGISTERED:
    if path is None:
      path = util.get_mjkey_path()
    result = mjlib.mj_activate(util.to_binary_string(path))
    if result == 1:
      _REGISTERED = True
    elif result == 0:
      raise Error("Could not register license.")
    else:
      raise Error("Unknown registration error (code: {})".format(result))
Ejemplo n.º 12
0
  def name2id(self, name, object_type):
    """Returns the integer ID of a specified MuJoCo object.

    Args:
      name: String specifying the name of the object to query.
      object_type: The type of the object. Can be either a lowercase string
        (e.g. 'body', 'geom') or an `mjtObj` enum value.

    Returns:
      An integer object ID.

    Raises:
      Error: If `object_type` is not a valid MuJoCo object type, or if no object
        with the corresponding name and type was found.
    """
    if not isinstance(object_type, int):
      object_type = _str2type(object_type)
    obj_id = mjlib.mj_name2id(
        self.ptr, object_type, util.to_binary_string(name))
    if obj_id == -1:
      raise Error("Object of type {!r} with name {!r} does not exist.".format(
          _type2str(object_type), name))
    return obj_id
Ejemplo n.º 13
0
def main(num_objs, path, model_name, gRange_inp=0.6):
	global gRange
	#gRange = gRange_inp
	xml_file = os.path.join(path, "assets", model_name)
	mjcf_model = etree.parse(xml_file)
	# pdb.set_trace()
	#mjcf_model = mjcf.from_path(xml_file)
	worldbody = mjcf_model.find('./worldbody')
	build_walls = True
	targets = []
	floor = create_floor()
	worldbody.append(floor)
	worldbody.append(make_camera())
	if num_objs:
		for obj in range(num_objs):
			body, pos, target = make_object(obj, mjcf_model)
			worldbody.append(body)
			targets.append(target)
	else:
		targets.append(make_target(0, mjcf_model))

	for tar in targets:
		worldbody.append(tar)

	if build_walls:
		walls = make_walls()
		for wall in walls:
			worldbody.append(wall)
	agent, pos = make_agent(0)
	worldbody.append(agent)	

	contents = etree.tostring(mjcf_model, pretty_print=True)
	contents= minidom.parseString(contents).toprettyxml(indent=" ")

	with open(os.path.join(path, "assets/point/", 'output.xml'), 'wb') as f:
		f.write(util.to_binary_string(contents))
Ejemplo n.º 14
0
 def save_binary(self, binary_path):
   """Saves the MjModel instance to a binary file."""
   mjlib.mj_saveModel(self.ptr, util.to_binary_string(binary_path), None, 0)
Ejemplo n.º 15
0
def _str2type(type_str):
  type_id = mjlib.mju_str2Type(util.to_binary_string(type_str))
  if not type_id:
    raise Error("{!r} is not a valid object type name.".format(type_str))
  return type_id