def get_performance(o, c, t, v_climb): chord_meters = c * radius prop = propeller.Propeller(t, chord_meters, radius, n_blades, r, y, dr, dy, airfoils=airfoils, Cl_tables=Cl_tables, Cd_tables=Cd_tables) perf = bemt.bemt_axial(prop, pitch, o, allowable_Re=allowable_Re, Cl_funs=Cl_funs, Cd_funs=Cd_funs, tip_loss=tip_loss, mach_corr=mach_corr, output='long', v_climb=v_climb) return perf[-2], perf[-1]
def get_performance(o, c, t): chord_meters = c * radius prop = propeller.Propeller(t, chord_meters, radius, n_blades, r, y, dr, dy, airfoils=airfoils, Cl_tables=Cl_tables, Cd_tables=Cd_tables) quad = quadrotor.Quadrotor(prop, vehicle_weight) ff_kwargs = { 'propeller': prop, 'pitch': pitch, 'n_azi_elements': n_azi_elements, 'allowable_Re': allowable_Re, 'Cl_funs': Cl_funs, 'Cd_funs': Cd_funs, 'tip_loss': tip_loss, 'mach_corr': mach_corr, 'alt': alt, 'lift_curve_info_dict': lift_curve_info_dict } trim0 = np.array([alpha0, o]) alpha_trim, omega_trim, converged = trim.trim(quad, v_inf, trim0, ff_kwargs) T_ff, H_ff, P_ff = bemt.bemt_forward_flight( quad, pitch, omega_trim, alpha_trim, v_inf, n_azi_elements, alt=alt, tip_loss=tip_loss, mach_corr=mach_corr, allowable_Re=allowable_Re, Cl_funs=Cl_funs, Cd_funs=Cd_funs, lift_curve_info_dict=lift_curve_info_dict) dT_h, P_h = bemt.bemt_axial(prop, pitch, o, allowable_Re=allowable_Re, Cl_funs=Cl_funs, Cd_funs=Cd_funs, tip_loss=tip_loss, mach_corr=mach_corr, alt=alt) return sum(dT_h), P_h, T_ff, P_ff, alpha_trim, omega_trim
def objfun(xn, **kwargs): radius = kwargs['radius'] r = kwargs['r'] y = kwargs['y'] dr = kwargs['dr'] dy = kwargs['dy'] n_blades = kwargs['n_blades'] airfoils = kwargs['airfoils'] pitch = kwargs['pitch'] vehicle_weight = kwargs['vehicle_weight'] max_chord = kwargs['max_chord'] max_chord_tip = kwargs['max_chord_tip'] tip_loss = kwargs['tip_loss'] mach_corr = kwargs['mach_corr'] Cl_tables = kwargs['Cl_tables'] Cd_tables = kwargs['Cd_tables'] Cl_funs = kwargs['Cl_funs'] Cd_funs = kwargs['Cd_funs'] lift_curve_info_dict = kwargs['lift_curve_info_dict'] allowable_Re = kwargs['allowable_Re'] alt = kwargs['alt'] v_inf = kwargs['v_inf'] alpha0 = kwargs['alpha0'] n_azi_elements = kwargs['n_azi_elements'] mission_time = kwargs['mission_time'] omega_h = xn[0] twist0 = xn[1] chord0 = xn[ 2] * radius # Convert to meters from c/R before we use in calculations dtwist = np.array(xn[3:len(r) + 2]) dchord = np.array([x * radius for x in xn[len(r) + 2:2 * len(r) + 2]]) twist = calc_twist_dist(twist0, dtwist) chord = calc_chord_dist(chord0, dchord) f = 10000000. fail = 0 g = [1.0] * (2 * len(r) + 2) # Calculate geometric constraint values. If a genetic algorithm is used we can fail the case immediately if there # are any violations. If a gradient-based algorithm is used this will cause the gradient calculation to fail so the # constraints must be checked normally by the optimizer. g[1] = chord[-1] / radius - max_chord_tip g[2:] = get_geocons(chord, max_chord, radius) prop = propeller.Propeller(twist, chord, radius, n_blades, r, y, dr, dy, airfoils=airfoils, Cl_tables=Cl_tables, Cd_tables=Cd_tables) quad = quadrotor.Quadrotor(prop, vehicle_weight) try: dT_h, P_h = bemt.bemt_axial(prop, pitch, omega_h, allowable_Re=allowable_Re, Cl_funs=Cl_funs, Cd_funs=Cd_funs, tip_loss=tip_loss, mach_corr=mach_corr, alt=alt) except FloatingPointError: print "Floating point error in axial BEMT" fail = 1 return f, g, fail except IndexError: print "Index error in axial BEMT" fail = 1 return f, g, fail try: trim0 = [ alpha0, omega_h ] # Use alpha0 (supplied by user) and the hover omega as initial guesses for trim ff_kwargs = { 'propeller': prop, 'pitch': pitch, 'n_azi_elements': n_azi_elements, 'allowable_Re': allowable_Re, 'Cl_funs': Cl_funs, 'Cd_funs': Cd_funs, 'tip_loss': tip_loss, 'mach_corr': mach_corr, 'alt': alt, 'lift_curve_info_dict': lift_curve_info_dict } alpha_trim, omega_trim, converged = trim.trim(quad, v_inf, trim0, ff_kwargs) if not converged or not 0 < alpha_trim < np.pi / 2 or omega_trim < 0: fail = 1 return f, g, fail T_trim, H_trim, P_trim = bemt.bemt_forward_flight( quad, pitch, omega_trim, alpha_trim, v_inf, n_azi_elements, alt=alt, tip_loss=tip_loss, mach_corr=mach_corr, allowable_Re=allowable_Re, Cl_funs=Cl_funs, Cd_funs=Cd_funs, lift_curve_info_dict=lift_curve_info_dict) except Exception as e: print "{} in ff trim".format(type(e).__name__) fail = 1 return f, g, fail # Find total energy mission_times = [time_in_hover, time_in_ff] in seconds energy = P_h * mission_time[0] + P_trim * mission_time[1] f = energy print "total energy = " + str(f) print "Thrust hover = %s" % str(sum(dT_h)) print "(alpha, omega) = (%f, %f)" % (alpha_trim, omega_trim) # Evaluate performance constraints. g[0] = vehicle_weight / 4 - sum(dT_h) if g[0] > 0: print "hover thrust too low" return f, g, fail
twist = np.array([6.97, 15.97, 21.77, 21.72, 19.91, 18.14, 16.55, 15.28, 14.01, 13., 12.18, 11.39, 10.76, 10.24, 9.85, 9.4, 9.07, 8.7, 8.46, 8.29, 8.19, 8.17]) * 2 * np.pi / 360 chord = in2m(np.array([0.77, 0.97, 1.18, 1.34, 1.44, 1.49, 1.50, 1.49, 1.46, 1.42, 1.38, 1.33, 1.27, 1.21, 1.14, 1.07, 1., 0.93, 0.86, 0.77, 0.67, 0.44])) prop = propeller.Propeller(twist, chord, radius, n_blades, r, y, dr, dy, airfoils=airfoils, Cl_tables=Cl_tables, Cd_tables=Cd_tables) quad = quadrotor.Quadrotor(prop, vehicle_weight) ff_kwargs = {'propeller': prop, 'pitch': pitch, 'n_azi_elements': n_azi_elements, 'allowable_Re': allowable_Re, 'Cl_funs': Cl_funs, 'Cd_funs': Cd_funs, 'tip_loss': tip_loss, 'mach_corr': mach_corr, 'alt': alt, 'lift_curve_info_dict': lift_curve_info_dict} omega = 2800 * 2*np.pi/60 Th, Ph = bemt.bemt_axial(prop, pitch, omega, allowable_Re=allowable_Re, Cd_funs=Cd_funs, Cl_funs=Cl_funs) print "(T, P) for %d RPM = (%f, %f)" % (omega*60/2/np.pi, sum(Th)*0.2248*4, Ph) omega = 4200 * 2*np.pi/60 Th, Ph = bemt.bemt_axial(prop, pitch, omega, allowable_Re=allowable_Re, Cd_funs=Cd_funs, Cl_funs=Cl_funs) print "(T, P) for %d RPM = (%f, %f)" % (omega*60/2/np.pi, sum(Th)*0.2248*4, Ph) ## Hover performance of SUI Endurance for a range of rotor speeds # hthrust = [] # hpower = [] # o_start = 2000. # o_end = 4600. # o_range = np.linspace(o_start, o_end, 10) # for o in o_range*2*np.pi/60: # dT_h, P_h = bemt.bemt_axial(prop, pitch, o, allowable_Re=allowable_Re, Cl_funs=Cl_funs, Cd_funs=Cd_funs, # tip_loss=True, mach_corr=mach_corr, alt=alt)
def objfun_optimize_twist(xn, **kwargs): radius = kwargs['radius'] r = kwargs['r'] y = kwargs['y'] dr = kwargs['dr'] dy = kwargs['dy'] n_blades = kwargs['n_blades'] airfoils = kwargs['airfoils'] pitch = kwargs['pitch'] target_thrust = kwargs['thrust'] tip_loss = kwargs['tip_loss'] mach_corr = kwargs['mach_corr'] allowable_Re = kwargs['allowable_Re'] Cl_tables = kwargs['Cl_tables'] Cd_tables = kwargs['Cd_tables'] Cl_funs = kwargs['Cl_funs'] Cd_funs = kwargs['Cd_funs'] chord = kwargs['chord'] * radius alt = kwargs['alt'] # The algorithm works with radius-normalized chord lengths, but the BEMT takes real chord lengths, so multiply by R omega = xn[0] twist0 = xn[1] dtwist = xn[2:] twist = calc_twist_dist(twist0, dtwist) f = 1000. fail = 0 g = [1.0] prop = propeller.Propeller(twist, chord, radius, n_blades, r, y, dr, dy, airfoils=airfoils, Cl_tables=Cl_tables, Cd_tables=Cd_tables) try: dT, P, FM = bemt.bemt_axial(prop, pitch, omega, allowable_Re=allowable_Re, Cl_funs=Cl_funs, Cd_funs=Cd_funs, tip_loss=tip_loss, mach_corr=mach_corr, alt=alt) except FloatingPointError: fail = 1 return f, g, fail except IndexError: return 10000, g, fail f = P print "Power = " + str(f) print "Thrust = %s" % str(sum(dT)) # Evaluate thrust constraint. Target thrust must be less than computed thrust g[0] = target_thrust - sum(dT) return f, g, fail
chord_inches = chord * radius # Run BEMT on propeller prop = propeller.Propeller(twist, chord, radius, n_blades, r, y, dr, dy, Clalpha, airfoils=airfoils) CT, CP, CQ, Cl, dT, pCT, pCP, Re, aoa = bemt.bemt_axial(prop, pitch, omega) print "C_P = " + str(pCP) print "Thrust = " + str(sum(dT)) plt.figure(1) plt.plot(r, chord, '-') plt.xlabel("radial station, r") plt.ylabel("chord length, inches") plt.figure(2) plt.plot(r, twist, '-') plt.xlabel("radial station, r") plt.ylabel("twist, degrees") plt.show()
def objfun(xn, **kwargs): radius = kwargs['radius'] r = kwargs['r'] y = kwargs['y'] dr = kwargs['dr'] dy = kwargs['dy'] n_blades = kwargs['n_blades'] airfoils = kwargs['airfoils'] pitch = kwargs['pitch'] target_thrust = kwargs['vehicle_weight'] / 4 cval_max = kwargs['max_chord'] tip_loss = kwargs['tip_loss'] mach_corr = kwargs['mach_corr'] Cl_tables = kwargs['Cl_tables'] Cd_tables = kwargs['Cd_tables'] Cl_funs = kwargs['Cl_funs'] Cd_funs = kwargs['Cd_funs'] allowable_Re = kwargs['allowable_Re'] opt_method = kwargs['opt_method'] alt = kwargs['alt'] omega = xn[0] twist0 = xn[1] chord0 = xn[2] * radius dtwist = np.array(xn[3:len(r) + 2]) dchord = np.array([x * radius for x in xn[len(r) + 2:2 * len(r) + 2]]) twist = calc_twist_dist(twist0, dtwist) chord = calc_chord_dist(chord0, dchord) f = 1000. fail = 0 g = [1.0] * (2 * len(r) + 1) # Calculate geometric constraint values. If a genetic algorithm is used we can fail the case immediately if there # are any violations. If a gradient-based algorithm is used this will cause the gradient calculation to fail so the # constraints must be checked normally by the optimizer. g[1:] = get_geocons(chord, cval_max, radius) if opt_method == 'nograd': if any(geocon > 0.0 for geocon in g[1:]): print "geocons violated" return f, g, fail prop = propeller.Propeller(twist, chord, radius, n_blades, r, y, dr, dy, airfoils=airfoils, Cl_tables=Cl_tables, Cd_tables=Cd_tables) try: dT, P = bemt.bemt_axial(prop, pitch, omega, allowable_Re=allowable_Re, Cl_funs=Cl_funs, Cd_funs=Cd_funs, tip_loss=tip_loss, mach_corr=mach_corr, alt=alt) except (FloatingPointError, IndexError): fail = 1 return f, g, fail f = P print f print "Thrust = %s" % str(sum(dT)) # Evaluate thrust constraint. Target thrust must be less than computed thrust g[0] = target_thrust - sum(dT) return f, g, fail