|
| 1 | +#!/usr/bin/env python |
| 2 | +# -*- coding: utf-8 -*- |
| 3 | + |
| 4 | +''' |
| 5 | + Author: Eduardo Gutierrez Maestro |
| 6 | + Master Thesis 2018 - 2019 |
| 7 | + Research Group : GRAM - University of Alcala |
| 8 | + Last Modification : 05.03.2019 |
| 9 | +''' |
| 10 | +''' |
| 11 | +:param scene_name: Name of the scene to be rendered |
| 12 | +:param hdf5_name: Name of the output fil with the scene rendered |
| 13 | +:param gridSize: Size of the scene grid |
| 14 | +:return: A HDF5 file with the information needed to navigate through the scene |
| 15 | +
|
| 16 | +''' |
| 17 | + |
| 18 | +import ai2thor.controller |
| 19 | +import numpy as np |
| 20 | +import h5py |
| 21 | +import argparse |
| 22 | + |
| 23 | + |
| 24 | +class ai2thor_scene_render(): |
| 25 | + |
| 26 | + def __init__(self, scene_name, hdf5_name, gridSize): |
| 27 | + |
| 28 | + self.scene_name = scene_name |
| 29 | + self.hdf5_name = hdf5_name |
| 30 | + self.gridSize = gridSize |
| 31 | + |
| 32 | + self.controller = ai2thor.controller.BFSController() |
| 33 | + self.controller.start() |
| 34 | + |
| 35 | + self.controller.step(dict(action='Initialize', gridSize=self.gridSize)) |
| 36 | + |
| 37 | + self.controller.search_all_closed(scene_name) # replace with whatever scene you want |
| 38 | + self.points_scene = self.controller.grid_points |
| 39 | + |
| 40 | + |
| 41 | + def scene_render(self): |
| 42 | + N = len(self.points_scene) |
| 43 | + |
| 44 | + num_ID_total = N * 4 |
| 45 | + self.rotations = np.zeros((num_ID_total,), dtype=np.uint64) |
| 46 | + self.locations = np.zeros((num_ID_total, 2), dtype=np.float64) |
| 47 | + |
| 48 | + self.rotations = self.assign_rotations() |
| 49 | + self.locations = self.assign_locations() |
| 50 | + self.transition_graph = self.assign_transition_graph(gridSize=self.gridSize) |
| 51 | + self.observations = np.zeros((num_ID_total, 300, 300, 3), dtype=np.uint8) |
| 52 | + |
| 53 | + aux = 0 |
| 54 | + for i in range(len(self.points_scene)): |
| 55 | + _x = self.points_scene[i]['x'] |
| 56 | + _y = self.points_scene[i]['y'] |
| 57 | + _z = self.points_scene[i]['z'] |
| 58 | + for rot in [0.0, 90.0, 180.0, 270.0]: |
| 59 | + event = self.controller.step(dict(action='TeleportFull', x=_x, y=_y, z=_z, rotation=rot)) |
| 60 | + self.observations[aux, :, :, :] = event.frame |
| 61 | + aux += 1 |
| 62 | + |
| 63 | + with h5py.File('data/' + self.hdf5_name, 'w') as hdf: |
| 64 | + hdf.create_dataset('rotation', data=self.rotations) |
| 65 | + hdf.create_dataset('location', data=self.locations) |
| 66 | + hdf.create_dataset('observation', data=self.observations) |
| 67 | + hdf.create_dataset('graph', data=self.transition_graph) |
| 68 | + |
| 69 | + def assign_rotations(self): |
| 70 | + done = False |
| 71 | + aux = 0 |
| 72 | + while not done: |
| 73 | + for i in [0, 90, 180, 270]: |
| 74 | + self.rotations[aux] = i |
| 75 | + aux += 1 |
| 76 | + if aux == len(self.rotations): |
| 77 | + done = True |
| 78 | + return self.rotations |
| 79 | + |
| 80 | + def assign_locations(self): |
| 81 | + |
| 82 | + x_z_tuple = np.zeros((np.size(self.points_scene, 0), 2)) |
| 83 | + |
| 84 | + for i in range(len(self.points_scene)): |
| 85 | + _x = self.points_scene[i]['x'] |
| 86 | + _z = self.points_scene[i]['z'] |
| 87 | + |
| 88 | + x_z_tuple[i, 0] = _x |
| 89 | + x_z_tuple[i, 1] = _z |
| 90 | + |
| 91 | + aux = 0 |
| 92 | + for i in range(len(x_z_tuple)): |
| 93 | + for _ in range(4): |
| 94 | + self.locations[aux] = x_z_tuple[i] |
| 95 | + aux += 1 |
| 96 | + return self.locations |
| 97 | + |
| 98 | + #This function creates the transition graph needed to navigate in discrete way |
| 99 | + def assign_transition_graph(self, ACTION_SPACE=4, gridSize=0.25): |
| 100 | + |
| 101 | + id_tot_num = np.size(self.locations, 0) |
| 102 | + t_graph = np.zeros((id_tot_num, ACTION_SPACE), dtype=np.int64) |
| 103 | + for i in range(len(t_graph)): |
| 104 | + current_loc = self.locations[i] |
| 105 | + current_rot = self.rotations[i] |
| 106 | + for act in range(ACTION_SPACE): |
| 107 | + if act == 0: # MoveAhead action in order to guess the ID |
| 108 | + _x = current_loc[0] |
| 109 | + _z = current_loc[1] |
| 110 | + |
| 111 | + if current_rot == 0: |
| 112 | + next_loc = [_x, _z + gridSize] |
| 113 | + if current_rot == 90: |
| 114 | + next_loc = [_x + gridSize, _z] |
| 115 | + if current_rot == 180: |
| 116 | + next_loc = [_x, _z - gridSize] |
| 117 | + if current_rot == 270: |
| 118 | + next_loc = [_x - gridSize, _z] |
| 119 | + |
| 120 | + id_loc = np.where(np.all(self.locations == next_loc, axis=1))[0] |
| 121 | + |
| 122 | + if np.size(id_loc) == 0: |
| 123 | + t_graph[i, act] = -1 # We consider that if there is no location available |
| 124 | + # is because there will be collision |
| 125 | + else: |
| 126 | + id_rot = np.where(self.rotations == current_rot)[0] |
| 127 | + id_ahead = np.intersect1d(id_loc, id_rot)[0] |
| 128 | + t_graph[i, act] = id_ahead |
| 129 | + |
| 130 | + if act == 1: # RotateRight action in order to guess the ID |
| 131 | + next_rot = current_rot + 90 |
| 132 | + if next_rot == 360: |
| 133 | + next_rot = 0 |
| 134 | + |
| 135 | + id_loc = np.where(np.all(self.locations == current_loc, axis=1))[0] |
| 136 | + id_rot = np.where(self.rotations == next_rot)[0] |
| 137 | + id_right = np.intersect1d(id_loc, id_rot)[0] |
| 138 | + |
| 139 | + t_graph[i, act] = id_right |
| 140 | + |
| 141 | + if act == 2: # RotateLeft action in order to guess the ID |
| 142 | + next_rot = current_rot - 90 |
| 143 | + if next_rot == -90: |
| 144 | + next_rot = 270 |
| 145 | + |
| 146 | + id_loc = np.where(np.all(self.locations == current_loc, axis=1))[0] |
| 147 | + id_rot = np.where(self.rotations == next_rot)[0] |
| 148 | + id_left = np.intersect1d(id_loc, id_rot)[0] |
| 149 | + |
| 150 | + t_graph[i, act] = id_left |
| 151 | + if act == 3: # MoveBack action in order to guess the ID |
| 152 | + _x = current_loc[0] |
| 153 | + _z = current_loc[1] |
| 154 | + |
| 155 | + if current_rot == 0: |
| 156 | + next_loc = [_x, _z - gridSize] |
| 157 | + if current_rot == 90: |
| 158 | + next_loc = [_x - gridSize, _z] |
| 159 | + if current_rot == 180: |
| 160 | + next_loc = [_x, _z + gridSize] |
| 161 | + if current_rot == 270: |
| 162 | + next_loc = [_x + gridSize, _z] |
| 163 | + |
| 164 | + id_loc = np.where(np.all(self.locations == next_loc, axis=1))[0] |
| 165 | + |
| 166 | + if np.size(id_loc) == 0: |
| 167 | + t_graph[i, act] = -1 # We consider that if there is no location available |
| 168 | + # is because there will be collision |
| 169 | + else: |
| 170 | + id_rot = np.where(self.rotations == current_rot)[0] |
| 171 | + id_back = np.intersect1d(id_loc, id_rot)[0] |
| 172 | + t_graph[i, act] = id_back |
| 173 | + |
| 174 | + return t_graph |
| 175 | + |
| 176 | +if __name__ == '__main__': |
| 177 | + |
| 178 | + scene1 = ai2thor_scene_render( |
| 179 | + scene_name='FloorPlan28', |
| 180 | + hdf5_name='scene_401.h5', |
| 181 | + gridSize=0.25 |
| 182 | + ) |
| 183 | + scene1.scene_render() |
| 184 | + |
0 commit comments