#!/usr/bin/python from GameClasses import * from tkinter import * from MenuDisplay import * from GameDisplay import * import pygame from pygame.locals import * from pygame.color import * import pymunk from pymunk.vec2d import Vec2d import pymunk.pygame_util import sys # Tank Target levelInfo = [ (Vec2d(100, 200), Vec2d(1000,175)), (Vec2d(100, 200), Vec2d(1300,175)), (Vec2d(100, 200), Vec2d(1000,600)) ] def stick_arrow_to_target(space, arrow_body, target_body, position, flying_arrows): pivot_joint = pymunk.PivotJoint(arrow_body, target_body, position) phase = target_body.angle - arrow_body.angle gear_joint = pymunk.GearJoint(arrow_body, target_body, phase, 1) space.add(pivot_joint) space.add(gear_joint) try: flying_arrows.remove(arrow_body) except: pass
# See the License for the specific language governing permissions and # limitations under the License. import math from multiprocessing import Event, Queue from queue import Empty, Full import numpy as np import pymunk from pymunk.vec2d import Vec2d from ..api.controller import Controller from ..api.plant import ActuatorVariable, SensorVariable, State from ..api.util import PhyPropMapping #: Gravity constants G_CONST = Vec2d(0, -9.8) def visualization_loop(input_q: Queue, shutdown_event: Event, screen_w: int, screen_h: int, caption: str, ppm: float = 200.0) \ -> None: import pyglet window = pyglet.window.Window(screen_w, screen_h, vsync=False, caption=caption) floor_offset = Vec2d(screen_w / 2, 5) # TODO fix magic number
def visualization_loop(input_q: Queue, shutdown_event: Event, screen_w: int, screen_h: int, caption: str, ppm: float = 200.0) \ -> None: import pyglet window = pyglet.window.Window(screen_w, screen_h, vsync=False, caption=caption) floor_offset = Vec2d(screen_w / 2, 5) # TODO fix magic number def on_draw(dt): # TODO: needs a timeout for shutdown while True: if shutdown_event.is_set(): window.close() pyglet.app.exit() return try: coord_dict = input_q.get(block=True, timeout=0.01) break except Empty: continue window.clear() for shape in coord_dict['shapes']: raw_vertices = shape['vertices'] angle = shape['angle'] position = shape['position'] # get vertices in world coordinates vertices = [ Vec2d(v).rotated(angle) + position for v in raw_vertices ] # convert vertices to pixel coordinates points = [] for v in vertices: v2 = (v * ppm) + floor_offset points.append(v2.x) points.append(v2.y) data = ('v2i', tuple(map(int, points))) pyglet.graphics.draw(len(vertices), pyglet.gl.GL_LINE_LOOP, data) for line in coord_dict['lines']: raw_vertices = line['vertices'] radius = line['radius'] vertices = [Vec2d(v) + (0, radius) for v in raw_vertices] # convert vertices to pixel coordinates points = [] for v in vertices: v2 = (v * ppm) + floor_offset points.append(v2.x) points.append(v2.y) data = ('v2i', tuple(map(int, points))) pyglet.graphics.draw(len(vertices), pyglet.gl.GL_LINES, data) pyglet.clock.schedule_interval(on_draw, 1 / 60.0) pyglet.app.run()
def draw_lasers(laser_list: [pymunk.Shape]): for laser in laser_list: laser.tip_coords = pygame_coordinates(*laser.body.position) laser.back_coords = pygame_coordinates(*(Vec2d(20, 0).rotated(laser.body.angle) + laser.body.position)) pygame.draw.line(DISPLAY_SURF, laser.color, laser.tip_coords, laser.back_coords, 3)
def frame_step(self, action): global keyboard_in if action == 0: # Turn left. self.car_body.angle -= .2 elif action == 1: # Turn right. self.car_body.angle += .2 # Move obstacles. if self.num_steps % 100 == 0: self.move_obstacles() # Move cat. if self.num_steps % 5 == 0: self.move_cat() driving_direction = Vec2d(1, 0).rotated(self.car_body.angle) self.car_body.velocity = 100 * driving_direction if action == 3: self.car_body.velocity = 0*Vec2d(1, 0).rotated(self.car_body.angle) # Update the screen and stuff. screen.fill(THECOLORS["black"]) draw(screen, self.space) self.space.step(1./10) if draw_screen: pygame.display.flip() clock.tick() # Get the current location and the readings there. x, y = self.car_body.position readings = self.get_sonar_readings(x, y, self.car_body.angle) color = self.verify_detected(x, y, self.car_body.angle) state = np.array([readings]) if keyboard_in=='t': #os.system("kill -9 %d"%(os.getppid())) exit() elif keyboard_in=='r': print("you killed yourself") readings = [1,1,1,1,1] keyboard_in = '' else: pass # Set the reward. # Car crashed when any reading == 1 if self.car_is_crashed(readings): self.crashed = True reward = -500 self.recover_from_crash(driving_direction) else: reward= (((1700*mlab.normpdf(readings[0], 20, 2))*color[0]+(3000*mlab.normpdf(readings[1], 15, 2))*color[1]+(6000*mlab.normpdf(readings[2], 15, 2))*color[2]+(3000*mlab.normpdf(readings[3], 15, 2))*color[3]+(1700*mlab.normpdf(readings[4], 20, 2))*color[4])) +( (int(self.sum_readings(readings))-5) / 10) #print data #print("\n reward:%d" % (reward)) #print("\n reading left: ",readings[0]) #print(" reading mid: ",readings[1]) #print(" reading right: ",readings[2]) self.num_steps += 1 return reward, state
def __init__(self, canvas, zoom, offset=Vec2d(0, 0)): self.canvas = canvas self.offset = offset self.zoom = zoom
def bubble_plot( ax, df, position_column, radius_column, label_column=None, color_column=None, palette="plasma", n_bins=10, num_steps=50, x_position_scaling=800, min_label_size=4, max_label_size=64, starting_y_range=None, margin=2, ): df = df.reset_index() space = pymunk.Space() space.gravity = (0, 0) radius = np.sqrt(df[radius_column].values) + margin if starting_y_range is None: starting_y_range = int(np.sqrt(df.shape[0])) for idx, row in df.iterrows(): x = row[position_column] * x_position_scaling y = np.random.randint(-starting_y_range, starting_y_range) mass = 10 r = radius[idx] moment = pymunk.moment_for_circle(mass, 0, r, (0, 0)) body = pymunk.Body(mass, moment) body.position = x, y body.start_position = Vec2d(*body.position) shape = pymunk.Circle(body, r) shape.elasticity = 0.9999999 space.add(body, shape) for i in range(num_steps): space.step(1) value_range = (min(radius), max(radius)) def scale(value): result = (value - value_range[0]) / (value_range[1] - value_range[0]) return result ax.set_aspect("equal") cmap = ListedColormap(sns.color_palette(palette, n_colors=n_bins)) collection = [] values = [] min_x = 0 max_x = 0 min_y = 0 max_y = 0 for body, (idx, row) in zip(space.bodies, df.iterrows()): circle = next(iter(body.shapes)) c = Circle(np.array(body.position), circle.radius - margin) collection.append(c) values.append(row[position_column]) body_x = body.position.x body_min_x = body_x - circle.radius body_max_x = body_x + circle.radius body_y = body.position.y body_min_y = body_y - circle.radius body_max_y = body_y + circle.radius if body_min_y < min_y: min_y = body_min_y if body_min_x < min_x: min_x = body_min_x if body_max_y > max_y: max_y = body_max_y if body_max_x > max_x: max_x = body_max_x if label_column is not None: label_size = int(scale(radius[idx]) * max_label_size) if label_size < min_label_size: continue ax.annotate( row[label_column], np.array(body.position), ha="center", va="center", fontsize=label_size, ) collection = PatchCollection(collection, color="pink", edgecolor="none", cmap=cmap) collection.set_array(np.array(values)) ax.add_collection(collection) ax.set_aspect("equal") ax.set_xlim([min_x, max_x]) ax.set_ylim([min_y, max_y]) return space, collection
def main(): sys.setrecursionlimit(10000) width, height = 690, 600 ### PyGame init pygame.init() screen = pygame.display.set_mode((width, height)) clock = pygame.time.Clock() running = True font = pygame.font.SysFont("Arial", 16) ### Physics stuff space = pymunk.Space() draw_options = pymunk.pygame_util.DrawOptions(screen) env_xml = EnvironmentXml( "/home/dseredyn/ws_stero/src/multilevel_planning/data/environments/env_05.xml" ) models = env_xml.getModels() for model in models: model.addToSpace(space) damped_objects_list = [] for model in models: if not model.damping is None: damped_objects_list.append( (model.body, model.damping[0], model.damping[1])) # cab = ModelCabinet(200, 100, Vec2d(200,200), -0.05) # cab.addToSpace(space) # box = ModelBox(50, 10, Vec2d(200,200), 0*math.pi/4.0) # box.addToSpace( space ) # damped_objects_list.append( (box.body, 300.0, 3000.0) ) # robot # rob = ModelRobot( Vec2d(100,100), 0.0 ) # rob = ModelRobot( Vec2d(220,225), 0.0 ) # rob.addToSpace(space) for ob in models: if ob.name == "robot": rob = ob if ob.name == "box": box = ob control_mode = "target_pos" position_control = ManualPositionControl(1000.0, 500.0, 50000.0, 50000.0) control_mode = "auto" dest_point = Vec2d(550, 270) # info_exp_motion = InformationExpectedMotion() # info_exp_motion.anchor = "instance_box" # info_exp_motion.target_point = Vec2d(500,500) dest_command = InformationDestinationGeom(dest_point) # provide information information = [ #InformationSpatialMapRange( (0, width), 100, (0, height), 100 ), # range and resolution of spatial map InformationRobotPose(rob.robot_body.position, rob.robot_body.angle), # current pose of robot InformationPerceptionSpace( space, models), # percepted environment (exact, full perception) dest_command, # target point for motion # InformationOpenDoorCommand(), # info_exp_motion, ] behaviors = [ BehaviorSpatialMapGeneration(models), # BehaviorSpaceDigging(env), BehaviorKeepContact(), BehaviorSpatialPathPlanner(), BehaviorMoveTowards(), BehaviorObstacleAvoidance(), BehaviorTightPassage(), # BehaviorDoorPerception(cab.left_door), # BehaviorOpenDoor(), BehaviorMoveObject(), BehaviorObjectPerception(), BehaviorPushObject(), BehaviorPushExecution(), BehaviorRobotControl(), ] # behaviors[0].update(information) # behaviors[0].plotTriangulation() # behaviors[0].plotGraph() # plt.show() # behaviors[1].update(information) # behaviors[1].plotTriangulation() # behaviors[1].plotGraph() # behaviors[1].plotOccludedSimplices() # behaviors[1].plotBorder() # plt.show() # exit(0) generateBehaviorsDotGraph( '/home/dseredyn/svn/phd/ds/doktorat/rozwazania_2018_04/img/zachowania.dot', behaviors) first_behavior_iteration = True iterations = 0 pause = False show_debug = False while running: iterations += 1 if iterations == 10: generateBehaviorsDotGraph( '/home/dseredyn/svn/phd/ds/doktorat/rozwazania_2018_04/img/zachowania_2.dot', behaviors) for event in pygame.event.get(): if event.type == QUIT or \ event.type == KEYDOWN and (event.key in [K_ESCAPE, K_q]): running = False if event.type == KEYDOWN and event.key == K_SPACE: pause = not pause if event.type == KEYDOWN and event.key == K_d: show_debug = not show_debug if pause: time.sleep(0.1) continue debug_info = [] keys = pygame.key.get_pressed() active_behaviors = [] # manual control if control_mode == "force": manualForceControl(rob.robot_body, keys) elif control_mode == "target_pos": position_control.update(rob.robot_body, keys) elif control_mode == "auto": position_control.update(rob.robot_body, keys) joinInformation(information, [ InformationRobotPose(rob.robot_body.position, rob.robot_body.angle) ]) # current pose of robot for b in behaviors: new_inf = b.update(information) joinInformation(information, new_inf) if len(new_inf) > 0: active_behaviors.append(b.name) #print new_inf[0].type inf_list = [] for inf in information: inf_list.append(inf.type) if inf.type == "robot_total_control": lin_damping = 300.0 lin_stiffness = 5000.0 rot_damping = 5000.0 rot_stiffness = 5000.0 #print inf.force, inf.torque rob.robot_body.force = lin_stiffness * inf.force - lin_damping * rob.robot_body.velocity rob.robot_body.torque = rot_stiffness * inf.torque - rot_damping * rob.robot_body.angular_velocity #print inf.torque #print "data:", inf_list # TODO: fix removing old information wrt. behavior execution sequence clearObsoleteInformation(information) #print active_behaviors # print "plan_idx", plan_idx #cab.debugVis(debug_info) #rob.debugVisQhull(debug_info) #rob.debugVisPushing(debug_info) applyDamping(damped_objects_list) mouse_position = pymunk.pygame_util.from_pygame( Vec2d(pygame.mouse.get_pos()), screen) mouse_position_munk = MunkToGame(mouse_position, height) dest_command.point = mouse_position ### Clear screen screen.fill(pygame.color.THECOLORS["black"]) ### Draw stuff space.debug_draw(draw_options) if control_mode == "target_pos": position_control.debugInfoDraw(debug_info) elif control_mode == "auto": #behaviors[2].debugVisDraw(debug_info) #drawDebugCircle(debug_info, "green", 5, dest_point) vis_behaviors = [ "keep_contact", "push_object", "spatial_path_planner", "obstacle_avoidance", "move_towards" ] for b in behaviors: if b.name in vis_behaviors and b.name in active_behaviors: b.debugVisDraw(debug_info) # draw debug info if show_debug: drawDebugInfo(screen, height, debug_info) # Info and flip screen screen.blit( font.render("fps: " + str(clock.get_fps()), 1, THECOLORS["white"]), (0, 0)) screen.blit( font.render( "Mouse position (in world coordinates): " + str(mouse_position[0]) + "," + str(mouse_position[1]), 1, THECOLORS["darkgrey"]), (5, height - 35)) screen.blit( font.render("Press ESC or Q to quit", 1, THECOLORS["darkgrey"]), (5, height - 20)) pygame.display.flip() ### Update physics fps = 60 dt = 1. / fps space.step(dt) clock.tick(fps)
def draw_sprite(screen, image, position, half_size): screen.blit( image, flip_y(position, screen.get_size()[1]) - Vec2d(half_size, half_size))
def update(self, dt, surface): tank_body = self.tank_body tank_control_body = self.tank_control_body self._odom_info = [ tuple(list(tank_body.position) + [0, tank_body.angle]) for _ in range(4) ] self.update_robot_coords() space = self.space mouse_delta = Vec2d(0, 0) # mouse_delta exact length does not matter pressed = pygame.key.get_pressed() if pressed[pygame.K_a]: mouse_delta = Vec2d(-1, 0) if pressed[pygame.K_q]: mouse_delta = Vec2d(-1, 1) if pressed[pygame.K_w]: mouse_delta = Vec2d(0, 1) if pressed[pygame.K_e]: mouse_delta = Vec2d(1, 1) if pressed[pygame.K_d]: mouse_delta = Vec2d(1, 0) if pressed[pygame.K_x]: mouse_delta = Vec2d(1, -1) if pressed[pygame.K_s]: mouse_delta = Vec2d(0, -1) if pressed[pygame.K_z]: mouse_delta = Vec2d(-1, -1) if mouse_delta.get_length_sqrd() > 0: if abs((tank_body.angle - mouse_delta.angle) % pi) < abs( (tank_body.angle - (mouse_delta.angle + pi) % pi)): tank_control_body.angle = mouse_delta.angle active_rotation_vector = tank_body.rotation_vector else: tank_control_body.angle = (mouse_delta.angle + pi) % pi active_rotation_vector = tank_body.rotation_vector.cpvrotate( Vec2d(-1, 0)) if mouse_delta.dot(active_rotation_vector) > 0.0: direction = 1.0 else: direction = -1.0 dv = Vec2d(30.0 * direction, 0.0) tank_control_body.velocity = active_rotation_vector.cpvrotate(dv) else: tank_control_body.angle = tank_body.angle tank_control_body.velocity = 0, 0 space.step(dt)
def pm_randomise_pose( space, bodies, arena_lrbt, rng, rand_pos=True, rand_rot=True, rel_pos_linf_limit=None, rel_rot_limit=None, ignore_shapes=None, rejection_tests=(), ): r"""Do rejection sampling to choose a position and/or orientation which ensures the given bodies and their attached shapes do not collide with any other collidable shape in the space, while still falling entirely within arena_xyhw. Note that position/orientation will be chosen in terms of the first body in the given list of bodies, then later bodies attached to it will be repositioned and rotated accordingly. Args: space (pm.Space): the space to place the given bodies in. bodies ([pm.Body]): a list of bodies to place. They should maintain the same relative positions and orientations. Usually you'll only need to pass one body, although passing multiple bodies can be useful when the bodies have a pin joint (e.g. the robot's body is attached to its fingers this way). arena_lrbt ([int]): bounding box to place the bodies in. rand_pos (bool or [bool]): should position be randomised? (optionally specified separately for each entity) rand_rot (bool or [bool]): should rotation be randomised? (optionally specified for each entity) rel_pos_linf_limit (float or [float]): bound on the $\ell_\infty$ distance between new sampled position and original position. (optionally specified per-entity) rel_rot_limit (float or [float]): maximum difference (in radians) between original main body orientation and new main body orientation. (optionally per-entity) rejection_tests ([(locals()) -> bool]): additional rejection tests to apply. If any one of these functions returns "True", then the shape pose will be rejected and re-sampled. Useful for, e.g., ensuring that placed shapes do not coincide with certain existing objects. Returns (int): number of random placements attempted before finding a successful one.""" assert ( rand_pos or rand_rot ), "need to randomise at least one thing, or placement may be impossible" assert len(bodies) >= 1, "no bodies given (?)" main_body = bodies[0] # Need to compute coordinates of other bodies in frame of main body saved_positions = [Vec2d(body.position) for body in bodies] saved_angles = [float(body.angle) for body in bodies] orig_main_angle = float(main_body.angle) orig_main_pos = Vec2d(main_body.position) shape_set = set() for body in bodies: shape_set.update(body.shapes) if ignore_shapes is not None: ignore_set = set(ignore_shapes) else: ignore_set = set() arena_l, arena_r, arena_b, arena_t = arena_lrbt if rel_pos_linf_limit is not None: assert 0 <= rel_pos_linf_limit init_x, init_y = main_body.position pos_x_minmax = ( max(arena_l, init_x - rel_pos_linf_limit), min(arena_r, init_x + rel_pos_linf_limit), ) pos_y_minmax = ( max(arena_b, init_y - rel_pos_linf_limit), min(arena_t, init_y + rel_pos_linf_limit), ) else: pos_x_minmax = (arena_l, arena_r) pos_y_minmax = (arena_b, arena_t) if rel_rot_limit is not None: assert 0 <= rel_rot_limit rot_min = orig_main_angle - rel_rot_limit rot_max = orig_main_angle + rel_rot_limit else: rot_min = -np.pi rot_max = np.pi # If we exceed this many tries then fitting is probably impossible, or # impractically hard. We'll warn if we get anywhere close to that number. max_tries = 10000 warn_tries = int(max_tries / 10) n_tries = 0 while n_tries < max_tries: # generate random position if rand_pos: new_main_body_pos = Vec2d(rng.uniform(*pos_x_minmax), rng.uniform(*pos_y_minmax)) else: new_main_body_pos = orig_main_pos # generate random orientation if rand_rot: new_angle = rng.uniform(rot_min, rot_max) else: new_angle = orig_main_angle # apply new position/orientation to all bodies pm_shift_bodies(space, bodies, position=new_main_body_pos, angle=new_angle) # apply collision tests reject = False for shape in shape_set: query_result = space.shape_query(shape) collisions = set(r.shape for r in query_result) - ignore_set # reject if we have any (non-self-)collisions if len(collisions) > 0: reject = True break # apply custom rejection tests, if any if not reject: for rejection_test in rejection_tests: reject = reject or rejection_test(locals()) if reject: break if not reject: # if we get to here without rejecting, then this is a good # orientation break n_tries += 1 else: # reset original positions before raising exception for body, saved_pos, saved_angle in zip(bodies, saved_positions, saved_angles): body.position = saved_pos body.angle = saved_angle space.reindex_shapes_for_body(body) raise PlacementError( f"Could not place bodies {bodies} in space {space} after " f"{n_tries} attempts. rand_pos={rand_pos}, rand_rot={rand_rot}, " f"arena_lrbt={arena_lrbt}.") if n_tries > warn_tries: warnings.warn(f"Took {n_tries}>{warn_tries} samples to place shape.") return n_tries
def vector(angle): return Vec2d(math.cos(angle), math.sin(angle))
def run(self): firstClick = False start_time = -1 timer = 0 while True: fps = 60 dt = 1. / fps self.top.update() if self.running: for event in pygame.event.get(): if event.type == QUIT or \ event.type == KEYDOWN and (event.key in [K_ESCAPE, K_q]): self.running = False elif event.type == pygame.MOUSEBUTTONDOWN and event.button == 1 and firstClick: start_time = pygame.time.get_ticks() elif event.type == KEYDOWN and event.key == K_p: pygame.image.save(self.screen, "arrows.png") elif event.type == pygame.MOUSEBUTTONUP and event.button == 1 and firstClick and start_time != -1: end_time = pygame.time.get_ticks() diff = end_time - start_time power = max(min(diff, 1000), 10) * 1.5 impulse = power * Vec2d(1, 0) impulse.rotate(self.level.tank.get_arrow_angle()) self.flying_arrows.append(self.level.tank.fire_arrow(self.space,self.flying_arrows,impulse)) elif not firstClick and event.type == pygame.MOUSEBUTTONUP and event.button == 1: firstClick = True start_time = 0 keys = pygame.key.get_pressed() speed = 7 #if (keys[K_UP]): # cannon_body.position += Vec2d(0, 1) * speed #if (keys[K_DOWN]): # cannon_body.position += Vec2d(0, -1) * speed if (keys[K_LEFT]): self.level.moveTank(1 * speed) elif (keys[K_RIGHT]): self.level.moveTank(-1 * speed) else: self.level.moveTank(0) self.level.update_level(self.space,self.get_mouse_pos()) # for flying_arrow in self.flying_arrows: # drag_constant = 0.0002 # # pointing_direction = Vec2d(1, 0).rotated(flying_arrow.angle) # flight_direction = Vec2d(flying_arrow.velocity) # flight_speed = flight_direction.normalize_return_length() # dot = flight_direction.dot(pointing_direction) # # (1-abs(dot)) can be replaced with (1-dot) to make arrows turn # # around even when fired straight up. Might not be as accurate, but # # maybe look better. # drag_force_magnitude = (1 - abs(dot)) * (flight_speed ** 2) * drag_constant * flying_arrow.mass # arrow_tail_position = Vec2d(-50, 0).rotated(flying_arrow.angle) # if drag_force_magnitude > -.5: # drag_force_magnitude = .5 # flying_arrow.apply_impulse_at_world_point(drag_force_magnitude * -flight_direction, # arrow_tail_position) # print("NEW ARROW") # print(arrow_tail_position) # print( str(drag_force_magnitude )+ " * -" + str(flight_direction) + " = " + str(drag_force_magnitude * -flight_direction)) # print("END ARROW") # # flying_arrow.angular_velocity *= 0.5 self.screen.fill(pygame.color.THECOLORS["lightgrey"]) self.space.debug_draw(self.draw_options) self.level.write_to_screen(self.screen) current_time = pygame.time.get_ticks() if pygame.mouse.get_pressed()[0] and firstClick: diff = current_time - start_time power = max(min(diff, 1000), 10) h = power / 2 pygame.draw.line(self.screen, pygame.color.THECOLORS["red"], (30, 550), (30, 550 - h), 10) self.screen.blit(pygame.font.SysFont("Arial", 16).render("Power: " + str(max(min(current_time - start_time, 1000), 10)/10) + "%", 1, THECOLORS["black"]), (10, 10)) self.screen.blit( pygame.font.SysFont("Arial", 16).render("Angle: " + str(self.level.tank.get_arrow_angle()*57.2958)[0:6] + "°", 1, THECOLORS["black"]), (self.level.tank.get_cannon_body_position()[0], 2*self.h - self.level.tank.get_cannon_body_position()[1])) if not firstClick: self.screen.blit(pygame.font.SysFont("Arial-bold", 73).render("CLICK TO BEGIN", 1, THECOLORS["black"]), (self.w*1.15, self.h/2)) pygame.display.flip() self.space.step(dt) timer += current_time - start_time else: firstClick = False start_time = -1 self.clock.tick(fps)
def get_mouse_pos(self): return pymunk.pygame_util.from_pygame(Vec2d(pygame.mouse.get_pos()), self.screen)
def main(): ### PyGame init pygame.init() screen = pygame.display.set_mode((width, height)) clock = pygame.time.Clock() running = True font = pygame.font.SysFont("Arial", 16) # sound = pygame.mixer.Sound("sfx.wav") img = pygame.image.load("ironman.png") ### Physics stuff space = pymunk.Space() space.gravity = 0, -1000 draw_options = pymunk.pygame_util.DrawOptions(screen) # box walls static = [ pymunk.Segment(space.static_body, (10, 50), (300, 50), 3), pymunk.Segment(space.static_body, (300, 50), (325, 50), 3), pymunk.Segment(space.static_body, (325, 50), (350, 50), 3), pymunk.Segment(space.static_body, (350, 50), (375, 50), 3), pymunk.Segment(space.static_body, (375, 50), (680, 50), 3), pymunk.Segment(space.static_body, (680, 50), (680, 370), 3), pymunk.Segment(space.static_body, (680, 370), (10, 370), 3), pymunk.Segment(space.static_body, (10, 370), (10, 50), 3) ] static[1].color = pygame.color.THECOLORS['red'] static[2].color = pygame.color.THECOLORS['green'] static[3].color = pygame.color.THECOLORS['red'] # rounded shape rounded = [ pymunk.Segment(space.static_body, (500, 50), (520, 60), 3), pymunk.Segment(space.static_body, (520, 60), (540, 80), 3), pymunk.Segment(space.static_body, (540, 80), (550, 100), 3), pymunk.Segment(space.static_body, (550, 100), (550, 150), 3) ] # static platforms platforms = [ pymunk.Segment(space.static_body, (170, 50), (270, 150), 3) #, pymunk.Segment(space.static_body, (270, 100), (300, 100), 5) , pymunk.Segment(space.static_body, (400, 150), (450, 150), 3), pymunk.Segment(space.static_body, (400, 200), (450, 200), 3), pymunk.Segment(space.static_body, (220, 200), (300, 200), 3), pymunk.Segment(space.static_body, (50, 250), (200, 250), 3), pymunk.Segment(space.static_body, (10, 370), (50, 250), 3) ] for s in static + platforms + rounded: s.friction = 1. s.group = 1 space.add(static, platforms + rounded) # moving platform platform_path = [(650, 100), (600, 200), (650, 300)] platform_path_index = 0 platform_body = pymunk.Body(body_type=pymunk.Body.KINEMATIC) platform_body.position = 650, 100 s = pymunk.Segment(platform_body, (-25, 0), (25, 0), 5) s.friction = 1. s.group = 1 s.color = pygame.color.THECOLORS["blue"] space.add(s) # pass through platform passthrough = pymunk.Segment(space.static_body, (270, 100), (320, 100), 5) passthrough.color = pygame.color.THECOLORS["yellow"] passthrough.friction = 1. passthrough.collision_type = 2 passthrough.filter = pymunk.ShapeFilter(categories=0b1000) space.add(passthrough) def passthrough_handler(arbiter, space, data): if arbiter.shapes[0].body.velocity.y < 0: return True else: return False space.add_collision_handler(1, 2).begin = passthrough_handler # player body = pymunk.Body(5, pymunk.inf) body.position = 100, 100 head = pymunk.Circle(body, 10, (0, 5)) head2 = pymunk.Circle(body, 10, (0, 13)) feet = pymunk.Circle(body, 10, (0, -5)) # Since we use the debug draw we need to hide these circles. To make it # easy we just set their color to black. feet.color = 0, 0, 0, 0 head.color = 0, 0, 0, 0 head2.color = 0, 0, 0, 0 mask = pymunk.ShapeFilter.ALL_MASKS ^ passthrough.filter.categories sf = pymunk.ShapeFilter(mask=mask) head.filter = sf head2.filter = sf feet.collision_type = 1 feet.ignore_draw = head.ignore_draw = head2.ignore_draw = True space.add(body, head, feet, head2) direction = 1 remaining_jumps = 2 landing = {'p': Vec2d.zero(), 'n': 0} frame_number = 0 landed_previous = False while running: grounding = { 'normal': Vec2d.zero(), 'penetration': Vec2d.zero(), 'impulse': Vec2d.zero(), 'position': Vec2d.zero(), 'body': None } # find out if player is standing on ground def f(arbiter): n = -arbiter.contact_point_set.normal if n.y > grounding['normal'].y: grounding['normal'] = n grounding['penetration'] = -arbiter.contact_point_set.points[ 0].distance grounding['body'] = arbiter.shapes[1].body grounding['impulse'] = arbiter.total_impulse grounding['position'] = arbiter.contact_point_set.points[ 0].point_b body.each_arbiter(f) well_grounded = False if grounding['body'] != None and abs( grounding['normal'].x / grounding['normal'].y) < feet.friction: well_grounded = True remaining_jumps = 2 ground_velocity = Vec2d.zero() if well_grounded: ground_velocity = grounding['body'].velocity for event in pygame.event.get(): if event.type == QUIT or \ event.type == KEYDOWN and (event.key in [K_ESCAPE, K_q]): running = False elif event.type == KEYDOWN and event.key == K_p: pygame.image.save(screen, "platformer.png") elif event.type == KEYDOWN and event.key == K_UP: if well_grounded or remaining_jumps > 0: jump_v = math.sqrt(2.0 * JUMP_HEIGHT * abs(space.gravity.y)) impulse = (0, body.mass * (ground_velocity.y + jump_v)) body.apply_impulse_at_local_point(impulse) remaining_jumps -= 1 elif event.type == KEYUP and event.key == K_UP: body.velocity.y = min(body.velocity.y, JUMP_CUTOFF_VELOCITY) # Target horizontal velocity of player target_vx = 0 if body.velocity.x > .01: direction = 1 elif body.velocity.x < -.01: direction = -1 keys = pygame.key.get_pressed() if (keys[K_LEFT]): direction = -1 target_vx -= PLAYER_VELOCITY if (keys[K_RIGHT]): direction = 1 target_vx += PLAYER_VELOCITY if (keys[K_DOWN]): direction = -3 feet.surface_velocity = -target_vx, 0 if grounding['body'] != None: feet.friction = -PLAYER_GROUND_ACCEL / space.gravity.y head.friction = HEAD_FRICTION else: feet.friction, head.friction = 0, 0 # Air control if grounding['body'] == None: body.velocity = Vec2d( cpflerpconst(body.velocity.x, target_vx + ground_velocity.x, PLAYER_AIR_ACCEL * dt), body.velocity.y) body.velocity.y = max(body.velocity.y, -FALL_VELOCITY) # clamp upwards as well? # Move the moving platform destination = platform_path[platform_path_index] current = Vec2d(platform_body.position) distance = current.get_distance(destination) if distance < PLATFORM_SPEED: platform_path_index += 1 platform_path_index = platform_path_index % len(platform_path) t = 1 else: t = PLATFORM_SPEED / distance new = current.interpolate_to(destination, t) platform_body.position = new platform_body.velocity = (new - current) / dt ### Clear screen screen.fill(pygame.color.THECOLORS["black"]) ### Helper lines for y in [50, 100, 150, 200, 250, 300]: color = pygame.color.THECOLORS['darkgrey'] pygame.draw.line(screen, color, (10, y), (680, y), 1) ### Draw stuff space.debug_draw(draw_options) direction_offset = 48 + (1 * direction + 1) // 2 * 48 if grounding['body'] != None and abs(target_vx) > 1: animation_offset = 32 * (frame_number // 8 % 4) elif grounding['body'] is None: animation_offset = 32 * 1 else: animation_offset = 32 * 0 position = body.position + (-16, 28) p = pymunk.pygame_util.to_pygame(position, screen) screen.blit(img, p, (animation_offset, direction_offset, 32, 48)) # Did we land? if abs(grounding['impulse'].y ) / body.mass > 200 and not landed_previous: # sound.play() landing = {'p': grounding['position'], 'n': 5} landed_previous = True else: landed_previous = False if landing['n'] > 0: p = pymunk.pygame_util.to_pygame(landing['p'], screen) pygame.draw.circle(screen, pygame.color.THECOLORS['yellow'], p, 5) landing['n'] -= 1 # Info and flip screen screen.blit( font.render("fps: " + str(clock.get_fps()), 1, THECOLORS["white"]), (0, 0)) screen.blit( font.render( "Move with Left/Right, jump with Up, press again to double jump", 1, THECOLORS["darkgrey"]), (5, height - 35)) screen.blit( font.render("Press ESC or Q to quit", 1, THECOLORS["darkgrey"]), (5, height - 20)) screen.blit(img, p, (animation_offset, direction_offset, 32, 48)) pygame.display.update() frame_number += 1 ### Update physics space.step(dt) clock.tick(fps)
def flip_y(vector, y): return Vec2d(int(vector.x), int(-vector.y + y))
def __init__(self, config, group=1): """Create a car. config -- car properties, big dictionary, big mess position -- position in pymunk world coords group -- car collision group, every car should """ position = config["position"] self.on_screen = [] self._to_space = [] self.motor_power = 0 shape_filter = pymunk.ShapeFilter(group) position = Vec2d(*position) tw = config["front_wheels_x"] th = config["front_wheels_y"] bw = config["back_wheels_x"] bh = config["back_wheels_y"] wheel_c = ( config["wheel_radius"], config["wheel_width"], config["wheel_mass"], config["wheel_slipforce"], config["wheel_friction_force"], config["wheel_side_friction"], config["wheel_weird_forward_friction"]) self._wheels = [ Wheel(*wheel_c, position + Vec2d(-tw, -th), shape_filter), Wheel(*wheel_c, position + Vec2d(+tw, -th), shape_filter), Wheel(*wheel_c, position + Vec2d(-bw, +bh), shape_filter), Wheel(*wheel_c, position + Vec2d(+bw, +bh), shape_filter), ] for wheel in self._wheels: self._to_space.extend(wheel._to_space) self.width = config["car_width"] self.height = config["car_height"] self.mass = config["car_mass"] self.max_steer_angle = config["max_steer_angle"] self.max_speed = config["max_speed"] self.max_power = config["max_power"] moment = pymunk.moment_for_box(self.mass, (self.width, self.height)) self.body = pymunk.Body(self.mass, moment) self.body.position = position w, h = self.width, self.height self.shape = pymunk.Poly( self.body, [ (-self.width/2, -self.height/2), (self.width/2, -self.height/2), (self.width/2, self.height/2), (-self.width/2, self.height/2) ]) self.shape.friction = config["hull_friction"] self.shape.filter = shape_filter self._to_space.extend((self.body, self.shape)) def glue(b1, b2): """Bind two bodies together.""" c1 = pymunk.constraints.PinJoint( b1, b2, (0, 0), b1.position - position) c2 = pymunk.constraints.GearJoint(b1, b2, 0, 1) c1.collide_bodies = False c2.collide_bodies = False c1.error_bias = 0 c2.error_bias = 0.00001 self._to_space.extend((c1, c2)) return c2 self.lw_gearjoint = glue(self._wheels[0].body, self.body) self.rw_gearjoint = glue(self._wheels[1].body, self.body) glue(self._wheels[2].body, self.body) glue(self._wheels[3].body, self.body) self.sensors = [] for sensor_config in config["sensors"]: sens = DistanceSensor( self.body, **sensor_config, shape_filter=shape_filter) self.sensors.append(sens) self._to_space.extend(sens._to_space)
def _create_objects(self): for y, row in enumerate(self.layout.tolist()): for x, object_type in enumerate(row): object_position = flip_y(vector=Vec2d( self.obj_size * (x + 0.5), self.obj_size * (y + 0.5)), y=self.screen.get_size()[1]) if object_type == 0: body, points = create_rectangle_body( mass=1000000, body_type=Body.STATIC, half_size=self.obj_size * 0.5) body.position = Vec2d(object_position) shape = create_rectangle_shape( body=body, points=points, friction=0, elasticity=0, collision_type=self.obstacle_collision, sensor=False) elif object_type == 2: body, points = create_rectangle_body( mass=1000000, body_type=Body.STATIC, half_size=self.obj_size * 0.5) body.position = Vec2d(object_position) shape = create_rectangle_shape( body=body, points=points, friction=0, elasticity=0, collision_type=self.goal_collision, sensor=True) elif object_type == 4: body, points = create_rectangle_body( mass=1, body_type=Body.DYNAMIC, half_size=self.obj_size * 0.5) body.position = Vec2d(object_position) shape = create_rectangle_shape( body=body, points=points, friction=0, elasticity=0, collision_type=self.block_collision, sensor=False) elif object_type == 5: body = create_circle_body(mass=1, body_type=Body.DYNAMIC, radius=self.obj_size * 0.5) body.position = Vec2d(object_position) shape = create_circle_shape( body=body, radius=self.obj_size * 0.5, friction=0, elasticity=0, collision_type=self.player_collision, sensor=False) else: continue self.space.add(body) self.space.add(shape)
def do_event(self, event): if event.type == QUIT: self.running = False elif event.type == KEYDOWN: if event.key in (K_q, K_ESCAPE): self.running = False keys = { K_LEFT: (-1, 0), K_RIGHT: (1, 0), K_UP: (0, 1), K_DOWN: (0, -1) } if event.key in keys: v = Vec2d(keys[event.key]) if self.active_shape != None: v.normalized() self.active_shape.body.apply_impulse_at_world_point( v * 50000, point=self.active_shape.body.position) if event.key == K_h: if self.gravity: self.space.gravity = 0, 0 else: self.space.gravity = 0, -900 if event.key == K_r: self.space.remove(self.space.constraints + self.space.shapes) self.startTime = time.time() self.run() if event.key == K_c: p = from_pygame(pygame.mouse.get_pos(), self.screen) new_circle = Circle(p, space=self.space, color=RED, radius=20).shape dist, info = new_circle.point_query(p) if dist < 0: self.active_shape = new_circle elif event.type == MOUSEBUTTONDOWN: p = from_pygame(event.pos, self.screen) self.active_shape = None for s in self.space.shapes: dist, info = s.point_query(p) if dist < 0: self.active_shape = s self.pulling = True s.body.angle = (p - s.body.position).angle if K_z: self.selected_shapes.append(s) else: self.selected_shapes = [] elif event.type == MOUSEMOTION: self.p = event.pos elif event.type == MOUSEBUTTONUP: if self.pulling: self.pulling = False b = self.active_shape.body p0 = Vec2d(b.position) p1 = from_pygame(event.pos, self.screen) impulse = 100 * Vec2d(p0 - p1).rotated(-b.angle) b.apply_impulse_at_local_point(impulse) pass
def main(): sys.setrecursionlimit(10000) if False: plot_data_x = [] plot_data_y = [] for angle in np.linspace(0.0, math.pi * 2.0, 500): plot_data_x.append(angle) plot_data_y.append( stats.norm.pdf(angle, math.pi / 4.0, math.pi / 16.0) + stats.norm.pdf(angle, math.pi / 4.0 + math.pi, math.pi / 16.0)) plt.plot(plot_data_x, plot_data_y) plt.text(math.pi / 4.0, stats.norm.pdf(0, 0, math.pi / 16.0), "A") plt.text(math.pi / 4.0 + math.pi, stats.norm.pdf(0, 0, math.pi / 16.0), "B") plt.show() exit(0) width, height = 690, 600 ### PyGame init pygame.init() screen = pygame.display.set_mode((width, height)) clock = pygame.time.Clock() running = True font = pygame.font.SysFont("Arial", 16) ### Physics stuff space = pymunk.Space() # space.gravity = 0,-1000 draw_options = pymunk.pygame_util.DrawOptions(screen) # walls - the left-top-right walls static = [ pymunk.Segment(space.static_body, (50, 50), (50, 550), 5), pymunk.Segment(space.static_body, (50, 550), (650, 550), 5), pymunk.Segment(space.static_body, (650, 550), (650, 50), 5), pymunk.Segment(space.static_body, (50, 50), (650, 50), 5) # ,pymunk.Segment(space.static_body, (323, 134), (566, 130), 5) # ,pymunk.Segment(space.static_body, (566, 130), (532, 367), 5) ] # b2 = pymunk.Body(body_type=pymunk.Body.KINEMATIC) # static.append(pymunk.Circle(b2, 30)) # b2.position = 300,400 static.append(pymunk.Circle(space.static_body, 30, (300, 400))) for s in static: s.friction = 1. s.group = 1 space.add(static) # cab = ModelCabinet(200, 100, (200,200), 0.0) cab = ModelCabinet(200, 100, Vec2d(200, 200), -0.05) cab.addToSpace(space) # robot rob = ModelRobot(Vec2d(100, 100), 0.0) # rob = ModelRobot( Vec2d(270,100), -math.pi/2.0 ) # rob = ModelRobot( Vec2d(180,200), -math.pi/2.0 ) #rob = ModelRobot( Vec2d(200,230), math.pi/2.0 ) rob.addToSpace(space) #createSpatialModelForBody(rob.robot_body) #rob_position_map = Vec2d(int(rob.robot_body.position[0]*100.0/width), int(rob.robot_body.position[1]*100.0/height)) space_map = SpaceMap() #space_map.build( space, rob_position_map, (0, width), 100, (0, height), 100 ) space_map.build(space, rob.robot_body.position, (0, width), 100, (0, height), 100) space_map.calculateShortcuts() #space_map.plotGraph() #plt.show() # wyznaczenie punktow kontaktu i odpowiadajacych im kierunkow dzialania sily # exit(0) #TODO: #space.point_query_nearest(mouse_pos, pymunk.inf, pymunk.ShapeFilter()) # target for manual control control_mode = "target_pos" target = [rob.robot_body.position[0], rob.robot_body.position[1], 0.0] control_mode = "auto" #move_target = Vec2d(150,450) #move_target = Vec2d(200,230) print "rob.robot_body.position", rob.robot_body.position #print "move_target", move_target #move_target_map = Vec2d(int(move_target[0]*100.0/width), int(move_target[1]*100.0/height)) #space_map.setTarget(move_target) #path = space_map.findShortestPath(rob_position_map, move_target_map) #path = space_map.findShortestPath(rob.robot_body.position, move_target) #print path #space_map.plotTriangulation() #space_map.plotGraph() #space_map.plotPath(path) # plt.plot( [rob_position_map[0]], [rob_position_map[1]], "o" ) # plt.plot( [move_target_map[0]], [move_target_map[1]], "o" ) #plt.show() # exit(0) plan_idx = 0 plan = [ ("move_to", Vec2d(180, 200)), # plan = [ #("move_to", Vec2d(150,450)), ( "open_door", ) ] # provide information information = [ InformationSpatialMapRange((0, width), 100, (0, height), 100), # range and resolution of spatial map InformationRobotPose(rob.robot_body.position, rob.robot_body.angle), # current pose of robot InformationPerceptionSpace( space), # percepted environment (exact, full perception) InformationDestinationGeom(Vec2d(180, 200)), # target point for motion ] behaviors = [] b_spatial_map = BehaviorSpatialMap() new_inf = b_spatial_map.update(information) joinInformation(information, new_inf) # print len(information) # exit(0) first_behavior_iteration = True while running: for event in pygame.event.get(): if event.type == QUIT or \ event.type == KEYDOWN and (event.key in [K_ESCAPE, K_q]): running = False elif event.type == pygame.MOUSEBUTTONDOWN and event.button == 1: start_time = pygame.time.get_ticks() elif event.type == KEYDOWN and event.key == K_p: pygame.image.save(screen, "arrows.png") elif event.type == pygame.MOUSEBUTTONUP and event.button == 1: #TODO: remove end_time = pygame.time.get_ticks() diff = end_time - start_time power = max(min(diff, 1000), 10) * 1.5 impulse = power * Vec2d(1, 0) debug_info = [] # manual control if control_mode == "force": forceControl(rob.robot_body) elif control_mode == "target_pos": keys = pygame.key.get_pressed() if (keys[K_UP]): target[0] += math.cos(target[2]) target[1] += math.sin(target[2]) if (keys[K_DOWN]): target[0] -= math.cos(target[2]) target[1] -= math.sin(target[2]) if (keys[K_LEFT]): target[2] += 0.05 if (keys[K_RIGHT]): target[2] -= 0.05 lin_stiffness = 1000.0 lin_damping = 500.0 rot_stiffness = 10000.0 rot_damping = 8000.0 rob.robot_body.force = lin_stiffness * ( Vec2d(target[0], target[1]) - rob.robot_body.position ) - lin_damping * rob.robot_body.velocity rob.robot_body.torque = rot_stiffness * wrapAnglePI( target[2] - rob.robot_body.angle ) - rot_damping * rob.robot_body.angular_velocity elif control_mode == "auto": if plan_idx >= len(plan): lin_damping = 50.0 rot_damping = 800.0 rob.robot_body.force = -lin_damping * rob.robot_body.velocity rob.robot_body.torque = -rot_damping * rob.robot_body.angular_velocity elif plan[plan_idx][0] == "move_to": if (rob.robot_body.position - plan[plan_idx][1]).get_length() < 10.0: plan_idx += 1 first_behavior_iteration = True print "plan_idx", plan_idx else: if first_behavior_iteration: # initialize behavior space_map.setTarget(plan[plan_idx][1]) first_behavior_iteration = False # make predictions and extend the plan predicted_path = space_map.findShortestPath( rob.robot_body.position) tp = TaskTightPassages(rob, predicted_path, space_map) force, torque = space_map.getDrivingForce( None, rob, plan[plan_idx][1]) force *= 1000.0 torque *= 2000.0 lin_damping = 50.0 * 0.5 rot_damping = 800.0 # * 0.5 rob.robot_body.force = force - lin_damping * rob.robot_body.velocity rob.robot_body.torque = torque - rot_damping * rob.robot_body.angular_velocity elif plan[plan_idx][0] == "open_door": if first_behavior_iteration: first_behavior_iteration = False door_instance_info = cab.getLeftDoorInfo() clear_space = ClearSpace() clear_space.addClearPoint((Vec2d(200, 250), 50)) #clear_space.getOperations(space) exp_door = ExperienceDoor() target_open_angle = exp_door.getDestPosition( clear_space, door_instance_info) door_instance_info = cab.getLeftDoorInfo() if abs(door_instance_info.open_angle - target_open_angle) < 0.2: plan_idx += 1 first_behavior_iteration = True print "plan_idx", plan_idx push = exp_door.getPush(target_open_angle, door_instance_info, debug_info) #exp_door.predictLeftDoorMovement(target_open_angle, door_instance_info, debug_info) #TODO: pushing #push_loc = space_map.pushLocations( push, rob ) force, torque = space_map.getPushForce(push, rob, debug_info) lin_damping = 50.0 rot_damping = 800.0 rob.robot_body.force = 500.0 * force - lin_damping * rob.robot_body.velocity rob.robot_body.torque = 500.0 * torque - rot_damping * rob.robot_body.angular_velocity #loc = space_map.pushLocations(push, rob) #print loc #print push_loc[0][0], push_loc[0][1] #rob.debugVisPose(debug_info, push_loc[0][0], push_loc[0][1]) # print "plan_idx", plan_idx #cab.debugVis(debug_info) rob.debugVisQhull(debug_info) rob.debugVisPushing(debug_info) mouse_position = pymunk.pygame_util.from_pygame( Vec2d(pygame.mouse.get_pos()), screen) mouse_position_munk = MunkToGame(mouse_position, height) ### Clear screen screen.fill(pygame.color.THECOLORS["black"]) ### Draw stuff space.debug_draw(draw_options) # bounding circle for the robot #pygame.draw.circle(screen, pygame.color.THECOLORS["yellow"], MunkToGame(rob.robot_body.position.int_tuple, height), 42, 1) # draw target if control_mode == "target_pos": col_g = pygame.color.THECOLORS["green"] pygame.draw.circle( screen, col_g, MunkToGame((int(target[0]), int(target[1])), height), 10, 1) pygame.draw.line( screen, col_g, MunkToGame((int(target[0]), int(target[1])), height), MunkToGame((int(target[0] + 15 * math.cos(target[2])), int(target[1] + 15 * math.sin(target[2]))), height), 1) # draw debug info drawDebugInfo(screen, height, debug_info) # Power meter if pygame.mouse.get_pressed()[0]: current_time = pygame.time.get_ticks() diff = current_time - start_time power = max(min(diff, 1000), 10) h = power / 2 pygame.draw.line(screen, pygame.color.THECOLORS["red"], (30, 550), (30, 550 - h), 10) # Info and flip screen screen.blit( font.render("fps: " + str(clock.get_fps()), 1, THECOLORS["white"]), (0, 0)) screen.blit( font.render( "Mouse position (in world coordinates): " + str(mouse_position[0]) + "," + str(mouse_position[1]), 1, THECOLORS["darkgrey"]), (5, height - 35)) screen.blit( font.render("Press ESC or Q to quit", 1, THECOLORS["darkgrey"]), (5, height - 20)) pygame.display.flip() ### Update physics fps = 60 dt = 1. / fps space.step(dt) clock.tick(fps)
def generateStickman(self): """ Returns: joints (dictionary) - 2D dictionary of joints with the following keys: motor - motor body targetAngle (positive float) - angle to stop motion at motionType (string) - flexion or extension previousAngle (positive float) - previous angle of the joint flexionDirection (boolean) - +1 if flexion is clockwise and -1 if flexion is counter-clockwise extensionDirection (boolean) - +1 if extension is clockwise and -1 if extension is counter-clockwise limbs (dictionary) - 1D dictionary. Key is limb name and value is limb body """ # In the json file, the format for limbs is --> "limb": [angle, length, mass]. # The head has format --> "head": [radius, mass] self.theta = self.theta - self.lean self.maxLegAngles = [0, np.pi / 2] foot_index = -1 hand_index = 1 self.hand_index, self.foot_index = hand_index, foot_index self.maxLegAngles = [0, np.pi / 2] self.footPosition = self.swing['rod'][foot_index].position + self.botVec #Generate lower leg and knee self.lowerLegVector = self.dirVec("lowerLeg") self.lowerLeg = Segment(self.footPosition, self.lowerLegVector, self.limbMass("lowerLeg")) self.kneePosition = self.vectorSum(self.footPosition, self.lowerLegVector) self.footMotor = pymunk.SimpleMotor(b0, self.lowerLeg.body, 0) self.footMotor.collide_bodies = False self.space.add(self.footMotor) #Generate upper leg self.upperLegVector = self.dirVec("upperLeg") self.upperLeg = Segment(self.kneePosition, self.upperLegVector, self.limbMass("upperLeg")) self.knee = PivotJoint(self.lowerLeg.body, self.upperLeg.body, self.lowerLegVector) self.kneeMotor = pymunk.SimpleMotor(b0, self.upperLeg.body, 0) self.kneeMotor.collide_bodies = False self.space.add(self.kneeMotor) #Generate pelvis and torso self.pelvisPosition = self.vectorSum(self.kneePosition, self.upperLegVector) self.torsoVector = self.dirVec("torso") self.torso = Segment(self.pelvisPosition, self.torsoVector, self.limbMass("torso")) self.pelvis = PivotJoint(self.upperLeg.body, self.torso.body, self.upperLegVector) self.pelvisMotor = pymunk.SimpleMotor(b0, self.torso.body, 0) self.pelvisMotor.collide_bodies = False self.space.add(self.pelvisMotor) #Generate shoulder and upper arm self.shoulderPosition = self.vectorSum(self.pelvisPosition, self.torsoVector) self.upperArmVector = self.dirVec("upperArm") self.upperArm = Segment(self.shoulderPosition, self.upperArmVector, self.limbMass("upperArm")) self.shoulder = PivotJoint(self.torso.body, self.upperArm.body, self.torsoVector) self.shoulderMotor = pymunk.SimpleMotor(b0, self.upperArm.body, 0) self.shoulderMotor.collide_bodies = False space.add(self.shoulderMotor) #Generate elbow and lower arm self.elbowPosition = self.vectorSum(self.shoulderPosition, self.upperArmVector) self.lowerArmVector = self.getJointByNumber( hand_index).position - self.elbowPosition self.lowerArm = Segment(self.elbowPosition, self.lowerArmVector, self.limbMass("lowerArm")) self.elbow = PivotJoint(self.upperArm.body, self.lowerArm.body, self.upperArmVector) self.elbowMotor = pymunk.SimpleMotor(b0, self.lowerArm.body, 0) self.elbowMotor.collide_bodies = False #space.add(self.elbowMotor) #Generate head headRadius = self.config['squatStandConfig']["head"][0] headPosition = self.shoulderPosition + ( headRadius * Vec2d(np.sin(self.stickFigureAngle * np.pi / 180), -np.cos(self.stickFigureAngle * np.pi / 180))) self.head = Circle(headPosition, headRadius) self.headJoint = PivotJoint( self.torso.body, self.head.body, self.torsoVector + (headRadius * Vec2d(np.sin(self.stickFigureAngle * np.pi / 180), -np.cos(self.stickFigureAngle * np.pi / 180)))) #Attack stick figure to swing self.holdHand = PinJoint(self.lowerArm.body, self.getJointByNumber(hand_index), self.lowerArmVector) self.holdFoot = PinJoint(self.getJointByNumber(foot_index), self.lowerLeg.body, self.botVec) self.previousKneeAngle = None # Limbs self.limbs = { 'lowerLeg': self.lowerLeg, 'upperLeg': self.upperLeg, 'torso': self.torso, 'upperArm': self.upperArm, 'lowerArm': self.lowerArm } self.joints = { "knee": { "motor": self.kneeMotor, "targetAngle": None, "motionType": None, "previousAngle": None, "flexionDirection": -1, "extensionDirection": 1 }, "foot": { "motor": self.footMotor, "targetAngle": None, "motionType": None, "previousAngle": None, "extensionDirection": -1, "flexionDirection": 1 }, "pelvis": { "motor": self.pelvisMotor, "targetAngle": None, "motionType": None, "previousAngle": None, "extensionDirection": -1, "flexionDirection": 1 }, "shoulder": { "motor": self.shoulderMotor, "targetAngle": None, "motionType": None, "previousAngle": None, "extensionDirection": 1, "flexionDirection": -1 }, "elbow": { "motor": self.elbowMotor, "targetAngle": None, "motionType": None, "previousAngle": None, "extensionDirection": -1, "flexionDirection": 1 } } #If stickman is a ragdoll let stickman fall if self.config["environmentConfig"]["ragdollEnabled"]: for joint in self.joints.keys(): self.joints[joint]["motor"].max_force = 0 #Otherwise set max force of motors to high limit else: for joint in self.joints.keys(): self.joints[joint]["motor"].max_force = self.config[ "environmentConfig"]["motorMaxForce"]
def frame_step(self, action): reward = 0 if action == 0: # Turn left. self.car_body.angle -= .2 reward -= 500 elif action == 1: # Turn right. self.car_body.angle += .2 reward -= 3 elif action == 2: if self.velocity < 30: self.velocity += 2 reward += 5 elif action == 3: self.velocity -= 2 reward -= 3 else: reward += 5 #print("PREV: " + str(previous_location) previous_location = self.car_body.position[0], self.car_body.position[1] #print(dist_from_prev) driving_direction = Vec2d(1, 0).rotated(self.car_body.angle) self.car_body.velocity = self.velocity * driving_direction # Update the screen and stuff. screen.fill(THECOLORS["black"]) draw(screen, self.space) self.space.step(1./10) if draw_screen: pygame.display.flip() clock.tick() dist_from_prev = math.hypot(previous_location[0] - self.car_body.position[0], previous_location[1] - self.car_body.position[1]) # Get the current location and the readings there. x, y = self.car_body.position readings, walls = self.get_sonar_readings(x, y, self.car_body.angle) normalized_readings = [(x-20.0)/20.0 for x in readings] state = np.array([normalized_readings]) # Set the reward. # Car crashed when any reading == 1 if self.car_is_crashed2(walls): self.crashed = True reward = -1000 self.recover_from_crash(driving_direction) print("CRASHED 2222222") elif self.car_is_crashed(readings): self.crashed = True reward = -500 self.recover_from_crash(driving_direction) print("CRASHED 11111") elif dist_from_prev < 0.3: reward -= 300 else: # Higher readings are better, so return the sum. reward += -5 + int(self.sum_readings(readings) / 10) if self.velocity<0: reward -= 10 reward += self.velocity/5 self.num_steps += 1 return reward, state
def main(): # Some global variables used by many functions global DISPLAY_SURF, FPS_CLOCK, camera_x, camera_y, crash_sound, player_health, circle_shapes, lasers, planets, planet_shapes # Start up pygame settings pygame.mixer.pre_init(44100, -16, 1, 512) pygame.init() pygame.display.set_caption('Space Game') FPS_CLOCK = pygame.time.Clock() # Set up pymunk physics circle_shapes = [] lasers = [] # Create player body (space ship thing) player_body = pymunk.Body(mass=100, moment=pymunk.moment_for_circle(100, 0, 10)) player_shape = pymunk.Circle(player_body, 15) player_shape.friction = 0.5 player_shape.elasticity = 0.9 player_shape.color = color.THECOLORS['coral'] player_shape.collision_type = PLAYER circle_shapes.append(player_shape) # Create camera center body. This invisible body moves around to follow the player, and the camera is constantly # centered on it camera_body = pymunk.Body(mass=.00000001, moment=pymunk.moment_for_circle(1, 0, 3)) # Add bodies to space SPACE.add(player_shape) SPACE.add(player_body) SPACE.add(camera_body) player_body.position = (0, 0) camera_body.position = (0, 0) for i in range(100): planets.append(Planet(radius=random.randint(30, 60), mass=1000 - 1 * i)) planet_shapes.append(planets[i].shape) # Generate 1000 stars. These will be automatically added to the Star._stars list, and will replace themselves with # new stars if they exit the active zone for i in range(1000): pass Star(color=random.choice(list(color.THECOLORS.values())), size=0, on_screen=True) # Collision handling stuff player_planet_handler = SPACE.add_collision_handler(PLAYER, PLANET) player_planet_handler.post_solve = player_planet_collision laser_planet_handler = SPACE.add_collision_handler(LASER, PLANET) laser_planet_handler.begin = laser_planet_collision # ------------------------------------- Sound -------------------------------------------------------- # Play Music pygame.mixer.init(22100, -16, 2, 64) pygame.mixer.music.load('resources/punch-deck-feel-the-pulse.mp3') pygame.mixer.music.play(-1, 0.0) # Load sound effects crash_sound = pygame.mixer.Sound('resources/click.ogg') rocket_boost_sound = pygame.mixer.Sound('resources/rocket_boost.ogg') if not fun_mode: laser_sound = pygame.mixer.Sound('resources/laser.ogg') else: laser_sound = pygame.mixer.Sound('resources/fun_laser.ogg') # Create sound channels rocket_boost_channel: pygame.mixer.Channel = pygame.mixer.Channel(0) rocket_boost_channel.play(rocket_boost_sound, -1) # Play a sound but pause it, to be unpaused rocket_boost_channel.pause() # When the rocket is boosting # Initialize player values for fuel, health, etc. rocket_fuel = 100 player_health = 100 ammunition = 100 game_over_string = '' # Set the starting game mode, the menu game_mode = MENU title_font = pygame.font.Font('resources/Airstream.ttf', 64) button_font = pygame.font.Font('resources/Airstream.ttf', 24) start_button_rect = pygame.rect.Rect(WIN_WIDTH / 2 - 60, WIN_HEIGHT * (2 / 3), 120, 50) start_time = 0 # ------------------------------------ Game Loop --------------------------------------------------- while True: # Deal with events for event in pygame.event.get(): if event.type == pygame.QUIT: terminate() if event.type == pygame.KEYDOWN: if event.key == pygame.K_ESCAPE: terminate() if event.key == pygame.K_UP and game_mode == PLAY and rocket_fuel > 0: rocket_boost_channel.unpause() if event.key == pygame.K_SPACE: if game_mode == PLAY and ammunition > 0: laser_sound.stop() laser_sound.play() laser_body, laser_shape = create_player_ammunition(player_shape) lasers.append(laser_shape) SPACE.add(laser_body, laser_shape) ammunition -= 1 player_body.angular_velocity = 0 if event.type == pygame.KEYUP: if event.key == pygame.K_UP and game_mode == PLAY: rocket_boost_channel.pause() if event.type == pygame.MOUSEBUTTONDOWN: if game_mode==MENU and start_button_rect.collidepoint(*pygame.mouse.get_pos()): start_game_sound = pygame.mixer.Sound('resources/click_button.ogg') start_game_sound.play() game_mode = PLAY start_time = pygame.time.get_ticks() if game_mode == MENU: # Draw background DISPLAY_SURF.fill(color.Color(7, 0, 15, 255)) draw_objects(Star._stars) # Draw the menu button mouse_pos = pygame.mouse.get_pos() start_button_color = color.Color(0, 180, 255, 255) if start_button_rect.collidepoint(*mouse_pos) \ else color.Color(0, 100, 150, 255) pygame.draw.rect(DISPLAY_SURF, start_button_color, start_button_rect) pygame.draw.rect(DISPLAY_SURF, color.Color(160, 160, 160, 255), start_button_rect, 2) button_text = button_font.render('START', True, color.THECOLORS['black']) button_text_rect = button_text.get_rect() button_text_rect.center = start_button_rect.center DISPLAY_SURF.blit(button_text, button_text_rect) instructions_one_text = button_font.render('Fly with arrow keys, fire with spacebar.', True, color.THECOLORS['orange']) instructions_one_rect = instructions_one_text.get_rect() instructions_one_rect.center = (WIN_WIDTH/2, WIN_HEIGHT * 1/2) DISPLAY_SURF.blit(instructions_one_text, instructions_one_rect) instructions_two_text = button_font.render("Don't crash, and don't let fuel, time, or ammo run out!", True, color.THECOLORS['orange']) instructions_two_rect = instructions_two_text.get_rect() instructions_two_rect.center = (WIN_WIDTH / 2, WIN_HEIGHT * 1/2 + 35) DISPLAY_SURF.blit(instructions_two_text, instructions_two_rect) # Draw the title text title_text = title_font.render('Space Game', True, color.THECOLORS['white']) title_text_rect = title_text.get_rect() title_text_rect.center = (WIN_WIDTH/2, WIN_HEIGHT/3) DISPLAY_SURF.blit(title_text, title_text_rect) if game_mode == PLAY: '''This stuff is only to be run if the game is in "play" mode''' time_elapsed = round((pygame.time.get_ticks() - start_time)/1000) time_remaining = 60 - time_elapsed # React to held keys keys = pygame.key.get_pressed() if keys[K_UP]: # Provide forward force in direction the player is pointing if rocket_fuel > 0: player_body.apply_impulse_at_local_point(Vec2d(800, 0).rotated(-2 * player_body.angle)) rocket_fuel -= .25 if keys[K_LEFT]: player_body.angle -= .13 if keys[K_RIGHT]: player_body.angle += .13 # Check for game overs if rocket_fuel <= 0: rocket_fuel = 0 rocket_boost_channel.pause() game_mode = GAME_OVER game_over_string = 'Out of fuel!' pygame.mixer.music.stop() game_over_sound = pygame.mixer.Sound('resources/out_of_gas.ogg') game_over_sound.play() if player_health <= 0: player_health = 0 game_mode = GAME_OVER game_over_string = 'Your ship wrecked!' pygame.mixer.music.stop() game_over_sound = pygame.mixer.Sound('resources/crash.ogg') game_over_sound.play() if ammunition <= 0: ammunition = 0 game_mode = GAME_OVER game_over_string = 'Out of ammunition!' pygame.mixer.music.stop() game_over_sound = pygame.mixer.Sound('resources/out_of_ammo.ogg') game_over_sound.play() if time_remaining <= 0: game_mode = GAME_OVER game_over_string = "Time's up!" pygame.mixer.music.stop() game_over_sound = pygame.mixer.Sound('resources/times_up.ogg') game_over_sound.play() player_body.angular_velocity = 0 # Move the camera body and center the camera on it camera_body.velocity = player_body.velocity * .8 + (player_body.position - camera_body.position) * 2 center_camera_on(camera_body) # Check for stars going outside for star in Star._stars: star.update_pg_coords() # Draw stuff DISPLAY_SURF.fill(color.Color(7, 0, 15, 255)) draw_objects(Star._stars) draw_objects(planets) draw_lasers(lasers) draw_pymunk_circles(circle_shapes) draw_fuel(rocket_fuel) draw_health(player_health) draw_ammo(ammunition) # Draw timer/score box box_rectangle = Rect(0, 0, 200, 60) box_rectangle.center = (WIN_WIDTH/2, WIN_HEIGHT/10) pygame.draw.rect(DISPLAY_SURF, color.THECOLORS['black'], box_rectangle) pygame.draw.rect(DISPLAY_SURF, color.THECOLORS['white'], box_rectangle, 2) # Draw timer timer_text = button_font.render(str(time_remaining), True, color.THECOLORS['white']) timer_text_rect = timer_text.get_rect() timer_text_rect.center = (WIN_WIDTH/2, WIN_HEIGHT/12) DISPLAY_SURF.blit(timer_text, timer_text_rect) # Draw score score_text = button_font.render(str(score), True, color.THECOLORS['gray']) score_text_rect = score_text.get_rect() score_text_rect.center = (WIN_WIDTH/2, WIN_HEIGHT/12 + 25) DISPLAY_SURF.blit(score_text, score_text_rect) # Physics tick dt = 1. / FPS SPACE.step(dt) if game_mode == GAME_OVER: rocket_boost_sound.stop() # Display background DISPLAY_SURF.fill(color.Color(7, 0, 15, 255)) draw_objects(Star._stars) # Large "GAME OVER" text game_over_text = title_font.render('Game Over!', True, color.THECOLORS['white']) game_over_text_rect = game_over_text.get_rect() game_over_text_rect.center = (WIN_WIDTH / 2, WIN_HEIGHT / 3) DISPLAY_SURF.blit(game_over_text, game_over_text_rect) # Score score_text = title_font.render(str(score), True, color.THECOLORS['gray']) score_text_rect = score_text.get_rect() score_text_rect.center = (WIN_WIDTH/2, WIN_HEIGHT/2) DISPLAY_SURF.blit(score_text, score_text_rect) # Details on how the player lost loss_details_text = button_font.render(game_over_string, True, color.THECOLORS['white']) loss_details_text_rect = loss_details_text.get_rect() loss_details_text_rect.center = (WIN_WIDTH/2, WIN_HEIGHT * 2/3) DISPLAY_SURF.blit(loss_details_text, loss_details_text_rect) # Update display pygame.display.update() FPS_CLOCK.tick(FPS)
def move_obstacles(self): # Randomly move obstacles around. for obstacle in self.obstacles: speed = random.randint(1, 5) direction = Vec2d(1, 0).rotated(self.car_body.angle + random.randint(-2, 2)) obstacle.velocity = speed * direction
def move_humans(self): for human in self.humans: speed = random.randint(20, 200) human.human_shape.angle -= random.randint(-1, 1) direction = Vec2d(1, 0).rotated(human.human_shape.angle) human.velocity = speed * direction
def reset_body(self, pop, angle): self.is_crashed = False self.body.position = pop self.body.angle = angle self.body.velocity = Vec2d(0.0, self.velocity) self.body.angular_velocity = 0.0
def __init__( self, ground_friction: float = 0.1, cart_mass: float = 0.5, cart_dims: Vec2d = Vec2d(0.3, 0.2), pend_com: float = 0.6, pend_width: float = 0.1, pend_mass: float = 0.2, pend_moment: float = 0.001, # TODO: calculate with pymunk? ): super(InvPendulumState, self).__init__() # set up state # space self._space = pymunk.Space(threaded=True) self._space.gravity = G_CONST # populate space # ground filt = pymunk.ShapeFilter(group=1) self._ground = pymunk.Segment(self._space.static_body, (-4, -0.1), (4, -0.1), 0.1) # TODO remove magic numbers self._ground.friction = ground_friction self._ground.filter = filt self._space.add(self._ground) # cart cart_moment = pymunk.moment_for_box(cart_mass, cart_dims) self._cart_body = pymunk.Body(mass=cart_mass, moment=cart_moment) self._cart_body.position = (0.0, cart_dims.y / 2) self._cart_shape = pymunk.Poly.create_box(self._cart_body, cart_dims) self._cart_shape.friction = ground_friction self._space.add(self._cart_body, self._cart_shape) # pendulum arm and mass pend_dims = (pend_width, pend_com * 2) self._pend_body = pymunk.Body(mass=pend_mass, moment=pend_moment) self._pend_body.position = \ (self._cart_body.position.x, self._cart_body.position.y + (cart_dims.y / 2) + pend_com) self._pend_shape = pymunk.Poly.create_box(self._pend_body, pend_dims) self._pend_shape.filter = filt self._space.add(self._pend_body, self._pend_shape) # joint _joint_pos = self._cart_body.position + Vec2d(0, cart_dims.y / 2) joint = pymunk.constraint.PivotJoint(self._cart_body, self._pend_body, _joint_pos) joint.collide_bodies = False self._space.add(joint) # actuated and sensor variables self.force = ActuatorVariable(0.0) self.position = SensorVariable(self._cart_body.position.x) self.speed = SensorVariable(self._cart_body.velocity.x) # the angle should never exceed ~20 degrees self.angle = SensorVariable( self._pend_body.angle, sanity_check=lambda angle: np.abs(angle) < 0.34) self.ang_vel = SensorVariable(self._pend_body.angular_velocity)
def unpack_int(x, y): return Vec2d((x << 16) >> 3, -((y << 16) >> 3))
def move_cat(self): speed = random.randint(20, 200) self.cat_body.angle -= random.randint(-1, 1) direction = Vec2d(1, 0).rotated(self.cat_body.angle) self.cat_body.velocity = speed * direction
def dash(self): if self.cooldowns["dash"].ready(): self.cooldowns["dash"].use() self.change_state(DashState(self, 0.10)) def change_facing(self): self.facing_direction = self.move_direction if self.move_direction.x > 0: self.set_texture(0) elif self.move_direction.x < 0: self.set_texture(1) MOVE_MAP_PLAYER_1 = { arcade.key.W: Vec2d(0, 1), arcade.key.S: Vec2d(0, -1), arcade.key.A: Vec2d(-1, 0), arcade.key.D: Vec2d(1, 0), } KEY_MAP_PLAYER_1 = { arcade.key.SPACE: "shoot", arcade.key.LSHIFT: "dash", } KEY_MAP_PLAYER_2 = { arcade.key.PERIOD: "shoot", arcade.key.MINUS: "dash", }