def setUp(self): self.points = [ Point2(0, 0), Point2(0, 4), Point2(4, 4), Point2(4, 0), ]
def line_circle_intersection(arc, circle_pos, circle_radius, inset=True): circ = Circle(Point2(circle_pos[0], circle_pos[1]), float(circle_radius)) p1 = Point2(arc.source_pos[0], arc.source_pos[1]) p2 = Point2(arc.target_pos[0], arc.target_pos[1]) if p1 != p2: line = Line2(p1, p2) inters = line.intersect(circ) if (abs((p2 - inters.p1).magnitude() - (p2 - inters.p2).magnitude()) > abs((p1 - inters.p1).magnitude() - (p1 - inters.p2).magnitude())): p = p2 else: p = p1 if (p - inters.p1).magnitude() > (p - inters.p2).magnitude(): return vec2d(inters.p2.x, inters.p2.y) #use p2 return vec2d(inters.p1.x, inters.p1.y) #use p1 else: # circle to ellipse intersection if arc.r_a != arc.r_b: delta = sqrt(arc.r_b**2 * (arc.r_a**4 - arc.r_a**2 * arc.r_b**2 + arc.r_b**2 * circle_radius**2)) y = ((circle_pos[1] - circle_radius) * arc.r_a**2 + delta - arc.r_b**2 * circle_pos[1]) / (arc.r_a**2 - arc.r_b**2) if inset: x = circle_pos[0] - sqrt(circle_radius**2 - (y - circle_pos[1])**2) else: x = circle_pos[0] + sqrt(circle_radius**2 - (y - circle_pos[1])**2) return vec2d(x, y) return circle_pos + (circle_radius, 0) #dummy
def to_html(self, stats=[]): """Return svg representation of the simulator""" stats = stats[:] recent_reward = self.collected_rewards[-100:] + [0] objects_eaten_str = ', '.join( ["%s: %s" % (o, c) for o, c in self.objects_eaten.items()]) stats.extend([ "nearest wall = %.1f" % (self.distance_to_walls(), ), "reward = %.1f" % (sum(recent_reward) / len(recent_reward), ), "objects eaten => %s" % (objects_eaten_str, ), ]) scene = svg.Scene( (self.size[0] + 20, self.size[1] + 20 + 20 * len(stats))) scene.add(svg.Rectangle((10, 10), self.size)) for line in self.observation_lines: scene.add( svg.Line(line.p1 + self.hero.position + Point2(10, 10), line.p2 + self.hero.position + Point2(10, 10))) for obj in self.objects + [self.hero]: scene.add(obj.draw()) offset = self.size[1] + 15 for txt in stats: scene.add(svg.Text((10, offset + 20), txt, 15)) offset += 20 return scene
def randomize_position(self, obj, noncoliding=True, margin=0.0): gen = lambda: random.uniform(obj.radius + margin, 1.0 - obj.radius - margin) obj.position = Point2(gen(), gen()) while noncoliding and any( objects_colliding(obj, other) for other in self.objects if other is not obj): obj.position = Point2(gen(), gen())
def build_scene(): scene = svg.Scene((xsize*amp + 2*offset, ysize*amp + 2*offset + 40)) # draw walls for wall in walls: p1 = wall[0] * amp + Point2(offset, offset) p2 = wall[1] * amp + Point2(offset, offset) scene.add(svg.Line(p1, p2)) scene.add(svg.Rectangle(Point2(offset, offset), Point2(xsize*amp, ysize*amp))) return scene
def draw_observation(self, scene): for line in self.observation_lines: obj = self.line_end_who[line] color = self.settings["colors"][ obj.obj_type] if type(obj) is GameObject else 'black' line_drawn = svg.Line( self.hero.position * self.size + Point2(10, 10), self.line_end_where[line] * self.size + Point2(10, 10), stroke=color) scene.add(line_drawn)
def test(): chassis = HoloChassis(wheels=[ HoloChassis.OmniWheel(position=Point2(1, 0), angle=0, radius=60), HoloChassis.OmniWheel(position=Point2(-1, 0), angle=0, radius=60) ]) print chassis.get_wheel_speeds( Motion(translation=Vector2(0, 0), rotation=0.5)) print chassis.get_wheel_speeds(Motion(translation=Vector2(0, 0), rotation=0.5), origin=Point2(1, 0))
def add(self, obj, randomize_position=False, ensure_noncolliding=False): self.objects.append(obj) gen = lambda: random.uniform(obj.radius, 1.0 - obj.radius) if randomize_position: obj.position = Point2(gen(), gen()) if ensure_noncolliding: while any( objects_colliding(obj, other) for other in self.objects if other is not obj): obj.position = Point2(gen(), gen())
def poll_task(self, context, tick): """ Create a set of simple waypoints and return the appropriate :class:`triangula.tasks.patrol.PatrolTask` which will visit them in turn then exit. """ waypoints = [ TaskWaypoint(pose=Pose(position=Point2(0, 300), orientation=0), task=PauseTask(pause_time=3), stop=True), TaskWaypoint(pose=Pose(position=Point2(300, 300), orientation=0)) ] return PatrolTask(waypoints=waypoints, max_power=0.4)
def _calculate_vertex_points(self): w = float(self.texture.width) h = float(self.texture.height) index_points = [] vertex_points_idx = [] texture_points_idx = [] for x in xrange(0, self.grid.x + 1): for y in xrange(0, self.grid.y + 1): vertex_points_idx += [-1, -1, -1] texture_points_idx += [-1, -1] for x in xrange(0, self.grid.x): for y in xrange(0, self.grid.y): x1 = x * self.x_step x2 = x1 + self.x_step y1 = y * self.y_step y2 = y1 + self.y_step # d <-- c # ^ # | # a --> b a = x * (self.grid.y + 1) + y b = (x + 1) * (self.grid.y + 1) + y c = (x + 1) * (self.grid.y + 1) + (y + 1) d = x * (self.grid.y + 1) + (y + 1) # 2 triangles: a-b-d, b-c-d index_points += [a, b, d, b, c, d] # triangles l1 = (a * 3, b * 3, c * 3, d * 3) l2 = (Point3(x1, y1, 0), Point3(x2, y1, 0), Point3(x2, y2, 0), Point3(x1, y2, 0)) # building the vertex for i in xrange(len(l1)): vertex_points_idx[l1[i]] = l2[i].x vertex_points_idx[l1[i] + 1] = l2[i].y vertex_points_idx[l1[i] + 2] = l2[i].z # building the texels tex1 = (a * 2, b * 2, c * 2, d * 2) tex2 = (Point2(x1, y1), Point2(x2, y1), Point2(x2, y2), Point2(x1, y2)) for i in xrange(len(tex1)): texture_points_idx[tex1[i]] = tex2[i].x / w texture_points_idx[tex1[i] + 1] = tex2[i].y / h return (index_points, vertex_points_idx, texture_points_idx)
def generate_observation_lines(self): """Generate observation segments in settings["num_observation_lines"] directions""" result = [] start = Point2(0.0, 0.0) end = Point2(self.settings["observation_line_length"], self.settings["observation_line_length"]) for angle in np.linspace(0, 2*np.pi, self.settings["num_observation_lines"], endpoint=False): rotation = Point2(math.cos(angle), math.sin(angle)) current_start = Point2(start[0] * rotation[0], start[1] * rotation[1]) current_end = Point2(end[0] * rotation[0], end[1] * rotation[1]) result.append( LineSegment2(current_start, current_end)) return result
class Galaxy(ParticleSystem): # total particles total_particles = 200 # duration duration = -1 # gravity gravity = Point2(0, 0) # angle angle = 90.0 angle_var = 360.0 # speed of particles speed = 60.0 speed_var = 10.0 # radial radial_accel = -80.0 radial_accel_var = 0 # tangential tangential_accel = 80.0 tangential_accel_var = 0.0 # emitter variable position pos_var = Point2(0, 0) # life of particles life = 4.0 life_var = 1.0 # size, in pixels size = 37.0 size_var = 10.0 # emits per frame emission_rate = total_particles / life # color of particles start_color = Color(0.12, 0.25, 0.76, 1.0) start_color_var = Color(0.0, 0.0, 0.0, 0.0) end_color = Color(0.0, 0.0, 0.0, 0.0) end_color_var = Color(0.0, 0.0, 0.0, 0.0) # blend additive blend_additive = True # color modulate color_modulate = True
class Spiral(ParticleSystem): # total paticles total_particles = 500 # duration duration = -1 # gravity gravity = Point2(0, 0) # angle angle = 90.0 angle_var = 0.0 # speed of particles speed = 150.0 speed_var = 0.0 # radial radial_accel = -380 radial_accel_var = 0 # tangential tangential_accel = 45.0 tangential_accel_var = 0.0 # emitter variable position pos_var = Point2(0, 0) # life of particles life = 12.0 life_var = 0.0 # emits per frame emission_rate = total_particles / life # color of particles start_color = Color(0.5, 0.5, 0.5, 1.0) start_color_var = Color(0.5, 0.5, 0.5, 0.0) end_color = Color(0.5, 0.5, 0.5, 1.0) end_color_var = Color(0.5, 0.5, 0.5, 0.0) # size, in pixels size = 20.0 size_var = 10.0 # blend additive blend_additive = True # color modulate color_modulate = True
def render_scene(scene): for ped in crowd: # axis transform o = Point2(ped.x*amp, (ysize-ped.y)*amp) + Point2(offset, offset) scene.add(svg.Circle(o, radius = ped_ra, color=ped.c)) robot_o = Point2(pos_rx*amp, (ysize-pos_ry)*amp) + Point2(offset, offset) scene.add(svg.Circle(robot_o, radius = ped_ra, color='black')) # write text text = 'Ped outflow ' + str(ped_outflow) scene.add(svg.Text((400,500), text, 20)) clear_output(wait=True) display(scene)
class Smoke(ParticleSystem): # total particles total_particles = 80 # duration duration = -1 # gravity gravity = Point2(0, 0) # angle angle = 90.0 angle_var = 10.0 # speed of particles speed = 25.0 speed_var = 10.0 # radial radial_accel = 5 radial_accel_var = 0 # tangential tangential_accel = 0.0 tangential_accel_var = 0.0 # emitter variable position pos_var = Point2(0.1, 0) # life of particles life = 4.0 life_var = 1.0 # size, in pixels size = 40.0 size_var = 10.0 # emits per frame emission_rate = total_particles / life start_color = Color(0.5, 0.5, 0.5, 0.1) start_color_var = Color(0, 0, 0, 0.1) end_color = Color(0.5, 0.5, 0.5, 0.1) end_color_var = Color(0, 0, 0, 0.1) # blend additive blend_additive = True # color modulate color_modulate = False
class Fire(ParticleSystem): # total particles total_particles = 250 # duration duration = -1 # gravity gravity = Point2(0, 0) # angle angle = 90.0 angle_var = 10.0 # radial radial_accel = 0 radial_accel_var = 0 # speed of particles speed = 60.0 speed_var = 20.0 # emitter variable position pos_var = Point2(40, 20) # life of particles life = 3.0 life_var = 0.25 # emits per frame emission_rate = total_particles / life # color of particles start_color = Color(0.76, 0.25, 0.12, 1.0) start_color_var = Color(0.0, 0.0, 0.0, 0.0) end_color = Color(0.0, 0.0, 0.0, 1.0) end_color_var = Color(0.0, 0.0, 0.0, 0.0) # size, in pixels size = 100.0 size_var = 10.0 # blend additive blend_additive = True # color modulate color_modulate = True
class Explosion(ParticleSystem): # total particle total_particles = 700 # duration duration = 0.1 # gravity gravity = Point2(0, -90) # angle angle = 90.0 angle_var = 360.0 # radial radial_accel = 0 radial_accel_var = 0 # speed of particles speed = 70.0 speed_var = 40.0 # emitter variable position pos_var = Point2(0, 0) # life of particles life = 5.0 life_var = 2.0 # emits per frame emission_rate = total_particles / duration # color of particles start_color = Color(0.7, 0.2, 0.1, 1.0) start_color_var = Color(0.5, 0.5, 0.5, 0.0) end_color = Color(0.5, 0.5, 0.5, 0.0) end_color_var = Color(0.5, 0.5, 0.5, 0.0) # size, in pixels size = 15.0 size_var = 10.0 # blend additive blend_additive = False # color modulate color_modulate = True
class Fireworks(ParticleSystem): # total particles total_particles = 3000 # duration duration = -1 # gravity gravity = Point2(0, -90) # angle angle = 90 angle_var = 20 # radial radial_accel = 0 radial_accel_var = 0 # speed of particles speed = 180 speed_var = 50 # emitter variable position pos_var = Point2(0, 0) # life of particles life = 3.5 life_var = 1 # emits per frame emission_rate = total_particles / life # color of particles start_color = Color(0.5, 0.5, 0.5, 1.0) start_color_var = Color(0.5, 0.5, 0.5, 1.0) end_color = Color(0.1, 0.1, 0.1, 0.2) end_color_var = Color(0.1, 0.1, 0.1, 0.2) # size, in pixels size = 8.0 size_var = 2.0 # blend additive blend_additive = False # color modulate color_modulate = True
def draw_objects(self, scene): for obj in self.objects: color = self.settings["colors"][obj.obj_type] obj_drawing = svg.Circle(obj.position * self.size + Point2(10, 10), obj.radius * self.size, color=color) scene.add(obj_drawing)
def reset(self): """ Clear the state of this :class:`approxeng.chassis.DeadReckoning` """ self.last_encoder_values = None self.last_reading_time = None self.pose = Pose(Point2(0, 0), 0)
def draw(self, temp_color=None): """Return svg object for this item.""" if temp_color: color = temp_color else: color = self.settings["colors"][self.obj_type] return svg.Circle(self.position + Point2(10, 10), self.radius, color=color)
def update_from_counts(self, counts): """ Update the pose from a new set of encoder values :param counts: A list of encoder counts, one per wheel :return: The updated :class:`triangula.chassis.Pose` object (this is also modified in the internal state of the DeadReckoning) """ reading_time = time() if self.last_encoder_values is None: self.last_encoder_values = counts self.last_reading_time = reading_time self.pose = Pose(Point2(0, 0), 0) else: time_delta = reading_time - self.last_reading_time wheel_speeds = [ smallest_difference(current_reading, last_reading, self.max_count_value) / (self.counts_per_revolution * time_delta) for last_reading, current_reading in zip( counts, self.last_encoder_values) ] motion = self.chassis.calculate_motion(speeds=wheel_speeds) self.pose = self.pose.calculate_pose_change(motion, time_delta) self.last_encoder_values = counts self.last_reading_time = reading_time return self.pose
def test_setting_direction_is_applied_to_entity(self): new_direction = Point2(1, -1) for vehicle, entity in (self.armour, self.tank), (self.missile, self.bullet): vehicle.direction = new_direction assert entity.direction.x == new_direction.x assert entity.direction.y == new_direction.y
def test_setting_position_is_applied_to_entity(self): new_position = Point2(20, 40) for vehicle, entity in (self.armour, self.tank), (self.missile, self.bullet): vehicle.position = new_position assert entity.position.x == new_position.x assert entity.position.y == new_position.y
def get_regular_triangular_chassis(wheel_distance, wheel_radius, max_rotations_per_second): """ Build a HoloChassis object with three wheels, each identical in size and maximum speed. Each wheel is positioned at the corner of a regular triangle, and with direction perpendicular to the normal vector at that corner. :param wheel_distance: Distance in millimetres between the contact points of each pair of wheels (i.e. the length of each edge of the regular triangle) :param wheel_radius: Wheel radius in millimetres :param max_rotations_per_second: Maximum wheel speed in revolutions per second :return: An appropriately configured HoloChassis """ point = Point2(0, cos(radians(30)) * wheel_distance / 2.0) vector = Vector2(-2 * pi * wheel_radius, 0) # Pink wheel_a = HoloChassis.OmniWheel(position=point, vector=vector, max_speed=max_rotations_per_second) # Yellow wheel_b = HoloChassis.OmniWheel(position=rotate_point(point, pi * 2 / 3), vector=rotate_vector(vector, pi * 2 / 3), max_speed=max_rotations_per_second) # Green wheel_c = HoloChassis.OmniWheel(position=rotate_point(point, pi * 4 / 3), vector=rotate_vector(vector, pi * 4 / 3), max_speed=max_rotations_per_second) return HoloChassis(wheels=[wheel_a, wheel_b, wheel_c])
def test_bounds(self, vehicle, x_func, x_inside, y_func, y_inside): cls, entity, parent = vehicle x = x_func(cls, self.width) y = y_func(cls, self.height) inside = x_inside and y_inside position = Point2(x, y) self._bounds_test(cls, entity, parent, position, not inside)
def __init__(self, settings): """Initiallize game simulator with settings""" self.settings = settings self.size = self.settings["world_size"] # make 4 walls self.walls = [ LineSegment2(Point2(0, 0), Point2(0, self.size[1])), LineSegment2(Point2(0, self.size[1]), Point2(self.size[0], self.size[1])), LineSegment2(Point2(self.size[0], self.size[1]), Point2(self.size[0], 0)), LineSegment2(Point2(self.size[0], 0), Point2(0, 0)) ] # make hero object self.hero = GameObject(Point2(*self.settings["hero_initial_position"]), Vector2(*self.settings["hero_initial_speed"]), "hero", self.settings) if not self.settings["hero_bounces_off_walls"]: self.hero.bounciness = 0.0 # now hero has no bounciness self.objects = [] # spawn 25 friends, 25 enemy for obj_type, number in settings["num_objects"].items(): # 2 times run for _ in range(number): self.spawn_object(obj_type) # generate 32 number of antennas self.observation_lines = self.generate_observation_lines() self.object_reward = 0 self.collected_rewards = [] # every observation_line sees one of objects or wall and # two numbers representing speed of the object (if applicable) self.eye_observation_size = len( self.settings["objects"] ) + 3 # 2+3 --> maybe [friend, enemy, wall, speed X, Y] # additionally there are two numbers representing agents own speed. self.observation_size = self.eye_observation_size * len( self.observation_lines ) + 2 # (5 * 32) + 2 ==> 2 is hero's own speed self.directions = [ Vector2(*d) for d in [[1, 0], [0, 1], [-1, 0], [0, -1]] ] # there are 4 directions. up down left right self.num_actions = len(self.directions) # so num_actions is 4 self.objects_eaten = defaultdict(lambda: 0)
def spawn_object(self, obj_type): speed = Vector2(random.gauss(0., 0.2), random.gauss(0., 0.2)) self.sim.add(GameObject(Point2(0., 0.), speed, obj_type, radius=self.obj_radius), ensure_noncolliding=True, randomize_position=True)
def __init__(self, name='SimulationThread', update_delay=0.01): super(Simulation, self).__init__(name=name) self.daemon = True self.motion = Motion(Vector2(0, 0), 0) self.pose = Pose(Point2(0, 0), 0) self.last_update_time = time() self.update_delay = update_delay self.after_simulation_callback = None self.running = True
def __init__(self, settings): """Initialize game simulator with settings""" self.settings = settings self.size = self.settings["world_size"] self.walls = [LineSegment2(Point2(0,0), Point2(0,self.size[1])), LineSegment2(Point2(0,self.size[1]), Point2(self.size[0], self.size[1])), LineSegment2(Point2(self.size[0], self.size[1]), Point2(self.size[0], 0)), LineSegment2(Point2(self.size[0], 0), Point2(0,0))] self.hero = GameObject(Point2(*self.settings["hero_initial_position"]), Vector2(*self.settings["hero_initial_speed"]), "hero", self.settings["hero_radius"], self.settings) # Hero direction is a number between 0 and num_observation_lines_total - 1 (0 is directly right) self.hero_direction = self.settings["hero_initial_direction"] self.unit_vectors = [] for angle in np.linspace(0, 2*np.pi, self.settings["num_observation_lines_total"], endpoint=False): u_vector = Point2(math.cos(angle), math.sin(angle)) self.unit_vectors.append(u_vector) self.objects = [] for obj_type, number in settings["num_objects"].items(): for _ in range(number): self.spawn_object(obj_type) self.observation_lines = self.generate_observation_lines() self.object_reward = 0 self.collected_rewards = [] self.just_shot = False self.just_got_hit = False # every observation_line sees one of objects and # two numbers representing speed of the object (if applicable) self.eye_observation_size = len(self.settings["objects"]) + 2 # additionally there are two numbers representing agents own speed. self.observation_size = self.eye_observation_size * len(self.observation_lines) + 2 # self.directions = [Vector2(*d) for d in [[1,0], [0,1], [-1,0],[0,-1]]] self.num_actions = 4 # Accelerate, turn clockwise, turn anticlockwise, shoot self.objects_eaten = defaultdict(lambda: 0) self.objects_shot = defaultdict(lambda: 0)