def __init__(self,
                 anchor=None,
                 invisible_elements=None,
                 normalize=True,
                 noise_params=None,
                 **sensor_params):
        """
        Refer to Sensor Class.

        Args:
            invisible_elements: elements that the sensor does not perceive.
                List of Parts of SceneElements.
            normalize: if true, Sensor values are normalized between 0 and 1.
                Default: True
            only_front: Only return the half part of the Playground that the Sensor faces.
                Remove what is behind the sensor. Default: False.
        """

        default_config = parse_configuration('agent_sensors', self.sensor_type)
        sensor_params = {**default_config, **sensor_params}

        super().__init__(anchor=None,
                         invisible_elements=invisible_elements,
                         normalize=normalize,
                         noise_params=noise_params,
                         **sensor_params)

        if invisible_elements:
            self._invisible_elements = invisible_elements
        else:
            self._invisible_elements = []

        self._scale = None

        self._sensor_max_value = 255
Ejemplo n.º 2
0
    def __init__(self, **kwargs):

        default_config = parse_configuration('element_interactive', self.entity_type)
        entity_params = {**default_config, **kwargs}

        SceneElement.__init__(self, **entity_params)
        self.pm_visible_shape.collision_type = CollisionTypes.GEM
Ejemplo n.º 3
0
    def __init__(self, **kwargs):
        """
        Edible entity provides a reward to the agent that eats it, then shrinks in size, mass, and available reward.

        Args:
            **kwargs: other params to configure SceneElement. Refer to Entity class.

        Keyword Args:
            shrink_ratio_when_eaten: When eaten by an agent, the mass, size, and reward are multiplied by this ratio.
                Default: 0.9
            initial_reward: Initial reward of the edible.
            min_reward: When reward is lower than min_reward, the edible entity disappears.

        """

        default_config = parse_configuration('element_interactive',
                                             self.entity_type)
        entity_params = {**default_config, **kwargs}

        super().__init__(**entity_params)

        self.shrink_ratio_when_eaten = entity_params['shrink_ratio_when_eaten']
        self.min_reward = entity_params['min_reward']
        self.initial_reward = entity_params['initial_reward']

        self.initial_width, self.initial_length = self.width, self.length
        self.initial_radius = self.radius
        self.initial_mass = self.mass

        self.reward = self.initial_reward

        self.pm_interaction_shape.collision_type = CollisionTypes.EDIBLE
Ejemplo n.º 4
0
    def __init__(self, **kwargs):

        default_config = parse_configuration('element_basic', self.entity_type)
        entity_params = {**default_config, **kwargs}

        super().__init__(**entity_params)

        self.opened = False
Ejemplo n.º 5
0
    def __init__(self,
                 size=(400, 200),
                 room_layout=(3, 2),
                 wall_type='classic',
                 **kwargs):

        self.width, self.length = size

        default_config = parse_configuration('playground',
                                             'connected-rooms-2d')
        playground_params = {**default_config, **kwargs}

        # Wall parameters
        self._wall_texture = kwargs.get(
            'wall_texture', parse_configuration('playground', wall_type))
        self._wall_params = {
            **parse_configuration('playground', 'wall'),
            **kwargs.get('wall_params', {}), 'texture': self._wall_texture
        }
        self._wall_depth = self._wall_params['depth']

        # Door parameters
        self._doorstep_type = playground_params['doorstep_type']
        self._doorstep_size = playground_params['doorstep_size']
        self._size_door = [self._wall_depth, self._doorstep_size]

        # Environment Layout
        self.room_layout = room_layout
        self._width_room = float(self.width) / self.room_layout[0]
        self._length_room = float(self.length) / self.room_layout[1]

        self.area_rooms = self._compute_area_rooms()
        self.doorsteps = self._compute_doorsteps()

        super().__init__(size=size)

        self._add_external_walls()
        self._add_room_walls()

        # By default, an agent starts in a random position of the first room
        center, shape = self.area_rooms[(0, 0)]
        shape = shape[0] - self._wall_depth, shape[1] - self._wall_depth
        self.initial_agent_coordinates = CoordinateSampler(
            center=center, area_shape='rectangle', width_length=shape)
Ejemplo n.º 6
0
    def __init__(self,
                 anchor,
                 position_anchor=(0, 0),
                 position_part=(0, 0),
                 rotation_range=math.pi/4,
                 angle_offset=0,
                 can_absorb=False,
                 **kwargs,
                 ):
        """

        Args:
            anchor (:obj:`Part`):
                Body Part on which the Part is attached
            position_anchor:
            position_part:
            rotation_range:
            angle_offset:
            can_absorb:
            **kwargs:
        """

        default_config = parse_configuration('agent_parts', self.entity_type)
        body_part_params = {**default_config, **kwargs}

        Entity.__init__(self, visible=True, movable=True, **body_part_params)
        self.pm_visible_shape.collision_type = CollisionTypes.AGENT

        self.can_absorb = can_absorb

        # Interactive parts
        self.is_eating = False
        self.is_activating = False

        self.can_grasp = False
        self.is_grasping = False
        self.is_holding = False
        self.grasped = []

        # For parts attached
        self.anchor = anchor
        self.angle_offset = angle_offset
        self.rotation_range = rotation_range
        self.motor = None

        # If part is attached to another part:
        if self.anchor:

            self._rel_coord_anchor = pymunk.Vec2d(*position_anchor)
            self._rel_coord_part = pymunk.Vec2d(*position_part)

            self.set_relative_coordinates()
            self._attach_to_anchor()
Ejemplo n.º 7
0
    def __init__(self,
                 anchor,
                 position_anchor=(0, 0),
                 position_part=(0, 0),
                 rotation_range=math.pi/4,
                 angle_offset=0,
                 can_absorb=False,
                 **kwargs,
                 ):
        """
        Args:
            **kwargs: Optional Keyword Arguments



        Note:
            All physical properties of the Part can be set as keyword argument.
            Refer to the Entity class for the list of available keyword arguments.

        """

        default_config = parse_configuration('agent_parts', self.entity_type)
        body_part_params = {**default_config, **kwargs}

        Entity.__init__(self, visible=True, movable=True, **body_part_params)
        self.pm_visible_shape.collision_type = CollisionTypes.AGENT

        self.can_absorb = can_absorb

        # Interactive parts
        self.is_eating = False
        self.is_activating = False

        self.can_grasp = False
        self.is_grasping = False
        self.is_holding = False
        self.grasped = []

        # For parts attached
        self.anchor = anchor
        self.angle_offset = angle_offset
        self.rotation_range = rotation_range
        self.motor = None

        # If part is attached to another part:
        if self.anchor:

            self._rel_coord_anchor = pymunk.Vec2d(*position_anchor)
            self._rel_coord_part = pymunk.Vec2d(*position_part)

            self.set_relative_coordinates()
            self._attach_to_anchor()
Ejemplo n.º 8
0
    def __init__(self, anchor, position_anchor, angle_offset=0, **kwargs):

        default_config = parse_configuration('agent_parts', self.entity_type)
        body_part_params = {**default_config, **kwargs}

        # arm attached at one extremity, and other anchor point defined at other extremity
        width, length = body_part_params['width_length']
        position_part = [-length/2.0 + width/2.0, 0]
        self.extremity_anchor_point = [+length/2.0 - width/2.0, 0]

        super().__init__(anchor, position_anchor, position_part, angle_offset, **body_part_params)

        self.motor.max_force = ARM_MAX_FORCE
Ejemplo n.º 9
0
    def __init__(self, **kwargs):
        """ Vending machine Entity.
        Default: Orange square of size 20, provides a reward of 10.
        """

        default_config = parse_configuration('element_interactive',
                                             self.entity_type)
        entity_params = {**default_config, **kwargs}

        super().__init__(**entity_params)
        self.pm_interaction_shape.collision_type = CollisionTypes.ACTIVATED_BY_GEM

        self.reward = entity_params.get('reward')
Ejemplo n.º 10
0
    def __init__(self, **kwargs):

        default_config = parse_configuration('element_interactive',
                                             self.entity_type)
        entity_params = {**default_config, **kwargs}

        super().__init__(**entity_params)

        self.pm_interaction_shape.collision_type = CollisionTypes.INTERACTIVE

        self.reward = entity_params['reward']

        self.reward_provided = False
Ejemplo n.º 11
0
    def __init__(self, **kwargs):
        """
        Absorbable entities provide a reward to the agent upon contact,
        then disappears from the playground.

        Args:
            **kwargs: other params to configure SceneElement. Refer to Entity class.
        """

        default_config = parse_configuration('element_contact', self.entity_type)
        entity_params = {**default_config, **kwargs}

        super().__init__(**entity_params)
        self.reward = entity_params['reward']
    def __init__(self,
                 anchor,
                 invisible_elements=None,
                 remove_duplicates=False,
                 **sensor_params):
        """
        Args:
            anchor: Entity on which the Lidar is attached.
            invisible_elements: Elements which are invisible to the Sensor.
            remove_occluded: remove occluded detections along cone.
            allow_duplicates: remove duplicates across cones.
                Keep the closest detection for each detected Entity.
            **sensor_params: Additional Parameters.

        Keyword Args:
            n_cones: number of cones evenly spaced across the field of view.
            rays_per_cone: number of ray per cone.
            resolution: minimum size of detected objects.
            fov: field of view
            range: range of the rays.
        """
        default_config = parse_configuration('agent_sensors', self.sensor_type)
        sensor_params = {**default_config, **sensor_params}

        self.number_cones = sensor_params['n_cones']
        rays_per_cone = sensor_params['rays_per_cone']

        if not rays_per_cone > 0:
            raise ValueError('rays_per_cone should be at least 1')

        n_rays = rays_per_cone * self.number_cones

        sensor_params['resolution'] = n_rays
        sensor_params['n_rays'] = n_rays

        super().__init__(anchor,
                         invisible_elements=invisible_elements,
                         number_rays=n_rays,
                         remove_duplicates=remove_duplicates,
                         **sensor_params)

        if self.number_cones == 1:
            self.angles_cone_center = [0]
        else:
            angle = self._fov - self._fov / self.number_cones
            self.angles_cone_center = [
                n * angle / (self.number_cones - 1) - angle / 2
                for n in range(self.number_cones)
            ]
Ejemplo n.º 13
0
    def __init__(self, door, **kwargs):
        """
        Opens a door when in contact with an agent.
        Default: Pale brown square of size 10.

        Args:
            door: Door opened by the switch.
            **kwargs: other params to configure SceneElement. Refer to Entity class.
        """

        default_config = parse_configuration('element_interactive', self.entity_type)
        entity_params = {**default_config, **kwargs}

        super().__init__(**entity_params)

        self.door = door
Ejemplo n.º 14
0
    def __init__(self, **kwargs):
        """
        TerminationContact terminate the Episode upon contact with an Agent.
        Provides a reward to the agent.

        Args:
            **kwargs: other params to configure SceneElement. Refer to Entity class.

        Keyword Args:
            reward: Reward provided.
        """

        default_config = parse_configuration('element_contact', self.entity_type)
        entity_params = {**default_config, **kwargs}

        super().__init__(**entity_params)
        self.reward = entity_params['reward']
Ejemplo n.º 15
0
    def __init__(self,
                 entity_produced,
                 entity_produced_params=None,
                 production_area=None,
                 **kwargs):
        """
        Default: pink circle of radius 15.

        Args:
            entity_produced: Class of the entity produced by the dispenser.
            entity_produced_params: Dictionary of additional parameters for the entity_produced.
            production_area: PositionAreaSampler.
                If no production_area has been set, the entities will be produced around the dispenser.
            **kwargs: other params to configure entity. Refer to Entity class.

        Keyword Args:
            production_limit: maximum number of entities produced. Default: 15.
        """

        default_config = parse_configuration('element_interactive',
                                             self.entity_type)
        entity_params = {**default_config, **kwargs}

        super().__init__(**entity_params)

        self.pm_interaction_shape.collision_type = CollisionTypes.INTERACTIVE

        self.entity_produced = entity_produced

        if entity_produced_params is None:
            self.entity_produced_params = {}
        else:
            self.entity_produced_params = entity_produced_params

        if production_area is None:
            self.local_dispenser = True
            self.location_sampler = CoordinateSampler(area_shape='circle',
                                                      center=[0, 0],
                                                      radius=self.radius + 10)
        else:
            self.local_dispenser = False
            self.location_sampler = production_area

        self.production_limit = entity_params['production_limit']
        self.produced_entities = []
Ejemplo n.º 16
0
    def __init__(self, default_config_key=None, **kwargs):
        """ Base class for Basic entities.

        Basic entities are non-interactive entities.

        Args:
            initial_position: Initial position of the entity.
                Can be list [x,y,theta], AreaPositionSampler or Trajectory.
            default_config_key: default configurations.
                Can be circle, square, rectangle, pentagon, hexagon.
            **kwargs: other params to configure entity.
                Refer to Entity class for physical properties.

        """

        default_config = parse_configuration('element_basic', default_config_key)
        entity_params = {**default_config, **kwargs}

        super().__init__(**entity_params)
Ejemplo n.º 17
0
    def __init__(self, timers, textures, **kwargs):
        """

        ColorChanging changes color and is controlled at the level of the playground.
        The color changes depending on a list of timers.

        Args:
            timers: Single timer (int) or list of Timers.
            textures: Single texture or list of Textures.
            **kwargs: other params to configure entity. Refer to Entity class.
        """

        default_config = parse_configuration('element_basic', self.entity_type)
        entity_params = {**default_config, **kwargs}

        if isinstance(timers, int):
            self.timers = [timers]
        else:
            if not isinstance(timers, (list, tuple)):
                raise ValueError("timers should be int, list or tuple")
            self.timers = timers

        if isinstance(textures, (list, tuple)):
            self.list_texture_params = textures
        else:
            self.list_texture_params = [textures]

        assert len(self.list_texture_params) == len(self.timers)

        super().__init__(**entity_params)

        self.textures = []
        for texture in self.list_texture_params:
            texture_surface = self._create_texture(texture)
            self.textures.append(texture_surface)

        self.texture_surface = self.textures[0]
        self.force_redraw = False

        self.timer = 0
        self.current_index = 0
        self._reset_timer()
Ejemplo n.º 18
0
    def __init__(self, key, treasure, **kwargs):
        """ Chest Entity.
        Default: Purple rectangle of size 20x30

        Args:
            key: Key object.
            treasure: SceneElement that is delivered when chest is opened.
            **kwargs: other params to configure entity. Refer to Entity class
        """

        default_config = parse_configuration('element_interactive',
                                             self.entity_type)
        entity_params = {**default_config, **kwargs}

        super().__init__(**entity_params)
        self.pm_interaction_shape.collision_type = CollisionTypes.ACTIVATED_BY_GEM

        self.key = key
        self.treasure = treasure
        self.treasure.is_temporary_entity = True
Ejemplo n.º 19
0
    def __init__(self, door, key, **kwargs):
        """ Lock for a door, opens with a key.

        Default: pale green 10x10 square.

        Args:
            door: Door opened by the lock
            key: Key object associated with the lock
            **kwargs: other params to configure entity. Refer to Entity class
        """

        default_config = parse_configuration('element_interactive',
                                             self.entity_type)
        entity_params = {**default_config, **kwargs}

        super().__init__(**entity_params)
        self.pm_interaction_shape.collision_type = CollisionTypes.ACTIVATED_BY_GEM

        self.door = door
        self.key = key
Ejemplo n.º 20
0
    def __init__(self, **kwargs):
        """
        Base class for Invisible zones that terminate upon contact.

        TerminationZone entities generate a termination of the episode,
        and provide a reward to the agent in contact with the entity.

        Args:
            **kwargs: other params to configure entity. Refer to Entity class.

        Keyword Args:
            reward: Reward provided.
        """

        default_config = parse_configuration('element_zone', self.entity_type)
        entity_params = {**default_config, **kwargs}

        super().__init__(**entity_params)

        self.reward = entity_params.get('reward', 0)
        self.reward_provided = False
Ejemplo n.º 21
0
    def __init__(self, **kwargs):
        """
        VisibleRewardZone entities provide a reward to the agent
        in close proximity with the entity.

        Args:
            **kwargs: other params to configure entity. Refer to Entity class

        Keyword Args:
            reward: Reward provided at each timestep when agent is in proximity
            total_reward: Total reward that the entity can provide during an Episode
        """

        default_config = parse_configuration('element_proximity', self.entity_type)
        entity_params = {**default_config, **kwargs}

        super().__init__(**entity_params)

        self.reward = entity_params['reward']
        self.initial_total_reward = entity_params['total_reward']
        self.total_reward = self.initial_total_reward
Ejemplo n.º 22
0
    def __init__(self, remove_duplicates, **sensor_params):
        """
        Args:
            remove_duplicates: If True, removes detections of the same objects on multiple rays.
                Keeps the closest detection.
            **sensor_params: Additional sensor params.
        """

        default_config = parse_configuration('agent_sensors', self.sensor_type)
        sensor_params = {**default_config, **sensor_params}

        super().__init__(**sensor_params)

        self._remove_duplicates = remove_duplicates

        # Field of View of the Sensor
        if self._resolution == 1:
            self._ray_angles = [0]
        else:
            self._ray_angles = [n * self._fov / (self._resolution - 1) - self._fov / 2
                                for n in range(self._resolution)]
Ejemplo n.º 23
0
    def __init__(self, door, time_open, **kwargs):
        """ Switch used to open a door for a certain duration.

        Default: Pale brown square of size 10.

        Args:
            door: Door opened by the switch.
            time_open: Timesteps during which door will stay open.
            **kwargs: other params to configure entity. Refer to Entity class.
        """

        default_config = parse_configuration('element_interactive',
                                             self.entity_type)
        entity_params = {**default_config, **kwargs}

        super().__init__(**entity_params)

        self.door = door

        self.time_open = time_open
        self.timer = self.time_open
Ejemplo n.º 24
0
    def __init__(self, door, **kwargs):
        """ Switch used to open and close a door

        Default: Pale brown square of size 10.

        Args:
            door: Door opened by the switch.
            **kwargs: other params to configure entity. Refer to Entity class.

        Notes:
            It is possible to have multiple switches for a single door.
            However the behavior is unstable in multiagent setting.
        """

        default_config = parse_configuration('element_interactive',
                                             self.entity_type)
        entity_params = {**default_config, **kwargs}

        super().__init__(**entity_params)

        self.door = door
Ejemplo n.º 25
0
    def __init__(self, **kwargs):
        """
        RewardZone entities are invisible zones.
        Provide a reward to the agent which is inside the zone.

        Args:
            **kwargs: other params to configure entity. Refer to Entity class

        Keyword Args:
            reward: Reward provided at each timestep when agent is in the zone
            total_reward: Total reward that the entity can provide during an Episode
        """

        default_config = parse_configuration('element_zone', self.entity_type)
        entity_params = {**default_config, **kwargs}

        super().__init__(**entity_params)

        self.reward = entity_params['reward']

        self.initial_total_reward = entity_params['total_reward']
        self.total_reward = self.initial_total_reward
    def __init__(self,
                 anchor,
                 invisible_elements=None,
                 normalize=True,
                 noise_params=None,
                 only_front=False,
                 **sensor_params):
        """
        Refer to Sensor Class.

        Args:
            anchor: body Part to which the sensor is attached.
                Sensor is attached to the center of the Part.
            invisible_elements: elements that the sensor does not perceive.
                List of Parts of SceneElements.
            normalize: if true, Sensor values are normalized between 0 and 1.
                Default: True
            only_front: Only return the half part of the Playground that the Sensor faces.
                Remove what is behind the sensor. Default: False.
        """

        default_config = parse_configuration('agent_sensors', self.sensor_type)
        sensor_params = {**default_config, **sensor_params}

        super().__init__(anchor=anchor,
                         invisible_elements=invisible_elements,
                         normalize=normalize,
                         noise_params=noise_params,
                         **sensor_params)

        if invisible_elements:
            self._invisible_elements = invisible_elements
        else:
            self._invisible_elements = []

        self.only_front = only_front

        self._center = (int(self._resolution / 2) - 1,
                        int(self._resolution / 2) - 1)

        # Calculate range with circle

        mask_circle = np.zeros((self._resolution, self._resolution),
                               dtype=bool)
        rr, cc = draw.disk((self._center[0], self._center[1]),
                           (int(self._resolution / 2) - 1),
                           shape=mask_circle.shape)
        mask_circle[rr, cc] = 1

        # Calculate fov with poly

        points = [[(int(self._resolution / 2) - 1), 0], [0, 0],
                  [0, self._resolution],
                  [(int(self._resolution / 2) - 1), self._resolution]]

        if self._fov > math.pi:
            points = [[self._resolution, 0]
                      ] + points + [[self._resolution, self._resolution]]

        r1 = self._center[0] - (int(self._resolution / 2) -
                                1) * np.sin(math.pi / 2 + self._fov / 2)
        c1 = self._center[1] + (int(self._resolution / 2) -
                                1) * np.cos(math.pi / 2 + self._fov / 2)

        r2 = self._center[0] - (int(self._resolution / 2) -
                                1) * np.sin(math.pi / 2 - self._fov / 2)
        c2 = self._center[1] + (int(self._resolution / 2) -
                                1) * np.cos(math.pi / 2 - self._fov / 2)

        points = points + [[r2, c2], self._center, [r1, c1]]
        mask_poly = draw.polygon2mask((self._resolution, self._resolution),
                                      np.array(points))

        self.mask_total_fov = mask_circle & mask_poly

        self._sensor_max_value = 255