other.py 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. """
  2. Copied and adapted from https://github.com/mila-iqia/babyai.
  3. Levels described in the Baby AI ICLR 2019 submission, with different instructions than those in other files.
  4. """
  5. from minigrid.envs.babyai.core.roomgrid_level import RoomGridLevel
  6. from minigrid.envs.babyai.core.verifier import (
  7. BeforeInstr,
  8. GoToInstr,
  9. ObjDesc,
  10. OpenInstr,
  11. PickupInstr,
  12. PutNextInstr,
  13. )
  14. class ActionObjDoor(RoomGridLevel):
  15. """
  16. [pick up an object] or
  17. [go to an object or door] or
  18. [open a door]
  19. (in the current room)
  20. """
  21. def __init__(self, **kwargs):
  22. super().__init__(room_size=7, **kwargs)
  23. def gen_mission(self):
  24. objs = self.add_distractors(1, 1, num_distractors=5)
  25. for _ in range(4):
  26. door, _ = self.add_door(1, 1, locked=False)
  27. objs.append(door)
  28. self.place_agent(1, 1)
  29. obj = self._rand_elem(objs)
  30. desc = ObjDesc(obj.type, obj.color)
  31. if obj.type == "door":
  32. if self._rand_bool():
  33. self.instrs = GoToInstr(desc)
  34. else:
  35. self.instrs = OpenInstr(desc)
  36. else:
  37. if self._rand_bool():
  38. self.instrs = GoToInstr(desc)
  39. else:
  40. self.instrs = PickupInstr(desc)
  41. class FindObjS5(RoomGridLevel):
  42. """
  43. Pick up an object (in a random room)
  44. Rooms have a size of 5
  45. This level requires potentially exhaustive exploration
  46. """
  47. def __init__(self, room_size=5, **kwargs):
  48. super().__init__(room_size=room_size, max_steps=20 * room_size**2, **kwargs)
  49. def gen_mission(self):
  50. # Add a random object to a random room
  51. i = self._rand_int(0, self.num_rows)
  52. j = self._rand_int(0, self.num_cols)
  53. obj, _ = self.add_object(i, j)
  54. self.place_agent(1, 1)
  55. self.connect_all()
  56. self.instrs = PickupInstr(ObjDesc(obj.type))
  57. class KeyCorridor(RoomGridLevel):
  58. """
  59. A ball is behind a locked door, the key is placed in a
  60. random room.
  61. """
  62. def __init__(self, num_rows=3, obj_type="ball", room_size=6, **kwargs):
  63. self.obj_type = obj_type
  64. super().__init__(
  65. room_size=room_size,
  66. num_rows=num_rows,
  67. max_steps=30 * room_size**2,
  68. **kwargs
  69. )
  70. def gen_mission(self):
  71. # Connect the middle column rooms into a hallway
  72. for j in range(1, self.num_rows):
  73. self.remove_wall(1, j, 3)
  74. # Add a locked door on the bottom right
  75. # Add an object behind the locked door
  76. room_idx = self._rand_int(0, self.num_rows)
  77. door, _ = self.add_door(2, room_idx, 2, locked=True)
  78. obj, _ = self.add_object(2, room_idx, kind=self.obj_type)
  79. # Add a key in a random room on the left side
  80. self.add_object(0, self._rand_int(0, self.num_rows), "key", door.color)
  81. # Place the agent in the middle
  82. self.place_agent(1, self.num_rows // 2)
  83. # Make sure all rooms are accessible
  84. self.connect_all()
  85. self.instrs = PickupInstr(ObjDesc(obj.type))
  86. class OneRoomS8(RoomGridLevel):
  87. """
  88. Pick up the ball
  89. Rooms have a size of 8
  90. """
  91. def __init__(self, room_size=8, **kwargs):
  92. super().__init__(room_size=room_size, num_rows=1, num_cols=1, **kwargs)
  93. def gen_mission(self):
  94. obj, _ = self.add_object(0, 0, kind="ball")
  95. self.place_agent()
  96. self.instrs = PickupInstr(ObjDesc(obj.type))
  97. class MoveTwoAcross(RoomGridLevel):
  98. """
  99. Task of the form: move the A next to the B and the C next to the D.
  100. This task is structured to have a very large number of possible
  101. instructions.
  102. """
  103. def __init__(self, room_size, objs_per_room, **kwargs):
  104. assert objs_per_room <= 9
  105. self.objs_per_room = objs_per_room
  106. super().__init__(
  107. num_rows=1,
  108. num_cols=2,
  109. room_size=room_size,
  110. max_steps=16 * room_size**2,
  111. **kwargs
  112. )
  113. def gen_mission(self):
  114. self.place_agent(0, 0)
  115. # Add objects to both the left and right rooms
  116. # so that we know that we have two non-adjacent set of objects
  117. objs_l = self.add_distractors(0, 0, self.objs_per_room)
  118. objs_r = self.add_distractors(1, 0, self.objs_per_room)
  119. # Remove the wall between the two rooms
  120. self.remove_wall(0, 0, 0)
  121. # Select objects from both subsets
  122. objs_l = self._rand_subset(objs_l, 2)
  123. objs_r = self._rand_subset(objs_r, 2)
  124. a = objs_l[0]
  125. b = objs_r[0]
  126. c = objs_r[1]
  127. d = objs_l[1]
  128. self.instrs = BeforeInstr(
  129. PutNextInstr(ObjDesc(a.type, a.color), ObjDesc(b.type, b.color)),
  130. PutNextInstr(ObjDesc(c.type, c.color), ObjDesc(d.type, d.color)),
  131. )