forked from FernFCT/Model
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
27ad916
commit 051cabb
Showing
8 changed files
with
247 additions
and
0 deletions.
There are no files selected for viewing
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import numpy as np | ||
from openmdao.api import ExplicitComponent | ||
|
||
class ThrustWeightComp(ExplicitComponent): | ||
|
||
def setup(self): | ||
self.add_input('G',desc = 'climb gradient') | ||
self.add_input('n',desc = 'load factor') | ||
self.add_input('e',desc = 'oswald efficieny') | ||
self.add_input('AR',desc = 'aspect ratio') | ||
self.add_input('cd0',desc = 'parasitic drag') | ||
self.add_input('rho',desc = 'density') | ||
self.add_input('W_S',desc = 'Wing Loading') | ||
self.add_input('Vc',desc = 'Cruise Speed') | ||
|
||
self.add_output('T_W_climb',desc = 'Thrust-to-Weight ratio climb') | ||
self.add_output('T_W_cruise',desc = 'Thrust-to-Weight ratio cruise') | ||
self.add_output('T_W_maneuver',desc = 'Thrust-to-Weight ratio maneuver') | ||
|
||
self.declare_partials(of = '*', wrt = '*', method = 'cs') | ||
|
||
def compute(self,inputs,outputs): | ||
q = 0.5*inputs['rho']*inputs['Vc']*inputs['Vc'] | ||
twclimb = inputs['G'] + (inputs['W_S']/(np.pi*inputs['e']*inputs['AR']*q)) + (inputs['cd0']*q/(inputs['W_S'])) | ||
cl = 2*inputs['W_S']/(inputs['rho']*inputs['Vc']*inputs['Vc']) | ||
cd = inputs['cd0'] + (1/(np.pi*inputs['e']*inputs['AR']))*cl*cl | ||
twcruise = (cl/cd)**(-1) | ||
twmaneuver = (inputs['cd0']*q/(inputs['W_S'])) + (inputs['n']*inputs['n'])*(inputs['W_S']/(np.pi*inputs['e']*inputs['AR']*q)) | ||
|
||
outputs['T_W_climb'] = twclimb | ||
outputs['T_W_cruise'] = twcruise | ||
outputs['T_W_maneuver'] = twmaneuver |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
from openmdao.api import ExplicitComponent | ||
import numpy as np | ||
|
||
class EmptyWeightComp(ExplicitComponent): | ||
# Coefficients | ||
|
||
|
||
def setup(self): | ||
self.add_input('AR',desc='aspect ratio') | ||
#self.add_input('Wb',desc='battery weight') | ||
self.add_input('V',desc='cruise speed') | ||
self.add_input('Neg',desc='number of engines') | ||
self.add_input('W0',desc='gross weight') | ||
self.add_input('Np',desc='number of people') | ||
|
||
self.declare_partials(of='*', wrt='*', method='cs') | ||
self.add_output('We',desc='empty weight') | ||
|
||
|
||
def compute(self, inputs, outputs): | ||
|
||
#Wb = inputs['Wb']*2.205 | ||
AR = inputs['AR'] | ||
Np = inputs['Np'] | ||
V = inputs['V']*3.281 # convert to american | ||
t_c = 0.12 # thickness to chord ratio | ||
L_f = 21.33 # Fuselage structural length [ft] | ||
Lm = 5 # lenth of main landing gear [in] | ||
Neg = inputs['Neg'] # number of engines | ||
Nl = 1 # ultimate landing gear factor | ||
Nz = 3.9 # ultimate load factor | ||
q = 0.5*0.002377*(V**2) # dynamic pressure at cruise | ||
Sf = 362.744 # fuselage wetted area | ||
Sw = 142.233 # trapezoidal wing area | ||
Wdg = inputs['W0']*2.2046 # gross weight | ||
Wen = 110 # engine weight each [lb] | ||
Wl = Wdg # langing gross weight | ||
#Wuav = 800 # usual 800-1400 | ||
M = V/1116.13 # mach | ||
L_D = 15.35 # lift over drag | ||
B_w = 31.5 # wing span | ||
|
||
#wing | ||
W_w = 0.036*(Sw**0.758)*(AR**0.86)*(q**0.006)*((100*t_c)**(-0.3))*((Nz*Wdg)**0.49) | ||
# fuselage | ||
W_f = 0.052*(Sf**1.086)*((Nz*Wdg)**0.22)*(L_f**(-0.051))*((L_D)**(-0.072))*(q**0.241) | ||
# landing gear | ||
W_lg = 0.095*((Nl*Wl)**0.768)*((Lm/12)**0.845) | ||
# installed engine | ||
W_ie = 2.575*(Wen**0.922)*(Neg) | ||
# flight controls | ||
W_fc = 0.053*(L_f**1.536)*(B_w**0.371)*((Nz*Wdg*10**(-4))**0.8) | ||
# hydraulics | ||
W_h = 0.001*Wdg | ||
# avionics | ||
W_av = 33 # vahana avionics = 15 kg = 33.069 lb | ||
# electrical | ||
W_el = 12.57*(W_av)**0.51 | ||
# air conditioning | ||
W_ac = 0.265*Wdg**0.52*Np**0.68*W_av**0.17*M**0.08 | ||
# furnishings | ||
W_fur = 0.0582*Wdg - 65 | ||
# actuators | ||
# 12 actuators, 0.65 kg each | ||
W_act = 12*1.43 | ||
|
||
We = 0.8*(W_w + W_f + W_lg + W_ie + W_fc + W_h + W_av + W_el + W_ac + W_fur + W_act)/2.205 | ||
#print('weight',We) | ||
outputs['We'] = We # outputs kg | ||
|
||
|
||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
# Estimate tooling cost of a vehicle by summing tooling costs for all major | ||
# components | ||
# | ||
# Inputs: | ||
# rProp - Prop/rotor radius [m] | ||
# cruiseOutput - Structure with cruise performance data | ||
# | ||
# Outputs: | ||
# toolCostPerVehicle - Estimate of tool cost per vehicle [$] | ||
# | ||
# Functions Called: | ||
# toolingCost.m | ||
|
||
#function toolCostPerVehicle = costBuildup(rProp,cruiseOutput) | ||
import numpy as np | ||
from ToolingCost import ToolingCost | ||
|
||
def CostBuildup(r_prop,c_ref, b_ref): | ||
# Inputs | ||
fuselage_width = 1 | ||
fuselage_length = 5 | ||
toc = 0.15 # Wing / canard thickness | ||
prop_radius = r_prop | ||
prop_chord = 0.15 * prop_radius | ||
x_hinge = 0.8 | ||
winglet = 0.2 | ||
|
||
parts_per_tool = 1000 | ||
|
||
fuselage_height = 1.3 # Guess | ||
span = b_ref | ||
chord = c_ref | ||
|
||
# tool_cost_per_vechile = 100 # used as test value | ||
|
||
# Wing Tooling | ||
wing_tool_cost = np.array([0, 0, 0, 0]) | ||
wing_tool_cost[0] = ToolingCost((span - fuselage_width)/2, toc*chord, chord*0.2) # Leading Edge | ||
wing_tool_cost[1] = ToolingCost((span - fuselage_width)/2, toc*chord*0.7, chord*0.2) # Aft spar | ||
wing_tool_cost[2] = ToolingCost((span - fuselage_width)/2, chord*0.75, 0.02)*2 # Upper/Lower skin | ||
wing_tool_cost[3] = ToolingCost(span, toc*chord, chord*.20) # Forward spar | ||
wing_tool_cost = 2*(2*sum(wing_tool_cost[0:3])+wing_tool_cost[3]) # Total wing tooling cost (matched tooling) | ||
|
||
# Winglet Tooling | ||
winglet_tool_cost = np.array([0, 0, 0, 0]) | ||
winglet_tool_cost[0] = ToolingCost(winglet*span/2, toc*chord, chord*.2) # Leading edge | ||
winglet_tool_cost[1] = ToolingCost(winglet*span/2,toc*chord*0.7,chord*.2) # Aft spar | ||
winglet_tool_cost[2] = ToolingCost(winglet*span/2,chord*0.75,0.02)*2 # Upper/Lower skin | ||
winglet_tool_cost[3] = ToolingCost(winglet*span/2,toc*chord,chord*.20) # Forward spar | ||
winglet_tool_cost = 4*sum(winglet_tool_cost) # Total winglet tooling cost (matched tooling) | ||
|
||
# Canard Tooling | ||
canard_tool_cost = wing_tool_cost # Total canard tooling cost | ||
|
||
# Fuselage Tooling | ||
fuselage_tool_cost = np.array([0, 0, 0, 0]) | ||
fuselage_tool_cost[0] = ToolingCost(fuselage_length*.8,fuselage_height,fuselage_width/2)*2 # Right/Left skin | ||
fuselage_tool_cost[1] = ToolingCost(fuselage_length*.8,fuselage_width/2,fuselage_height/4) # Keel | ||
fuselage_tool_cost[2] = ToolingCost(fuselage_width,fuselage_height,0.02)*2 # Fwd/Aft Bulkhead | ||
fuselage_tool_cost[3] = ToolingCost(fuselage_length*.1,fuselage_width,fuselage_height/3) # Nose/Tail cone | ||
fuselage_tool_cost = 2*sum(fuselage_tool_cost) # Total fuselage tooling cost (matched tooling) | ||
|
||
# Prop Tooling | ||
prop_tool_cost = np.array([0, 0]) | ||
prop_tool_cost[0] = ToolingCost(prop_radius,prop_chord,prop_chord*toc/2)*2 # Skin | ||
prop_tool_cost[1] = ToolingCost(prop_radius,prop_chord*toc,prop_chord/4)*2 # Spar tool | ||
prop_tool_cost = 4*sum(prop_tool_cost) # Total propeller tooling cost (left/right hand) (matched tooling) | ||
|
||
# Control Surface (2 tools) | ||
control_tool_cost = np.array([0, 0]) | ||
control_tool_cost[0] = ToolingCost((span-fuselage_width)/2,(1-x_hinge)*chord,chord*toc/4) # Skin | ||
control_tool_cost[1] = ToolingCost((span-fuselage_width)/2,(1-x_hinge)*chord,chord*toc/4) # Skin | ||
control_tool_cost = 8*sum(control_tool_cost) # Total wing tooling (matched tooling) | ||
|
||
# Total tool cost | ||
total_tool_cost = wing_tool_cost + canard_tool_cost + fuselage_tool_cost + prop_tool_cost + control_tool_cost + winglet_tool_cost | ||
|
||
tool_cost_per_vechile = total_tool_cost / parts_per_tool | ||
|
||
return tool_cost_per_vechile |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
# Estimates tooling cost based on part dimensions including material, rough | ||
# machining, and finishing machining | ||
# | ||
# Inputs: | ||
# length - part length [m] | ||
# width - part width [m] | ||
# depth - part depth [m] | ||
# | ||
# Output: | ||
# cost - Tool cost [$] | ||
# | ||
import math | ||
|
||
def ToolingCost(length, width, depth): | ||
# Material | ||
tool_side_offset = 0.09 # Offset on each side of tool | ||
tool_depth_offset = 0.03 # Offset at bottom of tool | ||
tool_cost = 10000 # Cost be m^3 of tooling material [$/m^3] | ||
|
||
tool_volume = (length + 2 * tool_side_offset) * (width + 2 * tool_side_offset) * (depth + tool_depth_offset) | ||
material_cost = tool_cost * tool_volume # Tooling material costs | ||
|
||
# Machining (Rough Pass) | ||
rough_SFM = 200 # Roughing surface feet per minute | ||
rough_FPT = 0.003 # Roughing feed per tooth [in] | ||
rough_cost_rate = 150/3600 # Cost to rough [$/s] | ||
rough_bit_diam = 0.05 # Rougher diameter [m] | ||
|
||
rough_bit_depth = rough_bit_diam/4 # Rougher cut depth [m] | ||
rough_RPM = 3.82 * rough_SFM / (39.37 * rough_bit_diam) # Roughing RPM | ||
rough_feed = rough_FPT * rough_RPM * 2 * 0.00042 # Roughing Feed [m/s] | ||
rough_bit_step = 0.8 * rough_bit_diam # Rougher step size | ||
|
||
cut_volume = length * math.pi * depth * width / 4 # Amount of material to rough out | ||
rough_time = cut_volume / (rough_feed * rough_bit_step * rough_bit_depth) # Time for roughing | ||
rough_cost = rough_time * rough_cost_rate # Roughing cost | ||
|
||
# Machining (Finish Pass) | ||
finish_SFM = 400 # Roughing surface feet per minute | ||
finish_FPT = 0.004 # Roughing feed per tooth [in] | ||
finish_cost_rate = 175/3600 # Cost to finish [$/s] | ||
finish_bit_diam = 0.006 # Finish diameter [m] | ||
finish_passes = 5 # Number of surface passes | ||
|
||
finish_RPM = 3.82 * finish_SFM / (39.37 * finish_bit_diam) # Roughing RPM | ||
finish_feed = finish_FPT * finish_RPM * 2 * 0.00042 # Roughing Feed [m/s] | ||
|
||
def EllipsePerimeter(a, b): | ||
h = (a - b)**2 / (a + b)**2 | ||
p = math.pi*(a+b)*(1+3*h/(10+(4-3*h)**0.5)) | ||
return p | ||
|
||
finish_bit_step = 0.8 * finish_bit_diam # Rougher step size | ||
cut_area = length * EllipsePerimeter(width/2,depth)/2; # Amount of material to rough out | ||
finish_time = cut_area / (finish_feed * finish_bit_step) * finish_passes; # Time for roughing | ||
finish_cost = finish_time * finish_cost_rate; # Roughing cost | ||
|
||
# Total Cost | ||
cost = material_cost + rough_cost + finish_cost | ||
|
||
return cost |