def get_weight_unc_estimations(cpacs_path, cpacs_out_path):
    """Function to estimate the all weights for a unconventional aircraft.

    Function 'get_weight_unc_estimations' ...

    Source:
        * Reference paper or book, with author and date, see ...

    Args:
        cpacs_path (str): Path to CPACS file
        cpacs_out_path (str):Path to CPACS output file

    """

    # Removing and recreating the ToolOutput folder.
    if os.path.exists("ToolOutput"):
        shutil.rmtree("ToolOutput")
    os.makedirs("ToolOutput")

    if not os.path.exists(cpacs_path):
        raise ValueError('No "ToolInput.xml" file in the ToolInput folder.')

    name = aircraft_name(cpacs_path)

    shutil.copyfile(cpacs_path, cpacs_out_path)  # TODO: shoud not be like that
    newpath = "ToolOutput/" + name
    if not os.path.exists(newpath):
        os.makedirs(newpath)

    # USER INPUTS
    # All the input data must be defined into the unc_weight_user_input.py
    # file inside the ceasiompy.InputClasses/Unconventioanl folder.

    adui = AdvancedInputs()
    ui = UserInputs()
    mw = MassesWeights()
    out = WeightOutput()
    ed = EngineData()
    (ed, ui, adui) = getinput.get_user_inputs(ed, ui, adui, cpacs_out_path)
    if ui.USER_ENGINES:
        (ed) = getinput.get_engine_inputs(ui, ed, cpacs_out_path)

    # GEOMETRY ANALYSIS

    (fus_nb, wing_nb) = uncgeomanalysis.get_number_of_parts(cpacs_path)
    h_min = ui.FLOORS_NB * ui.H_LIM_CABIN

    if not wing_nb:
        log.warning("Aircraft does not have wings")
        raise Exception("Aircraft does not have wings")
    elif not fus_nb:
        (awg, wing_nodes) = uncgeomanalysis.no_fuse_geom_analysis(
            cpacs_out_path, ui.FLOORS_NB, wing_nb, h_min, ui.FUEL_ON_CABIN,
            name, ed.TURBOPROP)
    else:
        log.info("Fuselage detected")
        log.info("Number of fuselage: " + str(int(fus_nb)))
        # Minimum fuselage segment height to be a cabin segment.
        (afg, awg) = uncgeomanalysis.with_fuse_geom_analysis(
            cpacs_out_path, fus_nb, wing_nb, h_min, adui, ed.TURBOPROP,
            ui.F_FUEL, name)

    ui = getinput.get_user_fuel(fus_nb, ui, cpacs_out_path)

    # WEIGHT ANALYSIS
    #  Engine evaluation
    if ui.USER_ENGINES:
        check_ed(ed)
        mw.mass_engines = ed.en_mass * ed.NE

    if fus_nb:
        # Passengers mass
        (out.pass_nb, out.toilet_nb, mw.mass_pass) = estimate_fuse_passengers(
            fus_nb,
            ui.FLOORS_NB,
            adui.PASS_PER_TOILET,
            afg.cabin_area,
            adui.MASS_PASS,
            ui.PASS_BASE_DENSITY,
        )
        cabin_area = np.sum(afg.cabin_area)
        # Structure mass
        mw.mass_structure = (adui.VRT_STR_DENSITY * adui.VRT_THICK *
                             (np.sum(afg.fuse_surface) +
                              np.sum(awg.total_wings_surface))**adui.VRT_EXP)
    else:
        # Passengers mass
        (out.pass_nb, out.toilet_nb, mw.mass_pass) = estimate_wing_passengers(
            ui.FLOORS_NB,
            adui.PASS_PER_TOILET,
            awg.cabin_area,
            adui.MASS_PASS,
            ui.PASS_BASE_DENSITY,
        )
        cabin_area = awg.cabin_area
        # Structure mass
        mw.mass_structure = (adui.VRT_STR_DENSITY * adui.VRT_THICK *
                             np.sum(awg.total_wings_surface)**adui.VRT_EXP)

    pass_limit = False
    if ui.MAX_PASS > 0 and out.pass_nb > ui.MAX_PASS:
        out.pass_nb = ui.MAX_PASS
        pass_limit = True
        pass_density = round(out.pass_nb / cabin_area, 2)
        mw.mass_pass = adui.MASS_PASS * out.pass_nb
        log.warning("With the defined maximum number of passengers,")
        log.warning("the number of passengers is reduced to : " +
                    str(out.pass_nb))
        log.warning("and the passenger density is: " + str(pass_density))

    # Payload masses
    mw.mass_payload = round(ui.MASS_CARGO + mw.mass_pass, 0)

    if ui.MAX_PAYLOAD > 0 and mw.mass_payload > ui.MAX_PAYLOAD:
        mw.mass_payload = ui.MAX_PAYLOAD
        if ui.MASS_CARGO > ui.MAX_PAYLOAD:
            log.warning("Mass cargo defined exceeds the chosen" +
                        " maximum payload, the code do not consider the" +
                        " user cargo mass")
            ui.MASS_CARGO = 0.0
        if pass_limit and mw.mass_pass < ui.MAX_PAYLOAD:
            ui.MASS_CARGO = round(ui.MAX_PAYLOAD - mw.mass_pass, 0)
        elif pass_limit and mw.mass_pass > ui.MAX_PAYLOAD:
            log.warning("Pass number defined exceeds the chosen" +
                        " maximum payload, the code do not consider the" +
                        " user passenger number.")
            mw.mass_pass = ui.MAX_PAYLOAD - ui.MASS_CARGO
            out.pass_nb = int(round(mw.mass_pass / adui.MASS_PASS, 0))
        else:
            mw.mass_pass = ui.MAX_PAYLOAD - ui.MASS_CARGO
            out.pass_nb = int(round(mw.mass_pass / adui.MASS_PASS, 0))
        pass_density = round(out.pass_nb / cabin_area, 2)
        log.warning("With the defined maximum payload and cargo masses,")
        log.warning("the number of passengers is: " + str(out.pass_nb))
        log.warning("and the passenger density is: " + str(pass_density))

    #  Fuel mass
    if fus_nb:
        mw.mass_fuse_fuel = estimate_fuse_fuel_mass(afg.fuse_fuel_vol,
                                                    adui.FUEL_DENSITY)
        mw.mass_wing_fuel = estimate_wing_fuel_mass(awg.wing_fuel_vol,
                                                    adui.FUEL_DENSITY)
        mw.mass_fuel_max = mw.mass_wing_fuel + mw.mass_fuse_fuel
    else:
        mw.mass_fuel_max = estimate_wing_fuel_mass(awg.fuel_vol_tot,
                                                   adui.FUEL_DENSITY)

    if ui.MAX_FUEL_VOL > 0 and (mw.mass_fuel_max /
                                adui.FUEL_DENSITY) * 1000.0 > ui.MAX_FUEL_VOL:
        mw.mass_fuel_max = (ui.MAX_FUEL_VOL * adui.FUEL_DENSITY) / 1000.0

    # Mass Reserve and Unusable Fuel
    mw.mass_fuel_unusable = mw.mass_fuel_max * (adui.RES_FUEL_PERC)

    # Mass Fuel Maxpass
    if not out.pass_nb:
        mw.mass_fuel_maxpass = mw.mass_fuel_max
    elif ed.TURBOPROP:
        mw.mass_fuel_maxpass = mw.mass_fuel_max * (adui.FPM_TP / 100.0)
    else:
        mw.mass_fuel_maxpass = mw.mass_fuel_max * (adui.FPM / 100.0)

    wing_area = np.sum(awg.wing_plt_area)
    mw.maximum_take_off_mass = wing_area * ui.wing_loading
    new_mtom = mw.maximum_take_off_mass
    old_mtom = 0
    it = 0
    mw.zero_fuel_mass = mw.maximum_take_off_mass - mw.mass_fuel_maxpass
    if mw.zero_fuel_mass < 0:
        mw.maximum_take_off_mass = mw.mass_fuel_maxpass * 2
        mw.zero_fuel_mass = mw.maximum_take_off_mass - mw.mass_fuel_maxpass
        ui.wing_loading = mw.maximum_take_off_mass / wing_area
        log.warning("Wing loading defined too low," +
                    " starting value modified to [kg/m^2]: " +
                    str(ui.wing_loading))

    while (abs(old_mtom - new_mtom) / max(old_mtom, new_mtom)) > 0.001:
        old_mtom = new_mtom
        mw.maximum_take_off_mass = new_mtom

        if not ui.USER_ENGINES:
            (mw.mass_engines, ed) = engine_definition(mw, ui, ed)

        # Crew mass
        (out.crew_nb, out.cabin_crew_nb, mw.mass_crew) = estimate_crew(
            out.pass_nb,
            adui.MASS_PILOT,
            adui.MASS_CABIN_CREW,
            mw.maximum_take_off_mass,
            adui.PILOT_NB,
        )

        # Total people and payload mass on the aircraft
        mw.mass_people = round(mw.mass_crew + mw.mass_pass, 0)

        #  System mass
        mw.mass_systems = round(
            estimate_system_mass(
                out.pass_nb,
                awg.main_wing_surface,
                awg.tail_wings_surface,
                adui.SINGLE_HYDRAULICS,
                mw,
                ed,
            ),
            0,
        )

        #  MTOM, OEM, ZFM re-evaluation
        mw.operating_empty_mass = round(
            mw.mass_systems + mw.mass_crew + mw.mass_engines +
            mw.mass_structure + mw.mass_fuel_unusable,
            0,
        )

        new_mtom = round(mw.operating_empty_mass + mw.mass_payload +
                         mw.mass_fuel_maxpass)
        mw.zero_fuel_mass = mw.operating_empty_mass + mw.mass_payload

        it += 1
    # End of the iterative process.

    mw.maximum_take_off_mass = new_mtom
    out.wing_loading = new_mtom / wing_area

    # Log writting  (TODO: maybe create a separate function)
    log.info("--------- Masses evaluated: -----------")
    log.info("System mass [kg]: " + str(int(round(mw.mass_systems))))
    log.info("People mass [kg]: " + str(int(round(mw.mass_people))))
    log.info("Payload mass [kg]: " + str(int(round(mw.mass_payload))))
    log.info("Structure mass [kg]: " + str(int(round(mw.mass_structure))))
    log.info("Total fuel mass [kg]: " + str(int(round(mw.mass_fuel_max))))
    log.info("Total fuel volume [l]: " +
             str(int(round(mw.mass_fuel_max / adui.FUEL_DENSITY * 1000.0))))
    log.info("Mass of fuel with max passengers [kg]: " +
             str(int(round(mw.mass_fuel_maxpass))))
    log.info("Volume of fuel with maximum passengers [l]: " +
             str(int(round(mw.mass_fuel_maxpass / adui.FUEL_DENSITY *
                           1000.0))))
    log.info("Engines mass [kg]: " + str(int(round(mw.mass_engines))))
    log.info("---------------------------------------")
    log.info("Maximum Take Off Mass [kg]: " +
             str(int(round(mw.maximum_take_off_mass))))
    log.info("Operating Empty Mass [kg]: " +
             str(int(round(mw.operating_empty_mass))))
    log.info("Zero Fuel Mass [kg]: " + str(int(round(mw.zero_fuel_mass))))
    log.info("Wing loading [kg/m^2]: " + str(int(round(out.wing_loading))))
    log.info("--------- Passegers evaluated: ---------")
    log.info("Passengers: " + str(out.pass_nb))
    log.info("Toilet: " + str(int(out.toilet_nb)))
    log.info("------- Crew members evaluated: --------")
    log.info("Pilots: " + str(adui.PILOT_NB))
    log.info("Cabin crew members: " + str(out.cabin_crew_nb))
    log.info("---------------------------------------")
    log.info("Number of iterations: " + str(it))
    log.info("---------------------------------------")
    log.info("### Uconventional Weight analysis succesfuly completed ###")

    # Outptu writting
    log.info("----- Generating output text file -----")
    cpacsweightupdate.cpacs_weight_update(out, mw, ui, cpacs_out_path)
    cpacsweightupdate.toolspecific_update(fus_nb, awg, mw, out, cpacs_out_path)
    cpacsweightupdate.cpacs_engine_update(ui, ed, mw, cpacs_out_path)

    if not fus_nb:
        outputweightgen.output_bwb_txt(ui.FLOORS_NB, ed, out, mw, adui, awg,
                                       name)
    else:
        outputweightgen.output_fuse_txt(fus_nb, ui.FLOORS_NB, ed, out, mw,
                                        adui, awg, afg, name)
    h_min = ui.FLOORS_NB * ui.H_LIM_CABIN

    if not w_nb:
        log.warning('Aircraft does not have wings')
        raise Exception('Aircraft does not have wings')
    elif not f_nb:
        (awg, wing_nodes) =\
            uncgeomanalysis.no_fuse_geom_analysis(ui.FLOORS_NB, w_nb,\
                h_min, ui.FUEL_ON_CABIN, out_xml, name, ed.TURBOPROP)
    else:
        log.info('Fuselage detected')
        log.info('Number of fuselage: ' + str(int(f_nb)))
        # Minimum fuselage segment height to be a cabin segment.
        (afg, awg) =\
            uncgeomanalysis.with_fuse_geom_analysis(f_nb, w_nb, h_min, adui,\
                                                    ed.TURBOPROP, ui.F_FUEL,\
                                                    out_xml, name)

    ui = getinput.get_user_fuel(f_nb, ui, out_xml)

##============================= WEIGHT ANALYSIS ============================##
    ## Engine evaluation
    if ui.USER_ENGINES:
        check_ed(ed)
        mw.mass_engines = ed.en_mass * ed.NE

    if f_nb:
        # Passengers mass
        (out.pass_nb, out.toilet_nb, mw.mass_pass)\
                = estimate_fuse_passengers(f_nb, ui.FLOORS_NB,\
                    adui.PASS_PER_TOILET, afg.cabin_area, adui.MASS_PASS,\
Example #3
0
def get_balance_unc_estimations(cpacs_path, cpacs_out_path):
    """Function to estimate inertia value and CoF of an unconventional aircraft.

    Function 'get_balance_unc_estimations' ...

    Source:
        * Reference paper or book, with author and date, see ...

    Args:
        cpacs_path (str): Path to CPACS file
        cpacs_out_path (str):Path to CPACS output file

    """

    # Removing and recreating the ToolOutput folder.
    if os.path.exists('ToolOutput'):
        shutil.rmtree('ToolOutput')
    os.makedirs('ToolOutput')

    if not os.path.exists(cpacs_path):
        raise ValueError('No "ToolInput.xml" file in the ToolInput folder.')

    name = aircraft_name(cpacs_path)

    shutil.copyfile(cpacs_path, cpacs_out_path)  # TODO: shoud not be like that
    newpath = 'ToolOutput/' + name
    if not os.path.exists(newpath):
        os.makedirs(newpath)

    bout = balanceuncclass.BalanceOutputs()

    # BALANCE ANALSIS INPUTS

    bi = balanceuncclass.BalanceInputs()
    mw = balanceuncclass.MassesWeights()
    ui = weightuncclass.UserInputs()
    ed = engineclass.EngineData()

    adui = weightuncclass.AdvancedInputs()

    (mw, ed) = getdatafromcpacs.get_data(ui, bi, mw, ed, cpacs_out_path)

    # GEOMETRY ANALYSIS

    (fus_nb, w_nb) = uncgeomanalysis.get_number_of_parts(cpacs_path)
    if not w_nb:
        log.warning('Aircraft does not have wings')
        raise Exception('Aircraft does not have wings')
    elif not fus_nb:
        (awg, wing_nodes) =\
            uncgeomanalysis.no_fuse_geom_analysis(cpacs_path, ui.FLOORS_NB,     \
                                                  w_nb, ui.H_LIM_CABIN,   \
                                                  ui.FUEL_ON_CABIN, name, \
                                                  ed.TURBOPROP)
    else:
        log.info('Fuselage detected')
        log.info('Number of fuselage: ' + str(int(fus_nb)))
        # Minimum fuselage segment height to be a cabin segment.
        h_min = ui.FLOORS_NB * ui.H_LIM_CABIN
        (afg, awg) = uncgeomanalysis.with_fuse_geom_analysis(cpacs_path, \
                         fus_nb, w_nb, h_min, adui, ed.TURBOPROP, ui.F_FUEL, name)

    ui = getdatafromcpacs.get_user_fuel(fus_nb, ui, cpacs_out_path)

    # BALANCE ANALYSIS

    log.info('----- Generating output text file -----')
    log.info('---- Starting the balance analysis ----')
    log.info('---- Aircraft: ' + name)

    # CENTER OF GRAVITY

    if not fus_nb:
        (bout, airplane_centers_segs) =\
                bwb_center_of_gravity(awg, bout, ui, bi, mw, ed)
    else:
        (bout, airplane_centers_segs) =\
                unc_center_of_gravity(awg, afg, bout, ui, bi, mw, ed)

    # MOMENT OF INERTIA

    if not fus_nb:
        (bout, wx, wy,
         wz) = uncinertia.bwb_inertia_eval(awg, bout, bi, mw, ed,
                                           cpacs_out_path)
    else:
        (bout, fx, fy, fz, wx, wy, wz)\
            = uncinertia.unc_inertia_eval(awg, afg, bout, bi, mw, ed, cpacs_out_path)

    # OUTPUT WRITING

    log.info('----- Generating output text file -----')
    outputbalancegen.output_txt(bout, mw, bi, ed, name)

    # CPACS WRITING
    cpacsbalanceupdate.cpacs_mbd_update(bout, mw, bi, np.sum(mw.ms_zpm),
                                        cpacs_out_path)

    # PLOTS

    log.info('--- Generating aircraft center of gravity plot (.png) ---')
    if not fus_nb:
        outputbalancegen.aircraft_cog_bwb_plot(bout.center_of_gravity, bi, ed,
                                               awg, name)
    else:
        outputbalancegen.aircraft_cog_unc_plot(bout.center_of_gravity, bi, ed,
                                               afg, awg, name)

    # Aircraft Nodes
    #log.info('--- Generating aircraft nodes plot (.png) ---')
    #if not fus_nb:
    #outputbalancegen.aircraft_nodes_bwb_plot(wx, wy, wz, name)
    #else:
    #outputbalancegen.aircraft_nodes_unc_plot(fx, fy, fz, wx, wy, wz, name)

    # Show plots
    plt.show()

    # LOG WRITING

    log.info('---- Center of Gravity coordinates ----')
    log.info('------ Max Payload configuration ------')
    log.info('[x, y, z]: ' + str(bout.center_of_gravity))
    log.info('---------------------------------------')
    log.info('------- Zero Fuel configuration -------')
    log.info('[x, y, z]: ' + str(bout.cg_zfm))
    log.info('---------------------------------------')
    log.info('----- Zero Payload configuration ------')
    log.info('[x, y, z]: ' + str(bout.cg_zpm))
    log.info('---------------------------------------')
    log.info('---------- OEM configuration ----------')
    log.info('[x, y, z]: ' + str(bout.cg_oem))
    log.info('---------------------------------------')

    if bi.USER_CASE:
        log.info('---------- User configuration ---------')
        log.info('Chosen Fuel Percentage: ' + str(bi.F_PERC))
        log.info('Chosen Payload Percentage: ' + str(bi.P_PERC))
        log.info('[x, y, z]: ' + str(bout.cg_user))

    log.info('---------------------------------------')
    log.info('---------- Inertia Evaluation ---------')

    if bi.USER_EN_PLACEMENT:
        log.info('------------ Engine Inertia -----------')
        log.info('Roll moment, Ixx [kgm^2]: ' + str(int(round(bout.Ixxen))))
        log.info('Pitch moment, Iyy [kgm^2]: ' + str(int(round(bout.Iyyen))))
        log.info('Yaw moment, Izz [kgm^2]: ' + str(int(round(bout.Izzen))))
        log.info('Ixy moment [kgm^2]: ' + str(int(round(bout.Ixyen))))
        log.info('Iyz moment [kgm^2]: ' + str(int(round(bout.Iyzen))))
        log.info('Ixz moment [kgm^2]: ' + str(int(round(bout.Ixzen))))
        log.info('---------------------------------------')

    log.info('--------- Lumped mass Inertia ---------')
    log.info('------ Max Payload configuration ------')
    log.info('Roll moment, Ixx [kgm^2]: ' + str(bout.Ixx_lump))
    log.info('Pitch moment, Iyy [kgm^2]: ' + str(bout.Iyy_lump))
    log.info('Yaw moment, Izz [kgm^2]: ' + str(bout.Izz_lump))
    log.info('Ixy moment [kgm^2]: ' + str(bout.Ixy_lump))
    log.info('Iyz moment [kgm^2]: ' + str(bout.Iyz_lump))
    log.info('Ixz moment [kgm^2]: ' + str(bout.Ixz_lump))

    log.info('---------------------------------------')
    log.info('------- Zero Fuel configuration -------')
    log.info('Roll moment, Ixx [kgm^2]: ' + str(bout.Ixx_lump_zfm))
    log.info('Pitch moment, Iyy [kgm^2]: ' + str(bout.Iyy_lump_zfm))
    log.info('Yaw moment, Izz [kgm^2]: ' + str(bout.Izz_lump_zfm))
    log.info('Ixy moment [kgm^2]: ' + str(bout.Ixy_lump_zfm))
    log.info('Iyz moment [kgm^2]: ' + str(bout.Iyz_lump_zfm))
    log.info('Ixz moment [kgm^2]: ' + str(bout.Ixz_lump_zfm))

    log.info('---------------------------------------')
    log.info('------ Zero Payload configuration -----')
    log.info('Roll moment, Ixx [kgm^2]: ' + str(bout.Ixx_lump_zpm))
    log.info('Pitch moment, Iyy [kgm^2]: ' + str(bout.Iyy_lump_zpm))
    log.info('Yaw moment, Izz [kgm^2]: ' + str(bout.Izz_lump_zpm))
    log.info('Ixy moment [kgm^2]: ' + str(bout.Ixy_lump_zpm))
    log.info('Iyz moment [kgm^2]: ' + str(bout.Iyz_lump_zpm))
    log.info('Ixz moment [kgm^2]: ' + str(bout.Ixz_lump_zpm))

    log.info('---------------------------------------')
    log.info('---------- OEM configuration ----------')
    log.info('Roll moment, Ixx [kgm^2]: ' + str(bout.Ixx_lump_oem))
    log.info('Pitch moment, Iyy [kgm^2]: ' + str(bout.Iyy_lump_oem))
    log.info('Yaw moment, Izz [kgm^2]: ' + str(bout.Izz_lump_oem))
    log.info('Ixy moment [kgm^2]: ' + str(bout.Ixy_lump_oem))
    log.info('Iyz moment [kgm^2]: ' + str(bout.Iyz_lump_oem))
    log.info('Ixz moment [kgm^2]: ' + str(bout.Ixz_lump_oem))
    log.info('---------------------------------------')

    if bi.USER_CASE:
        log.info('---------- User configuration ---------')
        log.info('Roll moment, Ixx [kgm^2]: ' + str(bout.Ixx_lump_user))
        log.info('Pitch moment, Iyy [kgm^2]: ' + str(bout.Iyy_lump_user))
        log.info('Yaw moment, Izz [kgm^2]: ' + str(bout.Izz_lump_user))
        log.info('Ixy moment [kgm^2]: ' + str(bout.Ixy_lump_user))
        log.info('Iyz moment [kgm^2]: ' + str(bout.Iyz_lump_user))
        log.info('Ixz moment [kgm^2]: ' + str(bout.Ixz_lump_user))
        log.info('---------------------------------------')

    log.info('##  Uconventional Balance analysis succesfuly completed ##')
    (f_nb, w_nb) = uncgeomanalysis.get_number_of_parts(PATH)
    if not w_nb:
        log.warning('Aircraft does not have wings')
        raise Exception('Aircraft does not have wings')
    elif not f_nb:
        (awg, wing_nodes) =\
            uncgeomanalysis.no_fuse_geom_analysis(\
                ui.FLOORS_NB, w_nb, ui.H_LIM_CABIN,\
                ui.FUEL_ON_CABIN, PATH, name, ed.TURBOPROP)
    else:
        log.info('Fuselage detected')
        log.info('Number of fuselage: ' + str(int(f_nb)))
        # Minimum fuselage segment height to be a cabin segment.
        h_min = ui.FLOORS_NB * ui.H_LIM_CABIN
        (afg, awg) = uncgeomanalysis.with_fuse_geom_analysis(\
                         f_nb, w_nb, h_min, adui, ed.TURBOPROP, ui.F_FUEL,\
                         PATH, name)

    ui = getdatafromcpacs.get_user_fuel(f_nb, ui, out_xml)
##============================== BALANCE ANALYSIS ==========================##

    log.info('----- Generating output text file -----')
    log.info('---- Starting the balance analysis ----')
    log.info('---- Aircraft: ' + name)

### CENTER OF GRAVITY---------------------------------------------------------

    if not f_nb:
        (bout, airplane_centers_segs) =\
                bwb_center_of_gravity(awg, bout, ui, bi, mw, ed)
    else: