putnext.py 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. """
  2. Copied and adapted from https://github.com/mila-iqia/babyai.
  3. Levels described in the Baby AI ICLR 2019 submission, with the `Put Next` instruction.
  4. """
  5. from minigrid.envs.babyai.core.roomgrid_level import RoomGridLevel
  6. from minigrid.envs.babyai.core.verifier import ObjDesc, PutNextInstr
  7. class PutNextLocal(RoomGridLevel):
  8. """
  9. Put an object next to another object, inside a single room
  10. with no doors, no distractors
  11. """
  12. def __init__(self, room_size=8, num_objs=8, **kwargs):
  13. self.num_objs = num_objs
  14. super().__init__(num_rows=1, num_cols=1, room_size=room_size, **kwargs)
  15. def gen_mission(self):
  16. self.place_agent()
  17. objs = self.add_distractors(num_distractors=self.num_objs, all_unique=True)
  18. self.check_objs_reachable()
  19. o1, o2 = self._rand_subset(objs, 2)
  20. self.instrs = PutNextInstr(
  21. ObjDesc(o1.type, o1.color), ObjDesc(o2.type, o2.color)
  22. )
  23. class PutNext(RoomGridLevel):
  24. """
  25. Task of the form: move the A next to the B and the C next to the D.
  26. This task is structured to have a very large number of possible
  27. instructions.
  28. """
  29. def __init__(self, room_size, objs_per_room, start_carrying=False, **kwargs):
  30. assert room_size >= 4
  31. assert objs_per_room <= 9
  32. self.objs_per_room = objs_per_room
  33. self.start_carrying = start_carrying
  34. super().__init__(
  35. num_rows=1,
  36. num_cols=2,
  37. room_size=room_size,
  38. max_steps=8 * room_size**2,
  39. **kwargs
  40. )
  41. def gen_mission(self):
  42. self.place_agent(0, 0)
  43. # Add objects to both the left and right rooms
  44. # so that we know that we have two non-adjacent set of objects
  45. objs_l = self.add_distractors(0, 0, self.objs_per_room)
  46. objs_r = self.add_distractors(1, 0, self.objs_per_room)
  47. # Remove the wall between the two rooms
  48. self.remove_wall(0, 0, 0)
  49. # Select objects from both subsets
  50. a = self._rand_elem(objs_l)
  51. b = self._rand_elem(objs_r)
  52. # Randomly flip the object to be moved
  53. if self._rand_bool():
  54. t = a
  55. a = b
  56. b = t
  57. self.obj_a = a
  58. self.instrs = PutNextInstr(ObjDesc(a.type, a.color), ObjDesc(b.type, b.color))
  59. def reset(self, **kwargs):
  60. obs = super().reset(**kwargs)
  61. # If the agent starts off carrying the object
  62. if self.start_carrying:
  63. self.grid.set(*self.obj_a.init_pos, None)
  64. self.carrying = self.obj_a
  65. return obs