mirror of
https://github.com/dcs-liberation/dcs_liberation.git
synced 2025-11-10 14:22:26 +00:00
changed AWACS orbit to a racetrack (#1826)
* AWACS now orbits in a racetrack. * Update AWACS racetrack length * Increase AWACS threat spacing.
This commit is contained in:
parent
383d1b2c9c
commit
2d07ef717c
@ -809,44 +809,38 @@ class SweepFlightPlan(LoiterFlightPlan):
|
|||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class AwacsFlightPlan(LoiterFlightPlan):
|
class AwacsFlightPlan(PatrollingFlightPlan):
|
||||||
takeoff: FlightWaypoint
|
takeoff: FlightWaypoint
|
||||||
nav_to: List[FlightWaypoint]
|
|
||||||
nav_from: List[FlightWaypoint]
|
|
||||||
land: FlightWaypoint
|
land: FlightWaypoint
|
||||||
divert: Optional[FlightWaypoint]
|
divert: Optional[FlightWaypoint]
|
||||||
bullseye: FlightWaypoint
|
bullseye: FlightWaypoint
|
||||||
|
|
||||||
def iter_waypoints(self) -> Iterator[FlightWaypoint]:
|
@property
|
||||||
yield self.takeoff
|
def patrol_start_time(self) -> timedelta:
|
||||||
yield from self.nav_to
|
return self.package.time_over_target
|
||||||
yield self.hold
|
|
||||||
yield from self.nav_from
|
|
||||||
yield self.land
|
|
||||||
if self.divert is not None:
|
|
||||||
yield self.divert
|
|
||||||
yield self.bullseye
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def mission_start_time(self) -> Optional[timedelta]:
|
def mission_start_time(self) -> Optional[timedelta]:
|
||||||
return self.takeoff_time()
|
return self.takeoff_time()
|
||||||
|
|
||||||
def tot_for_waypoint(self, waypoint: FlightWaypoint) -> Optional[timedelta]:
|
@property
|
||||||
if waypoint == self.hold:
|
def mission_departure_time(self) -> timedelta:
|
||||||
return self.package.time_over_target
|
return self.patrol_start_time + self.patrol_duration
|
||||||
return None
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def tot_waypoint(self) -> Optional[FlightWaypoint]:
|
def tot_waypoint(self) -> Optional[FlightWaypoint]:
|
||||||
return self.hold
|
return self.patrol_start
|
||||||
|
|
||||||
@property
|
def iter_waypoints(self) -> Iterator[FlightWaypoint]:
|
||||||
def push_time(self) -> timedelta:
|
yield self.takeoff
|
||||||
return self.package.time_over_target + self.hold_duration
|
yield from self.nav_to
|
||||||
|
yield self.patrol_start
|
||||||
@property
|
yield self.patrol_end
|
||||||
def mission_departure_time(self) -> timedelta:
|
yield from self.nav_from
|
||||||
return self.push_time
|
yield self.land
|
||||||
|
if self.divert is not None:
|
||||||
|
yield self.divert
|
||||||
|
yield self.bullseye
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
@ -1110,7 +1104,7 @@ class FlightPlanBuilder:
|
|||||||
elif task == FlightType.TARCAP:
|
elif task == FlightType.TARCAP:
|
||||||
return self.generate_tarcap(flight)
|
return self.generate_tarcap(flight)
|
||||||
elif task == FlightType.AEWC:
|
elif task == FlightType.AEWC:
|
||||||
return self.generate_aewc(flight)
|
return self.generate_aewc_racetrack(flight)
|
||||||
elif task == FlightType.TRANSPORT:
|
elif task == FlightType.TRANSPORT:
|
||||||
return self.generate_transport(flight)
|
return self.generate_transport(flight)
|
||||||
elif task == FlightType.REFUELING:
|
elif task == FlightType.REFUELING:
|
||||||
@ -1195,39 +1189,79 @@ class FlightPlanBuilder:
|
|||||||
flight, location, FlightWaypointType.INGRESS_STRIKE, targets
|
flight, location, FlightWaypointType.INGRESS_STRIKE, targets
|
||||||
)
|
)
|
||||||
|
|
||||||
def generate_aewc(self, flight: Flight) -> AwacsFlightPlan:
|
def generate_aewc_racetrack(self, flight: Flight) -> AwacsFlightPlan:
|
||||||
"""Generate a AWACS flight at a given location.
|
"""Generate a AWACS flight in racetrack orbit.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
flight: The flight to generate the flight plan for.
|
flight: The flight to generate the flight plan for.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
racetrack_half_distance = Distance.from_nautical_miles(30).meters
|
||||||
|
|
||||||
|
patrol_duration = timedelta(hours=4)
|
||||||
|
|
||||||
location = self.package.target
|
location = self.package.target
|
||||||
|
|
||||||
orbit_location = self.aewc_orbit(location)
|
closest_boundary = self.threat_zones.closest_boundary(location.position)
|
||||||
|
heading_to_threat_boundary = Heading.from_degrees(
|
||||||
|
location.position.heading_between_point(closest_boundary)
|
||||||
|
)
|
||||||
|
distance_to_threat = meters(
|
||||||
|
location.position.distance_to_point(closest_boundary)
|
||||||
|
)
|
||||||
|
orbit_heading = heading_to_threat_boundary
|
||||||
|
|
||||||
if flight.unit_type.patrol_altitude is not None:
|
# Station 80nm outside the threat zone.
|
||||||
patrol_alt = flight.unit_type.patrol_altitude
|
threat_buffer = nautical_miles(80)
|
||||||
|
if self.threat_zones.threatened(location.position):
|
||||||
|
orbit_distance = distance_to_threat + threat_buffer
|
||||||
else:
|
else:
|
||||||
patrol_alt = feet(25000)
|
orbit_distance = distance_to_threat - threat_buffer
|
||||||
|
|
||||||
|
racetrack_center = location.position.point_from_heading(
|
||||||
|
orbit_heading.degrees, orbit_distance.meters
|
||||||
|
)
|
||||||
|
|
||||||
|
racetrack_start = racetrack_center.point_from_heading(
|
||||||
|
orbit_heading.right.degrees, racetrack_half_distance
|
||||||
|
)
|
||||||
|
|
||||||
|
racetrack_end = racetrack_center.point_from_heading(
|
||||||
|
orbit_heading.left.degrees, racetrack_half_distance
|
||||||
|
)
|
||||||
|
|
||||||
builder = WaypointBuilder(flight, self.coalition)
|
builder = WaypointBuilder(flight, self.coalition)
|
||||||
orbit = builder.orbit(orbit_location, patrol_alt)
|
|
||||||
|
if flight.unit_type.patrol_altitude is not None:
|
||||||
|
altitude = flight.unit_type.patrol_altitude
|
||||||
|
else:
|
||||||
|
altitude = feet(25000)
|
||||||
|
|
||||||
|
if flight.unit_type.preferred_patrol_speed(altitude) is not None:
|
||||||
|
speed = flight.unit_type.preferred_patrol_speed(altitude)
|
||||||
|
else:
|
||||||
|
speed = knots(390)
|
||||||
|
|
||||||
|
racetrack = builder.race_track(racetrack_start, racetrack_end, altitude)
|
||||||
|
|
||||||
return AwacsFlightPlan(
|
return AwacsFlightPlan(
|
||||||
package=self.package,
|
package=self.package,
|
||||||
flight=flight,
|
flight=flight,
|
||||||
takeoff=builder.takeoff(flight.departure),
|
takeoff=builder.takeoff(flight.departure),
|
||||||
nav_to=builder.nav_path(
|
nav_to=builder.nav_path(
|
||||||
flight.departure.position, orbit.position, patrol_alt
|
flight.departure.position, racetrack_start, altitude
|
||||||
),
|
|
||||||
nav_from=builder.nav_path(
|
|
||||||
orbit.position, flight.arrival.position, patrol_alt
|
|
||||||
),
|
),
|
||||||
|
nav_from=builder.nav_path(racetrack_end, flight.arrival.position, altitude),
|
||||||
|
patrol_start=racetrack[0],
|
||||||
|
patrol_end=racetrack[1],
|
||||||
land=builder.land(flight.arrival),
|
land=builder.land(flight.arrival),
|
||||||
divert=builder.divert(flight.divert),
|
divert=builder.divert(flight.divert),
|
||||||
bullseye=builder.bullseye(),
|
bullseye=builder.bullseye(),
|
||||||
hold=orbit,
|
patrol_duration=patrol_duration,
|
||||||
hold_duration=timedelta(hours=4),
|
patrol_speed=speed,
|
||||||
|
# TODO: Factor out a common base of the combat and non-combat race-tracks.
|
||||||
|
# No harm in setting this, but we ought to clean up a bit.
|
||||||
|
engagement_distance=meters(0),
|
||||||
)
|
)
|
||||||
|
|
||||||
def generate_bai(self, flight: Flight) -> FlightPlan:
|
def generate_bai(self, flight: Flight) -> FlightPlan:
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user