The source code and dockerfile for the GSW2024 AI Lab.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.

109 lines
3.7 KiB

2 months ago
  1. from __future__ import annotations
  2. from minigrid.core.grid import Grid
  3. from minigrid.core.mission import MissionSpace
  4. from minigrid.core.world_object import Door, Goal, Key
  5. from minigrid.minigrid_env import MiniGridEnv
  6. class DoubleDoorEnv(MiniGridEnv):
  7. """
  8. ## Description
  9. This environment has a key that the agent must pick up in order to unlock a
  10. goal and then get to the green goal square. This environment is difficult,
  11. because of the sparse reward, to solve using classical RL algorithms. It is
  12. useful to experiment with curiosity or curriculum learning.
  13. ## Mission Space
  14. "use the key to open the door and then get to the goal"
  15. ## Action Space
  16. | Num | Name | Action |
  17. |-----|--------------|---------------------------|
  18. | 0 | left | Turn left |
  19. | 1 | right | Turn right |
  20. | 2 | forward | Move forward |
  21. | 3 | pickup | Pick up an object |
  22. | 4 | drop | Unused |
  23. | 5 | toggle | Toggle/activate an object |
  24. | 6 | done | Unused |
  25. ## Observation Encoding
  26. - Each tile is encoded as a 3 dimensional tuple:
  27. `(OBJECT_IDX, COLOR_IDX, STATE)`
  28. - `OBJECT_TO_IDX` and `COLOR_TO_IDX` mapping can be found in
  29. [minigrid/minigrid.py](minigrid/minigrid.py)
  30. - `STATE` refers to the door state with 0=open, 1=closed and 2=locked
  31. ## Rewards
  32. A reward of '1 - 0.9 * (step_count / max_steps)' is given for success, and '0' for failure.
  33. ## Termination
  34. The episode ends if any one of the following conditions is met:
  35. 1. The agent reaches the goal.
  36. 2. Timeout (see `max_steps`).
  37. ## Registered Configurations
  38. - `MiniGrid-DoubleDoor-16x16-v0`
  39. - `MiniGrid-DoubleDoor-12x12-v0`
  40. - `MiniGrid-DoubleDoor-10x8-v0`
  41. """
  42. def __init__(self, width=8, height=8, max_steps: int | None = None, **kwargs):
  43. if max_steps is None:
  44. max_steps = 10 * (width * height)
  45. mission_space = MissionSpace(mission_func=self._gen_mission)
  46. super().__init__(
  47. mission_space=mission_space, width=width, height=height, max_steps=max_steps, **kwargs
  48. )
  49. @staticmethod
  50. def _gen_mission():
  51. return "use the key to open the door and then get to the goal"
  52. def _gen_grid(self, width, height):
  53. # Create an empty grid
  54. self.grid = Grid(width, height)
  55. # Generate the surrounding walls
  56. self.grid.wall_rect(0, 0, width, height)
  57. # Place a goal in the bottom-right corner
  58. self.put_obj(Goal(), width - 2, height - 2)
  59. # Create first vertical splitting wall
  60. # splitIdx = self._rand_int(2, width - 2)
  61. splitIdxOne = width // 3
  62. self.grid.vert_wall(splitIdxOne, 0)
  63. # Place the agent at a random position and orientation
  64. # on the left side of the splitting wall
  65. self.place_agent(size=(splitIdxOne, height))
  66. # Place a door in the wall
  67. doorIdx = height // 2
  68. self.put_obj(Door("yellow", is_locked=True), splitIdxOne, doorIdx)
  69. self.place_obj(obj=Key("yellow"), top=(0, 0), size=(splitIdxOne, height))
  70. # Create second vertical splitting wall
  71. splitIdxTwo = (width // 3) * 2
  72. self.grid.vert_wall(splitIdxTwo, 0)
  73. doorIdx = height // 2
  74. self.put_obj(Door("red", is_locked=True), splitIdxTwo, doorIdx)
  75. self.place_obj(obj=Key("red"), top=(splitIdxOne, 0), size=(splitIdxTwo - splitIdxOne, height))
  76. # Place a yellow key on the left side
  77. self.mission = "use the key to open the door and then get to the goal"