def __init__(self, color, radius, pos_init, dir_init, speed, reward, TYPE, SCREEN_WIDTH, SCREEN_HEIGHT, jitter_speed): pygame.sprite.Sprite.__init__(self) self.SCREEN_WIDTH = SCREEN_WIDTH self.SCREEN_HEIGHT = SCREEN_HEIGHT self.TYPE = TYPE self.jitter_speed = jitter_speed self.speed = speed self.reward = reward self.radius = radius self.pos = vec2d(pos_init) self.direction = vec2d(dir_init) self.direction.normalize() # normalized image = pygame.Surface((radius * 2, radius * 2)) image.fill((0, 0, 0)) image.set_colorkey((0, 0, 0)) pygame.draw.circle(image, color, (radius, radius), radius, 0) self.image = image.convert() self.rect = self.image.get_rect() self.rect.center = pos_init
def drive_single_step(self, agent, delta_time): """ drive_single_step Drive the agent over a single simulation step """ agent.social_move(delta_time / 1000.0) # print agent.social_force, agent.desired_force, agent.obstacle_force # sum up all the forces forces = vec2d(0, 0) forces.x = SF_FACTORS.social * agent.social_force[0] + SF_FACTORS.obstacle * agent.obstacle_force[0] + \ SF_FACTORS.desired * agent.desired_force[0] + SF_FACTORS.lookahead * agent.lookahead_force[0] forces.y = SF_FACTORS.social * agent.social_force[1] + SF_FACTORS.obstacle * agent.obstacle_force[1] + \ SF_FACTORS.desired * agent.desired_force[1] + SF_FACTORS.lookahead * agent.lookahead_force[1] # calculate the velocity based on the acceleration (forces) and momentum agent._velocity.x += delta_time * forces.x agent._velocity.y += delta_time * forces.y # check is resulting speed is beyond maximum speed if agent._velocity.get_length() > agent._vmax: agent._velocity.x = (agent._velocity.normalized().x) * agent._vmax agent._velocity.y = (agent._velocity.normalized().y) * agent._vmax # update positions and velocities displacement = agent._velocity * delta_time agent.prev_pos = vec2d(agent.position) agent.position += displacement
def _compute_obstacle_force(self): obstacle_force = vec2d(0.0, 0.0) # if there are no obstacles, there is no obstacle force if len(self.game.obstacles) == 0: return obstacle_force # find the closest obstacle and the closest point on it closest_distance, closest_point = self.game.obstacles[0].agent_distance(self) for obstacle in self.game.obstacles: other_distance, other_point = obstacle.agent_distance(self) if other_distance < closest_distance: closest_distance, closest_point = other_distance, other_point distance = closest_distance - self._radius if closest_distance > self._radius*5: return obstacle_force force_amount = exp(-distance) min_diffn = (self._position - vec2d(closest_point)).normalized() obstacle_force.x = (force_amount * min_diffn).x obstacle_force.y = (force_amount * min_diffn).y return obstacle_force
def _compute_obstacle_force(self): obstacle_force = vec2d(0.0, 0.0) # if there are no obstacles, there is no obstacle force if len(self.game.obstacles) == 0: return obstacle_force # find the closest obstacle and the closest point on it closest_distance, closest_point = self.game.obstacles[0].agent_distance(self) for obstacle in self.game.obstacles: other_distance, other_point = obstacle.agent_distance(self) if other_distance < closest_distance: closest_distance, closest_point = other_distance, other_point distance = closest_distance - self._radius if closest_distance > self._radius * 5: return obstacle_force force_amount = exp(-distance) min_diffn = (self._position - vec2d(closest_point)).normalized() obstacle_force.x = (force_amount * min_diffn).x obstacle_force.y = (force_amount * min_diffn).y return obstacle_force
def init(self): """ Starts/Resets the game to its inital state """ self.creep_counts = {"GOOD": 0, "BAD": 0} if self.player is None: self.player = Player( self.AGENT_RADIUS, self.AGENT_COLOR, self.AGENT_SPEED, self.AGENT_INIT_POS, self.width, self.height ) else: self.player.pos = vec2d(self.AGENT_INIT_POS) self.player.vel = vec2d((0.0, 0.0)) if self.creeps is None: self.creeps = pygame.sprite.Group() else: self.creeps.empty() for i in range(self.N_CREEPS): self._add_creep() self.score = 0 self.ticks = 0 self.lives = -1
def drive_single_step(self, agent, delta_time): """ drive_single_step Drive the agent over a single simulation step """ self._change_direction(agent, delta_time / 1000.0) displacement = vec2d(agent._direction.x * agent._vmax * (delta_time), agent._direction.y * agent._vmax * (delta_time)) agent.prev_pos = vec2d(agent._position) agent.position += displacement
def drive_single_step(self, agent, delta_time): """ drive_single_step Drive the agent over a single simulation step """ self._change_direction(agent, delta_time / 1000.0) displacement = vec2d( agent._direction.x * agent._vmax * (delta_time), agent._direction.y * agent._vmax * (delta_time)) agent.prev_pos = vec2d(agent._position) agent.position += displacement
def __init__(self, radius, color, speed, pos_init, SCREEN_WIDTH, SCREEN_HEIGHT): pygame.sprite.Sprite.__init__(self) self.SCREEN_WIDTH = SCREEN_WIDTH self.SCREEN_HEIGHT = SCREEN_HEIGHT self.pos = vec2d(pos_init) self.vel = vec2d((0, 0)) image = pygame.Surface([radius * 2, radius * 2]) image.set_colorkey((0, 0, 0)) pygame.draw.circle(image, color, (radius, radius), radius, 0) self.image = image.convert() self.rect = self.image.get_rect() self.radius = radius
def _circle_intersection(self, circle, point): """ Compute the distance and point on the boundary of the circle intersected by a line from its center to the point """ dist = euclidean_distance((circle[0], circle[1]), point) - circle[2] vun = vec2d((circle[0] - point[0]), (circle[1] - point[1])) v = vun.normalized() x, y = (point[0] + dist * v.x), (point[0] + dist * v.x) return dist, (x, y)
def __init__(self, pos, w, h): pygame.sprite.Sprite.__init__(self) self.pos = vec2d(pos) self.w = w self.h = h image = pygame.Surface([w, h]) image.fill((10, 10, 10)) self.image = image.convert() self.rect = self.image.get_rect() self.rect.center = pos
def _compute_social_force(self): # variables according to Moussaid-Helbing paper lambda_importance = 2.0 gamma = 0.35 n, n_prime = 2, 3 social_force = vec2d(0, 0) for neighbor in self._neighbors: # no social force with oneself if neighbor.id == self.id: continue else: # position difference diff = neighbor.position - self.position diff_direction = diff.normalized() # velocity difference vel_diff = self.velocity - neighbor.velocity # interaction direction t_ij interaction_vector = lambda_importance * vel_diff + diff_direction if (interaction_vector.get_length()) == 0: continue; interaction_direction = interaction_vector / interaction_vector.get_length() # theta (angle between interaction direction and position difference vector) theta = interaction_direction.get_angle_between(diff_direction) # model parameter B = gamma * ||D|| B = gamma * interaction_vector.get_length() theta_rad = radians(theta) force_vel_amount = -exp(-diff.get_length() / B - (n_prime * B * theta_rad)**2) force_angle_amount = (-1 * SIGN(theta)) * exp(-diff.get_length() / B - (n * B * theta_rad)**2) force_vel = force_vel_amount * interaction_direction force_angle = force_angle_amount * interaction_direction.left_normal_vector() # social_force[0] += force_vel.x + force_angle.x # social_force[1] += force_vel.y + force_angle.y social_force += force_vel + force_angle return social_force
def _compute_social_force(self): # variables according to Moussaid-Helbing paper lambda_importance = 2.0 gamma = 0.35 n, n_prime = 2, 3 social_force = vec2d(0, 0) for neighbor in self._neighbors: # no social force with oneself if neighbor.id == self.id: continue else: # position difference diff = neighbor.position - self.position diff_direction = diff.normalized() # velocity difference vel_diff = self.velocity - neighbor.velocity # interaction direction t_ij interaction_vector = lambda_importance * vel_diff + diff_direction if (interaction_vector.get_length()) == 0: continue interaction_direction = interaction_vector / interaction_vector.get_length() # theta (angle between interaction direction and position difference vector) theta = interaction_direction.get_angle_between(diff_direction) # model parameter B = gamma * ||D|| B = gamma * interaction_vector.get_length() theta_rad = radians(theta) force_vel_amount = -exp(-diff.get_length() / B - (n_prime * B * theta_rad) ** 2) force_angle_amount = (-1 * SIGN(theta)) * exp(-diff.get_length() / B - (n * B * theta_rad) ** 2) force_vel = force_vel_amount * interaction_direction force_angle = force_angle_amount * interaction_direction.left_normal_vector() # social_force[0] += force_vel.x + force_angle.x # social_force[1] += force_vel.y + force_angle.y social_force += force_vel + force_angle return social_force
def __init__(self, screen, wid, wtype, position, radius): """ screen: The screen on which the waypoint lives wid: waypoint id wtype: waypoint type (birth, death, normal) position: 2D location of the waypoint in (x,y) format in metres radius: Radius of the waypoint (all waypoints are circular) in metres """ self.screen = screen self._id = wid self._type = wtype self._position = vec2d(position[0]*SCALE, position[1]*SCALE) # stored internally in pixels self._radius = radius * SCALE # stored internally in pixels
def update(self, time_passed): # cim = Image.open('assets/blueagent.bmp') # rim = cim.rotate(self._direction.get_angle(), expand=1) # self._image = pygame.image.fromstring(rim.tostring(), rim.size, rim.mode) # When the image is rotated, its size is changed. # self._image_w, self._image_h = self._image.get_size() # bounds_rect = self.screen.get_rect().inflate(-self._image_w, -self._image_h) bounds_rect = self.game.field_box.get_internal_rect() self._direction = vec2d(self._velocity.x, -self._velocity.y) if self._position.x*SCALE < bounds_rect.left: self._position.x = bounds_rect.left/SCALE self._direction.x *= -1 elif self._position.x*SCALE > bounds_rect.right: self._position.x = bounds_rect.right/SCALE self._direction.x *= -1 elif self._position.y*SCALE < bounds_rect.top: self._position.y = bounds_rect.top/SCALE self._direction.y *= -1 elif self._position.y*SCALE > bounds_rect.bottom: self._position.y = bounds_rect.bottom/SCALE self._direction.y *= -1
def update(self, time_passed): # cim = Image.open('assets/blueagent.bmp') # rim = cim.rotate(self._direction.get_angle(), expand=1) # self._image = pygame.image.fromstring(rim.tostring(), rim.size, rim.mode) # When the image is rotated, its size is changed. # self._image_w, self._image_h = self._image.get_size() # bounds_rect = self.screen.get_rect().inflate(-self._image_w, -self._image_h) bounds_rect = self.game.field_box.get_internal_rect() self._direction = vec2d(self._velocity.x, -self._velocity.y) if self._position.x * SCALE < bounds_rect.left: self._position.x = bounds_rect.left / SCALE self._direction.x *= -1 elif self._position.x * SCALE > bounds_rect.right: self._position.x = bounds_rect.right / SCALE self._direction.x *= -1 elif self._position.y * SCALE < bounds_rect.top: self._position.y = bounds_rect.top / SCALE self._direction.y *= -1 elif self._position.y * SCALE > bounds_rect.bottom: self._position.y = bounds_rect.bottom / SCALE self._direction.y *= -1
def __init__(self, agent_id, screen, game, agent_image, field, init_position, init_direction, max_speed, waypoints, radius = 0.2, relaxation_time = 0.5, atype = 0): """ Create a new Agent. screen: The screen on which the agent lives (must be a pygame Surface object, such as pygame.display) game: The game object that holds information about the game world. agent_image: Image reprsenting the agent in the simulation field: A Rect specifying the 'playing field' boundaries. The agent will bounce off the 'walls' of this field. init_position: A vec2d or a pair specifying the initial position of the agent on the screen in metres init_direction: A vec2d or a pair specifying the initial direction of the agent. Must have an angle that is a multiple of 45 degres. vmax: maximum agent speed, in (m/s) waypoints: a list of waypoints for the agent to follow """ Sprite.__init__(self) self._id = agent_id self.screen = screen self.game = game self._vmax = max_speed self._field = field self._radius = radius self._relaxation_time = relaxation_time self._type = atype # the current image representing the agent self._image = agent_image # A vector specifying the agent's position on the screen self._position = vec2d(init_position) self.prev_pos = vec2d(self._position) # The direction is a normalized vector self._direction = vec2d(init_direction).normalized() self._velocity = vec2d(init_direction) self._acceleration = vec2d(0.0, 0.0) self._waypoints = waypoints self._waypoint_index = 0 self._neighbors = [] # # default no forces self._social_force = vec2d(0.0, 0.0) self._desired_force = vec2d(0.0, 0.0) self._obstacle_force = vec2d(0.0, 0.0) self._lookahead_force = vec2d(0.0, 0.0)
def _compute_lookahead_force(self): lookahead_force = vec2d(0, 0) return lookahead_force
def __init__( self, agent_id, screen, game, agent_image, field, init_position, init_direction, max_speed, waypoints, radius=0.2, relaxation_time=0.5, atype=0, ): """ Create a new Agent. screen: The screen on which the agent lives (must be a pygame Surface object, such as pygame.display) game: The game object that holds information about the game world. agent_image: Image reprsenting the agent in the simulation field: A Rect specifying the 'playing field' boundaries. The agent will bounce off the 'walls' of this field. init_position: A vec2d or a pair specifying the initial position of the agent on the screen in metres init_direction: A vec2d or a pair specifying the initial direction of the agent. Must have an angle that is a multiple of 45 degres. vmax: maximum agent speed, in (m/s) waypoints: a list of waypoints for the agent to follow """ Sprite.__init__(self) self._id = agent_id self.screen = screen self.game = game self._vmax = max_speed self._field = field self._radius = radius self._relaxation_time = relaxation_time self._type = atype # the current image representing the agent self._image = agent_image # A vector specifying the agent's position on the screen self._position = vec2d(init_position) self.prev_pos = vec2d(self._position) # The direction is a normalized vector self._direction = vec2d(init_direction).normalized() self._velocity = vec2d(init_direction) self._acceleration = vec2d(0.0, 0.0) self._waypoints = waypoints self._waypoint_index = 0 self._neighbors = [] # # default no forces self._social_force = vec2d(0.0, 0.0) self._desired_force = vec2d(0.0, 0.0) self._obstacle_force = vec2d(0.0, 0.0) self._lookahead_force = vec2d(0.0, 0.0)