def _setup_basic_gtt_task(self, num_targets=1, reward_scale=1.0): walker = walkers.Ant() text_maze = arenas.padded_room.PaddedRoom( room_size=8, num_objects=2, pad_with_walls=True) maze_arena = arenas.MazeWithTargets(maze=text_maze) targets = [] for _ in range(num_targets): targets.append( props.PositionDetector( pos=[0, 0, 0.5], size=[0.5, 0.5, 0.5], inverted=False, visible=True)) test_predicates = [predicates.MoveWalkerToRandomTarget(walker, targets)] self._task = predicate_task.PredicateTask( walker=walker, maze_arena=maze_arena, predicates=test_predicates, targets=targets, randomize_num_predicates=False, reward_scale=reward_scale, terminating_reward_bonus=2.0, ) random_state = np.random.RandomState(12345) self._env = composer.Environment(self._task, random_state=random_state) self._walker = walker self._targets = targets
def test_error_too_few_targets(self): walker = walkers.Ant() num_targets = 5 text_maze = arenas.padded_room.PaddedRoom( room_size=8, num_objects=2, pad_with_walls=True) maze_arena = arenas.MazeWithTargets(maze=text_maze) targets = [] for _ in range(num_targets): targets.append( props.PositionDetector( pos=[0, 0, 0.5], size=[0.5, 0.5, 0.5], inverted=False, visible=True)) test_predicates = [predicates.MoveWalkerToRandomTarget(walker, targets)] task = predicate_task.PredicateTask( walker=walker, maze_arena=maze_arena, predicates=test_predicates, targets=targets, randomize_num_predicates=False, reward_scale=1.0, terminating_reward_bonus=2.0, ) random_state = np.random.RandomState(12345) env = composer.Environment(task, random_state=random_state) with self.assertRaisesWithLiteralMatch( RuntimeError, "The generated maze does not contain enough target " "positions for the requested number of props (0) and targets (5): " "got 2." ): env.reset()
def test_too_few_predicates_raises_exception(self): walker = walkers.Ant() num_targets = 1 text_maze = arenas.padded_room.PaddedRoom( room_size=8, num_objects=2, pad_with_walls=True) maze_arena = arenas.MazeWithTargets(maze=text_maze) targets = [] for _ in range(num_targets): targets.append( props.PositionDetector( pos=[0, 0, 0.5], size=[0.5, 0.5, 0.5], inverted=False, visible=True)) test_predicates = [] with self.assertRaisesWithLiteralMatch( ValueError, "Not enough predicates for task." " The maximum number of " "predicates can be " "1 but only 0 predicates provided."): predicate_task.PredicateTask( walker=walker, maze_arena=maze_arena, predicates=test_predicates, targets=targets, randomize_num_predicates=False, reward_scale=1.0, terminating_reward_bonus=2.0, )
def _build(self, size=_DEFAULT_PITCH_SIZE, goal_size=None, top_camera_distance=_TOP_CAMERA_DISTANCE, field_box=False, field_box_offset=0.0, hoarding_color_scheme_id=0, name='pitch'): """Construct a pitch with walls and position detectors. Args: size: a tuple of (length, width) of the pitch. goal_size: optional (depth, width, height) indicating the goal size. If not specified, the goal size is inferred from pitch size with a fixed default ratio. top_camera_distance: the distance of the top-down camera to the pitch. field_box: adds a "field box" that collides with the ball but not the walkers. field_box_offset: offset for the fieldbox if used. hoarding_color_scheme_id: An integer with value 0, 1, 2, or 3, specifying a preset scheme for the hoarding colors. name: the name of this arena. """ super(Pitch, self)._build(name=name) self._size = size self._goal_size = goal_size self._top_camera_distance = top_camera_distance self._hoarding_color_scheme_id = hoarding_color_scheme_id self._top_camera = self._mjcf_root.worldbody.add( 'camera', name='top_down', pos=[0, 0, top_camera_distance], zaxis=[0, 0, 1], fovy=_top_down_cam_fovy(self._size, top_camera_distance)) # Ensure close up geoms are rendered by egocentric cameras. self._mjcf_root.visual.map.znear = 0.0005 # Add skybox. self._mjcf_root.asset.add('texture', name='skybox', type='skybox', builtin='gradient', rgb1=(.7, .9, .9), rgb2=(.03, .09, .27), width=400, height=400) # Add and position corner lights. self._corner_lights = [ self._mjcf_root.worldbody.add('light', cutoff=60) for _ in range(4) ] _reposition_corner_lights(self._corner_lights, size) # Increase shadow resolution, (default is 1024). self._mjcf_root.visual.quality.shadowsize = 4096 # Build groundplane. if len(self._size) != 2: raise ValueError( '`size` should be a sequence of length 2: got {!r}'.format( self._size)) self._field_texture = self._mjcf_root.asset.add( 'texture', type='2d', file=_get_texture('pitch_nologo_l'), name='fieldplane') self._field_material = self._mjcf_root.asset.add( 'material', name='fieldplane', texture=self._field_texture) self._ground_geom = self._mjcf_root.worldbody.add( 'geom', name='ground', type='plane', material=self._field_material, size=list(self._size) + [max(self._size) * _GROUND_GEOM_GRID_RATIO]) # Build walls. self._walls = [] for wall_pos, wall_xyaxes in _wall_pos_xyaxes(self._size): self._walls.append( self._mjcf_root.worldbody.add('geom', type='plane', rgba=[.1, .1, .1, .8], pos=wall_pos, size=[1e-7, 1e-7, 1e-7], xyaxes=wall_xyaxes)) # Build goal position detectors. # If field_box is enabled, offset goal by 1.0 such that ball reaches the # goal position detector before bouncing off the field_box. self._fb_offset = field_box_offset if field_box else 0.0 goal_size = self._get_goal_size() self._home_goal = Goal(direction=1, make_net=False, pos=(-self._size[0] + goal_size[0] + self._fb_offset, 0, goal_size[2]), size=goal_size, rgba=(.2, .2, 1, 0.5), visible=True, name='home_goal') self.attach(self._home_goal) self._away_goal = Goal(direction=-1, make_net=False, pos=(self._size[0] - goal_size[0] - self._fb_offset, 0, goal_size[2]), size=goal_size, rgba=(1, .2, .2, 0.5), visible=True, name='away_goal') self.attach(self._away_goal) # Build inverted field position detectors. self._field = props.PositionDetector( pos=(0, 0), size=(self._size[0] - 2 * goal_size[0], self._size[1] - 2 * goal_size[0]), inverted=True, visible=False, name='field') self.attach(self._field) # Build field perimeter. def _visual_plane(): return self._mjcf_root.worldbody.add('geom', type='plane', size=(1, 1, 1), rgba=(0.306, 0.682, 0.223, 1), contype=0, conaffinity=0) self._perimeter = [_visual_plane() for _ in range(8)] self._update_perimeter() # Build field box. self._field_box = [] if field_box: for box_pos, box_size in _fieldbox_pos_size( (self._field.upper - self._field.lower) / 2.0, goal_size): self._field_box.append( self._mjcf_root.worldbody.add('geom', type='box', rgba=[.3, .3, .3, .0], pos=box_pos, size=box_size)) # Build hoarding sites. def _box_site(): return self._mjcf_root.worldbody.add('site', type='box', size=(1, 1, 1)) self._hoarding = [_box_site() for _ in range(4 * _NUM_HOARDING)] self._update_hoarding()
def _make_predicate_task(n_boxes, n_targets, include_gtt_predicates, include_move_box_predicates, max_num_predicates, control_timestep, time_limit): """Auxiliary function to construct different predicates tasks.""" walker = walkers.Ant() skybox = dmlab_assets.SkyBox(style='sky_03') wall = dmlab_assets.WallTextures(style='style_03') floor = dmlab_assets.FloorTextures(style='style_03') # Make room size become bigger once the number of objects become larger. num_objects = n_boxes + n_targets room_size = max(MIN_ROOM_SIZE, num_objects) text_maze = locomotion_arenas.padded_room.PaddedRoom( room_size=room_size, num_objects=num_objects, pad_with_walls=True) arena = locomotion_arenas.MazeWithTargets( maze=text_maze, skybox_texture=skybox, wall_textures=wall, floor_textures=floor) boxes = [] for _ in range(n_boxes): boxes.append( manipulation_props.BoxWithSites(mass=1.5, half_lengths=[0.5, 0.5, 0.5])) targets = [] for _ in range(n_targets): targets.append( props.PositionDetector( pos=[0, 0, 0.5], size=[0.5, 0.5, 0.5], inverted=False, visible=True)) predicates = [] if include_gtt_predicates: predicates.append( predicates_module.MoveWalkerToRandomTarget( walker=walker, targets=targets)) if include_move_box_predicates: for box_idx in range(len(boxes)): predicates.append( predicates_module.MoveBoxToRandomTarget( walker=walker, box=boxes[box_idx], box_index=box_idx, targets=targets)) task = PredicateTask( walker=walker, maze_arena=arena, predicates=predicates, props=boxes, targets=targets, max_num_predicates=max_num_predicates, randomize_num_predicates=False, reward_scale=10., regenerate_predicates=False, physics_timestep=0.005, control_timestep=control_timestep) env = composer.Environment(task=task, time_limit=time_limit) return env
def _build(self, size=_DEFAULT_PITCH_SIZE, goal_size=None, top_camera_distance=_TOP_CAMERA_DISTANCE, field_box=False, name='pitch'): """Construct a pitch with walls and position detectors. Args: size: a tuple of (length, width) of the pitch. goal_size: optional (depth, width, height) indicating the goal size. If not specified, the goal size is inferred from pitch size with a fixed default ratio. top_camera_distance: the distance of the top-down camera to the pitch. field_box: adds a "field box" that collides with the ball but not the walkers. name: the name of this arena. """ super(Pitch, self)._build(name=name) self._size = size self._goal_size = goal_size self._top_camera_distance = top_camera_distance self._top_camera = self._mjcf_root.worldbody.add( 'camera', name='top_down', pos=[0, 0, top_camera_distance], zaxis=[0, 0, 1], fovy=_top_down_cam_fovy(self._size, top_camera_distance)) self._mjcf_root.visual.headlight.set_attributes(ambient=[.4, .4, .4], diffuse=[.8, .8, .8], specular=[.1, .1, .1]) # Ensure close up geoms are rendered by egocentric cameras. self._mjcf_root.visual.map.znear = 0.0005 # Build groundplane. if len(self._size) != 2: raise ValueError( '`size` should be a sequence of length 2: got {!r}'.format( self._size)) self._ground_texture = self._mjcf_root.asset.add( 'texture', type='2d', builtin='checker', name='groundplane', rgb1=[0.3, 0.8, 0.3], rgb2=[0.1, 0.6, 0.1], width=300, height=300, mark='edge', markrgb=[0.8, 0.8, 0.8]) self._ground_material = self._mjcf_root.asset.add( 'material', name='groundplane', texture=self._ground_texture) self._ground_geom = self._mjcf_root.worldbody.add( 'geom', type='plane', material=self._ground_material, size=list(self._size) + [max(self._size) * _GROUND_GEOM_GRID_RATIO]) # Build walls. self._walls = [] for wall_pos, wall_xyaxes in _wall_pos_xyaxes(self._size): self._walls.append( self._mjcf_root.worldbody.add('geom', type='plane', rgba=[.1, .1, .1, .8], pos=wall_pos, size=[1e-7, 1e-7, 1e-7], xyaxes=wall_xyaxes)) # Build goal position detectors. # If field_box is enabled, offset goal by 1.0 such that ball reaches the # goal position detector before bouncing off the field_box. self._fb_offset = 0.5 if field_box else 0.0 goal_size = self._get_goal_size() self._home_goal = props.PositionDetector( pos=(-self._size[0] + goal_size[0] + self._fb_offset, 0, goal_size[2]), size=goal_size, rgba=(0, 0, 1, 0.5), visible=True, name='home_goal') self.attach(self._home_goal) self._away_goal = props.PositionDetector( pos=(self._size[0] - goal_size[0] - self._fb_offset, 0, goal_size[2]), size=goal_size, rgba=(1, 0, 0, 0.5), visible=True, name='away_goal') self.attach(self._away_goal) # Build inverted field position detectors. self._field = props.PositionDetector( pos=(0, 0), size=(self._size[0] - 2 * goal_size[0], self._size[1] - 2 * goal_size[0]), rgba=(1, 0, 0, 0.1), inverted=True, visible=True, name='field') self.attach(self._field) # Build field box. self._field_box = [] if field_box: for wall_pos, wall_xyaxes in _wall_pos_xyaxes( (self._field.upper - self._field.lower) / 2.0): self._field_box.append( self._mjcf_root.worldbody.add('geom', type='plane', rgba=[.3, .3, .3, .3], pos=wall_pos, size=[1e-7, 1e-7, 1e-7], xyaxes=wall_xyaxes))
def _build(self, size=_DEFAULT_PITCH_SIZE, goal_size=None, top_camera_distance=_TOP_CAMERA_DISTANCE, name='pitch'): """Construct a pitch with walls and position detectors. Args: size: a tuple of (length, width) of the pitch. goal_size: optional (depth, width, height) indicating the goal size. If not specified, the goal size is inferred from pitch size with a fixed default ratio. top_camera_distance: the distance of the top-down camera to the pitch. name: the name of this arena. """ super(Pitch, self)._build(name=name) self._size = size self._goal_size = goal_size self._top_camera_distance = top_camera_distance self._top_camera = self._mjcf_root.worldbody.add( 'camera', name='top_down', pos=[0, 0, top_camera_distance], zaxis=[0, 0, 1], fovy=_top_down_cam_fovy(self._size, top_camera_distance)) self._mjcf_root.visual.headlight.set_attributes(ambient=[.4, .4, .4], diffuse=[.8, .8, .8], specular=[.1, .1, .1]) # Build groundplane. if len(self._size) != 2: raise ValueError( '`size` should be a sequence of length 2: got {!r}'.format( self._size)) self._ground_texture = self._mjcf_root.asset.add( 'texture', type='2d', builtin='checker', name='groundplane', rgb1=[0.3, 0.8, 0.3], rgb2=[0.1, 0.6, 0.1], width=300, height=300, mark='edge', markrgb=[0.8, 0.8, 0.8]) self._ground_material = self._mjcf_root.asset.add( 'material', name='groundplane', texture=self._ground_texture) self._ground_geom = self._mjcf_root.worldbody.add( 'geom', type='plane', material=self._ground_material, size=list(self._size) + [_GROUND_GEOM_HEIGHT]) # Build walls. self._walls = [] for wall_pos, wall_size in _wall_pos_size(self._size): self._walls.append( self._mjcf_root.worldbody.add('geom', type='box', rgba=[.3, .3, .3, .0], pos=wall_pos, size=wall_size)) # Build roof. self._roof = self._mjcf_root.worldbody.add('geom', type='box', rgba=[.3, .3, .3, .3], pos=(0., 0., 2 * _WALL_HEIGHT), group=4, size=_roof_size(self._size)) # Build goal position detectors. goal_size = self._get_goal_size() self._home_goal = props.PositionDetector( pos=(-self._size[0] + goal_size[0], 0, goal_size[2]), size=goal_size, rgba=(0, 0, 1, 0.5), visible=True, name='home_goal') self.attach(self._home_goal) self._away_goal = props.PositionDetector( pos=(self._size[0] - goal_size[0], 0, goal_size[2]), size=goal_size, rgba=(1, 0, 0, 0.5), visible=True, name='away_goal') self.attach(self._away_goal) # Build inverted field position detectors. self._field = props.PositionDetector( pos=(0, 0), size=(self._size[0] - 2 * goal_size[0], self._size[1] - 2 * goal_size[0]), rgba=(0, 0, 0, 0.1), inverted=True, visible=True, name='field') self.attach(self._field)
def test_error_if_no_predicates_found(self): walker = walkers.Ant() num_targets = 2 text_maze = arenas.padded_room.PaddedRoom( room_size=8, num_objects=6, pad_with_walls=True) maze_arena = arenas.MazeWithTargets(maze=text_maze) targets = [] for _ in range(num_targets): targets.append( props.PositionDetector( pos=[0, 0, 0.5], size=[0.5, 0.5, 0.5], inverted=False, visible=True)) # Moving the walker to two targets is not possible since the walker is a # shared object in use. test_predicates = [predicates.MoveWalkerToTarget(walker, targets[0]), predicates.MoveWalkerToTarget(walker, targets[1])] task = predicate_task.PredicateTask( walker=walker, maze_arena=maze_arena, predicates=test_predicates, targets=targets[1:], randomize_num_predicates=False, max_num_predicates=2, reward_scale=1.0, terminating_reward_bonus=2.0, ) random_state = np.random.RandomState(12345) env = composer.Environment(task, random_state=random_state) with self.assertRaisesWithLiteralMatch( ValueError, "Could not find set of active predicates" " with unique objects are after 1000 iterations."): env.reset() # However moving to one of the two targets is fine. walker = walkers.Ant() num_targets = 2 text_maze = arenas.padded_room.PaddedRoom( room_size=8, num_objects=6, pad_with_walls=True) maze_arena = arenas.MazeWithTargets(maze=text_maze) targets = [] for _ in range(num_targets): targets.append( props.PositionDetector( pos=[0, 0, 0.5], size=[0.5, 0.5, 0.5], inverted=False, visible=True)) test_predicates = [predicates.MoveWalkerToTarget(walker, targets[0]), predicates.MoveWalkerToTarget(walker, targets[1])] task = predicate_task.PredicateTask( walker=walker, maze_arena=maze_arena, predicates=test_predicates, targets=targets[1:], randomize_num_predicates=False, max_num_predicates=1, reward_scale=1.0, terminating_reward_bonus=2.0, ) random_state = np.random.RandomState(12345) env = composer.Environment(task, random_state=random_state) env.reset()