| … | … | @@ -1,24 +1,13 @@ |
| 1 | 1 | import os |
| 2 | 2 | import time |
| 3 | 3 | |
| 4 | | from fastcore.basics import gen |
| 5 | | |
| 6 | 4 | from rocca.envs.wrappers.malmo_wrapper import MalmoWrapper |
| 7 | 5 | from rocca.envs.wrappers.utils import * |
| 8 | 6 | from builtins import range |
| 9 | | from past.utils import old_div |
| 10 | | import os |
| 11 | | import sys |
| 12 | | import time |
| 13 | 7 | import json |
| 14 | 8 | import random |
| 15 | 9 | import math |
| 16 | 10 | |
| 17 | | if sys.version_info[0] == 2: |
| 18 | | sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0) # flush print output immediately |
| 19 | | else: |
| 20 | | import functools |
| 21 | | print = functools.partial(print, flush=True) |
| 22 | 11 | |
| 23 | 12 | def drawBlock(x, y, z, type): |
| 24 | 13 | return """<DrawBlock x='{0}' y='{1}' z='{2}' type='{3}'/>""".format(x, y, z, type) |
| … | … | @@ -26,6 +15,9 @@ def drawBlock(x, y, z, type): |
| 26 | 15 | def GenCuboid(x1, y1, z1, x2, y2, z2, blocktype): |
| 27 | 16 | return '<DrawCuboid x1="' + str(x1) + '" y1="' + str(y1) + '" z1="' + str(z1) + '" x2="' + str(x2) + '" y2="' + str(y2) + '" z2="' + str(z2) + '" type="' + blocktype + '"/>' |
| 28 | 17 | |
| 18 | def drawLine(x1, y1, z1, x2, y2, z2, blocktype, face): |
| 19 | return '<DrawLine x1="' + str(x1) + '" y1="' + str(y1) + '" z1="' + str(z1) + '" x2="' + str(x2) + '" y2="' + str(y2) + '" z2="' + str(z2) + '" type="' + blocktype + '" face="' + face +'"/>' |
| 20 | |
| 29 | 21 | def build_house(x, y, z, width, length, height, blocktype): |
| 30 | 22 | x_front = x |
| 31 | 23 | x_back = x + length if x >= 0 else x-length |
| … | … | @@ -56,8 +48,10 @@ def build_house(x, y, z, width, length, height, blocktype): |
| 56 | 48 | |
| 57 | 49 | return genstring |
| 58 | 50 | |
| 59 | | |
| 60 | | agent_x, agent_y, agent_z, agent_yaw = 9, 230, -2, 90 |
| 51 | agent_x, agent_y, agent_z, agent_yaw = 19, 230, -2, 90 |
| 52 | key_x, key_y, key_z = 7, 228, -10 |
| 53 | door_x, door_y, door_z = -4, 228, -3 |
| 54 | diamond_x, diamond_y, diamond_z = -8, 228, -3 |
| 61 | 55 | |
| 62 | 56 | missionXML = ''' |
| 63 | 57 | <?xml version="1.0" encoding="UTF-8" standalone="no" ?> |
| … | … | @@ -81,14 +75,10 @@ missionXML = ''' |
| 81 | 75 | <FlatWorldGenerator generatorString="3;7,220*1,5*3,2;1;biome_1"/> |
| 82 | 76 | <DrawingDecorator> |
| 83 | 77 | '''+build_house(-4, 226, -1,6,6,5,"planks")+''' |
| 84 | | <DrawBlock x="-8" y="228" z="-3" type="diamond_block"/> |
| 85 | | |
| 86 | | |
| 87 | | <DrawLine x1="-4" y1="227" z1="-3" x2="-4" y2="228" z2="-3" type="dark_oak_door" face="EAST"/> |
| 88 | | |
| 89 | | <DrawBlock x="-4" y="227" z="-15" type="command_block"/> |
| 90 | | <DrawBlock x="-4" y="228" z="-15" type="tripwire_hook"/> |
| 91 | | |
| 78 | '''+drawBlock(diamond_x, diamond_y, diamond_z, "diamond_block")+''' |
| 79 | '''+drawLine(door_x, door_y-1, door_z, door_x, door_y, door_z, "dark_oak_door", "EAST")+''' |
| 80 | '''+drawBlock(key_x, key_y-1, key_z, "command_block")+''' |
| 81 | '''+drawBlock(key_x, key_y, key_z, "tripwire_hook")+''' |
| 92 | 82 | |
| 93 | 83 | </DrawingDecorator> |
| 94 | 84 | <ServerQuitFromTimeUp description="" timeLimitMs="1000000"/> |
| … | … | @@ -128,60 +118,85 @@ missionXML = ''' |
| 128 | 118 | </Mission> |
| 129 | 119 | |
| 130 | 120 | ''' |
| 131 | | |
| 132 | | # Moves the agent to the position given |
| 133 | | def turn_to(agent,x1, y1, z1, yaw, x2, y2, z2): |
| 134 | | x_dist = abs(x1) + abs(x2) |
| 135 | | z_dist = abs(z1) + abs(z2) |
| 121 | def get_angle(x1, y1, z1, x2, y2, z2): |
| 122 | x_dist = abs(x1 - x2) |
| 123 | z_dist = abs(z1 - z2) |
| 136 | 124 | h = math.sqrt(x_dist**2 + z_dist**2) |
| 137 | | angle = yaw + math.degrees(z_dist/h) |
| 138 | | agent.step(mk_action("setYaw",angle)) |
| 125 | return math.degrees(z_dist/h) if h != 0 else 0 |
| 126 | |
| 127 | # Turn the agent towards the location given |
| 128 | def turn_to(agent, x1, y1, z1, yaw, x2, y2, z2): |
| 129 | angle = get_angle(x1, y1, z1, x2, y2, z2) |
| 130 | yaw = 90 if x1 > x2 else -90 |
| 131 | if yaw > 0: |
| 132 | angle = yaw - angle if z1 < z2 else yaw + angle |
| 133 | else: |
| 134 | angle = yaw + angle if z1 < z2 else yaw - angle |
| 135 | agent.sendCommand("setYaw {}".format(angle)) |
| 139 | 136 | |
| 140 | 137 | # Agent goes to the key |
| 141 | 138 | # reward=0 |
| 142 | | def go_to_the_key(agent, x, y, z): |
| 143 | | turn_to(agent,agent_x, agent_y, agent_z, agent_yaw, x, y, z) |
| 144 | | agent.step(mk_action("move", 1)) |
| 145 | | |
| 139 | def go_to_the_key(agent): |
| 140 | global agent_x, agent_y, agent_z |
| 141 | turn_to(agent,agent_x, agent_y, agent_z, agent_yaw, key_x, key_y, key_z) |
| 142 | time.sleep(0.2) |
| 143 | agent.sendCommand("move 1") |
| 144 | stop_condition(agent, 'tripwire_hook') |
| 145 | agent_x, agent_y, agent_z = key_x, key_y, key_z |
| 146 | 146 | |
| 147 | 147 | # Agent stops and grab the key |
| 148 | 148 | # observations: agent holds the key and reward=0 |
| 149 | 149 | def get_the_key(agent): |
| 150 | | global agent_z |
| 151 | | agent_z = -15 |
| 152 | | agent.step(mk_action("move", 0)) |
| 153 | | agent.step(mk_action("hotbar.2", 1)) |
| 150 | agent.sendCommand("move 0") |
| 151 | agent.sendCommand("hotbar.2 1") |
| 154 | 152 | |
| 155 | 153 | # Agent goes to the house. The agent should have the key |
| 156 | 154 | # observations: |
| 157 | 155 | # - Agent is next to closed door |
| 158 | 156 | # - Agent holds the key |
| 159 | 157 | # - reward = 0 |
| 160 | | def go_to_the_house(agent, x, y, z): |
| 161 | | agent.step(mk_action("tpx", agent_x)) |
| 158 | def go_to_the_house(agent): |
| 159 | global agent_x, agent_y, agent_z |
| 160 | turn_to(agent,agent_x, agent_y, agent_z, agent_yaw, door_x, door_y, door_z) |
| 162 | 161 | time.sleep(0.2) |
| 163 | | turn_to(agent, x, y, z) |
| 164 | | agent.step(mk_action("move", 1)) |
| 162 | agent.sendCommand("move 1") |
| 163 | stop_condition(agent, 'dark_oak_door') |
| 164 | agent_x, agent_y, agent_z = door_x, door_y, door_z |
| 165 | 165 | |
| 166 | 166 | # Agent opens the house. |
| 167 | 167 | # observations: |
| 168 | 168 | # - Agent next to opened door |
| 169 | 169 | # - reward = 0 |
| 170 | 170 | def open_the_door(agent): |
| 171 | | agent.step(mk_action("move", 0)) |
| 172 | | agent.step(mk_action("attack", 1)) |
| 171 | agent.sendCommand("move 0") |
| 172 | agent.sendCommand("attack 1") |
| 173 | 173 | |
| 174 | 174 | # Agent goes to the diamond inside the house. |
| 175 | 175 | # reward = 0 |
| 176 | | def go_to_the_diamond(): |
| 177 | | return True |
| 176 | def go_to_the_diamonds(agent): |
| 177 | global agent_x, agent_y, agent_z |
| 178 | turn_to(agent,agent_x, agent_y, agent_z, agent_yaw, diamond_x, diamond_y, diamond_z) |
| 179 | time.sleep(0.2) |
| 180 | agent.sendCommand("move 1") |
| 181 | stop_condition(agent, "diamond_block") |
| 182 | agent_x, agent_y, agent_z = diamond_x, diamond_y, diamond_z |
| 183 | |
| 184 | def stop_condition(agent, block_type): |
| 185 | done = False |
| 186 | while not done: |
| 187 | world_state = agent.getWorldState() |
| 188 | if world_state.number_of_observations_since_last_state > 0: |
| 189 | ob = world_state.observations[-1].text |
| 190 | if block_type in ob: |
| 191 | agent.sendCommand("move 0") |
| 192 | done = True |
| 178 | 193 | |
| 179 | 194 | # Agent collects the diamond inside the house |
| 180 | 195 | # reward = 1 |
| 181 | | def collect_diamond(agent): |
| 182 | | agent.step(mk_action("hotbar.1", 1)) |
| 183 | | rw, ob, _ = agent.step(mk_action("attack", 1)) |
| 184 | | return rw, ob |
| 196 | def collect_diamonds(agent): |
| 197 | agent.sendCommand("hotbar.1 1") |
| 198 | agent.sendCommand("attack 1") |
| 199 | |
| 185 | 200 | |
| 186 | 201 | if __name__ == "__main__": |
| 187 | 202 | """ |
| … | … | @@ -205,42 +220,22 @@ if __name__ == "__main__": |
| 205 | 220 | malmoWrapper.step(mk_action("hotbar.1", 0)) |
| 206 | 221 | malmoWrapper.step(mk_action("hotbar.2", 0)) |
| 207 | 222 | |
| 208 | | go_to_the_key(malmoWrapper, -4, 228, -15) |
| 223 | agent = malmoWrapper.agent_host |
| 224 | |
| 225 | go_to_the_key(agent) |
| 209 | 226 | |
| 210 | | while not done : |
| 227 | while not done: |
| 211 | 228 | print(".", end="") |
| 212 | 229 | time.sleep(0.5) |
| 213 | | agent = malmoWrapper.agent_host |
| 214 | 230 | world_state = malmoWrapper.agent_host.getWorldState() |
| 215 | 231 | |
| 216 | 232 | if world_state.number_of_observations_since_last_state > 0: |
| 217 | 233 | ob = world_state.observations[-1].text |
| 218 | | |
| 219 | | print(ob) |
| 220 | | if "tripwire_hook" in ob: |
| 221 | | malmoWrapper.step(mk_action("move", 0)) |
| 222 | | malmoWrapper.step(mk_action("hotbar.2", 1)) |
| 223 | | malmoWrapper.step(mk_action("tpx", agent_x)) |
| 224 | | |
| 225 | | malmoWrapper.step(mk_action("setYaw", 45)) |
| 226 | | malmoWrapper.step(mk_action("move", 1)) |
| 227 | | |
| 228 | | if "dark_oak_door" in ob: |
| 229 | | malmoWrapper.step(mk_action("move", 0)) |
| 230 | | malmoWrapper.step(mk_action("setYaw", 90)) |
| 231 | | malmoWrapper.step(mk_action("attack", 1)) |
| 232 | | malmoWrapper.step(mk_action("move", 1)) |
| 233 | | |
| 234 | | if "diamond_block" in ob: |
| 235 | | malmoWrapper.step(mk_action("move", 0)) |
| 236 | | collect_diamond(malmoWrapper) |
| 237 | | |
| 238 | | if world_state.number_of_rewards_since_last_state > 0: |
| 239 | | malmoWrapper.step(mk_action("attack", 0)) |
| 240 | | reward = world_state.rewards[-1].getValue() |
| 241 | | print("Reward: " + str(reward)) |
| 242 | | total_reward += reward |
| 243 | | malmoWrapper.step(mk_action("tp", "{} {} {}".format(agent_x, agent_y, agent_z))) |
| 244 | | |
| 234 | go_to_the_house(agent) |
| 235 | get_the_key(agent) |
| 236 | open_the_door(agent) |
| 237 | collect_diamonds(agent) |
| 238 | malmoWrapper.step(mk_action("tp", "{} {} {}".format(19, 230, -2))) |
| 239 | done = True |
| 245 | 240 | print() |
| 246 | 241 | print("Mission ended") |