FLOPS Based Detailed Takeoff and Landing#

Note

This doc page details the Level 3 API for FLOPS-based detailed takeoff and landing. This is useful for advanced users who want to model these flight phases and have supreme control over how the problem is set up. For a simpler and slightly more limited experience, please see the Level 2 takeoff and landing examples.

Aviary support of FLOPS based detailed takeoff and landing is implemented in terms of user options, initial guesses, and different types of builders. User options and initial guesses are often collected in AviaryValues objects, which are then used to setup different builders. Builders are used to create analysis components. The builders for takeoff and landing can be separated into three general categories: aerodynamics, phases, and trajectories. The following sections describe which builders are associated with takeoff and landing and how to generally use them.

The following code excerpts were copied from Aviary validation data and benchmarks. For a more complete working example, with appropriate support for drivers, see the following files:

Takeoff#

Aerodynamics Builder#

Both takeoff and landing are designed to use the FLOPS-derived low_speed aerodynamics method defined in the CoreAerodynamicsBuilder. The builder supports several options specified in a subsystem_options dictionary provided to the phase builder. The most important subsystem options are the three required sequences: angles_of_attack, lift_coefficients, and drag_coefficients. At least two values must be specified in angles_of_attack. For each value in angles_of_attack, there must be one dependent value at the corresponding index in each of lift_coefficients and drag_coefficients.

Once a CoreAerodynamicsBuilder object is created, it can be used to create a phase builder. The phase builder will pass the aerodynamics builder down to where it is needed to create appropriate aerodynamics analysis components. A single CoreAerodynamicsBuilder object can be shared with different phase builders. Subsystem options can also often be shared by different phase builders. In most cases, values like angles_of_attack, lift_coefficients, drag_coefficients, and a few others are identical across all phases of takeoff/landing trajectory, even if other option values vary by phase.

from aviary.api import Dynamic, Mission

import aviary.api as av

from aviary.models.N3CC.N3CC_data import inputs

aviary_options = inputs.deepcopy()

# This builder can be used for both takeoff and landing phases
aero_builder = av.CoreAerodynamicsBuilder(
    name='low_speed_aero',
    code_origin=av.LegacyCode.FLOPS
)

takeoff_subsystem_options = {'low_speed_aero': {
    'method': 'low_speed',
    'ground_altitude': 0.,  # units='m'
    'angles_of_attack': [
        0.0, 1.0, 2.0, 3.0, 4.0, 5.0,
        6.0, 7.0, 8.0, 9.0, 10.0, 11.0,
        12.0, 13.0, 14.0, 15.0],  # units='deg'
    'lift_coefficients': [
        0.5178, 0.6, 0.75, 0.85, 0.95, 1.05,
        1.15, 1.25, 1.35, 1.5, 1.6, 1.7,
        1.8, 1.85, 1.9, 1.95],
    'drag_coefficients': [
        0.0674, 0.065, 0.065, 0.07, 0.072, 0.076,
        0.084, 0.09, 0.10, 0.11, 0.12, 0.13,
        0.15, 0.16, 0.18, 0.20],
    'lift_coefficient_factor': 1.,
    'drag_coefficient_factor': 1.}}

# when using spoilers, add a few more options
takeoff_spoiler_subsystem_options = {'low_speed_aero': {
    **takeoff_subsystem_options['low_speed_aero'],
    'use_spoilers': True,
    'spoiler_drag_coefficient': inputs.get_val(Mission.Takeoff.SPOILER_DRAG_COEFFICIENT),
    'spoiler_lift_coefficient': inputs.get_val(Mission.Takeoff.SPOILER_LIFT_COEFFICIENT)}}

# We also need propulsion analysis for takeoff and landing. No additional configuration
# is needed for this builder
engine = av.build_engine_deck(aviary_options)
prop_builder = av.CorePropulsionBuilder(engine_models=engine)
/usr/share/miniconda/envs/test/lib/python3.12/site-packages/pyoptsparse/pyOpt_MPI.py:68: UserWarning: mpi4py could not be imported. mpi4py is required to use the parallel gradient analysis and parallel objective analysis for non-gradient based optimizers. Continuing using a dummy MPI module from pyOptSparse.
  warnings.warn(warn)

Phase Builders#

There are eleven types of phase builders for takeoff. In general, the following phase builders are always required:

  • TakeoffBrakeReleaseToDecisionSpeed : a phase builder for the first phase of takeoff, from brake release to decision speed, the maximum speed at which takeoff can be safely brought to full stop using zero thrust while braking;

  • TakeoffDecisionSpeedToRotate : a phase builder for the second phase of takeoff, from decision speed to rotation;

  • TakeoffRotateToLiftoff : a phase builder for the third phase of takeoff, from rotation to liftoff;

  • TakeoffLiftoffToObstacle : a phase builder for the fourth phase of takeoff, from liftoff to clearing the required obstacle.

The following phase builders are only required if acoustic calculations are required:

  • TakeoffObstacleToMicP2 : a phase builder for the fifth phase of takeoff, from clearing the required obstacle to the P2 mic location;

  • TakeoffMicP2ToEngineCutback : a phase builder for the sixth phase of takeoff, from the P2 mic location to engine cutback;

  • TakeoffEngineCutback : a phase builder for the seventh phase of takeoff, from start to finish of engine cutback;

  • TakeoffEngineCutbackToMicP1 : a phase builder for the eighth phase of takeoff, from engine cutback to the P1 mic location;

  • TakeoffMicP1ToClimb : a phase builder for the ninth phase of takeoff, from P1 mic location to climb.

The following phase builders are only required if balanced field length calculations are required:

  • TakeoffDecisionSpeedBrakeDelay : a phase builder for the second phase of aborted takeoff, from decision speed to brake application;

  • TakeoffBrakeToAbort : a phase builder for the last phase of aborted takeoff, from brake application to full stop.

When creating any of these phase builders, the following data should first be collected and passed to the builder during creation: subsystem builders, subsystem options, user options, and initial guesses. The subsystem builders and options are created as described in the previous section. User options are collected in an AviaryValues object. Each type of phase builder supports its own set of user options, with associated default values. Initial guesses are collected in an AviaryValues object separate from the user options. Each type of phase builder supports its own set of initial guesses; initial guesses have no default values and are required.

Once the required phase builders are created, they can be used to create a trajectory builder. The trajectory builder will then use the phase builders to create phase analysis components as required to be added to a trajectory analysis component.

takeoff_brake_release_user_options = av.AviaryValues()

takeoff_brake_release_user_options.set_val('max_duration', val=60.0, units='s')
takeoff_brake_release_user_options.set_val('duration_ref', val=60.0, units='s')
takeoff_brake_release_user_options.set_val('distance_max', val=7500.0, units='ft')
takeoff_brake_release_user_options.set_val('max_velocity', val=167.85, units='kn')

takeoff_brake_release_initial_guesses = av.AviaryValues()

takeoff_brake_release_initial_guesses.set_val('time', [0., 30.], 's')
takeoff_brake_release_initial_guesses.set_val('distance', [0., 4100.], 'ft')
takeoff_brake_release_initial_guesses.set_val('velocity', [0.01, 150.], 'kn')

gross_mass_units = 'lbm'
gross_mass = inputs.get_val(Mission.Design.GROSS_MASS, gross_mass_units)
takeoff_brake_release_initial_guesses.set_val('mass', gross_mass, gross_mass_units)

takeoff_brake_release_initial_guesses.set_val('throttle', 1.)
takeoff_brake_release_initial_guesses.set_val('angle_of_attack', 0., 'deg')

takeoff_brake_release_builder = av.DetailedTakeoffBrakeReleaseToDecisionSpeedPhaseBuilder(
    'takeoff_brake_release',
    core_subsystems=[aero_builder, prop_builder],
    subsystem_options=takeoff_subsystem_options,
    user_options=takeoff_brake_release_user_options,
    initial_guesses=takeoff_brake_release_initial_guesses)

Trajectory Builder#

Objects of the trajectory builder type TakeoffTrajectory can be used to collect the required phases for either general takeoff analysis or balanced field length analysis. The builder has setters for each of the following generally required phase builders:

  • set_brake_release_to_decision_speed() : assign a phase builder, typically of type TakeoffBrakeReleaseToDecisionSpeed, for the beginning of takeoff to the time when the pilot must choose either to liftoff or halt the aircraft;

  • set_decision_speed_to_rotate() : assign a phase builder, typically of type TakeoffDecisionSpeedToRotate, for the short distance between achieving decision speed and beginning the rotation phase;

  • set_rotate_to_liftoff() : assign a phase builder, typically of type TakeoffRotateToLiftoff, for the short distance required to rotate the aircraft to achieve liftoff;

  • set_liftoff_to_obstacle() : assign a phase builder, typically of type TakeoffLiftoffToObstacle, for the short period between liftoff and clearing the required obstacle.

The builder has setters for the following phase builders, which are only required if acoustic calculations are required:

  • set_obstacle_to_mic_p2() : assign a phase builder, typically of type TakeoffObstacleToMicP2, for the fifth phase of takeoff, from clearing the required obstacle to the p2 mic loation;

  • set_mic_p2_to_engine_cutback() : a phase builder, typically of type TakeoffMicP2ToEngineCutback, for the sixth phase of takeoff, from the p2 mic location to engine cutback;

  • set_engine_cutback() : a phase builder, typically of type TakeoffEngineCutback, for the seventh phase of takeoff, from start to finish of engine cutback;

  • set_engine_cutback_to_mic_p1() : a phase builder, typically of type TakeoffEngineCutbackToMicP1, for the eighth phase of takeoff, engine cutback to the P1 mic location;

  • set_mic_p1_to_climb() : a phase builder, typically of type TakeoffMicP1ToClimb, for the ninth phase of takeoff, from P1 mic location to climb.

The builder also has setters for the following phase builders, which are only required if balanced field length calculations are required:

  • set_decision_speed_to_brake() : assign a phase builder, typically of type TakeoffDecisionSpeedBrakeDelay, for delayed braking when the engine fails;

  • set_brake_to_abort() : assign a phase builder, typically of type TakeoffBrakeToAbort, for braking to fullstop after engine failure.

After all required phase builders have been assigned, the build_trajectory() method can be called on the builder, which requires an AviaryValues object for Aviary level analysis options, and which optionally accepts a model (an OpenMDAO Group) and a trajectory. If specified, the model is used in handling trajectory parameter setup; otherwise, trajectory parameter setup must be handled by client code. If specified, the trajectory is updated with phase analysis components created from the phase builders; otherwise, a new trajectory is created, updated with these components, and returned. Calling build_trajectory() adds phase analysis components to the trajectory, and then links those phases appropriately. Note, externally created trajectories can be added to the problem model either before or after the call to build_trajectory().

Once build_trajectory() is called on the builder, client code can optionally retrieve named phase analysis components from the builder with the get_phase() method. Client code can then add objectives and constraints to these components to satisfy application specific requirements.

Before running the problem, the apply_initial_guesses() method should be called on the trajectory builder with the problem and the name of the trajectory. For each created phase, this method calls the apply_initial_guesses() method on the associated phase builder. Any initial guesses not applied are returned in a dictionary, where the name of the phase maps to the list of initial guesses not applied. Once the problem is built up and set up, the problem can be run for trajectory analysis.

import warnings

import dymos as dm

import openmdao.api as om

from aviary.models.N3CC.N3CC_data import (
    takeoff_decision_speed_builder, takeoff_rotate_builder, takeoff_liftoff_builder,
    takeoff_mic_p2_builder, takeoff_mic_p2_to_engine_cutback_builder,
    takeoff_engine_cutback_builder, takeoff_engine_cutback_to_mic_p1_builder,
    takeoff_mic_p1_to_climb_builder, takeoff_liftoff_user_options)
from aviary.utils.test_utils.default_subsystems import get_default_premission_subsystems


takeoff_trajectory_builder = av.DetailedTakeoffTrajectoryBuilder('detailed_takeoff')

takeoff_trajectory_builder.set_brake_release_to_decision_speed(
    takeoff_brake_release_builder)

takeoff_trajectory_builder.set_decision_speed_to_rotate(takeoff_decision_speed_builder)

takeoff_trajectory_builder.set_rotate_to_liftoff(takeoff_rotate_builder)

takeoff_trajectory_builder.set_liftoff_to_obstacle(takeoff_liftoff_builder)

takeoff_trajectory_builder.set_obstacle_to_mic_p2(takeoff_mic_p2_builder)

takeoff_trajectory_builder.set_mic_p2_to_engine_cutback(
    takeoff_mic_p2_to_engine_cutback_builder)

takeoff_trajectory_builder.set_engine_cutback(takeoff_engine_cutback_builder)

takeoff_trajectory_builder.set_engine_cutback_to_mic_p1(
    takeoff_engine_cutback_to_mic_p1_builder)

takeoff_trajectory_builder.set_mic_p1_to_climb(takeoff_mic_p1_to_climb_builder)

takeoff = om.Problem()

# default subsystems
default_premission_subsystems = get_default_premission_subsystems('FLOPS', engine)
    
# Upstream pre-mission analysis for aero
takeoff.model.add_subsystem(
    'core_subsystems',
    av.CorePreMission(
        aviary_options=aviary_options,
        subsystems=default_premission_subsystems,
    ),
    promotes_inputs=['*'],
    promotes_outputs=['*'])

# Instantiate the trajectory and add the phases
traj = dm.Trajectory()
takeoff.model.add_subsystem('traj', traj)

takeoff_trajectory_builder.build_trajectory(
    aviary_options=aviary_options, model=takeoff.model, traj=traj)

distance_max, units = takeoff_liftoff_user_options.get_item('distance_max')
liftoff = takeoff_trajectory_builder.get_phase('takeoff_liftoff')

liftoff.add_objective(
    Dynamic.Mission.DISTANCE, loc='final', ref=distance_max, units=units)

# Insert a constraint for a fake decision speed, until abort is added.
takeoff.model.add_constraint(
    'traj.takeoff_brake_release.states:velocity',
    equals=149.47, units='kn', ref=150.0, indices=[-1])

takeoff.model.add_constraint(
    'traj.takeoff_decision_speed.states:velocity',
    equals=155.36, units='kn', ref=159.0, indices=[-1])

varnames = [
    av.Aircraft.Wing.AREA,
    av.Aircraft.Wing.ASPECT_RATIO,
    av.Aircraft.Wing.SPAN,
]
av.set_aviary_input_defaults(takeoff.model, varnames, aviary_options)
   
# suppress warnings:
# "input variable '...' promoted using '*' was already promoted using 'aircraft:*'
with warnings.catch_warnings():

    warnings.simplefilter("ignore", om.PromotionWarning)
    takeoff.setup(check=True)

av.set_aviary_initial_values(takeoff, aviary_options)

takeoff_trajectory_builder.apply_initial_guesses(takeoff, 'traj')
/usr/share/miniconda/envs/test/lib/python3.12/site-packages/dymos/phase/phase.py:902: OMDeprecationWarning:None: The method `add_polynomial_control` is deprecated and will be removed in Dymos 2.1. Please use `add_control` with the appropriate options to define a polynomial control.
/usr/share/miniconda/envs/test/lib/python3.12/site-packages/openmdao/core/system.py:4284: OpenMDAOWarning:Calling `list_inputs` before `final_setup` will only display the default values of variables and will not show the result of any `set_val` calls.
The following variables have been overridden:
  'aircraft:design:landing_to_takeoff_mass_ratio
  'aircraft:engine:mass
  'aircraft:fuel:auxiliary_fuel_capacity
  'aircraft:fuel:fuselage_fuel_capacity
  'aircraft:fuselage:planform_area
  'aircraft:fuselage:wetted_area
  'aircraft:horizontal_tail:wetted_area
  'aircraft:nacelle:total_wetted_area
  'aircraft:nacelle:wetted_area
  'aircraft:propulsion:total_engine_controls_mass
  'aircraft:propulsion:total_starter_mass
  'aircraft:vertical_tail:wetted_area
  'aircraft:wing:aspect_ratio
  'aircraft:wing:wetted_area
--- Constraint Report [traj] ---
    --- takeoff_brake_release ---
        None
    --- takeoff_decision_speed ---
        [final]   1.2000e+00 <= v_over_v_stall  [unitless]
    --- takeoff_rotate ---
        None
    --- takeoff_liftoff ---
        [initial] 0.0000e+00 == takeoff_eom.forces_vertical [N]
        [final]   3.5000e+01 == altitude [ft]
        [path]    1.2500e+00 <= v_over_v_stall  [unitless]
    --- takeoff_mic_p2 ---
        [final]   9.8500e+02 == altitude [ft]
        [final]   1.2500e+00 <= v_over_v_stall  [unitless]
    --- takeoff_mic_p2_to_engine_cutback ---
        [final]   1.9000e+04 == distance [ft]
        [final]   1.2500e+00 <= v_over_v_stall  [unitless]
    --- takeoff_engine_cutback ---
        [final]   1.2500e+00 <= v_over_v_stall  [unitless]
    --- takeoff_engine_cutback_to_mic_p1 ---
        [final]   2.1325e+04 == distance [ft]
        [final]   1.2500e+00 <= v_over_v_stall  [unitless]
    --- takeoff_mic_p1_to_climb ---
        [final]   3.0000e+04 == distance [ft]
        [final]   1.2500e+00 <= v_over_v_stall  [unitless]
{}

Landing#

Aerodynamics Builder#

Aerodynamics analysis is added to landing phases identically to takeoff. See the “Aerodynamics Builder” subsection in the “Takeoff” section above for a description.

landing_subsystem_options = {'low_speed_aero': {
    'method': 'low_speed',
    'ground_altitude': 0.,  # units='m'
    'angles_of_attack': [
        0.0, 1.0, 2.0, 3.0, 4.0, 5.0,
        6.0, 7.0, 8.0, 9.0, 10.0, 11.0,
        12.0, 13.0, 14.0, 15.0],  # units='deg'
    'lift_coefficients': [
        0.7, 0.9, 1.05, 1.15, 1.25, 1.4,
        1.5, 1.60, 1.7, 1.8, 1.9, 2.0,
        2.1, 2.2, 2.3, 2.40],
    'drag_coefficients': [
        0.1, 0.1, 0.12, 0.13, 0.14, 0.15,
        0.16, 0.17, 0.18, 0.20, 0.22, 0.24,
        0.26, 0.3, 0.32, 0.34],
    'lift_coefficient_factor': 1.,
    'drag_coefficient_factor': 1.}}

# when using spoilers, add a few more options
landing_spoiler_subsystem_options = {'low_speed_aero': {
    **landing_subsystem_options['low_speed_aero'],
    'use_spoilers': True,
    'spoiler_lift_coefficient': -0.81,
    'spoiler_drag_coefficient': 0.085}}

Phase Builders#

There are six types of phase builders for landing. In general, the following phase builders are always required:

  • LandingObstacleToFlare : a phase builder for moving from the start of the runway, just above the required clearance height, to the start of a maneuver to help soften the impact of touchdown;

  • LandingFlareToTouchdown : a phase builder for moving through a maneuver to help soften the impact of touchdown;

  • LandingTouchdownToNoseDown : a phase builder for rotating the nose down after touchdown;

  • LandingNoseDownToStop : a phase builder for the final phase of landing, from nose down to full stop.

The following phase builders are only required if acoustic calculations are required:

  • LandingApproachToMicP3 : a phase builder for moving from descent to the mic location P3;

  • LandingMicP3ToObstacle : a phase builder for moving from the mic location P3 to the start of the runway, just above the required clearance height.

The general procedure for creating and using phase builders for landing is the same as that for phase buiders for takeoff. See the “Phase Builders” subsection in the “Takeoff” section above for a description.

from aviary.api import DetailedLandingApproachToMicP3PhaseBuilder as LandingApproachToMicP3


# NOTE FLOPS output is based on "constant" landing mass - assume reserves weight
#    - currently neglecting taxi
detailed_landing_mass = 106292.  # units='lbm'

# Flops variable APRANG
apr_angle = -3.0  # deg
apr_angle_ref = abs(apr_angle)

# From FLOPS output data.
# throttle position should be (roughly) thrust / max thrust
throttle = 7233.0 / 44000

landing_approach_to_mic_p3_user_options = av.AviaryValues()

landing_approach_to_mic_p3_user_options.set_val('max_duration', val=50., units='s')
landing_approach_to_mic_p3_user_options.set_val('duration_ref', val=50., units='s')
landing_approach_to_mic_p3_user_options.set_val('initial_ref', val=50.0, units='s')
landing_approach_to_mic_p3_user_options.set_val('distance_max', val=10000., units='ft')
landing_approach_to_mic_p3_user_options.set_val('max_velocity', val=140., units='kn')
landing_approach_to_mic_p3_user_options.set_val('altitude_ref', val=800., units='ft')

landing_approach_to_mic_p3_user_options.set_val(
    'lower_angle_of_attack', val=0., units='deg')

landing_approach_to_mic_p3_user_options.set_val(
    'upper_angle_of_attack', val=12., units='deg')

landing_approach_to_mic_p3_user_options.set_val(
    'angle_of_attack_ref', val=12., units='deg')

landing_approach_to_mic_p3_user_options.set_val('initial_height', val=600., units='ft')

landing_approach_to_mic_p3_initial_guesses = av.AviaryValues()

landing_approach_to_mic_p3_initial_guesses.set_val('time', [-42., 15.], 's')
landing_approach_to_mic_p3_initial_guesses.set_val('distance', [-4000., -2000.], 'ft')
landing_approach_to_mic_p3_initial_guesses.set_val('velocity', 140., 'kn')
landing_approach_to_mic_p3_initial_guesses.set_val('mass', detailed_landing_mass, 'lbm')
landing_approach_to_mic_p3_initial_guesses.set_val('throttle', throttle)
landing_approach_to_mic_p3_initial_guesses.set_val('altitude', [600., 394.], 'ft')

landing_approach_to_mic_p3_initial_guesses.set_val(
    Dynamic.Mission.FLIGHT_PATH_ANGLE, [apr_angle, apr_angle], 'deg')

landing_approach_to_mic_p3_initial_guesses.set_val('angle_of_attack', 5.25, 'deg')

landing_approach_to_mic_p3_builder = LandingApproachToMicP3(
    'landing_approach_to_mic_p3',
    core_subsystems=[aero_builder, prop_builder],
    subsystem_options=landing_subsystem_options,
    user_options=landing_approach_to_mic_p3_user_options,
    initial_guesses=landing_approach_to_mic_p3_initial_guesses)

Trajectory Builder#

Objects of the trajectory builder type LandingTrajectory can be used to collect the required phases for general landing analysis. The builder has setters for each of the following generally required phase builders:

  • set_obstacle_to_flare() : assign a phase builder, typically of type LandingObstacleToFlare, for moving from the start of the runway, just above the required clearance height, to the start of a maneuver to help soften the impact of touchdown;

  • set_flare_to_touchdown() : assign a phase builder, typically of type LandingFlareToTouchdown, for moving through a maneuver to help soften the impact of touchdown;

  • set_touchdown_to_nose_down() : assign a phase builder, typically of type LandingTouchdownToNoseDown, for rotating the nose down after touchdown;

  • set_nose_down_to_stop() : assign a phase builder, typically of type LandingNoseDownToStop, for the final phase of landing, from nose down to full stop.

The builder also has setters for each of the following phase builders, which are only required if acoustic calculations are required:

  • set_approach_to_mic_p3() : assign a phase builder, typically of type LandingApproachToMicP3, for moving from the end of descent to the mic location P3;

  • set_mic_p3_to_obstacle() : assign a phase builder, typically of type LandingMicP3ToObstacle, for moving from the mic location P3 to the start of the runway, just above the required clearance height.

After all required phase builders have been assigned, the general procedure for using the build_trajectory(), get_phase(), and apply_initial_guesses() methods of the trajectory builder is the same for landing as that for takeoff. See the “Trajectory Builder” subsection in the “Takeoff” section above for a description.

from aviary.models.N3CC.N3CC_data import (
    landing_mic_p3_to_obstacle_builder, landing_obstacle_builder, landing_flare_builder,
    landing_touchdown_builder, landing_fullstop_builder, landing_fullstop_user_options)


landing_trajectory_builder = av.DetailedLandingTrajectoryBuilder('detailed_landing')

landing_trajectory_builder.set_approach_to_mic_p3(landing_approach_to_mic_p3_builder)

landing_trajectory_builder.set_mic_p3_to_obstacle(landing_mic_p3_to_obstacle_builder)

landing_trajectory_builder.set_obstacle_to_flare(landing_obstacle_builder)

landing_trajectory_builder.set_flare_to_touchdown(landing_flare_builder)

landing_trajectory_builder.set_touchdown_to_nose_down(landing_touchdown_builder)

landing_trajectory_builder.set_nose_down_to_stop(landing_fullstop_builder)

landing = om.Problem()

# Upstream pre-mission analysis for aero
landing.model.add_subsystem(
    'core_subsystems',
    av.CorePreMission(
        aviary_options=aviary_options,
        subsystems=default_premission_subsystems,
    ),
    promotes_inputs=['*'],
    promotes_outputs=['*'])

# Instantiate the trajectory and add the phases
traj = dm.Trajectory()
landing.model.add_subsystem('traj', traj)

landing_trajectory_builder.build_trajectory(
    aviary_options=aviary_options, model=landing.model, traj=traj)

distance_max, units = landing_fullstop_user_options.get_item('distance_max')
fullstop = landing_trajectory_builder.get_phase('landing_fullstop')

fullstop.add_objective(Dynamic.Mission.DISTANCE, loc='final', ref=distance_max, units=units)

varnames = [
    av.Aircraft.Wing.AREA,
    av.Aircraft.Wing.ASPECT_RATIO,
    av.Aircraft.Wing.SPAN,
]
av.set_aviary_input_defaults(landing.model, varnames, aviary_options)
   
# suppress warnings:
# "input variable '...' promoted using '*' was already promoted using 'aircraft:*'
with warnings.catch_warnings():

    warnings.simplefilter("ignore", om.PromotionWarning)
    landing.setup(check=True)

av.set_aviary_initial_values(landing, aviary_options)

landing_trajectory_builder.apply_initial_guesses(landing, 'traj')
/usr/share/miniconda/envs/test/lib/python3.12/site-packages/dymos/phase/phase.py:902: OMDeprecationWarning:None: The method `add_polynomial_control` is deprecated and will be removed in Dymos 2.1. Please use `add_control` with the appropriate options to define a polynomial control.
/usr/share/miniconda/envs/test/lib/python3.12/site-packages/openmdao/core/system.py:4284: OpenMDAOWarning:Calling `list_inputs` before `final_setup` will only display the default values of variables and will not show the result of any `set_val` calls.
The following variables have been overridden:
  'aircraft:design:landing_to_takeoff_mass_ratio
  'aircraft:engine:mass
  'aircraft:fuel:auxiliary_fuel_capacity
  'aircraft:fuel:fuselage_fuel_capacity
  'aircraft:fuselage:planform_area
  'aircraft:fuselage:wetted_area
  'aircraft:horizontal_tail:wetted_area
  'aircraft:nacelle:total_wetted_area
  'aircraft:nacelle:wetted_area
  'aircraft:propulsion:total_engine_controls_mass
  'aircraft:propulsion:total_starter_mass
  'aircraft:vertical_tail:wetted_area
  'aircraft:wing:aspect_ratio
  'aircraft:wing:wetted_area
--- Constraint Report [traj] ---
    --- landing_approach_to_mic_p3 ---
        [initial] 6.0000e+02 == altitude [ft]
    --- landing_mic_p3_to_obstacle ---
        [initial] 3.9400e+02 == altitude [ft]
    --- landing_obstacle ---
        [initial] 5.0000e+01 == altitude [ft]
    --- landing_flare ---
        [final]   0.0000e+00 == net_alpha_rate [deg/s]
    --- landing_touchdown ---
        None
    --- landing_fullstop ---
        None
{}