Trajectory builders
This is a system of organization for the different classes that do trajectory simulation.
The basic idea here is to separate the logic of flying trajectories from the
data container representing a trajectory (the Trajectory class and the
associated idea of field sets), and to allow for easy swapping of different
trajectory building algorithms (the current AEIC v2 “legacy” one, and later
TASOPT-based, simulations based on ADS-B data, or whatever). The builder API
has a base abstract Builder class, plus a concrete class derived from that
for each type of trajectory builder. (The only one of these that’s fully
implemented so far is LegacyBuilder, which does AEIC v2 trajectories.) Each
builder class has an options class that wraps up any options that the builder
supports. The main method used to simulate a trajectory is called fly: you
pass a performance model and a mission and get back a trajectory.
The part of all this that probably requires some explanation is the Context
classes. Each of the trajectory builders will have state that it needs to keep
track of during the calculations that go on in the fly method and the
subsidiary methods that fly calls. Instead of either a). threading lots of
parameters through all the function calls; or b). having a bunch of instance
variables on the builder classes that have poorly defined lifecycles and
initialization states (lots of things being set to None in constructors, for
example), there is the idea of a “context”, which is a separate object which
maintains all of the required state in one place. Because there is a single
context object whose lifecycle is bounded by any particular call to the fly
method, managing the lifecycle is easy. To avoid saying
self.context.whatever all over the place, there is some more Python magic
using __getattr__ to route attribute accesses on the builder to the context
instead. It ends up being quite comfortable to program against. (One
disadvantage is that it isn’t thread-safe: if you share a trajectory builder
across threads, the context will get mixed up. But trajectory builders are
lightweight things, so it’s not a problem to create them in each thread where
you need one.)
You can see how all of this works together in the
tests/test_trajectory_simulation.py test file. There’s a test function there
that simulates a list of sample missions from an input file, saves them to a
NetCDF file and reloads them.
A trajectory builderr class should have a fly_... method for each flight
phase that it implements, e.g. fly_climb, fly_cruise, fly_descent at a
minimum. These methods are passed the Trajectory being constructed, plus a
set of additional builder-specific keyword arguments passed through from
fly, used for any builder-specific specials.
Documentation for the base Builder class is currently sparse, and the best
reference to how to use these things is to look at the LegacyBuilder
implementation. Actually using the trajectory builders is simple, but
implementing a builder is more complicated!
Warning
Some of this code is definitely unfinished. There needs to be a way to incrementally extend trajectories instead of having to specify the length of the trajectory up-front, and there needs to be a smoother API for the builders to save trajectory data for different flight phases. At the moment, there are no helper methods to deal with the “extra” LTO flight phases at all.
- class AEIC.trajectories.builders.base.Builder(options: Options = Options(optimize_traj=False, iterate_mass=True, use_weather=False, max_mass_iters=5, mass_iter_reltol=0.01), *args, **kwargs)
Abstract parent class for all AEIC trajectory builders. Contains overall fly logic.
- options
Options for trajectory building.
- Type:
Options
- CONTEXT_CLASS: type | None = None
Class for trajectory building context. Should be derived from base Context class.
- abstractmethod calc_starting_mass(**kwargs) float
Calculate the starting mass of the aircraft for the flight.
- fly(ac_performance: PerformanceModel, mission: Mission, starting_mass: float | None = None, **kwargs) Trajectory
Top-level function that initiates and runs flights.
As well as the fixed arguments listed below, this can also take builder-specific additional keyword arguments.
- Parameters:
ac_performance (PerformanceModel) – Performance model used for trajectory simulation.
mission (Mission) – Data dictating the mission to be flown (departure/arrival info, etc.).
startMass (float, optional) – Starting mass of the aircraft; leave as default to calculate starting mass during simulation.
- Returns:
Trajectory object.
- Return type:
trajectory (Trajectory)
- property n_climb: int
Number of trajectory points in climb phase.
- property n_cruise: int
Number of trajectory points in cruise phase.
- property n_descent: int
Number of trajectory points in descent phase.
- property n_total: int
Total number of trajectory points.
Legacy trajectory builder
The legacy trajectory relies on BADA-3-like performane data in the AEIC performance data format. Specifically, it requires data that has prescribed climb and descent profiles, as well as cruise data at a single altitude (\(7000\,\text{ft}\) below operating ceiling).
- class AEIC.trajectories.builders.legacy.LegacyBuilder(options: Options = Options(optimize_traj=False, iterate_mass=True, use_weather=False, max_mass_iters=5, mass_iter_reltol=0.01), legacy_options: LegacyOptions = LegacyOptions(pct_step_clm=0.01, pct_step_crz=0.01, pct_step_des=0.01, fuel_LHV=43800000.0), *args, **kwargs)
Model for determining flight trajectories using the legacy method from AEIC v2.
- Parameters:
options (Options) – Base options for trajectory building.
legacy_options (LegactyOptions) – Builder-specific options for legacy trajectory builder.
- CONTEXT_CLASS
alias of
LegacyContext
- calc_starting_mass(**kwargs) float
Calculates the starting mass using AEIC v2 methods. Sets both starting mass and non-reserve/hold/divert fuel mass.
- fly_climb(traj: Trajectory, **kwargs) None
Simulate climb phase.
Computes state over the climb segment using AEIC v2 methods based on BADA-3 formulas.
- fly_cruise(traj: Trajectory, **kwargs)
Simulate cruise phase.
Computes state over cruise segment using AEIC v2 methods based on BADA-3 formulas
- fly_descent(traj: Trajectory, **kwargs)
Simulate descent phase.
Computes state over the descent segment using AEIC v2 methods based on BADA-3 formulas
- class AEIC.trajectories.builders.legacy.LegacyContext(builder: LegacyBuilder, ac_performance: PerformanceModel, mission: Mission, starting_mass: float | None)
Context for legacy trajectory builder.
- class AEIC.trajectories.builders.legacy.LegacyOptions(pct_step_clm: float = 0.01, pct_step_crz: float = 0.01, pct_step_des: float = 0.01, fuel_LHV: float = 43800000.0)
Additional options for the legacy trajectory builder.
- fuel_LHV: float = 43800000.0
Lower heating value of the fuel used.
- pct_step_clm: float = 0.01
Climb step size as percentage of total climb altitude change.
- pct_step_crz: float = 0.01
Cruise step size as percentage of total cruise ground distance.
- pct_step_des: float = 0.01
Descent step size as percentage of total descent altitude change.