def navigate_to_goal(self, game_state, start_pose, end_pose): # Look down self.update_map(game_state.env) start_angle = start_pose[3] if start_angle > 180: start_angle -= 360 if start_angle != 45: # pitch angle # Perform initial tilt to get to 45 degrees. tilt_pose = [pp for pp in start_pose] tilt_pose[3] = 45 tilt_actions, _ = self.get_shortest_path(start_pose, tilt_pose) for action in tilt_actions: game_state.step(action) start_pose = tuple(tilt_pose) actions, path = self.get_shortest_path(start_pose, end_pose) while len(actions) > 0: for ii, (action, pose) in enumerate(zip(actions, path)): game_state.step(action) event = game_state.env.last_event last_action_success = event.metadata['lastActionSuccess'] if not last_action_success: # Can't traverse here, make sure the weight is correct. if action['action'].startswith( 'Look') or action['action'].startswith('Rotate'): raise Exception('Look action failed %s' % event.metadata['errorMessage']) self.add_impossible_spot(path[ii + 1]) break pose = game_util.get_pose(event) actions, path = self.get_shortest_path(pose, end_pose) print('nav done')
def process_frame(self): self.event = self.env.last_event self.pose = game_util.get_pose(self.event) self.s_t_orig = self.event.frame self.s_t = game_util.imresize(self.event.frame, (constants.SCREEN_HEIGHT, constants.SCREEN_WIDTH), rescale=False) self.s_t_depth = game_util.imresize(self.event.depth_frame, (constants.SCREEN_HEIGHT, constants.SCREEN_WIDTH), rescale=False)
'action': 'TeleportFull', 'x': start_pose[0] * constants.AGENT_STEP_SIZE, 'y': agent_height, 'z': start_pose[1] * constants.AGENT_STEP_SIZE, 'rotateOnTeleport': True, 'rotation': start_pose[2], 'horizon': start_pose[3], } env.step(action) actions, path = graph.get_shortest_path(start_pose, end_pose) while len(actions) > 0: for ii, (action, pose) in enumerate(zip(actions, path)): env.step(action) event = env.last_event last_action_success = event.metadata['lastActionSuccess'] if not last_action_success: # Can't traverse here, make sure the weight is correct. if action['action'].startswith( 'Look') or action['action'].startswith('Rotate'): raise Exception('Look action failed %s' % event.metadata['errorMessage']) graph.add_impossible_spot(path[ii + 1]) break pose = game_util.get_pose(event) actions, path = graph.get_shortest_path(pose, end_pose) if end_pose == pose: print('made it') else: print('could not make it :(')
def reset(self, scene_num=None, use_gt=True, seed=None, max_num_repeats=constants.MAX_NUM_OF_OBJ_INSTANCES, remove_prob=None, scene=None, objs=None): # Reset should be called only when all information from a scene should be cleared. self.current_frame_count = 0 self.timers = np.zeros((2, 2)) self.board = None self.original_board = None self.currently_opened_object_ids = SetWithGet() self.cleaned_object_ids = SetWithGet() self.hot_object_ids = SetWithGet() self.cool_object_ids = SetWithGet() self.on_object_ids = set() self.toggleable_object_ids = set() self.sliced_object_ids = set() self.inventory_ids = SetWithGet() self.scene_name = None self.bounds = None self.start_point = None self.event = None self.s_t = None self.s_t_orig = None self.s_t_depth = None self.pose = None self.agent_height = None self.camera_height = None new_scene = (self.gt_graph is None or self.gt_graph.scene_id is None or self.gt_graph.scene_id == scene_num) self.scene_num = scene_num if self.scene_num is None: self.scene_num = self.local_random.choice(constants.SCENE_NUMBERS) self.scene_num = self.scene_num if scene is not None: self.scene_num = scene['scene_num'] seed = scene['random_seed'] self.scene_name = 'FloorPlan%d' % self.scene_num self.event = self.env.reset(self.scene_name) if max_num_repeats is None: self.event = self.env.random_initialize(seed) else: self.env.step(dict( action='Initialize', gridSize=constants.AGENT_STEP_SIZE / constants.RECORD_SMOOTHING_FACTOR, cameraY=constants.CAMERA_HEIGHT_OFFSET, renderImage=constants.RENDER_IMAGE, renderDepthImage=constants.RENDER_DEPTH_IMAGE, renderClassImage=constants.RENDER_CLASS_IMAGE, renderObjectImage=constants.RENDER_OBJECT_IMAGE, visibility_distance=constants.VISIBILITY_DISTANCE, makeAgentsVisible=False, )) free_per_receptacle = [] if objs is not None: if 'sparse' in objs: for o, c in objs['sparse']: free_per_receptacle.append({'objectType': o, 'count': c}) if 'empty' in objs: for o, c in objs['empty']: free_per_receptacle.append({'objectType': o, 'count': c}) self.env.step(dict(action='InitialRandomSpawn', randomSeed=seed, forceVisible=False, numRepeats=[{'objectType': o, 'count': c} for o, c in objs['repeat']] if objs is not None and 'repeat' in objs else None, minFreePerReceptacleType=free_per_receptacle if objs is not None else None )) # if 'clean' action, make everything dirty and empty out fillable things if constants.pddl_goal_type == "pick_clean_then_place_in_recep": self.env.step(dict(action='SetStateOfAllObjects', StateChange="CanBeDirty", forceAction=True)) self.env.step(dict(action='SetStateOfAllObjects', StateChange="CanBeFilled", forceAction=False)) if objs is not None and ('seton' in objs and len(objs['seton']) > 0): self.env.step(dict(action='SetObjectToggles', objectToggles=[{'objectType': o, 'isOn': v} for o, v in objs['seton']])) self.gt_graph = graph_obj.Graph(use_gt=True, construct_graph=True, scene_id=self.scene_num) if seed is not None: self.local_random.seed(seed) print('set seed in game_state_base reset', seed) self.bounds = np.array([self.gt_graph.xMin, self.gt_graph.yMin, self.gt_graph.xMax - self.gt_graph.xMin + 1, self.gt_graph.yMax - self.gt_graph.yMin + 1]) self.agent_height = self.env.last_event.metadata['agent']['position']['y'] self.camera_height = self.agent_height + constants.CAMERA_HEIGHT_OFFSET start_point = self.local_random.randint(0, self.gt_graph.points.shape[0] - 1) start_point = self.gt_graph.points[start_point, :].copy() self.start_point = (start_point[0], start_point[1], self.local_random.randint(0, 3)) action = {'action': 'TeleportFull', 'x': self.start_point[0] * constants.AGENT_STEP_SIZE, 'y': self.agent_height, 'z': self.start_point[1] * constants.AGENT_STEP_SIZE, 'rotateOnTeleport': True, 'horizon': 30, 'rotation': self.start_point[2] * 90, } self.event = self.env.step(action) constants.data_dict['scene']['scene_num'] = self.scene_num constants.data_dict['scene']['init_action'] = action constants.data_dict['scene']['floor_plan'] = self.scene_name constants.data_dict['scene']['random_seed'] = seed self.pose = game_util.get_pose(self.event) # Manually populate parentReceptacles data based on existing ReceptableObjectIds. objects = self.env.last_event.metadata['objects'] for idx in range(len(objects)): if objects[idx]['parentReceptacles'] is None: objects[idx]['parentReceptacles'] = [] for jdx in range(len(objects)): if (objects[jdx]['receptacleObjectIds'] is not None and objects[idx]['objectId'] in objects[jdx]['receptacleObjectIds']): objects[idx]['parentReceptacles'].append(objects[jdx]['objectId'])
def step(self, action_or_ind, process_frame=True): if self.event is None: self.event = self.env.last_event self.current_frame_count += 1 self.total_frame_count += 1 action, should_fail = self.get_action(action_or_ind) if should_fail: self.env.last_event.metadata['lastActionSuccess'] = False else: t_start = time.time() start_pose = game_util.get_pose(self.event) if 'action' not in action or action['action'] is None or action['action'] == 'None': self.env.last_event.metadata['lastActionSuccess'] = True else: if constants.RECORD_VIDEO_IMAGES: im_ind = len(glob.glob(constants.save_path + '/*.png')) if 'Teleport' in action['action']: position = self.env.last_event.metadata['agent']['position'] rotation = self.env.last_event.metadata['agent']['rotation'] start_horizon = self.env.last_event.metadata['agent']['cameraHorizon'] start_rotation = rotation['y'] if (np.abs(action['x'] - position['x']) > 0.001 or np.abs(action['z'] - position['z']) > 0.001): # Movement for xx in np.arange(.1, 1, .1): new_action = copy.deepcopy(action) new_action['x'] = np.round(position['x'] * (1 - xx) + action['x'] * xx, 5) new_action['z'] = np.round(position['z'] * (1 - xx) + action['z'] * xx, 5) new_action['rotation'] = start_rotation new_action['horizon'] = start_horizon self.event = self.env.step(new_action) cv2.imwrite(constants.save_path + '/%09d.png' % im_ind, self.event.frame[:, :, ::-1]) # #game_util.store_image_name('%09d.png' % im_ind) # eww... seriously need to clean this up im_ind += 1 if np.abs(action['horizon'] - self.env.last_event.metadata['agent']['cameraHorizon']) > 0.001: end_horizon = action['horizon'] for xx in np.arange(.1, 1, .1): new_action = copy.deepcopy(action) new_action['horizon'] = np.round(start_horizon * (1 - xx) + end_horizon * xx, 3) new_action['rotation'] = start_rotation self.event = self.env.step(new_action) cv2.imwrite(constants.save_path + '/%09d.png' % im_ind, self.event.frame[:, :, ::-1]) #game_util.store_image_name('%09d.png' % im_ind) im_ind += 1 if np.abs(action['rotation'] - rotation['y']) > 0.001: end_rotation = action['rotation'] for xx in np.arange(.1, 1, .1): new_action = copy.deepcopy(action) new_action['rotation'] = np.round(start_rotation * (1 - xx) + end_rotation * xx, 3) self.event = self.env.step(new_action) cv2.imwrite(constants.save_path + '/%09d.png' % im_ind, self.event.frame[:, :, ::-1]) #game_util.store_image_name('%09d.png' % im_ind) im_ind += 1 self.event = self.env.step(action) # elif 'MoveAhead' in action['action']: # # self.store_ll_action(action) # # self.save_image(1) # events = self.env.smooth_move_ahead(action) # # for event in events: # # im_ind = len(glob.glob(constants.save_path + '/*.png')) # # cv2.imwrite(constants.save_path + '/%09d.png' % im_ind, event.frame[:, :, ::-1]) # # #game_util.store_image_name('%09d.png' % im_ind) # # elif 'Rotate' in action['action']: # # self.store_ll_action(action) # # self.save_image(1) # events = self.env.smooth_rotate(action) # # for event in events: # # im_ind = len(glob.glob(constants.save_path + '/*.png')) # # cv2.imwrite(constants.save_path + '/%09d.png' % im_ind, event.frame[:, :, ::-1]) # # #game_util.store_image_name('%09d.png' % im_ind) # # elif 'Look' in action['action']: # # self.store_ll_action(action) # # self.save_image(1) # events = self.env.smooth_look(action) # # for event in events: # # im_ind = len(glob.glob(constants.save_path + '/*.png')) # # cv2.imwrite(constants.save_path + '/%09d.png' % im_ind, event.frame[:, :, ::-1]) # # #game_util.store_image_name('%09d.png' % im_ind) elif 'OpenObject' in action['action']: open_action = dict(action=action['action'], objectId=action['objectId'], moveMagnitude=1.0) # self.store_ll_action(open_action) # self.save_act_image(open_action, dir=constants.BEFORE) self.event = self.env.step(open_action) # self.save_act_image(open_action, dir=constants.AFTER) self.check_action_success(self.event) elif 'CloseObject' in action['action']: close_action = dict(action=action['action'], objectId=action['objectId']) # self.store_ll_action(close_action) # self.save_act_image(close_action, dir=constants.BEFORE) self.event = self.env.step(close_action) # self.save_act_image(close_action, dir=constants.AFTER) self.check_action_success(self.event) elif 'PickupObject' in action['action']: # [hack] correct object ids of slices action['objectId'] = self.correct_slice_id(action['objectId']) # open the receptacle if needed parent_recep = self.get_parent_receps(action['objectId']) if parent_recep is not None and parent_recep['objectType'] in constants.OPENABLE_CLASS_SET: self.open_recep(parent_recep) # stores LL action # close/open the object if needed pickup_obj = game_util.get_object(action['objectId'], self.env.last_event.metadata) if pickup_obj['objectType'] in constants.FORCED_OPEN_STATE_ON_PICKUP: if pickup_obj['isOpen'] != constants.FORCED_OPEN_STATE_ON_PICKUP[pickup_obj['objectType']]: if pickup_obj['isOpen']: self.close_recep(pickup_obj) # stores LL action else: self.open_recep(pickup_obj) # stores LL action # pick up the object self.check_obj_visibility(action, min_pixels=10) pickup_action = dict(action=action['action'], objectId=action['objectId']) # self.store_ll_action(pickup_action) # self.save_act_image(pickup_action, dir=constants.BEFORE) self.event = self.env.step(pickup_action) # self.save_act_image(pickup_action, dir=constants.AFTER) self.check_action_success(self.event) # close the receptacle if needed if parent_recep is not None: parent_recep = game_util.get_object(parent_recep['objectId'], self.env.last_event.metadata) self.close_recep(parent_recep) # stores LL action elif 'PutObject' in action['action']: if len(self.env.last_event.metadata['inventoryObjects']) > 0: inv_obj = self.env.last_event.metadata['inventoryObjects'][0]['objectId'] else: raise RuntimeError("Taking 'PutObject' action with no held inventory object") action['objectId'] = inv_obj # open the receptacle if needed parent_recep = game_util.get_object(action['receptacleObjectId'], self.env.last_event.metadata) if parent_recep is not None and parent_recep['objectType'] in constants.OPENABLE_CLASS_SET: self.open_recep(parent_recep) # stores LL action # Open the parent receptacle of the movable receptacle target. elif parent_recep['objectType'] in constants.MOVABLE_RECEPTACLES_SET: movable_parent_recep_ids = parent_recep['parentReceptacles'] if movable_parent_recep_ids is not None and len(movable_parent_recep_ids) > 0: print(parent_recep['objectId'], movable_parent_recep_ids) # DEBUG movable_parent_recep = game_util.get_object(movable_parent_recep_ids[0], self.env.last_event.metadata) if movable_parent_recep['objectType'] in constants.OPENABLE_CLASS_SET: self.open_recep(movable_parent_recep) # stores LL action # put the object put_action = dict(action=action['action'], objectId=action['objectId'], receptacleObjectId=action['receptacleObjectId'], forceAction=True, placeStationary=True) # self.store_ll_action(put_action) # self.save_act_image(put_action, dir=constants.BEFORE) self.event = self.env.step(put_action) # self.save_act_image(put_action, dir=constants.AFTER) self.check_obj_visibility(action) self.check_action_success(self.event) # close the receptacle if needed if parent_recep is not None: parent_recep = game_util.get_object(parent_recep['objectId'], self.env.last_event.metadata) self.close_recep(parent_recep) # stores LL action elif 'CleanObject' in action['action']: # put the object in the sink sink_obj_id = self.get_some_visible_obj_of_name('SinkBasin')['objectId'] inv_obj = self.env.last_event.metadata['inventoryObjects'][0] put_action = dict(action='PutObject', objectId=inv_obj['objectId'], receptacleObjectId=sink_obj_id, forceAction=True, placeStationary=True) # self.store_ll_action(put_action) # self.save_act_image(put_action, dir=constants.BEFORE) self.event = self.env.step(put_action) # self.save_act_image(put_action, dir=constants.AFTER) self.check_obj_visibility(put_action) self.check_action_success(self.event) # turn on the tap clean_action = copy.deepcopy(action) clean_action['action'] = 'ToggleObjectOn' clean_action['objectId'] = game_util.get_obj_of_type_closest_to_obj( "Faucet", inv_obj['objectId'], self.env.last_event.metadata)['objectId'] # self.store_ll_action(clean_action) # self.save_act_image(clean_action, dir=constants.BEFORE) self.event = self.env.step({k: clean_action[k] for k in ['action', 'objectId']}) # self.save_act_image(clean_action, dir=constants.AFTER) self.check_action_success(self.event) # Need to delay one frame to let `isDirty` update on stream-affected. self.env.noop() # Call built-in 'CleanObject' THOR action on every object in the SinkBasin. # This means we clean everything in the sink, rather than just the things that happen to touch # the water stream, which is the default simulator behavior but looks weird for our purposes. sink_basin_obj = game_util.get_obj_of_type_closest_to_obj( "SinkBasin", clean_action['objectId'], self.env.last_event.metadata) for in_sink_obj_id in sink_basin_obj['receptacleObjectIds']: if (game_util.get_object(in_sink_obj_id, self.env.last_event.metadata)['dirtyable'] and game_util.get_object(in_sink_obj_id, self.env.last_event.metadata)['isDirty']): self.event = self.env.step({'action': 'CleanObject', 'objectId': in_sink_obj_id}) # turn off the tap close_action = copy.deepcopy(clean_action) close_action['action'] = 'ToggleObjectOff' # self.store_ll_action(close_action) # self.save_act_image(close_action, dir=constants.BEFORE) self.event = self.env.step({k: close_action[k] for k in ['action', 'objectId']}) # self.save_act_image(action, dir=constants.AFTER) self.check_action_success(self.event) # pick up the object from the sink pickup_action = dict(action='PickupObject', objectId=inv_obj['objectId']) # self.store_ll_action(pickup_action) # self.save_act_image(pickup_action, dir=constants.BEFORE) self.event = self.env.step(pickup_action) # self.save_act_image(pickup_action, dir=constants.AFTER) self.check_obj_visibility(pickup_action) self.check_action_success(self.event) elif 'HeatObject' in action['action']: # open the microwave microwave_obj_id = self.get_some_visible_obj_of_name('Microwave')['objectId'] microwave_obj = game_util.get_object(microwave_obj_id, self.env.last_event.metadata) self.open_recep(microwave_obj) # put the object in the microwave inv_obj = self.env.last_event.metadata['inventoryObjects'][0] put_action = dict(action='PutObject', objectId=inv_obj['objectId'], receptacleObjectId=microwave_obj_id, forceAction=True, placeStationary=True) # self.store_ll_action(put_action) # self.save_act_image(put_action, dir=constants.BEFORE) self.event = self.env.step(put_action) # self.save_act_image(put_action, dir=constants.AFTER) self.check_obj_visibility(put_action) self.check_action_success(self.event) # close the microwave microwave_obj = game_util.get_object(microwave_obj_id, self.env.last_event.metadata) self.close_recep(microwave_obj) # turn on the microwave heat_action = copy.deepcopy(action) heat_action['action'] = 'ToggleObjectOn' heat_action['objectId'] = microwave_obj_id # self.store_ll_action(heat_action) # self.save_act_image(heat_action, dir=constants.BEFORE) self.event = self.env.step({k: heat_action[k] for k in ['action', 'objectId']}) # self.save_act_image(heat_action, dir=constants.AFTER) # turn off the microwave stop_action = copy.deepcopy(heat_action) stop_action['action'] = 'ToggleObjectOff' # self.store_ll_action(stop_action) # self.save_act_image(stop_action, dir=constants.BEFORE) self.event = self.env.step({k: stop_action[k] for k in ['action', 'objectId']}) # self.save_act_image(stop_action, dir=constants.AFTER) # open the microwave microwave_obj = game_util.get_object(microwave_obj_id, self.env.last_event.metadata) self.open_recep(microwave_obj) # pick up the object from the microwave pickup_action = dict(action='PickupObject', objectId=inv_obj['objectId']) # self.store_ll_action(pickup_action) # self.save_act_image(pickup_action, dir=constants.BEFORE) self.event = self.env.step(pickup_action) # self.save_act_image(pickup_action, dir=constants.AFTER) self.check_obj_visibility(pickup_action) self.check_action_success(self.event) # close the microwave again microwave_obj = game_util.get_object(microwave_obj_id, self.env.last_event.metadata) self.close_recep(microwave_obj) elif 'CoolObject' in action['action']: # open the fridge fridge_obj_id = self.get_some_visible_obj_of_name('Fridge')['objectId'] fridge_obj = game_util.get_object(fridge_obj_id, self.env.last_event.metadata) self.open_recep(fridge_obj) # put the object in the fridge inv_obj = self.env.last_event.metadata['inventoryObjects'][0] put_action = dict(action='PutObject', objectId=inv_obj['objectId'], receptacleObjectId=fridge_obj_id, forceAction=True, placeStationary=True) # self.store_ll_action(put_action) # self.save_act_image(put_action, dir=constants.BEFORE) self.event = self.env.step(put_action) # self.save_act_image(put_action, dir=constants.AFTER) self.check_obj_visibility(put_action) self.check_action_success(self.event) # close and cool the object inside the frige cool_action = dict(action='CloseObject', objectId=action['objectId']) # self.store_ll_action(cool_action) # self.save_act_image(action, dir=constants.BEFORE) self.event = self.env.step(cool_action) # self.save_act_image(action, dir=constants.MIDDLE) # self.save_act_image(action, dir=constants.AFTER) # open the fridge again fridge_obj = game_util.get_object(fridge_obj_id, self.env.last_event.metadata) self.open_recep(fridge_obj) # pick up the object from the fridge pickup_action = dict(action='PickupObject', objectId=inv_obj['objectId']) # self.store_ll_action(pickup_action) # self.save_act_image(pickup_action, dir=constants.BEFORE) self.event = self.env.step(pickup_action) # self.save_act_image(pickup_action, dir=constants.AFTER) self.check_obj_visibility(pickup_action) self.check_action_success(self.event) # close the fridge again fridge_obj = game_util.get_object(fridge_obj_id, self.env.last_event.metadata) self.close_recep(fridge_obj) elif 'ToggleObject' in action['action']: on_action = dict(action=action['action'], objectId=action['objectId']) toggle_obj = game_util.get_object(action['objectId'], self.env.last_event.metadata) on_action['action'] = 'ToggleObjectOff' if toggle_obj['isToggled'] else 'ToggleObjectOn' # self.store_ll_action(on_action) # self.save_act_image(on_action, dir=constants.BEFORE) self.event = self.env.step(on_action) # self.save_act_image(on_action, dir=constants.AFTER) self.check_action_success(self.event) elif 'SliceObject' in action['action']: # open the receptacle if needed parent_recep = self.get_parent_receps(action['objectId']) if parent_recep is not None and parent_recep['objectType'] in constants.OPENABLE_CLASS_SET: self.open_recep(parent_recep) # slice the object slice_action = dict(action=action['action'], objectId=action['objectId']) # self.store_ll_action(slice_action) # self.save_act_image(slice_action, dir=constants.BEFORE) self.event = self.env.step(slice_action) # self.save_act_image(action, dir=constants.AFTER) self.check_action_success(self.event) # close the receptacle if needed if parent_recep is not None: parent_recep = game_util.get_object(parent_recep['objectId'], self.env.last_event.metadata) self.close_recep(parent_recep) # stores LL action else: # check that the object to pick is visible in the camera frame if action['action'] == 'PickupObject': self.check_obj_visibility(action) # self.store_ll_action(action) # self.save_act_image(action, dir=constants.BEFORE) self.event = self.env.step(action) # self.save_act_image(action, dir=constants.AFTER) if action['action'] == 'PutObject': self.check_obj_visibility(action) else: self.event = self.env.step(action) new_pose = game_util.get_pose(self.event) point_dists = np.sum(np.abs(self.gt_graph.points - np.array(new_pose)[:2]), axis=1) if np.min(point_dists) > 0.0001: # print('Point teleport failure') self.event = self.env.step({ 'action': 'Teleport', 'x': start_pose[0] * constants.AGENT_STEP_SIZE, 'y': self.agent_height, 'z': start_pose[1] * constants.AGENT_STEP_SIZE, 'rotateOnTeleport': True, 'rotation': new_pose[2] * 90, }) self.env.last_event.metadata['lastActionSuccess'] = False self.timers[0, 0] += time.time() - t_start self.timers[0, 1] += 1 if self.timers[0, 1] % 100 == 0: # print('env step time %.3f' % (self.timers[0, 0] / self.timers[0, 1])) self.timers[0, :] = 0 if self.env.last_event.metadata['lastActionSuccess']: if action['action'] == 'OpenObject': self.currently_opened_object_ids.add(action['objectId']) elif action['action'] == 'CloseObject': self.currently_opened_object_ids.remove(action['objectId']) elif action['action'] == 'PickupObject': self.inventory_ids.add(action['objectId']) elif action['action'] == 'PutObject': self.inventory_ids.remove(action['objectId']) if self.env.last_event.metadata['lastActionSuccess'] and process_frame: self.process_frame()