예제 #1
0
    def set_drone_states(self, drones: List[Drone]):
        # get the length of the path from start to the dragons's head (first bot)
        head_t = self.time_since_start / self.duration * self.path.length

        for drone in drones:
            # offset the other body parts
            drone_t = head_t - self.distance_between_body_parts * (
                drone.id - drones[0].id)

            # if we're not on the path yet, don't do any state setting
            if drone_t < 0:
                continue

            t = self.path.length - drone_t  # because Curve.point_at's argument means distance to end

            pos = self.path.point_at(t)
            pos_ahead = self.path.point_at(t - 500)
            pos_behind = self.path.point_at(t + 300)

            # figure out the orientation of the body part
            facing_direction = direction(pos_behind, pos)
            target_left = cross(facing_direction, direction(pos, pos_ahead))
            target_up = cross(target_left, facing_direction)
            up = drone.up() + target_up * 0.9 + vec3(0, 0, 0.1)
            target_orientation = look_at(facing_direction, up)

            drone.position = pos_behind
            drone.velocity = facing_direction * (self.path.length /
                                                 self.duration)
            drone.angular_velocity = vec3(
                0, 0, 0
            )  # TODO: setting correct angular velocity could help with replays
            drone.orientation = target_orientation
예제 #2
0
 def triangle(self,
              pos: vec3,
              pointing_dir: vec3,
              width=50,
              length=50,
              up=vec3(0, 0, 1)):
     left = pos + cross(pointing_dir, up) * width / 2
     right = pos - cross(pointing_dir, up) * width / 2
     top = pos + pointing_dir * length
     self.cyclic_polyline([left, right, top])
예제 #3
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)
        ]
예제 #4
0
    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))
예제 #5
0
    def simulate_landing(self):
        dummy = Car(self.car)
        self.trajectory = [vec3(dummy.position)]
        self.landing = False
        collision_normal: Optional[vec3] = None

        dt = 1 / 60
        simulation_duration = 0.8
        for i in range(int(simulation_duration / dt)):
            dummy.step(Input(), dt)
            self.trajectory.append(vec3(dummy.position))

            collision_sphere = sphere(dummy.position, 50)
            collision_ray = Field.collide(collision_sphere)
            collision_normal = collision_ray.direction

            if (norm(collision_normal) > 0.0
                    or dummy.position[2] < 0) and i > 20:
                self.landing = True
                self.landing_pos = dummy.position
                break

        if self.landing:
            u = collision_normal
            f = normalize(dummy.velocity - dot(dummy.velocity, u) * u)
            l = normalize(cross(u, f))
            self.aerial_turn.target = mat3(f[0], l[0], u[0], f[1], l[1], u[1],
                                           f[2], l[2], u[2])
        else:
            target_direction = normalize(
                normalize(self.car.velocity) - vec3(0, 0, 3))
            self.aerial_turn.target = look_at(target_direction, vec3(0, 0, 1))
예제 #6
0
    def set_drone_states(self, drones: List[Drone]):
        for drone in drones:
            t = self.time_since_start / self.duration * self.curve.length
            t -= self.distance_between_body_parts * (drone.id -
                                                     self.target_indexes[0])
            t = self.curve.length - t

            pos = self.curve.point_at(t)
            pos_ahead = self.curve.point_at(t - 500)
            pos_behind = self.curve.point_at(t + 30)

            facing_direction = direction(pos_behind, pos)
            target_left = cross(facing_direction, direction(pos, pos_ahead))
            target_up = cross(target_left, facing_direction)
            up = drone.up() + target_up * 0.9 + vec3(0, 0, 0.1)
            target_orientation = look_at(facing_direction, up)

            drone.position = pos
            drone.velocity = facing_direction * (self.curve.length /
                                                 self.duration)
            drone.angular_velocity = vec3(0, 0, 0)
            drone.orientation = target_orientation
예제 #7
0
def rotate_by_axis(orientation: Orientation,
                   original: Vec3,
                   target: Vec3,
                   percent=1) -> Rotator:
    """
    Updates the given orientation's original direction to the target direction.
    original should be `orientation.forward` or `orientation.up` or `orientation.right`
    """
    angle = angle_between(to_rlu_vec(target), to_rlu_vec(original)) * percent
    rotate_axis = cross(to_rlu_vec(target), to_rlu_vec(original))
    ortho = normalize(rotate_axis) * -angle
    rot_mat_initial: mat3 = orientation.to_rot_mat()
    rot_mat_adj = axis_to_rotation(ortho)

    rot_mat = dot(rot_mat_adj, rot_mat_initial)
    r = rot_mat_to_rot(rot_mat)
    # printO(orientation)
    # printO(Orientation(r))
    return r
def roll_away_from_target(target, theta, game_info):
    '''
    Returns an orientation mat3 for an air roll shot.  Turns directly away from the dodge direction (target) by angle theta
    Target can either be RLU vec3, or CowBot Vec3.
    '''

    starting_forward = game_info.utils_game.my_car.forward()
    starting_left = game_info.utils_game.my_car.left()
    starting_up = game_info.utils_game.my_car.up()
    starting_orientation = mat3(starting_forward[0], starting_left[0],
                                starting_up[0], starting_forward[1],
                                starting_left[1], starting_up[1],
                                starting_forward[2], starting_left[2],
                                starting_up[2])
    if type(target) == vec3:
        target = vec3_to_Vec3(target, game_info.team_sign)
    car_to_target = Vec3_to_vec3((target - game_info.me.pos).normalize(),
                                 game_info.team_sign)
    axis = theta * cross(car_to_target, starting_up)
    return dot(axis_to_rotation(axis), starting_orientation)
예제 #9
0
    def step(self, packet: GameTickPacket, drones: List[Drone]):
        orbit_t = max(0, self.time_since_start - self.orbit_start_delay)
        orbit_rotation = self.starting_orbit_rotation + orbit_t * self.orbit_speed

        direction_from_center = dot(
            axis_to_rotation(vec3(0, 0, 1) * orbit_rotation), vec3(1, 0, 0))
        ring_center = self.orbit_center + direction_from_center * self.orbit_radius
        ring_facing_direction = cross(direction_from_center, vec3(0, 0, 1))

        for drone in drones:
            i = drone.id - drones[0].id
            angle = i / len(drones) * pi * 2
            pos = ring_center + dot(
                vec3(0, 0, 1), axis_to_rotation(
                    ring_facing_direction * angle)) * self.ring_radius

            if pos[2] > self.orbit_center[
                    2] + self.ring_radius - self.time_since_start * 200:
                drone.hover.target = pos
                drone.hover.up = ring_facing_direction
                drone.hover.step(self.dt)
                drone.controls = drone.hover.controls
                drone.controls.jump = True
예제 #10
0
    def to_Curve(self, team_sign):
        '''
        Converts the path to an RLU Curve object that can be followed
        '''

        control_points = []

        #The first arc
        direction1 = self.start - self.center1
        starting_angle = atan2(direction1.y, direction1.x)
        steps = ceil(30 * (self.phi1 / (2 * pi)))
        delta = -self.sgn1 * self.phi1 / steps
        center1 = Vec3_to_vec3(self.center1, team_sign)

        for i in range(1, steps - 2):
            angle = starting_angle + delta * i
            next_point = center1 + abs(self.radius1) * vec3(
                cos(angle), sin(angle), 0)
            normal = normalize(next_point - center1)

            next_control_point = ControlPoint()
            next_control_point.p = next_point
            next_control_point.t = cross(normal)
            next_control_point.n = normal
            control_points.append(next_control_point)

        #The line
        steps = max(10, ceil(self.length_line / 300))
        delta = self.length_line / steps
        tangent = Vec3_to_vec3(
            (self.transition2 - self.transition1).normalize(), team_sign)
        normal = cross(tangent)

        for i in range(0, steps + 1):
            next_point = Vec3_to_vec3(self.transition1,
                                      team_sign) + delta * tangent * i

            next_control_point = ControlPoint()
            next_control_point.p = next_point
            next_control_point.t = tangent
            next_control_point.n = normal
            control_points.append(next_control_point)

        #The second arc
        direction2 = self.transition2 - self.center2
        starting_angle = atan2(direction2.y, direction2.x)
        steps = ceil(30 * (self.phi2 / (2 * pi)))
        delta = -self.sgn2 * self.phi2 / steps
        center2 = Vec3_to_vec3(self.center2, team_sign)

        for i in range(1, steps + 1):
            angle = starting_angle + delta * i
            next_point = center2 + abs(self.radius2) * vec3(
                cos(angle), sin(angle), 0)
            normal = normalize(next_point - center2)

            next_control_point = ControlPoint()
            next_control_point.p = next_point
            next_control_point.t = cross(normal)
            next_control_point.n = normal
            control_points.append(next_control_point)

        curve = Curve(control_points)

        self.RLU_curve = curve
        self.discretized_path = [
            vec3_to_Vec3(point.p, team_sign) for point in control_points
        ]