Example #1
0
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
Example #2
0
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
Example #3
0
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
Example #4
0
    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
Example #5
0
    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
Example #6
0
    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
Example #7
0
 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
Example #8
0
    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
Example #9
0
    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)
Example #10
0
    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
Example #11
0
 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)
Example #13
0
    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
Example #14
0
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)
                    
Example #15
0
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)
Example #16
0
 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)
Example #17
0
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)
Example #19
0
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
Example #20
0
    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
Example #21
0
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
Example #22
0
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
Example #23
0
    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
Example #24
0
    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
Example #25
0
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)
Example #26
0
    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
Example #27
0
    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
Example #28
0
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)
Example #29
0
    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
Example #30
0
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