예제 #1
0
 def choose_object_def(self) -> Dict[str, Any]:
     """Pick one object definition (to be added to the scene) and return a copy of it."""
     object_def_list = random.choices([
         objects.OBJECTS_PICKUPABLE, objects.OBJECTS_MOVEABLE,
         objects.OBJECTS_IMMOBILE
     ], [50, 25, 25])[0]
     return util.finalize_object_definition(random.choice(object_def_list))
예제 #2
0
 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
예제 #3
0
def test_can_contain_both():
    small1 = {'dimensions': {'x': 0.01, 'y': 0.01, 'z': 0.01}}
    small2 = {'dimensions': {'x': 0.02, 'y': 0.02, 'z': 0.02}}
    big = {'dimensions': {'x': 42, 'y': 42, 'z': 42}}
    container_def = util.finalize_object_definition(DEFAULT_CONTAINER)
    assert can_contain_both(container_def, small1, small2) is not None
    assert can_contain_both(container_def, small1, big) is None
예제 #4
0
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
예제 #5
0
 def choose_definition(
     self,
     must_be_pickupable: bool = False
 ) -> Dict[str, Any]:
     """Choose and return an object definition."""
     definition_list = random.choice(retrieve_trained_definition_list(
         objects.get(objects.ObjectDefinitionList.PICKUPABLES)
         if must_be_pickupable
         else objects.get(objects.ObjectDefinitionList.ALL)
     ))
     # Same chance to pick each object definition from the list.
     definition = finalize_object_definition(random.choice(definition_list))
     # Finalize the material here in case we need to make a confusor.
     return random.choice(finalize_object_materials_and_colors(definition))
예제 #6
0
    def choose_target_definition(self, target_number: int) -> Dict[str, Any]:
        if target_number == 0:
            return self.choose_definition(must_be_pickupable=True)

        if target_number != 1:
            raise exceptions.SceneException(
                f'Expected target with number 0 or 1 but got {target_number}')

        definition_list = random.choice(retrieve_trained_definition_list(
            objects.get(objects.ObjectDefinitionList.STACK_TARGETS)
        ))

        # Same chance to pick each object definition from the list.
        definition = finalize_object_definition(random.choice(definition_list))
        # Finalize the material here in case we need to make a confusor.
        return random.choice(finalize_object_materials_and_colors(definition))
예제 #7
0
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'
예제 #8
0
파일: util_test.py 프로젝트: RajeshDM/MCS
def test_finalize_object_definition():
    object_type = 'type1'
    mass = 12.34
    material_category = ['plastic']
    salient_materials = ['plastic', 'hollow']
    object_def = {
        'type': 'type2',
        'mass': 56.78,
        'choose': [{
            'type': object_type,
            'mass': mass,
            'materialCategory': material_category,
            'salientMaterials': salient_materials
        }]
    }
    obj = finalize_object_definition(object_def)
    assert obj['type'] == object_type
    assert obj['mass'] == mass
    assert obj['materialCategory'] == material_category
    assert obj['salientMaterials'] == salient_materials
예제 #9
0
    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
예제 #10
0
def test_finalize_object_definition():
    dimensions = {'x': 1, 'y': 1, 'z': 1}
    mass = 12.34
    material_category = ['plastic']
    salient_materials = ['plastic', 'hollow']
    object_def = {
        'type': 'type1',
        'mass': 56.78,
        'chooseMaterial': [{
            'materialCategory': material_category,
            'salientMaterials': salient_materials
        }],
        'chooseSize': [{
            'dimensions': dimensions,
            'mass': mass
        }]
    }
    obj = finalize_object_definition(object_def)
    assert obj['dimensions'] == dimensions
    assert obj['mass'] == mass
    assert obj['materialCategory'] == material_category
    assert obj['salientMaterials'] == salient_materials
예제 #11
0
 def _set_target_def(self) -> None:
     """Chooses a pickupable object since most interaction goals require that."""
     pickupable_defs = random.choice(objects.OBJECTS_PICKUPABLE_LISTS)
     self._target_def = finalize_object_definition(
         random.choice(pickupable_defs))
예제 #12
0
from object_data import ObjectData, ReceptacleData, TargetData, \
    identify_larger_definition

from interactive_plans import ObjectLocationPlan, ObjectPlan
import objects
import util

CAKE = objects._get('CAKE')
TROPHY = objects._get('TROPHY')

CASE_1_SUITCASE = objects._get('CASE_1_SUITCASE')
CASE_1_SUITCASE = util.finalize_object_definition(
    CASE_1_SUITCASE, choice_size=CASE_1_SUITCASE['chooseSize'][0])
CHEST_1_CUBOID = objects._get('CHEST_1_CUBOID')
CHEST_1_CUBOID = util.finalize_object_definition(
    CHEST_1_CUBOID, choice_size=CHEST_1_CUBOID['chooseSize'][0])


def test_identify_larger_definition():
    assert identify_larger_definition(CAKE, TROPHY) == CAKE
    assert identify_larger_definition(TROPHY, CAKE) == CAKE


def test_object_data_init():
    data = ObjectData('ROLE', ObjectPlan(ObjectLocationPlan.NONE))
    assert data.role == 'ROLE'
    assert data.location_plan_list == [ObjectLocationPlan.NONE]
    assert data.untrained_plan_list == [False]
    assert not data.original_definition
    assert not data.trained_definition
    assert not data.untrained_definition
예제 #13
0
    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