pickup.py 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. """
  2. Copied and adapted from https://github.com/mila-iqia/babyai.
  3. Levels described in the Baby AI ICLR 2019 submission, with the `Pick up` instruction.
  4. """
  5. from typing import Optional
  6. from minigrid.envs.babyai.core.levelgen import LevelGen
  7. from minigrid.envs.babyai.core.roomgrid_level import RejectSampling, RoomGridLevel
  8. from minigrid.envs.babyai.core.verifier import ObjDesc, PickupInstr
  9. class Pickup(RoomGridLevel):
  10. """
  11. Pick up an object, the object may be in another room.
  12. """
  13. def gen_mission(self):
  14. self.place_agent()
  15. self.connect_all()
  16. objs = self.add_distractors(num_distractors=18, all_unique=False)
  17. self.check_objs_reachable()
  18. obj = self._rand_elem(objs)
  19. self.instrs = PickupInstr(ObjDesc(obj.type, obj.color))
  20. class UnblockPickup(RoomGridLevel):
  21. """
  22. Pick up an object, the object may be in another room. The path may
  23. be blocked by one or more obstructors.
  24. """
  25. def gen_mission(self):
  26. self.place_agent()
  27. self.connect_all()
  28. objs = self.add_distractors(num_distractors=20, all_unique=False)
  29. # Ensure that at least one object is not reachable without unblocking
  30. # Note: the selected object will still be reachable most of the time
  31. if self.check_objs_reachable(raise_exc=False):
  32. raise RejectSampling("all objects reachable")
  33. obj = self._rand_elem(objs)
  34. self.instrs = PickupInstr(ObjDesc(obj.type, obj.color))
  35. class PickupLoc(LevelGen):
  36. """
  37. Pick up an object which may be described using its location. This is a
  38. single room environment.
  39. Competencies: PickUp, Loc. No unblocking.
  40. """
  41. def __init__(self, **kwargs):
  42. # We add many distractors to increase the probability
  43. # of ambiguous locations within the same room
  44. super().__init__(
  45. action_kinds=["pickup"],
  46. instr_kinds=["action"],
  47. num_rows=1,
  48. num_cols=1,
  49. num_dists=8,
  50. locked_room_prob=0,
  51. locations=True,
  52. unblocking=False,
  53. **kwargs
  54. )
  55. class PickupDist(RoomGridLevel):
  56. """
  57. Pick up an object
  58. The object to pick up is given by its type only, or
  59. by its color, or by its type and color.
  60. (in the current room, with distractors)
  61. """
  62. def __init__(self, debug=False, **kwargs):
  63. self.debug = debug
  64. super().__init__(num_rows=1, num_cols=1, room_size=7, **kwargs)
  65. def gen_mission(self):
  66. # Add 5 random objects in the room
  67. objs = self.add_distractors(num_distractors=5)
  68. self.place_agent(0, 0)
  69. obj = self._rand_elem(objs)
  70. type = obj.type
  71. color = obj.color
  72. select_by = self._rand_elem(["type", "color", "both"])
  73. if select_by == "color":
  74. type = None
  75. elif select_by == "type":
  76. color = None
  77. self.instrs = PickupInstr(ObjDesc(type, color), strict=self.debug)
  78. class PickupAbove(RoomGridLevel):
  79. """
  80. Pick up an object (in the room above)
  81. This task requires to use the compass to be solved effectively.
  82. """
  83. def __init__(self, max_steps: Optional[int] = None, **kwargs):
  84. room_size = 6
  85. if max_steps is None:
  86. max_steps = 8 * room_size**2
  87. super().__init__(room_size=room_size, max_steps=max_steps, **kwargs)
  88. def gen_mission(self):
  89. # Add a random object to the top-middle room
  90. obj, pos = self.add_object(1, 0)
  91. # Make sure the two rooms are directly connected
  92. self.add_door(1, 1, 3, locked=False)
  93. self.place_agent(1, 1)
  94. self.connect_all()
  95. self.instrs = PickupInstr(ObjDesc(obj.type, obj.color))