def tas2ssec(tas, alt, oat, ias, 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. Returns delta_Vpc, delta_Ps, delta_Hpc and Vc 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 sea level = actual altitude - altitude sensed by the static system Vc = calibrated airspeed at the test point """ P0 = U.press_conv(constants.P0, from_units = 'pa', to_units = press_units) cas = A.tas2cas(tas, alt, oat, speed_units=speed_units, alt_units=alt_units, temp_units=temp_units) delta_Vpc = cas - ias qcic = A.cas2dp(ias, speed_units=speed_units, press_units =press_units) qc = A.cas2dp(cas, speed_units=speed_units, press_units = press_units) delta_Ps = qc - qcic delta_Hpc = SA.press2alt(P0 - delta_Ps, press_units = press_units) # print 'Vc = %.1f, delta_vpc = %.1f, delta_ps = %.1f, delta_hpc = %.0f' % (cas, delta_Vpc, delta_Ps, delta_Hpc) return delta_Vpc, delta_Ps, delta_Hpc, cas
def WOT_speed(altitude, weight = 2100, rpm = 2700, temp = 'std', \ temp_units = 'C', rv = 'F1', wing_area = 102, speed_units = 'kt', \ prop_eff = 0.78, MP_loss = 1.322, ram = 0.5, rated_power=275): """ Returns the predicted speed at full throttle. The MP_loss is the MP lost in the induction tract at full throttle at 2700 rpm at MSL. The default value is from the Lycoming power charts. The ram is the percentage of available ram recovery pressure that is achieved in the MP. """ press = SA.alt2press(altitude, press_units='in HG') MP_loss = MP_loss * (rpm / 2700.)**2 cas_guess = 300 error = 1 while error > 0.0001: dp = A.cas2dp(cas_guess, press_units='in HG') # print 'dp =', dp ram_press = ram * dp # print 'Ram rise =', ram_press MP = press - MP_loss + ram_press pwr = O.pwr(rpm, MP, altitude, temp=temp, temp_units=temp_units) * rated_power / 180 print('MP =', MP, 'Power =', pwr) tas = speed(altitude, weight, pwr, rpm, temp = temp, \ temp_units = temp_units, rv = rv, wing_area = wing_area, \ speed_units = speed_units, prop_eff = prop_eff) cas = A.tas2cas(tas, altitude, temp=temp, temp_units=temp_units) error = M.fabs((cas - cas_guess) / cas) cas_guess = cas # print 'CAS =', cas, 'TAS =', tas return tas
def WOT_speed(altitude, weight = 2100, rpm = 2700, temp = 'std', \ temp_units = 'C', rv = 'F1', wing_area = 102, speed_units = 'kt', \ prop_eff = 0.78, MP_loss = 1.322, ram = 0.5, rated_power=275): """ Returns the predicted speed at full throttle. The MP_loss is the MP lost in the induction tract at full throttle at 2700 rpm at MSL. The default value is from the Lycoming power charts. The ram is the percentage of available ram recovery pressure that is achieved in the MP. """ press = SA.alt2press(altitude, press_units = 'in HG') MP_loss = MP_loss * (rpm / 2700.) ** 2 cas_guess = 300 error = 1 while error > 0.0001: dp = A.cas2dp(cas_guess, press_units = 'in HG') # print 'dp =', dp ram_press = ram * dp # print 'Ram rise =', ram_press MP = press - MP_loss + ram_press pwr = O.pwr(rpm, MP, altitude, temp = temp, temp_units = temp_units) * rated_power/180 print 'MP =', MP, 'Power =', pwr tas = speed(altitude, weight, pwr, rpm, temp = temp, \ temp_units = temp_units, rv = rv, wing_area = wing_area, \ speed_units = speed_units, prop_eff = prop_eff) cas = A.tas2cas(tas, altitude, temp = temp, temp_units = temp_units) error = M.fabs((cas - cas_guess) / cas) cas_guess = cas # print 'CAS =', cas, 'TAS =', tas return tas
def test_16(self): # 1000 kt to pa # truth value from NASA RP 1046 Value = A.cas2dp(1000, press_units='pa') Truth = 249053 self.failUnless(RE(Value, Truth) <= 2e-5)
def test_15(self): # 1000 kt to mm HG # truth value from NASA RP 1046 Value = A.cas2dp(1000, press_units='mm HG') Truth = 1868.05 self.failUnless(RE(Value, Truth) <= 2e-5)
def test_14(self): # 1700 km/h to pa # truth value from NASA RP 1046 Value = A.cas2dp(1700, press_units='pa', speed_units='km/h') Truth = 203298 self.failUnless(RE(Value, Truth) <= 2e-5)
def test_13(self): # 1700 km/h to mm HG # truth value from NASA RP 1046 Value = A.cas2dp(1700, press_units='mm HG', speed_units='km/h') Truth = 1524.86 self.failUnless(RE(Value, Truth) <= 2e-5)
def test_12(self): # 1000 kt to psf # truth value from NASA RP 1046 Value = A.cas2dp(1000, press_units='psf') Truth = 5201.59 self.failUnless(RE(Value, Truth) <= 2e-5)
def test_05(self): # 300 km/h to mm HG # truth value from NASA RP 1046 Value = A.cas2dp(300, press_units='mm HG', speed_units='km/h') Truth = 32.385 self.failUnless(RE(Value, Truth) <= 1e-5)
def test_03(self): # 300 mph to in HG # truth value from NASA RP 1046 Value = A.cas2dp(300, press_units='in HG', speed_units='mph') Truth = 3.38145 self.failUnless(RE(Value, Truth) <= 1e-5)
def test_09(self): # 1000 mph to in HG # truth value from NASA RP 1046 Value = A.cas2dp(1000, press_units='in HG', speed_units='mph') Truth = 52.5970 self.failUnless(RE(Value, Truth) <= 2e-5)
def test_08(self): # 244 kt to pa # truth value from NASA RP 1046 Value = A.cas2dp(244, press_units='pa') Truth = 9983.7 self.failUnless(RE(Value, Truth) <= 2e-5)
def test_07(self): # 280 kt to mm HG # truth value from NASA RP 1046 Value = A.cas2dp(280, press_units='mm HG') Truth = 99.671 self.assertTrue(RE(Value, Truth) <= 2e-5)
def test_01(self): # 100 kt to lb/ft**3 # truth value from NASA RP 1046 Value = A.cas2dp(100, press_units='psf') Truth = 34.0493 self.failUnless(RE(Value, Truth) <= 1e-5)
def test_10(self): # 1000 mph to psf # truth value from NASA RP 1046 Value = A.cas2dp(1000, press_units='psf', speed_units='mph') Truth = 3719.98 self.failUnless(RE(Value, Truth) <= 2e-5)
def test_02(self): # 600 kt to lb/ft**3 # truth value from NASA RP 1046 Value = A.cas2dp(700, press_units='psf', speed_units='mph') Truth = 1540.37 self.failUnless(RE(Value, Truth) <= 1e-5)
def test_11(self): # 1000 kt to in HG # truth value from NASA RP 1046 Value = A.cas2dp(1000, press_units='in HG') Truth = 73.5454 self.failUnless(RE(Value, Truth) <= 2e-5)
def test_06(self): # 299 km/h to pa # truth value from NASA RP 1046 Value = A.cas2dp(299, press_units='pa', speed_units='km/h') Truth = 4288.5 self.assertTrue(RE(Value, Truth) <= 1e-5)
def test_04(self): # 300 mph to in HG # truth value from NASA RP 1046 Value = A.cas2dp(55, press_units='in HG', speed_units='kt') Truth = .145052 self.failUnless(RE(Value, Truth) <= 1e-5)
def test_05(self): # 300 km/h to mm HG # truth value from NASA RP 1046 Value = A.cas2dp(300, press_units='mm HG', speed_units='km/h') Truth = 32.385 self.assertTrue(RE(Value, Truth) <= 1e-5)
def test_06(self): # 299 km/h to pa # truth value from NASA RP 1046 Value = A.cas2dp(299, press_units='pa', speed_units='km/h') Truth = 4288.5 self.failUnless(RE(Value, Truth) <= 1e-5)
def test_03(self): # 300 mph to in HG # truth value from NASA RP 1046 Value = A.cas2dp(300, press_units='in HG', speed_units='mph') Truth = 3.38145 self.assertTrue(RE(Value, Truth) <= 1e-5)
def test_04(self): # 300 mph to in HG # truth value from NASA RP 1046 Value = A.cas2dp(55, press_units='in HG', speed_units='kt') Truth = .145052 self.assertTrue(RE(Value, Truth) <= 1e-5)
def test_01(self): # 100 kt to lb/ft**3 # truth value from NASA RP 1046 Value = A.cas2dp(100, press_units='psf') Truth = 34.0493 self.assertTrue(RE(Value, Truth) <= 1e-5)
def test_02(self): # 600 kt to lb/ft**3 # truth value from NASA RP 1046 Value = A.cas2dp(700, press_units='psf', speed_units='mph') Truth = 1540.37 self.assertTrue(RE(Value, Truth) <= 1e-5)
def test_15(self): # 1000 kt to mm HG # truth value from NASA RP 1046 Value = A.cas2dp(1000, press_units='mm HG') Truth = 1868.05 self.assertTrue(RE(Value, Truth) <= 2e-5)
def test_16(self): # 1000 kt to pa # truth value from NASA RP 1046 Value = A.cas2dp(1000, press_units='pa') Truth = 249053 self.assertTrue(RE(Value, Truth) <= 2e-5)
def test_13(self): # 1700 km/h to mm HG # truth value from NASA RP 1046 Value = A.cas2dp(1700, press_units='mm HG', speed_units='km/h') Truth = 1524.86 self.assertTrue(RE(Value, Truth) <= 2e-5)
def test_14(self): # 1700 km/h to pa # truth value from NASA RP 1046 Value = A.cas2dp(1700, press_units='pa', speed_units='km/h') Truth = 203298 self.assertTrue(RE(Value, Truth) <= 2e-5)
def test_11(self): # 1000 kt to in HG # truth value from NASA RP 1046 Value = A.cas2dp(1000, press_units='in HG') Truth = 73.5454 self.assertTrue(RE(Value, Truth) <= 2e-5)
def test_12(self): # 1000 kt to psf # truth value from NASA RP 1046 Value = A.cas2dp(1000, press_units='psf') Truth = 5201.59 self.assertTrue(RE(Value, Truth) <= 2e-5)
def test_10(self): # 1000 mph to psf # truth value from NASA RP 1046 Value = A.cas2dp(1000, press_units='psf', speed_units='mph') Truth = 3719.98 self.assertTrue(RE(Value, Truth) <= 2e-5)
def test_09(self): # 1000 mph to in HG # truth value from NASA RP 1046 Value = A.cas2dp(1000, press_units='in HG', speed_units='mph') Truth = 52.5970 self.assertTrue(RE(Value, Truth) <= 2e-5)
def test_08(self): # 244 kt to pa # truth value from NASA RP 1046 Value = A.cas2dp(244, press_units='pa') Truth = 9983.7 self.assertTrue(RE(Value, Truth) <= 2e-5)
def test_07(self): # 280 kt to mm HG # truth value from NASA RP 1046 Value = A.cas2dp(280, press_units='mm HG') Truth = 99.671 self.failUnless(RE(Value, Truth) <= 2e-5)
def tas2ssec(tas, alt, oat, ias, 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. Returns delta_Vpc, delta_Ps, delta_Hpc and Vc 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 sea level = actual altitude - altitude sensed by the static system Vc = calibrated airspeed at the test point """ P0 = U.press_conv(constants.P0, from_units='pa', to_units=press_units) cas = A.tas2cas(tas, alt, oat, speed_units=speed_units, alt_units=alt_units, temp_units=temp_units) delta_Vpc = cas - ias qcic = A.cas2dp(ias, speed_units=speed_units, press_units=press_units) qc = A.cas2dp(cas, speed_units=speed_units, press_units=press_units) delta_Ps = qc - qcic delta_Hpc = SA.press2alt(P0 - delta_Ps, press_units=press_units) # print 'Vc = %.1f, delta_vpc = %.1f, delta_ps = %.1f, delta_hpc = %.0f' % (cas, delta_Vpc, delta_Ps, delta_Hpc) return delta_Vpc, delta_Ps, delta_Hpc, cas
def WOT_speed_orig(prop, altitude, weight = 1800, rpm = 2700, temp = 'std', \ temp_units = 'C', rv = '8', wing_area = 110, speed_units = 'kt' , \ MP_loss = 1.322, ram = 0.5, pwr_factor=1, mixture='pwr', \ wheel_pants=1): """ Returns the predicted speed at full throttle. The MP_loss is the MP lost in the induction tract at full throttle at 2700 rpm at MSL. The default value is from the Lycoming power charts. The ram is the percentage of available ram recovery pressure that is achieved in the MP. """ press = SA.alt2press(altitude, press_units='in HG') MP_loss = MP_loss * (rpm / 2700.)**2 cas_guess = 300 error = 1 if mixture == 'econ': pwr_factor *= .86 # average power ratio to max power when at 50 deg LOP mixture elif mixture == 'pwr': pass else: raise ValueError('mixture must be one of "pwr" or "econ"') while error > 0.0001: dp = A.cas2dp(cas_guess, press_units='in HG') # print 'dp =', dp ram_press = ram * dp # print 'Ram rise =', ram_press MP = press - MP_loss + ram_press pwr = IO.pwr(rpm, MP, altitude, temp=temp, temp_units=temp_units) * pwr_factor # print 'MP =', MP, 'Power =', pwr tas = speed(prop, altitude, weight, pwr, rpm, temp = temp, \ temp_units = temp_units, rv = rv, wing_area = wing_area, \ speed_units = speed_units, wheel_pants = wheel_pants) cas = A.tas2cas(tas, altitude, temp=temp, temp_units=temp_units) error = M.fabs((cas - cas_guess) / cas) cas_guess = cas # print 'CAS =', cas, 'TAS =', tas # print "MP = %.3f" % MP # print "Pwr = %.2f" % pwr return tas
def WOT_speed_orig(prop, altitude, weight = 1800, rpm = 2700, temp = 'std', \ temp_units = 'C', rv = '8', wing_area = 110, speed_units = 'kt' , \ MP_loss = 1.322, ram = 0.5, pwr_factor=1, mixture='pwr', \ wheel_pants=1): """ Returns the predicted speed at full throttle. The MP_loss is the MP lost in the induction tract at full throttle at 2700 rpm at MSL. The default value is from the Lycoming power charts. The ram is the percentage of available ram recovery pressure that is achieved in the MP. """ press = SA.alt2press(altitude, press_units = 'in HG') MP_loss = MP_loss * (rpm / 2700.) ** 2 cas_guess = 300 error = 1 if mixture == 'econ': pwr_factor *= .86 # average power ratio to max power when at 50 deg LOP mixture elif mixture == 'pwr': pass else: raise ValueError, 'mixture must be one of "pwr" or "econ"' while error > 0.0001: dp = A.cas2dp(cas_guess, press_units = 'in HG') # print 'dp =', dp ram_press = ram * dp # print 'Ram rise =', ram_press MP = press - MP_loss + ram_press pwr = IO.pwr(rpm, MP, altitude, temp = temp, temp_units = temp_units) * pwr_factor # print 'MP =', MP, 'Power =', pwr tas = speed(prop, altitude, weight, pwr, rpm, temp = temp, \ temp_units = temp_units, rv = rv, wing_area = wing_area, \ speed_units = speed_units, wheel_pants = wheel_pants) cas = A.tas2cas(tas, altitude, temp = temp, temp_units = temp_units) error = M.fabs((cas - cas_guess) / cas) cas_guess = cas # print 'CAS =', cas, 'TAS =', tas # print "MP = %.3f" % MP # print "Pwr = %.2f" % pwr return tas
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