in mujoco_worldgen/objs/obj_from_xml.py [0: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