Differentiate total time and travel time.

There's an ugly special case in flight simulation to handle hold points
because we don't differentiate between the total time between two
waypoints (which can include delays from actions like holding) and
travel time. Split those up and remove the special case.
This commit is contained in:
Dan Albert 2023-08-13 11:16:14 -07:00
parent bf1e559a41
commit 59756ce14c
6 changed files with 21 additions and 19 deletions

View File

@ -214,7 +214,7 @@ class FlightPlan(ABC, Generic[LayoutT]):
)
for previous_waypoint, waypoint in self.edges(until=destination):
total += self.travel_time_between_waypoints(previous_waypoint, waypoint)
total += self.total_time_between_waypoints(previous_waypoint, waypoint)
# Trim microseconds. Our simulation tick rate is 1 second, so anything that
# takes 100.1 or 100.9 seconds will take 100 seconds. DCS doesn't handle
@ -223,6 +223,16 @@ class FlightPlan(ABC, Generic[LayoutT]):
# model.
return timedelta(seconds=math.floor(total.total_seconds()))
def total_time_between_waypoints(
self, a: FlightWaypoint, b: FlightWaypoint
) -> timedelta:
"""Returns the total time spent between a and b.
The total time between waypoints differs from the travel time in that it may
include additional time for actions such as loitering.
"""
return self.travel_time_between_waypoints(a, b)
def travel_time_between_waypoints(
self, a: FlightWaypoint, b: FlightWaypoint
) -> timedelta:

View File

@ -57,17 +57,17 @@ class FormationAttackFlightPlan(FormationFlightPlan, ABC):
@property
def join_time(self) -> datetime:
travel_time = self.travel_time_between_waypoints(
travel_time = self.total_time_between_waypoints(
self.layout.join, self.layout.ingress
)
return self.ingress_time - travel_time
@property
def split_time(self) -> datetime:
travel_time_ingress = self.travel_time_between_waypoints(
travel_time_ingress = self.total_time_between_waypoints(
self.layout.ingress, self.target_area_waypoint
)
travel_time_egress = self.travel_time_between_waypoints(
travel_time_egress = self.total_time_between_waypoints(
self.target_area_waypoint, self.layout.split
)
minutes_at_target = 0.75 * len(self.layout.targets)
@ -82,7 +82,7 @@ class FormationAttackFlightPlan(FormationFlightPlan, ABC):
@property
def ingress_time(self) -> datetime:
tot = self.tot
travel_time = self.travel_time_between_waypoints(
travel_time = self.total_time_between_waypoints(
self.layout.ingress, self.target_area_waypoint
)
return tot - travel_time

View File

@ -33,10 +33,10 @@ class LoiterFlightPlan(StandardFlightPlan[Any], ABC):
return self.push_time
return None
def travel_time_between_waypoints(
def total_time_between_waypoints(
self, a: FlightWaypoint, b: FlightWaypoint
) -> timedelta:
travel_time = super().travel_time_between_waypoints(a, b)
travel_time = super().total_time_between_waypoints(a, b)
if a != self.layout.hold:
return travel_time
return travel_time + self.hold_duration

View File

@ -59,10 +59,10 @@ class PackageRefuelingFlightPlan(RefuelingFlightPlan):
"REFUEL", FlightWaypointType.REFUEL, refuel, altitude
)
delay_target_to_split: timedelta = self.travel_time_between_waypoints(
delay_target_to_split: timedelta = self.total_time_between_waypoints(
self.target_area_waypoint(), split_waypoint
)
delay_split_to_refuel: timedelta = self.travel_time_between_waypoints(
delay_split_to_refuel: timedelta = self.total_time_between_waypoints(
split_waypoint, refuel_waypoint
)

View File

@ -55,7 +55,7 @@ class SweepFlightPlan(LoiterFlightPlan):
@property
def sweep_start_time(self) -> datetime:
travel_time = self.travel_time_between_waypoints(
travel_time = self.total_time_between_waypoints(
self.layout.sweep_start, self.layout.sweep_end
)
return self.sweep_end_time - travel_time

View File

@ -51,17 +51,9 @@ class InFlight(FlightState, ABC):
return index <= self.waypoint_index
def travel_time_between_waypoints(self) -> timedelta:
travel_time = self.flight.flight_plan.travel_time_between_waypoints(
return self.flight.flight_plan.travel_time_between_waypoints(
self.current_waypoint, self.next_waypoint
)
if self.current_waypoint.waypoint_type is FlightWaypointType.LOITER:
# Loiter time is already built into travel_time_between_waypoints. If we're
# at a loiter point but still a regular InFlight (Loiter overrides this
# method) that means we're traveling from the loiter point but no longer
# loitering.
assert self.flight.flight_plan.is_loiter(self.flight.flight_plan)
travel_time -= self.flight.flight_plan.hold_duration
return travel_time
@abstractmethod
def estimate_position(self) -> Point: