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
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
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
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
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)
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()
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()
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
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')
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
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) ]
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
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']
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 = []
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)
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()
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
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
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
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
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)]
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
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
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