def plot_regions(self, axes, best_regions, plane): """ Function to plot the best efficiency regions, once they've been calculated. """ axes.autoscale(True) # colors = itertools.cycle(["r", "b", "g", "y", "c","m"]) idx = np.linspace(0, 1, len(best_regions)) cmap = cm.get_cmap('Accent') colors = itertools.cycle(cmap(idx)) legend_handles = [] axes.clear() axes.axis([ self.optimisation['Umin'], self.optimisation['Umax'], self.optimisation['Tmin'], self.optimisation['Tmax'] ]) battery = self.battery atmosphere = self.atmosphere # fig, ax = plt.subplots() # axes.set_color_cycle(jet(idx)) for patch in best_regions: zone = patch['region'] combo_colour = next(colors) area = 0 for i, p in enumerate(zone): axes.add_collection( collections.PathCollection(zone, color=combo_colour)) bbx = p.get_extents() length = bbx.x1 - bbx.x0 height = bbx.y1 - bbx.y0 area = area + length * height if area > 0.1: combo_patch = mpatches.Patch(color=combo_colour, label=patch['combo_name']) legend_handles.append(combo_patch) # plt.scatter(points[:,0], points[:,1]) axes.set_title(r"Most efficient combination") axes.set_ylabel(r"Thrust produced [N]") axes.set_xlabel(r"Air speed (in steady flight) [m/s]") axes.autoscale(False) Uplot = np.linspace(self.optimisation['Umin'] + 0.1, self.optimisation['Umax'], 100) dragP = optimised_consumption.dragFunc(Uplot, plane, atmosphere) self.plane_curve = [Uplot, dragP] axes.plot(Uplot, dragP, color='k', label='Plane') plane_line = mlines.Line2D([], [], color='k', label='Plane drag') legend_handles.append(plane_line) axes.legend(handles=legend_handles) self.canvas.draw()
def top_choices(plane, motors, propellers, atmosphere, folder, conditions, number): """ Function that returns the best motor-prop combinations for a specified plane subject to a number of conditions. The conditions can be turned on or off and the number of top results the function returns is given by the 'number' parameter. """ best_combos = [] combo_name_list = [] result_list = [] no_low_thrust = 0 no_over_current = 0 no_over_mass = 0 no_too_weak = 0 no_analysed = 0 no_suitable = 0 #To be safe we use the urange and trange from the generated power surface #properties. gen_props = pickle.load(open(folder + 'generation_properties.pk', "rb")) Urange = gen_props['Urange'] Trange = gen_props['Trange'] #Make sure the velocity and thrust ranges match, if they don't... Well it's probably not too bad but it's better to play safe. Umesh, Tmesh = np.meshgrid(Urange, Trange) Psurf_col = np.empty(np.shape(Umesh)) Capacity = gen_props['battery']['capacity'] * 3.6 * gen_props['battery'][ 'V'] Tlimit = conditions['static_thrust'] masslimit = conditions['motor_mass'] if conditions['static_thrust'] == False: Tlimit = 0 if conditions['allowable_overload'] == False: overload = float('inf') else: overload = conditions['allowable_overload'] if conditions['motor_mass'] == False: masslimit = float('inf') #Check to make sure all requested power surfaces have been calculated and filter them by conditions. for motor in motors: for propeller in propellers: no_analysed += 1 combo_name = motor['name'] + ' - ' + propeller['name'] save_name = folder + motor['name'] + propeller['name'] + '.pk' if os.path.isfile(save_name): result = pickle.load(open(save_name, "rb")) Ilimit = overload * result['motor']['Imax'] if result['Tmax'] < Tlimit: no_low_thrust += 1 continue if result['Imax'] > Ilimit: no_over_current += 1 continue if result['motor']['mass'] > masslimit: no_over_mass += 1 continue #ADDD MAX SPEED CONDITION combo_name_list.append(combo_name) Pfunc = result['Pinterp'] drag_min_vel = sp.optimize.minimize_scalar( lambda x: optimised_consumption.dragFunc( x, plane, atmosphere), bounds=(0.5, max(Urange)), method='bounded') d_max_vel = drag_min_vel.x drag_min = optimised_consumption.dragFunc( d_max_vel, plane, atmosphere) P_d_max = Pfunc(d_max_vel, drag_min) if P_d_max != P_d_max: no_too_weak += 1 continue # P_min_vel=sp.optimize.minimize_scalar(lambda x : Pfunc(x, optimised_consumption.dragFunc(x, plane, atmosphere)), bounds=(0.5, max(Urange)), method='bounded') # P_min_vel=P_min_vel.x # P_min=Pfunc(P_min_vel, optimised_consumption.dragFunc(P_min_vel, plane, atmosphere)) no_suitable += 1 if conditions['fixed_speed'] == False: try: P_min_vel = sp.optimize.minimize_scalar( lambda x: Pfunc( x, optimised_consumption.dragFunc( x, plane, atmosphere)), bounds=(0.5, max(Urange)), method='bounded') P_min_vel = P_min_vel.x P_min_vel_drag = optimised_consumption.dragFunc( P_min_vel, plane, atmosphere) P_min = Pfunc(P_min_vel, P_min_vel_drag) except Exception as e: print(e) pass result['max_time'] = int(Capacity / P_min) result['max_time_speed'] = P_min_vel result['max_time_drag'] = P_min_vel_drag result['max_time_distance'] = result['max_time'] * result[ 'max_time_speed'] result['max_distance_time'] = int(Capacity / P_d_max) result['max_distance_speed'] = d_max_vel result['max_distance_drag'] = drag_min result['max_distance'] = result[ 'max_distance_time'] * result['max_distance_speed'] else: P_min_vel = conditions['fixed_speed'] P_min = Pfunc( P_min_vel, optimised_consumption.dragFunc(P_min_vel, plane, atmosphere)) P_min_vel_drag = optimised_consumption.dragFunc( P_min_vel, plane, atmosphere) result['max_time'] = int(Capacity / P_min) result['max_time_speed'] = P_min_vel result['max_time_drag'] = P_min_vel_drag result['max_time_distance'] = result['max_time'] * result[ 'max_time_speed'] d_max_vel = conditions['fixed_speed'] P_d_max = Pfunc( d_max_vel, optimised_consumption.dragFunc(d_max_vel, plane, atmosphere)) result['max_distance_time'] = int(Capacity / P_d_max) result['max_distance_speed'] = d_max_vel result['max_distance_drag'] = P_min_vel_drag result['max_distance'] = result[ 'max_distance_time'] * result['max_distance_speed'] result_list.append(result) Psurf_col = np.dstack( (Psurf_col, result['Psurf'])) #Collect power surface else: print('Combination missing') return #Now we sort the results by whatever we're interested in if conditions['maximise_distance'] == True: best_combos = sorted(result_list, key=itemgetter('max_distance'), reverse=True)[:number] else: best_combos = sorted(result_list, key=itemgetter('max_time'), reverse=True)[:number] #Summarise the analysis report = { 'analysed': no_analysed, 'low_thrust': no_low_thrust, 'over_current': no_over_current, 'over_mass': no_over_mass, 'too_weak': no_too_weak, 'suitable': no_suitable, } return best_combos, report
def plot_eff(self, axes): # try: # plt.delaxes(axes.axes[1]) # except Exception as e: # print(e) selected_combos = [] axes.clear() item_model = self.listView_results.model() for row in self.listView_results.selectedIndexes(): item = item_model.itemFromIndex(row) selected_combos.append(item.combo) combo = selected_combos[0] plane = self.plane atmosphere = self.atmosphere # plt.suptitle(image_name, fontsize=14, fontweight='bold') axes.set_title(r"Total efficiency of combination") axes.set_ylabel(r"Thrust produced [N]") axes.set_xlabel(r"Air speed (in steady flight) [m/s]") levels = [0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.70, 0.75] colormap = cm.get_cmap('RdYlGn') CS_filled = axes.contourf(combo['Umesh'], combo['Tmesh'], combo['eta_system'], levels, cmap=colormap, extend='both') if hasattr(self, 'cbar'): self.cbar = plt.colorbar(CS_filled, cax=self.cbar.ax) self.cbar.ax.set_ylabel('Total efficiency') else: self.cbar = plt.colorbar(CS_filled, ax=axes) self.cbar.ax.set_ylabel('Total efficiency') CS = plt.contour(combo['Umesh'], combo['Tmesh'], combo['eta_system'], levels, colors=('k', ), linewidths=(1, )) axes.clabel(CS, fmt='%2.1f', colors='k', fontsize=14) id_valid = (np.array(combo['Pmesh']) == np.array(combo['Pmesh'])) T = combo['Tmesh'] T[~id_valid] = float('nan') axes.axis([0, np.nanmax(combo['Umesh']), 0, np.nanmax(T)]) # axes.plot(self.plane_curve[0],self.plane_curve[1], color='k', label='PLane') if self.radioButton_fixed_speed.isChecked(): axes.scatter(combo['max_time_speed'], combo['max_time_drag'], c='b', label='Cruise speed') else: axes.scatter(combo['max_distance_speed'], combo['max_distance_drag'], c='b', label='Max range conditions') axes.scatter(combo['max_time_speed'], combo['max_time_drag'], c='r', label='Max flight time conditions') try: axes.plot(self.plane_curve[0], self.plane_curve[1], color='k', label='Plane drag') except AttributeError: Uplot = np.linspace(self.optimisation['Umin'] + 0.1, self.optimisation['Umax'], 100) dragP = optimised_consumption.dragFunc(Uplot, plane, atmosphere) self.plane_curve = [Uplot, dragP] axes.plot(Uplot, dragP, color='k', label='Plane drag') plane_line = mlines.Line2D([], [], color='k', label='Plane drag') axes.legend(loc=1) self.canvas.draw()
def plot_perf(self, axes): """ Function to plot performance of currently selected result. """ selected_combos = [] axes.clear() item_model = self.listView_results.model() for row in self.listView_results.selectedIndexes(): item = item_model.itemFromIndex(row) selected_combos.append(item.combo) combo = selected_combos[0] plane = self.plane atmosphere = self.atmosphere # plt.suptitle(image_name, fontsize=14, fontweight='bold') axes.set_title(r"Power consumption of system") axes.set_ylabel(r"Thrust produced [N]") axes.set_xlabel(r"Air speed (in steady flight) [m/s]") Pmax = combo['motor']['Imax'] * self.battery['V'] levels = np.linspace( 20, Pmax, 10) #[20,40,60,80,100,120,140,160,180,200,220,240,260,280] colormap = cm.get_cmap('coolwarm') CS_filled = axes.contourf(combo['Umesh'], combo['Tmesh'], combo['Pmesh'], levels, cmap=colormap, extend='both') if hasattr(self, 'cbar'): # image.set_data(CS_filled) #use this if you use new array self.cbar = plt.colorbar(CS_filled, cax=self.cbar.ax) self.cbar.ax.set_ylabel('Power [W]') else: self.cbar = plt.colorbar(CS_filled, ax=axes) self.cbar.ax.set_ylabel('Power [W]') CS = axes.contour(combo['Umesh'], combo['Tmesh'], combo['Pmesh'], levels, colors=('k', ), linewidths=(1, )) axes.clabel(CS, fmt='%2.1f', colors='k', fontsize=14) axes.contourf(combo['Umesh'], combo['Tmesh'], combo['Pmesh'], [Pmax, Pmax * 1.2], hatches=['//'], colors='none', extend='max', alpha=0.0) #Find the max because autoscale can't handle the abundunce of nana in these arrays. id_valid = (np.array(combo['Pmesh']) == np.array(combo['Pmesh'])) T = combo['Tmesh'] T[~id_valid] = float('nan') axes.axis([0, np.nanmax(combo['Umesh']), 0, np.nanmax(T)]) # axes.autoscale(True) if self.radioButton_fixed_speed.isChecked(): axes.scatter(combo['max_time_speed'], combo['max_time_drag'], c='b', label='Cruise speed') else: axes.scatter(combo['max_distance_speed'], combo['max_distance_drag'], c='b', label='Max range conditions') axes.scatter(combo['max_time_speed'], combo['max_time_drag'], c='r', label='Max flight time conditions') try: axes.plot(self.plane_curve[0], self.plane_curve[1], color='k', label='Plane drag') except AttributeError: Uplot = np.linspace(self.optimisation['Umin'] + 0.1, self.optimisation['Umax'], 100) dragP = optimised_consumption.dragFunc(Uplot, plane, atmosphere) self.plane_curve = [Uplot, dragP] axes.plot(Uplot, dragP, color='k', label='Plane drag') plane_line = mlines.Line2D([], [], color='k', label='Plane drag') axes.legend(loc=1) self.canvas.draw()
'mass': 1.15, #mass in kilos 'C_1': 0.1156, 'C_2': -0.0069, 'C_3': 0.0174, 'loss_factor': 1.0, #Assumed to scale with reynolds 'loss_ref_length': 1, 'theta_sweep': 30, 'body_length': 0.4, 'aero_factor':0.5 } atmosphere={ 'rho':1.10, # 'mu':1.8e-5, #dynamic viscosity 'Ta': 25, #Ambient temperature } plane_mass=payload/payload_frac U_range=np.linspace(5,20,100) drag=dragFunc(U_range,plane1,atmosphere) drag_real=consumption_functions.dragFunc(U_range,plane1,atmosphere) plt.plot(U_range, drag, label='Estimate') plt.plot(U_range, drag_real, label='real') plt.legend(loc=4) plt.show()