def recreate_both_templates(self) -> None: """Recreate both templates in this data.""" self.trained_template = util.instantiate_object( self.trained_definition, geometry.ORIGIN_LOCATION) self.untrained_template = util.instantiate_object( self.untrained_definition, geometry.ORIGIN_LOCATION) if self.untrained_definition else None if self.untrained_template: self.untrained_template['id'] = self.trained_template['id']
def test_put_object_in_container(): for obj_def in PICKUPABLE_DEFINITIONS: print(f'\nOBJECT={obj_def}') obj_location = geometry.calc_obj_pos({ 'x': 1, 'y': 0, 'z': 1 }, [], obj_def) obj = util.instantiate_object(obj_def, obj_location) obj_bounds = obj['shows'][0]['boundingBox'] containments = get_valid_containments(obj_def) if (len(containments) == 0 and not obj_def.get('enclosedAreas', []) and obj_def['type'] not in PICKUPABLE_OBJECTS_WITHOUT_CONTAINMENTS): print(f'pickupable object should have at least one containment: ' f'{obj_def}') assert False for container_def, containment in containments: area_index, rotations = containment container_location = geometry.calc_obj_pos( { 'x': -1, 'y': 0, 'z': -1 }, [], container_def) container = util.instantiate_object(container_def, container_location) put_object_in_container(obj, container, area_index, rotations[0]) assert obj['locationParent'] == container['id'] assert (obj['shows'][0]['position']['x'] == container_def['enclosedAreas'][0]['position']['x']) expected_position_y = ( container_def['enclosedAreas'][0]['position']['y'] - obj_def.get('offset', {}).get('y', 0) - (container_def['enclosedAreas'][area_index]['dimensions']['y'] / 2.0) + # noqa: E501 obj_def.get('positionY', 0)) assert obj['shows'][0]['position']['y'] == pytest.approx( expected_position_y) assert (obj['shows'][0]['position']['z'] == container_def['enclosedAreas'][0]['position']['z']) assert obj['shows'][0]['rotation'] assert obj['shows'][0]['boundingBox'] assert obj['shows'][0]['boundingBox'] != obj_bounds
def compute_objects( self, wall_material_name: str ) -> Tuple[List[Dict[str, Any]], List[Dict[str, Any]], List[List[Dict[ str, float]]]]: # add objects we need for the goal target_def = self.choose_object_def() performer_start = self.compute_performer_start() performer_position = performer_start['position'] # make sure the target is far enough away from the performer start while True: bounding_rects = [] target_location = geometry.calc_obj_pos(performer_position, bounding_rects, target_def) if target_location is None: raise GoalException('could not place target object') distance = geometry.position_distance(performer_start['position'], target_location['position']) if distance >= geometry.MINIMUM_START_DIST_FROM_TARGET: break target = instantiate_object(target_def, target_location) self._targets.append(target) all_objects = [target] self.add_objects(all_objects, bounding_rects, performer_position) return [target], all_objects, bounding_rects
def test_instantiate_object_multiple_materials(): materials.TEST1_MATERIALS = [('test_material_1', ['blue'])] materials.TEST2_MATERIALS = [('test_material_2', ['yellow'])] object_def = { 'type': 'sofa_1', 'dimensions': {'x': 1, 'y': 0.5, 'z': 0.5}, 'shape': 'sofa', 'size': 'huge', 'mass': 12.34, 'scale': {'x': 1, 'y': 1, 'z': 1}, 'attributes': [], 'materialCategory': ['test1', 'test2'] } object_location = { 'position': { 'x': 0.0, 'y': 0.0, 'z': 0.0 }, 'rotation': { 'x': 0.0, 'y': 0.0, 'z': 0.0 } } obj = instantiate_object(object_def, object_location) assert obj['materials'] == ['test_material_1', 'test_material_2'] assert obj['color'] == ['blue', 'yellow'] assert obj['goalString'] == 'huge massive blue yellow sofa' assert obj['info'] == [ 'huge', 'massive', 'blue', 'yellow', 'sofa', 'blue yellow', 'huge massive', 'huge blue yellow', 'huge sofa', 'massive blue yellow', 'massive sofa', 'blue yellow sofa', 'huge massive blue yellow sofa' ]
def move_to_container(target: Dict[str, Any], all_objects: List[Dict[str, Any]], bounding_rects: List[List[Dict[str, float]]], performer_position: Dict[str, float]) -> bool: """Try to find a random container that target will fit in. If found, set the target's locationParent, and add container to all_objects (and bounding_rects). Return True iff the target was put in a container.""" shuffled_containers = objects.get_enclosed_containers().copy() random.shuffle(shuffled_containers) for container_def in shuffled_containers: container_def = finalize_object_definition(container_def) area_index = geometry.can_contain(container_def, target) if area_index is not None: # try to place the container before we accept it container_location = geometry.calc_obj_pos(performer_position, bounding_rects, container_def) if container_location is not None: found_container = instantiate_object(container_def, container_location) found_area = container_def['enclosed_areas'][area_index] all_objects.append(found_container) target['locationParent'] = found_container['id'] target['shows'][0]['position'] = found_area['position'].copy() if 'rotation' not in target['shows'][0]: target['shows'][0]['rotation'] = geometry.ORIGIN.copy() return True return False
def test_instantiate_object_rotation(): object_def = { 'type': 'sofa_1', 'dimensions': {'x': 1, 'y': 0.5, 'z': 0.5}, 'shape': 'sofa', 'size': 'huge', 'mass': 12.34, 'scale': {'x': 1, 'y': 1, 'z': 1}, 'attributes': [], 'rotation': {'x': 1, 'y': 2, 'z': 3} } object_location = { 'position': { 'x': 0.0, 'y': 0.0, 'z': 0.0 }, 'rotation': { 'x': 30.0, 'y': 60.0, 'z': 90.0 } } obj = instantiate_object(object_def, object_location) assert obj['shows'][0]['rotation'] == {'x': 31.0, 'y': 62.0, 'z': 93.0}
def test_instantiate_object_salient_materials(): object_def = { 'type': 'sofa_1', 'dimensions': {'x': 1, 'y': 0.5, 'z': 0.5}, 'shape': 'sofa', 'size': 'huge', 'mass': 12.34, 'scale': {'x': 1, 'y': 1, 'z': 1}, 'attributes': [], 'salientMaterials': ['fabric', 'wood'] } object_location = { 'position': { 'x': 0.0, 'y': 0.0, 'z': 0.0 }, 'rotation': { 'x': 0.0, 'y': 0.0, 'z': 0.0 } } obj = instantiate_object(object_def, object_location) assert obj['salientMaterials'] == ['fabric', 'wood'] assert obj['goalString'] == 'huge massive fabric wood sofa' assert obj['info'] == [ 'huge', 'massive', 'fabric', 'wood', 'sofa', 'fabric wood', 'huge massive', 'huge fabric wood', 'huge sofa', 'massive fabric wood', 'massive sofa', 'fabric wood sofa', 'huge massive fabric wood sofa' ]
def test_instantiate_object_materials(): material_category = ['plastic'] materials_list = materials.PLASTIC_MATERIALS object_def = { 'type': str(uuid.uuid4()), 'info': [str(uuid.uuid4()), str(uuid.uuid4())], 'mass': random.random(), 'scale': 1.0, 'attributes': [], 'materialCategory': material_category } object_location = { 'position': { 'x': 0.0, 'y': 0.0, 'z': 0.0 }, 'rotation': { 'x': 0.0, 'y': 0.0, 'z': 0.0 } } obj = instantiate_object(object_def, object_location) assert obj['materials'][0] in (mat[0] for mat in materials_list)
def test_instantiate_object_offset(): offset = { 'x': random.random(), 'z': random.random() } object_def = { 'type': str(uuid.uuid4()), 'info': [str(uuid.uuid4()), str(uuid.uuid4())], 'mass': random.random(), 'scale': 1.0, 'attributes': [], 'offset': offset } x = random.random() z = random.random() object_location = { 'position': { 'x': x, 'y': 0.0, 'z': z }, 'rotation': { 'x': 0.0, 'y': 0.0, 'z': 0.0 } } obj = instantiate_object(object_def, object_location) position = obj['shows'][0]['position'] assert position['x'] == x - offset['x'] assert position['z'] == z - offset['z']
def test_instantiate_object(): object_def = { 'type': str(uuid.uuid4()), 'info': [str(uuid.uuid4()), str(uuid.uuid4())], 'mass': random.random(), 'attributes': ['foo', 'bar'], 'scale': 1.0 } object_location = { 'position': { 'x': 0.0, 'y': 0.0, 'z': 0.0 }, 'rotation': { 'x': 0.0, 'y': 0.0, 'z': 0.0 } } obj = instantiate_object(object_def, object_location) assert type(obj['id']) is str for prop in ('type', 'mass'): assert object_def[prop] == obj[prop] for attribute in object_def['attributes']: assert obj[attribute] is True assert obj['shows'][0]['position'] == object_location['position'] assert obj['shows'][0]['rotation'] == object_location['rotation']
def test_instantiate_object_size(): object_def = { 'type': str(uuid.uuid4()), 'info': [str(uuid.uuid4()), str(uuid.uuid4())], 'mass': random.random(), 'scale': 1.0, 'attributes': [], } object_location = { 'position': { 'x': 0.0, 'y': 0.0, 'z': 0.0 }, 'rotation': { 'x': 0.0, 'y': 0.0, 'z': 0.0 } } size_mapping = { 'pickupable': 'light', 'moveable': 'heavy', 'anythingelse': 'massive' } for attribute in size_mapping: size = size_mapping[attribute] object_def['attributes'] = [attribute] obj = instantiate_object(object_def, object_location) assert size in obj['info']
def test_instantiate_object_salient_materials(): salient_materials = ["plastic", "hollow"] object_def = { 'type': str(uuid.uuid4()), 'info': [str(uuid.uuid4()), str(uuid.uuid4())], 'mass': random.random(), 'scale': 1.0, 'attributes': [], 'salientMaterials': salient_materials } object_location = { 'position': { 'x': 0.0, 'y': 0.0, 'z': 0.0 }, 'rotation': { 'x': 0.0, 'y': 0.0, 'z': 0.0 } } obj = instantiate_object(object_def, object_location) assert obj['salientMaterials'] == salient_materials for sm in salient_materials: assert sm in obj['info']
def _create_b(self) -> Dict[str, Any]: a = self._scenes[0]['objects'][0] possible_defs = [] normalized_scale = a['shows'][0]['scale'] # cylinders have "special" scaling: scale.y is half what it is # for other objects (because Unity automatically doubles the # scale.y of cylinders) if a['type'] == 'cylinder': normalized_scale = normalized_scale.copy() normalized_scale['y'] *= 2 for obj_def in objects.OBJECTS_INTPHYS: if obj_def['type'] != a['type']: def_scale = obj_def['scale'] if obj_def['type'] == 'cylinder': def_scale = def_scale.copy() def_scale['y'] *= 2 if def_scale == normalized_scale: possible_defs.append(obj_def) if len(possible_defs) == 0: raise goal.GoalException( f'no valid choices for "b" object. a = {a}') b_def = random.choice(possible_defs) b_def = util.finalize_object_definition(b_def) b = util.instantiate_object(b_def, a['original_location'], a['materials_list']) logging.debug(f'a type: {a["type"]}\tb type: {b["type"]}') return b
def test_instantiate_object_size(): object_def = { 'type': 'sofa_1', 'dimensions': {'x': 1, 'y': 0.5, 'z': 0.5}, 'shape': 'sofa', 'size': 'huge', 'mass': 12.34, 'scale': {'x': 1, 'y': 1, 'z': 1}, 'attributes': [], } object_location = { 'position': { 'x': 0.0, 'y': 0.0, 'z': 0.0 }, 'rotation': { 'x': 0.0, 'y': 0.0, 'z': 0.0 } } size_mapping = { 'pickupable': 'light', 'moveable': 'heavy', 'anythingelse': 'massive' } for attribute in size_mapping: size = size_mapping[attribute] object_def['attributes'] = [attribute] obj = instantiate_object(object_def, object_location) assert size in obj['info']
def test_instantiate_object_untrained_size(): materials.TEST_MATERIALS = [('test_material', ['blue', 'yellow'])] object_def = { 'type': 'sofa_1', 'dimensions': {'x': 1, 'y': 0.5, 'z': 0.5}, 'untrainedSize': True, 'shape': 'sofa', 'size': 'huge', 'mass': 12.34, 'scale': 1.0, 'attributes': [], 'materialCategory': ['test'] } object_location = { 'position': { 'x': 0.0, 'y': 0.0, 'z': 0.0 }, 'rotation': { 'x': 0.0, 'y': 0.0, 'z': 0.0 } } obj = instantiate_object(object_def, object_location) assert obj['goalString'] == 'huge massive blue yellow sofa' assert obj['info'] == [ 'huge', 'massive', 'blue', 'yellow', 'sofa', 'blue yellow', 'huge massive', 'huge blue yellow', 'huge sofa', 'massive blue yellow', 'massive sofa', 'blue yellow sofa', 'huge massive blue yellow sofa', 'untrained size', 'untrained huge massive blue yellow sofa' ]
def create_assign_location_test_data(): data = ObjectData('ROLE', ObjectPlan(ObjectLocationPlan.NONE)) data.location_plan_list = [ ObjectLocationPlan.NONE, ObjectLocationPlan.BACK, ObjectLocationPlan.BETWEEN, ObjectLocationPlan.CLOSE, ObjectLocationPlan.FAR, ObjectLocationPlan.FRONT, ObjectLocationPlan.INSIDE_0, ObjectLocationPlan.RANDOM, ObjectLocationPlan.NONE, ObjectLocationPlan.BACK, ObjectLocationPlan.BETWEEN, ObjectLocationPlan.CLOSE, ObjectLocationPlan.FAR, ObjectLocationPlan.FRONT, ObjectLocationPlan.INSIDE_0, ObjectLocationPlan.RANDOM ] data.untrained_plan_list = [ False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False ] data.instance_list = [ None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None ] data.trained_definition = TROPHY data.trained_template = util.instantiate_object(data.trained_definition, { 'position': { 'x': 0, 'y': 0, 'z': 0 }, 'rotation': { 'x': 0, 'y': 0, 'z': 0 } }) return data
def test_instantiate_object_offset(): offset = { 'x': random.random(), 'z': random.random() } object_def = { 'type': 'sofa_1', 'dimensions': {'x': 1, 'y': 0.5, 'z': 0.5}, 'shape': 'sofa', 'size': 'huge', 'mass': 12.34, 'scale': {'x': 1, 'y': 1, 'z': 1}, 'attributes': [], 'offset': offset } x = random.random() z = random.random() object_location = { 'position': { 'x': x, 'y': 0.0, 'z': z }, 'rotation': { 'x': 0.0, 'y': 0.0, 'z': 0.0 } } obj = instantiate_object(object_def, object_location) position = obj['shows'][0]['position'] assert position['x'] == x - offset['x'] assert position['z'] == z - offset['z']
def test_instantiate_object_light_pickupable(): object_def = { 'type': 'sofa_1', 'dimensions': {'x': 1, 'y': 0.5, 'z': 0.5}, 'shape': 'sofa', 'size': 'huge', 'mass': 12.34, 'attributes': ['moveable', 'pickupable'], 'scale': {'x': 1, 'y': 1, 'z': 1} } object_location = { 'position': { 'x': 0.0, 'y': 0.0, 'z': 0.0 }, 'rotation': { 'x': 0.0, 'y': 0.0, 'z': 0.0 } } obj = instantiate_object(object_def, object_location) assert obj['goalString'] == 'huge light sofa' assert obj['info'] == [ 'huge', 'light', 'sofa', 'huge light', 'huge sofa', 'light sofa', 'huge light sofa' ] assert obj['moveable'] is True assert obj['pickupable'] is True
def test_instantiate_object_choose(): object_def = { 'type': 'sofa_1', 'chooseSize': [{ 'untrainedShape': True, 'shape': 'sofa', 'size': 'medium', 'attributes': ['moveable'], 'dimensions': {'x': 0.5, 'y': 0.25, 'z': 0.25}, 'mass': 12.34, 'scale': {'x': 0.5, 'y': 0.5, 'z': 0.5} }, { 'shape': 'sofa', 'size': 'huge', 'attributes': [], 'dimensions': {'x': 1, 'y': 0.5, 'z': 0.5}, 'mass': 56.78, 'scale': {'x': 1, 'y': 1, 'z': 1} }] } object_location = { 'position': { 'x': 0.0, 'y': 0.0, 'z': 0.0 }, 'rotation': { 'x': 0.0, 'y': 0.0, 'z': 0.0 } } obj = instantiate_object(object_def, object_location) assert obj['size'] == 'medium' or obj['size'] == 'huge' if obj['size'] == 'medium': assert obj['moveable'] assert obj['untrainedShape'] assert obj['info'] == [ 'medium', 'heavy', 'sofa', 'medium heavy', 'medium sofa', 'heavy sofa', 'medium heavy sofa', 'untrained shape', 'untrained medium heavy sofa' ] assert obj['goalString'] == 'medium heavy sofa' assert obj['dimensions'] == {'x': 0.5, 'y': 0.25, 'z': 0.25} assert obj['mass'] == 12.34 assert obj['shows'][0]['scale'] == {'x': 0.5, 'y': 0.5, 'z': 0.5} if obj['size'] == 'huge': assert 'moveable' not in obj assert not obj['untrainedShape'] assert obj['info'] == [ 'huge', 'massive', 'sofa', 'huge massive', 'huge sofa', 'massive sofa', 'huge massive sofa' ] assert obj['goalString'] == 'huge massive sofa' assert obj['dimensions'] == {'x': 1, 'y': 0.5, 'z': 0.5} assert obj['mass'] == 56.78 assert obj['shows'][0]['scale'] == {'x': 1, 'y': 1, 'z': 1}
def test_put_objects_in_container(): for obj_a_def in PICKUPABLE_DEFINITIONS: print(f'\nOBJECT_A={obj_a_def}') obj_a_location = geometry.calc_obj_pos(geometry.ORIGIN, [], obj_a_def) obj_a = util.instantiate_object(obj_a_def, obj_a_location) obj_a_bounds = obj_a['shows'][0]['boundingBox'] for obj_b_def in PICKUPABLE_DEFINITIONS: print(f'\nOBJECT_B={obj_b_def}') obj_b_location = geometry.calc_obj_pos(geometry.ORIGIN, [], obj_b_def) obj_b = util.instantiate_object(obj_b_def, obj_b_location) obj_b_bounds = obj_b['shows'][0]['boundingBox'] containments = get_valid_containments(obj_a_def, obj_b_def) if (len(containments) == 0 and not obj_a_def.get('enclosedAreas', []) and not obj_b_def.get('enclosedAreas', []) and obj_a_def['type'] not in PICKUPABLE_OBJECTS_WITHOUT_CONTAINMENTS and obj_b_def['type'] not in PICKUPABLE_OBJECTS_WITHOUT_CONTAINMENTS): print(f'pair of pickupable objects should have at least one ' f'containment:\nobject_a={obj_a_def}\n' f'object_b={obj_b_def}') assert False for container_def, containment in containments: area_index, rotations, orientation = containment container_location = geometry.calc_obj_pos( geometry.ORIGIN, [], container_def) container = util.instantiate_object(container_def, container_location) put_objects_in_container(obj_a, obj_b, container, area_index, orientation, rotations[0], rotations[1]) assert obj_a['locationParent'] == container['id'] assert obj_b['locationParent'] == container['id'] assert obj_a['shows'][0]['boundingBox'] assert obj_b['shows'][0]['boundingBox'] assert obj_a['shows'][0]['boundingBox'] != obj_a_bounds assert obj_b['shows'][0]['boundingBox'] != obj_b_bounds assert are_adjacent(obj_a, obj_b)
def add_objects(self, object_list: List[Dict[str, Any]], rectangles: List[List[Dict[str, float]]], performer_position: Dict[str, float]) -> None: """Add random objects to fill object_list to some random number of objects up to MAX_OBJECTS. If object_list already has more than this randomly determined number, no new objects are added.""" object_count = random.randint(1, MAX_OBJECTS) for i in range(len(object_list), object_count): object_def = self.choose_object_def() obj_location = geometry.calc_obj_pos(performer_position, rectangles, object_def) obj_info = object_def['info'][-1] targets_info = [tgt['info'][-1] for tgt in self._targets] if obj_info not in targets_info and obj_location is not None: obj = util.instantiate_object(object_def, obj_location) object_list.append(obj)
def test_instantiate_object(): object_def = { 'type': 'sofa_1', 'dimensions': {'x': 1, 'y': 0.5, 'z': 0.5}, 'shape': 'sofa', 'size': 'huge', 'mass': 12.34, 'attributes': ['foo', 'bar'], 'scale': {'x': 1, 'y': 1, 'z': 1} } object_location = { 'position': { 'x': 0.0, 'y': 0.0, 'z': 0.0 }, 'rotation': { 'x': 0.0, 'y': 0.0, 'z': 0.0 } } obj = instantiate_object(object_def, object_location) assert isinstance(obj['id'], str) assert obj['type'] == 'sofa_1' assert obj['dimensions'] == object_def['dimensions'] assert obj['goalString'] == 'huge massive sofa' assert obj['info'] == [ 'huge', 'massive', 'sofa', 'huge massive', 'huge sofa', 'massive sofa', 'huge massive sofa' ] assert obj['mass'] == 12.34 assert obj['untrainedCategory'] is False assert obj['untrainedColor'] is False assert obj['untrainedCombination'] is False assert obj['untrainedShape'] is False assert obj['untrainedSize'] is False assert obj['shape'] == ['sofa'] assert obj['size'] == 'huge' assert obj['weight'] == 'massive' assert obj['foo'] is True assert obj['bar'] is True assert obj['shows'][0]['stepBegin'] == 0 assert obj['shows'][0]['position'] == object_location['position'] assert obj['shows'][0]['rotation'] == object_location['rotation'] assert obj['shows'][0]['scale'] == object_def['scale']
def compute_objects( self, wall_material_name: str ) -> Tuple[List[Dict[str, Any]], List[Dict[str, Any]], List[List[Dict[ str, float]]]]: self._set_performer_start() self._set_target_def() self._set_target_location() self._target = instantiate_object(self._target_def, self._target_location) self._set_goal_objects() all_objects = [self._target] + self._goal_objects all_goal_objects = all_objects.copy() self.add_objects(all_objects, self._bounding_rects, self._performer_start['position']) return all_goal_objects, all_objects, self._bounding_rects
def test_move_to_container(): # find a tiny object so we know it will fit in *something* for obj_def in objects.OBJECTS_PICKUPABLE: obj_def = finalize_object_definition(obj_def) if 'tiny' in obj_def['info']: obj = instantiate_object(obj_def, geometry.ORIGIN_LOCATION) all_objects = [obj] tries = 0 while tries < 100: if move_to_container(obj, all_objects, [], geometry.ORIGIN): break tries += 1 if tries == 100: logging.error('could not put the object in any container') container_id = all_objects[1]['id'] assert obj['locationParent'] == container_id return assert False, 'could not find a tiny object'
def test_mcs_209(): obj_defs = OBJECTS_INTPHYS.copy() random.shuffle(obj_defs) obj_def = next((od for od in obj_defs if 'rotation' in od)) obj = instantiate_object(obj_def, {'position': ORIGIN}) assert obj['shows'][0]['rotation'] == obj_def['rotation'] class TestGoal(IntPhysGoal): TEMPLATE = {'type_list': [], 'metadata': {}} pass goal = TestGoal() objs = goal._get_objects_moving_across('dummy', 55) for obj in objs: assert obj['shows'][0]['stepBegin'] == obj['forces'][0]['stepBegin'] body = {'wallMaterial': 'dummy'} goal._scenery_count = 0 goal.update_body(body, False)
def _compute_scenery(self): MIN_VISIBLE_X = -6.5 MAX_VISIBLE_X = 6.5 MIN_Z = 3.25 MAX_Z = 4.95 def random_x(): return random_real(MIN_VISIBLE_X, MAX_VISIBLE_X, MIN_RANDOM_INTERVAL) def random_z(): # Choose values so the scenery is placed between the # moving IntPhys objects and the room's wall. return random_real(MIN_Z, MAX_Z, MIN_RANDOM_INTERVAL) self._scenery_count = random.choices((0, 1, 2, 3, 4, 5), (50, 10, 10, 10, 10, 10))[0] scenery_list = [] scenery_rects = [] scenery_defs = objects.OBJECTS_MOVEABLE + objects.OBJECTS_IMMOBILE for i in range(self._scenery_count): location = None while location is None: scenery_def = finalize_object_definition( random.choice(scenery_defs)) location = geometry.calc_obj_pos(geometry.ORIGIN, scenery_rects, scenery_def, random_x, random_z) if location is not None: # check that the bounds are valid for point in location['bounding_box']: x = point['x'] z = point['z'] if x < MIN_VISIBLE_X or x > MAX_VISIBLE_X or \ z < MIN_Z or z > MAX_Z: # reset location so we try again location = None break scenery_obj = instantiate_object(scenery_def, location) scenery_list.append(scenery_obj) return scenery_list
def _set_goal_objects(self) -> None: targets = objects.get_all_object_defs() random.shuffle(targets) target2_def = next( (tgt for tgt in targets if 'stackTarget' in tgt.get('attributes', [])), None) if target2_def is None: raise ValueError(f'No stack targets found for transferral goal') # ensure the targets aren't too close together while True: new_bounding_rects = self._bounding_rects.copy() target2_location = geometry.calc_obj_pos( self._performer_start['position'], new_bounding_rects, target2_def) distance = geometry.position_distance( self._target['shows'][0]['position'], target2_location['position']) if distance >= geometry.MINIMUM_TARGET_SEPARATION: break self._bounding_rects = new_bounding_rects target2 = instantiate_object(target2_def, target2_location) self._goal_objects = [target2]
def _get_objects_falling_down(self, room_wall_material_name: str) \ -> Tuple[List[Dict[str, Any]], List[Dict[str, Any]]]: MAX_POSITION_TRIES = 100 MIN_OCCLUDER_SEPARATION = 0.5 # min scale for each occluder / 2, plus 0.5 separation # divided by the smaller scale factor for distance from viewpoint min_obj_distance = ( IntPhysGoal.MIN_OCCLUDER_SCALE / 2 + IntPhysGoal.MIN_OCCLUDER_SCALE / 2 + MIN_OCCLUDER_SEPARATION) / IntPhysGoal.FAR_X_PERSPECTIVE_FACTOR num_objects = random.choice((1, 2)) object_list = [] for i in range(num_objects): found_space = False # It doesn't matter how close the objects are to each # other, but each one must have an occluder, and those # have to be a certain distance apart, so these objects # do, too. for _ in range(MAX_POSITION_TRIES): # Choose x so the occluder (for this object) is fully # in the camera's viewport and with a gap so we can # see when an object enters/leaves the scene. x_position = random_real(-2.5, 2.5, MIN_RANDOM_INTERVAL) too_close = False for obj in object_list: distance = abs(obj['shows'][0]['position']['x'] - x_position) too_close = distance < min_obj_distance if too_close: break if not too_close: found_space = True break if not found_space: raise GoalException( f'Could not place {i+1} objects to fall down') location = { 'position': { 'x': x_position, 'y': 3.8, # ensure the object starts above the camera viewport 'z': random.choice( (IntPhysGoal.OBJECT_NEAR_Z, IntPhysGoal.OBJECT_FAR_Z)) } } obj_def = random.choice(objects.OBJECTS_INTPHYS) obj = instantiate_object(obj_def, location) obj['shows'][0]['stepBegin'] = random.randint( IntPhysGoal.EARLIEST_ACTION_START_STEP, IntPhysGoal.LATEST_ACTION_FALL_DOWN_START_STEP) obj['intphys_option'] = {'position_y': obj_def['position_y']} object_list.append(obj) # place required occluders, then (maybe) some random ones num_occluders = self._get_num_occluders_falling_down(num_objects) logging.debug( f'num_objects = {num_objects}\tnum_occluders = {num_occluders}') occluders = [] non_room_wall_materials = [ m for m in materials.CEILING_AND_WALL_MATERIALS if m[0] != room_wall_material_name ] for i in range(num_objects): paired_obj = object_list[i] min_scale = min( max(paired_obj['shows'][0]['scale']['x'], IntPhysGoal.MIN_OCCLUDER_SCALE), 1) x_position = paired_obj['shows'][0]['position']['x'] paired_z = paired_obj['shows'][0]['position']['z'] factor = IntPhysGoal.NEAR_X_PERSPECTIVE_FACTOR if paired_z == IntPhysGoal.OBJECT_NEAR_Z \ else IntPhysGoal.FAR_X_PERSPECTIVE_FACTOR # Determine the biggest scale we could use for the new # occluder (up to 1) so it isn't too close to any of the # others. max_scale = IntPhysGoal.MAX_OCCLUDER_SCALE for occluder in occluders: distance = abs(occluder['shows'][0]['position']['x'] - x_position) scale = 2 * (distance - occluder['shows'][0]['scale']['x'] / 2.0 - MIN_OCCLUDER_SEPARATION) if scale < 0: raise GoalException( f'Placed objects too close together after all ({distance})' ) if scale < max_scale: max_scale = scale if max_scale <= min_scale: x_scale = min_scale else: x_scale = random_real(min_scale, max_scale, MIN_RANDOM_INTERVAL) adjusted_x = x_position * factor occluder_pair = objects.create_occluder( random.choice(non_room_wall_materials)[0], random.choice(materials.METAL_MATERIALS)[0], adjusted_x, x_scale, True) # occluded_id needed by SpatioTemporalContinuityQuartet if 'intphys_option' not in occluder_pair[0]: occluder_pair[0]['intphys_option'] = {} occluder_pair[0]['intphys_option']['occluded_id'] = paired_obj[ 'id'] occluders.extend(occluder_pair) self._add_occluders(occluders, num_occluders - num_objects, non_room_wall_materials, True) return object_list, occluders
def _get_objects_moving_across(self, room_wall_material_name: str, last_action_end_step: int, earliest_action_start_step: int = EARLIEST_ACTION_START_STEP, valid_positions: Iterable = frozenset(Position), positions = None, valid_defs: List[Dict[str, Any]] = objects.OBJECTS_INTPHYS) \ -> List[Dict[str, Any]]: """Get objects to move across the scene. Returns objects.""" num_objects = self._get_num_objects_moving_across() # The following x positions start outside the camera viewport # and ensure that objects with scale 1 don't collide with each # other. object_positions = { IntPhysGoal.Position.RIGHT_FIRST_NEAR: (4.2, IntPhysGoal.OBJECT_NEAR_Z), IntPhysGoal.Position.RIGHT_LAST_NEAR: (5.3, IntPhysGoal.OBJECT_NEAR_Z), IntPhysGoal.Position.RIGHT_FIRST_FAR: (4.8, IntPhysGoal.OBJECT_FAR_Z), IntPhysGoal.Position.RIGHT_LAST_FAR: (5.9, IntPhysGoal.OBJECT_FAR_Z), IntPhysGoal.Position.LEFT_FIRST_NEAR: (-4.2, IntPhysGoal.OBJECT_NEAR_Z), IntPhysGoal.Position.LEFT_LAST_NEAR: (-5.3, IntPhysGoal.OBJECT_NEAR_Z), IntPhysGoal.Position.LEFT_FIRST_FAR: (-4.8, IntPhysGoal.OBJECT_FAR_Z), IntPhysGoal.Position.LEFT_LAST_FAR: (-5.9, IntPhysGoal.OBJECT_FAR_Z) } exclusions = { IntPhysGoal.Position.RIGHT_FIRST_NEAR: (IntPhysGoal.Position.LEFT_FIRST_NEAR, IntPhysGoal.Position.LEFT_LAST_NEAR), IntPhysGoal.Position.RIGHT_LAST_NEAR: (IntPhysGoal.Position.LEFT_FIRST_NEAR, IntPhysGoal.Position.LEFT_LAST_NEAR), IntPhysGoal.Position.RIGHT_FIRST_FAR: (IntPhysGoal.Position.LEFT_FIRST_FAR, IntPhysGoal.Position.LEFT_LAST_FAR), IntPhysGoal.Position.RIGHT_LAST_FAR: (IntPhysGoal.Position.LEFT_FIRST_FAR, IntPhysGoal.Position.LEFT_LAST_FAR), IntPhysGoal.Position.LEFT_FIRST_NEAR: (IntPhysGoal.Position.RIGHT_FIRST_NEAR, IntPhysGoal.Position.RIGHT_LAST_NEAR), IntPhysGoal.Position.LEFT_LAST_NEAR: (IntPhysGoal.Position.RIGHT_FIRST_NEAR, IntPhysGoal.Position.RIGHT_LAST_NEAR), IntPhysGoal.Position.LEFT_FIRST_FAR: (IntPhysGoal.Position.RIGHT_FIRST_FAR, IntPhysGoal.Position.RIGHT_LAST_FAR), IntPhysGoal.Position.LEFT_LAST_FAR: (IntPhysGoal.Position.RIGHT_FIRST_FAR, IntPhysGoal.Position.RIGHT_LAST_FAR) } # Object in key position must have acceleration <= # acceleration for object in value position (e.g., object in # RIGHT_LAST_NEAR must have acceleration <= acceleration for # object in RIGHT_FIRST_NEAR). acceleration_ordering = { IntPhysGoal.Position.RIGHT_LAST_NEAR: IntPhysGoal.Position.RIGHT_FIRST_NEAR, IntPhysGoal.Position.RIGHT_LAST_FAR: IntPhysGoal.Position.RIGHT_FIRST_FAR, IntPhysGoal.Position.LEFT_LAST_NEAR: IntPhysGoal.Position.LEFT_FIRST_NEAR, IntPhysGoal.Position.LEFT_LAST_FAR: IntPhysGoal.Position.LEFT_FIRST_FAR } available_locations = set(valid_positions) location_assignments = {} new_objects = [] for i in range(num_objects): location = random.choice(list(available_locations)) available_locations.remove(location) for loc in exclusions[location]: available_locations.discard(loc) obj_def = finalize_object_definition(random.choice(valid_defs)) remaining_intphys_options = obj_def['intphys_options'].copy() while len(remaining_intphys_options) > 0: intphys_option = random.choice(remaining_intphys_options) if location in acceleration_ordering and \ acceleration_ordering[location] in location_assignments: # ensure the objects won't collide acceleration = abs(intphys_option['force']['x'] / obj_def['mass']) other_obj = location_assignments[ acceleration_ordering[location]] other_acceleration = abs( other_obj['intphys_option']['force']['x'] / other_obj['mass']) collision = acceleration > other_acceleration if not collision: break elif len(remaining_intphys_options) == 1: # last chance, so just swap the items to make their relative acceleration "ok" location_assignments[location] = other_obj location = acceleration_ordering[location] location_assignments[ location] = None # to be assigned later break else: break remaining_intphys_options.remove(intphys_option) object_location = { 'position': { 'x': object_positions[location][0], 'y': intphys_option['y'] + obj_def['position_y'], 'z': object_positions[location][1] } } obj = instantiate_object(obj_def, object_location) location_assignments[location] = obj position_by_step = copy.deepcopy( intphys_option['position_by_step']) object_position_x = object_positions[location][0] # adjust position_by_step and remove outliers new_positions = [] for position in position_by_step: if location in (IntPhysGoal.Position.RIGHT_FIRST_NEAR, IntPhysGoal.Position.RIGHT_LAST_NEAR, IntPhysGoal.Position.RIGHT_FIRST_FAR, IntPhysGoal.Position.RIGHT_LAST_FAR): position = object_position_x - position else: position = object_position_x + position new_positions.append(position) if location in (IntPhysGoal.Position.RIGHT_FIRST_NEAR, IntPhysGoal.Position.RIGHT_LAST_NEAR, IntPhysGoal.Position.LEFT_FIRST_NEAR, IntPhysGoal.Position.LEFT_LAST_NEAR): max_x = IntPhysGoal.VIEWPORT_LIMIT_NEAR + obj_def['scale'][ 'x'] / 2.0 * IntPhysGoal.VIEWPORT_PERSPECTIVE_FACTOR else: max_x = IntPhysGoal.VIEWPORT_LIMIT_FAR + obj_def['scale'][ 'x'] / 2.0 * IntPhysGoal.VIEWPORT_PERSPECTIVE_FACTOR filtered_position_by_step = [ position for position in new_positions if (abs(position) <= max_x) ] # set shows.stepBegin min_step_begin = earliest_action_start_step if location in acceleration_ordering and acceleration_ordering[ location] in location_assignments: min_step_begin = location_assignments[ acceleration_ordering[location]]['shows'][0]['stepBegin'] max_step_begin = last_action_end_step - len( filtered_position_by_step) if min_step_begin >= max_step_begin: stepBegin = min_step_begin else: stepBegin = random.randint(min_step_begin, max_step_begin) obj['shows'][0]['stepBegin'] = stepBegin obj['forces'] = [{ 'stepBegin': stepBegin, 'stepEnd': last_action_end_step, 'vector': intphys_option['force'] }] if location in (IntPhysGoal.Position.RIGHT_FIRST_NEAR, IntPhysGoal.Position.RIGHT_LAST_NEAR, IntPhysGoal.Position.RIGHT_FIRST_FAR, IntPhysGoal.Position.RIGHT_LAST_FAR): obj['forces'][0]['vector']['x'] *= -1 intphys_option['position_by_step'] = filtered_position_by_step intphys_option['position_y'] = obj_def['position_y'] obj['intphys_option'] = intphys_option new_objects.append(obj) if positions is not None: positions.append(location) return new_objects