コード例 #1
0
 def _alt2ROC(prop, alt):
     """
     calculate ROC for an altitude
     """
     temp = SA.isa2temp(isa_dev, alt)
     calc_pwr = alt2pwr(alt, rpm = rpm, MP_max = MP_max, temp = temp) * pwr_factor
     cas = alt2roc_speed(alt, climb_speed = climb_speed)
     eas = A.cas2eas(cas, alt)
     ROC = roc(prop, alt, eas, weight, calc_pwr, rpm, rv = rv, \
         wing_area = wing_area)
     
     return ROC
コード例 #2
0
ファイル: rv8_test.py プロジェクト: khorton/AeroCalc_Package
    def _alt2ROC(prop, alt):
        """
        calculate ROC for an altitude
        """
        temp = SA.isa2temp(isa_dev, alt)
        calc_pwr = alt2pwr(alt, rpm=rpm, MP_max=MP_max, temp=temp) * pwr_factor
        cas = alt2roc_speed(alt, climb_speed=climb_speed)
        eas = A.cas2eas(cas, alt)
        ROC = roc(prop, alt, eas, weight, calc_pwr, rpm, rv = rv, \
            wing_area = wing_area)

        return ROC
コード例 #3
0
 def test_03(self):
     Value = SA.isa2temp(10, 10000, temp_units='K', alt_units='m')
     Truth = 233.15
     self.assertTrue(RE(Value, Truth) <= 1e-5)
コード例 #4
0
 def test_02(self):
     Value = SA.isa2temp(-10, 10000, temp_units='F')
     Truth = 13.3384
     self.assertTrue(RE(Value, Truth) <= 1e-5)
コード例 #5
0
 def test_01(self):
     Value = SA.isa2temp(25, 0)
     Truth = 40
     self.assertTrue(RE(Value, Truth) <= 1e-5)
コード例 #6
0
 def test_03(self):
     Value = SA.isa2temp(10, 10000, temp_units='K', alt_units='m')
     Truth = 233.15
     self.failUnless(RE(Value, Truth) <= 1e-5)
コード例 #7
0
 def test_02(self):
     Value = SA.isa2temp(-10, 10000, temp_units='F')
     Truth = 13.3384
     self.failUnless(RE(Value, Truth) <= 1e-5)
コード例 #8
0
 def test_01(self):
     Value = SA.isa2temp(25, 0)
     Truth = 40
     self.failUnless(RE(Value, Truth) <= 1e-5)
コード例 #9
0
def descent_data(prop, weight=1600., alt_max=20000., fuel_units='USG', \
    alt_interval=500., isa_dev=0, temp_units='C', rv='8',  wing_area=110., \
    tas=180., ROD=-500., angle='', speed_units='kt', rpm=2100., sfc=0.45, output='raw'):
    """
    Returns a table of descent performance vs altitude.

    The items in each row of the table are altitude, time, fuel burned and distance.
    Time is in units of minutes, rounded to the nearest half minute.
    Fuel units are selectable, with a default of USG.
    Distances are in nm.
    
    The output may be specified as raw, latex (a LaTeX table for the POH), or array.
    
    tas is the TAS in descent (overridden by the angle, if the angle is provided).
    angle is the flight path angle in degrees.
    """
    tas_fts = U.speed_conv(tas, speed_units, 'ft/s')

    if angle:
        ROD = tas_fts * 60 * M.sin(angle * M.pi / 180)
        
    rod_fts = ROD / 60

    tas = U.speed_conv(tas, speed_units, 'kt')
    
    alt = alt_max + alt_interval
    temp = SA.isa2temp(isa_dev, alt, temp_units=temp_units)
    time = 0
    fuel_used = 0
    dist = 0
    
    if output == 'raw':
        print S.center('Altitude', 10),
        print S.center('ROD', 10),
        print S.center('Time', 10),
        print S.center('Fuel Used', 10),
        print S.center('Dist', 10),
        print S.center('Speed', 10)
        
        print S.center('(ft)', 10),
        print S.center('(ft/mn)', 10),
        print S.center('(mn)', 10),
        f_units = '(' + fuel_units + ')'
        print S.center(f_units, 10),
        print S.center('(nm)', 10),
        print S.center('(KCAS)', 10)
        
        # # data for max altitude
        # print S.rjust(locale.format('%.0f', alt_max, True), 7),
        # print S.rjust(locale.format('%.0f', round(ROD / 10.) * 10, True), 10),
        # print S.rjust('%.1f' % (0), 10),
        # print S.rjust('%.1f' % (fuel_used), 10),
        # print S.rjust('%.1f' % (dist), 10),
        # print S.rjust('%3d' % (A.tas2cas(tas, alt_max, temp, temp_units=temp_units)), 10)

    # elif output == 'latex':
    #     # temp = 15 + isa_dev
    #     MSL_line = []
    #     MSL_line.append(str(locale.format('%.0f', weight, True)))
    #     MSL_line.append('0')
    #     MSL_line.append(str(locale.format('%.0f', temp)))
    #     MSL_line.append(str(locale.format('%.0f', A.tas2cas(tas, alt, temp, temp_units=temp_units))))
    #     MSL_line.append(str(locale.format('%.0f', round(ROD / 10.) * 10, True)))
    #     MSL_line.append('0')
    #     MSL_line.append(str(fuel_used))
    #     MSL_line.append(str(dist))
    #     
    #     print '&'.join(MSL_line) + '\\\\'
    #     print '\\hline'
    # elif output == 'array':
    #     # no header rows, but make blank array
    #     array = [[alt_max,0,0,0]]
        

    alts = []
    RODs = []
    times_temp = []
    CASs = []
    dists_temp = []
    fuel_useds_temp = []
    temps = []

    calc_alt = alt_max - alt_interval / 2.
    while alt > 0:
        temp = SA.isa2temp(isa_dev, alt, temp_units = temp_units)
        eas = A.tas2eas(tas, alt)
        drag = FT.eas2drag(eas, weight)
        pwr_level_flt = tas_fts * drag / 550
        thrust_power = pwr_level_flt + FT.Pexcess_vs_roc(weight, ROD)
        prop_eff = PM.prop_eff(prop, thrust_power, rpm, tas, alt, temp, temp_units=temp_units)
        calc_pwr = thrust_power / prop_eff        
        #fuel_flow = IO.pwr2ff(calc_pwr, rpm, ff_units = 'lb/hr')
        fuel_flow = calc_pwr * sfc 
        # print "Level flt pwr = %.1f, thrust power = %.1f, prop eff = %.3f, fuel flow = %.3f" % (pwr_level_flt, thrust_power, prop_eff, fuel_flow)
        slice_time = alt_interval / rod_fts * -1.
        slice_dist = tas_fts * slice_time
        slice_fuel = fuel_flow * slice_time / 3600
        fuel_used += slice_fuel
        fuel_out = (U.avgas_conv(fuel_used, from_units = 'lb', \
            to_units = fuel_units))
        weight -= slice_fuel
        alt -= alt_interval
        cas_out = A.tas2cas(tas, alt, temp, temp_units=temp_units)
        temp_out = SA.isa2temp(isa_dev, alt)
        time += slice_time / 60.
        dist += slice_dist / 6076.115

        alts.append(alt)
        CASs.append(cas_out)
        RODs.append(ROD)
        times_temp.append(time)
        fuel_useds_temp.append(fuel_out)
        dists_temp.append(dist)
        temps.append(temp_out)
        
        calc_alt += alt_interval
        
    alts.reverse()
    CASs.reverse()
    RODs.reverse()
    temps.reverse()
    
    times = []
    fuel_useds = []
    dists = []
    
    for n, time in enumerate(times_temp):
        times.append(times_temp[-1] - time)
        fuel_useds.append(fuel_useds_temp[-1] - fuel_useds_temp[n])
        dists.append(dists_temp[-1] - dists_temp[n])
        
    times.reverse()
    fuel_useds.reverse()
    dists.reverse()
    
    if output == 'raw':
        for n, alt in enumerate(alts):            
            print S.rjust(locale.format('%.0f', alt, True), 7),
            # calculate ROC at the displayed altitude
            print S.rjust(locale.format('%.0f', RODs[n], True), 10),
            print S.rjust('%.1f' % (times[n]), 10),
            print S.rjust('%.1f' % (fuel_useds[n]), 10),
            print S.rjust('%.1f' % (dists[n]), 10),
            print S.rjust('%3d' % (int(CASs[n])), 10)
    elif output == 'latex':
        for n, alt in enumerate(alts):                    
            line = []
            line.append(str(locale.format('%.0f', alt, True)))
            line.append(str(locale.format('%.0f', round(temps[n]))))
            line.append(str(locale.format('%.0f', CASs[n])))
            line.append(str(locale.format('%.0f', round(RODs[n] / 10.) * 10, True)))
            line.append(str(locale.format('%.0f', times[n])))
            line.append(str(locale.format('%.1f', fuel_useds[n])))
            line.append(str(locale.format('%.0f', dists[n])))
            print '&' + '&'.join(line) + '\\\\'
            print '\\hline'
    elif output == 'array':
        array = []
        for n, alt in enumerate(alts):
            array.append([alt, times[n], fuel_useds[n], dists[n]])
        return array
コード例 #10
0
def climb_data(prop, weight = 1800., alt_max = 20000., TO_fuel = 0, TO_dist = 0, \
    fuel_units = 'USG', alt_interval = 500., isa_dev = 0, temp_units = 'C', \
    rv = '8', wing_area = 110., pwr = 'max', pwr_factor=1.0, \
    climb_speed = 'max', output = 'raw'):
    """
    Returns a table of climb performance vs altitude.

    The items in each row of the table are altitude, time, fuel burned and distance.
    Time is in units of minutes, rounded to the nearest half minute.
    Fuel units are selectable, with a default of USG.
    Distances are in nm.
    
    The output may be specified as raw, latex (a LaTeX table for the POH), or array.
    
    pwr may be 'max', 'cc' (cruise climb = 2500 rpm and 25") or 2500 (2500 rpm and full throttle)
    climb_speed may be 'max' (Vy), 'cc' (120 kt to 10,000 ft, then reducing by 4 kt/1000 ft) or
                'norm' (100 kt to 10,000 ft, then reducing by 2 kt/1000 ft)
                
    Note: compared cruise range for all climb speed and power.  The predicted results are all 
          within 1.5 nm of range.  Thus there is no advantage to using anything but Vy and max
          power.
    """
    def _alt2ROC(prop, alt):
        """
        calculate ROC for an altitude
        """
        temp = SA.isa2temp(isa_dev, alt)
        calc_pwr = alt2pwr(alt, rpm = rpm, MP_max = MP_max, temp = temp) * pwr_factor
        cas = alt2roc_speed(alt, climb_speed = climb_speed)
        eas = A.cas2eas(cas, alt)
        ROC = roc(prop, alt, eas, weight, calc_pwr, rpm, rv = rv, \
            wing_area = wing_area)
        
        return ROC
    
    alt = 0
    time = 0
    fuel_used = U.avgas_conv(TO_fuel, from_units = fuel_units, to_units = 'lb')
    weight = weight - fuel_used
    dist = TO_dist
    if pwr == 'max':
        # rpm = 2700
        rpm = 2650
        MP_max = 30
    elif pwr == 'cc':
        rpm = 2500
        MP_max = 25
    elif pwr == 2500:
        rpm = 2500
        MP_max = 30
    else:
        raise ValueError, "pwr must be one of 'max', 'cc', or 2500"
    

    if output == 'raw':
        print S.center('Altitude', 10),
        print S.center('ROC', 10),
        print S.center('Time', 10),
        print S.center('Fuel Used', 10),
        print S.center('Dist', 10),
        print S.center('Speed', 10)
        
        print S.center('(ft)', 10),
        print S.center('(ft/mn)', 10),
        print S.center('(mn)', 10),
        f_units = '(' + fuel_units + ')'
        print S.center(f_units, 10),
        print S.center('(nm)', 10),
        print S.center('(KCAS)', 10)
        
        # data for MSL
        print S.rjust(locale.format('%.0f', 0, True), 7),
        # calculate ROC at MSL
        print S.rjust(locale.format('%.0f', round(_alt2ROC(prop, 0) / 10.) * 10, \
            True), 10),
        print S.rjust('%.1f' % (0), 10),
        print S.rjust('%.1f' % (TO_fuel), 10),
        print S.rjust('%.1f' % (TO_dist), 10),
        print S.rjust('%3d' % (alt2roc_speed(0, climb_speed = climb_speed)), 10)

    elif output == 'latex':
        temp = 15 + isa_dev
        MSL_line = []
        MSL_line.append(str(locale.format('%.0f', weight, True)))
        MSL_line.append('0')
        MSL_line.append(str(locale.format('%.0f', temp)))
        MSL_line.append(str(locale.format('%.0f', alt2roc_speed(0, \
            climb_speed = climb_speed))))
        MSL_line.append(str(locale.format('%.0f', round(_alt2ROC(prop, 0) / 10.)\
          * 10, True)))
        MSL_line.append('0')
        MSL_line.append(str(TO_fuel))
        MSL_line.append(str(TO_dist))
        
        print '&'.join(MSL_line) + '\\\\'
        print '\\hline'
    elif output == 'array':
        # no header rows, but make blank array
        array = [[0,0,TO_fuel,0]]
        
    calc_alt = alt_interval / 2.
    while calc_alt < alt_max:
        temp = SA.isa2temp(isa_dev, calc_alt)
        pwr = alt2pwr(calc_alt, rpm = rpm, MP_max = MP_max, temp = temp)
        calc_pwr = pwr * pwr_factor
        cas = alt2roc_speed(calc_alt, climb_speed = climb_speed)
        eas = A.cas2eas(cas, calc_alt)
        tas = A.cas2tas(cas, calc_alt, temp = temp, temp_units = temp_units)
        tas_fts = U.speed_conv(tas, from_units = 'kt', to_units = 'ft/s')
        ROC = roc(prop, calc_alt, eas, weight, calc_pwr, rpm, rv = rv, \
            wing_area = wing_area)
        roc_fts = ROC / 60
        fuel_flow = IO.pwr2ff(pwr, rpm, ff_units = 'lb/hr')
        slice_time = alt_interval / roc_fts
        slice_dist = tas_fts * slice_time
        slice_fuel = fuel_flow * slice_time / 3600
        fuel_used += slice_fuel
        fuel_out = (U.avgas_conv(fuel_used, from_units = 'lb', \
            to_units = fuel_units))
        weight -= slice_fuel
        alt += alt_interval
        cas_out = alt2roc_speed(alt, climb_speed = climb_speed)
        temp_out = SA.isa2temp(isa_dev, alt)
        ROC = _alt2ROC(prop, alt)
        time += slice_time / 60
        dist += slice_dist / 6076.115

        if output == 'raw':
            print S.rjust(locale.format('%.0f', alt, True), 7),
            # calculate ROC at the displayed altitude
            print S.rjust(locale.format('%.0f', ROC, True), 10),
            print S.rjust('%.1f' % (time), 10),
            print S.rjust('%.1f' % (fuel_out), 10),
            print S.rjust('%.1f' % (dist), 10),
            print S.rjust('%3d' % (int(cas_out)), 10)
        elif output == 'latex':
            line = []
            line.append(str(locale.format('%.0f', alt, True)))
            line.append(str(locale.format('%.0f', round(temp_out))))
            line.append(str(locale.format('%.0f', cas_out)))
            line.append(str(locale.format('%.0f', round(ROC / 10.) * 10, True)))
            line.append(str(locale.format('%.0f', time)))
            line.append(str(locale.format('%.1f', fuel_out)))
            line.append(str(locale.format('%.0f', dist)))
            print '&' + '&'.join(line) + '\\\\'
            print '\\hline'
        elif output == 'array':
            array.append([alt, time, fuel_out, dist])
        calc_alt += alt_interval
    if output == 'array':
        return array
コード例 #11
0
ファイル: rv8_test.py プロジェクト: khorton/AeroCalc_Package
def descent_data(prop, weight=1600., alt_max=20000., fuel_units='USG', \
    alt_interval=500., isa_dev=0, temp_units='C', rv='8',  wing_area=110., \
    tas=180., ROD=-500., angle='', speed_units='kt', rpm=2100., sfc=0.45, output='raw'):
    """
    Returns a table of descent performance vs altitude.

    The items in each row of the table are altitude, time, fuel burned and distance.
    Time is in units of minutes, rounded to the nearest half minute.
    Fuel units are selectable, with a default of USG.
    Distances are in nm.
    
    The output may be specified as raw, latex (a LaTeX table for the POH), or array.
    
    tas is the TAS in descent (overridden by the angle, if the angle is provided).
    angle is the flight path angle in degrees.
    """
    tas_fts = U.speed_conv(tas, speed_units, 'ft/s')

    if angle:
        ROD = tas_fts * 60 * M.sin(angle * M.pi / 180)

    rod_fts = ROD / 60

    tas = U.speed_conv(tas, speed_units, 'kt')

    alt = alt_max + alt_interval
    temp = SA.isa2temp(isa_dev, alt, temp_units=temp_units)
    time = 0
    fuel_used = 0
    dist = 0

    if output == 'raw':
        print(S.center('Altitude', 10), end=' ')
        print(S.center('ROD', 10), end=' ')
        print(S.center('Time', 10), end=' ')
        print(S.center('Fuel Used', 10), end=' ')
        print(S.center('Dist', 10), end=' ')
        print(S.center('Speed', 10))

        print(S.center('(ft)', 10), end=' ')
        print(S.center('(ft/mn)', 10), end=' ')
        print(S.center('(mn)', 10), end=' ')
        f_units = '(' + fuel_units + ')'
        print(S.center(f_units, 10), end=' ')
        print(S.center('(nm)', 10), end=' ')
        print(S.center('(KCAS)', 10))

        # # data for max altitude
        # print S.rjust(locale.format('%.0f', alt_max, True), 7),
        # print S.rjust(locale.format('%.0f', round(ROD / 10.) * 10, True), 10),
        # print S.rjust('%.1f' % (0), 10),
        # print S.rjust('%.1f' % (fuel_used), 10),
        # print S.rjust('%.1f' % (dist), 10),
        # print S.rjust('%3d' % (A.tas2cas(tas, alt_max, temp, temp_units=temp_units)), 10)

    # elif output == 'latex':
    #     # temp = 15 + isa_dev
    #     MSL_line = []
    #     MSL_line.append(str(locale.format('%.0f', weight, True)))
    #     MSL_line.append('0')
    #     MSL_line.append(str(locale.format('%.0f', temp)))
    #     MSL_line.append(str(locale.format('%.0f', A.tas2cas(tas, alt, temp, temp_units=temp_units))))
    #     MSL_line.append(str(locale.format('%.0f', round(ROD / 10.) * 10, True)))
    #     MSL_line.append('0')
    #     MSL_line.append(str(fuel_used))
    #     MSL_line.append(str(dist))
    #
    #     print '&'.join(MSL_line) + '\\\\'
    #     print '\\hline'
    # elif output == 'array':
    #     # no header rows, but make blank array
    #     array = [[alt_max,0,0,0]]

    alts = []
    RODs = []
    times_temp = []
    CASs = []
    dists_temp = []
    fuel_useds_temp = []
    temps = []

    calc_alt = alt_max - alt_interval / 2.
    while alt > 0:
        temp = SA.isa2temp(isa_dev, alt, temp_units=temp_units)
        eas = A.tas2eas(tas, alt)
        drag = FT.eas2drag(eas, weight)
        pwr_level_flt = tas_fts * drag / 550
        thrust_power = pwr_level_flt + FT.Pexcess_vs_roc(weight, ROD)
        prop_eff = PM.prop_eff(prop,
                               thrust_power,
                               rpm,
                               tas,
                               alt,
                               temp,
                               temp_units=temp_units)
        calc_pwr = thrust_power / prop_eff
        #fuel_flow = IO.pwr2ff(calc_pwr, rpm, ff_units = 'lb/hr')
        fuel_flow = calc_pwr * sfc
        # print "Level flt pwr = %.1f, thrust power = %.1f, prop eff = %.3f, fuel flow = %.3f" % (pwr_level_flt, thrust_power, prop_eff, fuel_flow)
        slice_time = alt_interval / rod_fts * -1.
        slice_dist = tas_fts * slice_time
        slice_fuel = fuel_flow * slice_time / 3600
        fuel_used += slice_fuel
        fuel_out = (U.avgas_conv(fuel_used, from_units = 'lb', \
            to_units = fuel_units))
        weight -= slice_fuel
        alt -= alt_interval
        cas_out = A.tas2cas(tas, alt, temp, temp_units=temp_units)
        temp_out = SA.isa2temp(isa_dev, alt)
        time += slice_time / 60.
        dist += slice_dist / 6076.115

        alts.append(alt)
        CASs.append(cas_out)
        RODs.append(ROD)
        times_temp.append(time)
        fuel_useds_temp.append(fuel_out)
        dists_temp.append(dist)
        temps.append(temp_out)

        calc_alt += alt_interval

    alts.reverse()
    CASs.reverse()
    RODs.reverse()
    temps.reverse()

    times = []
    fuel_useds = []
    dists = []

    for n, time in enumerate(times_temp):
        times.append(times_temp[-1] - time)
        fuel_useds.append(fuel_useds_temp[-1] - fuel_useds_temp[n])
        dists.append(dists_temp[-1] - dists_temp[n])

    times.reverse()
    fuel_useds.reverse()
    dists.reverse()

    if output == 'raw':
        for n, alt in enumerate(alts):
            print(S.rjust(locale.format('%.0f', alt, True), 7), end=' ')
            # calculate ROC at the displayed altitude
            print(S.rjust(locale.format('%.0f', RODs[n], True), 10), end=' ')
            print(S.rjust('%.1f' % (times[n]), 10), end=' ')
            print(S.rjust('%.1f' % (fuel_useds[n]), 10), end=' ')
            print(S.rjust('%.1f' % (dists[n]), 10), end=' ')
            print(S.rjust('%3d' % (int(CASs[n])), 10))
    elif output == 'latex':
        for n, alt in enumerate(alts):
            line = []
            line.append(str(locale.format('%.0f', alt, True)))
            line.append(str(locale.format('%.0f', round(temps[n]))))
            line.append(str(locale.format('%.0f', CASs[n])))
            line.append(
                str(locale.format('%.0f',
                                  round(RODs[n] / 10.) * 10, True)))
            line.append(str(locale.format('%.0f', times[n])))
            line.append(str(locale.format('%.1f', fuel_useds[n])))
            line.append(str(locale.format('%.0f', dists[n])))
            print('&' + '&'.join(line) + '\\\\')
            print('\\hline')
    elif output == 'array':
        array = []
        for n, alt in enumerate(alts):
            array.append([alt, times[n], fuel_useds[n], dists[n]])
        return array
コード例 #12
0
ファイル: rv8_test.py プロジェクト: khorton/AeroCalc_Package
def climb_data(prop, weight = 1800., alt_max = 20000., TO_fuel = 0, TO_dist = 0, \
    fuel_units = 'USG', alt_interval = 500., isa_dev = 0, temp_units = 'C', \
    rv = '8', wing_area = 110., pwr = 'max', pwr_factor=1.0, \
    climb_speed = 'max', output = 'raw'):
    """
    Returns a table of climb performance vs altitude.

    The items in each row of the table are altitude, time, fuel burned and distance.
    Time is in units of minutes, rounded to the nearest half minute.
    Fuel units are selectable, with a default of USG.
    Distances are in nm.
    
    The output may be specified as raw, latex (a LaTeX table for the POH), or array.
    
    pwr may be 'max', 'cc' (cruise climb = 2500 rpm and 25") or 2500 (2500 rpm and full throttle)
    climb_speed may be 'max' (Vy), 'cc' (120 kt to 10,000 ft, then reducing by 4 kt/1000 ft) or
                'norm' (100 kt to 10,000 ft, then reducing by 2 kt/1000 ft)
                
    Note: compared cruise range for all climb speed and power.  The predicted results are all 
          within 1.5 nm of range.  Thus there is no advantage to using anything but Vy and max
          power.
    """
    def _alt2ROC(prop, alt):
        """
        calculate ROC for an altitude
        """
        temp = SA.isa2temp(isa_dev, alt)
        calc_pwr = alt2pwr(alt, rpm=rpm, MP_max=MP_max, temp=temp) * pwr_factor
        cas = alt2roc_speed(alt, climb_speed=climb_speed)
        eas = A.cas2eas(cas, alt)
        ROC = roc(prop, alt, eas, weight, calc_pwr, rpm, rv = rv, \
            wing_area = wing_area)

        return ROC

    alt = 0
    time = 0
    fuel_used = U.avgas_conv(TO_fuel, from_units=fuel_units, to_units='lb')
    weight = weight - fuel_used
    dist = TO_dist
    if pwr == 'max':
        # rpm = 2700
        rpm = 2650
        MP_max = 30
    elif pwr == 'cc':
        rpm = 2500
        MP_max = 25
    elif pwr == 2500:
        rpm = 2500
        MP_max = 30
    else:
        raise ValueError("pwr must be one of 'max', 'cc', or 2500")

    if output == 'raw':
        print(S.center('Altitude', 10), end=' ')
        print(S.center('ROC', 10), end=' ')
        print(S.center('Time', 10), end=' ')
        print(S.center('Fuel Used', 10), end=' ')
        print(S.center('Dist', 10), end=' ')
        print(S.center('Speed', 10))

        print(S.center('(ft)', 10), end=' ')
        print(S.center('(ft/mn)', 10), end=' ')
        print(S.center('(mn)', 10), end=' ')
        f_units = '(' + fuel_units + ')'
        print(S.center(f_units, 10), end=' ')
        print(S.center('(nm)', 10), end=' ')
        print(S.center('(KCAS)', 10))

        # data for MSL
        print(S.rjust(locale.format('%.0f', 0, True), 7), end=' ')
        # calculate ROC at MSL
        print(S.rjust(locale.format('%.0f', round(_alt2ROC(prop, 0) / 10.) * 10, \
            True), 10), end=' ')
        print(S.rjust('%.1f' % (0), 10), end=' ')
        print(S.rjust('%.1f' % (TO_fuel), 10), end=' ')
        print(S.rjust('%.1f' % (TO_dist), 10), end=' ')
        print(S.rjust('%3d' % (alt2roc_speed(0, climb_speed=climb_speed)), 10))

    elif output == 'latex':
        temp = 15 + isa_dev
        MSL_line = []
        MSL_line.append(str(locale.format('%.0f', weight, True)))
        MSL_line.append('0')
        MSL_line.append(str(locale.format('%.0f', temp)))
        MSL_line.append(str(locale.format('%.0f', alt2roc_speed(0, \
            climb_speed = climb_speed))))
        MSL_line.append(str(locale.format('%.0f', round(_alt2ROC(prop, 0) / 10.)\
          * 10, True)))
        MSL_line.append('0')
        MSL_line.append(str(TO_fuel))
        MSL_line.append(str(TO_dist))

        print('&'.join(MSL_line) + '\\\\')
        print('\\hline')
    elif output == 'array':
        # no header rows, but make blank array
        array = [[0, 0, TO_fuel, 0]]

    calc_alt = alt_interval / 2.
    while calc_alt < alt_max:
        temp = SA.isa2temp(isa_dev, calc_alt)
        pwr = alt2pwr(calc_alt, rpm=rpm, MP_max=MP_max, temp=temp)
        calc_pwr = pwr * pwr_factor
        cas = alt2roc_speed(calc_alt, climb_speed=climb_speed)
        eas = A.cas2eas(cas, calc_alt)
        tas = A.cas2tas(cas, calc_alt, temp=temp, temp_units=temp_units)
        tas_fts = U.speed_conv(tas, from_units='kt', to_units='ft/s')
        ROC = roc(prop, calc_alt, eas, weight, calc_pwr, rpm, rv = rv, \
            wing_area = wing_area)
        roc_fts = ROC / 60
        fuel_flow = IO.pwr2ff(pwr, rpm, ff_units='lb/hr')
        slice_time = alt_interval / roc_fts
        slice_dist = tas_fts * slice_time
        slice_fuel = fuel_flow * slice_time / 3600
        fuel_used += slice_fuel
        fuel_out = (U.avgas_conv(fuel_used, from_units = 'lb', \
            to_units = fuel_units))
        weight -= slice_fuel
        alt += alt_interval
        cas_out = alt2roc_speed(alt, climb_speed=climb_speed)
        temp_out = SA.isa2temp(isa_dev, alt)
        ROC = _alt2ROC(prop, alt)
        time += slice_time / 60
        dist += slice_dist / 6076.115

        if output == 'raw':
            print(S.rjust(locale.format('%.0f', alt, True), 7), end=' ')
            # calculate ROC at the displayed altitude
            print(S.rjust(locale.format('%.0f', ROC, True), 10), end=' ')
            print(S.rjust('%.1f' % (time), 10), end=' ')
            print(S.rjust('%.1f' % (fuel_out), 10), end=' ')
            print(S.rjust('%.1f' % (dist), 10), end=' ')
            print(S.rjust('%3d' % (int(cas_out)), 10))
        elif output == 'latex':
            line = []
            line.append(str(locale.format('%.0f', alt, True)))
            line.append(str(locale.format('%.0f', round(temp_out))))
            line.append(str(locale.format('%.0f', cas_out)))
            line.append(str(locale.format('%.0f',
                                          round(ROC / 10.) * 10, True)))
            line.append(str(locale.format('%.0f', time)))
            line.append(str(locale.format('%.1f', fuel_out)))
            line.append(str(locale.format('%.0f', dist)))
            print('&' + '&'.join(line) + '\\\\')
            print('\\hline')
        elif output == 'array':
            array.append([alt, time, fuel_out, dist])
        calc_alt += alt_interval
    if output == 'array':
        return array