def compute_location_heuristic(interpreter, speaker, d, mems): # handle relative direction reldir = d.get("relative_direction") loc = mems[0].get_pos() if reldir is not None: if reldir == "BETWEEN": loc = (np.add(mems[0].get_pos(), mems[1].get_pos())) / 2 loc = (loc[0], loc[1], loc[2]) elif reldir == "INSIDE": ref_obj_dict = d.get("reference_object", SPEAKERLOOK["reference_object"]) special = ref_obj_dict.get("special_reference") if not special: for i in range(len(mems)): mem = mems[i] locs = heuristic_perception.find_inside(mem) if len(locs) > 0: break if len(locs) == 0: raise ErrorWithResponse("I don't know how to go inside there") else: interpreter.memory.update_recent_entities([mem]) loc = locs[0] else: raise ErrorWithResponse("I don't know how to go inside there") 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.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) 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 post_process_loc(loc, interpreter)
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)