def Car(packet, rigid_body_tick, jumped_last_frame, index, my_index, team_sign): ''' Gets the game info for a given car, and returns the values. Should be fed into a CarState object. ''' this_car = packet.game_cars[index] pos = Vec3(team_sign * this_car.physics.location.x, team_sign * this_car.physics.location.y, this_car.physics.location.z) pitch = this_car.physics.rotation.pitch yaw = this_car.physics.rotation.yaw if team_sign == -1: yaw = rotate_to_range(this_car.physics.rotation.yaw + pi, [-pi, pi]) roll = this_car.physics.rotation.roll rot = Orientation(pitch=pitch, yaw=yaw, roll=roll) vel = Vec3(team_sign * this_car.physics.velocity.x, team_sign * this_car.physics.velocity.y, this_car.physics.velocity.z) omega = Vec3(team_sign * this_car.physics.angular_velocity.x, team_sign * this_car.physics.angular_velocity.y, this_car.physics.angular_velocity.z) demo = this_car.is_demolished wheel_contact = this_car.has_wheel_contact supersonic = this_car.is_super_sonic jumped = this_car.jumped double_jumped = this_car.double_jumped boost = this_car.boost return CarState(pos=pos, rot=rot, vel=vel, omega=omega, demo=demo, wheel_contact=wheel_contact, supersonic=supersonic, jumped=jumped, double_jumped=double_jumped, boost=boost, jumped_last_frame=jumped_last_frame, index=index)
def follow_waypoints(game_info, starting_path, waypoint_list, waypoint_index, path_following_state): ''' This function will take a list of Vec3 waypoints and choose paths so that the bot goes through the points in a reasonably efficient way. Currently, it uses GroundTurn if the next two waypoints are roughly in the same direction, and it uses an ArcLineArc to line up the next two waypoints if not. ''' #TODO: upgrade turning radius calculations turn_radius = min_radius(1410) #The next two waypoints we're aiming for current_waypoint = waypoint_list[waypoint_index] next_waypoint = waypoint_list[(waypoint_index + 1) % len(waypoint_list)] #Find the direction between them and try to guess how far off we'll be to #see if we need an ArcLineArc. #TODO: Check if we can just always use ArcLineArc, with most being small turns? waypoint_pair_angle = atan2(next_waypoint.y - current_waypoint.y, next_waypoint.x - current_waypoint.x) delta_theta = abs( rotate_to_range(game_info.me.rot.yaw - waypoint_pair_angle, [-pi, pi])) theta = game_info.me.rot.yaw start_tangent = Vec3(cos(theta), sin(theta), 0) if path_following_state == None and delta_theta > pi / 3: #If we're not lined up well to go through the next two points, #do an ArcLineArc to be at a good angle #TODO: Choose between the four ArcLineArc options to minimize path length path_following_state = "First Arc" #Here we check which combination of turns is the shortest, and follow that path. #Later we might also check if we run into walls, the post, etc. #Maybe even decide based on actual strategical principles of the game o.O min_length = 100000 path = WaypointPath([current_waypoint], current_state=game_info.me) for sign_pair in [[1, 1], [1, -1], [-1, 1], [-1, -1]]: temp_path = ArcLineArc(start=game_info.me.pos, end=current_waypoint, start_tangent=start_tangent, end_tangent=next_waypoint - current_waypoint, radius1=sign_pair[0] * turn_radius, radius2=sign_pair[1] * turn_radius, current_state=game_info.me) if not temp_path.is_valid: print("Invalid Path") continue if temp_path.length < min_length: min_length = temp_path.length path = temp_path if type(path) == WaypointPath: print("WARNING: No ArcLineArc path chosen") ############################## elif path_following_state == "First Arc": path = ArcLineArc(start=game_info.me.pos, end=current_waypoint, start_tangent=start_tangent, end_tangent=next_waypoint - current_waypoint, radius1=turn_radius, radius2=turn_radius, current_state=game_info.me) if (game_info.me.pos - path.transition1).magnitude() < 150: path_following_state = "Switch to Line" ############################## elif path_following_state == "Switch to Line": #If we're on the first frame of the line segment, #match everything up accoringly, then go over to normal "Line" following path = LineArcPath(start=game_info.me.pos, start_tangent=start_tangent, end=starting_path.end, end_tangent=starting_path.end_tangent, radius=starting_path.radius2, current_state=game_info.me) path_following_state = "Line" ############################## elif path_following_state == "Line": path = LineArcPath(start=game_info.me.pos, end=starting_path.end, start_tangent=start_tangent, end_tangent=starting_path.end_tangent, radius=starting_path.radius, current_state=game_info.me) if (game_info.me.pos - path.transition).magnitude() < 150: path_following_state = "Switch to Arc" ############################## elif path_following_state == "Switch to Arc": path = ArcPath(start=starting_path.transition, start_tangent=starting_path.transition, end=starting_path.end, end_tangent=starting_path.end_tangent, radius=starting_path.radius, current_state=game_info.me) path_following_state = "Final Arc" ############################## elif path_following_state == "Final Arc": path = ArcPath(start=game_info.me.pos, start_tangent=start_tangent, end=starting_path.end, end_tangent=starting_path.end_tangent, radius=starting_path.radius, current_state=game_info.me) if (game_info.me.pos - path.end).magnitude() < 150: path_following_state = None ############################## else: #If we're facing the right way and not following another path, #just GroundTurn towards the target path_following_state == None path = WaypointPath([current_waypoint], current_state=game_info.me) if (game_info.me.pos - current_waypoint).magnitude() < 150: waypoint_index = (waypoint_index + 1) % len(waypoint_list) return path, path_following_state, waypoint_index
def Ball(packet, team_sign, state=None): #Packet is used for the current ball state in game. #State can be used instead to get a BallState object for a prediction in the future. if state == None: #Position x = packet.game_ball.physics.location.x y = packet.game_ball.physics.location.y z = packet.game_ball.physics.location.z pos = Vec3(team_sign * x, team_sign * y, z) #Rotation pitch = packet.game_ball.physics.rotation.pitch yaw = packet.game_ball.physics.rotation.yaw roll = packet.game_ball.physics.rotation.roll rot = Orientation(pitch=pitch, yaw=yaw, roll=roll) if team_sign == -1: rot = Orientation(pitch=pitch, yaw=rotate_to_range(yaw + pi, [-pi, pi]), roll=roll) #Velocity vx = packet.game_ball.physics.velocity.x vy = packet.game_ball.physics.velocity.y vz = packet.game_ball.physics.velocity.z vel = Vec3(team_sign * vx, team_sign * vy, vz) #Angular velocity omegax = packet.game_ball.physics.angular_velocity.x omegay = packet.game_ball.physics.angular_velocity.y omegaz = packet.game_ball.physics.angular_velocity.z omega = Vec3(team_sign * omegax, team_sign * omegay, omegaz) #Miscellaneous latest_touch = packet.game_ball.latest_touch hit_location = Vec3(team_sign * latest_touch.hit_location.x, team_sign * latest_touch.hit_location.y, latest_touch.hit_location.z) else: #Position x = state.x y = state.y z = state.z pos = Vec3(team_sign * x, team_sign * y, z) #Velocity velx = state.velx vely = state.vely velz = state.velz vel = Vec3(team_sign * vx, team_sign * vy, vz) #Rotation pitch = state.pitch yaw = state.yaw roll = state.roll rot = Orientation(pitch=pitch, yaw=yaw, roll=roll) if team_sign == -1: rot = Orientation(pitch=pitch, yaw=rotate_to_range(yaw + pi, [-pi, pi]), roll=roll) #Angular velocity omegax = state.omegax omegay = state.omegay omegaz = state.omegaz omega = Vec3(team_sign * omegax, team_sign * omegay, omegaz) return BallState(pos=pos, rot=rot, vel=vel, omega=omega, latest_touch=latest_touch, hit_location=hit_location)
def __init__(self, packet = None, hitboxes = None, index = None, team_sign = None, label = None, pos = None, rot = None, vel = None, omega = None, demo = None, wheel_contact = None, supersonic = None, jumped = None, double_jumped = None, boost = None, jumped_last_frame = None, hitbox_class = None): ''' Gets the game info for a given car, and returns the values. Should be fed into a CarState object. Never call directly: Only in GameState.__init__() or via CarState.copy_state() ''' if packet != None: this_car = packet.game_cars[index] self.pos = Vec3( team_sign*this_car.physics.location.x, team_sign*this_car.physics.location.y, this_car.physics.location.z ) yaw = this_car.physics.rotation.yaw if team_sign == -1: yaw = rotate_to_range(this_car.physics.rotation.yaw + pi, [-pi, pi]) pitch = this_car.physics.rotation.pitch roll = this_car.physics.rotation.roll self.rot = Orientation( pitch = pitch, yaw = yaw, roll = roll ) self.vel = Vec3( team_sign*this_car.physics.velocity.x, team_sign*this_car.physics.velocity.y, this_car.physics.velocity.z ) self.omega = Vec3( team_sign*this_car.physics.angular_velocity.x, team_sign*this_car.physics.angular_velocity.y, this_car.physics.angular_velocity.z ) self.demo = this_car.is_demolished self.wheel_contact = this_car.has_wheel_contact self.supersonic = this_car.is_super_sonic self.jumped = this_car.jumped self.double_jumped = this_car.double_jumped self.boost = this_car.boost self.hitbox_class = Hitbox(this_car) self.jumped_last_frame = jumped_last_frame self.index = index self.label = label else: self.pos = pos self.rot = rot self.vel = vel self.omega = omega self.demo = demo self.wheel_contact = wheel_contact self.supersonic = supersonic self.jumped = jumped self.double_jumped = double_jumped self.boost = boost self.index = index self.hitbox_class = hitbox_class self.jumped_last_frame = jumped_last_frame