mirror of
https://github.com/dcs-liberation/dcs_liberation.git
synced 2025-11-10 14:22:26 +00:00
Improve flight plan layout for untheatened IPs.
Try all the nav points between the origin and the target rather than just the first non-threatened point. This prevents us from using the fallback behavior for any target that's sufficiently far from the package airfield.
This commit is contained in:
parent
a1910f49a8
commit
f7bbe0fa94
@ -959,30 +959,14 @@ class FlightPlanBuilder:
|
|||||||
raise PlanningError(f"{task} flight plan generation not implemented")
|
raise PlanningError(f"{task} flight plan generation not implemented")
|
||||||
|
|
||||||
def regenerate_package_waypoints(self) -> None:
|
def regenerate_package_waypoints(self) -> None:
|
||||||
# The simple case is where the target is greater than the ingress
|
# The simple case is where the target is not near the departure airfield. In
|
||||||
# distance into the threat zone and the target is not near the departure
|
# this case, we can plan the shortest route from the departure airfield to the
|
||||||
# airfield. In this case, we can plan the shortest route from the
|
# target, use the nearest non-threatened point *that's farther from the target
|
||||||
# departure airfield to the target, use the last non-threatened point as
|
# than the ingress point to avoid backtracking) as the join point.
|
||||||
# the join point, and plan the IP inside the threatened area.
|
|
||||||
#
|
|
||||||
# When the target is near the edge of the threat zone the IP may need to
|
|
||||||
# be placed outside the zone.
|
|
||||||
#
|
|
||||||
# +--------------+ +---------------+
|
|
||||||
# | | | |
|
|
||||||
# | | IP---+-T |
|
|
||||||
# | | | |
|
|
||||||
# | | | |
|
|
||||||
# +--------------+ +---------------+
|
|
||||||
#
|
|
||||||
# Here we want to place the IP first and route the flight to the IP
|
|
||||||
# rather than routing to the target and placing the IP based on the join
|
|
||||||
# point.
|
|
||||||
#
|
#
|
||||||
# The other case that we need to handle is when the target is close to
|
# The other case that we need to handle is when the target is close to
|
||||||
# the origin airfield. In this case we also need to set up the IP first,
|
# the origin airfield. In this case we currently fall back to the old planning
|
||||||
# but depending on the placement of the IP we may need to place the join
|
# behavior.
|
||||||
# point in a retreating position.
|
|
||||||
#
|
#
|
||||||
# A messy (and very unlikely) case that we can't do much about:
|
# A messy (and very unlikely) case that we can't do much about:
|
||||||
#
|
#
|
||||||
@ -996,21 +980,18 @@ class FlightPlanBuilder:
|
|||||||
|
|
||||||
target = self.package.target.position
|
target = self.package.target.position
|
||||||
|
|
||||||
join_point = self.preferred_join_point()
|
for join_point in self.preferred_join_points():
|
||||||
if join_point is None:
|
join_distance = meters(join_point.distance_to_point(target))
|
||||||
# The whole path from the origin airfield to the target is
|
if join_distance > self.doctrine.ingress_egress_distance:
|
||||||
# threatened. Need to retreat out of the threat area.
|
break
|
||||||
join_point = self.retreat_point(self.package_airfield().position)
|
else:
|
||||||
|
# The entire path to the target is threatened. Use the fallback behavior for
|
||||||
|
# now.
|
||||||
|
self.legacy_package_waypoints_impl()
|
||||||
|
return
|
||||||
|
|
||||||
attack_heading = join_point.heading_between_point(target)
|
attack_heading = join_point.heading_between_point(target)
|
||||||
ingress_point = self._ingress_point(attack_heading)
|
ingress_point = self._ingress_point(attack_heading)
|
||||||
join_distance = meters(join_point.distance_to_point(target))
|
|
||||||
ingress_distance = meters(ingress_point.distance_to_point(target))
|
|
||||||
if join_distance < ingress_distance:
|
|
||||||
# The second case described above. The ingress point is farther from
|
|
||||||
# the target than the join point. Use the fallback behavior for now.
|
|
||||||
self.legacy_package_waypoints_impl()
|
|
||||||
return
|
|
||||||
|
|
||||||
# The first case described above. The ingress and join points are placed
|
# The first case described above. The ingress and join points are placed
|
||||||
# reasonably relative to each other.
|
# reasonably relative to each other.
|
||||||
@ -1031,7 +1012,7 @@ class FlightPlanBuilder:
|
|||||||
ingress_point = self._ingress_point(self._target_heading_to_package_airfield())
|
ingress_point = self._ingress_point(self._target_heading_to_package_airfield())
|
||||||
egress_point = self._egress_point(self._target_heading_to_package_airfield())
|
egress_point = self._egress_point(self._target_heading_to_package_airfield())
|
||||||
join_point = self._rendezvous_point(ingress_point)
|
join_point = self._rendezvous_point(ingress_point)
|
||||||
split_point = self._rendezvous_point(egress_point)
|
split_point = self._rendezvous_point(self.package.target.position)
|
||||||
self.package.waypoints = PackageWaypoints(
|
self.package.waypoints = PackageWaypoints(
|
||||||
join_point,
|
join_point,
|
||||||
ingress_point,
|
ingress_point,
|
||||||
@ -1039,14 +1020,16 @@ class FlightPlanBuilder:
|
|||||||
split_point,
|
split_point,
|
||||||
)
|
)
|
||||||
|
|
||||||
def preferred_join_point(self) -> Optional[Point]:
|
def preferred_join_points(self) -> Iterator[Point]:
|
||||||
path = self.coalition.nav_mesh.shortest_path(
|
path = self.coalition.nav_mesh.shortest_path(
|
||||||
self.package_airfield().position, self.package.target.position
|
self.package_airfield().position, self.package.target.position
|
||||||
)
|
)
|
||||||
for point in reversed(path):
|
# Use non-threatened points along the path to the target (excluding the target
|
||||||
|
# itself) as the join point. We may need to try more than one in the event that
|
||||||
|
# the close non-threatened points are closer than the ingress point itself.
|
||||||
|
for point in reversed(path[:-1]):
|
||||||
if not self.threat_zones.threatened(point):
|
if not self.threat_zones.threatened(point):
|
||||||
return point
|
yield point
|
||||||
return None
|
|
||||||
|
|
||||||
def generate_strike(self, flight: Flight) -> StrikeFlightPlan:
|
def generate_strike(self, flight: Flight) -> StrikeFlightPlan:
|
||||||
"""Generates a strike flight plan.
|
"""Generates a strike flight plan.
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user