| … | … | @@ -0,0 +1,246 @@ |
| 1 | import os |
| 2 | import time |
| 3 | |
| 4 | from fastcore.basics import gen |
| 5 | |
| 6 | from rocca.envs.wrappers.malmo_wrapper import MalmoWrapper |
| 7 | from rocca.envs.wrappers.utils import * |
| 8 | from builtins import range |
| 9 | from past.utils import old_div |
| 10 | import os |
| 11 | import sys |
| 12 | import time |
| 13 | import json |
| 14 | import random |
| 15 | import math |
| 16 | |
| 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 | |
| 23 | def drawBlock(x, y, z, type): |
| 24 | return """<DrawBlock x='{0}' y='{1}' z='{2}' type='{3}'/>""".format(x, y, z, type) |
| 25 | |
| 26 | def GenCuboid(x1, y1, z1, x2, y2, z2, blocktype): |
| 27 | return '<DrawCuboid x1="' + str(x1) + '" y1="' + str(y1) + '" z1="' + str(z1) + '" x2="' + str(x2) + '" y2="' + str(y2) + '" z2="' + str(z2) + '" type="' + blocktype + '"/>' |
| 28 | |
| 29 | def build_house(x, y, z, width, length, height, blocktype): |
| 30 | x_front = x |
| 31 | x_back = x + length if x >= 0 else x-length |
| 32 | z_left = z + width if z >= 0 else z-width |
| 33 | z_right = z |
| 34 | |
| 35 | genstring = "" |
| 36 | y_cur = y |
| 37 | for i in range(height): |
| 38 | z_cur = z |
| 39 | x_cur = x |
| 40 | for j in range(width): |
| 41 | genstring = genstring + drawBlock(x_front, y_cur, z_cur, "glass") + "\n" |
| 42 | genstring = genstring + drawBlock(x_back, y_cur, z_cur, blocktype) + "\n" |
| 43 | z_cur = z_cur + 1 if z_cur >= 0 else z_cur-1 |
| 44 | |
| 45 | for k in range(length): |
| 46 | genstring = genstring + drawBlock(x_cur, y_cur, z_left, blocktype) + "\n" |
| 47 | genstring = genstring + drawBlock(x_cur, y_cur, z_right, blocktype) + "\n" |
| 48 | x_cur = x_cur + 1 if x_cur >= 0 else x_cur-1 |
| 49 | |
| 50 | y_cur = y_cur + 1 if y_cur >= 0 else y_cur-1 |
| 51 | |
| 52 | # floor |
| 53 | genstring = genstring + GenCuboid(x_back + 1 if x_back >= 0 else x_back - 1, y, z_left + 1 if z_left >= 0 else z_left - 1, x - 1 if x >= 0 else x + 1, y, z - 1 if x >= 0 else z + 1, blocktype ) |
| 54 | # ceiling |
| 55 | genstring = genstring + GenCuboid(x_back + 1 if x_back >= 0 else x_back - 1, y_cur, z_left + 1 if z_left >= 0 else z_left - 1, x - 1 if x >= 0 else x + 1, y_cur, z - 1 if x >= 0 else z + 1, blocktype ) |
| 56 | |
| 57 | return genstring |
| 58 | |
| 59 | |
| 60 | agent_x, agent_y, agent_z, agent_yaw = 9, 230, -2, 90 |
| 61 | |
| 62 | missionXML = ''' |
| 63 | <?xml version="1.0" encoding="UTF-8" standalone="no" ?> |
| 64 | <Mission xmlns="http://ProjectMalmo.microsoft.com" |
| 65 | xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> |
| 66 | |
| 67 | <About> |
| 68 | <Summary>Collect diamonds!</Summary> |
| 69 | </About> |
| 70 | |
| 71 | <ServerSection> |
| 72 | <ServerInitialConditions> |
| 73 | <Time> |
| 74 | <StartTime>1000</StartTime> |
| 75 | <AllowPassageOfTime>true</AllowPassageOfTime> |
| 76 | </Time> |
| 77 | <Weather>clear</Weather> |
| 78 | <AllowSpawning>true</AllowSpawning> |
| 79 | </ServerInitialConditions> |
| 80 | <ServerHandlers> |
| 81 | <FlatWorldGenerator generatorString="3;7,220*1,5*3,2;1;biome_1"/> |
| 82 | <DrawingDecorator> |
| 83 | '''+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 | |
| 92 | |
| 93 | </DrawingDecorator> |
| 94 | <ServerQuitFromTimeUp description="" timeLimitMs="1000000"/> |
| 95 | <ServerQuitWhenAnyAgentFinishes/> |
| 96 | </ServerHandlers> |
| 97 | </ServerSection> |
| 98 | |
| 99 | <AgentSection mode="Survival"> |
| 100 | <Name>Cog Agent</Name> |
| 101 | <AgentStart> |
| 102 | '''+'<Placement x="{}" y="{}" z="{}" yaw="{}"/>'.format(agent_x, agent_y, agent_z, agent_yaw)+''' |
| 103 | <Inventory> |
| 104 | <InventoryItem slot="0" type="diamond_pickaxe"/> |
| 105 | <InventoryItem slot="1" type="tripwire_hook"/> |
| 106 | </Inventory> |
| 107 | </AgentStart> |
| 108 | <AgentHandlers> |
| 109 | <ObservationFromGrid> |
| 110 | <Grid name="BlocksInFront"> |
| 111 | <min x="-1" y="1" z="-1"/> |
| 112 | <max x="1" y="1" z="1"/> |
| 113 | </Grid> |
| 114 | </ObservationFromGrid> |
| 115 | <ObservationFromRecentCommands/> |
| 116 | <ContinuousMovementCommands turnSpeedDegs="180"/> |
| 117 | <AbsoluteMovementCommands /> |
| 118 | <InventoryCommands/> |
| 119 | <RewardForTouchingBlockType> |
| 120 | <Block type="diamond_block" reward="1" /> |
| 121 | </RewardForTouchingBlockType> |
| 122 | <RewardForCollectingItem> |
| 123 | <Item reward="1" type="diamond_block" /> |
| 124 | </RewardForCollectingItem> |
| 125 | </AgentHandlers> |
| 126 | </AgentSection> |
| 127 | |
| 128 | </Mission> |
| 129 | |
| 130 | ''' |
| 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) |
| 136 | h = math.sqrt(x_dist**2 + z_dist**2) |
| 137 | angle = yaw + math.degrees(z_dist/h) |
| 138 | agent.step(mk_action("setYaw",angle)) |
| 139 | |
| 140 | # Agent goes to the key |
| 141 | # 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 | |
| 146 | |
| 147 | # Agent stops and grab the key |
| 148 | # observations: agent holds the key and reward=0 |
| 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)) |
| 154 | |
| 155 | # Agent goes to the house. The agent should have the key |
| 156 | # observations: |
| 157 | # - Agent is next to closed door |
| 158 | # - Agent holds the key |
| 159 | # - reward = 0 |
| 160 | def go_to_the_house(agent, x, y, z): |
| 161 | agent.step(mk_action("tpx", agent_x)) |
| 162 | time.sleep(0.2) |
| 163 | turn_to(agent, x, y, z) |
| 164 | agent.step(mk_action("move", 1)) |
| 165 | |
| 166 | # Agent opens the house. |
| 167 | # observations: |
| 168 | # - Agent next to opened door |
| 169 | # - reward = 0 |
| 170 | def open_the_door(agent): |
| 171 | agent.step(mk_action("move", 0)) |
| 172 | agent.step(mk_action("attack", 1)) |
| 173 | |
| 174 | # Agent goes to the diamond inside the house. |
| 175 | # reward = 0 |
| 176 | def go_to_the_diamond(): |
| 177 | return True |
| 178 | |
| 179 | # Agent collects the diamond inside the house |
| 180 | # 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 |
| 185 | |
| 186 | if __name__ == "__main__": |
| 187 | """ |
| 188 | The following is some random heuristics to demo how you |
| 189 | would use the MalmoWrapper and the environment defined |
| 190 | with the xml above. |
| 191 | """ |
| 192 | |
| 193 | a = AtomSpace() |
| 194 | set_default_atomspace(a) |
| 195 | |
| 196 | malmoWrapper = MalmoWrapper(missionXML=missionXML, validate=True) |
| 197 | |
| 198 | def stp_callback(action, ws): |
| 199 | pass # you can do something here. |
| 200 | |
| 201 | rw, ob, done = malmoWrapper.restart() |
| 202 | total_reward = 0 |
| 203 | # main loop: |
| 204 | time.sleep(0.5) |
| 205 | malmoWrapper.step(mk_action("hotbar.1", 0)) |
| 206 | malmoWrapper.step(mk_action("hotbar.2", 0)) |
| 207 | |
| 208 | go_to_the_key(malmoWrapper, -4, 228, -15) |
| 209 | |
| 210 | while not done : |
| 211 | print(".", end="") |
| 212 | time.sleep(0.5) |
| 213 | agent = malmoWrapper.agent_host |
| 214 | world_state = malmoWrapper.agent_host.getWorldState() |
| 215 | |
| 216 | if world_state.number_of_observations_since_last_state > 0: |
| 217 | 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 | |
| 245 | print() |
| 246 | print("Mission ended") |