def test_03(self): # Truth values from NASA RP 1046 Value = SA.alt2press_ratio(20000, alt_units='m') Truth = 5474.87 / 101325 self.assertTrue(RE(Value, Truth) <= 1e-5)
def blade_angle( prop, bhp, rpm, tas, altitude, temp="std", power_units="hp", alt_units="ft", temp_units="C", speed_units="kt", dia_units="in", ): """ Returns propeller blade angle. """ press_ratio = SA.alt2press_ratio(altitude, alt_units=alt_units) if temp == "std": temp = SA.alt2temp(altitude, temp_units=temp_units, alt_units=alt_units) temp_ratio = U.temp_conv(temp, from_units=temp_units, to_units="K") / 288.15 density_ratio = press_ratio / temp_ratio density = density_ratio * SA.Rho0 Cp = bhp2Cp(bhp, rpm, density, prop.dia, power_units=power_units, density_units="kg/m**3", dia_units=dia_units) J = advance_ratio(tas, rpm, prop.dia, speed_units=speed_units, dia_units=dia_units) blade_tip_mach = tip_mach( tas, rpm, temp, prop.dia, speed_units=speed_units, temp_units=temp_units, dia_units=dia_units ) blade_angle = cp2blade_angle(prop, Cp, J, blade_tip_mach) return blade_angle
def test_02(self): # Truth values from NASA RP 1046 Value = SA.alt2press_ratio(-1000) Truth = 2193.82 / 2116.22 self.assertTrue(RE(Value, Truth) <= 1e-5)
def blade_angle2bhp( prop, blade_angle, rpm, tas, altitude, temp="std", power_units="hp", alt_units="ft", temp_units="C", speed_units="kt", dia_units="in", ): """ Returns returns engine power, given blade angle, rpm and flight conditions. """ press_ratio = SA.alt2press_ratio(altitude, alt_units=alt_units) if temp == "std": temp = SA.alt2temp(altitude, temp_units=temp_units, alt_units=alt_units) temp_ratio = U.temp_conv(temp, from_units=temp_units, to_units="K") / 288.15 density_ratio = press_ratio / temp_ratio density = density_ratio * SA.Rho0 # Cp = bhp2Cp(bhp, rpm, density, prop.dia, power_units = power_units, density_units = 'kg/m**3', dia_units = dia_units) J = advance_ratio(tas, rpm, prop.dia, speed_units=speed_units, dia_units=dia_units) blade_tip_mach = tip_mach( tas, rpm, temp, prop.dia, speed_units=speed_units, temp_units=temp_units, dia_units=dia_units ) Cp = blade_angle2cp(prop, blade_angle, J, blade_tip_mach) bhp = cp2bhp(Cp, rpm, density, prop.dia, power_units=power_units, density_units="kg/m**3", dia_units=dia_units) return bhp
def prop_eff( prop, bhp, rpm, tas, altitude, temp="std", power_units="hp", alt_units="ft", temp_units="C", speed_units="kt", dia_units="in", ): """ Returns propeller efficiency based on engine power provided to the propeller. """ press_ratio = SA.alt2press_ratio(altitude, alt_units=alt_units) if temp == "std": temp = SA.alt2temp(altitude, temp_units=temp_units, alt_units=alt_units) temp_ratio = U.temp_conv(temp, from_units=temp_units, to_units="K") / 288.15 density_ratio = press_ratio / temp_ratio density = density_ratio * SA.Rho0 Cp = bhp2Cp(bhp, rpm, density, prop.dia, power_units=power_units, density_units="kg/m**3", dia_units=dia_units) J = advance_ratio(tas, rpm, prop.dia, speed_units=speed_units, dia_units=dia_units) blade_tip_mach = tip_mach( tas, rpm, temp, prop.dia, speed_units=speed_units, temp_units=temp_units, dia_units=dia_units ) prop_eff = cp2eff(prop, Cp, J, blade_tip_mach) if N.isnan(prop_eff): raise ValueError, "Out of range inputs" return prop_eff
def test_03(self): # Truth values from NASA RP 1046 Value = SA.alt2press_ratio(20000, alt_units='m') Truth = 5474.87 / 101325 self.failUnless(RE(Value, Truth) <= 1e-5)
def test_02(self): # Truth values from NASA RP 1046 Value = SA.alt2press_ratio(-1000) Truth = 2193.82 / 2116.22 self.failUnless(RE(Value, Truth) <= 1e-5)
def prop_eff(prop, bhp, rpm, tas, altitude, temp='std', power_units='hp', alt_units='ft', temp_units='C', speed_units='kt', dia_units='in'): """ Returns propeller efficiency based on engine power provided to the propeller. """ press_ratio = SA.alt2press_ratio(altitude, alt_units=alt_units) if temp == 'std': temp = SA.alt2temp(altitude, temp_units=temp_units, alt_units=alt_units) temp_ratio = U.temp_conv(temp, from_units=temp_units, to_units='K') / 288.15 density_ratio = press_ratio / temp_ratio density = density_ratio * SA.Rho0 Cp = bhp2Cp(bhp, rpm, density, prop.dia, power_units=power_units, density_units='kg/m**3', dia_units=dia_units) J = advance_ratio(tas, rpm, prop.dia, speed_units=speed_units, dia_units=dia_units) blade_tip_mach = tip_mach(tas, rpm, temp, prop.dia, speed_units=speed_units, temp_units=temp_units, dia_units=dia_units) prop_eff = cp2eff(prop, Cp, J, blade_tip_mach) if N.isnan(prop_eff): raise ValueError('Out of range inputs') return prop_eff
def blade_angle2bhp(prop, blade_angle, rpm, tas, altitude, temp='std', power_units='hp', alt_units='ft', temp_units='C', speed_units='kt', dia_units='in'): """ Returns returns engine power, given blade angle, rpm and flight conditions. """ press_ratio = SA.alt2press_ratio(altitude, alt_units=alt_units) if temp == 'std': temp = SA.alt2temp(altitude, temp_units=temp_units, alt_units=alt_units) temp_ratio = U.temp_conv(temp, from_units=temp_units, to_units='K') / 288.15 density_ratio = press_ratio / temp_ratio density = density_ratio * SA.Rho0 # Cp = bhp2Cp(bhp, rpm, density, prop.dia, power_units = power_units, density_units = 'kg/m**3', dia_units = dia_units) J = advance_ratio(tas, rpm, prop.dia, speed_units=speed_units, dia_units=dia_units) blade_tip_mach = tip_mach(tas, rpm, temp, prop.dia, speed_units=speed_units, temp_units=temp_units, dia_units=dia_units) Cp = blade_angle2cp(prop, blade_angle, J, blade_tip_mach) bhp = cp2bhp(Cp, rpm, density, prop.dia, power_units=power_units, density_units='kg/m**3', dia_units=dia_units) return bhp
def blade_angle(prop, bhp, rpm, tas, altitude, temp='std', power_units='hp', alt_units='ft', temp_units='C', speed_units='kt', dia_units='in'): """ Returns propeller blade angle. """ press_ratio = SA.alt2press_ratio(altitude, alt_units=alt_units) if temp == 'std': temp = SA.alt2temp(altitude, temp_units=temp_units, alt_units=alt_units) temp_ratio = U.temp_conv(temp, from_units=temp_units, to_units='K') / 288.15 density_ratio = press_ratio / temp_ratio density = density_ratio * SA.Rho0 Cp = bhp2Cp(bhp, rpm, density, prop.dia, power_units=power_units, density_units='kg/m**3', dia_units=dia_units) J = advance_ratio(tas, rpm, prop.dia, speed_units=speed_units, dia_units=dia_units) blade_tip_mach = tip_mach(tas, rpm, temp, prop.dia, speed_units=speed_units, temp_units=temp_units, dia_units=dia_units) blade_angle = cp2blade_angle(prop, Cp, J, blade_tip_mach) return blade_angle
def test_01(self): PR = SA.alt2press_ratio(0) self.assertEqual(PR, 1)
def prop_data( prop, bhp, rpm, tas, altitude, temp="std", power_units="hp", alt_units="ft", temp_units="C", speed_units="kt", dia_units="in", thrust_units="lb", ): """ Returns advance ratio, power coefficient, thrust coefficient, blade tip mach number, propeller efficiency and thrust. Validated against Excel spreadsheet provided by Les Doud (Hartzell). """ press_ratio = SA.alt2press_ratio(altitude, alt_units=alt_units) if temp == "std": temp = SA.alt2temp(altitude, temp_units=temp_units, alt_units=alt_units) temp_ratio = U.temp_conv(temp, from_units=temp_units, to_units="K") / 288.15 density_ratio = press_ratio / temp_ratio density = density_ratio * SA.Rho0 Cp = bhp2Cp(bhp, rpm, density, prop.dia, power_units=power_units, density_units="kg/m**3", dia_units=dia_units) J = advance_ratio(tas, rpm, prop.dia, speed_units=speed_units, dia_units=dia_units) blade_tip_mach = tip_mach( tas, rpm, temp, prop.dia, speed_units=speed_units, temp_units=temp_units, dia_units=dia_units ) prop_eff = cp2eff(prop, Cp, J, blade_tip_mach) try: Ct = cp2ct(prop, Cp, J, blade_tip_mach) except: Ct = cp2ct_alt( prop, Cp, bhp, rpm, tas, altitude, temp=temp, power_units=power_units, alt_units=alt_units, temp_units=temp_units, speed_units=speed_units, ) if prop_eff > 0.1: thrust = eff2thrust( prop_eff, bhp, tas, power_units=power_units, speed_units=speed_units, thrust_units=thrust_units ) else: thrust = ct2thrust( Ct, density, rpm, prop.dia, thrust_units=thrust_units, density_units="kg/m**3", dia_units=dia_units ) # data_block = 'J = ' + str(J) + '\nCp = ' + str(Cp) + '\n Tip mach = ' + str(blade_tip_mach) + '\n Ct = ' + str(Ct) + '\n Thrust = ' + str(thrust) + ' ' + thrust_units + '\n Prop efficiency = ' + str(prop_eff) print " prop = ", prop.prop print " J = %.3f" % J print " Cp = %.5f" % Cp print " Tip Mach = %.3f" % blade_tip_mach print " Ct = %.3f" % Ct print " Thrust = %.2f" % thrust, thrust_units print "Prop efficiency = %.4f" % prop_eff print " Thrust HP = %.2f" % bhp * prop_eff return
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 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 prop_data(prop, bhp, rpm, tas, altitude, temp='std', power_units='hp', alt_units='ft', temp_units='C', speed_units='kt', dia_units='in', thrust_units='lb'): """ Returns advance ratio, power coefficient, thrust coefficient, blade tip mach number, propeller efficiency and thrust. Validated against Excel spreadsheet provided by Les Doud (Hartzell). """ press_ratio = SA.alt2press_ratio(altitude, alt_units=alt_units) if temp == 'std': temp = SA.alt2temp(altitude, temp_units=temp_units, alt_units=alt_units) temp_ratio = U.temp_conv(temp, from_units=temp_units, to_units='K') / 288.15 density_ratio = press_ratio / temp_ratio density = density_ratio * SA.Rho0 Cp = bhp2Cp(bhp, rpm, density, prop.dia, power_units=power_units, density_units='kg/m**3', dia_units=dia_units) J = advance_ratio(tas, rpm, prop.dia, speed_units=speed_units, dia_units=dia_units) blade_tip_mach = tip_mach(tas, rpm, temp, prop.dia, speed_units=speed_units, temp_units=temp_units, dia_units=dia_units) prop_eff = cp2eff(prop, Cp, J, blade_tip_mach) try: Ct = cp2ct(prop, Cp, J, blade_tip_mach) except: Ct = cp2ct_alt(prop, Cp, bhp, rpm, tas, altitude, temp=temp, power_units=power_units, alt_units=alt_units, temp_units=temp_units, speed_units=speed_units) if prop_eff > 0.1: thrust = eff2thrust(prop_eff, bhp, tas, power_units=power_units, speed_units=speed_units, thrust_units=thrust_units) else: thrust = ct2thrust(Ct, density, rpm, prop.dia, thrust_units=thrust_units, density_units='kg/m**3', dia_units=dia_units) # data_block = 'J = ' + str(J) + '\nCp = ' + str(Cp) + '\n Tip mach = ' + str(blade_tip_mach) + '\n Ct = ' + str(Ct) + '\n Thrust = ' + str(thrust) + ' ' + thrust_units + '\n Prop efficiency = ' + str(prop_eff) print(' prop = ', prop.prop) print(' J = %.3f' % J) print(' Cp = %.5f' % Cp) print(' Tip Mach = %.3f' % blade_tip_mach) print(' Ct = %.3f' % Ct) print(' Thrust = %.2f' % thrust, thrust_units) print('Prop efficiency = %.4f' % prop_eff) print(' Thrust HP = %.2f' % bhp * prop_eff) return