Source code for RCAIDE.Library.Plots.Aerodynamics.plot_rotor_conditions

# RCAIDE/Library/Plots/Performance/Aerodynamics/plot_rotor_conditions.py
# 
# 
# Created:  Jul 2023, M. Clarke
 
# ----------------------------------------------------------------------------------------------------------------------
#  IMPORT
# ----------------------------------------------------------------------------------------------------------------------  

from RCAIDE.Framework.Core import Units
from RCAIDE.Library.Plots.Common import set_axes, plot_style, segment_colors 
import matplotlib.pyplot as plt
import numpy as np 

# ----------------------------------------------------------------------------------------------------------------------
#  PLOTS
# ----------------------------------------------------------------------------------------------------------------------      
[docs] def plot_rotor_conditions(results, save_figure = False, show_legend=True, save_filename = "Rotor_Conditions", file_type = ".png", width = 11, height = 7): """ Generate plots of key rotor operating conditions over time. Parameters ---------- results : Data Mission results data structure containing: - results.segments[0].analyses.vehicle.networks save_figure : bool, optional Save figure to file if True, default False show_legend : bool, optional Display segment legend if True, default True save_filename : str, optional Name for saved figure file, default "Rotor_Conditions" file_type : str, optional File extension for saved figure, default ".png" width : float, optional Figure width in inches, default 11 height : float, optional Figure height in inches, default 7 Returns ------- fig : matplotlib.figure.Figure Notes ----- Creates a 2x2 subplot figure showing: - Top left: RPM vs time (minutes) - Top right: Rotor tilt angle (degrees) vs time - Bottom left: Thrust (N) vs time - Bottom right: Torque (N-m) vs time Each mission segment uses a different color from the inferno colormap. Multiple rotors are distinguished by different markers. **Definitions** 'RPM' Rotor rotational speed in revolutions per minute 'Thrust Vector Angle' Angle between rotor thrust vector and vertical See Also -------- RCAIDE.Library.Plots.Common.set_axes : Standardized axis formatting RCAIDE.Library.Plots.Common.plot_style : RCAIDE plot styling RCAIDE.Library.Analysis.Performance.propulsion : Analysis modules """ save_filename_1 = save_filename + '_1' save_filename_2 = save_filename + '_2' # get plotting style ps = plot_style() parameters = {'axes.labelsize': ps.axis_font_size, 'xtick.labelsize': ps.axis_font_size, 'ytick.labelsize': ps.axis_font_size, 'axes.titlesize': ps.title_font_size} plt.rcParams.update(parameters) # get line colors for plots line_colors = segment_colors(len(results.segments)) fig_1 = plt.figure(save_filename_1) fig_1.set_size_inches(width,height) axis_1_1 = fig_1.add_subplot(2,2,1) axis_1_2 = fig_1.add_subplot(2,2,2) axis_1_3 = fig_1.add_subplot(2,2,3) axis_1_4 = fig_1.add_subplot(2,2,4) fig_2 = plt.figure(save_filename_2) fig_2.set_size_inches(width,height) axis_2_1 = fig_2.add_subplot(2,2,1) axis_2_2 = fig_2.add_subplot(2,2,2) axis_2_3 = fig_2.add_subplot(2,2,3) axis_2_4 = fig_2.add_subplot(2,2,4) for network in results.segments[0].analyses.vehicle.networks: for p_i, propulsor in enumerate(network.propulsors): if (p_i == 0) or (network.identical_propulsors == False): plot_propulsor_data(results,propulsor, axis_1_1, axis_1_2, axis_1_3, axis_1_4, axis_2_1, axis_2_2, axis_2_3, axis_2_4,line_colors,ps,p_i) if show_legend: leg = fig_1.legend(bbox_to_anchor=(0.5, 0.95), loc='upper center', ncol = 4) leg.set_title('Flight Segment', prop={'size': ps.legend_font_size, 'weight': 'heavy'}) leg = fig_2.legend(bbox_to_anchor=(0.5, 0.95), loc='upper center', ncol = 4) leg.set_title('Flight Segment', prop={'size': ps.legend_font_size, 'weight': 'heavy'}) # Adjusting the sub-plots for legend fig_1.tight_layout() fig_1.subplots_adjust(top=0.8) fig_2.tight_layout() fig_2.subplots_adjust(top=0.8) # set title of plot title_text = 'Rotor Performance' fig_1.suptitle(title_text) fig_2.suptitle(title_text) if save_figure: plt.savefig(save_filename_1 + file_type) plt.savefig(save_filename_2 + file_type) return (fig_1, fig_2)
[docs] def plot_propulsor_data(results, propulsor, axis_1_1, axis_1_2, axis_1_3, axis_1_4, axis_2_1, axis_2_2, axis_2_3, axis_2_4, line_colors, ps, p_i): """ Plot operating conditions data for a single propulsor across mission segments. Parameters ---------- results : Data Mission results data structure containing: - results.segments[i].conditions with fields: - energy[propulsor_tag][thrustor_tag].rpm - energy[propulsor_tag][thrustor_tag].thrust - energy[propulsor_tag][thrustor_tag].torque - energy[propulsor_tag].commanded_thrust_vector_angle - frames.inertial.time propulsor : Data Propulsor data structure containing: - tag : str Identifier for the propulsor - rotor/propeller : Data Thrustor component data axis_1 : matplotlib.axes.Axes Axis for RPM plot axis_2 : matplotlib.axes.Axes Axis for rotor angle plot axis_3 : matplotlib.axes.Axes Axis for thrust plot axis_4 : matplotlib.axes.Axes Axis for torque plot line_colors : array Array of RGB colors for different segments ps : Data Plot style data structure with fields: - markers : list Marker styles for different propulsors - line_width : float Width for plot lines p_i : int Index of current propulsor for marker selection Returns ------- None Notes ----- Helper function for plot_rotor_conditions that handles plotting data for a single propulsor (rotor or propeller) across all mission segments. The function: - Identifies thrustor type (rotor vs propeller) - Extracts time histories for each segment - Plots RPM, angle, thrust, and torque vs time - Applies consistent styling - Adds legend for first segment only - Converts units as needed (time to minutes, angles to degrees) See Also -------- RCAIDE.Library.Plots.Aerodynamics.plot_rotor_conditions : Main plotting function """ if 'rotor' in propulsor: thrustor = propulsor.rotor elif 'propeller' in propulsor: thrustor = propulsor.propeller for i in range(len(results.segments)): time = results.segments[i].conditions.frames.inertial.time[:,0] / Units.min rpm = results.segments[i].conditions.energy.converters[thrustor.tag].rpm[:,0] eta = results.segments[i].conditions.energy.converters[thrustor.tag].efficiency[:,0] angle = results.segments[i].conditions.energy.converters[thrustor.tag].commanded_thrust_vector_angle[:,0] beta = results.segments[i].conditions.energy.converters[thrustor.tag].blade_pitch_command[:,0] DL = results.segments[i].conditions.energy.converters[thrustor.tag].disc_loading[:,0] PL = results.segments[i].conditions.energy.converters[thrustor.tag].power_loading[:,0] thrust = np.linalg.norm(results.segments[i].conditions.energy.converters[thrustor.tag].thrust , axis =1) torque = results.segments[i].conditions.energy.converters[thrustor.tag].torque[:,0] if p_i == 0 and i ==0: axis_1_1.plot(time,DL, color = line_colors[i], marker = ps.markers[p_i], linewidth = ps.line_width, label = thrustor.tag) axis_2_1.plot(time,rpm, color = line_colors[i], marker = ps.markers[p_i] , linewidth = ps.line_width, label = thrustor.tag) else: axis_1_1.plot(time,DL, color = line_colors[i], marker = ps.markers[p_i], linewidth = ps.line_width) axis_2_1.plot(time,rpm, color = line_colors[i], marker = ps.markers[p_i] , linewidth = ps.line_width) axis_1_1.set_ylabel(r'Disc Loading (N/m^2)') set_axes(axis_1_1) axis_2_1.set_ylabel(r'RPM') set_axes(axis_2_1) axis_1_2.plot(time,PL, color = line_colors[i], marker = ps.markers[p_i], linewidth = ps.line_width) axis_1_2.set_xlabel('Time (mins)') axis_1_2.set_ylabel(r'Power Loading (N/W)') set_axes(axis_1_2) axis_1_3.plot(time,thrust, color = line_colors[i], marker = ps.markers[p_i] , linewidth = ps.line_width) axis_1_3.set_ylabel(r'Thrust (N)') set_axes(axis_1_3) axis_1_4.plot(time,torque, color = line_colors[i], marker = ps.markers[p_i] , linewidth = ps.line_width) axis_1_4.set_ylabel(r'Torque (N-m)') set_axes(axis_1_4) axis_2_2.plot(time, angle/Units.degrees, color = line_colors[i], marker = ps.markers[p_i] , linewidth = ps.line_width) axis_2_2.set_ylabel(r'Thrust Vector (deg)') set_axes(axis_2_2) axis_2_3.plot(time,beta/Units.degrees, color = line_colors[i], marker = ps.markers[p_i] , linewidth = ps.line_width) axis_2_3.set_ylabel(r'Pitch Command (deg)') set_axes(axis_2_3) axis_2_4.plot(time,eta, color = line_colors[i], marker = ps.markers[p_i] , linewidth = ps.line_width) axis_2_4.set_ylabel(r'Efficiency') set_axes(axis_2_4) return