def get_holes(interpreter, speaker, location, limit=1, all_proximity=10) -> List[Tuple[XYZ, Hole]]: holes: List[Hole] = perception.get_all_nearby_holes( interpreter.agent, location) candidates: List[Tuple[XYZ, Hole]] = [ (to_block_pos(np.mean(hole[0], axis=0)), hole) for hole in holes ] if len(candidates) > 0: # NB(demiguo): by default, we fill the hole the player is looking at player = interpreter.memory.get_player_struct_by_name(speaker) centroid_hole = object_looked_at(interpreter.agent, candidates, player, limit=limit) if centroid_hole is None or len(centroid_hole) == 0: # NB(demiguo): if there's no hole in front of the player, we will fill the nearest hole speaker_pos = interpreter.memory.get_player_struct_by_name( speaker).pos speaker_pos = to_block_pos(pos_to_np(speaker_pos)) if limit == "ALL": return list( filter( lambda c: euclid_dist(c[0], speaker_pos) <= all_proximity, candidates)) else: candidates.sort(key=lambda c: euclid_dist(c[0], speaker_pos)) return candidates[:limit] else: return centroid_hole else: return []
def post_process(m): if (m.__class__.__name__ == "BlockObjectNode" or m.__class__.__name__ == "ComponentObjectNode"): m_pos = to_block_pos( np.mean(strip_idmeta(m.blocks.items()), axis=0)) elif m.__class__.__name__ == "InstSegNode": m_pos = to_block_pos(np.mean(m.locs, axis=0)) else: return None return (m_pos, m)
def __init__(self, agent, task_data): super(Move, self).__init__() self.target = util.to_block_pos(np.array(task_data["target"])) self.approx = task_data.get("approx", 1) self.path = None self.replace = set() self.last_stepped_time = agent.memory.get_time()
def compute_locations(interpreter, speaker, d, ref_mems, objects=[], enable_geoscorer=False): location_d = d.get("location", SPEAKERLOOK) repeat_num = len(objects) origin = compute_location_heuristic(interpreter, speaker, location_d, ref_mems) if ( enable_geoscorer and interpreter.agent.geoscorer is not None and interpreter.agent.geoscorer.use(location_d, repeat_num) ): r = interpreter.agent.geoscorer.radius brc = (origin[0] - r, origin[1] - r, origin[2] - r) tlc = (brc[0] + 2 * r - 1, brc[1] + 2 * r - 1, brc[2] + 2 * r - 1) context = interpreter.agent.get_blocks(brc[0], tlc[0], brc[1], tlc[1], brc[2], tlc[2]) segment = objects[0][0] origin = interpreter.agent.geoscorer.produce_segment_pos_in_context(segment, context, brc) origin = to_block_pos(origin) offsets = [(0, 0, 0)] else: # hack to fix build 1 block underground!!! # FIXME should SPEAKER_LOOK deal with this? if is_loc_speakerlook(location_d): origin[1] += 1 if repeat_num > 1: offsets = get_repeat_arrangement( d, interpreter, speaker, objects[0][0], ref_mems, repeat_num=repeat_num ) else: offsets = [(0, 0, 0)] return origin, offsets
def perceive(self, force=False): # FIXME (low pri) remove these in code, get from sql self.agent.pos = to_block_pos(pos_to_np(self.agent.get_player().pos)) # note: no "force"; these run on every perceive call. assumed to be fast for mob in self.agent.get_mobs(): self.memory.set_mob_position(mob) self.update_other_players(self.agent.get_other_players()) # use safe_get_changed_blocks to deal with pointing for (xyz, idm) in self.agent.safe_get_changed_blocks(): self.on_block_changed(xyz, idm)
def step(self): self.pos = to_block_pos(pos_to_np(self.get_player().pos)) # Update memory with current world state # Removed get_objects call due to very slow updates on non-flatworlds with TimingWarn(2): self.memory.update(self) # Process incoming chats self.dialogue_step() # Step topmost task on stack self.task_step()
def step(self): self.pos = to_block_pos(pos_to_np(self.get_player().pos)) # remove old point targets self.point_targets = [pt for pt in self.point_targets if time.time() - pt[1] < 6] # Update memory with current world state # Removed perceive call due to very slow updates on non-flatworlds with TimingWarn(2): self.memory.update(self) # Process incoming chats self.dialogue_step() # Step topmost task on stack self.task_step()
def get_repeat_arrangement(d, interpreter, speaker, schematic, repeat_num=-1, extra_space=1) -> List[XYZ]: shapeparams = {} # eventually fix this to allow number based on shape shapeparams["N"] = repeat_num shapeparams["extra_space"] = extra_space if "repeat" in d: direction_name = d.get("repeat", {}).get("repeat_dir", "FRONT") elif "schematic" in d: direction_name = d["schematic"].get("repeat", {}).get("repeat_dir", "FRONT") if direction_name != "AROUND": reldir_vec = rotation.DIRECTIONS[direction_name] look = (interpreter.agent.perception_modules["low_level"]. get_player_struct_by_name(speaker).look) # this should be an inverse transform so we set inverted=True dir_vec = rotation.transform(reldir_vec, look.yaw, 0, inverted=True) shapeparams["orient"] = dir_vec offsets = shapes.arrange("line", schematic, shapeparams) else: # TODO vertical "around" shapeparams["orient"] = "xy" shapeparams["encircled_object_radius"] = 1 if d.get("location") is not None: central_object = interpret_reference_object( interpreter, speaker, d["location"]["reference_object"], limit=1) # FIXME: .blocks is unsafe, assumes BlockObject only object could be Mob. Ignoring for now. central_object_blocks = central_object[0].blocks # type: ignore # .blocks returns a dict of (x, y, z) : (block_id, meta), convert to list # to get bounds central_object_list = [ tuple([k, v]) for k, v in central_object_blocks.items() ] bounds = shapes.get_bounds(central_object_list) b = max(bounds[1] - bounds[0], bounds[3] - bounds[2], bounds[5] - bounds[4]) shapeparams["encircled_object_radius"] = b offsets = shapes.arrange("circle", schematic, shapeparams) offsets = [tuple(to_block_pos(o)) for o in offsets] return offsets
def perceive(self, force=False): # FIXME (low pri) remove these in code, get from sql self.agent.pos = to_block_pos(pos_to_np(self.agent.get_player().pos)) if self.agent.count % self.perceive_freq == 0 or force: for mob in self.agent.get_mobs(): if euclid_dist(self.agent.pos, pos_to_np( mob.pos)) < self.memory.perception_range: self.memory.set_mob_position(mob) for item_stack in self.agent.get_item_stacks(): if (euclid_dist(self.agent.pos, pos_to_np(item_stack.pos)) < self.memory.perception_range): self.memory.set_item_stack_position(item_stack) # note: no "force"; these run on every perceive call. assumed to be fast self.update_self_memory() self.update_other_players(self.agent.get_other_players()) # use safe_get_changed_blocks to deal with pointing for (xyz, idm) in self.agent.safe_get_changed_blocks(): self.on_block_changed(xyz, idm)
def find_inside(entity): """Return a point inside the entity if it can find one. TODO: heuristic quick check to find that there aren't any, and maybe make this not d^3""" # is this a negative object? if yes, just return its mean: if hasattr(entity, "blocks"): if all(b == (0, 0) for b in entity.blocks.values()): m = np.mean(list(entity.blocks.keys()), axis=0) return [util.to_block_pos(m)] l = util.get_locs_from_entity(entity) if l is None: return None m = np.round(np.mean(l, axis=0)) maxes = np.max(l, axis=0) mins = np.min(l, axis=0) inside = [] for x in range(mins[0], maxes[0] + 1): for y in range(mins[1], maxes[1] + 1): for z in range(mins[2], maxes[2] + 1): if check_inside([(x, y, z), entity]): inside.append((x, y, z)) return sorted(inside, key=lambda x: util.euclid_dist(x, m))
def __init__(self, agent, task_data, featurizer=None): super(Move, self).__init__(featurizer=featurizer) self.target = util.to_block_pos(np.array(task_data["target"])) self.approx = task_data.get("approx", 1) self.path = None self.replace = set()
def post_process(objs): obj_poss = [ to_block_pos(np.mean(strip_idmeta(b.blocks.items()), axis=0)) for b in objs ] return list(zip(obj_poss, objs))
def get_mobs(interpreter, *tags) -> List[Tuple[XYZ, MobNode]]: """Return a list of (xyz, memory) tuples, filtered by tags""" mobs = interpreter.memory.get_mobs_tagged(*tags) return [(to_block_pos(mob.pos), mob) for mob in mobs]
def interpret_location(interpreter, speaker, d, ignore_reldir=False) -> XYZ: """Location dict -> coordinates Side effect: adds mems to agent_memory.recent_entities if a reference object is interpreted; and loc to memory """ location_type = d.get("location_type", "SPEAKER_LOOK") if location_type == "REFERENCE_OBJECT": mems = interpret_reference_object(interpreter, speaker, d["reference_object"]) if len(mems) == 0: raise ErrorWithResponse("I don't know what you're referring to") assert len(mems) == 1, mems interpreter.memory.update_recent_entities(mems) mem = mems[0] loc = mem.get_pos() elif location_type == "SPEAKER_LOOK": player = interpreter.memory.get_player_struct_by_name(speaker) loc = capped_line_of_sight(interpreter.agent, player) elif location_type == "SPEAKER_POS": loc = pos_to_np( interpreter.memory.get_player_struct_by_name(speaker).pos) elif location_type == "AGENT_POS": loc = pos_to_np(interpreter.agent.get_player().pos) elif location_type == "COORDINATES": loc = cast( XYZ, tuple( int(float(w)) for w in re.findall("[-0-9.]+", d["coordinates"]))) if len(loc) != 3: logging.error("Bad coordinates: {}".format(d["coordinates"])) raise ErrorWithResponse( "I don't understand what location you're referring to") else: raise ValueError( "Can't handle Location type: {}".format(location_type)) # handle relative direction reldir = d.get("relative_direction") if reldir is not None and not ignore_reldir: if reldir == "INSIDE": if location_type == "REFERENCE_OBJECT": locs = perception.find_inside(mem) if len(locs) == 0: raise ErrorWithResponse( "I don't know how to go inside there") else: loc = locs[0] elif reldir == "AWAY": apos = pos_to_np(interpreter.agent.get_player().pos) dir_vec = (apos - loc) / np.linalg.norm(apos - loc) num_steps = word_to_num(d.get("steps", "5")) loc = num_steps * np.array(dir_vec) + to_block_center(loc) elif reldir == "NEAR": pass else: # LEFT, RIGHT, etc... reldir_vec = rotation.DIRECTIONS[reldir] look = interpreter.memory.get_player_struct_by_name(speaker).look # this should be an inverse transform so we set inverted=True dir_vec = rotation.transform(reldir_vec, look.yaw, 0, inverted=True) num_steps = word_to_num(d.get("steps", "5")) loc = num_steps * np.array(dir_vec) + to_block_center(loc) # if steps without relative direction elif "steps" in d: num_steps = word_to_num(d.get("steps", "5")) loc = to_block_center(loc) + [0, 0, num_steps] return to_block_pos(loc)
def get_players(interpreter, *tags) -> List[Tuple[XYZ, PlayerNode]]: """Return a list of (xyz, memory) tuples, filtered by tags""" players = interpreter.memory.get_players_tagged(*tags) return [(to_block_pos(pos_to_np(player.pos)), player) for player in players]
def post_process_loc(loc, interpreter): return to_block_pos(loc)