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 calc_dwdt(self, moment_body): """Calculate dwdt, body frame.""" return np.dot(self.Inverse_of_I, moment_body) def calc_one_step(self, inputs): FM = self.calc_Force_Torque(inputs) x, t = self.dynamics.simulate_onestep(dvdt=self.calc_dvdt(FM[0:3, 0]), dwdt=self.calc_dwdt(FM[3:6, 0])) if __name__ == '__main__': array_propellers = [] array_propellers.append( propeller.Propeller(position=np.array([[1.0, 1.0, 0.0]]).T, direction=np.array([[0.0, 0.0, -1.0]]).T)) array_propellers.append( propeller.Propeller(position=np.array([[1.0, -1.0, 0.0]]).T, direction=np.array([[0.0, 0.0, -1.0]]).T, k_F=1.0, k_M=-1.0)) array_propellers.append( propeller.Propeller(position=np.array([[-1.0, -1.0, 0.0]]).T, direction=np.array([[0.0, 0.0, -1.0]]).T)) array_propellers.append( propeller.Propeller(position=np.array([[-1.0, 1.0, 0.0]]).T, direction=np.array([[0.0, 0.0, -1.0]]).T, k_F=1.0,
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
Cl_funs = {} Cd_funs = {} lift_curve_info_dict = {} if any(Cl_tables) and allowable_Re: Cl_funs = dict(zip(allowable_Re, [aero_coeffs.get_Cl_fun(Re, Cl_tables[airfoils[0][0]], Clmax[airfoils[0][0]][Re]) for Re in allowable_Re])) Cd_funs = dict(zip(allowable_Re, [aero_coeffs.get_Cd_fun(Re, Cd_tables[airfoils[0][0]]) for Re in allowable_Re])) lift_curve_info_dict = aero_coeffs.create_liftCurveInfoDict(allowable_Re, Cl_tables[airfoils[0][0]]) radius = in2m(15./2) 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)
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
for i, dc in enumerate(dc_vec): c[i + 1] = c[i] + dc return c twist = calc_twist_dist(theta0, dtwist) chord = calc_chord_dist(chord0, dchord) 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")
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