def subtask_alloc_is_doable(self, env, subtask, subtask_agent_names): """Return whether subtask allocation (subtask x subtask_agent_names) is doable in the current environment state.""" # Doing nothing is always possible. if subtask is None: return True agent_locs = [ agent.location for agent in list( filter(lambda a: a.name in subtask_agent_names, env.sim_agents)) ] start_obj, goal_obj = get_subtask_obj(subtask=subtask) subtask_action_obj = get_subtask_action_obj(subtask=subtask) A_locs, B_locs = env.get_AB_locs_given_objs( subtask=subtask, subtask_agent_names=subtask_agent_names, start_obj=start_obj, goal_obj=goal_obj, subtask_action_obj=subtask_action_obj) distance = env.world.get_lower_bound_between( subtask=subtask, agent_locs=tuple(agent_locs), A_locs=tuple(A_locs), B_locs=tuple(B_locs)) # Subtask allocation is doable if it's reachable between agents and subtask objects. return distance < env.world.perimeter
def reward(self): reward = 0 for idx, subtask in enumerate(self.all_subtasks): # Check if subtask is complete if not self.subtask_status[idx]: _, goal_obj = nav_utils.get_subtask_obj(subtask) goal_obj_locs = self.world.get_all_object_locs(obj=goal_obj) if isinstance(subtask, recipe.Deliver): # If task is delivery then give max reward delivery_loc = list(filter(lambda o: o.name=='Delivery',\ self.world.get_object_list()))[0].location if goal_obj_locs: if all([gol == delivery_loc for gol in goal_obj_locs]): reward = 150 else: # for completion of any other subtasks give small rewards if goal_obj_locs: reward = 20 self.subtask_status[idx] = 1 if not self.tomato_start == self.state[28] and not self.pick: reward = 20 self.pick = True if reward == 0: reward = -0.01 print("Reward for step: {}".format(reward)) return reward
def done(self): # Done if the episode maxes out if self.t >= self.arglist.max_num_timesteps and self.arglist.max_num_timesteps: self.termination_info = "Terminating because passed {} timesteps".format( self.arglist.max_num_timesteps) self.successful = False return True assert any([ isinstance(subtask, recipe.Deliver) for subtask in self.all_subtasks ]), "no delivery subtask" # Done if subtask is completed. for subtask in self.all_subtasks: # Double check all goal_objs are at Delivery. if isinstance(subtask, recipe.Deliver): _, goal_obj = nav_utils.get_subtask_obj(subtask) delivery_loc = list( filter(lambda o: o.name == 'Delivery', self.world.get_object_list()))[0].location goal_obj_locs = self.world.get_all_object_locs(obj=goal_obj) if not any([gol == delivery_loc for gol in goal_obj_locs]): self.termination_info = "" self.successful = False return False self.termination_info = "Terminating because all deliveries were completed" self.successful = True return True
def _configure_subtask_information(self, subtask, subtask_agent_names): """Tracking information about subtask allocation.""" # Subtask allocation self.subtask = subtask self.subtask_agent_names = subtask_agent_names # Relevant objects for subtask allocation. self.start_obj, self.goal_obj = nav_utils.get_subtask_obj(subtask) self.subtask_action_obj = nav_utils.get_subtask_action_obj(subtask)
def update_state(self): chopped = 0 tomato_loc = 0 plate_loc = 0 # Find out if tomatoes are chopped. Works only when not plated for subtask in self.all_subtasks: if isinstance(subtask, recipe.Chop): _, goal_obj = nav_utils.get_subtask_obj(subtask) goal_obj_locs = self.world.get_all_object_locs(obj=goal_obj) if goal_obj_locs: chopped = 1 for obj in self.world.objects["Tomato"]: if obj.location: tomato_loc = self.get_state_idx(obj) objs = [] for o in self.world.objects.values(): objs += o for obj in objs: idx = obj.location[1] * self.world.width + obj.location[0] if obj.name == "Counter": self.state[idx] = 1 elif obj.name == "Cutboard": self.state[idx] = 2 elif obj.name == "Delivery": self.state[idx] = 3 elif obj.name == "Plate": self.state[idx] = 4 elif obj.name == "Plate-Tomato": tomato_loc = obj.location[1] * self.world.width + obj.location[ 0] plate_loc = obj.location[1] * self.world.width + obj.location[0] chopped = 1 self.state[28] = tomato_loc self.state[29] = plate_loc self.state[30] = chopped
def def_subtask_completion(self, env): # Determine desired objects. self.start_obj, self.goal_obj = nav_utils.get_subtask_obj(subtask=self.new_subtask) self.subtask_action_object = nav_utils.get_subtask_action_obj(subtask=self.new_subtask) # Define termination conditions for agent subtask. # For Deliver subtask, desired object should be at a Deliver location. if isinstance(self.new_subtask, Deliver): self.cur_obj_count = len(list( filter(lambda o: o in set(env.world.get_all_object_locs(self.subtask_action_object)), env.world.get_object_locs(obj=self.goal_obj, is_held=False)))) self.has_more_obj = lambda x: int(x) > self.cur_obj_count self.is_subtask_complete = lambda w: self.has_more_obj( len(list(filter(lambda o: o in set(env.world.get_all_object_locs(obj=self.subtask_action_object)), w.get_object_locs(obj=self.goal_obj, is_held=False))))) # Otherwise, for other subtasks, check based on # of objects. else: # Current count of desired objects. self.cur_obj_count = len(env.world.get_all_object_locs(obj=self.goal_obj)) # Goal state is reached when the number of desired objects has increased. self.is_subtask_complete = lambda w: len(w.get_all_object_locs(obj=self.goal_obj)) > self.cur_obj_count