Beispiel #1
0
    def step(self, packet: GameTickPacket, drone: Drone, index: int):
        self.finished = (100 + self.big_radius -
                         self.time_since_start * self.speed) <= 0

        # Get centre of small circle.
        direction_angle = (math.pi / 4) + ((math.pi / 2) * (index // 16))
        centre = vec3(dot(rotation(direction_angle), vec2(1, 0)))
        # Crossing action.
        centre *= (self.big_radius - self.time_since_start * self.speed)
        centre[2] = self.height

        # Angle for the small circle.
        angle = (2 * math.pi / 16) * (index % 16)
        angle += (2 * math.pi / 4) * (index // 16 - 1)
        angle += self.time_since_start * self.spin
        target = vec3(dot(rotation(angle), vec2(self.small_radius, 0)))
        target += centre

        # Different heights.
        target[2] += (index // 16 - 2) * self.height_diff

        # Hover controls.
        drone.hover.up = normalize(drone.position - centre)
        drone.hover.target = target
        drone.hover.step(self.dt)
        drone.controls = drone.hover.controls
Beispiel #2
0
    def step(self, packet: GameTickPacket, drone: Drone, index: int):

        # Get centre of small circle.
        direction_angle = (math.pi / 4) + ((math.pi / 2) * (index // 16))
        centre = vec3(dot(rotation(direction_angle), vec2(
            1, 0))) * self.big_radius
        centre[2] = self.height

        # Angle for the small circle.
        # Wraps nicely around the small circle.
        t = self.time_since_start + 2.5
        if t > 2 * math.pi: t = 2 * math.pi
        angle = (t / 16) * (index % 16 - 8)
        angle += (2 * math.pi / 4) * (index // 16) + (math.pi / 4)
        target = vec3(dot(rotation(angle), vec2(self.small_radius, 0)))
        target += centre

        # Hover controls.
        drone.hover.up = normalize(drone.position - centre)
        drone.hover.target = target
        drone.hover.step(self.dt)
        drone.controls = drone.hover.controls

        # If any bot got lost, now they have a chance to recover.
        if drone.on_ground:
            drone.controls.jump = True
        else:
            drone.controls.jump = False
Beispiel #3
0
    def step(self, dt):
        car = self.car
        target = ground(self.target)

        car_speed = norm(car.velocity)
        time_left = (ground_distance(car, target) -
                     self.finish_distance) / max(car_speed + 500, 1400)
        forward_speed = dot(car.forward(), car.velocity)

        if self.driving and car.on_ground:
            self.action.target_pos = target
            self._time_on_ground += dt

            # check if it's a good idea to dodge, wavedash or halfflip
            if (self._time_on_ground > 0.2 and car.position[2] < 200
                    and angle_to(car, target, forward_speed < 0) < 0.1):
                # if going forward, use a dodge or a wavedash
                if forward_speed > 0:
                    use_boost_instead = self.waste_boost and car.boost > 20

                    if car_speed > 1200 and not use_boost_instead:
                        if time_left > self.DODGE_DURATION:
                            dodge = Dodge(car)
                            dodge.duration = 0.05
                            dodge.direction = vec2(direction(car, target))
                            self.action = dodge
                            self.driving = False

                        elif time_left > self.WAVEDASH_DURATION:
                            wavedash = Wavedash(car)
                            wavedash.direction = vec2(direction(car, target))
                            self.action = wavedash
                            self.driving = False

                # if going backwards, use a halfflip
                elif time_left > self.HALFFLIP_DURATION and car_speed > 800:
                    self.action = HalfFlip(car, self.waste_boost
                                           and time_left > 3)
                    self.driving = False

        self.action.step(dt)
        self.controls = self.action.controls

        # make sure we're not boosting airborne
        if self.driving and not car.on_ground:
            self.controls.boost = False

        # make sure we're not stuck turtling
        if not car.on_ground:
            self.controls.throttle = 1

        if self.action.finished and not self.driving:
            self.driving = True
            self._time_on_ground = 0
            self.action = self.drive
            self.drive.backwards = False

        if ground_distance(car,
                           target) < self.finish_distance and self.driving:
            self.finished = True
Beispiel #4
0
def should_dodge(agent):
    """"Method that checks if we should dodge"""
    car = agent.info.my_car
    their_goal = agent.their_goal
    close_to_goal = distance_2d(car.position, their_goal.center) < 4000
    aiming_for_goal = abs(line_backline_intersect(
        their_goal.center[1], vec2(car.position), vec2(car.forward()))) < 850
    bot_to_target = agent.info.ball.position - car.position
    local_bot_to_target = dot(bot_to_target, agent.info.my_car.orientation)
    angle_front_to_target = math.atan2(local_bot_to_target[1], local_bot_to_target[0])
    close_to_ball = norm(vec2(bot_to_target)) < 750
    good_angle = abs(angle_front_to_target) < math.radians(15)
    return close_to_ball and close_to_goal and aiming_for_goal and good_angle
Beispiel #5
0
 def should_defending(self):
     return False  # Don't.
     """Method which returns a boolean regarding whether we should defend or not"""
     ball = self.info.ball
     car = self.info.my_car
     our_goal = self.my_goal.center
     car_to_ball = ball.location - car.location
     in_front_of_ball = distance_2d(ball.location, our_goal) < distance_2d(
         car.location, our_goal)
     backline_intersect = line_backline_intersect(self.my_goal.center[1],
                                                  vec2(car.location),
                                                  vec2(car_to_ball))
     return (in_front_of_ball
             and abs(backline_intersect) < 2000) or self.conceding
Beispiel #6
0
    def predict_car_drive(self,
                          index,
                          time_limit=2.0,
                          dt=1 / 60) -> List[vec3]:
        """Simple prediction of a driving car assuming no acceleration."""
        car = self.cars[index]
        time_steps = int(time_limit / dt)
        speed = norm(car.velocity)
        ang_vel_z = car.angular_velocity[2]

        # predict circular path
        if ang_vel_z != 0 and car.on_ground:
            radius = speed / ang_vel_z
            centre = car.position - cross(normalize(xy(car.velocity)),
                                          vec3(0, 0, 1)) * radius
            centre_to_car = vec2(car.position - centre)
            return [
                vec3(dot(rotation(ang_vel_z * dt * i), centre_to_car)) + centre
                for i in range(time_steps)
            ]

        # predict straight path
        return [
            car.position + car.velocity * dt * i for i in range(time_steps)
        ]
Beispiel #7
0
    def step(self, packet: GameTickPacket, drone: Drone, index: int):

        if drone.position[2] < 25:
            drone.since_jumped = 0.0

            # Go forward
            drone.controls.throttle = 1.0 if abs(
                drone.velocity[1]) < 500 else 0.01

            # If near half-line
            if abs(drone.position[1]) < 200:
                drone.controls.jump = True

        else:
            drone.since_jumped += self.dt

            height = 50 + drone.since_jumped * 150
            angle = 1.0 + drone.since_jumped * 1.2
            if index % 2 == 0: angle += math.pi

            rot = rotation(angle)
            v = vec3(dot(rot, vec2(1, 0)))
            drone.hover.target = v * self.radius
            drone.hover.target[2] = height

            drone.hover.up = normalize(drone.position)
            drone.hover.step(self.dt)
            drone.controls = drone.hover.controls
Beispiel #8
0
def shooting_target(agent):
    """"Method that gives the target for the shooting strategy"""
    ball = agent.info.ball
    car = agent.info.my_car
    car_to_ball = ball.location - car.location
    backline_intersect = line_backline_intersect(agent.their_goal.center[1],
                                                 vec2(car.location),
                                                 vec2(car_to_ball))
    if abs(backline_intersect) < 700:
        goal_to_ball = normalize(car.location - ball.location)
        error = 0
    else:
        # Right of the ball
        if -500 > backline_intersect:
            target = agent.their_goal.corners[3] + vec3(400, 0, 0)
        # Left of the ball
        elif backline_intersect > 500:
            target = agent.their_goal.corners[2] - vec3(400, 0, 0)
        goal_to_ball = normalize(ball.location - target)
        # Subtract the goal to car vector
        difference = goal_to_ball - normalize(car.location - target)
        error = cap(abs(difference[0]) + abs(difference[1]), 0, 5)

    goal_to_ball_2d = vec2(goal_to_ball[0], goal_to_ball[1])
    test_vector_2d = dot(rotation(0.5 * math.pi), goal_to_ball_2d)
    test_vector = vec3(test_vector_2d[0], test_vector_2d[1], 0)

    distance = cap(
        (40 + distance_2d(ball.location, car.location) * (error**2)) / 1.8, 0,
        4000)
    location = ball.location + vec3(
        (goal_to_ball[0] * distance), goal_to_ball[1] * distance, 0)

    # this adjusts the target based on the ball velocity perpendicular
    # to the direction we're trying to hit it
    multiplier = cap(distance_2d(car.location, location) / 1500, 0, 2)
    distance_modifier = cap(
        dot(test_vector, ball.velocity) * multiplier, -1000, 1000)
    location += vec3(test_vector[0] * distance_modifier,
                     test_vector[1] * distance_modifier, 0)

    # another target adjustment that applies if the ball is close to the wall
    extra = 3850 - abs(location[0])
    if extra < 0:
        location[0] = cap(location[0], -3850, 3850)
        location[1] = location[1] + (-sign(agent.team) * cap(extra, -800, 800))
    return location
Beispiel #9
0
 def set_drone_states(self, drones: List[Drone]):
     for i, drone in enumerate(drones):
         angle = (2 * math.pi / 64) * i
         drone.position = vec3(dot(rotation(angle), vec2(self.radius, 0)))
         drone.position[2] = self.height
         drone.velocity = vec3(0, 0, 0)
         drone.orientation = euler_to_rotation(
             vec3(math.pi / 2, angle, math.pi))
         drone.angular_velocity = vec3(0, 0, 0)
Beispiel #10
0
 def set_drone_states(self, drones: List[Drone]):
     for i, drone in enumerate(drones):
         angle = i * math.pi * 2 / len(drones)
         rot = rotation(angle)
         v = vec3(dot(rot, vec2(1, 0)))
         drone.position = v * self.radius + self.center
         drone.orientation = look_at(v * -1, vec3(0, 0, 1))
         drone.velocity = vec3(0, 0, 0)
         drone.angular_velocity = vec3(0, 0, 0)
Beispiel #11
0
    def step(self, packet: GameTickPacket, drone: Drone, index: int):
        # Calculate shift direction.
        direction_angle = (math.pi / 4) + ((math.pi / 2) * (index // 16))
        direction = vec3(dot(rotation(direction_angle), vec2(1, 0)))

        # Shift in one direction.
        angle = (2 * math.pi / 64) * index
        target = vec3(dot(rotation(angle), vec2(self.start_radius, 0)))
        target += direction * (self.end_radius - self.start_radius) * (
            self.time_since_start / self.duration)
        target[2] = self.height

        target = (target + drone.position) / 2

        # Hover controls.
        drone.hover.up = normalize(drone.position)
        drone.hover.target = target
        drone.hover.step(self.dt)
        drone.controls = drone.hover.controls
Beispiel #12
0
    def step(self, packet: GameTickPacket, drone: Drone, index: int):
        radius = 1050 + 150 * self.time_since_start
        angle = math.pi + self.time_since_start * (math.pi / 5)
        angle += (2 * math.pi / 64) * index
        target = vec3(dot(rotation(angle), vec2(radius, 0)))
        target[2] = self.height

        drone.hover.up = normalize(-1 * xy(drone.position))
        drone.hover.target = target
        drone.hover.step(self.dt)
        drone.controls = drone.hover.controls
Beispiel #13
0
    def step(self, packet: GameTickPacket, drone: Drone, index: int):
        if drone.start_pos is None:
            drone.start_pos = drone.position

        # spin = (index % 16 - 8) * 0.01 # Unwind helix.
        # rotation = axis_to_rotation(vec3(0, 0, spin))
        # position_on_circle = normalize(xy(drone.position)) * self.start_radius
        # drone.hover.target = dot(rotation, position_on_circle)
        # drone.hover.target[2] = drone.start_pos[2]
        # drone.hover.step(self.dt)
        # drone.controls = drone.hover.controls

        current_radius = norm(vec2(drone.position))

        desired_angle = (2 * math.pi / 64) * index
        current_angle = math.atan2(drone.position[1], drone.position[0])
        if current_angle < 0.0:
            current_angle += 2 * math.pi  # only positive angles

        # Expand radius.
        if current_radius < self.radius - 150:
            direction_angle = (math.pi / 4) + ((math.pi / 2) * (index // 16))
            direction = vec3(dot(rotation(direction_angle), vec2(1, 0)))
            target = drone.position + direction * 200
            target[2] = drone.start_pos[2]
        # Get to correct angle.
        elif abs(desired_angle - current_angle) > 0.05:
            target = vec3(dot(rotation(desired_angle), vec2(self.radius, 0)))
            target[2] = drone.start_pos[2]
        # Get to correct height.
        else:
            target = vec3(dot(rotation(desired_angle), vec2(self.radius, 0)))
            target[2] = self.height

        drone.hover.up = normalize(drone.position)
        drone.hover.target = target
        drone.hover.step(self.dt)
        drone.controls = drone.hover.controls
Beispiel #14
0
    def step(self, packet: GameTickPacket, drones: List[Drone]):
        s = int(math.sqrt(len(drones)))  # Side length
        for i, drone in enumerate(drones):
            # Get grid pos.
            x = (i // s) - (s - 1) / 2
            y = (i % s) - (s - 1) / 2
            # Get height from func.
            z = 800 + self.func(x, y)  # 800 is base height

            drone.hover.target = vec3(x * self.spacing, y * self.spacing, z)
            rot = rotation(self.rotation_speed * self.time_since_start * 2)
            drone.hover.up = vec3(dot(rot, vec2(1, 0)))
            drone.hover.step(self.dt)
            drone.controls = drone.hover.controls
Beispiel #15
0
def can_dodge(agent, target):
    """Returns whether its wise to dodge"""
    bot_to_target = target - agent.info.my_car.location
    local_bot_to_target = dot(bot_to_target, agent.info.my_car.rotation)
    angle_front_to_target = math.atan2(local_bot_to_target[1],
                                       local_bot_to_target[0])
    distance_bot_to_target = norm(vec2(bot_to_target))
    good_angle = math.radians(-10) < angle_front_to_target < math.radians(10)
    on_ground = agent.info.my_car.on_ground and agent.info.my_car.location[
        2] < 100
    going_fast = velocity_2d(agent.info.my_car.velocity) > 1250
    target_not_in_goal = not agent.my_goal.inside(target)
    return (good_angle and distance_bot_to_target > 2000 and on_ground
            and going_fast and target_not_in_goal)
Beispiel #16
0
    def __init__(self, car: Car, use_boost=False):
        self.car = car
        self.use_boost = use_boost
        self.controls = Input()

        self.dodge = Dodge(car)
        self.dodge.duration = 0.12
        self.dodge.direction = vec2(car.forward() * (-1))

        self.s = 0.95 * sgn(
            dot(self.car.angular_velocity, self.car.up()) + 0.01)

        self.timer = 0.0

        self.finished = False
Beispiel #17
0
 def set_drone_states(self, drones: List[Drone]):
     for i, drone in enumerate(drones):
         angle = math.pi / 2
         rot = rotation(angle)
         v = vec3(dot(rot, vec2(1, 0)))
         v[2] = 0.25
         if i % 2 == 0:
             drone.position = self.center + vec3(
                 math.floor(i / 2) * 250,
                 math.floor(i / 2) * -250, 1750)
         else:
             drone.position = self.center + vec3(
                 (1 + math.floor(i / 2)) * -250,
                 (1 + math.floor(i / 2)) * -250, 1750)
         print(i, drone.position)
Beispiel #18
0
    def step(self, packet: GameTickPacket, drone: Drone, index: int):
        angle = (2 * math.pi / 64) * index
        target = vec3(dot(rotation(angle), vec2(self.radius, 0)))
        target[2] = self.height

        # Hover controls
        drone.hover.target = target
        drone.hover.up = normalize(drone.position)
        drone.hover.step(self.dt)
        drone.controls = drone.hover.controls

        # If any bot got lost, now they have a chance to recover.
        if drone.on_ground:
            drone.controls.jump = True
        else:
            drone.controls.jump = False
Beispiel #19
0
    def step(self, packet: GameTickPacket, drones: List[Drone]):
        for drone in drones:
            drone.hover.up = normalize(drone.position)

            for i, layer in enumerate(self.layers):
                if drone.id in layer:
                    # Calculate radius
                    if self.time_since_start < self.radius_shrink_start:
                        radius = 2000

                    elif self.time_since_start < self.radius_shrink_start + self.radius_shrink_duration:
                        diff = 2000 - self.radii[i]
                        radius = 2000 - diff * (
                            (self.time_since_start - self.radius_shrink_start)
                            / self.radius_shrink_duration)
                    else:
                        radius = self.radii[i]

                    # Calculate xy position
                    if self.time_since_start > self.recirculation_start:
                        a = layer.index(drone.id)
                        angle = a * math.pi * 2 / len(layer)
                        rot = rotation(angle)
                        pos_xy = vec3(dot(rot, vec2(1, 0)))

                    else:
                        pos_xy = xy(drone.position)

                    # Combine xy and radius
                    drone.hover.target = normalize(pos_xy) * radius

                    # Get height
                    if self.time_since_start < self.separation_duration:
                        diff = 1000 - self.heights[i]
                        height = 1000 - diff * (self.time_since_start /
                                                self.separation_duration)

                    else:
                        height = self.heights[i]

                    drone.hover.target[2] = height
                    break

            drone.hover.step(self.dt)
            drone.controls = drone.hover.controls
Beispiel #20
0
c.time = 0.0
c.location = vec3(1509.38, -686.19, 17.01)
c.velocity = vec3(-183.501, 1398., 8.321)
c.angular_velocity = vec3(0, 0, 0)
c.rotation = mat3(-0.130158, -0.991493, -0.00117062, 0.991447, -0.130163,
                  0.00948812, -0.00955977, 0.0000743404, 0.999954)
c.dodge_rotation = mat2(-0.130163, -0.991493, 0.991493, -0.130163)

c.on_ground = True
c.jumped = False
c.double_jumped = False
c.jump_timer = -1.0
c.dodge_timer = -1.0

dodge = Dodge(c)
dodge.direction = vec2(-230.03, 463.42)
dodge.duration = 0.1333
dodge.delay = 0.35

f = open("dodge_simulation.csv", "w")
for i in range(300):
    dodge.step(0.008333)
    print(c.time, dodge.controls.jump, dodge.controls.pitch,
          dodge.controls.yaw)
    c.step(dodge.controls, 0.008333)
    f.write(
        f"{c.time}, {c.location[0]}, {c.location[1]}, {c.location[2]}, "
        f"{c.velocity[0]}, {c.velocity[1]}, {c.velocity[2]}, "
        f"{c.angular_velocity[0]}, {c.angular_velocity[1]}, {c.angular_velocity[2]}\n"
    )
Beispiel #21
0
def velocity_2d(velocity):
    """Returns the total 2d velocity given a velocity vector"""
    return norm(vec2(velocity))
Beispiel #22
0
    def step(self, packet: GameTickPacket, drone: Drone, index: int):
        if drone.start_pos is None:
            drone.start_pos = drone.position
            drone.sort_phase = 1

        # Finish if all have been sorted.
        if index == 0:
            # Initially set finished to True.
            self.finished = True
        if drone.sort_phase != 3:
            # Will be set to False if any is not in phase 3.
            self.finished = False

            # It's my time!
        if self.time_since_start > 0.5 + index * self.delay:

            desired_angle = (2 * math.pi / 64) * index

            # current_radius = norm(vec2(drone.position))
            current_angle = math.atan2(drone.position[1], drone.position[0])
            if current_angle < 0.0:
                current_angle += 2 * math.pi  # only positive angles

            # Rotate to correct angle.
            if drone.sort_phase == 1:
                # if index in range(64)[::8]: print(index, current_angle, desired_angle)
                if abs(current_angle - desired_angle) < 0.1:
                    drone.sort_phase = 2
                target = dot(rotation(current_angle + 0.4),
                             vec2(self.radius - 400, 0))
                target = vec3(target)
                target[2] = self.height + (180 * index // 16)

            # Height and final corrections.
            elif drone.sort_phase == 2:
                target = vec3(
                    dot(rotation(desired_angle), vec2(self.radius, 0)))
                target[2] = self.height
                if norm(drone.position - target) < 200:
                    drone.sort_phase = 3

                target[2] = (4 * drone.position[2] + self.height) / 5

            elif drone.sort_phase == 3:
                target = vec3(
                    dot(rotation(desired_angle), vec2(self.radius, 0)))
                target[2] = self.height

        else:
            # Stay in place.
            target = drone.start_pos

        # Hover controls
        drone.hover.target = target
        drone.hover.up = normalize(drone.position)
        drone.hover.step(self.dt)
        drone.controls = drone.hover.controls

        # If any bot got lost, now they have a chance to recover.
        if drone.on_ground:
            drone.controls.jump = True
        else:
            drone.controls.jump = False
Beispiel #23
0
    def step(self):
        """"Gives output for the dribbling strategy"""
        # direction of ball relative to center of car (where should we aim)
        # direction of ball relative to yaw of car (where should we aim verse where we are aiming)
        local_bot_to_ball = dot(self.ball.position - self.car.position,
                                self.car.orientation)
        angle_front_to_ball = math.atan2(local_bot_to_ball[1],
                                         local_bot_to_ball[0])
        # distance between bot and ball
        distance = distance_2d(self.car.position, self.ball.position)
        # direction of ball velocity relative to yaw of car (which way the ball is moving verse which way we are moving)
        if velocity_2d(self.ball.velocity) < 1e-10:
            angle_car_forward_to_ball_velocity = 0
        else:
            angle_car_forward_to_ball_velocity = angle_between(
                z_0(self.car.forward()), z_0(self.ball.velocity))
        # magnitude of ball_bot_angle (squared)
        ball_bot_diff = (self.ball.velocity[0]**2 +
                         self.ball.velocity[1]**2) - (self.car.velocity[0]**2 +
                                                      self.car.velocity[1]**2)
        # p is the distance between ball and car
        # i is the magnitude of the ball's velocity (squared) the i term would normally
        # be the integral of p over time, but the ball's velocity is essentially that number
        # d is the relative speed between ball and car
        # note that bouncing a ball is distinctly different than balancing something that doesnt bounce
        # p_s is the x component of the distance to the ball
        # d_s is the one frame change of p_s, that's why p_s has to be global

        # we modify distance and ball_bot_diff so that only the component along the car's path is counted
        # if the ball is too far to the left, we don't want the bot to think it has to drive forward
        # to catch it
        distance_y = math.fabs(distance * math.cos(angle_front_to_ball))
        distance_x = math.fabs(distance * math.sin(angle_front_to_ball))
        # ball moving forward WRT car yaw?
        forward = False
        if math.fabs(angle_car_forward_to_ball_velocity) < math.radians(90):
            forward = True
        # first we give the distance values signs
        if forward:
            d = ball_bot_diff
            i = (self.ball.velocity[0]**2 + self.ball.velocity[1]**2)
        else:
            d = -ball_bot_diff
            i = -(self.ball.velocity[0]**2 + self.ball.velocity[1]**2)

        if math.fabs(math.degrees(angle_front_to_ball)) < 90:
            p = distance_y

        else:
            p = -1 * distance_y
        # this is the PID correction.  all of the callibration goes on right here
        # there is literature about how to set the variables but it doesn't work quite the same
        # because the car is only touching the ball (and interacting with the system) on bounces
        # we run the PID formula through tanh to give a value between -1 and 1 for steering input
        # if the ball is lower we have no velocity bias
        bias_v = 600000  # 600000

        # just the basic PID if the ball is too low
        if self.ball.position[2] < 120:
            correction = np.tanh((20 * p + .0015 * i + .006 * d) / 500)
        # if the ball is on top of the car we use our bias (the bias is in velocity units squared)
        else:
            correction = np.tanh(
                (20 * p + .0015 * (i - bias_v) + .006 * d) / 500)
        # makes sure we don't get value over .99 so we dont exceed maximum thrust
        self.controls.throttle = correction * .99
        # anything over .9 is boost
        if correction > .99:
            self.controls.boost = True
        else:
            self.controls.boost = False

        # this is the PID steering section
        # p_s is the x component of the distance to the ball (relative to the cars direction)
        # d_s is the on frame change in p_s

        # we use absolute value and then set the sign later
        d_s = math.fabs(self.p_s) - math.fabs(distance_x)
        self.p_s = math.fabs(distance_x)
        # give the values the correct sign
        if angle_front_to_ball < 0:
            self.p_s = -self.p_s
            d_s = -d_s
        # d_s is actually -d_s ...whoops
        d_s = -d_s
        max_bias = 35
        backline_intersect = line_backline_intersect(self.goal.center[1],
                                                     vec2(self.car.position),
                                                     vec2(self.car.forward()))
        if abs(backline_intersect) < 1000 or self.ball.position[2] > 200:
            bias = 0
        # Right of the ball
        elif -850 > backline_intersect:
            bias = max_bias
        # Left of the ball
        elif 850 < backline_intersect:
            bias = -max_bias

        # the correction settings can be altered to change performance
        correction = np.tanh((100 * (self.p_s + bias) + 1500 * d_s) / 8000)
        # apply the correction
        self.controls.steer = correction
Beispiel #24
0
 def get_controls(self):
     """Decides what strategy to uses and gives corresponding output"""
     self.drive.power_turn = False
     if self.step is Step.Steer or self.step is Step.Drive:
         self.step = Step.Catching
     if self.step is Step.Catching:
         # Enable power turning for catching, since we don't halfflip
         self.drive.power_turn = True
         target = get_bounce(self)
         if target is None:
             self.step = Step.Shooting
         else:
             self.catching.target = target[0]
             self.catching.speed = (distance_2d(self.info.my_car.location,
                                                target[0]) + 50) / target[1]
             self.catching.step(self.info.time_delta)
             self.controls = self.catching.controls
             ball = self.info.ball
             car = self.info.my_car
             if distance_2d(ball.location, car.location) < 150 and 65 < abs(
                     ball.location[2] - car.location[2]) < 127:
                 self.step = Step.Dribbling
                 self.dribble = Dribbling(self.info.my_car, self.info.ball,
                                          self.their_goal)
             if self.defending:
                 self.step = Step.Defending
             ball = self.info.ball
             if abs(ball.velocity[2]) < 100 and sign(self.team) * ball.velocity[1] < 0 and sign(self.team) * \
                     ball.location[1] < 0:
                 self.step = Step.Shooting
     elif self.step is Step.Dribbling:
         self.dribble.step()
         self.controls = self.dribble.controls
         ball = self.info.ball
         car = self.info.my_car
         bot_to_opponent = self.info.cars[
             1 - self.index].location - self.info.my_car.location
         local_bot_to_target = dot(bot_to_opponent,
                                   self.info.my_car.rotation)
         angle_front_to_target = math.atan2(local_bot_to_target[1],
                                            local_bot_to_target[0])
         opponent_is_near = norm(vec2(bot_to_opponent)) < 2000
         opponent_is_in_the_way = math.radians(
             -10) < angle_front_to_target < math.radians(10)
         if not (distance_2d(ball.location, car.location) < 150
                 and 65 < abs(ball.location[2] - car.location[2]) < 127):
             self.step = Step.Catching
         if self.defending:
             self.step = Step.Defending
         if opponent_is_near and opponent_is_in_the_way:
             self.step = Step.Dodge
             self.dodge = Dodge(self.info.my_car)
             self.dodge.duration = 0.25
             self.dodge.target = self.their_goal.center
     elif self.step is Step.Defending:
         defending(self)
     elif self.step in [
             Step.Dodge, Step.Dodge_1, Step.Dodge_2, Step.HalfFlip
     ]:
         halfflipping = self.step is 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:
             self.step = Step.Catching
         else:
             self.controls = (self.halfflip.controls
                              if halfflipping else self.dodge.controls)
     elif self.step is Step.Shooting:
         shooting(self)
    def get_output(self, packet: GameTickPacket) -> SimpleControllerState:
        self.renderer.begin_rendering()

        self.game.read_game_information(packet, self.get_rigid_body_tick(),
                                        self.get_field_info())

        if self.lastReset + 300 < self.currentTick:
            if self.tests > 0:
                score = min(300, self.currentTick - self.lastDoneTick)
                self.totalScore += score
                print(self.tests, score, round(self.totalScore / self.tests,
                                               2))
            self.tests += 1
            self.lastReset = self.currentTick
            self.target = vec3(2 * random() - 1, 2 * random() - 1,
                               2 * random() - 1)
            self.up = orthogonalize(
                vec3(2 * random() - 1, 2 * random() - 1, 2 * random() - 1),
                self.target)
            self.targetOrientation = look_at(self.target, self.up)
            car_state = CarState(
                physics=Physics(location=Vector3(0, 1000, 17),
                                velocity=Vector3(0, 0, 0),
                                rotation=Rotator(0, 0, 0),
                                angular_velocity=Vector3(0, 0, 0)))
            self.set_game_state(GameState(cars={self.index: car_state}))
            self.stage = 0
            self.lastDodgeTick = -math.inf
            # print("TELEPORT TO GROUND")
            return self.controls
        else:
            car_state = CarState(physics=Physics(location=Vector3(0, 0, 400),
                                                 velocity=Vector3(0, 0, 0)))
            self.set_game_state(GameState(cars={self.index: car_state}))

        if self.stage <= 5:
            self.stage += 1
        if self.stage == 6:
            self.dodgeDirection = normalize(vec2(0, 2 * random() - 1))
            self.controls.jump = True  #random() > 0.5
            if self.controls.jump:
                self.lastDodgeTick = self.currentTick

            self.controls.roll, self.controls.pitch, self.controls.yaw = self.dodgeDirection[
                0], self.dodgeDirection[1], 0
            self.stage += 1
            return self.controls
        else:
            self.controls.jump = False

        self.packet = packet
        self.handleTime()

        car = packet.game_cars[self.index]
        position = vec3(car.physics.location.x, car.physics.location.y,
                        car.physics.location.z)

        self.renderer.draw_line_3d(car.physics.location,
                                   position + 300 * normalize(self.target),
                                   self.renderer.yellow())
        self.renderer.draw_line_3d(car.physics.location,
                                   position + 300 * normalize(self.up),
                                   self.renderer.pink())

        carOrientation = rotationToOrientation(car.physics.rotation)
        ang = parseVector(car.physics.angular_velocity)

        if angle_between(carOrientation,
                         self.targetOrientation) > 1 / 180 * math.pi:
            self.lastDoneTick = self.currentTick

        o_rlu = dot(transpose(self.targetOrientation), carOrientation)
        w_rlu = dot(transpose(self.targetOrientation), ang)
        o = torch.tensor([[o_rlu[i, j] for j in range(3)]
                          for i in range(3)])[None, :].float().to(device)
        w = torch.tensor([w_rlu[i]
                          for i in range(3)])[None, :].float().to(device)

        noPitchTime = max(0,
                          (self.lastDodgeTick - self.currentTick) / 120 + .95)
        dodgeTime = max(0, (self.lastDodgeTick - self.currentTick) / 120 + .65)
        if dodgeTime == 0:
            self.dodgeDirection = vec2(0, 0)

        noPitchTime = torch.tensor([noPitchTime]).float().to(device)
        dodgeTime = torch.tensor([dodgeTime]).float().to(device)
        dodgeDirection = torch.tensor([
            self.dodgeDirection[i] for i in range(2)
        ])[None, :].float().to(device)

        # if self.simulation.o is not None and self.simulation.w is not None:
        # 	print("=====================================")
        # 	print("-------------------------------------")
        # 	print(self.simulation.o, o)
        # 	print(self.simulation.w, w)
        # 	print(self.simulation.noPitchTime, noPitchTime)
        # 	print(self.simulation.dodgeTime, dodgeTime)
        # 	print(self.simulation.dodgeDirection, dodgeDirection)
        # 	self.simulation.step(self.ticksNowPassed / 120)
        # 	print(self.simulation.o, o)
        # 	print(self.simulation.w, w)
        # 	print(self.simulation.noPitchTime, noPitchTime)
        # 	print(self.simulation.dodgeTime, dodgeTime)
        # 	print(self.simulation.dodgeDirection, dodgeDirection)

        self.simulation.o = o
        self.simulation.w = w
        self.simulation.noPitchTime = noPitchTime
        self.simulation.dodgeTime = dodgeTime
        self.simulation.dodgeDirection = dodgeDirection

        if True:

            rpy = self.policy(self.simulation.o.permute(0, 2, 1),
                              self.simulation.w_local(),
                              self.simulation.noPitchTime,
                              self.simulation.dodgeTime,
                              self.simulation.dodgeDirection)[0]
            self.controls.roll, self.controls.pitch, self.controls.yaw = rpy

        else:

            self.reorientML.target_orientation = self.targetOrientation
            self.reorientML.step(1 / self.FPS)
            self.controls.roll, self.controls.pitch, self.controls.yaw = self.reorientML.controls.roll, self.reorientML.controls.pitch, self.reorientML.controls.yaw

        if self.simulation.error()[0].item() < 0.01:
            self.frames_done += 1
        else:
            self.frames_done = 0

        if self.frames_done >= 10:
            self.finished = True

        self.renderer.end_rendering()
        return self.controls
Beispiel #26
0
    def step(self, packet: GameTickPacket, drone: Drone, index: int):

        if drone.since_jumped is None:
            # Control throttle start and jump.
            if self.time_since_start > self.delay * (index % 16):
                # Speed controller.
                drone.controls.throttle = 1.0 if max(abs(
                    drone.velocity[0]), abs(drone.velocity[1])) < 500 else 0.03

                # If near half-line
                if norm(vec3(0, 0, 0) - drone.position) < 700:
                    drone.since_jumped = 0.0
                    drone.controls.jump = True

        # Create helix after jump.
        else:
            # Increment timer.
            drone.since_jumped += self.dt

            # HEIGHT
            if drone.since_jumped < 11:
                height = 150 + drone.since_jumped * 150  # speed of rise
            elif drone.since_jumped < 20:
                height = 1800 - (drone.since_jumped - 11) * 150
            else:
                height = 450 + (drone.since_jumped - 16) * 30
                height = min(height, 600)

            # RADIUS
            if drone.since_jumped < 11:
                radius = 500
            elif drone.since_jumped < 15:
                radius = 500 - (drone.since_jumped - 10) * 50
            elif drone.since_jumped < 17:
                radius = 300
            elif drone.since_jumped < 20:
                radius = 300 + (drone.since_jumped - 17) * 100
            else:
                radius = 400 + drone.since_jumped**3 / 10
                radius = min(radius, 2000)

            # ANGLE
            if drone.since_jumped < 11:
                angle = drone.since_jumped * 0.4  # rotation speed
            elif drone.since_jumped < 20:
                angle = (11 * 0.4) + (drone.since_jumped - 11) * 0.6
            else:
                angle = (11 * 0.4) + (9 *
                                      0.6) + (drone.since_jumped - 20) * 0.3

            # Offset angle.
            angle += (index // 16) * (math.pi / 2)

            # Set hover target and controller.
            rot = rotation(angle)
            v = vec3(dot(rot, vec2(1, 0)))
            drone.hover.target = v * radius
            drone.hover.target[2] = height
            drone.hover.up = normalize(drone.position)
            drone.hover.step(self.dt)
            drone.controls = drone.hover.controls

            if drone.since_jumped < 0.05:
                drone.controls.jump = True
                drone.controls.boost = False
Beispiel #27
0
def distance_2d(vec_a, vec_b):
    """returns 2d distance between two vectors"""
    return norm(vec2(vec_a - vec_b))