Esempio n. 1
0
def alt2temp(H, alt_units=default_alt_units, temp_units=default_temp_units):
    """Return the standard temperature for the specified altitude.  Altitude
    units may be feet ('ft'), metres ('m'), statute miles, ('sm') or 
    nautical miles ('nm').  Temperature units may be degrees C, F, K or R 
    ('C', 'F', 'K' or 'R')  
    
    If the units are not specified, the units in default_units.py are used.
    
    Examples:
    
    Calculate the standard temperature (in default temperature units) at 
    5,000 (default altitude units):
    >>> alt2temp(5000)
    5.093999999999994
    
    Calculate the standard temperature in deg F at sea level:
    >>> alt2temp(0, temp_units = 'F')
    59.0
    
    Calculate the standard temperature in deg K at 11,000 m:
    >>> alt2temp(11000, alt_units = 'm', temp_units = 'K')
    216.64999999999998
    
    Calculate the standard temperature at 11 statute miles in deg R:
    >>> alt2temp(11, alt_units = 'sm', temp_units = 'R')
    389.96999999999997
    
    The input value may be an expression:
    >>> alt2temp(11 * 5280, temp_units = 'R')
    389.96999999999997
    
    """

    # Validated to 84000 m
    # uses meters and degrees K for the internal calculations

    # function tested in tests/test_std_atm.py

    H = U.length_conv(H, from_units=alt_units, to_units='km')

    if H <= 11:
        temp = T0 + H * L0
    elif H <= 20:
        temp = T11
    elif H <= 32:
        temp = T20 + (H - 20) * L20
    elif H <= 47:
        temp = T32 + (H - 32) * L32
    elif H <= 51:
        temp = T47
    elif H <= 71:
        temp = T51 + (H - 51) * L51
    elif H <= 84.852:
        temp = T71 + (H - 71) * L71
    else:
        raise ValueError(
            'This function is only implemented for altitudes of 84.852 km and below.'
        )

    return U.temp_conv(temp, to_units=temp_units, from_units='K')
Esempio n. 2
0
def cp2bhp(Cp,
           rpm,
           density,
           dia,
           power_units='hp',
           density_units='lb/ft**3',
           dia_units='in'):
    """
    Returns the bhp, given propeller power coefficient (Cp), revolutions per 
    minute (rpm), and propeller diameter.

    The power units may be specified as "hp", "ft-lb/mn", "ft-lb/s", "W"
    (watts) or "kW" (kilowatts), but default to "hp" if not specified.

    The density units may be specified as "lb/ft**3", "slug/ft**3" or 
    "kg/m**3", but default to "lb/ft**3" if not specified.

    The diameter units may be specified as "in", "ft", or "m", but default
    to inches if not specified.
    """
    # bhp = U.power_conv(bhp, from_units = power_units, to_units = 'W')
    density = U.density_conv(density,
                             from_units=density_units,
                             to_units='kg/m**3')
    dia = U.length_conv(dia, from_units=dia_units, to_units='m')

    bhp = Cp * (density * ((rpm / 60.)**3) * dia**5)
    bhp = U.power_conv(bhp, from_units='W', to_units=power_units)

    return bhp
Esempio n. 3
0
def tip_mach(tas,
             rpm,
             temperature,
             dia,
             speed_units='kt',
             temp_units='C',
             dia_units='in'):
    """
    Returns the mach number of the propeller blade tip, given the
    true airspeed (tas), revolutions per minute (rpm), temperature and
    propeller diameter.
    
    The speed units may be specified as "kt", "mph", "km/h" or "ft/s", but
    default to "kt" if not specified.
    
    The temperature units may be specified as "C", "F", "K" or "R", but
    default to deg C if not specified.
    
    The diameter units may be specified as "in", "ft", or "m", but default
    to inches if not specified.
    """
    dia = U.length_conv(dia, from_units=dia_units, to_units='m')
    tas = U.speed_conv(tas, from_units=speed_units, to_units='m/s')
    speed_of_sound = SA.temp2speed_of_sound(temperature,
                                            temp_units=temp_units,
                                            speed_units='m/s')

    rotation_speed = dia * rpm * M.pi / 60
    tip_speed = M.sqrt(tas**2 + rotation_speed**2)
    tip_mach = tip_speed / speed_of_sound

    return tip_mach
Esempio n. 4
0
def press2alt(P, press_units=default_press_units, alt_units=default_alt_units):
    """
    Return the altitude corresponding to the specified pressure, with
    pressure in inches of HG, mm of HG, psi, psf (lb per sq. ft), pa, hpa or
    mb. 
    
    The altitude is in units of feet ('ft'), metres ('m'), statute miles, 
    ('sm') or nautical miles ('nm')
    
    If the units are not specified, the units in default_units.py are used.
    
    Examples:
    
    Calculate the pressure altitude in feet for a pressure of 31.0185 inches
    of HG:
    >>> press2alt(31.0185)
    -999.9602016597179
    
    Calculate the pressure altitude in feet for a pressure of 
    1455.33 lb sq. ft:
    >>> press2alt(1455.33, press_units = 'psf')
    10000.029960829057
    
    Calculate the pressure altitude in metres for a pressure of 
    90.3415 mm HG:
    >>> press2alt(90.3415, press_units = 'mm HG', alt_units = 'm')
    15000.032231346277
    
    Calculate the pressure altitude in metres for a pressure of 
    1171.86 pascal:
    >>> press2alt(1171.86, press_units = 'pa', alt_units = 'm')
    30000.03658869385
    """

    # function tested in tests/test_std_atm.py

    P = U.press_conv(P, from_units=press_units, to_units='pa')

    if P > P11:
        H = _press2alt_gradient(P, P0, 0, T0, L0)
    elif P > P20:
        H = _press2alt_isothermal(P, P11, 11, T11)
    elif P > P32:
        H = _press2alt_gradient(P, P20, 20, T20, L20)
    elif P > P47:
        H = _press2alt_gradient(P, P32, 32, T32, L32)
    elif P > P51:
        H = _press2alt_isothermal(P, P47, 47, T47)
    elif P > P71:
        H = _press2alt_gradient(P, P51, 51, T51, L51)
    else:
        H = _press2alt_gradient(P, P71, 71, T71, L71)

    if H > 84.852:
        raise ValueError(
            'This function is only implemented for altitudes of 84.852 km and below.'
        )

    return U.length_conv(H, from_units='km', to_units=alt_units)
Esempio n. 5
0
def alt2temp(H, alt_units=default_alt_units,
             temp_units=default_temp_units):
    """Return the standard temperature for the specified altitude.  Altitude
    units may be feet ('ft'), metres ('m'), statute miles, ('sm') or 
    nautical miles ('nm').  Temperature units may be degrees C, F, K or R 
    ('C', 'F', 'K' or 'R')  
    
    If the units are not specified, the units in default_units.py are used.
    
    Examples:
    
    Calculate the standard temperature (in default temperature units) at 
    5,000 (default altitude units):
    >>> alt2temp(5000)
    5.0939999999999941
    
    Calculate the standard temperature in deg F at sea level:
    >>> alt2temp(0, temp_units = 'F')
    59.0
    
    Calculate the standard temperature in deg K at 11,000 m:
    >>> alt2temp(11000, alt_units = 'm', temp_units = 'K')
    216.64999999999998
    
    Calculate the standard temperature at 11 statute miles in deg R:
    >>> alt2temp(11, alt_units = 'sm', temp_units = 'R')
    389.96999999999997
    
    The input value may be an expression:
    >>> alt2temp(11 * 5280, temp_units = 'R')
    389.96999999999997
    
    """

    # Validated to 84000 m
    # uses meters and degrees K for the internal calculations

    # function tested in tests/test_std_atm.py

    H = U.length_conv(H, from_units=alt_units, to_units='km')

    if H <= 11:
        temp = T0 + H * L0
    elif H <= 20:
        temp = T11
    elif H <= 32:
        temp = T20 + (H - 20) * L20
    elif H <= 47:
        temp = T32 + (H - 32) * L32
    elif H <= 51:
        temp = T47
    elif H <= 71:
        temp = T51 + (H - 51) * L51
    elif H <= 84.852:
        temp = T71 + (H - 71) * L71
    else:
        raise ValueError('This function is only implemented for altitudes of 84.852 km and below.')

    return U.temp_conv(temp, to_units=temp_units, from_units='K')
Esempio n. 6
0
def QNH(
    HP,
    H,
    alt_units=default_alt_units,
    alt_setting_units='in HG',
):
    """
    Return the altimeter setting, given the pressure altitude (HP) and the 
    barometric altitude (H).
    """

    HP = U.length_conv(HP, from_units=alt_units, to_units='ft')
    H = U.length_conv(H, from_units=alt_units, to_units='ft')
    QNH = P0 * (1 - (HP - H) / 145442.2)**5.255594
    QNH = U.press_conv(QNH, from_units='in HG', to_units=alt_setting_units)

    return QNH
Esempio n. 7
0
def press2alt(P, press_units=default_press_units,
              alt_units=default_alt_units):
    """
    Return the altitude corresponding to the specified pressure, with
    pressure in inches of HG, mm of HG, psi, psf (lb per sq. ft), pa, hpa or
    mb. 
    
    The altitude is in units of feet ('ft'), metres ('m'), statute miles, 
    ('sm') or nautical miles ('nm')
    
    If the units are not specified, the units in default_units.py are used.
    
    Examples:
    
    Calculate the pressure altitude in feet for a pressure of 31.0185 inches
    of HG:
    >>> press2alt(31.0185)
    -999.96020165971788
    
    Calculate the pressure altitude in feet for a pressure of 
    1455.33 lb sq. ft:
    >>> press2alt(1455.33, press_units = 'psf')
    10000.029960829057
    
    Calculate the pressure altitude in metres for a pressure of 
    90.3415 mm HG:
    >>> press2alt(90.3415, press_units = 'mm HG', alt_units = 'm')
    15000.032231346277
    
    Calculate the pressure altitude in metres for a pressure of 
    1171.86 pascal:
    >>> press2alt(1171.86, press_units = 'pa', alt_units = 'm')
    30000.036588693849
    """

    # function tested in tests/test_std_atm.py

    P = U.press_conv(P, from_units=press_units, to_units='pa')

    if P > P11:
        H = _press2alt_gradient(P, P0, 0, T0, L0)
    elif P > P20:
        H = _press2alt_isothermal(P, P11, 11, T11)
    elif P > P32:
        H = _press2alt_gradient(P, P20, 20, T20, L20)
    elif P > P47:
        H = _press2alt_gradient(P, P32, 32, T32, L32)
    elif P > P51:
        H = _press2alt_isothermal(P, P47, 47, T47)
    elif P > P71:
        H = _press2alt_gradient(P, P51, 51, T51, L51)
    else:
        H = _press2alt_gradient(P, P71, 71, T71, L71)

    if H > 84.852:
        raise ValueError('This function is only implemented for altitudes of 84.852 km and below.')

    return U.length_conv(H, from_units='km', to_units=alt_units)
Esempio n. 8
0
def QNH(
    HP,
    H,
    alt_units=default_alt_units,
    alt_setting_units='in HG',
    ):
    """
    Return the altimeter setting, given the pressure altitude (HP) and the 
    barometric altitude (H).
    """

    HP = U.length_conv(HP, from_units=alt_units, to_units='ft')
    H = U.length_conv(H, from_units=alt_units, to_units='ft')
    QNH = P0 * (1 - (HP - H) / 145442.2) ** 5.255594
    QNH = U.press_conv(QNH, from_units='in HG',
                       to_units=alt_setting_units)

    return QNH
Esempio n. 9
0
def pressure_alt(H, alt_setting, alt_units=default_alt_units):
    """
    Return the pressure altitude, given the barometric altitude and the
    altimeter setting. 
    
    Altimeter setting may have units of inches of HG, or hpa or mb.  If the
    altimeter setting value is less than 35, the units are assumed to be
    in HG, otherwise they are assumed to be hpa.  The altimeter setting must
    be in the range of 25 to 35 inches of mercury.
    
    The altitude may have units of feet ('ft'), metres ('m'), statute miles,
    ('sm') or nautical miles ('nm').

    If the units are not specified, the units in default_units.py are used.
    
    Examples:
    
    Calculate the pressure altitude for 1,000 (default altitude units) 
    barometric altitude with altimeter setting of 30.92 in HG:
    >>> pressure_alt(1000, 30.92)
    88.6424431787118
    
    Calculate the pressure altitude for 1,000 (default altitude units) 
    barometric altitude with altimeter setting of 1008 mb:
    >>> pressure_alt(1000, 1008)
    1143.679844292918
    
    Calculate the pressure altitude in metres for 304.8 m barometric 
    altitude with altimeter setting of 1008 mb:
    >>> pressure_alt(304.8, 1008, alt_units = 'm')
    348.59361654048143
    """

    H = U.length_conv(H, from_units=alt_units, to_units='ft')
    if alt_setting > 35:
        alt_setting = U.press_conv(alt_setting,
                                   from_units='hpa',
                                   to_units='in HG')
    if alt_setting < 25 or alt_setting > 35:
        raise ValueError('Altimeter setting out of range.')
    base_press = U.press_conv(P0, from_units='pa', to_units='in HG')
    HP = H + 145442.2 * (1 - (alt_setting / base_press)**0.190261)
    HP = U.length_conv(HP, from_units='ft', to_units=alt_units)
    return HP
Esempio n. 10
0
def pressure_alt(H, alt_setting, alt_units=default_alt_units):
    """
    Return the pressure altitude, given the barometric altitude and the
    altimeter setting. 
    
    Altimeter setting may have units of inches of HG, or hpa or mb.  If the
    altimeter setting value is less than 35, the units are assumed to be
    in HG, otherwise they are assumed to be hpa.  The altimeter setting must
    be in the range of 25 to 35 inches of mercury.
    
    The altitude may have units of feet ('ft'), metres ('m'), statute miles,
    ('sm') or nautical miles ('nm').

    If the units are not specified, the units in default_units.py are used.
    
    Examples:
    
    Calculate the pressure altitude for 1,000 (default altitude units) 
    barometric altitude with altimeter setting of 30.92 in HG:
    >>> pressure_alt(1000, 30.92)
    88.642443178711801
    
    Calculate the pressure altitude for 1,000 (default altitude units) 
    barometric altitude with altimeter setting of 1008 mb:
    >>> pressure_alt(1000, 1008)
    1143.679844292918
    
    Calculate the pressure altitude in metres for 304.8 m barometric 
    altitude with altimeter setting of 1008 mb:
    >>> pressure_alt(304.8, 1008, alt_units = 'm')
    348.59361654048143
    """

    H = U.length_conv(H, from_units=alt_units, to_units='ft')
    if alt_setting > 35:
        alt_setting = U.press_conv(alt_setting, from_units='hpa',
                                   to_units='in HG')
    if alt_setting < 25 or alt_setting > 35:
        raise ValueError('Altimeter setting out of range.')
    base_press = U.press_conv(P0, from_units='pa', to_units='in HG')
    HP = H + 145442.2 * (1 - (alt_setting / base_press) ** 0.190261)
    HP = U.length_conv(HP, from_units='ft', to_units=alt_units)
    return HP
Esempio n. 11
0
def ct2thrust(Ct, Rho, rpm, dia, thrust_units="lb", density_units="lb/ft**3", dia_units="in"):
    """
    Returns the thrust, given thrust coefficient, Ct, density, rpm and prop
    diameter.
    """
    Rho = U.density_conv(Rho, from_units=density_units, to_units="kg/m**3")
    dia = U.length_conv(dia, from_units=dia_units, to_units="m")
    # convert rpm to revolutions / s
    n = rpm / 60.0
    thrust = Ct * Rho * n ** 2.0 * dia ** 4.0

    return U.force_conv(thrust, from_units="N", to_units=thrust_units)
Esempio n. 12
0
def pwr(rpm, MP, altitude, temp  = 'std', alt_units = 'ft', temp_units = 'C'):
    """ 
    Returns horsepower for Lycoming IO-360-A series engines, given:
    rpm - engine speed in revolutions per minute
    MP - manifold pressure (" HG)
    altitude - pressure altitude
    temp - ambient temperature  (optional - std temperature is used if no 
           temperature is input).
    alt_units - (optional) - units for altitude, ft, m, or km 
                                 (default is ft)
    temp_units - (optional) - units for temperature, C, F, K or R 
                              (default is deg C)
    
    The function replicates Lycoming curve 12700-A, and is valid at mixture 
    for maximum power.
    
    Examples:
    
    Determine power at 2620 rpm, 28 inches HG manifold pressure, 0 ft, and 
    -10 deg C:
    >>> pwr(2620, 28, 0, -10)
    197.71751932574702
    
    Determine power at 2500 rpm, 25" MP, 5000 ft and 0 deg F:
    >>> pwr(2500, 25, 5000, 0, temp_units = 'F')
    171.87810350172663
    
    Determine power at 2200 rpm, 20" MP, 2000 metres and -5 deg C
    >>> pwr(2200, 20, 2000, -5, alt_units = 'm')
    108.60284092217333
    
    Determine power at 2200 rpm, 20" MP, 2000 metres and standard 
    temperature:
    >>> pwr(2200, 20, 2000, alt_units = 'm')
    107.2124765533882
    """
    # convert units
    altitude = U.length_conv(altitude, from_units = alt_units, to_units = 'ft')
    if temp == 'std':
        temp = SA.alt2temp(altitude, temp_units = temp_units)
    temp = U.temp_conv(temp, from_units = temp_units, to_units = 'K')
    
    # get standard temperature
    temp_std = SA.alt2temp(altitude, temp_units = 'K')
    
    # get power at standard temperature
    pwr_std = _pwr_std_temp(rpm, MP, altitude)
    
    # correct power for non-standard temperature
    pwr = pwr_std * M.sqrt(temp_std / temp)
    
    return pwr
Esempio n. 13
0
def pwr(rpm, MP, altitude, temp  = 'std', alt_units = 'ft', temp_units = 'C'):
	""" 
	Returns horsepower for Lycoming O-360-A series engines, given:
	rpm - engine speed in revolutions per minute
	MP - manifold pressure (" HG)
	altitude - pressure altitude
	temp - ambient temperature  (optional - std temperature is used if no 
	       temperature is input).
	alt_units - (optional) - units for altitude, ft, m, or km 
	                             (default is ft)
	temp_units - (optional) - units for temperature, C, F, K or R 
	                          (default is deg C)
	
	The function replicates Lycoming curve ??????? and is valid at mixture 
	for maximum power.
	
	Examples:
	
	Determine power at 2620 rpm, 28 inches HG manifold pressure, 0 ft, 
	and -10 deg C:
	>>> pwr(2620, 28, 0, -10)
	183.91485642478889
	
	Determine power at 2500 rpm, 25" MP, 5000 ft and 0 deg F:
	>>> pwr(2500, 25, 5000, 0, temp_units = 'F')
	164.10572738791328
	
	Determine power at 2200 rpm, 20" MP, 2000 metres and -5 deg C
	>>> pwr(2200, 20, 2000, -5, alt_units = 'm')
	111.72954664842844
	
	Determine power at 2200 rpm, 20" MP, 2000 metres and standard 
	temperature:
	>>> pwr(2200, 20, 2000, alt_units = 'm')
	110.29915330621547
	"""
	# convert units
	altitude = U.length_conv(altitude, from_units = alt_units, to_units = 'ft')
	if temp == 'std':
		temp = SA.alt2temp(altitude, temp_units = temp_units)
	temp = U.temp_conv(temp, from_units = temp_units, to_units = 'K')
	
	# get standard temperature
	temp_std = SA.alt2temp(altitude, temp_units = 'K')
	
	# get power at standard temperature
	pwr_std = _pwr_std_temp(rpm, MP, altitude)
	
	# correct power for non-standard temperature
	pwr = pwr_std * M.sqrt(temp_std / temp)
	
	return pwr
Esempio n. 14
0
def pwr(rpm, MP, altitude, temp='std', alt_units='ft', temp_units='C'):
    """ 
    Returns horsepower for Lycoming IO-360-A series engines, given:
    rpm - engine speed in revolutions per minute
    MP - manifold pressure (" HG)
    altitude - pressure altitude
    temp - ambient temperature  (optional - std temperature is used if no 
           temperature is input).
    alt_units - (optional) - units for altitude, ft, m, or km 
                                 (default is ft)
    temp_units - (optional) - units for temperature, C, F, K or R 
                              (default is deg C)
    
    The function replicates Lycoming curve 12700-A, and is valid at mixture 
    for maximum power.
    
    Examples:
    
    Determine power at 2620 rpm, 28 inches HG manifold pressure, 0 ft, and 
    -10 deg C:
    >>> pwr(2620, 28, 0, -10)
    197.71751932574702
    
    Determine power at 2500 rpm, 25" MP, 5000 ft and 0 deg F:
    >>> pwr(2500, 25, 5000, 0, temp_units = 'F')
    171.87810350172663
    
    Determine power at 2200 rpm, 20" MP, 2000 metres and -5 deg C
    >>> pwr(2200, 20, 2000, -5, alt_units = 'm')
    108.60284092217333
    
    Determine power at 2200 rpm, 20" MP, 2000 metres and standard 
    temperature:
    >>> pwr(2200, 20, 2000, alt_units = 'm')
    107.2124765533882
    """
    # convert units
    altitude = U.length_conv(altitude, from_units=alt_units, to_units='ft')
    if temp == 'std':
        temp = SA.alt2temp(altitude, temp_units=temp_units)
    temp = U.temp_conv(temp, from_units=temp_units, to_units='K')

    # get standard temperature
    temp_std = SA.alt2temp(altitude, temp_units='K')

    # get power at standard temperature
    pwr_std = _pwr_std_temp(rpm, MP, altitude)

    # correct power for non-standard temperature
    pwr = pwr_std * M.sqrt(temp_std / temp)

    return pwr
Esempio n. 15
0
def pwr(rpm, MP, altitude, temp='std', alt_units='ft', temp_units='C'):
    """
    Returns horsepower for Lycoming O-360-A series engines, given:
    rpm - engine speed in revolutions per minute
    MP - manifold pressure (" HG)
    altitude - pressure altitude
    temp - ambient temperature  (optional - std temperature is used if no
           temperature is input).
    alt_units - (optional) - units for altitude, ft, m, or km
                                 (default is ft)
    temp_units - (optional) - units for temperature, C, F, K or R
                              (default is deg C)

    The function replicates Lycoming curve ??????? and is valid at mixture
    for maximum power.

    Examples:

    Determine power at 2620 rpm, 28 inches HG manifold pressure, 0 ft,
    and -10 deg C:
    >>> pwr(2620, 28, 0, -10)
    183.91485642478889

    Determine power at 2500 rpm, 25" MP, 5000 ft and 0 deg F:
    >>> pwr(2500, 25, 5000, 0, temp_units = 'F')
    164.10572738791328

    Determine power at 2200 rpm, 20" MP, 2000 metres and -5 deg C
    >>> pwr(2200, 20, 2000, -5, alt_units = 'm')
    111.72954664842844

    Determine power at 2200 rpm, 20" MP, 2000 metres and standard
    temperature:
    >>> pwr(2200, 20, 2000, alt_units = 'm')
    110.29915330621547
    """
    # convert units
    altitude = U.length_conv(altitude, from_units=alt_units, to_units='ft')
    if temp == 'std':
        temp = SA.alt2temp(altitude, temp_units=temp_units)
    temp = U.temp_conv(temp, from_units=temp_units, to_units='K')

    # get standard temperature
    temp_std = SA.alt2temp(altitude, temp_units='K')

    # get power at standard temperature
    pwr_std = _pwr_std_temp(rpm, MP, altitude)

    # correct power for non-standard temperature
    pwr = pwr_std * np.sqrt(temp_std / temp)

    return pwr
Esempio n. 16
0
def alt2press_ratio(H, alt_units=default_alt_units):
    """
    Return the pressure ratio (atmospheric pressure / standard pressure
    for sea level).  The altitude is specified in feet ('ft'), metres ('m'),
    statute miles, ('sm') or nautical miles ('nm').   
    
    If the units are not specified, the units in default_units.py are used.
    
    Examples:
    
    Calculate the pressure ratio at 5000 (default altitude units):
    >>> alt2press_ratio(5000)
    0.8320481158727735
    
    Calculate the pressure ratio at 1000 m:
    >>> alt2press_ratio(1000, alt_units = 'm')
    0.8869930463888704
    
    The functions are only implemented at altitudes of 84.852 km and lower.
    >>> alt2press_ratio(90, alt_units = 'km')
    Traceback (most recent call last):
      File \"<stdin>\", line 1, in <module>
      File \"std_atm.py\", line 461, in alt2press_ratio
        'This function is only implemented for altitudes of 84.852 km and below.'
    ValueError: This function is only implemented for altitudes of 84.852 km and below.
        """

    # uses meters and degrees K for the internal calculations

    # function tested in tests/test_std_atm.py

    H = U.length_conv(H, from_units=alt_units, to_units='km')

    if H <= 11:
        return _alt2press_ratio_gradient(H, 0, P0, T0, L0)
    if H <= 20:
        return _alt2press_ratio_isothermal(H, 11, P11, T11)
    if H <= 32:
        return _alt2press_ratio_gradient(H, 20, P20, T20, L20)
    if H <= 47:
        return _alt2press_ratio_gradient(H, 32, P32, T32, L32)
    if H <= 51:
        return _alt2press_ratio_isothermal(H, 47, P47, T47)
    if H <= 71:
        return _alt2press_ratio_gradient(H, 51, P51, T51, L51)
    if H <= 84.852:
        return _alt2press_ratio_gradient(H, 71, P71, T71, L71)
    else:
        raise ValueError(
            'This function is only implemented for altitudes of 84.852 km and below.'
        )
Esempio n. 17
0
def density2alt(Rho,
                density_units=default_density_units,
                alt_units=default_alt_units):
    """
    Return the altitude corresponding to the specified density, with
    density in 'lb/ft**3', 'slug/ft**3' or 'kg/m**3'.  
    
    The altitude is specified in feet ('ft'), metres ('m'), statute miles, 
    ('sm') or nautical miles ('nm').
    
    If the units are not specified, the units in default_units.py are used.
    
    Examples:
    
    Calculate the altitude in default altitude units where the density is 
    0.056475 in default density units:
    >>> density2alt(.056475)
    9999.804093493727
    
    Calculate the altitude in metres where the density is 0.018012 kg / m 
    cubed:
    >>> density2alt(.018012, alt_units = 'm', density_units = 'kg/m**3')
    29999.978688508152
    """

    # function tested in tests/test_std_atm.py

    Rho = U.density_conv(Rho, from_units=density_units, to_units='kg/m**3')

    if Rho > Rho11:
        H = _density2alt_gradient(Rho, Rho0, 0, T0, L0)
    elif Rho > Rho20:
        H = _density2alt_isothermal(Rho, Rho11, 11, T11)
    elif Rho > Rho32:
        H = _density2alt_gradient(Rho, Rho20, 20, T20, L20)
    elif Rho > Rho47:
        H = _density2alt_gradient(Rho, Rho32, 32, T32, L32)
    elif Rho > Rho51:
        H = _density2alt_isothermal(Rho, Rho47, 47, T47)
    elif Rho > Rho71:
        H = _density2alt_gradient(Rho, Rho51, 51, T51, L51)
    else:
        H = _density2alt_gradient(Rho, Rho71, 71, T71, L71)

    if H > 84.852:
        raise ValueError(
            'This function is only implemented for altitudes of 84.852 km and below.'
        )

    return U.length_conv(H, from_units='km', to_units=alt_units)
Esempio n. 18
0
def alt2press_ratio(H, alt_units=default_alt_units):
    """
    Return the pressure ratio (atmospheric pressure / standard pressure
    for sea level).  The altitude is specified in feet ('ft'), metres ('m'),
    statute miles, ('sm') or nautical miles ('nm').   
    
    If the units are not specified, the units in default_units.py are used.
    
    Examples:
    
    Calculate the pressure ratio at 5000 (default altitude units):
    >>> alt2press_ratio(5000)
    0.8320481158727735
    
    Calculate the pressure ratio at 1000 m:
    >>> alt2press_ratio(1000, alt_units = 'm')
    0.88699304638887044
    
    The functions are only implemented at altitudes of 84.852 km and lower.
    >>> alt2press_ratio(90, alt_units = 'km')
    Traceback (most recent call last):
      File \"<stdin>\", line 1, in <module>
      File \"std_atm.py\", line 461, in alt2press_ratio
        'This function is only implemented for altitudes of 84.852 km and below.'
    ValueError: This function is only implemented for altitudes of 84.852 km and below.
        """

    # uses meters and degrees K for the internal calculations

    # function tested in tests/test_std_atm.py

    H = U.length_conv(H, from_units=alt_units, to_units='km')

    if H <= 11:
        return _alt2press_ratio_gradient(H, 0, P0, T0, L0)
    if H <= 20:
        return _alt2press_ratio_isothermal(H, 11, P11, T11)
    if H <= 32:
        return _alt2press_ratio_gradient(H, 20, P20, T20, L20)
    if H <= 47:
        return _alt2press_ratio_gradient(H, 32, P32, T32, L32)
    if H <= 51:
        return _alt2press_ratio_isothermal(H, 47, P47, T47)
    if H <= 71:
        return _alt2press_ratio_gradient(H, 51, P51, T51, L51)
    if H <= 84.852:
        return _alt2press_ratio_gradient(H, 71, P71, T71, L71)
    else:
        raise ValueError('This function is only implemented for altitudes of 84.852 km and below.')
Esempio n. 19
0
def density2alt(Rho, density_units=default_density_units,
                alt_units=default_alt_units):
    """
    Return the altitude corresponding to the specified density, with
    density in 'lb/ft**3', 'slug/ft**3' or 'kg/m**3'.  
    
    The altitude is specified in feet ('ft'), metres ('m'), statute miles, 
    ('sm') or nautical miles ('nm').
    
    If the units are not specified, the units in default_units.py are used.
    
    Examples:
    
    Calculate the altitude in default altitude units where the density is 
    0.056475 in default density units:
    >>> density2alt(.056475)
    9999.8040934937271
    
    Calculate the altitude in metres where the density is 0.018012 kg / m 
    cubed:
    >>> density2alt(.018012, alt_units = 'm', density_units = 'kg/m**3')
    29999.978688508152
    """

    # function tested in tests/test_std_atm.py

    Rho = U.density_conv(Rho, from_units=density_units,
                         to_units='kg/m**3')

    if Rho > Rho11:
        H = _density2alt_gradient(Rho, Rho0, 0, T0, L0)
    elif Rho > Rho20:
        H = _density2alt_isothermal(Rho, Rho11, 11, T11)
    elif Rho > Rho32:
        H = _density2alt_gradient(Rho, Rho20, 20, T20, L20)
    elif Rho > Rho47:
        H = _density2alt_gradient(Rho, Rho32, 32, T32, L32)
    elif Rho > Rho51:
        H = _density2alt_isothermal(Rho, Rho47, 47, T47)
    elif Rho > Rho71:
        H = _density2alt_gradient(Rho, Rho51, 51, T51, L51)
    else:
        H = _density2alt_gradient(Rho, Rho71, 71, T71, L71)

    if H > 84.852:
        raise ValueError('This function is only implemented for altitudes of 84.852 km and below.')

    return U.length_conv(H, from_units='km', to_units=alt_units)
Esempio n. 20
0
def pp(rpm, MP, altitude, temp  = 'std', alt_units = 'ft', temp_units = 'C'):
    """
    Returns percent power for Lycoming IO-360-A series engines, given:
    rpm - engine speed in revolutions per minute
    MP - manifold pressure (" HG)
    altitude - pressure altitude
    temp - ambient temperature  (optional - std temperature is used if no 
           temperature is input).
    alt_units - (optional) - units for altitude, ft, m, or km 
                                 (default is ft)
    temp_units - (optional) - units for temperature, C, F, K or R 
                              (default is deg C)
    
    The function replicates Lycoming curve 12700-A, and is valid at mixture 
    for maximum power.
    
    Note: the output is rounded off to two decimal places.
    
    Examples:
    
    Determine power at 2620 rpm, 28 inches HG manifold pressure, 0 ft, and 
    -10 deg C:
    >>> pp(2620, 28, 0, -10)
    '98.86%'
    
    Determine power at 2500 rpm, 25" MP, 5000 ft and 0 deg F:
    >>> pp(2500, 25, 5000, 0, temp_units = 'F')
    '85.94%'
    
    Determine power at 2200 rpm, 20" MP, 2000 metres and -5 deg C
    >>> pp(2200, 20, 2000, -5, alt_units = 'm')
    '54.30%'
    
    Determine power at 2200 rpm, 20" MP, 2000 metres and standard 
    temperature:
    >>> pp(2200, 20, 2000, alt_units = 'm')
    '53.61%'
    
    """
    altitude = U.length_conv(altitude, from_units = alt_units, to_units = 'ft')
    if temp == 'std':
        temp = SA.alt2temp(altitude, temp_units = temp_units)
    temp = U.temp_conv(temp, from_units = temp_units, to_units = 'C')

    pp = pwr(rpm, MP, altitude, temp) / 2
    
#   return pp
    return '%.2f' % (pp) + '%'
Esempio n. 21
0
def pp(rpm, MP, altitude, temp='std', alt_units='ft', temp_units='C'):
    """
    Returns percent power for Lycoming IO-360-A series engines, given:
    rpm - engine speed in revolutions per minute
    MP - manifold pressure (" HG)
    altitude - pressure altitude
    temp - ambient temperature  (optional - std temperature is used if no 
           temperature is input).
    alt_units - (optional) - units for altitude, ft, m, or km 
                                 (default is ft)
    temp_units - (optional) - units for temperature, C, F, K or R 
                              (default is deg C)
    
    The function replicates Lycoming curve 12700-A, and is valid at mixture 
    for maximum power.
    
    Note: the output is rounded off to two decimal places.
    
    Examples:
    
    Determine power at 2620 rpm, 28 inches HG manifold pressure, 0 ft, and 
    -10 deg C:
    >>> pp(2620, 28, 0, -10)
    '98.86%'
    
    Determine power at 2500 rpm, 25" MP, 5000 ft and 0 deg F:
    >>> pp(2500, 25, 5000, 0, temp_units = 'F')
    '85.94%'
    
    Determine power at 2200 rpm, 20" MP, 2000 metres and -5 deg C
    >>> pp(2200, 20, 2000, -5, alt_units = 'm')
    '54.30%'
    
    Determine power at 2200 rpm, 20" MP, 2000 metres and standard 
    temperature:
    >>> pp(2200, 20, 2000, alt_units = 'm')
    '53.61%'
    
    """
    altitude = U.length_conv(altitude, from_units=alt_units, to_units='ft')
    if temp == 'std':
        temp = SA.alt2temp(altitude, temp_units=temp_units)
    temp = U.temp_conv(temp, from_units=temp_units, to_units='C')

    pp = pwr(rpm, MP, altitude, temp) / 2

    #   return pp
    return '%.2f' % (pp) + '%'
Esempio n. 22
0
def Re(V, L, KV, speed_units=default_speed_units, length_units=default_length_units, 
    #kinematic_viscosity_units=default_kinematic_viscosity_units
    ):
    """
    Return Reynold's number, given velocity, characteristic length and kinematic viscosity'
    
    V  = velocity
    L  = characteristic length
    KV = kinematic viscosity
    """
    V = U.speed_conv(V, speed_units, 'm/s')
    L = U.length_conv(L, length_units, 'm')
    # KV = U.kinematic_viscosity_conv(KV, kinematic_viscosity_units, '??')
    
    Re = V * L / KV
    
    return Re
Esempio n. 23
0
def pp2mp(percent_power,
          rpm,
          altitude,
          temp='std',
          alt_units='ft',
          temp_units='C'):
    """
    Returns manifold pressure in inches of mercury for a given percent 
    power, rpm, altitude and temperature (temperature input is optional
    - standard temperature is used if no temperature is input).

    Note: the output is rounded off to two decimal places.
    
    Examples:
    
    Determine manifold pressure required for 62.5% power at 2550 rpm 
    at 8000 ft and 10 deg C:
    >>> pp2mp(62.5, 2550, 8000, 10)
    '19.45'
    
    Determine manifold pressure required for 75% power at 2500 rpm at 
    7500 ft at 10 deg F:
    >>> pp2mp(75, 2500, 7500, 10, temp_units = 'F')
    '22.25'
    
    
    Determine manifold pressure required for 55% power at 2400 rpm at 
    9,500 ft at standard temperature:
    >>> pp2mp(55, 2400, 9500)
    '18.18'
    """
    if percent_power <= 0:
        raise ValueError('Power input must be positive.')

    # convert units
    altitude = U.length_conv(altitude, from_units=alt_units, to_units='ft')
    if temp == 'std':
        temp = SA.alt2temp(altitude, temp_units=temp_units)
    temp = U.temp_conv(temp, from_units=temp_units, to_units='C')

    pwr_seek = percent_power * 2

    mp = pwr2mp(pwr_seek, rpm, altitude, temp)

    return mp
Esempio n. 24
0
def advance_ratio(tas, rpm, dia, speed_units='kt', dia_units='in'):
    """
    Returns the propeller advance ratio, J, given the
    revolutions per minute (rpm), true airspeed (tas), temperature and
    propeller diameter.

    The advance ratio is the forward distance that the propeller advances
    during one revolution, divided by the diameter of the propeller.

    The diameter units may be specified as "in", "ft", or "m", but default
    to inches if not specified.
    """
    tas = U.speed_conv(tas, from_units=speed_units, to_units='m/s')
    dia = U.length_conv(dia, from_units=dia_units, to_units='m')

    advance_ratio = tas * 60. / (rpm * dia)

    return advance_ratio
Esempio n. 25
0
def ct2thrust(Ct,
              Rho,
              rpm,
              dia,
              thrust_units='lb',
              density_units='lb/ft**3',
              dia_units='in'):
    """
    Returns the thrust, given thrust coefficient, Ct, density, rpm and prop
    diameter.
    """
    Rho = U.density_conv(Rho, from_units=density_units, to_units='kg/m**3')
    dia = U.length_conv(dia, from_units=dia_units, to_units='m')
    # convert rpm to revolutions / s
    n = rpm / 60.
    thrust = Ct * Rho * n**2. * dia**4.

    return U.force_conv(thrust, from_units='N', to_units=thrust_units)
Esempio n. 26
0
def advance_ratio(tas, rpm, dia, speed_units="kt", dia_units="in"):
    """
    Returns the propeller advance ratio, J, given the
    revolutions per minute (rpm), true airspeed (tas), temperature and
    propeller diameter.

    The advance ratio is the forward distance that the propeller advances
    during one revolution, divided by the diameter of the propeller.

    The diameter units may be specified as "in", "ft", or "m", but default
    to inches if not specified.
    """
    tas = U.speed_conv(tas, from_units=speed_units, to_units="m/s")
    dia = U.length_conv(dia, from_units=dia_units, to_units="m")

    advance_ratio = tas * 60.0 / (rpm * dia)

    return advance_ratio
Esempio n. 27
0
def pp2rpm(percent_power,
           mp,
           altitude,
           temp='std',
           alt_units='ft',
           temp_units='C'):
    """
    Returns manifold pressure in inches of mercury for a given percent
    power, rpm, altitude and temperature (temperature input is optional -
    standard temperature is used if no temperature is input).

    Examples:

    Determine rpm required for 125 hp at 20 inches HG manifold pressure at
    8000 ft and 10 deg C:
    >>> pp2rpm(62.5, 20, 8000, 10)
    2246

    Determine rpm required for 75% power at 22 inches HG manifold pressure
    at 6500 ft and 10 deg F:
    >>> pp2rpm(75, 22, 6500, 10, temp_units = 'F')
    2345

    Determine rpm required for 55% power at at 18 inches HG manifold
    pressure at 9,500 ft at standard temperature:
    >>> pp2rpm(55, 18, 9500)
    2423
    """
    if percent_power <= 0:
        raise ValueError('Power input must be positive.')

    # convert units
    altitude = U.length_conv(altitude, from_units=alt_units, to_units='ft')
    if temp == 'std':
        temp = SA.alt2temp(altitude, temp_units=temp_units)
    temp = U.temp_conv(temp, from_units=temp_units, to_units='C')

    pwr_seek = percent_power * 1.8
    # 	print('Temp:', temp)
    print('Power seeked:', pwr_seek)
    rpm = pwr2rpm(pwr_seek, mp, altitude, temp)

    return rpm
Esempio n. 28
0
def bhp2Cp(bhp, rpm, density, dia, power_units="hp", density_units="lb/ft**3", dia_units="in"):
    """
    Returns the propeller power coefficient, Cp, given power, revolutions per 
    minute (rpm), and propeller diameter.

    The power units may be specified as "hp", "ft-lb/mn", "ft-lb/s", "W"
    (watts) or "kW" (kilowatts), but default to "hp" if not specified.

    The density units may be specified as "lb/ft**3", "slug/ft**3" or 
    "kg/m**3", but default to "lb/ft**3" if not specified.

    The diameter units may be specified as "in", "ft", or "m", but default
    to inches if not specified.
    """
    bhp = U.power_conv(bhp, from_units=power_units, to_units="W")
    density = U.density_conv(density, from_units=density_units, to_units="kg/m**3")
    dia = U.length_conv(dia, from_units=dia_units, to_units="m")

    Cp = bhp / (density * ((rpm / 60.0) ** 3) * dia ** 5)

    return Cp
Esempio n. 29
0
def pp2mp(percent_power, rpm, altitude, temp = 'std', alt_units = 'ft', temp_units = 'C'):
    """
    Returns manifold pressure in inches of mercury for a given percent 
    power, rpm, altitude and temperature (temperature input is optional
    - standard temperature is used if no temperature is input).

    Note: the output is rounded off to two decimal places.
    
    Examples:
    
    Determine manifold pressure required for 62.5% power at 2550 rpm 
    at 8000 ft and 10 deg C:
    >>> pp2mp(62.5, 2550, 8000, 10)
    '19.45'
    
    Determine manifold pressure required for 75% power at 2500 rpm at 
    7500 ft at 10 deg F:
    >>> pp2mp(75, 2500, 7500, 10, temp_units = 'F')
    '22.25'
    
    
    Determine manifold pressure required for 55% power at 2400 rpm at 
    9,500 ft at standard temperature:
    >>> pp2mp(55, 2400, 9500)
    '18.18'
    """
    if percent_power <= 0:
        raise ValueError, 'Power input must be positive.'
    
    # convert units
    altitude = U.length_conv(altitude, from_units = alt_units, to_units = 'ft')
    if temp == 'std':
        temp = SA.alt2temp(altitude, temp_units = temp_units)
    temp = U.temp_conv(temp, from_units = temp_units, to_units = 'C')

    pwr_seek = percent_power * 2
    
    mp = pwr2mp(pwr_seek, rpm, altitude, temp)
    
    return mp
Esempio n. 30
0
def Re(
    V,
    L,
    KV,
    speed_units=default_speed_units,
    length_units=default_length_units,
    #kinematic_viscosity_units=default_kinematic_viscosity_units
):
    """
    Return Reynold's number, given velocity, characteristic length and kinematic viscosity'
    
    V  = velocity
    L  = characteristic length
    KV = kinematic viscosity
    """
    V = U.speed_conv(V, speed_units, 'm/s')
    L = U.length_conv(L, length_units, 'm')
    # KV = U.kinematic_viscosity_conv(KV, kinematic_viscosity_units, '??')

    Re = V * L / KV

    return Re
Esempio n. 31
0
def pp2rpm(percent_power, mp, altitude, temp = 'std', alt_units = 'ft', temp_units = 'C'):
	"""
	Returns manifold pressure in inches of mercury for a given percent 
	power, rpm, altitude and temperature (temperature input is optional - 
	standard temperature is used if no temperature is input).
	
	Examples:
	
	Determine rpm required for 125 hp at 20 inches HG manifold pressure at 
	8000 ft and 10 deg C:
	>>> pp2rpm(62.5, 20, 8000, 10)
	2246
	
	Determine rpm required for 75% power at 22 inches HG manifold pressure 
	at 6500 ft and 10 deg F:
	>>> pp2rpm(75, 22, 6500, 10, temp_units = 'F')
	2345
	
	Determine rpm required for 55% power at at 18 inches HG manifold 
	pressure at 9,500 ft at standard temperature:
	>>> pp2rpm(55, 18, 9500)
	2423
	"""
	if percent_power <= 0:
		raise ValueError, 'Power input must be positive.'
	
	# convert units
	altitude = U.length_conv(altitude, from_units = alt_units, to_units = 'ft')
	if temp == 'std':
		temp = SA.alt2temp(altitude, temp_units = temp_units)
	temp = U.temp_conv(temp, from_units = temp_units, to_units = 'C')

	pwr_seek = percent_power * 1.8
# 	print 'Temp:', temp
	print 'Power seeked:', pwr_seek
	rpm = pwr2rpm(pwr_seek, mp, altitude, temp)
	
	return rpm
Esempio n. 32
0
def alt2press(H, alt_units=default_alt_units,
              press_units=default_press_units):
    """
    Return the atmospheric pressure for a given altitude, with the 
    altitude in feet ('ft'), metres ('m'), statute miles, ('sm') or nautical
    miles ('nm'), and the pressure in inches of HG ('in HG'), mm of HG 
    ('mm HG'), psi, lb per sq. ft ('psf'), pa, hpa or mb.  
    
    If the units are not specified, the units in default_units.py are used.
    
    Examples:
    
    Calculate the pressure in inches of mercury at 5,000 (default altitude 
    units):
    >>> alt2press(5000)
    24.895987851572702
    
    Calculate the pressure in pounds per square foot at 10,000 (default 
    altitude units):
    >>> alt2press(10000, press_units = 'psf')
    1455.331692025379
    
    Calculate the pressure in pascal at 20 km:
    >>> alt2press(20, press_units = 'pa', alt_units = 'km')
    5474.8885557436233
    """

    # uses meters, pa and degrees K for the internal calculations

    # function tested in tests/test_std_atm.py

    H = U.length_conv(H, from_units=alt_units, to_units='m')

    press = P0 * alt2press_ratio(H, alt_units='m')
    press = U.press_conv(press, from_units='pa', to_units=press_units)

    return press
Esempio n. 33
0
def tip_mach(tas, rpm, temperature, dia, speed_units="kt", temp_units="C", dia_units="in"):
    """
    Returns the mach number of the propeller blade tip, given the
    true airspeed (tas), revolutions per minute (rpm), temperature and
    propeller diameter.
    
    The speed units may be specified as "kt", "mph", "km/h" or "ft/s", but
    default to "kt" if not specified.
    
    The temperature units may be specified as "C", "F", "K" or "R", but
    default to deg C if not specified.
    
    The diameter units may be specified as "in", "ft", or "m", but default
    to inches if not specified.
    """
    dia = U.length_conv(dia, from_units=dia_units, to_units="m")
    tas = U.speed_conv(tas, from_units=speed_units, to_units="m/s")
    speed_of_sound = SA.temp2speed_of_sound(temperature, temp_units=temp_units, speed_units="m/s")

    rotation_speed = dia * rpm * M.pi / 60
    tip_speed = M.sqrt(tas ** 2 + rotation_speed ** 2)
    tip_mach = tip_speed / speed_of_sound

    return tip_mach
Esempio n. 34
0
def alt2press(H, alt_units=default_alt_units, press_units=default_press_units):
    """
    Return the atmospheric pressure for a given altitude, with the 
    altitude in feet ('ft'), metres ('m'), statute miles, ('sm') or nautical
    miles ('nm'), and the pressure in inches of HG ('in HG'), mm of HG 
    ('mm HG'), psi, lb per sq. ft ('psf'), pa, hpa or mb.  
    
    If the units are not specified, the units in default_units.py are used.
    
    Examples:
    
    Calculate the pressure in inches of mercury at 5,000 (default altitude 
    units):
    >>> alt2press(5000)
    24.895987851572702
    
    Calculate the pressure in pounds per square foot at 10,000 (default 
    altitude units):
    >>> alt2press(10000, press_units = 'psf')
    1455.331692025379
    
    Calculate the pressure in pascal at 20 km:
    >>> alt2press(20, press_units = 'pa', alt_units = 'km')
    5474.888555743623
    """

    # uses meters, pa and degrees K for the internal calculations

    # function tested in tests/test_std_atm.py

    H = U.length_conv(H, from_units=alt_units, to_units='m')

    press = P0 * alt2press_ratio(H, alt_units='m')
    press = U.press_conv(press, from_units='pa', to_units=press_units)

    return press
 def test_01(self):
     Value = U.length_conv(120, from_units='in', to_units='ft')
     Truth = 10
     self.assertTrue(RE(Value, Truth) <= 1e-5)
Esempio n. 36
0
def pwr2rpm(pwr_seek, mp, altitude, temp = 'std', alt_units = 'ft', temp_units = 'C'):
    """ 
    Returns rpm for a given power, manifold pressure in inches of mercury,
    altitude and temperature (temperature input is optional - standard 
    temperature is used if no temperature is input).

    Note: the output is rounded off to the nearest rpm.
    
    Examples:
    
    Determine rpm required for 125 hp at 20 inches HG manifold pressure at 
    8000 ft and 10 deg C:
    >>> pwr2rpm(125, 20, 8000, 10)
    2477
    
    Determine rpm required for 75% power at 22 inches HG manifold pressure 
    at 6500 ft and 10 deg F:
    >>> pwr2rpm(.75 * 200, 22, 6500, 10, temp_units = 'F')
    2547
    
    Determine rpm required for 55% power at at 18 inches HG manifold 
    pressure at 9,500 ft at standard temperature:
    >>> pwr2rpm(.55 * 200, 18, 9500)
    2423
    """
    if pwr_seek <= 0:
        raise ValueError, 'Power input must be positive.'
    
    low = 1000 # initial lower guess
    high = 3500 # initial upper guess
    
    # convert units
    altitude = U.length_conv(altitude, from_units = alt_units, to_units = 'ft')
    if temp == 'std':
        temp = SA.alt2temp(altitude, temp_units = temp_units)
    temp = U.temp_conv(temp, from_units = temp_units, to_units = 'C')
    
    # confirm initial low and high are OK:
    pwr_low = pwr(low, mp, altitude, temp)
    # print "pwr_low=", pwr_low
    if pwr_low > pwr_seek:
        raise ValueError, 'Initial low guess too high.'
    
    pwr_high = pwr(high, mp, altitude, temp)
    # print "pwr_high=", pwr_high
    if pwr_high < pwr_seek:
        # print "pwr_high=", pwr_high
        print "Function called was IO.pwr(%f, %f, %f, %f)" % (high, mp, altitude, temp)
        raise ValueError, 'Initial high guess too low.'
    
    guess = (low + high) / 2.
    pwr_guess = pwr(guess, mp, altitude, temp)
    
    # keep iterating until power is within 0.1% of desired value
    while M.fabs(pwr_guess - pwr_seek) / pwr_seek > 1e-4:
        if pwr_guess > pwr_seek:
            high = guess
        else:
            low = guess

        guess = (low + high) / 2.
        pwr_guess = pwr(guess, mp, altitude, temp)

    return int(round(guess,0))  
Esempio n. 37
0
    def __init__(self, base_name, base_path=''):
        """Returns a propeller object
        
        prop = Prop('7666-2RV')
        prop = Prop('MTV*183-59B')
        prop = Prop('MTV*402')
        """
        self.prop = base_name

        # create temp lists, to hold the data before it is read into arrays
        temp_data_storage1 = []
        temp_data_storage2 = []
        temp_data_storage3 = []

        if '7666' in base_name:
            self.manufacturer = 'Hartzell'
            self.model = base_name
            if base_path == '':
                node_name = node()
                if node_name[:9] == 'PowerBook':
                    base_path = '/Users/kwh/RV/Engine_prop/Hartzell_prop_maps/'
                elif node_name == 'Kevins-MacBook-Air.local':
                    base_path = '/Users/kwh/Documents/RV/Engine_prop/Hartzell_prop_maps/'
                elif node_name == 'Kevins-MBPr.local':
                    base_path = '/Users/kwh/Documents/RV/Engine_prop/Hartzell_prop_maps/'
                elif node_name == 'MacMini.local':
                    base_path = '/Users/kwh/Documents/Flying/RV/Engine_prop/Hartzell_prop_maps/'
                elif node_name == 'ncrnbhortonk2':
                    base_path = 'C:\\Documents and Settings\\hortonk\\My Documents\\rv\\Prop\\Hartzell_prop_maps\\'
                elif node_name == 'eeepc':
                    base_path = '/home/kwh/RV/Hartzell_prop_maps/'
                elif node_name == 'sage-BHYVE':
                    base_path = '/home/kwh/Prop_Maps/Hartzell_prop_maps/'
                elif node_name == 'sage-ubuntu-1404':
                    base_path = '/home/kwh/python/prop_maps/Hartzell_prop_maps/'
                else:
                    raise ValueError('Unknown computer')

            # confirm the path to the data files exists
            if os.path.exists(base_path):
                pass
            else:
                raise ValueError(
                    'The path specified for the prop map files does not exist')

            file_glob = base_path + base_name + '*.csv'
            file_names = glob.glob(file_glob)

            # confirm that at least one data file was found
            if len(file_names) < 1:
                raise ValueError('No prop data files were found.')

            # need names in sorted order, so the array ends up in order of mach
            # sorting seems to not be needed on OS X, as glob.glob() returns a sorted list
            # but, on Linux, the list is not sorted
            file_names.sort()

            for file_name in file_names:
                FILE = open(file_name)
                raw_data = csv.reader(FILE)

                # parse mach number
                for line in raw_data:
                    mach_search = re.search('Mach\s0\.\d+', line[0])
                    if mach_search:
                        mach_group = re.search('0\.\d+', line[0])
                        mach = mach_group.group()
                        break

                # find start of CT data
                for line in raw_data:
                    try:
                        header_search = re.search('THRUST COEFFICIENT',
                                                  line[0])
                        if header_search:
                            break

                    except IndexError:
                        pass
                # load block of CT values into temp storage
                temp_lines1 = []
                while 1:
                    value_line = next(raw_data)
                    try:
                        value_line_search = re.match('[0\.\d+,CP]',
                                                     value_line[0])
                    except IndexError:
                        # at the end of the data block - move on
                        break
                    if value_line_search:
                        # strip spurious zeros from right end of data
                        while value_line[-1] == '0':
                            value_line.pop()
                        temp_lines1.append(value_line)

                        # convert values to float
                        for i, item in enumerate(value_line):
                            try:
                                value_line[i] = float(item)
                            except ValueError:
                                value_line[i] = 0
                    else:
                        # at the end of the data block - move on
                        break

                # strip of "CP / J" from first line, and replace by mach,
                temp_lines1[0][0] = float(mach)

                # find start of blade angle data
                for line in raw_data:
                    try:
                        header_search = re.search('BLADE ANGLE', line[0])
                        if header_search:
                            break
                    except IndexError:
                        pass

                # load block of blade angle values into temp storage
                temp_lines3 = []
                while 1:
                    try:
                        value_line = next(raw_data)
                    except StopIteration:
                        break
                    try:
                        value_line_search = re.match('[0\.\d+,CP]',
                                                     value_line[0])
                    except IndexError:
                        # at the end of the data block - move on
                        break
                    if value_line_search:
                        # strip spurious zeros from right end of data
                        while value_line[-1] == '0':
                            value_line.pop()
                        temp_lines3.append(value_line)

                        # convert values to float
                        for i, item in enumerate(value_line):
                            try:
                                value_line[i] = float(item)
                            except ValueError:
                                value_line[i] = 0
                    else:
                        # at the end of the data block - move on
                        break

                # strip of "CP / J" from first line, and replace by mach,
                temp_lines3[0][0] = float(mach)

                # find start of efficiency data
                for line in raw_data:
                    try:
                        header_search = re.search('EFFICIENCY', line[0])
                        if header_search:
                            break
                    except IndexError:
                        pass

                # load block of efficiency values into temp storage
                temp_lines2 = []
                while 1:
                    try:
                        value_line = next(raw_data)
                    except StopIteration:
                        break
                    try:
                        value_line_search = re.match('[0\.\d+,CP]',
                                                     value_line[0])
                    except IndexError:
                        # at the end of the data block - move on
                        break
                    if value_line_search:
                        # strip spurious zeros from right end of data
                        while value_line[-1] == '0':
                            value_line.pop()
                        temp_lines2.append(value_line)

                        # convert values to float
                        for i, item in enumerate(value_line):
                            try:
                                value_line[i] = float(item)
                            except ValueError:
                                value_line[i] = 0
                    else:
                        # at the end of the data block - move on
                        break

                # strip of "CP / J" from first line, and replace by mach,
                temp_lines2[0][0] = float(mach)

                # determine required size for array
                # this is done once for each data file, but only the last result is used
                self.x_size = len(temp_lines1[0])
                self.y_size = len(temp_lines1)
                self.z_size = len(file_names)

                # push data blocks into temp storage
                temp_data_storage1.append(temp_lines1)
                temp_data_storage2.append(temp_lines2)
                temp_data_storage3.append(temp_lines3)

            # create array for CT data, and populate it
            self.prop_CT_map = N.zeros((self.z_size, self.y_size, self.x_size))

            # trim length of temp data to be sure it will fit in array
            for i, layer in enumerate(temp_data_storage1):
                for i, line in enumerate(layer):
                    while len(line) > self.x_size:
                        if line[-1] == 0:
                            line.pop(-1)
                        else:
                            print('Problem line =', line)
                            raise ValueError(
                                'Problem - Trying to remove real data from end of line'
                            )

            for i, item in enumerate(temp_data_storage1):
                self.prop_CT_map[i] = temp_data_storage1[i]

            # determine range of mach, advance ratio and power coefficient in the CT data
            self.Ct_mach_min = min(self.prop_CT_map[:, 0, 0])
            self.Ct_mach_max = max(self.prop_CT_map[:, 0, 0])
            self.Ct_Cp_min = min(self.prop_CT_map[0, 1:, 0])
            self.Ct_Cp_max = max(self.prop_CT_map[0, 1:, 0])
            self.Ct_J_min = min(self.prop_CT_map[0, 0, :])
            self.Ct_J_max = max(self.prop_CT_map[0, 0, :])

            # create array for blade angle data, and populate it
            self.blade_angle_map = N.zeros(
                (self.z_size, self.y_size, self.x_size))

            # trim length of temp data to be sure it will fit in array
            for i, layer in enumerate(temp_data_storage3):
                for i, line in enumerate(layer):
                    while len(line) > self.x_size:
                        if line[-1] == 0:
                            line.pop(-1)
                        else:
                            raise ValueError(
                                'Problem - Trying to remove real data from end of line'
                            )

            for i, item in enumerate(temp_data_storage1):
                self.blade_angle_map[i] = temp_data_storage3[i]

            # determine range of mach, advance ratio and power coefficient in the blade angle data
            self.blade_angle_mach_min = min(self.blade_angle_map[:, 0, 0])
            self.blade_angle_mach_max = max(self.blade_angle_map[:, 0, 0])
            self.blade_angle_Cp_min = min(self.blade_angle_map[0, 1:, 0])
            self.blade_angle_Cp_max = max(self.blade_angle_map[0, 1:, 0])
            self.blade_angle_J_min = min(self.blade_angle_map[0, 0, :])
            self.blade_angle_J_max = max(self.blade_angle_map[0, 0, :])

            # create array for efficiency data, and populate it
            self.prop_eff_map = N.zeros(
                (self.z_size, self.y_size, self.x_size))

            # trim length of temp data to be sure it will fit in array
            for i, layer in enumerate(temp_data_storage2):
                for i, line in enumerate(layer):
                    while len(line) > self.x_size:
                        if line[-1] == 0:
                            line.pop(-1)
                        else:
                            raise ValueError(
                                'Problem - Trying to remove real data from end of line'
                            )

            for i, item in enumerate(temp_data_storage1):
                self.prop_eff_map[i] = temp_data_storage2[i]

            # determine range of mach, advance ratio and power coefficient in the efficiency data
            self.eff_mach_min = min(self.prop_eff_map[:, 0, 0])
            self.eff_mach_max = max(self.prop_eff_map[:, 0, 0])
            self.eff_Cp_min = min(self.prop_eff_map[0, 1:, 0])
            self.eff_Cp_max = max(self.prop_eff_map[0, 1:, 0])
            self.eff_J_min = min(self.prop_eff_map[0, 0, :])
            self.eff_J_max = max(self.prop_eff_map[0, 0, :])

            # wipe temp storage, to be sure to start with a clean slate for the next type of data
            temp_data_storage1 = []
            temp_data_storage2 = []
            temp_data_storage3 = []

            if base_name == '7666-4RV':
                self.dia = 72
            elif base_name == '7666-2RV':
                self.dia = 74
            else:
                raise ValueError('Invalid prop')
        elif 'MTV' in base_name:
            if base_path == '':
                node_name = node()
                if node_name[:9] == 'PowerBook':
                    base_path = '/Users/kwh/Documents/RV/MT_Prop/'
                elif node_name == 'Kevins-MacBook-Air.local':
                    base_path = '/Users/kwh/Documents/RV/Engine_prop/MT_Prop/'
                elif node_name == 'Kevins-MBPr.local':
                    base_path = '/Users/kwh/Documents/RV/Engine_prop/MT_Prop/'
                elif node_name == 'MacMini.local':
                    base_path = '/Users/kwh/Documents/Flying/RV/Engine_prop/MT_Prop/'
                elif node_name == 'ncrnbhortonk2':
                    base_path = 'C:\\Documents and Settings\\hortonk\\My Documents\\rv\\Prop\\MT_Prop\\'
                elif node_name == 'eeepc':
                    base_path = '/home/kwh/RV/MT_Prop/'
                elif node_name == 'sage-BHYVE':
                    base_path = '/home/kwh/Prop_Maps/MT_Prop/'
                elif node_name == 'sage-ubuntu-1204':
                    base_path = '/home/kwh/python//prop_maps/'
                else:
                    raise ValueError('Unknown computer')

            # confirm the path to the data files exists
            if os.path.exists(base_path):
                pass
            else:
                raise ValueError(
                    'The path specified for the prop map files does not exist')
            file_glob = base_path + base_name + '*.csv'
            #            file_glob = base_path + '*' + base_name + '*.csv'

            file_names = glob.glob(file_glob)

            # confirm that at least one data file was found
            if len(file_names) < 1:
                raise ValueError('No prop data files were found.')

            for file_name in file_names:
                temp_lines = []
                FILE = open(file_name)
                raw_data = csv.reader(FILE)
                header_lines = 2
                line1 = next(raw_data)
                model_match = re.search('(\S+)\s+(\S+)\s.*', line1[0])
                self.manufacturer = model_match.group(1)
                self.model = model_match.group(2)
                self.dia = float(
                    re.search('[^-]+-[^-]+-[^-]+-(\d+).*', line1[0]).group(1))
                self.dia = U.length_conv(self.dia,
                                         from_units='cm',
                                         to_units='in')
                for n in range(header_lines - 1):
                    next(raw_data)

                #replace "J" with mach 0
                temp_lines.append(next(raw_data))
                temp_lines[0][0] = 0

                # load block of efficiency values into temp storage
                while 1:
                    try:
                        temp_lines.append(next(raw_data))
                    except StopIteration:
                        break
                for l, line in enumerate(temp_lines):
                    for i, item in enumerate(line):
                        try:
                            temp_lines[l][i] = float(item)
                        except ValueError:
                            temp_lines[l][i] = 0.

                # determine required size for array
                self.x_size = len(temp_lines[0])
                self.y_size = len(temp_lines)
                self.z_size = 2

                temp_array1 = []
                for line in temp_lines:
                    temp_array1.append(line)
                # MT eff map does not have different data for different tip mach numbers.
                # To allow using the same routines as for Hartzell props, set the original
                # data for Mach 0, and make a copy for Mach 1.
                temp_array = [temp_array1, temp_array1]
                self.prop_eff_map = N.array(temp_array)
                self.prop_eff_map[1, 0, 0] = 1

                # MT eff data has Cp running left to right, and Js running
                # vertically, which is the reverse of the Hartzell data.
                # Must swapaxes to get the same orientation for both props.
                self.prop_eff_map = self.prop_eff_map.swapaxes(1, 2)

                # determine range of mach, advance ratio and power coefficient in the efficiency data
                self.eff_mach_min = min(self.prop_eff_map[:, 0, 0])
                self.eff_mach_max = max(self.prop_eff_map[:, 0, 0])
                self.eff_Cp_min = min(self.prop_eff_map[0, :, 0])
                self.eff_Cp_max = max(self.prop_eff_map[0, :, 0])
                self.eff_J_min = min(self.prop_eff_map[0, 0, 1:])
                self.eff_J_max = max(self.prop_eff_map[0, 0, 1:])

        else:
            print('prop type not known')
Esempio n. 38
0
    def __init__(self, base_name, base_path=""):
        """Returns a propeller object
        
        prop = Prop('7666-2RV')
        prop = Prop('MTV*183-59B')
        prop = Prop('MTV*402')
        """
        self.prop = base_name

        # create temp lists, to hold the data before it is read into arrays
        temp_data_storage1 = []
        temp_data_storage2 = []
        temp_data_storage3 = []

        if "7666" in base_name:
            self.manufacturer = "Hartzell"
            self.model = base_name
            if base_path == "":
                node_name = node()
                if node_name[:9] == "PowerBook":
                    base_path = "/Users/kwh/RV/Engine_prop/Hartzell_prop_maps/"
                elif node_name == "Kevins-MacBook-Air.local":
                    base_path = "/Users/kwh/Documents/RV/Engine_prop/Hartzell_prop_maps/"
                elif node_name == "Kevins-MBPr.local":
                    base_path = "/Users/kwh/Documents/RV/Engine_prop/Hartzell_prop_maps/"
                elif node_name == "MacMini.local":
                    base_path = "/Users/kwh/Documents/Flying/RV/Engine_prop/Hartzell_prop_maps/"
                elif node_name == "ncrnbhortonk2":
                    base_path = "C:\\Documents and Settings\\hortonk\\My Documents\\rv\\Prop\\Hartzell_prop_maps\\"
                elif node_name == "eeepc":
                    base_path = "/home/kwh/RV/Hartzell_prop_maps/"
                elif node_name[:4] == "sage":
                    base_path = "/home/kwh/python/prop_maps/Hartzell_prop_maps/"
                elif node_name == "sage-ubuntu-1404":
                    base_path = "/home/kwh/python/prop_maps/Hartzell_prop_maps/"
                else:
                    raise ValueError, "Unknown computer"

            # confirm the path to the data files exists
            if os.path.exists(base_path):
                pass
            else:
                raise ValueError, "The path specified for the prop map files does not exist"

            file_glob = base_path + base_name + "*.csv"
            file_names = glob.glob(file_glob)

            # confirm that at least one data file was found
            if len(file_names) < 1:
                raise ValueError, "No prop data files were found."

            # need names in sorted order, so the array ends up in order of mach
            # sorting seems to not be needed on OS X, as glob.glob() returns a sorted list
            # but, on Linux, the list is not sorted
            file_names.sort()

            for file_name in file_names:
                FILE = open(file_name)
                raw_data = csv.reader(FILE)

                # parse mach number
                for line in raw_data:
                    mach_search = re.search("Mach\s0\.\d+", line[0])
                    if mach_search:
                        mach_group = re.search("0\.\d+", line[0])
                        mach = mach_group.group()
                        break

                # find start of CT data
                for line in raw_data:
                    try:
                        header_search = re.search("THRUST COEFFICIENT", line[0])
                        if header_search:
                            break

                    except IndexError:
                        pass
                # load block of CT values into temp storage
                temp_lines1 = []
                while 1:
                    value_line = raw_data.next()
                    try:
                        value_line_search = re.match("[0\.\d+,CP]", value_line[0])
                    except IndexError:
                        # at the end of the data block - move on
                        break
                    if value_line_search:
                        # strip spurious zeros from right end of data
                        while value_line[-1] == "0":
                            value_line.pop()
                        temp_lines1.append(value_line)

                        # convert values to float
                        for i, item in enumerate(value_line):
                            try:
                                value_line[i] = float(item)
                            except ValueError:
                                value_line[i] = 0
                    else:
                        # at the end of the data block - move on
                        break

                # strip of "CP / J" from first line, and replace by mach,
                temp_lines1[0][0] = float(mach)

                # find start of blade angle data
                for line in raw_data:
                    try:
                        header_search = re.search("BLADE ANGLE", line[0])
                        if header_search:
                            break
                    except IndexError:
                        pass

                # load block of blade angle values into temp storage
                temp_lines3 = []
                while 1:
                    try:
                        value_line = raw_data.next()
                    except StopIteration:
                        break
                    try:
                        value_line_search = re.match("[0\.\d+,CP]", value_line[0])
                    except IndexError:
                        # at the end of the data block - move on
                        break
                    if value_line_search:
                        # strip spurious zeros from right end of data
                        while value_line[-1] == "0":
                            value_line.pop()
                        temp_lines3.append(value_line)

                        # convert values to float
                        for i, item in enumerate(value_line):
                            try:
                                value_line[i] = float(item)
                            except ValueError:
                                value_line[i] = 0
                    else:
                        # at the end of the data block - move on
                        break

                # strip of "CP / J" from first line, and replace by mach,
                temp_lines3[0][0] = float(mach)

                # find start of efficiency data
                for line in raw_data:
                    try:
                        header_search = re.search("EFFICIENCY", line[0])
                        if header_search:
                            break
                    except IndexError:
                        pass

                # load block of efficiency values into temp storage
                temp_lines2 = []
                while 1:
                    try:
                        value_line = raw_data.next()
                    except StopIteration:
                        break
                    try:
                        value_line_search = re.match("[0\.\d+,CP]", value_line[0])
                    except IndexError:
                        # at the end of the data block - move on
                        break
                    if value_line_search:
                        # strip spurious zeros from right end of data
                        while value_line[-1] == "0":
                            value_line.pop()
                        temp_lines2.append(value_line)

                        # convert values to float
                        for i, item in enumerate(value_line):
                            try:
                                value_line[i] = float(item)
                            except ValueError:
                                value_line[i] = 0
                    else:
                        # at the end of the data block - move on
                        break

                # strip of "CP / J" from first line, and replace by mach,
                temp_lines2[0][0] = float(mach)

                # determine required size for array
                # this is done once for each data file, but only the last result is used
                self.x_size = len(temp_lines1[0])
                self.y_size = len(temp_lines1)
                self.z_size = len(file_names)

                # push data blocks into temp storage
                temp_data_storage1.append(temp_lines1)
                temp_data_storage2.append(temp_lines2)
                temp_data_storage3.append(temp_lines3)

            # create array for CT data, and populate it
            self.prop_CT_map = N.zeros((self.z_size, self.y_size, self.x_size))

            # trim length of temp data to be sure it will fit in array
            for i, layer in enumerate(temp_data_storage1):
                for i, line in enumerate(layer):
                    while len(line) > self.x_size:
                        if line[-1] == 0:
                            line.pop(-1)
                        else:
                            print "Problem line =", line
                            raise ValueError, "Problem - Trying to remove real data from end of line"

            for i, item in enumerate(temp_data_storage1):
                self.prop_CT_map[i] = temp_data_storage1[i]

            # determine range of mach, advance ratio and power coefficient in the CT data
            self.Ct_mach_min = min(self.prop_CT_map[:, 0, 0])
            self.Ct_mach_max = max(self.prop_CT_map[:, 0, 0])
            self.Ct_Cp_min = min(self.prop_CT_map[0, 1:, 0])
            self.Ct_Cp_max = max(self.prop_CT_map[0, 1:, 0])
            self.Ct_J_min = min(self.prop_CT_map[0, 0, :])
            self.Ct_J_max = max(self.prop_CT_map[0, 0, :])

            # create array for blade angle data, and populate it
            self.blade_angle_map = N.zeros((self.z_size, self.y_size, self.x_size))

            # trim length of temp data to be sure it will fit in array
            for i, layer in enumerate(temp_data_storage3):
                for i, line in enumerate(layer):
                    while len(line) > self.x_size:
                        if line[-1] == 0:
                            line.pop(-1)
                        else:
                            raise ValueError, "Problem - Trying to remove real data from end of line"

            for i, item in enumerate(temp_data_storage1):
                self.blade_angle_map[i] = temp_data_storage3[i]

            # determine range of mach, advance ratio and power coefficient in the blade angle data
            self.blade_angle_mach_min = min(self.blade_angle_map[:, 0, 0])
            self.blade_angle_mach_max = max(self.blade_angle_map[:, 0, 0])
            self.blade_angle_Cp_min = min(self.blade_angle_map[0, 1:, 0])
            self.blade_angle_Cp_max = max(self.blade_angle_map[0, 1:, 0])
            self.blade_angle_J_min = min(self.blade_angle_map[0, 0, :])
            self.blade_angle_J_max = max(self.blade_angle_map[0, 0, :])

            # create array for efficiency data, and populate it
            self.prop_eff_map = N.zeros((self.z_size, self.y_size, self.x_size))

            # trim length of temp data to be sure it will fit in array
            for i, layer in enumerate(temp_data_storage2):
                for i, line in enumerate(layer):
                    while len(line) > self.x_size:
                        if line[-1] == 0:
                            line.pop(-1)
                        else:
                            raise ValueError, "Problem - Trying to remove real data from end of line"

            for i, item in enumerate(temp_data_storage1):
                self.prop_eff_map[i] = temp_data_storage2[i]

            # determine range of mach, advance ratio and power coefficient in the efficiency data
            self.eff_mach_min = min(self.prop_eff_map[:, 0, 0])
            self.eff_mach_max = max(self.prop_eff_map[:, 0, 0])
            self.eff_Cp_min = min(self.prop_eff_map[0, 1:, 0])
            self.eff_Cp_max = max(self.prop_eff_map[0, 1:, 0])
            self.eff_J_min = min(self.prop_eff_map[0, 0, :])
            self.eff_J_max = max(self.prop_eff_map[0, 0, :])

            # wipe temp storage, to be sure to start with a clean slate for the next type of data
            temp_data_storage1 = []
            temp_data_storage2 = []
            temp_data_storage3 = []

            if base_name == "7666-4RV":
                self.dia = 72
            elif base_name == "7666-2RV":
                self.dia = 74
            else:
                raise ValueError, "Invalid prop"
        elif "MTV" in base_name:
            if base_path == "":
                node_name = node()
                if node_name[:9] == "PowerBook":
                    base_path = "/Users/kwh/Documents/RV/MT_Prop/"
                elif node_name == "Kevins-MacBook-Air.local":
                    base_path = "/Users/kwh/Documents/RV/Engine_prop/MT_Prop/"
                elif node_name == "Kevins-MBPr.local":
                    base_path = "/Users/kwh/Documents/RV/Engine_prop/MT_Prop/"
                elif node_name == "MacMini.local":
                    base_path = "/Users/kwh/Documents/Flying/RV/Engine_prop/MT_Prop/"
                elif node_name == "ncrnbhortonk2":
                    base_path = "C:\\Documents and Settings\\hortonk\\My Documents\\rv\\Prop\\MT_Prop\\"
                elif node_name == "eeepc":
                    base_path = "/home/kwh/RV/MT_Prop/"
                elif node_name[:4] == "sage":
                    base_path = "/home/kwh/python/prop_maps/"
                elif node_name == "sage-ubuntu-1204":
                    base_path = "/home/kwh/python//prop_maps/"
                else:
                    raise ValueError, "Unknown computer"

            # confirm the path to the data files exists
            if os.path.exists(base_path):
                pass
            else:
                raise ValueError, "The path specified for the prop map files does not exist"
            file_glob = base_path + base_name + "*.csv"
            #            file_glob = base_path + '*' + base_name + '*.csv'

            file_names = glob.glob(file_glob)

            # confirm that at least one data file was found
            if len(file_names) < 1:
                raise ValueError, "No prop data files were found."

            for file_name in file_names:
                temp_lines = []
                FILE = open(file_name)
                raw_data = csv.reader(FILE)
                header_lines = 2
                line1 = raw_data.next()
                model_match = re.search("(\S+)\s+(\S+)\s.*", line1[0])
                self.manufacturer = model_match.group(1)
                self.model = model_match.group(2)
                self.dia = float(re.search("[^-]+-[^-]+-[^-]+-(\d+).*", line1[0]).group(1))
                self.dia = U.length_conv(self.dia, from_units="cm", to_units="in")
                for n in range(header_lines - 1):
                    raw_data.next()

                # replace "J" with mach 0
                temp_lines.append(raw_data.next())
                temp_lines[0][0] = 0

                # load block of efficiency values into temp storage
                while 1:
                    try:
                        temp_lines.append(raw_data.next())
                    except StopIteration:
                        break
                for l, line in enumerate(temp_lines):
                    for i, item in enumerate(line):
                        try:
                            temp_lines[l][i] = float(item)
                        except ValueError:
                            temp_lines[l][i] = 0.0

                # determine required size for array
                self.x_size = len(temp_lines[0])
                self.y_size = len(temp_lines)
                self.z_size = 2

                temp_array1 = []
                for line in temp_lines:
                    temp_array1.append(line)
                # MT eff map does not have different data for different tip mach numbers.
                # To allow using the same routines as for Hartzell props, set the original
                # data for Mach 0, and make a copy for Mach 1.
                temp_array = [temp_array1, temp_array1]
                self.prop_eff_map = N.array(temp_array)
                self.prop_eff_map[1, 0, 0] = 1

                # MT eff data has Cp running left to right, and Js running
                # vertically, which is the reverse of the Hartzell data.
                # Must swapaxes to get the same orientation for both props.
                self.prop_eff_map = self.prop_eff_map.swapaxes(1, 2)

                # determine range of mach, advance ratio and power coefficient in the efficiency data
                self.eff_mach_min = min(self.prop_eff_map[:, 0, 0])
                self.eff_mach_max = max(self.prop_eff_map[:, 0, 0])
                self.eff_Cp_min = min(self.prop_eff_map[0, :, 0])
                self.eff_Cp_max = max(self.prop_eff_map[0, :, 0])
                self.eff_J_min = min(self.prop_eff_map[0, 0, 1:])
                self.eff_J_max = max(self.prop_eff_map[0, 0, 1:])

        else:
            print "prop type not known"
 def test_06(self):
     Value = U.length_conv(0.86897624, from_units='nm', to_units='sm')
     Truth = 1
     self.assertTrue(RE(Value, Truth) <= 1e-5)
Esempio n. 40
0
def pwr2mp(pwr_seek,
           rpm,
           altitude,
           temp='std',
           alt_units='ft',
           temp_units='C'):
    """ 
    Returns manifold pressure in inches of mercury for a given power, rpm,
    altitude and temperature (temperature input is optional - standard 
    temperature is used if no temperature is input).
    
    Note: the output is rounded off to two decimal places.
    
    Examples:
    
    Determine manifold pressure required for 125 hp at 2550 rpm at 8000 ft 
    and 10 deg C:
    >>> pwr2mp(125, 2550, 8000, 10)
    '19.45'
    
    Determine manifold pressure required for 75% power at 2500 rpm at 
    7500 ft at 10 deg F:
    >>> pwr2mp(.75 * 200, 2500, 7500, 10, temp_units = 'F')
    '22.25'
    
    
    Determine manifold pressure required for 55% power at 2400 rpm at 
    9,500 ft at standard temperature:
    >>> pwr2mp(.55 * 200, 2400, 9500)
    '18.18'
    """
    if pwr_seek <= 0:
        raise ValueError('Power input must be positive.')

    low = 0  # initial lower guess
    high = 35  # initial upper guess

    # convert units
    altitude = U.length_conv(altitude, from_units=alt_units, to_units='ft')
    if temp == 'std':
        temp = SA.alt2temp(altitude, temp_units=temp_units)
    temp = U.temp_conv(temp, from_units=temp_units, to_units='C')

    # confirm initial low and high are OK:
    pwr_low = pwr(rpm, low, altitude, temp)
    if pwr_low > pwr_seek:
        raise ValueError('Initial low guess too high.')

    pwr_high = pwr(rpm, high, altitude, temp)
    if pwr_high < pwr_seek:
        raise ValueError('Initial high guess too low.')

    guess = (low + high) / 2.
    pwr_guess = pwr(rpm, guess, altitude, temp)

    # keep iterating until power is within 0.1% of desired value
    while M.fabs(pwr_guess - pwr_seek) / pwr_seek > 1e-3:
        if pwr_guess > pwr_seek:
            high = guess
        else:
            low = guess

        guess = (low + high) / 2.
        pwr_guess = pwr(rpm, guess, altitude, temp)


#   result = int(guess) + round(guess % 1, 2))
#   return guess
#   return result
    return '%.2f' % (guess)
 def test_06(self):
     Value = U.length_conv(0.86897624, from_units='nm', to_units='sm')
     Truth = 1
     self.failUnless(RE(Value, Truth) <= 1e-5)
Esempio n. 42
0
def pwr2mp(pwr_seek, rpm, altitude, temp = 'std', alt_units = 'ft', temp_units = 'C'):
    """ 
    Returns manifold pressure in inches of mercury for a given power, rpm,
    altitude and temperature (temperature input is optional - standard 
    temperature is used if no temperature is input).
    
    Note: the output is rounded off to two decimal places.
    
    Examples:
    
    Determine manifold pressure required for 125 hp at 2550 rpm at 8000 ft 
    and 10 deg C:
    >>> pwr2mp(125, 2550, 8000, 10)
    '19.45'
    
    Determine manifold pressure required for 75% power at 2500 rpm at 
    7500 ft at 10 deg F:
    >>> pwr2mp(.75 * 200, 2500, 7500, 10, temp_units = 'F')
    '22.25'
    
    
    Determine manifold pressure required for 55% power at 2400 rpm at 
    9,500 ft at standard temperature:
    >>> pwr2mp(.55 * 200, 2400, 9500)
    '18.18'
    """
    if pwr_seek <= 0:
        raise ValueError, 'Power input must be positive.'
    
    low = 0 # initial lower guess
    high = 35 # initial upper guess
    
    # convert units
    altitude = U.length_conv(altitude, from_units = alt_units, to_units = 'ft')
    if temp == 'std':
        temp = SA.alt2temp(altitude, temp_units = temp_units)
    temp = U.temp_conv(temp, from_units = temp_units, to_units = 'C')
    
    # confirm initial low and high are OK:
    pwr_low = pwr(rpm, low, altitude, temp)
    if pwr_low > pwr_seek:
        raise ValueError, 'Initial low guess too high.'
    
    pwr_high = pwr(rpm, high, altitude, temp)
    if pwr_high < pwr_seek:
        raise ValueError, 'Initial high guess too low.'
    
    guess = (low + high) / 2.
    pwr_guess = pwr(rpm, guess, altitude, temp)
    
    # keep iterating until power is within 0.1% of desired value
    while M.fabs(pwr_guess - pwr_seek) / pwr_seek > 1e-3:
        if pwr_guess > pwr_seek:
            high = guess
        else:
            low = guess

        guess = (low + high) / 2.
        pwr_guess = pwr(rpm, guess, altitude, temp)

#   result = int(guess) + round(guess % 1, 2))
#   return guess
#   return result
    return '%.2f' % (guess)
Esempio n. 43
0
def pwr2rpm(pwr_seek,
            mp,
            altitude,
            temp='std',
            alt_units='ft',
            temp_units='C'):
    """ 
    Returns rpm for a given power, manifold pressure in inches of mercury,
    altitude and temperature (temperature input is optional - standard 
    temperature is used if no temperature is input).

    Note: the output is rounded off to the nearest rpm.
    
    Examples:
    
    Determine rpm required for 125 hp at 20 inches HG manifold pressure at 
    8000 ft and 10 deg C:
    >>> pwr2rpm(125, 20, 8000, 10)
    2477
    
    Determine rpm required for 75% power at 22 inches HG manifold pressure 
    at 6500 ft and 10 deg F:
    >>> pwr2rpm(.75 * 200, 22, 6500, 10, temp_units = 'F')
    2547
    
    Determine rpm required for 55% power at at 18 inches HG manifold 
    pressure at 9,500 ft at standard temperature:
    >>> pwr2rpm(.55 * 200, 18, 9500)
    2423
    """
    if pwr_seek <= 0:
        raise ValueError('Power input must be positive.')

    low = 1000  # initial lower guess
    high = 3500  # initial upper guess

    # convert units
    altitude = U.length_conv(altitude, from_units=alt_units, to_units='ft')
    if temp == 'std':
        temp = SA.alt2temp(altitude, temp_units=temp_units)
    temp = U.temp_conv(temp, from_units=temp_units, to_units='C')

    # confirm initial low and high are OK:
    pwr_low = pwr(low, mp, altitude, temp)
    # print "pwr_low=", pwr_low
    if pwr_low > pwr_seek:
        raise ValueError('Initial low guess too high.')

    pwr_high = pwr(high, mp, altitude, temp)
    # print "pwr_high=", pwr_high
    if pwr_high < pwr_seek:
        # print "pwr_high=", pwr_high
        print("Function called was IO.pwr(%f, %f, %f, %f)" %
              (high, mp, altitude, temp))
        raise ValueError('Initial high guess too low.')

    guess = (low + high) / 2.
    pwr_guess = pwr(guess, mp, altitude, temp)

    # keep iterating until power is within 0.1% of desired value
    while M.fabs(pwr_guess - pwr_seek) / pwr_seek > 1e-4:
        if pwr_guess > pwr_seek:
            high = guess
        else:
            low = guess

        guess = (low + high) / 2.
        pwr_guess = pwr(guess, mp, altitude, temp)

    return int(round(guess, 0))
Esempio n. 44
0
def tas2ssec2(tas, ind_alt, oat, ias, std_alt = 0, speed_units=default_speed_units, alt_units=default_alt_units, temp_units=default_temp_units, press_units = default_press_units):
    """
    Return static source position error as speed error, pressure error and 
    altitude error at sea level using speed course method.
    
    Returns delta_Vpc, delta_Ps and delta_Hpc
    
    tas = true airspeed determined by speed course method, or GPS
    
    ind_alt = pressure altitude, corrected for instrument error
    
    oat = outside air temperature, corrected for instrument error and ram temperature rise
    
    ias = indicated airspeed, corrected for instrument error
    
    std_alt = altitude to provide delta_Hpc for
    
    delta_Vpc = error in airspeed = calibrated airspeed - indicated airspeed 
    corrected for instrument error
    
    delta_Ps = error in the pressure sensed by the static system = pressure 
    sensed in the static system - ambient pressure
    
    delta_Hpc = altitude error at std_alt = actual altitude - altitude 
    sensed by the static system
    
    Uses analysis method from USAF Test Pilot School.  Unlike some other 
    methods (e.g.. that in FAA AC 23-8B, or NTPS GPS_PEC.xls), this method 
    provides an exact conversion from TAS to CAS (some other methods assume 
    CAS = EAS), and it accounts for the effect of position error of altitude 
    on the conversion from TAS to CAS (some  other methods assume pressure 
    altitude =  indicated pressure altitude).
    """
    tas = U.speed_conv(tas, speed_units, 'kt')
    ind_alt = U.length_conv(ind_alt, alt_units, 'ft')
    oat = U.temp_conv(oat, temp_units, 'C')
    M = A.tas2mach(tas, oat, temp_units='C', speed_units='kt')
    if M > 1:
        raise ValueError, 'This method only works for Mach < 1'
    delta_ic = SA.alt2press_ratio(ind_alt, alt_units='ft')
    qcic_over_Psl = A.cas2dp(ias, speed_units='kt', press_units=press_units) / U.press_conv(constants.P0, 'pa', to_units=press_units)
    qcic_over_Ps = qcic_over_Psl / delta_ic
    Mic = A.dp_over_p2mach(qcic_over_Ps)
    delta_mach_pc = M - Mic
    if Mic > 1:
        raise ValueError, 'This method only works for Mach < 1'
    deltaPp_over_Ps = (1.4 * delta_mach_pc * (Mic + delta_mach_pc / 2)) / (1 + 0.2 * (Mic + delta_mach_pc / 2 )**2)
    deltaPp_over_qcic = deltaPp_over_Ps / qcic_over_Ps
    delta_Hpc = SA.alt2temp_ratio(std_alt, alt_units='ft') * deltaPp_over_Ps / 3.61382e-5
    
    # experimental - alternate way to calculate delta_Hpc that gives same answer
    Ps = SA.alt2press(ind_alt, alt_units='ft', press_units=press_units)
    delta_Ps = deltaPp_over_Ps * Ps
    P_std = SA.alt2press(std_alt, alt_units='ft', press_units=press_units)
    deltaPs_std = deltaPp_over_Ps * P_std
    delta_Hpc2 = SA.press2alt(P_std  - deltaPs_std, press_units  = press_units) - std_alt

    delta_std_alt = SA.alt2press_ratio(std_alt, alt_units='ft')
    asl = U.speed_conv(constants.A0, 'm/s', 'kt')
    delta_Vpc_std_alt = deltaPp_over_Ps * delta_std_alt * asl**2 / (1.4 * ias * (1 + 0.2 * (ias / asl)**2)**2.5)

    actual_alt = SA.press2alt(Ps + delta_Ps, press_units = press_units, alt_units = 'ft')
    cas = A.tas2cas(tas, actual_alt, oat, speed_units='kt', alt_units='ft', temp_units='C')
    return delta_Vpc, delta_Ps, delta_Hpc, cas
 def test_04(self):
     Value = U.length_conv(10, from_units='km', to_units='m')
     Truth = 10000
     self.failUnless(RE(Value, Truth) <= 1e-5)
 def test_04(self):
     Value = U.length_conv(10, from_units='km', to_units='m')
     Truth = 10000
     self.assertTrue(RE(Value, Truth) <= 1e-5)
 def test_01(self):
     Value = U.length_conv(120, from_units='in', to_units='ft')
     Truth = 10
     self.failUnless(RE(Value, Truth) <= 1e-5)
Esempio n. 48
0
def tas2ssec2(tas,
              ind_alt,
              oat,
              ias,
              std_alt=0,
              speed_units=default_speed_units,
              alt_units=default_alt_units,
              temp_units=default_temp_units,
              press_units=default_press_units):
    """
    Return static source position error as speed error, pressure error and 
    altitude error at sea level using speed course method.
    
    Returns delta_Vpc, delta_Ps and delta_Hpc
    
    tas = true airspeed determined by speed course method, or GPS
    
    ind_alt = pressure altitude, corrected for instrument error
    
    oat = outside air temperature, corrected for instrument error and ram temperature rise
    
    ias = indicated airspeed, corrected for instrument error
    
    std_alt = altitude to provide delta_Hpc for
    
    delta_Vpc = error in airspeed = calibrated airspeed - indicated airspeed 
    corrected for instrument error
    
    delta_Ps = error in the pressure sensed by the static system = pressure 
    sensed in the static system - ambient pressure
    
    delta_Hpc = altitude error at std_alt = actual altitude - altitude 
    sensed by the static system
    
    Uses analysis method from USAF Test Pilot School.  Unlike some other 
    methods (e.g.. that in FAA AC 23-8B, or NTPS GPS_PEC.xls), this method 
    provides an exact conversion from TAS to CAS (some other methods assume 
    CAS = EAS), and it accounts for the effect of position error of altitude 
    on the conversion from TAS to CAS (some  other methods assume pressure 
    altitude =  indicated pressure altitude).
    """
    tas = U.speed_conv(tas, speed_units, 'kt')
    ind_alt = U.length_conv(ind_alt, alt_units, 'ft')
    oat = U.temp_conv(oat, temp_units, 'C')
    M = A.tas2mach(tas, oat, temp_units='C', speed_units='kt')
    if M > 1:
        raise ValueError('This method only works for Mach < 1')
    delta_ic = SA.alt2press_ratio(ind_alt, alt_units='ft')
    qcic_over_Psl = A.cas2dp(ias, speed_units='kt',
                             press_units=press_units) / U.press_conv(
                                 constants.P0, 'pa', to_units=press_units)
    qcic_over_Ps = qcic_over_Psl / delta_ic
    Mic = A.dp_over_p2mach(qcic_over_Ps)
    delta_mach_pc = M - Mic
    if Mic > 1:
        raise ValueError('This method only works for Mach < 1')
    deltaPp_over_Ps = (1.4 * delta_mach_pc * (Mic + delta_mach_pc / 2)) / (
        1 + 0.2 * (Mic + delta_mach_pc / 2)**2)
    deltaPp_over_qcic = deltaPp_over_Ps / qcic_over_Ps
    delta_Hpc = SA.alt2temp_ratio(
        std_alt, alt_units='ft') * deltaPp_over_Ps / 3.61382e-5

    # experimental - alternate way to calculate delta_Hpc that gives same answer
    Ps = SA.alt2press(ind_alt, alt_units='ft', press_units=press_units)
    delta_Ps = deltaPp_over_Ps * Ps
    P_std = SA.alt2press(std_alt, alt_units='ft', press_units=press_units)
    deltaPs_std = deltaPp_over_Ps * P_std
    delta_Hpc2 = SA.press2alt(P_std - deltaPs_std,
                              press_units=press_units) - std_alt

    delta_std_alt = SA.alt2press_ratio(std_alt, alt_units='ft')
    asl = U.speed_conv(constants.A0, 'm/s', 'kt')
    delta_Vpc_std_alt = deltaPp_over_Ps * delta_std_alt * asl**2 / (
        1.4 * ias * (1 + 0.2 * (ias / asl)**2)**2.5)

    actual_alt = SA.press2alt(Ps + delta_Ps,
                              press_units=press_units,
                              alt_units='ft')
    cas = A.tas2cas(tas,
                    actual_alt,
                    oat,
                    speed_units='kt',
                    alt_units='ft',
                    temp_units='C')
    return delta_Vpc, delta_Ps, delta_Hpc, cas