示例#1
0
    def update_states(self, action):
        '''
        extra updates to metadata after step
        '''
        # add 'cleaned' to all object that were washed in the sink
        event = self.last_event
        if event.metadata['lastActionSuccess']:
            # clean
            if action['action'] == 'ToggleObjectOn' and "Faucet" in action[
                    'objectId']:
                sink_basin = get_obj_of_type_closest_to_obj(
                    'SinkBasin', action['objectId'], event.metadata)
                cleaned_object_ids = sink_basin['receptacleObjectIds']
                self.cleaned_objects = self.cleaned_objects | set(
                    cleaned_object_ids
                ) if cleaned_object_ids is not None else set()
            # heat
            if action['action'] == 'ToggleObjectOn' and "Microwave" in action[
                    'objectId']:
                microwave = get_objects_of_type('Microwave', event.metadata)[0]
                heated_object_ids = microwave['receptacleObjectIds']
                self.heated_objects = self.heated_objects | set(
                    heated_object_ids
                ) if heated_object_ids is not None else set()
            # cool
            if action['action'] == 'CloseObject' and "Fridge" in action[
                    'objectId']:
                fridge = get_objects_of_type('Fridge', event.metadata)[0]
                cooled_object_ids = fridge['receptacleObjectIds']
                self.cooled_objects = self.cooled_objects | set(
                    cooled_object_ids
                ) if cooled_object_ids is not None else set()

        return event
示例#2
0
    def setup_problem(self, seed=None, info=None, scene=None, objs=None):
        '''
        setup goal with sampled objects or with the objects specified
        note: must be used with `initialize_random_scene`
        '''
        self.terminal = False
        print(
            'setup random goal ----------------------------------------------')
        print('seed', seed)
        print('info', info)
        print(
            '--------------------------------------------------------------------\n\n'
        )
        super(TaskGameState, self).setup_problem(seed)
        info, max_num_repeats, remove_prob = self.get_random_task_vals(
            scene=scene)
        dataset_type, task_row = info

        print('Type:', dataset_type, 'Row: ', task_row, 'Scene',
              self.scene_name, 'seed', self.scene_seed)
        perform_sanity_check = True

        # pickupable, receptacle, toggleable candidates
        pickupable_objects = [
            o for o in self.env.last_event.metadata['objects']
            if (o['pickupable'] and o['objectType'] in constants.OBJECTS)
        ]
        receptacle_objects = [
            o for o in self.env.last_event.metadata['objects']
            if (o['receptacle'] and o['objectType'] in constants.RECEPTACLES
                and o['objectType'] not in constants.MOVABLE_RECEPTACLES_SET)
        ]
        toggle_objects = [
            o for o in self.env.last_event.metadata['objects']
            if o['toggleable']
            and not o['isToggled']  # must be one we can turn on.
            and o['objectType'] in constants.VAL_ACTION_OBJECTS["Toggleable"]
        ]

        if len(pickupable_objects) == 0:
            print("Task Failed - %s" % constants.pddl_goal_type)
            raise Exception("No pickupable objects in the scene")

        # filter based on crit
        obj_crit, _ = self.get_filter_crit(constants.pddl_goal_type)
        pickupable_objects = list(filter(obj_crit, pickupable_objects))
        if len(pickupable_objects) == 0:
            print("Task Failed - %s" % constants.pddl_goal_type)
            raise Exception("No pickupable objects related to the goal '%s'" %
                            constants.pddl_goal_type)

        # choose a pickupable object
        if constants.FORCED_SAMPLING or objs is None:
            self.rand_chosen_object = random.choice(pickupable_objects)
        else:
            chosen_class_available = [
                obj for obj in pickupable_objects
                if obj['objectType'] == constants.OBJ_PARENTS[objs['pickup']]
            ]
            if len(chosen_class_available) == 0:
                print("Task Failed - %s" % constants.pddl_goal_type)
                raise Exception(
                    "Couldn't find a valid parent '%s' for pickup object with class '%s'"
                    % (constants.OBJ_PARENTS[objs['pickup']], objs['pickup']))
            self.rand_chosen_object = random.choice(chosen_class_available)
        self.rand_chosen_object_class = self.rand_chosen_object['objectType']
        self.object_target = constants.OBJECTS.index(
            self.rand_chosen_object_class)

        # for now, any obj differing from its parent is obtained via slicing, but that may change in the future.
        if constants.OBJ_PARENTS[objs['pickup']] != objs['pickup']:
            requires_slicing = True
        else:
            requires_slicing = False

        # choose a movable receptacle
        if "movable_recep" in constants.pddl_goal_type:
            val_movable_receps = [
                o for o in self.env.last_event.metadata['objects']
                if (o['objectType'] in constants.MOVABLE_RECEPTACLES_SET) and (
                    self.rand_chosen_object_class in
                    constants.VAL_RECEPTACLE_OBJECTS[o['objectType']])
            ]

            if len(val_movable_receps) == 0:
                print("Task Failed - %s" % constants.pddl_goal_type)
                raise Exception(
                    "Couldn't find a valid moveable receptacle for the chosen object class"
                )

            if objs is not None:
                val_movable_receps = [
                    o for o in val_movable_receps
                    if o['objectType'] == objs['mrecep']
                ]

            self.rand_chosen_val_moveable_recep_class = random.choice(
                val_movable_receps)['objectType']
            self.mrecep_target = constants.OBJECTS.index(
                self.rand_chosen_val_moveable_recep_class)
        else:
            self.mrecep_target = None

        # if slicing is required, make sure a knife is available in the scene
        if requires_slicing:
            knife_objs = [
                o for o in self.env.last_event.metadata['objects']
                if ("Knife" in o['objectType'])
            ]
            if len(knife_objs) == 0:
                print("Task Failed - %s" % constants.pddl_goal_type)
                raise Exception("Couldn't find knife in the scene to cut with")

        if constants.pddl_goal_type == "look_at_obj_in_light":
            # choose a toggleable object
            self.parent_target = None

            if constants.FORCED_SAMPLING or objs is None:
                rand_chosen_toggle_object = random.choice(toggle_objects)
            else:
                toggle_class_available = [
                    obj for obj in toggle_objects
                    if obj['objectType'] == objs['toggle']
                ]
                if len(toggle_class_available) == 0:
                    print("Task Failed - %s" % constants.pddl_goal_type)
                    raise Exception(
                        "Couldn't find a valid toggle object of class '%s'" %
                        objs['toggle'])
                rand_chosen_toggle_object = random.choice(
                    toggle_class_available)

            rand_chosen_toggle_class = rand_chosen_toggle_object['objectType']
            self.toggle_target = constants.OBJECTS.index(
                rand_chosen_toggle_class)
        else:
            self.toggle_target = None

            # find all valid receptacles in which rand_chosen object or rand chosen moveable receptacle can be placed
            val_receptacle_objects_orig = [
                r for r in receptacle_objects
                if (self.rand_chosen_val_moveable_recep_class if self.
                    mrecep_target != None else self.rand_chosen_object_class
                    ) in constants.VAL_RECEPTACLE_OBJECTS[r['objectType']]
            ]
            _, recep_crit = self.get_filter_crit(constants.pddl_goal_type)
            val_receptacle_objects = list(
                filter(recep_crit, val_receptacle_objects_orig))

            if len(val_receptacle_objects) == 0:
                print("Task Failed - %s" % constants.pddl_goal_type)
                raise Exception(
                    "Couldn't find a valid receptacle object according to constraints specified"
                )

            # choose a receptacle object
            if constants.FORCED_SAMPLING or objs is None:
                rand_chosen_receptacle_object = random.choice(
                    val_receptacle_objects)
            else:
                receptacle_class_available = [
                    obj for obj in val_receptacle_objects
                    if obj['objectType'] == objs['receptacle']
                ]
                if len(receptacle_class_available) == 0:
                    print("Task Failed - %s" % constants.pddl_goal_type)
                    raise Exception(
                        "Couldn't find a valid receptacle object of class '%s'"
                        % objs['receptacle'])
                rand_chosen_receptacle_object = random.choice(
                    receptacle_class_available)
            rand_chosen_receptacle_object_class = rand_chosen_receptacle_object[
                'objectType']
            self.parent_target = constants.OBJECTS.index(
                rand_chosen_receptacle_object_class)

        # pddl_param dict
        constants.data_dict['pddl_params'][
            'object_target'] = constants.OBJECTS[
                self.object_target] if self.object_target is not None else ""
        constants.data_dict['pddl_params']['object_sliced'] = requires_slicing
        constants.data_dict['pddl_params'][
            'parent_target'] = constants.OBJECTS[
                self.parent_target] if self.parent_target is not None else ""
        constants.data_dict['pddl_params'][
            'toggle_target'] = constants.OBJECTS[
                self.toggle_target] if self.toggle_target is not None else ""
        constants.data_dict['pddl_params'][
            'mrecep_target'] = constants.OBJECTS[
                self.mrecep_target] if self.mrecep_target is not None else ""
        self.task_target = (self.object_target, self.parent_target,
                            self.toggle_target, self.mrecep_target)

        if self.parent_target is None:
            validity_check = True
        else:
            objs = game_util.get_objects_of_type(
                constants.OBJECTS[self.object_target],
                self.env.last_event.metadata)
            available_receptacles = game_util.get_objects_of_type(
                constants.OBJECTS[self.parent_target],
                self.env.last_event.metadata)
            validity_check = (len(objs) > 0
                              and len([obj for obj in available_receptacles]))

        if perform_sanity_check:
            try:
                assert validity_check, 'Task does not seem valid according to scene metadata'
            except AssertionError:
                raise Exception(
                    str(('Row: ', task_row, 'Scene', self.scene_name, 'seed',
                         self.scene_seed)))

        templated_task_desc = self.get_task_str()
        print('problem id', self.problem_id)
        print('Task:', templated_task_desc)
        constants.data_dict['template']['task_desc'] = templated_task_desc
示例#3
0
 def does_have_atleast_n_duplicates(x, n):
     num_instances = len(
         game_util.get_objects_of_type(x['objectType'],
                                       self.env.last_event.metadata))
     return num_instances >= n