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) ]
def step(self, packet: GameTickPacket, drone: Drone, index: int): drone.hover.up = normalize(drone.position) clockwise_rotation = axis_to_rotation(vec3(0, 0, 0.5)) position_on_circle = normalize(xy(drone.position)) * 2000 drone.hover.target = dot(clockwise_rotation, position_on_circle) drone.hover.target[2] = 1000 drone.hover.step(self.dt) drone.controls = drone.hover.controls
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
def step(self, packet: GameTickPacket, drone: Drone, index: int): for i, layer in enumerate(self.layers): if index in layer: drone.hover.up = normalize(drone.position) clockwise_rotation = axis_to_rotation(vec3(0, 0, 0.3)) position_on_circle = normalize(xy( drone.position)) * self.radii[i] drone.hover.target = dot(clockwise_rotation, position_on_circle) drone.hover.target[2] = self.heights[i] break drone.hover.step(self.dt) drone.controls = drone.hover.controls
def step(self, packet: GameTickPacket, drone: Drone, index: int): drone.hover.up = normalize(drone.position) rotation = axis_to_rotation(vec3(0, 0, self.spin * (-1)**(index // 16))) position_on_circle = normalize(xy(drone.position)) * ( self.radius + self.radius_increase * self.time_since_start) drone.hover.target = dot(rotation, position_on_circle) drone.hover.target[ 2] = self.height + self.height_increase * self.time_since_start drone.hover.target[2] += (index // 16 - 2) * ( self.height_diff + self.height_diff_increase * self.time_since_start) drone.hover.step(self.dt) drone.controls = drone.hover.controls
def step(self, packet: GameTickPacket, drone: Drone, index: int): # Just ask me in discord about this. layer = (2 * (index // 16) + (index % 2) - 3.5) / 4 height = self.height + layer * self.radius radius = math.sqrt(1 - layer**2) * self.radius spin = 0 if self.time_since_start < 3.0 else 0.5 drone.hover.up = normalize(drone.position) rotation = axis_to_rotation(vec3(0, 0, spin)) position_on_circle = normalize(xy(drone.position)) * radius drone.hover.target = dot(rotation, position_on_circle) drone.hover.target[2] = height drone.hover.step(self.dt) drone.controls = drone.hover.controls
def determine_max_speed(self, local_target): low = 100 high = 2200 if self.kickoff: return high for i in range(5): mid = (low + high) / 2 radius = (1 / RLUDrive.max_turning_curvature(mid)) local_circle = vec3(0, copysign(radius, local_target[1]), 0) dist = norm(local_circle - xy(local_target)) if dist < radius: high = mid else: low = mid return high
def step(self, dt: float): self.speed = abs(self.speed) car_to_target = (self.target - self.car.location) local_target = dot(car_to_target, self.car.rotation) angle = atan2(local_target[1], local_target[0]) vel = norm(self.car.velocity) in_air = (not self.car.on_ground) on_wall = (self.car.location[2] > 250 and not in_air) reverse = (cos(angle) < 0 and not (on_wall or in_air or self.kickoff)) get_off_wall = (on_wall and local_target[2] > 450) if get_off_wall: car_to_target[2] = -self.car.location[2] local_target = dot(car_to_target, self.car.rotation) angle = atan2(local_target[1], local_target[0]) max_speed = self.determine_max_speed(local_target) self.update_rlu_drive(reverse, max_speed) self.rlu_drive.step(dt) self.finished = self.rlu_drive.finished self.controls = self.rlu_drive.controls self.controls.handbrake = False if reverse: angle = -invert_angle(angle) if self.power_turn and not on_wall: angle *= -1 self.controls.handbrake = (vel > 200) self.controls.steer = cap(angle * 3, -1, 1) self.controls.boost = False if not self.controls.handbrake: self.controls.handbrake = (abs(angle) > radians(70) and vel > 500 and not on_wall) if self.controls.handbrake: self.controls.handbrake = (dot(self.car.velocity, car_to_target) > -150) if in_air: self.aerial_turn.target = look_at(xy(car_to_target), vec3(0, 0, 1)) self.aerial_turn.step(dt) aerial_turn_controls = self.aerial_turn.controls self.controls.pitch = aerial_turn_controls.pitch self.controls.yaw = aerial_turn_controls.yaw self.controls.roll = aerial_turn_controls.roll self.controls.boost = False
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
def step(self, dt): if self.car.on_ground and norm(self.car.position + self.car.velocity - xy(self.target)) > 2500: self.drive.speed = 1000 self.drive.target = self.target self.drive.step(dt) self.controls = self.drive.controls self.controls.handbrake = angle_between(self.car.forward(), self.target - self.car.position) > 1.2 return self.hover.target = self.target self.hover.up = normalize(self.car.position * -1) self.hover.step(dt) self.controls = self.hover.controls self.controls.throttle = not self.car.on_ground self.controls.jump = (self.car.position[2] < 30 or self.car.on_ground) and self.__time_spent_on_ground > 0.1 if self.info.round_active: self.__time_spent_on_ground += dt if not self.car.on_ground: self.__time_spent_on_ground = 0.0
def step(self, dt): time_left = self.aerial.arrival_time - self.car.time if self.aerialing: to_ball = direction(self.car, self.info.ball) # freestyling if self.car.position[2] > 200: # if time_left > 0.7: # rotation = axis_to_rotation(self.car.forward() * 0.5) # self.aerial.up = dot(rotation, self.car.up()) # else: self.aerial.up = vec3(0, 0, -1) + xy(to_ball) self.aerial.target_orientation = look_at(to_ball, vec3(0, 0, -3) + to_ball) self.aerial.step(dt) self.controls = self.aerial.controls self.finished = self.aerial.finished and time_left < -0.3 else: super().step(dt) # simulate aerial from current state simulated_car = self.simulate_flight(self.car, self.aerial, self._flight_path) speed_towards_target = dot( self.car.velocity, ground_direction(self.car, self.aerial.target_position)) speed_needed = ground_distance( self.car, self.aerial.target_position) / time_left # too fast, slow down if speed_towards_target > speed_needed and angle_to( self.car, self.aerial.target_position) < 0.1: self.controls.throttle = -1 # if it ended up near the target, we could take off elif distance( simulated_car, self.aerial.target_position) < self.MAX_DISTANCE_ERROR: if angle_to(self.car, self.aerial.target_position) < 0.1 or norm( self.car.velocity) < 1000: if self.DELAY_TAKEOFF and ground_distance( self.car, self.aerial.target_position) > 1000: # extrapolate current state a small amount of time future_car = Car(self.car) time = 0.5 future_car.time += time displacement = future_car.velocity * time if norm(future_car.velocity) > 500\ else normalize(future_car.velocity) * 500 * time future_car.position += displacement # simulate aerial fot the extrapolated car again future_simulated_car = self.simulate_flight( future_car, self.aerial) # if the aerial is also successful, that means we should continue driving instead of taking off # this makes sure that we go for the most late possible aerials, which are the most effective if distance(future_simulated_car, self.aerial. target_position) > self.MAX_DISTANCE_ERROR: self.aerialing = True else: self.too_early = True else: self.aerialing = True else: # self.controls.boost = True self.controls.throttle = 1
def angle_to(car: Car, target: vec3, backwards=False) -> float: return abs(angle_between(xy(car.forward()) * (-1 if backwards else 1), ground_direction(car.position, target)))