Exemplo n.º 1
0
    def generate(self, random_state, world_params, placement_size):
        # Only do this once, because it sometimes picks object at random
        self.xml_path = self._generate_xml_path(random_state)
        self.xml = parse_file(self.xml_path)
        self.placements = OrderedDict()
        bodies = []
        for body in self.xml["worldbody"]["body"]:
            name = body.get('@name', '')
            if name.startswith('annotation:'):
                # Placement annotation, for example the insides of shelves,
                # or outer_bound, which determines size and "top" placement.
                assert '@pos' in body, "Annotation %s must have pos" % name
                assert 'geom' in body, "Annotation %s must have geom" % name
                assert len(body['geom']) == 1, "%s must have 1 geom" % name
                geom = body['geom'][0]
                assert geom.get('@type') == 'box', "%s must have box" % name
                assert '@size' in geom, "%s geom must have size" % name
                if '@pos' in geom:
                    # Worldgen places objects by moving qpos (slide joints)
                    # to put them in position, and their final position is:
                    #   qpos + pos + parent_pos + ...
                    # In order for objects to end up where worldgen wants them,
                    # all of the pos + parent_pos + ... have to equal zero.
                    # Otherwise the offsets get messed up.
                    assert np.array_equal(geom['@pos'], np.zeros(3)), \
                        "%s: Set pos on body instead of geom" % name
                size = geom['@size'] * 2  # given as halfsize
                origin = body['@pos'] - (size / 2)  # given as center coord
                placement_name = name[len('annotation:'):]
                if placement_name == 'outer_bound':
                    # Note: "top" placement is not automatically created
                    # Must be explicitly added in XML
                    # bin/annotate.py --suggestions will show possible ones
                    self.size = size
                    if world_params.show_outer_bounds:
                        bodies.append(body)
                    continue
                placement = OrderedDict(size=size, origin=origin)
                self.placements[placement_name] = placement

        for body in self.xml["worldbody"]["body"]:
            name = body.get('@name', '')
            if not name.startswith(
                    "annotation:"):  # Not an annotation, must be a main body
                if self.name is not None:
                    body_name = self.name
                    if name:
                        body_name += ":" + name
                    body['@name'] = body_name
                    body["@pos"] = body["@pos"]
                bodies.append(body)
        self.xml['worldbody']['body'] = bodies
Exemplo n.º 2
0
def get_size_from_xml(obj):
    '''
        Args:
            obj (worldgen.Obj): worldgen object
        Returns: size of object annotation:outerbound if it exists, None if it doesn't
    '''
    outer_bound = None
    for body in parse_file(obj._generate_xml_path())['worldbody']['body']:
        if body.get('@name', '') == 'annotation:outer_bound':
            outer_bound = body
    if outer_bound is None:
        return None
    else:
        return outer_bound['geom'][0]['@size'][:2] * 2
Exemplo n.º 3
0
def load_model_from_path_fix_paths(xml_path, zero_gravity=True):
    """
    Loads model from XML path. Ensures that
    all assets are locally available. If needed might rename
    paths.

    :param xml_path: path to xml file
    :param zero_gravity: if true, zero gravity in model
    """
    xml_dict = parse_file(xml_path, enforce_validation=False)

    if zero_gravity:
        # zero gravity so that the object doesn't fall down
        option = xml_dict.setdefault('option', OrderedDict())
        option['@gravity'] = np.zeros(3)
    xml = unparse_dict(xml_dict)
    model = load_model_from_xml(xml)
    return model