def cmu_humanoid_run_gaps(random_state=None):
    """Requires a CMU humanoid to run down a corridor with gaps."""

    # Build a position-controlled CMU humanoid walker.
    walker = cmu_humanoid.CMUHumanoidPositionControlled(
        observable_options={'egocentric_camera': dict(enabled=True)})

    # Build a corridor-shaped arena with gaps, where the sizes of the gaps and
    # platforms are uniformly randomized.
    arena = corr_arenas.GapsCorridor(
        platform_length=distributions.Uniform(.3, 2.5),
        gap_length=distributions.Uniform(.5, 1.25),
        corridor_width=10,
        corridor_length=100)

    # Build a task that rewards the agent for running down the corridor at a
    # specific velocity.
    task = corr_tasks.RunThroughCorridor(walker=walker,
                                         arena=arena,
                                         walker_spawn_position=(0.5, 0, 0),
                                         target_velocity=3.0,
                                         physics_timestep=0.005,
                                         control_timestep=0.03)

    return composer.Environment(time_limit=30,
                                task=task,
                                random_state=random_state,
                                strip_singleton_obs_buffer_dim=True)
Exemple #2
0
def rodent_run_gaps(random_state=None):
    """Requires a rodent to run down a corridor with gaps."""

    # Build a position-controlled rodent walker.
    walker = rodent.Rat(
        observable_options={'egocentric_camera': dict(enabled=True)})

    # Build a corridor-shaped arena with gaps, where the sizes of the gaps and
    # platforms are uniformly randomized.
    arena = corr_arenas.GapsCorridor(platform_length=distributions.Uniform(
        .4, .8),
                                     gap_length=distributions.Uniform(.05, .2),
                                     corridor_width=2,
                                     corridor_length=40,
                                     aesthetic='outdoor_natural')

    # Build a task that rewards the agent for running down the corridor at a
    # specific velocity.
    task = corr_tasks.RunThroughCorridor(walker=walker,
                                         arena=arena,
                                         walker_spawn_position=(5, 0, 0),
                                         walker_spawn_rotation=0,
                                         target_velocity=1.0,
                                         contact_termination=False,
                                         terminate_at_height=-0.3,
                                         physics_timestep=_PHYSICS_TIMESTEP,
                                         control_timestep=_CONTROL_TIMESTEP)

    return composer.Environment(time_limit=30,
                                task=task,
                                random_state=random_state,
                                strip_singleton_obs_buffer_dim=True)
Exemple #3
0
def _build_rodent_corridor_gaps():
    """Build environment where a rodent runs over gaps."""
    walker = walkers.Rat(
        observable_options={'egocentric_camera': dict(enabled=True)}, )

    platform_length = distributions.Uniform(low=0.4, high=0.8)
    gap_length = distributions.Uniform(low=0.05, high=0.2)
    arena = arenas.corridors.GapsCorridor(corridor_width=2,
                                          platform_length=platform_length,
                                          gap_length=gap_length,
                                          corridor_length=40,
                                          aesthetic='outdoor_natural')

    rodent_task = tasks.corridors.RunThroughCorridor(walker=walker,
                                                     arena=arena,
                                                     walker_spawn_position=(5,
                                                                            0,
                                                                            0),
                                                     walker_spawn_rotation=0,
                                                     target_velocity=1.0,
                                                     contact_termination=False,
                                                     terminate_at_height=-0.3,
                                                     physics_timestep=0.001,
                                                     control_timestep=.02)
    raw_env = composer.Environment(time_limit=30,
                                   task=rodent_task,
                                   strip_singleton_obs_buffer_dim=True)

    return raw_env
Exemple #4
0
def jumping_ball_run_gaps(random_state=None):
    walker = jumping_ball.JumpingBallWithHead()

    # Build a corridor-shaped arena with gaps, where the sizes of the gaps and
    # platforms are uniformly randomized.
    arena = corr_arenas.GapsCorridor(
        platform_length=distributions.Uniform(1.0, 2.5),  # (0.3, 2.5)
        gap_length=distributions.Uniform(0.3, 0.7),  # (0.5, 1.25)
        corridor_width=10,
        corridor_length=250)

    # Build a task that rewards the agent for running down the corridor at a
    # specific velocity.
    task = corr_tasks.RunThroughCorridor(walker=walker,
                                         arena=arena,
                                         walker_spawn_position=(1.0, 0, 0),
                                         target_velocity=3.0,
                                         contact_termination=False,
                                         physics_timestep=_PHYSICS_TIMESTEP,
                                         control_timestep=_CONTROL_TIMESTEP)

    return composer.Environment(time_limit=30,
                                task=task,
                                random_state=random_state,
                                strip_singleton_obs_buffer_dim=True)
Exemple #5
0
def build_vision_warehouse(random_state=None):
    """Build canonical 4-pedestal, 2-prop task."""

    # Build a position-controlled CMU humanoid walker.
    walker = cmu_humanoid.CMUHumanoidPositionControlled(
        observable_options={'egocentric_camera': dict(enabled=True)})

    # Build the task.
    size_distribution = distributions.Uniform(low=0.75, high=1.25)
    mass_distribution = distributions.Uniform(low=2, high=7)
    prop_resizer = mocap_loader.PropResizer(size_factor=size_distribution,
                                            mass=mass_distribution)
    task = warehouse.PhasedBoxCarry(
        walker=walker,
        num_props=2,
        num_pedestals=4,
        proto_modifier=prop_resizer,
        negative_reward_on_failure_termination=True)

    # return the environment
    return composer.Environment(time_limit=15,
                                task=task,
                                random_state=random_state,
                                strip_singleton_obs_buffer_dim=True,
                                max_reset_attempts=float('inf'))
Exemple #6
0
def _build_humanoid_walls_env():
    """Build humanoid walker walls environment."""
    walker = walkers.CMUHumanoidPositionControlled(
        name='walker',
        observable_options={'egocentric_camera': dict(enabled=True)},
    )
    wall_width = distributions.Uniform(low=1, high=7)
    wall_height = distributions.Uniform(low=2.5, high=4.0)
    swap_wall_side = distributions.Bernoulli(prob=0.5)
    wall_r = distributions.Uniform(low=0.5, high=0.6)
    wall_g = distributions.Uniform(low=0.21, high=0.41)
    wall_rgba = colors.RgbVariation(r=wall_r, g=wall_g, b=0, alpha=1)
    arena = arenas.WallsCorridor(wall_gap=5.0,
                                 wall_width=wall_width,
                                 wall_height=wall_height,
                                 swap_wall_side=swap_wall_side,
                                 wall_rgba=wall_rgba,
                                 corridor_width=10,
                                 corridor_length=100)
    humanoid_task = tasks.RunThroughCorridor(
        walker=walker,
        arena=arena,
        walker_spawn_rotation=1.57,  # pi / 2
        physics_timestep=0.005,
        control_timestep=0.03)
    raw_env = composer.Environment(time_limit=30,
                                   task=humanoid_task,
                                   strip_singleton_obs_buffer_dim=True)

    return raw_env
Exemple #7
0
def walker_run_gaps(random_state=None):
    walker = planar_walker.PlanarWalker()

    # Build a corridor-shaped arena with gaps, where the sizes of the gaps and
    # platforms are uniformly randomized.
    arena = corr_arenas.GapsCorridor(
        platform_length=distributions.Uniform(1.25, 2.5),  # (0.3, 2.5)
        gap_length=distributions.Uniform(0.3, 0.7),  # (0.5, 1.25)
        corridor_width=10,
        corridor_length=250)

    # Build a task that rewards the agent for running down the corridor at a
    # specific velocity.
    task = corr_tasks.RunThroughCorridor(walker=walker,
                                         arena=arena,
                                         walker_spawn_position=(1.0, 0, 0),
                                         stand_height=1.2,
                                         contact_termination=False,
                                         physics_timestep=_PHYSICS_TIMESTEP,
                                         control_timestep=_CONTROL_TIMESTEP)

    # (Chongyi Zheng): redefine reward function
    task.get_reward = _walker_get_reward.__get__(task, task.get_reward)

    return composer.Environment(time_limit=30,
                                task=task,
                                random_state=random_state,
                                strip_singleton_obs_buffer_dim=True)
Exemple #8
0
def build_vision_toss(random_state=None):
    """Build canonical ball tossing task."""

    # Build a position-controlled CMU humanoid walker.
    walker = cmu_humanoid.CMUHumanoidPositionControlled(
        observable_options={'egocentric_camera': dict(enabled=True)})

    # Build the task.
    size_distribution = distributions.Uniform(low=0.95, high=1.5)
    mass_distribution = distributions.Uniform(low=2, high=4)
    prop_resizer = mocap_loader.PropResizer(size_factor=size_distribution,
                                            mass=mass_distribution)
    task = ball_toss.BallToss(walker=walker,
                              proto_modifier=prop_resizer,
                              negative_reward_on_failure_termination=True,
                              priority_friction=True,
                              bucket_offset=3.,
                              y_range=0.5,
                              toss_delay=1.5,
                              randomize_init=True)

    # return the environment
    return composer.Environment(time_limit=6,
                                task=task,
                                random_state=random_state,
                                strip_singleton_obs_buffer_dim=True,
                                max_reset_attempts=float('inf'))
Exemple #9
0
  def __init__(
      self, arena, arm, hand, prop, obs_settings, workspace, control_timestep):
    """Initializes a new `Reach` task.

    Args:
      arena: `composer.Entity` instance.
      arm: `robot_base.RobotArm` instance.
      hand: `robot_base.RobotHand` instance.
      prop: `composer.Entity` instance specifying the prop to reach to, or None
        in which case the target is a fixed site whose position is specified by
        the workspace.
      obs_settings: `observations.ObservationSettings` instance.
      workspace: `_ReachWorkspace` specifying the placement of the prop and TCP.
      control_timestep: Float specifying the control timestep in seconds.
    """
    self._arena = arena
    self._arm = arm
    self._hand = hand
    self._arm.attach(self._hand)
    self._arena.attach_offset(self._arm, offset=workspace.arm_offset)
    self.control_timestep = control_timestep
    self._tcp_initializer = initializers.ToolCenterPointInitializer(
        self._hand, self._arm,
        position=distributions.Uniform(*workspace.tcp_bbox),
        quaternion=workspaces.DOWN_QUATERNION)

    # Add custom camera observable.
    self._task_observables = cameras.add_camera_observables(
        arena, obs_settings, cameras.FRONT_CLOSE)

    target_pos_distribution = distributions.Uniform(*workspace.target_bbox)
    self._prop = prop
    if prop:
      # The prop itself is used to visualize the target location.
      self._make_target_site(parent_entity=prop, visible=False)
      self._target = self._arena.add_free_entity(prop)
      self._prop_placer = initializers.PropPlacer(
          props=[prop],
          position=target_pos_distribution,
          quaternion=workspaces.uniform_z_rotation,
          settle_physics=True)
    else:
      self._target = self._make_target_site(parent_entity=arena, visible=True)
      self._target_placer = target_pos_distribution

      obs = observable.MJCFFeature('pos', self._target)
      obs.configure(**obs_settings.prop_pose._asdict())
      self._task_observables['target_position'] = obs

    # Add sites for visualizing the prop and target bounding boxes.
    workspaces.add_bbox_site(
        body=self.root_entity.mjcf_model.worldbody,
        lower=workspace.tcp_bbox.lower, upper=workspace.tcp_bbox.upper,
        rgba=constants.GREEN, name='tcp_spawn_area')
    workspaces.add_bbox_site(
        body=self.root_entity.mjcf_model.worldbody,
        lower=workspace.target_bbox.lower, upper=workspace.target_bbox.upper,
        rgba=constants.BLUE, name='target_spawn_area')
Exemple #10
0
    def __init__(self, arena, arm, hand, prop, obs_settings, workspace,
                 control_timestep):
        """Initializes a new `Lift` task.

    Args:
      arena: `composer.Entity` instance.
      arm: `robot_base.RobotArm` instance.
      hand: `robot_base.RobotHand` instance.
      prop: `composer.Entity` instance.
      obs_settings: `observations.ObservationSettings` instance.
      workspace: `_LiftWorkspace` specifying the placement of the prop and TCP.
      control_timestep: Float specifying the control timestep in seconds.
    """
        self._arena = arena
        self._arm = arm
        self._hand = hand
        self._arm.attach(self._hand)
        self._arena.attach_offset(self._arm, offset=workspace.arm_offset)
        self.control_timestep = control_timestep

        # Add custom camera observable.
        self._task_observables = cameras.add_camera_observables(
            arena, obs_settings, cameras.FRONT_CLOSE)

        self._tcp_initializer = initializers.ToolCenterPointInitializer(
            self._hand,
            self._arm,
            position=distributions.Uniform(*workspace.tcp_bbox),
            quaternion=workspaces.DOWN_QUATERNION)

        self._prop = prop
        self._arena.add_free_entity(prop)
        self._prop_placer = initializers.PropPlacer(
            props=[prop],
            position=distributions.Uniform(*workspace.prop_bbox),
            quaternion=workspaces.uniform_z_rotation,
            ignore_collisions=True,
            settle_physics=True)

        # Add sites for visualizing bounding boxes and target height.
        self._target_height_site = workspaces.add_bbox_site(
            body=self.root_entity.mjcf_model.worldbody,
            lower=(-1, -1, 0),
            upper=(1, 1, 0),
            rgba=constants.RED,
            name='target_height')
        workspaces.add_bbox_site(body=self.root_entity.mjcf_model.worldbody,
                                 lower=workspace.tcp_bbox.lower,
                                 upper=workspace.tcp_bbox.upper,
                                 rgba=constants.GREEN,
                                 name='tcp_spawn_area')
        workspaces.add_bbox_site(body=self.root_entity.mjcf_model.worldbody,
                                 lower=workspace.prop_bbox.lower,
                                 upper=workspace.prop_bbox.upper,
                                 rgba=constants.BLUE,
                                 name='prop_spawn_area')
Exemple #11
0
class PitchTest(parameterized.TestCase):

  def _pitch_with_ball(self, pitch_size, ball_pos):
    pitch = pitch_lib.Pitch(size=pitch_size)
    self.assertEqual(pitch.size, pitch_size)

    sphere = props.Primitive(geom_type='sphere', size=(0.1,), pos=ball_pos)
    pitch.register_ball(sphere)
    pitch.attach(sphere)

    env = composer.Environment(
        composer.NullTask(pitch), random_state=np.random.RandomState(42))
    env.reset()
    return pitch

  def test_pitch_none_detected(self):
    pitch = self._pitch_with_ball((12, 9), (0, 0, 0))
    self.assertEmpty(pitch.detected_off_court())
    self.assertIsNone(pitch.detected_goal())

  def test_pitch_detected_off_court(self):
    pitch = self._pitch_with_ball((12, 9), (20, 0, 0))
    self.assertLen(pitch.detected_off_court(), 1)
    self.assertIsNone(pitch.detected_goal())

  def test_pitch_detected_away_goal(self):
    pitch = self._pitch_with_ball((12, 9), (-9.5, 0, 1))
    self.assertLen(pitch.detected_off_court(), 1)
    self.assertEqual(team_lib.Team.AWAY, pitch.detected_goal())

  def test_pitch_detected_home_goal(self):
    pitch = self._pitch_with_ball((12, 9), (9.5, 0, 1))
    self.assertLen(pitch.detected_off_court(), 1)
    self.assertEqual(team_lib.Team.HOME, pitch.detected_goal())

  @parameterized.parameters((True, distributions.Uniform()),
                            (False, distributions.Uniform()))
  def test_randomize_pitch(self, keep_aspect_ratio, randomizer):
    pitch = pitch_lib.RandomizedPitch(
        min_size=(4, 3),
        max_size=(8, 6),
        randomizer=randomizer,
        keep_aspect_ratio=keep_aspect_ratio)
    pitch.initialize_episode_mjcf(np.random.RandomState(42))

    self.assertBetween(pitch.size[0], 4, 8)
    self.assertBetween(pitch.size[1], 3, 6)

    if keep_aspect_ratio:
      self.assertAlmostEqual((pitch.size[0] - 4) / (8. - 4.),
                             (pitch.size[1] - 3) / (6. - 3.))
Exemple #12
0
def ant_run_walls():
    walker = ant.Ant()

    arena = corr_arenas.WallsCorridor(wall_gap=4.,
                                      wall_width=distributions.Uniform(1, 7),
                                      wall_height=3.0,
                                      corridor_width=10,
                                      corridor_length=250,
                                      include_initial_padding=False)

    task = corr_tasks.RunThroughCorridor(walker=walker,
                                         arena=arena,
                                         walker_spawn_position=(0.5, 0, 0),
                                         walker_spawn_rotation=0,
                                         stand_height=0.2,
                                         contact_termination=False,
                                         physics_timestep=_PHYSICS_TIMESTEP,
                                         control_timestep=_CONTROL_TIMESTEP)

    # (Chongyi Zheng): redefine reward function
    # task.get_reward = _ant_get_reward.__get__(task, task.get_reward)

    return composer.Environment(time_limit=30,
                                task=task,
                                strip_singleton_obs_buffer_dim=True)
def cmu_humanoid_run_walls(random_state=None):
    """Requires a CMU humanoid to run down a corridor obstructed by walls."""

    # Build a position-controlled CMU humanoid walker.
    walker = cmu_humanoid.CMUHumanoidPositionControlled(
        observable_options={'egocentric_camera': dict(enabled=True)})

    # Build a corridor-shaped arena that is obstructed by walls.
    arena = corr_arenas.WallsCorridor(wall_gap=4.,
                                      wall_width=distributions.Uniform(1, 7),
                                      wall_height=3.0,
                                      corridor_width=10,
                                      corridor_length=100,
                                      include_initial_padding=False)

    # Build a task that rewards the agent for running down the corridor at a
    # specific velocity.
    task = corr_tasks.RunThroughCorridor(walker=walker,
                                         arena=arena,
                                         walker_spawn_position=(0.5, 0, 0),
                                         target_velocity=3.0,
                                         physics_timestep=0.005,
                                         control_timestep=0.03)

    return composer.Environment(time_limit=30,
                                task=task,
                                random_state=random_state,
                                strip_singleton_obs_buffer_dim=True)
Exemple #14
0
 def testUniform(self):
     lower, upper = [2, 3, 4], [5, 6, 7]
     variation = distributions.Uniform(low=lower, high=upper)
     for _ in range(NUM_ITERATIONS):
         np.testing.assert_array_equal(
             variation(random_state=self._variation_random_state),
             self._np_random_state.uniform(lower, upper))
    def __init__(self, arena, arm, hand, num_bricks, randomize_initial_order,
                 randomize_desired_order, obs_settings, workspace,
                 control_timestep):
        """Initializes a new `Reassemble` task.

    Args:
      arena: `composer.Entity` instance.
      arm: `robot_base.RobotArm` instance.
      hand: `robot_base.RobotHand` instance.
      num_bricks: The total number of bricks; must be between 2 and 6.
      randomize_initial_order: Boolean specifying whether to randomize the
        initial order  of bricks in the stack at the start of each episode.
      randomize_desired_order: Boolean specifying whether to independently
        randomize the desired order of bricks in the stack at the start of each
        episode. By default the desired order will be the reverse of the initial
        order, with the exception of the base brick which is always the same as
        in the initial order since it is welded in place.
      obs_settings: `observations.ObservationSettings` instance.
      workspace: A `_BrickWorkspace` instance.
      control_timestep: Float specifying the control timestep in seconds.

    Raises:
      ValueError: If `num_bricks` is not between 2 and 6.
    """
        super(Reassemble, self).__init__(arena=arena,
                                         arm=arm,
                                         hand=hand,
                                         num_bricks=num_bricks,
                                         obs_settings=obs_settings,
                                         workspace=workspace,
                                         control_timestep=control_timestep)
        self._randomize_initial_order = randomize_initial_order
        self._randomize_desired_order = randomize_desired_order

        # Randomized at the start of each episode if `randomize_initial_order` is
        # True.
        self._initial_order = np.arange(num_bricks)

        # Randomized at the start of each episode if `randomize_desired_order` is
        # True.
        self._desired_order = self._initial_order.copy()
        self._desired_order[1:] = self._desired_order[-1:0:-1]

        # In the random order case, create a `prop_pose` observable that informs the
        # agent of the desired order.
        if randomize_desired_order:
            desired_order_observable = observable.Generic(
                self._get_desired_order)
            desired_order_observable.configure(
                **obs_settings.prop_pose._asdict())
            self._task_observables['desired_order'] = desired_order_observable

        # Distributions of positions and orientations for the base of the stack.
        self._base_pos = distributions.Uniform(*workspace.prop_bbox)
        self._base_quat = workspaces.uniform_z_rotation
    def __init__(self, observation_settings, opponent, game_logic, board,
                 markers):
        """Initializes the task.

    Args:
      observation_settings: An `observations.ObservationSettings` namedtuple
        specifying configuration options for each category of observation.
      opponent: Opponent used for generating opponent moves.
      game_logic: Logic for keeping track of the logical state of the board.
      board: Board to use.
      markers: Markers to use.
    """
        self._game_logic = game_logic
        self._game_opponent = opponent
        arena = arenas.Standard(observable_options=observations.make_options(
            observation_settings, observations.ARENA_OBSERVABLES))
        arena.attach(board)
        arm = kinova.JacoArm(observable_options=observations.make_options(
            observation_settings, observations.JACO_ARM_OBSERVABLES))
        hand = kinova.JacoHand(observable_options=observations.make_options(
            observation_settings, observations.JACO_HAND_OBSERVABLES))
        arm.attach(hand)
        arena.attach_offset(arm, offset=(0, _ARM_Y_OFFSET, 0))
        arena.attach(markers)

        # Geoms belonging to the arm and hand are placed in a custom group in order
        # to disable their visibility to the top-down camera. NB: we assume that
        # there are no other geoms in ROBOT_GEOM_GROUP that don't belong to the
        # robot (this is usually the case since the default geom group is 0). If
        # there are then these will also be invisible to the top-down camera.
        for robot_geom in arm.mjcf_model.find_all('geom'):
            robot_geom.group = arenas.ROBOT_GEOM_GROUP

        self._arena = arena
        self._board = board
        self._arm = arm
        self._hand = hand
        self._markers = markers
        self._tcp_initializer = initializers.ToolCenterPointInitializer(
            hand=hand,
            arm=arm,
            position=distributions.Uniform(_TCP_LOWER_BOUNDS,
                                           _TCP_UPPER_BOUNDS),
            quaternion=_uniform_downward_rotation())

        # Add an observable exposing the logical state of the board.
        board_state_observable = observable.Generic(
            lambda physics: self._game_logic.get_board_state())
        board_state_observable.configure(
            **observation_settings.board_state._asdict())
        self._task_observables = {'board_state': board_state_observable}
Exemple #17
0
def _build_humanoid_corridor_gaps():
    """Build humanoid walker walls environment."""
    walker = walkers.CMUHumanoidPositionControlled(
        name='walker',
        observable_options={'egocentric_camera': dict(enabled=True)},
    )
    platform_length = distributions.Uniform(low=0.3, high=2.5)
    gap_length = distributions.Uniform(low=0.75, high=1.25)
    arena = arenas.GapsCorridor(corridor_width=10,
                                platform_length=platform_length,
                                gap_length=gap_length,
                                corridor_length=100)
    humanoid_task = tasks.RunThroughCorridor(
        walker=walker,
        arena=arena,
        walker_spawn_position=(2, 0, 0),
        walker_spawn_rotation=1.57,  # pi / 2
        physics_timestep=0.005,
        control_timestep=0.03)
    raw_env = composer.Environment(time_limit=30,
                                   task=humanoid_task,
                                   strip_singleton_obs_buffer_dim=True)

    return raw_env
 def test_sample_non_colliding_positions(self):
     halfwidth = 0.05
     radius = halfwidth / 4.
     offset = np.array([0, 0, halfwidth + radius * 1.1])
     lower = -np.full(3, halfwidth) + offset
     upper = np.full(3, halfwidth) + offset
     position_variation = distributions.Uniform(lower, upper)
     physics, spheres = _make_spheres(num_spheres=8,
                                      radius=radius,
                                      nconmax=1000)
     prop_placer = prop_initializer.PropPlacer(props=spheres,
                                               position=position_variation,
                                               ignore_collisions=False,
                                               settle_physics=False)
     prop_placer(physics, random_state=np.random.RandomState(0))
     self.assertNoContactsInvolvingEntities(physics, spheres)
     self.assertPositionsWithinBounds(physics, spheres, lower, upper)
Exemple #19
0
    def __init__(self,
                 min_size,
                 max_size,
                 randomizer=None,
                 keep_aspect_ratio=False,
                 goal_size=None,
                 field_box=False,
                 field_box_offset=0.0,
                 top_camera_distance=_TOP_CAMERA_DISTANCE,
                 name='randomized_pitch'):
        """Construct a randomized pitch.

    Args:
      min_size: a tuple of minimum (length, width) of the pitch.
      max_size: a tuple of maximum (length, width) of the pitch.
      randomizer: a callable that returns ratio between [0., 1.] that scales
        between min_size, max_size.
      keep_aspect_ratio: if `True`, keep the aspect ratio constant during
        randomization.
      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.
      field_box: optional indicating if we should construct field box containing
        the ball (but not the walkers).
      field_box_offset: offset for the fieldbox if used.
      top_camera_distance: the distance of the top-down camera to the pitch.
      name: the name of this arena.
    """
        super(RandomizedPitch,
              self).__init__(size=max_size,
                             goal_size=goal_size,
                             top_camera_distance=top_camera_distance,
                             field_box=field_box,
                             field_box_offset=field_box_offset,
                             name=name)

        self._min_size = min_size
        self._max_size = max_size

        self._randomizer = randomizer or distributions.Uniform()
        self._keep_aspect_ratio = keep_aspect_ratio

        # Sample a new size and regenerate the soccer pitch.
        logging.info('%s between (%s, %s) with %s', self.__class__.__name__,
                     min_size, max_size, self._randomizer)
Exemple #20
0
def ant_run_walls(random_state=None):
    walker = ant.Ant()

    arena = corr_arenas.WallsCorridor(wall_gap=4.,
                                      wall_width=distributions.Uniform(1, 7),
                                      wall_height=3.0,
                                      corridor_width=10,
                                      corridor_length=100,
                                      include_initial_padding=False)

    task = corr_tasks.RunThroughCorridor(walker=walker,
                                         arena=arena,
                                         walker_spawn_position=(0.5, 0, 0),
                                         walker_spawn_rotation=0,
                                         physics_timestep=_PHYSICS_TIMESTEP,
                                         control_timestep=_CONTROL_TIMESTEP)

    return composer.Environment(time_limit=30,
                                task=task,
                                random_state=random_state,
                                strip_singleton_obs_buffer_dim=True)
Exemple #21
0
def jumping_ball_run_walls():
    walker = jumping_ball.JumpingBallWithHead()

    arena = corr_arenas.WallsCorridor(wall_gap=4.,
                                      wall_width=distributions.Uniform(1, 7),
                                      wall_height=3.0,
                                      corridor_width=10,
                                      corridor_length=250,
                                      include_initial_padding=False)

    task = corr_tasks.RunThroughCorridor(walker=walker,
                                         arena=arena,
                                         walker_spawn_position=(0.5, 0, 0),
                                         walker_spawn_rotation=0,
                                         contact_termination=False,
                                         physics_timestep=_PHYSICS_TIMESTEP,
                                         control_timestep=_CONTROL_TIMESTEP)

    return composer.Environment(time_limit=30,
                                task=task,
                                strip_singleton_obs_buffer_dim=True)
    def initialize_episode_mjcf(self, random_state):
        if self._randomize_order:
            self._desired_order = random_state.choice(len(self._bricks),
                                                      size=self._target_height,
                                                      replace=False)
            logging.info(
                'Desired stack order (from bottom to top): [%s]',
                ' '.join(_COLOR_NAMES[i] for i in self._desired_order))

        # If the base of the stack should be fixed, remove the freejoint for the
        # first brick (and ensure that all the others have freejoints).
        fixed_indices = [] if self._moveable_base else [self._desired_order[0]]
        _add_or_remove_freejoints(attachment_frames=self._brick_frames,
                                  fixed_indices=fixed_indices)

        # We need to define the prop initializer for the bricks here rather than in
        # the `__init__`, since `PropPlacer` looks for freejoints on instantiation.
        self._brick_placer = initializers.PropPlacer(
            props=self._bricks,
            position=distributions.Uniform(*self._prop_bbox),
            quaternion=workspaces.uniform_z_rotation,
            settle_physics=True)
Exemple #23
0
_MIN_SITE_DIMENSION = 1e-6  # Ensures that all site dimensions are positive.
_VISIBLE_GROUP = 0
_INVISIBLE_GROUP = 3  # Invisible sensor sites live in group 4 by convention.

DOWN_QUATERNION = base.DOWN_QUATERNION

BoundingBox = collections.namedtuple('BoundingBox', ['lower', 'upper'])

uniform_z_rotation = rotations.QuaternionFromAxisAngle(
    axis=(0., 0., 1.),
    # NB: We must specify `single_sample=True` here otherwise we will sample a
    #     length-4 array of angles rather than a scalar. This happens because
    #     `PropPlacer` passes in the previous quaternion as `initial_value`,
    #     and by default `distributions.Distribution` assumes that the shape
    #     of the output array should be the same as that of `initial_value`.
    angle=distributions.Uniform(-np.pi, np.pi, single_sample=True))


def add_bbox_site(body, lower, upper, visible=False, **kwargs):
    """Adds a site for visualizing a bounding box to an MJCF model.

  Args:
    body: An `mjcf.Element`, the (world)body to which the site should be added.
    lower: A sequence of lower x,y,z bounds.
    upper: A sequence of upper x,y,z bounds.
    visible: Whether the site should be visible by default.
    **kwargs: Keyword arguments used to set other attributes of the newly
      created site.

  Returns:
    An `mjcf.Element` representing the newly created site.
    def __init__(self, arena, arm, hand, num_bricks, obs_settings, workspace,
                 control_timestep):
        if not 2 <= num_bricks <= 6:
            raise ValueError(
                '`num_bricks` must be between 2 and 6, got {}.'.format(
                    num_bricks))

        if num_bricks > 3:
            # The default values computed by MuJoCo's compiler are too small if there
            # are more than three stacked bricks, since each stacked pair generates
            # a large number of contacts. The values below are sufficient for up to
            # 6 stacked bricks.
            # TODO(b/78331644): It may be useful to log the size of `physics.model`
            #                   and `physics.data` after compilation to gauge the
            #                   impact of these changes on MuJoCo's memory footprint.
            arena.mjcf_model.size.nconmax = 400
            arena.mjcf_model.size.njmax = 1200

        self._arena = arena
        self._arm = arm
        self._hand = hand
        self._arm.attach(self._hand)
        self._arena.attach_offset(self._arm, offset=workspace.arm_offset)
        self.control_timestep = control_timestep

        # Add custom camera observable.
        self._task_observables = cameras.add_camera_observables(
            arena, obs_settings, cameras.FRONT_CLOSE)

        color_sequence = iter(_COLOR_VALUES)
        brick_obs_options = observations.make_options(
            obs_settings, observations.FREEPROP_OBSERVABLES)

        bricks = []
        brick_frames = []
        goal_hint_bricks = []
        for _ in range(num_bricks):
            color = next(color_sequence)
            brick = props.Duplo(color=color,
                                observable_options=brick_obs_options)
            brick_frames.append(arena.add_free_entity(brick))
            bricks.append(brick)

            # Translucent, contactless brick with no observables. These are used to
            # provide a visual hint representing the goal state for each task.
            hint_brick = props.Duplo(color=color)
            _hintify(hint_brick, alpha=_HINT_ALPHA)
            arena.attach(hint_brick)
            goal_hint_bricks.append(hint_brick)

        self._bricks = bricks
        self._brick_frames = brick_frames
        self._goal_hint_bricks = goal_hint_bricks

        # Position and quaternion for the goal hint.
        self._goal_hint_pos = workspace.goal_hint_pos
        self._goal_hint_quat = workspace.goal_hint_quat

        self._tcp_initializer = initializers.ToolCenterPointInitializer(
            self._hand,
            self._arm,
            position=distributions.Uniform(*workspace.tcp_bbox),
            quaternion=workspaces.DOWN_QUATERNION)

        # Add sites for visual debugging.
        workspaces.add_bbox_site(body=self.root_entity.mjcf_model.worldbody,
                                 lower=workspace.tcp_bbox.lower,
                                 upper=workspace.tcp_bbox.upper,
                                 rgba=constants.GREEN,
                                 name='tcp_spawn_area')

        workspaces.add_bbox_site(body=self.root_entity.mjcf_model.worldbody,
                                 lower=workspace.prop_bbox.lower,
                                 upper=workspace.prop_bbox.upper,
                                 rgba=constants.BLUE,
                                 name='prop_spawn_area')
Exemple #25
0
    def __init__(self, arena, arm, hand, prop, obs_settings, workspace,
                 control_timestep, table_col_tag):
        """Initializes a new `Reach` task.

    Args:
      arena: `composer.Entity` instance.
      arm: `robot_base.RobotArm` instance.
      hand: `robot_base.RobotHand` instance.
      prop: `composer.Entity` instance specifying the prop to reach to, or None
        in which case the target is a fixed site whose position is specified by
        the workspace.
      obs_settings: `observations.ObservationSettings` instance.
      workspace: `_ReachWorkspace` specifying the placement of the prop and TCP.
      control_timestep: Float specifying the control timestep in seconds.
    """
        self._arena = arena
        self._arm = arm
        self._hand = hand
        self._arm.attach(self._hand)
        self._arena.attach_offset(self._arm, offset=workspace.arm_offset)
        self.control_timestep = control_timestep
        self._tcp_initializer = initializers.ToolCenterPointInitializer(
            self._hand,
            self._arm,
            position=distributions.Uniform(*workspace.tcp_bbox),
            quaternion=workspaces.DOWN_QUATERNION)

        # Add custom camera observable.
        self._task_observables = cameras.add_camera_observables(
            arena, obs_settings, cameras.FRONT_FAR)

        target_pos_distribution = distributions.Uniform(*workspace.target_bbox)
        self._prop = prop
        if prop:
            # The prop itself is used to visualize the target location.
            self._make_target_site(parent_entity=prop, visible=False)
            self._target = self._arena.add_free_entity(prop)
            self._prop_placer = initializers.PropPlacer(
                props=[prop],
                position=target_pos_distribution,
                quaternion=workspaces.uniform_z_rotation,
                settle_physics=True)
        else:
            self._target = self._make_target_site(parent_entity=arena,
                                                  visible=True)
            self._target_placer = target_pos_distribution

            obs = observable.MJCFFeature('pos', self._target)
            obs.configure(**obs_settings.prop_pose._asdict())
            self._task_observables['target_position'] = obs

        # Randomize the table surface
        if table_col_tag == 0:
            self.root_entity.mjcf_model.worldbody.add('geom',
                                                      type='plane',
                                                      pos="0 0 0.01",
                                                      size="0.6 0.6 0.5",
                                                      rgba=".6 .6 .5 1",
                                                      contype="1",
                                                      conaffinity="1",
                                                      friction="2 0.1 0.002",
                                                      material="j2s7/robot_bw")
        elif table_col_tag == 1:
            self.root_entity.mjcf_model.worldbody.add('geom',
                                                      type='plane',
                                                      pos="0 0 0.01",
                                                      size="0.6 0.6 0.5",
                                                      rgba=".6 .6 .5 1",
                                                      contype="1",
                                                      conaffinity="1",
                                                      friction="2 0.1 0.002",
                                                      material="j2s7/robot_bw")

        elif table_col_tag == 2:
            self.root_entity.mjcf_model.worldbody.add(
                'geom',
                type='plane',
                pos="0 0 0.01",
                size="0.6 0.6 0.5",
                rgba=".6 .6 .5 1",
                contype="1",
                conaffinity="1",
                friction="2 0.1 0.002",
                material="j2s7/real_desk")

        # Blue stary sky
        self.root_entity.mjcf_model.asset.texture[0].mark = 'random'
        self.root_entity.mjcf_model.asset.texture[0].rgb1 = np.array(
            [.4, .6, .8])
        self.root_entity.mjcf_model.asset.texture[0].width = 800
        self.root_entity.mjcf_model.asset.texture[0].height = 800

        # How to remove the checkerboard groundplane ?
        # For now this somehow sets it to a white plane!
        self.root_entity.mjcf_model.asset.texture[1].width = 1
        self.root_entity.mjcf_model.asset.texture[1].height = 1
        # Add sites for visualizing the prop and target bounding boxes.
        workspaces.add_bbox_site(body=self.root_entity.mjcf_model.worldbody,
                                 lower=workspace.tcp_bbox.lower,
                                 upper=workspace.tcp_bbox.upper,
                                 rgba=constants.GREEN,
                                 name='tcp_spawn_area')
        workspaces.add_bbox_site(body=self.root_entity.mjcf_model.worldbody,
                                 lower=workspace.target_bbox.lower,
                                 upper=workspace.target_bbox.upper,
                                 rgba=constants.BLUE,
                                 name='target_spawn_area')
Exemple #26
0
    def __init__(self, arena, arm, hand, prop, obs_settings, workspace,
                 control_timestep, table_col_tag, sky_col_tag):
        """Initializes a new `Reach` task.

    Args:
      arena: `composer.Entity` instance.
      arm: `robot_base.RobotArm` instance.
      hand: `robot_base.RobotHand` instance.
      prop: `composer.Entity` instance specifying the prop to reach to, or None
        in which case the target is a fixed site whose position is specified by
        the workspace.
      obs_settings: `observations.ObservationSettings` instance.
      workspace: `_ReachWorkspace` specifying the placement of the prop and TCP.
      control_timestep: Float specifying the control timestep in seconds.
    """
        self._arena = arena
        self._arm = arm
        self._hand = hand
        self._arm.attach(self._hand)
        self._arena.attach_offset(self._arm, offset=workspace.arm_offset)
        self.control_timestep = control_timestep
        self._tcp_initializer = initializers.ToolCenterPointInitializer(
            self._hand,
            self._arm,
            position=distributions.Uniform(*workspace.tcp_bbox),
            quaternion=workspaces.DOWN_QUATERNION)

        # Add custom camera observable.
        # Randomize camera viewing angle during training
        # Experimental
        randomize_cam = False

        if randomize_cam:
            camera_angle = random.choice([0, 1, 2, 3])
            if camera_angle == 0:
                self._task_observables = cameras.add_camera_observables(
                    arena, obs_settings, cameras.FRONT_FAR)
            elif camera_angle == 1:
                self._task_observables = cameras.add_camera_observables(
                    arena, obs_settings, cameras.FRONT_CLOSE)
            elif camera_angle == 2:
                self._task_observables = cameras.add_camera_observables(
                    arena, obs_settings, cameras.FRONT_CLOSE_TILT_UP)
            elif camera_angle == 3:
                self._task_observables = cameras.add_camera_observables(
                    arena, obs_settings, cameras.FRONT_CLOSE_TILT_DOWN)
        else:
            self._task_observables = cameras.add_camera_observables(
                arena, obs_settings, cameras.FRONT_FAR)

        target_pos_distribution = distributions.Uniform(*workspace.target_bbox)
        self._prop = prop
        if prop:
            # The prop itself is used to visualize the target location.
            self._make_target_site(parent_entity=prop, visible=False)
            self._target = self._arena.add_free_entity(prop)
            self._prop_placer = initializers.PropPlacer(
                props=[prop],
                position=target_pos_distribution,
                quaternion=workspaces.uniform_z_rotation,
                settle_physics=True)
        else:
            self._target = self._make_target_site(parent_entity=arena,
                                                  visible=True)
            self._target_placer = target_pos_distribution

            obs = observable.MJCFFeature('pos', self._target)
            obs.configure(**obs_settings.prop_pose._asdict())
            self._task_observables['target_position'] = obs

        # Randomize the table surface
        if table_col_tag == 0:
            self.root_entity.mjcf_model.worldbody.add('geom',
                                                      type='plane',
                                                      pos="0 0 0.01",
                                                      size="0.6 0.6 0.5",
                                                      rgba=".6 .6 .5 1",
                                                      contype="1",
                                                      conaffinity="1",
                                                      friction="2 0.1 0.002",
                                                      material="j2s7/darkwood")
        elif table_col_tag == 1:
            self.root_entity.mjcf_model.worldbody.add('geom',
                                                      type='plane',
                                                      pos="0 0 0.01",
                                                      size="0.6 0.6 0.5",
                                                      rgba=".6 .6 .5 1",
                                                      contype="1",
                                                      conaffinity="1",
                                                      friction="2 0.1 0.002",
                                                      material="j2s7/marble")
        elif table_col_tag == 2:
            self.root_entity.mjcf_model.worldbody.add(
                'geom',
                type='plane',
                pos="0 0 0.01",
                size="0.6 0.6 0.5",
                rgba=".6 .6 .5 1",
                contype="1",
                conaffinity="1",
                friction="2 0.1 0.002",
                material="j2s7/navy_blue")
        elif table_col_tag == 3:
            self.root_entity.mjcf_model.worldbody.add('geom',
                                                      type='plane',
                                                      pos="0 0 0.01",
                                                      size="0.6 0.6 0.5",
                                                      rgba=".6 .6 .5 1",
                                                      contype="1",
                                                      conaffinity="1",
                                                      friction="2 0.1 0.002",
                                                      material="j2s7/tennis")
        elif table_col_tag == 4:
            self.root_entity.mjcf_model.worldbody.add('geom',
                                                      type='plane',
                                                      pos="0 0 0.01",
                                                      size="0.6 0.6 0.5",
                                                      rgba=".6 .6 .5 1",
                                                      contype="1",
                                                      conaffinity="1",
                                                      friction="2 0.1 0.002",
                                                      material="j2s7/wood")
        elif table_col_tag == 5:
            self.root_entity.mjcf_model.worldbody.add(
                'geom',
                type='plane',
                pos="0 0 0.01",
                size="0.6 0.6 0.5",
                rgba=".6 .6 .5 1",
                contype="1",
                conaffinity="1",
                friction="2 0.1 0.002",
                material="j2s7/wood_light")

        elif table_col_tag == 6:
            self.root_entity.mjcf_model.worldbody.add(
                'geom',
                type='plane',
                pos="0 0 0.01",
                size="0.6 0.6 0.5",
                rgba=".6 .6 .5 1",
                contype="1",
                conaffinity="1",
                friction="2 0.1 0.002",
                material="j2s7/light_wood_v2")

        elif table_col_tag == 7:
            self.root_entity.mjcf_model.worldbody.add('geom',
                                                      type='plane',
                                                      pos="0 0 0.01",
                                                      size="0.6 0.6 0.5",
                                                      rgba=".6 .6 .5 1",
                                                      contype="1",
                                                      conaffinity="1",
                                                      friction="2 0.1 0.002",
                                                      material="j2s7/metal")

        elif table_col_tag == 8:
            self.root_entity.mjcf_model.worldbody.add('geom',
                                                      type='plane',
                                                      pos="0 0 0.01",
                                                      size="0.6 0.6 0.5",
                                                      rgba=".6 .6 .5 1",
                                                      contype="1",
                                                      conaffinity="1",
                                                      friction="2 0.1 0.002",
                                                      material="j2s7/grass")

        elif table_col_tag == 9:
            self.root_entity.mjcf_model.worldbody.add(
                'geom',
                type='plane',
                pos="0 0 0.01",
                size="0.6 0.6 0.5",
                rgba=".6 .6 .5 1",
                contype="1",
                conaffinity="1",
                friction="2 0.1 0.002",
                material="j2s7/blue_cloud")

        elif table_col_tag == 10:
            self.root_entity.mjcf_model.worldbody.add(
                'geom',
                type='plane',
                pos="0 0 0.01",
                size="0.6 0.6 0.5",
                rgba=".6 .6 .5 1",
                contype="1",
                conaffinity="1",
                friction="2 0.1 0.002",
                material="j2s7/marble_v2")

        elif table_col_tag == 11:
            self.root_entity.mjcf_model.worldbody.add(
                'geom',
                type='plane',
                pos="0 0 0.01",
                size="0.6 0.6 0.5",
                rgba=".6 .6 .5 1",
                contype="1",
                conaffinity="1",
                friction="2 0.1 0.002",
                material="j2s7/wood_gray")
        # Sky change of colour
        if sky_col_tag == 1:
            # Red stary sky
            self.root_entity.mjcf_model.asset.texture[0].mark = 'random'
            self.root_entity.mjcf_model.asset.texture[0].rgb1 = np.array(
                [.8, .1, .4])
            self.root_entity.mjcf_model.asset.texture[0].width = 800
            self.root_entity.mjcf_model.asset.texture[0].height = 800

        elif sky_col_tag == 2:
            # Orange stary sky
            self.root_entity.mjcf_model.asset.texture[0].mark = 'random'
            self.root_entity.mjcf_model.asset.texture[0].rgb1 = np.array(
                [.8, .5, .1])
            self.root_entity.mjcf_model.asset.texture[0].width = 800
            self.root_entity.mjcf_model.asset.texture[0].height = 800

        elif sky_col_tag == 3:
            # Yellow stary sky
            self.root_entity.mjcf_model.asset.texture[0].mark = 'random'
            self.root_entity.mjcf_model.asset.texture[0].rgb1 = np.array(
                [1, 1, .4])
            self.root_entity.mjcf_model.asset.texture[0].width = 800
            self.root_entity.mjcf_model.asset.texture[0].height = 800

        elif sky_col_tag == 4:
            # Pink stary sky
            self.root_entity.mjcf_model.asset.texture[0].mark = 'random'
            self.root_entity.mjcf_model.asset.texture[0].rgb1 = np.array(
                [1, .5, 1])
            self.root_entity.mjcf_model.asset.texture[0].width = 800
            self.root_entity.mjcf_model.asset.texture[0].height = 800

        elif sky_col_tag == 5:
            # Amber stary sky
            self.root_entity.mjcf_model.asset.texture[0].mark = 'random'
            self.root_entity.mjcf_model.asset.texture[0].rgb1 = np.array(
                [1, .6, .4])
            self.root_entity.mjcf_model.asset.texture[0].width = 800
            self.root_entity.mjcf_model.asset.texture[0].height = 800

        elif sky_col_tag == 6:
            # White stary sky
            self.root_entity.mjcf_model.asset.texture[0].rgb1 = np.array(
                [1., 1., 1.])
            self.root_entity.mjcf_model.asset.texture[0].rgb2 = np.array(
                [1., 1., 1.])
            self.root_entity.mjcf_model.asset.texture[0].width = 800
            self.root_entity.mjcf_model.asset.texture[0].height = 800

        elif sky_col_tag == 7:
            # Black stary sky
            self.root_entity.mjcf_model.asset.texture[0].rgb1 = np.array(
                [0, 0, 0])
            self.root_entity.mjcf_model.asset.texture[0].width = 800
            self.root_entity.mjcf_model.asset.texture[0].height = 800

        elif sky_col_tag == 8:
            # Leave the checkerboard
            self.root_entity.mjcf_model.asset.texture[1].width = 1
            self.root_entity.mjcf_model.asset.texture[1].height = 1

        # TODO: Remove the checkerboard groundplane
        # For now this somehow sets it to a white plane!
        self.root_entity.mjcf_model.asset.texture[1].width = 1
        self.root_entity.mjcf_model.asset.texture[1].height = 1
        # Add sites for visualizing the prop and target bounding boxes.
        workspaces.add_bbox_site(body=self.root_entity.mjcf_model.worldbody,
                                 lower=workspace.tcp_bbox.lower,
                                 upper=workspace.tcp_bbox.upper,
                                 rgba=constants.GREEN,
                                 name='tcp_spawn_area')
        workspaces.add_bbox_site(body=self.root_entity.mjcf_model.worldbody,
                                 lower=workspace.target_bbox.lower,
                                 upper=workspace.target_bbox.upper,
                                 rgba=constants.BLUE,
                                 name='target_spawn_area')
def _uniform_downward_rotation():
    angle = distributions.Uniform(-np.pi, np.pi, single_sample=True)
    quaternion = rotations.QuaternionFromAxisAngle(axis=(0., 0., 1.),
                                                   angle=angle)
    return functools.partial(rotations.QuaternionPreMultiply(quaternion),
                             initial_value=base.DOWN_QUATERNION)
Exemple #28
0
    def __init__(self, arena, arm, hand, prop, obs_settings, workspace,
                 control_timestep, cradle):
        """Initializes a new `Place` task.

    Args:
      arena: `composer.Entity` instance.
      arm: `robot_base.RobotArm` instance.
      hand: `robot_base.RobotHand` instance.
      prop: `composer.Entity` instance.
      obs_settings: `observations.ObservationSettings` instance.
      workspace: A `_PlaceWorkspace` instance.
      control_timestep: Float specifying the control timestep in seconds.
      cradle: `composer.Entity` onto which the `prop` must be placed.
    """
        self._arena = arena
        self._arm = arm
        self._hand = hand
        self._arm.attach(self._hand)
        self._arena.attach_offset(self._arm, offset=workspace.arm_offset)
        self.control_timestep = control_timestep

        # Add custom camera observable.
        self._task_observables = cameras.add_camera_observables(
            arena, obs_settings, cameras.FRONT_CLOSE)

        self._tcp_initializer = initializers.ToolCenterPointInitializer(
            self._hand,
            self._arm,
            position=distributions.Uniform(*workspace.tcp_bbox),
            quaternion=workspaces.DOWN_QUATERNION)

        self._prop = prop
        self._prop_frame = self._arena.add_free_entity(prop)
        self._pedestal = Pedestal(cradle=cradle, target_radius=_TARGET_RADIUS)
        self._arena.attach(self._pedestal)

        for obs in six.itervalues(self._pedestal.observables.as_dict()):
            obs.configure(**obs_settings.prop_pose._asdict())

        self._prop_placer = initializers.PropPlacer(
            props=[prop],
            position=distributions.Uniform(*workspace.prop_bbox),
            quaternion=workspaces.uniform_z_rotation,
            settle_physics=True,
            max_attempts_per_prop=50)

        self._pedestal_placer = initializers.PropPlacer(
            props=[self._pedestal],
            position=distributions.Uniform(*workspace.target_bbox),
            settle_physics=False)

        # Add sites for visual debugging.
        workspaces.add_bbox_site(body=self.root_entity.mjcf_model.worldbody,
                                 lower=workspace.tcp_bbox.lower,
                                 upper=workspace.tcp_bbox.upper,
                                 rgba=constants.GREEN,
                                 name='tcp_spawn_area')
        workspaces.add_bbox_site(body=self.root_entity.mjcf_model.worldbody,
                                 lower=workspace.prop_bbox.lower,
                                 upper=workspace.prop_bbox.upper,
                                 rgba=constants.BLUE,
                                 name='prop_spawn_area')
        workspaces.add_bbox_site(body=self.root_entity.mjcf_model.worldbody,
                                 lower=workspace.target_bbox.lower,
                                 upper=workspace.target_bbox.upper,
                                 rgba=constants.CYAN,
                                 name='pedestal_spawn_area')
  def __init__(self,
               walker,
               arena,
               moving_target=False,
               target_relative=False,
               target_relative_dist=1.5,
               steps_before_moving_target=10,
               distance_tolerance=DEFAULT_DISTANCE_TOLERANCE_TO_TARGET,
               target_spawn_position=None,
               walker_spawn_position=None,
               walker_spawn_rotation=None,
               physics_timestep=0.005,
               control_timestep=0.025):
    """Initializes this task.

    Args:
      walker: an instance of `locomotion.walkers.base.Walker`.
      arena: an instance of `locomotion.arenas.floors.Floor`.
      moving_target: bool, Whether the target should move after receiving the
        walker reaches it.
      target_relative: bool, Whether the target be set relative to its current
        position.
      target_relative_dist: float, new target distance range if
        using target_relative.
      steps_before_moving_target: int, the number of steps before the target
        moves, if moving_target==True.
      distance_tolerance: Accepted to distance to the target position before
        providing reward.
      target_spawn_position: a sequence of 2 numbers, or a `composer.Variation`
        instance that generates such sequences, specifying the position at
        which the target is spawned at the beginning of an episode.
        If None, the entire arena is used to generate random target positions.
      walker_spawn_position: a sequence of 2 numbers, or a `composer.Variation`
        instance that generates such sequences, specifying the position at
        which the walker is spawned at the beginning of an episode.
        If None, the entire arena is used to generate random spawn positions.
      walker_spawn_rotation: a number, or a `composer.Variation` instance that
        generates a number, specifying the yaw angle offset (in radians) that is
        applied to the walker at the beginning of an episode.
      physics_timestep: a number specifying the timestep (in seconds) of the
        physics simulation.
      control_timestep: a number specifying the timestep (in seconds) at which
        the agent applies its control inputs (in seconds).
    """

    self._arena = arena
    self._walker = walker
    self._walker.create_root_joints(self._arena.attach(self._walker))

    arena_position = distributions.Uniform(
        low=-np.array(arena.size) / 2, high=np.array(arena.size) / 2)
    if target_spawn_position is not None:
      self._target_spawn_position = target_spawn_position
    else:
      self._target_spawn_position = arena_position

    if walker_spawn_position is not None:
      self._walker_spawn_position = walker_spawn_position
    else:
      self._walker_spawn_position = arena_position

    self._walker_spawn_rotation = walker_spawn_rotation

    self._distance_tolerance = distance_tolerance
    self._moving_target = moving_target
    self._target_relative = target_relative
    self._target_relative_dist = target_relative_dist
    self._steps_before_moving_target = steps_before_moving_target
    self._reward_step_counter = 0

    self._target = self.root_entity.mjcf_model.worldbody.add(
        'site',
        name='target',
        type='sphere',
        pos=(0., 0., 0.),
        size=(0.1,),
        rgba=(0.9, 0.6, 0.6, 1.0))

    enabled_observables = []
    enabled_observables += self._walker.observables.proprioception
    enabled_observables += self._walker.observables.kinematic_sensors
    enabled_observables += self._walker.observables.dynamic_sensors
    enabled_observables.append(self._walker.observables.sensors_touch)
    for obs in enabled_observables:
      obs.enabled = True

    walker.observables.add_egocentric_vector(
        'target',
        observable.MJCFFeature('pos', self._target),
        origin_callable=lambda physics: physics.bind(walker.root_body).xpos)

    self.set_timesteps(
        physics_timestep=physics_timestep, control_timestep=control_timestep)