class HalfFlip: def __init__(self, car): self.timer = 0 self.car = car self.direction = vec3(car.forward() * -1) self.target = self.direction * 1000 + self.car.location self.aerial_turn = AerialTurn(car) self.aerial_turn.target = look_at(self.direction, vec3(0, 0, 1)) self.controls = SimpleControllerState() self.finished = False def step(self, dt: float): self.controls = SimpleControllerState() self.aerial_turn.step(dt) aerial_turn_controls = self.aerial_turn.controls if self.timer < 0.7: self.controls.jump = True if 0.075 < self.timer < 0.1: self.controls.jump = False self.controls.pitch = (-1 if self.timer > 0.425 else 1) self.controls.roll = aerial_turn_controls.roll else: self.controls = aerial_turn_controls if (self.car.on_ground and self.timer > 0.25) or self.timer > 1.1: self.finished = True self.controls.boost = (dot(self.car.forward(), self.direction) > 0.8) self.timer += dt
class Hover: """ PD controller for hovering in the air """ P = 1.8 D = 2.5 def __init__(self, car: Car): self.turn = AerialTurn(car) self.target: vec3 = None self.car: Car = car self.up: vec3 = None self.controls: Input = Input() def step(self, dt): delta_target = self.target - self.car.position target_direction = normalize( vec3((delta_target[0]) * self.P - self.car.velocity[0] * self.D, (delta_target[1]) * self.P - self.car.velocity[1] * self.D, 1000)) self.turn.target = look_at(target_direction, self.up) self.turn.step(dt) self.controls = self.turn.controls self.controls.boost = 0 # tap boost to keep height if (delta_target[2] - self.car.velocity[2] * 0.5) > 0: self.controls.boost = 1
class AimDodge(Maneuver): def __init__(self, car: Car, duration: float, target: vec3): super().__init__(car) self.dodge = AirDodge(car, duration, target) self.turn = AerialTurn(car) self.turn.target = look_at(direction(car, target), vec3(0, 0, 1)) self.jump = self.dodge.jump self.target = target def step(self, dt): self.dodge.step(dt) self.controls = self.dodge.controls self.finished = self.dodge.finished if not self.dodge.jump.finished and not self.car.on_ground: target_direction = direction(self.car, self.target + vec3(0, 0, 100)) up = target_direction * (-1) up[2] = 1 up = normalize(up) self.turn.target = look_at(target_direction, up) self.turn.step(dt) self.controls.pitch = self.turn.controls.pitch self.controls.yaw = self.turn.controls.yaw self.controls.roll = self.turn.controls.roll
def __init__(self, car: Car, info: Game): self.turn = AerialTurn(car) self.target = None self.car: Car = car self.info: Game = info self.controls = Input() self.jump = False
def __init__(self, car: Car): super().__init__(car) self.landing = False self.aerial_turn = AerialTurn(self.car) self.trajectory: List[vec3] = [] self.landing_pos: Optional[vec3] = None
def __init__(self, car: Car, duration: float, target: vec3): super().__init__(car) self.dodge = AirDodge(car, duration, target) self.turn = AerialTurn(car) self.turn.target = look_at(direction(car, target), vec3(0, 0, 1)) self.jump = self.dodge.jump self.target = target
def __init__(self, car): self.timer = 0 self.car = car self.direction = vec3(car.forward() * -1) self.target = self.direction * 1000 + self.car.location self.aerial_turn = AerialTurn(car) self.aerial_turn.target = look_at(self.direction, vec3(0, 0, 1)) self.controls = SimpleControllerState() self.finished = False
def __init__(self, car: Car, jump_when_upside_down=True): super().__init__(car) self.jump_when_upside_down = jump_when_upside_down self.landing = False self.aerial_turn = AerialTurn(self.car) self.trajectory: List[vec3] = [] self.landing_pos: Optional[vec3] = None
def __init__(self, car: Car, info: GameInfo, target=None): self.drive = Drive(car) self.aerial_turn = AerialTurn(car) self.jumping = False self.time_for_jump = float("inf") self.timer = 0.0 super().__init__(car, info, target)
def rotate(self, car: Car, target: vec3, dt) -> SimpleControllerState: # up = vec3(*[self.car.theta[i, 2] for i in range(3)]) target_rotation = look_at(self.target, vec3(0, 0, 1)) action = AerialTurn(car) action.target = target_rotation action.step(dt) controls = action.controls return controls
def __init__(self, car): self.car = car self.target = vec3(0, 0, 0) self.speed = 2300 self.controls = SimpleControllerState() self.finished = False self.rlu_drive = RLUDrive(self.car) self.update_rlu_drive() self.power_turn = True # Handbrake while reversing to turn around quickly self.aerial_turn = AerialTurn(car) self.kickoff = False
def moving_ball_dodge_contact(game_info): ''' Returns dodge duration and delay so the car can reach contact_height ''' ball = game_info.ball contact_height = ball.pos.z - 20 hitbox_class = game_info.me.hitbox_class car_copy = RLU_Car(game_info.utils_game.my_car) turn = RLU_AerialTurn(car_copy) turn.target = roll_away_from_target(ball.pos, pi / 4, game_info) box = update_hitbox(car_copy, hitbox_class) time = 0 dt = 1 / 60 ball_contact = has_ball_contact(time, box, ball, game_info.team_sign) closest_point = ball_contact[1] while closest_point[2] < contact_height and not ball_contact[0]: time += dt ball = game_info.ball_prediction.state_at_time(game_info.game_time + time) turn.step(dt) contact_height = ball.pos.z - 30 controls = turn.controls if time <= 0.20: controls.jump = 1 controls.boost = 1 car_copy.step(controls, dt) box = update_hitbox(car_copy, hitbox_class) ball_contact = has_ball_contact(time, box, ball, game_info.team_sign) closest_point = ball_contact[1] if time >= 1.45: #Max dodge time return None, None, Simulation() if not ball_contact[0]: return None, None, Simulation() if time < 0.2: duration = time delay = duration + 2 * dt else: duration = 0.2 delay = time delay -= 0.05 #Window to dodge just before ball contact return duration, delay, Simulation(ball_contact=True, car=car_copy, hitbox=box, time=time)
def step(self, dt): car = self.car if self.phase == 1: if norm(car.velocity) > 1300: self.phase = 2 self.action = AirDodge(car, 0.05, car.position + car.velocity) if self.phase == 2: if car.on_ground and self.action.finished: self.action = self.drive self.phase = 3 if self.phase == 3: if distance(car, self.info.ball) < norm(car.velocity) * 0.4: # detect if an opponent is going for kickoff is_opponent_going_for_kickoff = False for opponent in self.info.opponents: if distance(self.info.ball, opponent) < 1500: is_opponent_going_for_kickoff = True if is_opponent_going_for_kickoff: self.phase = 4 self.action = AirDodge(car, 0.05, self.info.ball.position) else: self.phase = "anti-fake-kickoff" self.action = self.drive if self.phase == 4: if self.action.finished: self.action = AerialTurn(car) self.phase = 5 if self.phase == 5: self.action.target = look_at(self.info.my_goal.center, vec3(0, 0, 1)) self.action.controls.throttle = 1 if car.on_ground: self.finished = True # self.phase = 6 # self.action = DodgeShot(car, self.info, self.info.their_goal.center) if self.phase == 6: self.finished = self.action.finished if self.phase == "anti-fake-kickoff": self.drive.target_pos = vec3(80, 0, 0) self.finished = self.info.ball.position[1] != 0 self.action.step(dt) self.controls = self.action.controls
class FastRecovery(Maneuver): '''Boost down and try to land on all four wheels''' def __init__(self, car: Car): super().__init__(car) self.landing = False self.turn = AerialTurn(self.car) self.recovery = Recovery(self.car) def step(self, dt): self.controls.throttle = 1 # in case we're turtling if self.landing: self.recovery.step(dt) self.controls = self.recovery.controls else: landing_pos = self.find_landing_pos() landing_dir = direction(self.car, landing_pos - vec3(0,0,1000)) self.turn.target = look_at(landing_dir, vec3(0,0,1)) self.turn.step(dt) self.controls = self.turn.controls # boost down if angle_between(self.car.forward(), landing_dir) < 0.8: self.controls.boost = 1 else: self.controls.boost = 0 # when nearing landing position, start recovery if distance(self.car, landing_pos) < clamp(norm(self.car.velocity), 600, 2300): self.landing = True self.finished = self.car.on_ground def find_landing_pos(self, num_points=200, dt=0.0333) -> vec3: '''Simulate car falling until it hits a plane and return it's final position''' dummy = Car(self.car) for i in range(0, num_points): dummy.step(Input(), dt) dummy.time += dt n = Field.collide(sphere(dummy.position, 40)).direction if norm(n) > 0.0 and i > 10: return dummy.position return self.car.position def render(self, draw): if self.landing: self.recovery.render(draw)
class Recovery(Maneuver): ''' Wrapper for RLU recovery (in AerialTurn). Not actually used by Botimus, FastRecovery is better. ''' def __init__(self, car: Car): super().__init__(car) self.turn = AerialTurn(car) self.trajectory = [] def step(self, dt): self.find_landing_orientation(200) self.turn.step(dt) self.controls = self.turn.controls self.controls.throttle = 1 # in case we're turtling self.finished = self.car.on_ground def find_landing_orientation(self, num_points): f = vec3(0, 0, 0) l = vec3(0, 0, 0) u = vec3(0, 0, 0) dummy = Car(self.car) self.trajectory = [vec3(dummy.position)] found = False for i in range(0, num_points): dummy.step(Input(), 0.01633) self.trajectory.append(vec3(dummy.position)) u = Field.collide(sphere(dummy.position, 40)).direction if norm(u) > 0.0 and i > 40: f = normalize(dummy.velocity - dot(dummy.velocity, u) * u) l = normalize(cross(u, f)) found = True break if found: self.turn.target = mat3(f[0], l[0], u[0], f[1], l[1], u[1], f[2], l[2], u[2]) else: self.turn.target = self.car.orientation def render(self, draw: DrawingTool): draw.color(draw.cyan) draw.polyline(self.trajectory) draw.color(draw.green) draw.vector(self.car.position, facing(self.turn.target) * 200) draw.color(draw.red) draw.vector(self.car.position, self.car.forward() * 200)
def __init__(self, index: int, team: int): super().__init__() self.team = team self.id = index self.aerial_turn = AerialTurn(self) self.aerial = Aerial(self) self.hover = Hover(self)
def defending(agent): """"Method that gives output for the defending strategy""" target = defending_target(agent) agent.drive.target = target distance = distance_2d(agent.info.my_car.position, target) vf = velocity_forward(agent.info.my_car) dodge_overshoot = distance < (abs(vf) + 500) * 1.5 agent.drive.speed = get_speed(agent, target) agent.drive.step(agent.info.time_delta) agent.controls = agent.drive.controls t = time.time() can_dodge, simulated_duration, simulated_target = agent.simulate() # print(time.time() - t) if can_dodge: agent.dodge = Dodge(agent.info.my_car) agent.turn = AerialTurn(agent.info.my_car) agent.dodge.duration = simulated_duration - 0.1 agent.dodge.target = simulated_target agent.dodge.preorientation = look_at(simulated_target, vec3(0, 0, 1)) agent.timer = 0 agent.step = Step.Dodge if not agent.should_defend(): agent.step = Step.Shooting elif vf < -900 and (not dodge_overshoot or distance < 600): agent.step = Step.HalfFlip agent.halfflip = HalfFlip(agent.info.my_car) elif not dodge_overshoot and agent.info.my_car.position[2] < 80 and \ (agent.drive.speed > abs(vf) + 300 and 1200 < abs(vf) < 2000 and agent.info.my_car.boost <= 25): # Dodge towards the target for speed agent.step = Step.Dodge agent.dodge = Dodge(agent.info.my_car) agent.dodge.duration = 0.1 agent.dodge.target = target
def stationary_ball_dodge_contact(game_info, contact_height): ''' Returns dodge duration and delay so the car can reach contact_height ''' ball = game_info.ball hitbox_class = game_info.me.hitbox_class car_copy = RLU_Car(game_info.utils_game.my_car) turn = RLU_AerialTurn(car_copy) turn.target = roll_away_from_target(ball.pos, pi / 4, game_info) box = update_hitbox(car_copy, hitbox_class) time = 0 dt = 1 / 60 ball_contact = has_ball_contact(time, box, ball, game_info.team_sign) intended_contact_point = ball_contact[1] while intended_contact_point[2] < contact_height and not ball_contact[0]: time += dt turn.step(dt) controls = turn.controls if time <= 0.20: controls.jump = 1 controls.boost = 1 car_copy.step(controls, dt) box = update_hitbox(car_copy, hitbox_class) ball_contact = has_ball_contact(time, box, ball, game_info.team_sign) intended_contact_point = ball_contact[1] if time >= 1.45: #Max dodge time return None, None, Simulation() if not ball_contact[0]: return None, None, Simulation() if time < 0.2: duration = time delay = duration + 2 * dt else: duration = 0.2 delay = time delay -= 0.05 #How long before we hit the ball is acceptable to dodge return duration, delay, Simulation(ball_contact=True, car=car_copy, hitbox=box, time=time)
def setup_first_dodge(agent, duration, delay, target, preorientation): agent.dodge = Dodge(agent.info.my_car) agent.turn = AerialTurn(agent.info.my_car) agent.dodge.duration = duration agent.dodge.delay = delay agent.dodge.target = target agent.dodge.preorientation = preorientation agent.timer = 0.0 agent.step = Step.Dodge_1
def get_output(self, packet: GameTickPacket) -> SimpleControllerState: self.game.read_game_information(packet, self.get_rigid_body_tick(), self.get_field_info()) self.controls = SimpleControllerState() next_state = self.state if self.state == State.RESET: self.timer = 0.0 self.set_gamestate_straight_moving() # self.set_gamestate_angled_stationary() # self.set_gamestate_straight_moving_towards() next_state = State.WAIT if self.state == State.WAIT: if self.timer > 0.2: next_state = State.INITIALIZE if self.state == State.INITIALIZE: self.drive = Drive(self.game.my_car) self.drive.target, self.drive.speed = self.game.ball.location, 2300 next_state = State.DRIVING if self.state == State.DRIVING: self.drive.target = self.game.ball.location self.drive.step(self.game.time_delta) self.controls = self.drive.controls can_dodge, simulated_duration, simulated_target = self.simulate() if can_dodge: self.dodge = Dodge(self.game.my_car) self.turn = AerialTurn(self.game.my_car) print("============") print(simulated_duration) self.dodge.duration = simulated_duration - 0.1 self.dodge.target = simulated_target self.timer = 0 next_state = State.DODGING if self.state == State.DODGING: self.dodge.step(self.game.time_delta) self.controls = self.dodge.controls if self.game.time == packet.game_ball.latest_touch.time_seconds: print(self.timer) if self.dodge.finished and self.game.my_car.on_ground: next_state = State.RESET self.timer += self.game.time_delta self.state = next_state return self.controls
class AirHover(Maneuver): ''' Double jump of the ground and hover in the air at target position. Currently useless, but maybe future potential for air-dribbling? ''' P = 1.8 D = 2.5 def __init__(self, car: Car, target: vec3): super().__init__(car) self.turn = AerialTurn(car) self.target = target self.jump = AirDodge(car, 0.2) def step(self, dt): if not self.jump.finished: self.jump.step(dt) self.controls = self.jump.controls return delta_target = self.target - self.car.position target_direction = normalize( vec3((delta_target[0]) * self.P - self.car.velocity[0] * self.D, (delta_target[1]) * self.P - self.car.velocity[1] * self.D, 1000)) self.turn.target = look_at(target_direction, self.car.up()) self.turn.step(dt) self.controls = self.turn.controls self.controls.boost = 0 # tap boost to keep height if (delta_target[2] - self.car.velocity[2] * 0.5) > 0: self.controls.boost = 1 # boost so we don't fall while relocating if dot(self.car.forward(), vec3(0, 0, 1)) < 0.5: self.controls.boost = 1
class Hover: def __init__(self, car: Car, info: Game): self.turn = AerialTurn(car) self.target = None self.car: Car = car self.info: Game = info self.controls = Input() self.jump = False def step(self, dt): delta_target = self.target - self.car.position if norm(delta_target) > 500: delta_target = direction(self.car.position, self.target) * 500 target_direction = delta_target - self.car.velocity + vec3(0, 0, 500) self.turn.target = look_at(target_direction, direction(self.car.position, vec3(0, 0, 0))) self.turn.step(dt) self.controls = self.turn.controls self.controls.boost = delta_target[2] - self.car.velocity[2] * 0.5 > 0 and self.car.forward()[2] > 0.2 self.controls.throttle = not self.car.on_ground self.controls.jump = self.car.position[2] < 30 and self.info.time % 1.0 < 0.5
def setup(self): self.aerial = Aerial(self.agent.game.my_car) self.turn = AerialTurn(self.agent.game.my_car) myGoal = center = Vector([0, 5200 * sign(self.agent.team), 200]) enemyGoal = center = Vector([0, 5200 * -sign(self.agent.team), 200]) if self.agent.me.boostLevel > 0: for i in range(0, self.agent.ballPred.num_slices): targetVec = Vector([self.agent.ballPred.slices[i].physics.location.x, self.agent.ballPred.slices[i].physics.location.y, self.agent.ballPred.slices[i].physics.location.z]) # interferenceTimer += self.agent.deltaTime # if interferenceTimer < 1: # if findEnemyClosestToLocation(self.agent,targetVec)[1] < 150: # break if self.agent.ballPred.slices[i].physics.location.z >= 300: goalDist = distance2D(center, targetVec) #if distance2D(myGoal, targetVec) > distance2D(myGoal, self.agent.me.location): if self.agent.me.location[1] * sign(self.agent.team) > self.agent.ballPred.slices[i].physics.location.y * sign(self.agent.team): zOffset = 0 if goalDist < 1500: if targetVec[2] > 600: zOffset = 70 shotAngle = correctAngle(math.degrees(angle2(targetVec, enemyGoal)) + 90 * -sign(self.agent.team)) if abs(shotAngle) <=80: xOffset = clamp(80,-80,(shotAngle*2)*-sign(self.agent.team)) self.aerial.target = vec3(self.agent.ballPred.slices[i].physics.location.x+xOffset, self.agent.ballPred.slices[i].physics.location.y, self.agent.ballPred.slices[i].physics.location.z+zOffset) self.aerial.arrival_time = self.agent.ballPred.slices[i].game_seconds simulation = self.aerial.simulate() # # check if we can reach it by an aerial if norm(simulation.location - self.aerial.target) < 100: self.target_ball = self.agent.ballPred.slices[i] self.xOffset = xOffset self.zOffset = zOffset self.active = True break
def get_controls(self): """Decides what strategy to uses and gives corresponding output""" if self.step == Step.Steer or self.step == Step.Dodge_2 or self.step == Step.Dodge_1 or self.step == Step.Drive: print("GETCONTROLS") # self.time = 0 # self.set_state = True self.step = Step.Shooting if self.step == Step.Shooting: target = get_intersect(self, self.info.my_car) self.drive.target = target self.drive.step(self.info.time_delta) self.controls = self.drive.controls t = time.time() can_dodge, simulated_duration, simulated_target = self.simulate( self.their_goal.center) # print(time.time() - t) if can_dodge: self.dodge = Dodge(self.info.my_car) self.turn = AerialTurn(self.info.my_car) self.dodge.duration = simulated_duration - 0.1 self.dodge.direction = vec2(self.their_goal.center - simulated_target) target = vec3(vec2(self.their_goal.center)) + vec3( 0, 0, jeroens_magic_number * simulated_target[2]) self.dodge.preorientation = look_at(target - simulated_target, vec3(0, 0, 1)) self.step = Step.Dodge if self.should_defend(): self.step = Step.Defending elif not self.closest_to_ball or self.in_front_off_ball: self.step = Step.Rotating elif should_halfflip(self, target): self.step = Step.HalfFlip self.halfflip = HalfFlip(self.info.my_car) elif should_dodge(self, target): self.step = Step.Dodge self.dodge = Dodge(self.info.my_car) self.dodge.target = target self.dodge.duration = 0.1 elif self.step == Step.Rotating: target = 0.5 * (self.info.ball.position - self.my_goal.center) + self.my_goal.center self.drive.target = target self.drive.speed = 1410 self.drive.step(self.info.time_delta) self.controls = self.drive.controls in_position = not not_back(self.info.my_car.position, self.info.ball.position, self.my_goal.center) faster = self.closest_to_ball and in_position if len(self.teammates) == 0 and in_position: self.step = Step.Shooting elif len(self.teammates) == 1: teammate = self.info.cars[self.teammates[0]].position teammate_out_location = not_back(teammate, self.info.ball.position, self.my_goal.center) if teammate_out_location or faster: self.step = Step.Shooting elif len(self.teammates) == 2: teammate1 = self.info.cars[self.teammates[0]].position teammate2 = self.info.cars[self.teammates[0]].position teammate1_out_location = not_back(teammate1, self.info.ball.position, self.my_goal.center) teammate2_out_location = not_back(teammate2, self.info.ball.position, self.my_goal.center) if teammate1_out_location and teammate2_out_location: self.step = Step.Shooting elif (teammate1_out_location or teammate2_out_location) and faster or faster: self.step = Step.Shooting if self.should_defend(): self.step = Step.Defending elif should_halfflip(self, target): self.step = Step.HalfFlip self.halfflip = HalfFlip(self.info.my_car) elif should_dodge(self, target): self.step = Step.Dodge self.dodge = Dodge(self.info.my_car) self.dodge.target = target self.dodge.duration = 0.1 elif self.step == Step.Defending: defending(self) elif self.step == Step.Dodge or self.step == Step.HalfFlip: halfflipping = self.step == Step.HalfFlip if halfflipping: self.halfflip.step(self.info.time_delta) else: self.dodge.step(self.info.time_delta) if (self.halfflip.finished if halfflipping else self.dodge.finished) and self.info.my_car.on_ground: self.step = Step.Shooting else: self.controls = (self.halfflip.controls if halfflipping else self.dodge.controls) if not halfflipping: self.controls.boost = False self.controls.throttle = velocity_2d( self.info.my_car.velocity) < 500
class Recovery(Maneuver): """Boost down and try to land smoothly""" def __init__(self, car: Car, jump_when_upside_down=True): super().__init__(car) self.jump_when_upside_down = jump_when_upside_down self.landing = False self.aerial_turn = AerialTurn(self.car) self.trajectory: List[vec3] = [] self.landing_pos: Optional[vec3] = None def interruptible(self) -> bool: return False def step(self, dt): self.simulate_landing() self.aerial_turn.step(dt) self.controls = self.aerial_turn.controls self.controls.boost = angle_between(self.car.forward(), vec3( 0, 0, -1)) < 1.5 and not self.landing self.controls.throttle = 1 # in case we're turtling # jump if the car is upside down and has wheel contact if (self.jump_when_upside_down and self.car.on_ground and dot(self.car.up(), vec3(0, 0, 1)) < -0.95): self.controls.jump = True self.landing = False else: self.finished = self.car.on_ground def simulate_landing(self): pos = vec3(self.car.position) vel = vec3(self.car.velocity) grav = vec3(0, 0, -650) self.trajectory = [vec3(pos)] self.landing = False collision_normal: Optional[vec3] = None dt = 1 / 60 simulation_duration = 0.8 for i in range(int(simulation_duration / dt)): pos += vel * dt vel += grav * dt if norm(vel) > 2300: vel = normalize(vel) * 2300 self.trajectory.append(vec3(pos)) collision_sphere = sphere(pos, 50) collision_ray = Field.collide(collision_sphere) collision_normal = collision_ray.direction if (norm(collision_normal) > 0.0 or pos[2] < 0) and i > 20: self.landing = True self.landing_pos = pos break if self.landing: u = collision_normal f = normalize(vel - dot(vel, u) * u) l = normalize(cross(u, f)) self.aerial_turn.target = three_vec3_to_mat3(f, l, u) else: target_direction = normalize( normalize(self.car.velocity) - vec3(0, 0, 3)) self.aerial_turn.target = look_at(target_direction, vec3(0, 0, 1)) def render(self, draw: DrawingTool): if self.landing: draw.color(draw.cyan) draw.polyline(self.trajectory) if self.landing_pos: draw.crosshair(self.landing_pos) draw.color(draw.green) draw.vector(self.car.position, forward(self.aerial_turn.target) * 200) draw.color(draw.red) draw.vector(self.car.position, self.car.forward() * 200)
def setup(self): self.aerial = Aerial(self.agent.game.my_car) self.turn = AerialTurn(self.agent.game.my_car) myGoal = center = Vector([0, 5120 * sign(self.agent.team), 200]) enemyGoal = center = Vector([0, 5120 * -sign(self.agent.team), 200]) aboveThreshold = False if self.agent.me.boostLevel > 0: for i in range(0, self.agent.ballPred.num_slices): targetVec = Vector([ self.agent.ballPred.slices[i].physics.location.x, self.agent.ballPred.slices[i].physics.location.y, self.agent.ballPred.slices[i].physics.location.z ]) if self.agent.ballPred.slices[i].physics.location.z >= 300: if not aboveThreshold: aboveThreshold = True goalDist = distance2D(center, targetVec) acceptable = False if self.agent.team == 0: if self.agent.me.location[1] < targetVec[1]: acceptable = True else: if self.agent.me.location[1] > targetVec[1]: acceptable = True if acceptable: zOffset = -10 if goalDist < 1500: if targetVec[2] > 600: zOffset = 70 shotAngle = correctAngle( math.degrees(angle2(targetVec, enemyGoal)) + 90 * -sign(self.agent.team)) if self.agent.team == 0: if targetVec[1] >= 0: if abs(targetVec[0]) > 893: if targetVec[0] > 0: closePost = Vector([ 893, 5120 * -sign(self.agent.team), 200 ]) else: closePost = Vector([ -893, 5120 * -sign(self.agent.team), 200 ]) attackAngle = correctAngle( math.degrees( angle2(targetVec, closePost)) + 90 * -sign(self.agent.team)) targetLocal = toLocal( Vector([ self.agent.ballPred.slices[i]. physics.location.x, self.agent.ballPred.slices[i]. physics.location.y, self.agent.ballPred.slices[i]. physics.location.z ]), self.agent.me) carToBallAngle = correctAngle( math.degrees( math.atan2(targetLocal[1], targetLocal[0]))) totalAngle = correctAngle( math.degrees( math.tan(attackAngle) + math.tan(carToBallAngle) / (1 - (math.tan(attackAngle) * math.tan(carToBallAngle))))) if abs(totalAngle) > 60: continue elif self.agent.team == 1: if targetVec[1] <= 0: if abs(targetVec[0]) > 893: if targetVec[0] > 0: closePost = Vector([ 893, 5120 * -sign(self.agent.team), 200 ]) else: closePost = Vector([ -893, 5120 * -sign(self.agent.team), 200 ]) attackAngle = correctAngle( math.degrees( angle2(targetVec, closePost)) + 90 * -sign(self.agent.team)) targetLocal = toLocal( Vector([ self.agent.ballPred.slices[i]. physics.location.x, self.agent.ballPred.slices[i]. physics.location.y, self.agent.ballPred.slices[i]. physics.location.z ]), self.agent.me) carToBallAngle = correctAngle( math.degrees( math.atan2(targetLocal[1], targetLocal[0]))) totalAngle = correctAngle(carToBallAngle + attackAngle) if abs(totalAngle) > 60: continue if abs(shotAngle) <= 75: xOffset = clamp(80, -80, (shotAngle * 2) * -sign(self.agent.team)) self.aerial.target = vec3( self.agent.ballPred.slices[i].physics.location. x + xOffset, self.agent.ballPred.slices[i]. physics.location.y, self.agent.ballPred. slices[i].physics.location.z + zOffset) self.aerial.arrival_time = self.agent.ballPred.slices[ i].game_seconds simulation = self.aerial.simulate() if norm(simulation.location - self.aerial.target) < 100: self.target_ball = self.agent.ballPred.slices[ i] self.xOffset = xOffset self.zOffset = zOffset self.active = True if self.agent.onSurface: if self.agent.ballPred.slices[ i].physics.location.z >= 400: targetLocal = toLocal( Vector([ self.agent.ballPred.slices[i]. physics.location.x + xOffset, self.agent.ballPred.slices[i]. physics.location.y, self.agent.ballPred.slices[i]. physics.location.z + zOffset ]), self.agent.me) carToBallAngle = correctAngle( math.degrees( math.atan2( targetLocal[1], targetLocal[0]))) if abs(carToBallAngle) < 45: if distance2D( self.agent.me.location, targetLocal) > 1500: if self.agent.ballPred.slices[ i].physics.location.z >= 900: self.agent.activeState = airLaunch( self.agent) self.active = False return self.agent.activeState.update( ) break else: if aboveThreshold: break
def get_output(self, packet: GameTickPacket) -> SimpleControllerState: ############################################################################################### #Startup and frame info ############################################################################################### #Initialization info if self.is_init: self.is_init = False self.field_info = self.get_field_info() #Find teammates and opponents self.teammate_indices = [] self.opponent_indices = [] for i in range(packet.num_cars): if i == self.index: pass elif packet.game_cars[i].team == self.team: self.teammate_indices.append(i) else: self.opponent_indices.append(i) self.utils_game = utils.simulation.Game(self.index, self.team) utils.simulation.Game.set_mode("soccar") if TESTING or DEBUGGING: EvilGlobals.renderer = self.renderer self.prediction = PredictionPath( ball_prediction=self.get_ball_prediction_struct(), source="Framework", team=self.team) #Game state info self.game_info = GameState(packet=packet, rigid_body_tick=self.get_rigid_body_tick(), utils_game=self.utils_game, field_info=self.field_info, my_index=self.index, my_team=self.team, ball_prediction=self.prediction, teammate_indices=self.teammate_indices, opponent_indices=self.opponent_indices, my_old_inputs=self.old_inputs) ############################################################################################### #Planning ############################################################################################### #For now everything is a 1v1. I'll fix team code again in the future. #if self.game_info.team_mode == "1v1": self.plan, self.persistent = OnesPlanning.make_plan( self.game_info, self.plan.old_plan, self.plan.path, self.persistent) ''' else: self.plan, self.persistent = TeamPlanning.make_plan(self.game_info, self.plan.old_plan, self.plan.path, self.persistent) ''' #Check if it's a kickoff. If so, we'll run kickoff code later on. self.kickoff_position = update_kickoff_position( self.game_info, self.kickoff_position) #If we're in the first frame of an RLU mechanic, start up the object. #If we're finished with it, reset it to None ### if self.persistent.aerial_turn.initialize: self.persistent.aerial_turn.initialize = False self.persistent.aerial_turn.action = AerialTurn( self.game_info.utils_game.my_car) self.persistent.aerial_turn.action.target = rot_to_mat3( self.persistent.aerial_turn.target_orientation) elif not self.persistent.aerial_turn.check: self.persistent.aerial_turn.action = None self.persistent.aerial_turn.check = False ### if self.persistent.aerial.initialize: self.persistent.aerial.initialize = False self.persistent.aerial.action = Aerial( self.game_info.utils_game.my_car) self.persistent.aerial.action.target = Vec3_to_vec3( self.persistent.aerial.target_location, self.game_info.team_sign) self.persistent.aerial.action.arrival_time = self.persistent.aerial.target_time self.persistent.aerial.action.up = Vec3_to_vec3( self.persistent.aerial.target_up, self.game_info.team_sign) elif not self.persistent.aerial.check: self.persistent.aerial.action = None self.persistent.aerial.check = False ### ############################################################################################### #Testing ############################################################################################### if TESTING: #Copy-paste from a testing file here controller_input = SimpleControllerState() return controller_input ############################################################################################### #Run either Kickoff or Cowculate ############################################################################################### if self.plan.layers[0] == "Kickoff": if self.old_kickoff_data != None: self.kickoff_data = Kickoff(self.game_info, self.kickoff_position, self.old_kickoff_data.memory, self.persistent) else: self.kickoff_data = Kickoff(self.game_info, self.kickoff_position, None, self.persistent) output, self.persistent = self.kickoff_data.input() else: output, self.persistent = Cowculate(self.plan, self.game_info, self.prediction, self.persistent) ############################################################################################### #Update previous frame variables. ############################################################################################### self.old_kickoff_data = self.kickoff_data self.old_inputs = output #Make sure we don't get stuck turtling. Not sure how effective this is. if output.throttle == 0: output.throttle = 0.01 #Making sure that RLU output is interpreted properly as an input for RLBot framework_output = SimpleControllerState() framework_output.throttle = output.throttle framework_output.steer = output.steer framework_output.yaw = output.yaw framework_output.pitch = output.pitch framework_output.roll = output.roll framework_output.boost = output.boost framework_output.handbrake = output.handbrake framework_output.jump = output.jump return framework_output
from rlutilities.linear_algebra import vec3, axis_to_rotation, look_at from rlutilities.mechanics import AerialTurn from rlutilities.simulation import Car c = Car() c.time = 0.0 c.location = vec3(0, 0, 500) c.velocity = vec3(0, 0, 0) c.angular_velocity = vec3(0.1, -2.0, 1.2) c.rotation = axis_to_rotation(vec3(1.7, -0.5, 0.3)) c.on_ground = False turn = AerialTurn(c) turn.target = look_at(vec3(1, 0, 0), vec3(0, 0, 1)) turn.step(0.0166) print(turn.controls.roll) print(turn.controls.pitch) print(turn.controls.yaw) simulation = turn.simulate() print(simulation.time)
def get_output(self, packet: GameTickPacket) -> SimpleControllerState: self.game.read_game_information(packet, self.get_rigid_body_tick(), self.get_field_info()) self.controls = SimpleControllerState() next_state = self.state if self.state == State.RESET: self.timer = 0.0 b_position = Vector3(random.uniform(-1500, 1500), random.uniform( 2500, 3500), random.uniform( 300, 500)) b_velocity = Vector3(random.uniform(-300, 300), random.uniform(-100, 100), random.uniform(1000, 1500)) ball_state = BallState(physics=Physics( location=b_position, velocity=b_velocity, rotation=Rotator(0, 0, 0), angular_velocity=Vector3(0, 0, 0) )) # this just initializes the car and ball # to different starting points each time c_position = Vector3(b_position.x, 0 * random.uniform(-1500, -1000), 25) #c_position = Vector3(200, -1000, 25) car_state = CarState(physics=Physics( location=c_position, velocity=Vector3(0, 800, 0), rotation=Rotator(0, 1.6, 0), angular_velocity=Vector3(0, 0, 0) ), boost_amount=100) self.set_game_state(GameState( ball=ball_state, cars={self.game.id: car_state}) ) next_state = State.WAIT if self.state == State.WAIT: if self.timer > 0.2: next_state = State.INITIALIZE if self.state == State.INITIALIZE: self.aerial = Aerial(self.game.my_car) # self.aerial.up = normalize(vec3( # random.uniform(-1, 1), # random.uniform(-1, 1), # random.uniform(-1, 1))) self.turn = AerialTurn(self.game.my_car) # predict where the ball will be prediction = Ball(self.game.ball) self.ball_predictions = [vec3(prediction.location)] for i in range(100): prediction.step(0.016666) prediction.step(0.016666) self.ball_predictions.append(vec3(prediction.location)) # if the ball is in the air if prediction.location[2] > 500: self.aerial.target = prediction.location self.aerial.arrival_time = prediction.time simulation = self.aerial.simulate() # # check if we can reach it by an aerial if norm(simulation.location - self.aerial.target) < 100: prediction.step(0.016666) prediction.step(0.016666) self.aerial.target = prediction.location self.aerial.arrival_time = prediction.time self.target_ball = Ball(prediction) break next_state = State.RUNNING if self.state == State.RUNNING: self.log.write(f"{{\"car\":{self.game.my_car.to_json()}," f"\"ball\":{self.game.ball.to_json()}}}\n") self.aerial.step(self.game.time_delta) self.controls = self.aerial.controls if self.timer > self.timeout: next_state = State.RESET self.aerial = None self.turn = None self.timer += self.game.time_delta self.state = next_state self.renderer.begin_rendering() red = self.renderer.create_color(255, 230, 30, 30) purple = self.renderer.create_color(255, 230, 30, 230) white = self.renderer.create_color(255, 230, 230, 230) if self.aerial: r = 200 x = vec3(r, 0, 0) y = vec3(0, r, 0) z = vec3(0, 0, r) target = self.aerial.target self.renderer.draw_line_3d(target - x, target + x, purple) self.renderer.draw_line_3d(target - y, target + y, purple) self.renderer.draw_line_3d(target - z, target + z, purple) if self.ball_predictions: self.renderer.draw_polyline_3d(self.ball_predictions, purple) self.renderer.end_rendering() return self.controls
class DoubleJumpStrike(Strike): def intercept_predicate(self, car, ball): return 250 < ball.position[2] < 550 def __init__(self, car: Car, info: GameInfo, target=None): self.drive = Drive(car) self.aerial_turn = AerialTurn(car) self.jumping = False self.time_for_jump = float("inf") self.timer = 0.0 super().__init__(car, info, target) def configure(self, intercept: Intercept): super().configure(intercept) self.drive.target_pos = ground(intercept.position) self.time_for_jump = self.double_jump_time_needed( intercept.position[2]) def interruptible(self) -> bool: return not self.jumping and super().interruptible() def step(self, dt): if self.jumping: self.controls = Input() # first jump for full 0.2 sec if self.timer <= 0.2: self.controls.jump = True # single tick between jumps elif self.timer <= 0.2 + dt * JUMP_FALSE_TICKS: self.controls.jump = False # second jump else: self.controls.jump = True self.jumping = False self.timer += dt else: self.finished = self.intercept.time < self.info.time if self.car.on_ground: # manage speed before jump distance_to_target = ground_distance(self.car.position, self.intercept.position) if distance_to_target < MIN_DIST_BEFORE_SPEED_CONTROL: target_speed = distance_to_target / self.time_for_jump self.drive.target_speed = -target_speed if self._should_strike_backwards else target_speed self.drive.step(dt) self.controls = self.drive.controls else: super().step(dt) # decide when to jump ground_vel = ground(self.car.velocity) direction_to_target = ground_direction(self.car.position, self.intercept.position) alignment = dot(normalize(ground_vel), direction_to_target) # check alignment if alignment >= MIN_ALIGNMENT: # check that speed is correct speed_in_direction = dot(ground_vel, direction_to_target) time_to_target = distance_to_target / speed_in_direction if self.time_for_jump - ALLOWED_TIME_ERROR <= time_to_target <= self.time_for_jump + ALLOWED_TIME_ERROR: self.jumping = True # after jump (when the car is in the air) else: # face the ball for some additional height self.aerial_turn.target = look_at( direction(self.car.position, self.info.ball), vec3(0, 0, 1)) self.aerial_turn.step(dt) self.controls = self.aerial_turn.controls @staticmethod def double_jump_time_needed(height): """Return the time needed for the double jump to reach a given height""" # polynomial approximation a = 1.872348977E-8 * height * height * height b = -1.126747937E-5 * height * height c = 3.560647225E-3 * height d = -7.446058499E-3 return a + b + c + d