keycorridor.py 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. from typing import Optional
  2. from minigrid.core.constants import COLOR_NAMES
  3. from minigrid.core.mission import MissionSpace
  4. from minigrid.core.roomgrid import RoomGrid
  5. class KeyCorridorEnv(RoomGrid):
  6. """
  7. <p>
  8. <img src="https://raw.githubusercontent.com/Farama-Foundation/Minigrid/master/figures/KeyCorridorS3R1.png" alt="KeyCorridorS3R1" width="200px"/>
  9. <img src="https://raw.githubusercontent.com/Farama-Foundation/Minigrid/master/figures/KeyCorridorS3R2.png" alt="KeyCorridorS3R2" width="200px"/>
  10. <img src="https://raw.githubusercontent.com/Farama-Foundation/Minigrid/master/figures/KeyCorridorS3R3.png" alt="KeyCorridorS3R3" width="200px"/>
  11. </p>
  12. <p>
  13. <img src="https://raw.githubusercontent.com/Farama-Foundation/Minigrid/master/figures/KeyCorridorS4R3.png" alt="KeyCorridorS4R3" width="200px"/>
  14. <img src="https://raw.githubusercontent.com/Farama-Foundation/Minigrid/master/figures/KeyCorridorS5R3.png" alt="KeyCorridorS5R3" width="200px"/>
  15. <img src="https://raw.githubusercontent.com/Farama-Foundation/Minigrid/master/figures/KeyCorridorS6R3.png" alt="KeyCorridorS6R3" width="200px"/>
  16. </p>
  17. ### Description
  18. This environment is similar to the locked room environment, but there are
  19. multiple registered environment configurations of increasing size,
  20. making it easier to use curriculum learning to train an agent to solve it.
  21. The agent has to pick up an object which is behind a locked door. The key is
  22. hidden in another room, and the agent has to explore the environment to find
  23. it. The mission string does not give the agent any clues as to where the
  24. key is placed. This environment can be solved without relying on language.
  25. ### Mission Space
  26. "pick up the {color} {obj_type}"
  27. {color} is the color of the object. Can be "red", "green", "blue", "purple",
  28. "yellow" or "grey".
  29. {type} is the type of the object. Can be "ball" or "key".
  30. ### Action Space
  31. | Num | Name | Action |
  32. |-----|--------------|-------------------|
  33. | 0 | left | Turn left |
  34. | 1 | right | Turn right |
  35. | 2 | forward | Move forward |
  36. | 3 | pickup | Pick up an object |
  37. | 4 | drop | Unused |
  38. | 5 | toggle | Unused |
  39. | 6 | done | Unused |
  40. ### Observation Encoding
  41. - Each tile is encoded as a 3 dimensional tuple:
  42. `(OBJECT_IDX, COLOR_IDX, STATE)`
  43. - `OBJECT_TO_IDX` and `COLOR_TO_IDX` mapping can be found in
  44. [minigrid/minigrid.py](minigrid/minigrid.py)
  45. - `STATE` refers to the door state with 0=open, 1=closed and 2=locked
  46. ### Rewards
  47. A reward of '1' is given for success, and '0' for failure.
  48. ### Termination
  49. The episode ends if any one of the following conditions is met:
  50. 1. The agent picks up the correct object.
  51. 2. Timeout (see `max_steps`).
  52. ### Registered Configurations
  53. S: room size.
  54. R: Number of rows.
  55. - `MiniGrid-KeyCorridorS3R1-v0`
  56. - `MiniGrid-KeyCorridorS3R2-v0`
  57. - `MiniGrid-KeyCorridorS3R3-v0`
  58. - `MiniGrid-KeyCorridorS4R3-v0`
  59. - `MiniGrid-KeyCorridorS5R3-v0`
  60. - `MiniGrid-KeyCorridorS6R3-v0`
  61. """
  62. def __init__(
  63. self,
  64. num_rows=3,
  65. obj_type="ball",
  66. room_size=6,
  67. max_steps: Optional[int] = None,
  68. **kwargs,
  69. ):
  70. self.obj_type = obj_type
  71. mission_space = MissionSpace(
  72. mission_func=self._gen_mission,
  73. ordered_placeholders=[COLOR_NAMES, [obj_type]],
  74. )
  75. if max_steps is None:
  76. max_steps = 30 * room_size**2
  77. super().__init__(
  78. mission_space=mission_space,
  79. room_size=room_size,
  80. num_rows=num_rows,
  81. max_steps=max_steps,
  82. **kwargs,
  83. )
  84. @staticmethod
  85. def _gen_mission(color: str, obj_type: str):
  86. return f"pick up the {color} {obj_type}"
  87. def _gen_grid(self, width, height):
  88. super()._gen_grid(width, height)
  89. # Connect the middle column rooms into a hallway
  90. for j in range(1, self.num_rows):
  91. self.remove_wall(1, j, 3)
  92. # Add a locked door on the bottom right
  93. # Add an object behind the locked door
  94. room_idx = self._rand_int(0, self.num_rows)
  95. door, _ = self.add_door(2, room_idx, 2, locked=True)
  96. obj, _ = self.add_object(2, room_idx, kind=self.obj_type)
  97. # Add a key in a random room on the left side
  98. self.add_object(0, self._rand_int(0, self.num_rows), "key", door.color)
  99. # Place the agent in the middle
  100. self.place_agent(1, self.num_rows // 2)
  101. # Make sure all rooms are accessible
  102. self.connect_all()
  103. self.obj = obj
  104. self.mission = f"pick up the {obj.color} {obj.type}"
  105. def step(self, action):
  106. obs, reward, terminated, truncated, info = super().step(action)
  107. if action == self.actions.pickup:
  108. if self.carrying and self.carrying == self.obj:
  109. reward = self._reward()
  110. terminated = True
  111. return obs, reward, terminated, truncated, info