aerosandbox.library.propulsion_electric ======================================= .. py:module:: aerosandbox.library.propulsion_electric Attributes ---------- .. autoapisummary:: aerosandbox.library.propulsion_electric.pows Functions --------- .. autoapisummary:: aerosandbox.library.propulsion_electric.motor_electric_performance aerosandbox.library.propulsion_electric.electric_propeller_propulsion_analysis aerosandbox.library.propulsion_electric.motor_resistance_from_no_load_current aerosandbox.library.propulsion_electric.mass_ESC aerosandbox.library.propulsion_electric.mass_battery_pack aerosandbox.library.propulsion_electric.mass_motor_electric aerosandbox.library.propulsion_electric.mass_wires Module Contents --------------- .. py:function:: motor_electric_performance(voltage = None, current = None, rpm = None, torque = None, kv = 1000.0, resistance = 0.1, no_load_current = 0.4) A function for predicting the performance of an electric motor. Performance equations based on Mark Drela's First Order Motor Model: http://web.mit.edu/drela/Public/web/qprop/motor1_theory.pdf Instructions: Input EXACTLY TWO of the following parameters: voltage, current, rpm, torque. Exception: You cannot supply the combination of current and torque - this makes for an ill-posed problem. Note that this function is fully vectorized, so arrays can be supplied to any of the inputs. :param voltage: Voltage across motor terminals [Volts] :param current: Current through motor [Amps] :param rpm: Motor rotation speed [rpm] :param torque: Motor torque [N m] :param kv: voltage constant, in rpm/volt :param resistance: resistance, in ohms :param no_load_current: no-load current, in amps :returns: "voltage", "current", "rpm", "torque", "shaft power", "electrical power", "efficiency" "waste heat" And values are corresponding quantities in SI units. Note that "efficiency" is just (shaft power) / (electrical power), and hence implicitly assumes that the motor is operating as a motor (electrical -> shaft power), and not a generator (shaft power -> electrical). If you want to know the efficiency of the motor as a generator, you can simply calculate it as (electrical power) / (shaft power). :rtype: A dictionary where keys are .. py:function:: electric_propeller_propulsion_analysis(total_thrust, n_engines, propeller_diameter, op_point, motor_kv, motor_no_load_current, motor_resistance, wire_resistance, battery_voltage, propeller_tip_mach = 0.5, gearbox_ratio = 1, gearbox_efficiency = 1, esc_efficiency = 0.98, battery_discharge_efficiency = 0.985) Performs a propulsion analysis for an electric propeller-driven aircraft. May be used for single-engine or multi-engine aircraft, so long as all engines / propellers are identical. :param total_thrust: Total thrust force produced by all engines at the cruise operating point [N]. :param n_engines: Number of engines on the aircraft. :param propeller_diameter: Diameter of each of the propellers [m]. :param op_point: The cruise operating point. Must be an AeroSandbox OperatingPoint object. :param motor_kv: Motor voltage constant [rpm/volt]. :param motor_no_load_current: Motor no-load current [amps]. :param motor_resistance: Motor resistance [ohms]. :param wire_resistance: Round-trip resistance of the wires connecting the ESC to the battery [ohms]. :param battery_voltage: Battery voltage [volts]. :param propeller_tip_mach: Mach number at the propeller tip. Defaults to 0.50. From a propulsive efficiency perspective, you want this to be as high as possible while still keeping the tip speed (hypotenuse of the velocity triangle) below the critical Mach number of the propeller blade airfoil. This is because motor efficiency and specific power tend to be better at high-speed low-torque conditions, and also the propeller aerodynamics tend to be better at low solidity. But there may be reasons to lower this, such as propeller structural considerations or noise considerations (with noise being a *strong* function of tip Mach). :param gearbox_ratio: Gearbox reduction ratio. Defaults to 1 (no gearbox). For example, a `gearbox_ratio` of 5 is a 5:1 reduction, meaning that the propeller turns 5 times slower than the motor. :param gearbox_efficiency: Gearbox efficiency. Defaults to 1, only because the `gearbox_ratio` defaults to 1 (no gearbox), and so this represents no losses. If you have a gearbox, you should probably use a value of 0.98 or so. :param esc_efficiency: Efficiency of the electronic speed controller (ESC), sometimes called the inverter. Defaults to 0.98, which is a reasonable value for a high-quality ESC at a large (>5 kW) scale. Small components will lower efficiencies than this. :param battery_discharge_efficiency: Coulobmic efficiency of the battery in discharge only (i.e., not round-trip). Defaults to 0.985, which is a reasonable value for a high-quality lithium-polymer battery. Other battery chemistries will have different values. Returns: A dictionary of various parameters of the propulsion analysis. Of particular note are the following keys: * "air_power": The power delivered to the air (thrust * velocity) [W] * "shaft_power": The power at the propeller shaft (after the gearbox; rotational speed * torque) [W] * "motor_electrical_power": The electrical power input to the motor [W] * "esc_electrical_power": The electrical power input to the ESC [W] * "battery_power": The power draw from the battery [W]. * "propeller_efficiency": The propulsive efficiency of the propeller, defined as (air_power / shaft_power). * "motor_efficiency": The efficiency of the motor, defined as (shaft_power / motor_electrical_power). * "overall_efficiency": The overall efficiency of the propulsion system, defined as (air_power / battery_power). .. py:function:: motor_resistance_from_no_load_current(no_load_current) Estimates the internal resistance of a motor from its no_load_current. Gates quotes R^2=0.93 for this model. Source: Gates, et. al., "Combined Trajectory, Propulsion, and Battery Mass Optimization for Solar-Regen..." https://scholarsarchive.byu.edu/cgi/viewcontent.cgi?article=3932&context=facpub :param no_load_current: No-load current [amps] :returns: motor internal resistance [ohms] .. py:function:: mass_ESC(max_power) Estimates the mass of an ESC. Informal correlation I did to Hobbyking ESCs in the 8S LiPo, 100A range :param max_power: maximum power [W] :returns: estimated ESC mass [kg] .. py:function:: mass_battery_pack(battery_capacity_Wh, battery_cell_specific_energy_Wh_kg=240, battery_pack_cell_fraction=0.7) Estimates the mass of a lithium-polymer battery. :param battery_capacity_Wh: Battery capacity, in Watt-hours [W*h] :param battery_cell_specific_energy: Specific energy of the battery at the CELL level [W*h/kg] :param battery_pack_cell_fraction: Fraction of the battery pack that is cells, by weight. * Note: Ed Lovelace, a battery engineer for Aurora Flight Sciences, gives this figure as 0.70 in a Feb. 2020 presentation for MIT 16.82 :returns: Estimated battery mass [kg] .. py:function:: mass_motor_electric(max_power, kv_rpm_volt=1000, voltage=20, method='hobbyking') Estimates the mass of a brushless DC electric motor. Curve fit to scraped Hobbyking BLDC motor data as of 2/24/2020. Estimated range of validity: 50 < max_power < 10000 :param max_power: maximum power [W] :type max_power: float :param kv_rpm_volt: Voltage constant of the motor, measured in rpm/volt, not rads/sec/volt! [rpm/volt] :type kv_rpm_volt: float :param voltage: Operating voltage of the motor [V] :type voltage: float :param method: method to use. "burton", "hobbyking", or "astroflight" (increasing level of detail). * Burton source: https://dspace.mit.edu/handle/1721.1/112414 * Hobbyking source: C:\Projects\GitHub\MotorScraper, * Astroflight source: Gates, et. al., "Combined Trajectory, Propulsion, and Battery Mass Optimization for Solar-Regen..." https://scholarsarchive.byu.edu/cgi/viewcontent.cgi?article=3932&context=facpub * Validity claimed from 1.5 kW to 15 kW, kv from 32 to 1355. :type method: str :returns: Estimated motor mass [kg] .. py:function:: mass_wires(wire_length, max_current, allowable_voltage_drop, material='aluminum', insulated=True, max_voltage=600, wire_packing_factor=1, insulator_density=1700, insulator_dielectric_strength=12000000.0, insulator_min_thickness=0.0002, return_dict = False) Estimates the mass of wires used for power transmission. Materials data from: https://en.wikipedia.org/wiki/Electrical_resistivity_and_conductivity#Resistivity-density_product All data measured at STP; beware, as this data (especially resistivity) can be a strong function of temperature. :param wire_length: Length of the wire [m] :type wire_length: float :param max_current: Max current of the wire [Amps] :type max_current: float :param allowable_voltage_drop: How much is the voltage allowed to drop along the wire? :type allowable_voltage_drop: float :param material: Conductive material of the wire ("aluminum"). Determines density and resistivity. One of: * "sodium" * "lithium" * "calcium" * "potassium" * "beryllium" * "aluminum" * "magnesium" * "copper" * "silver" * "gold" * "iron" :type material: str :param insulated: Should we add the mass of the wire's insulator coating? Usually you'll want to leave this True. :type insulated: bool :param max_voltage: Maximum allowable voltage (used for sizing insulator). 600 is a common off-the-shelf rating. :type max_voltage: float :param wire_packing_factor: What fraction of the enclosed cross section is conductor? This is 1 for solid wire, and less for stranded wire. :type wire_packing_factor: float :param insulator_density: Density of the insulator [kg/m^3] :type insulator_density: float :param insulator_dielectric_strength: Dielectric strength of the insulator [V/m]. The default value of 12e6 corresponds :type insulator_dielectric_strength: float :param to rubber.: :param insulator_min_thickness: Minimum thickness of the insulator [m]. This is essentially a gauge limit. :type insulator_min_thickness: float :param The default value is 0.2 mm.: :param return_dict: If True, returns a dictionary of all local variables. If False, just returns the wire :type return_dict: bool :param mass as a float. Defaults to False.: Returns: If `return_dict` is False (default), returns the wire mass as a single number. If `return_dict` is True, returns a dictionary of all local variables. .. py:data:: pows