Skip to content

Commit

Permalink
Added airfoil polar fit; blade element model
Browse files Browse the repository at this point in the history
  • Loading branch information
courtin committed Apr 5, 2018
1 parent 095f247 commit 7aee43c
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 34 deletions.
11 changes: 6 additions & 5 deletions gpkitmodels/GP/aircraft/motor/motor.py
@@ -1,7 +1,7 @@
"Electric motor model "
from numpy import pi
from gpkit import Model, parse_variables, SignomialsEnabled, SignomialEquality, units
from gpkitmodels.GP.aircraft.prop.propeller import Propeller
from gpkitmodels.GP.aircraft.prop.propeller import Actuator_Propeller, One_Element_Propeller
from gpkitmodels import g
from gpkitmodels.GP.aircraft.wing.wing_test import FlightState
import matplotlib.pyplot as plt
Expand All @@ -21,9 +21,9 @@ class ElecMotor_Performance(Model):
omega [rpm] propeller rotation rate
i [amps] current
v [V] woltage
i0 .1 [amps] zero-load current
Kv 100 [rpm/V] motor voltage constant
R .05 [ohms] internal resistance
i0 4.5 [amps] zero-load current
Kv 29 [rpm/V] motor voltage constant
R .033 [ohms] internal resistance
"""
def setup(self,parent, state):
exec parse_variables(ElecMotor_Performance.__doc__)
Expand Down Expand Up @@ -101,7 +101,8 @@ class Propulsor(Model):
def setup(self):
exec parse_variables(Propulsor.__doc__)

self.prop = Propeller()
#self.prop = Actuator_Propeller()
self.prop = One_Element_Propeller()
self.motor = ElecMotor()

components = [self.prop, self.motor]
Expand Down
32 changes: 24 additions & 8 deletions gpkitmodels/GP/aircraft/motor/motor_test.py
@@ -1,6 +1,6 @@
from gpkit import Model, parse_variables, SignomialsEnabled, SignomialEquality, units
from motor import Propulsor, ElecMotor, ElecMotor_Performance
from prop import Propeller
from gpkitmodels.GP.aircraft.prop.propeller import Actuator_Propeller
from gpkitmodels.GP.aircraft.wing.wing_test import FlightState

class Propulsor_Test(Model):
Expand All @@ -11,16 +11,17 @@ def setup(self):
fs = FlightState()
p = Propulsor()
pp = p.flight_model(p,fs)
pp.substitutions[pp.prop.T] = 50
self.cost = 1./pp.motor.etam + p.W/(10000000*units('lbf')) + 1./pp.prop.eta
pp.substitutions[pp.prop.T] = 100
#pp.substitutions[pp.prop.AR_b] = 15
self.cost = 1./pp.motor.etam + p.W/(1000*units('lbf')) + 1./pp.prop.eta

return fs,p,pp

def propulsor_test():

test = Propulsor_Test()
#sol = test.debug()
sol = test.solve()
sol = test.localsolve(iteration_limit = 400)
print sol.table()

class Motor_P_Test(Model):
Expand All @@ -47,21 +48,35 @@ def setup(self):
mp.substitutions[mp.v] = 6
self.cost = 1./mp.etam
return self.mp, fs
class hacker_q150_45_motor(Model):
def setup(self):
fs = FlightState()
m = ElecMotor()
mp = ElecMotor_Performance(m,fs)
self.mp = mp
mp.substitutions[m.Qmax] = 10000
mp.substitutions[mp.R] = .033
mp.substitutions[mp.i0] = 4.5
mp.substitutions[mp.Kv] = 29
self.cost = 1./mp.etam
return self.mp, fs

def speed_280_test():
test = speed_280_motor()
sol = test.solve()
print sol.table()




class graupner_cam_6x3(Model):
def setup(self):
self.fs = FlightState()
self.p = Propeller()

self.p.substitutions[self.p.R] = (3./12.) #Convert in to ft

return self.p, self.fs
return self.p, self.fs
class motorProp(Model):
def setup(self):
p = graupner_cam_6x3()
Expand All @@ -70,7 +85,8 @@ def setup(self):

p.fs.substitutions[p.fs.V] = 10

self.cost(1/p.)
self.cost(1/p.eta)




Expand Down Expand Up @@ -103,5 +119,5 @@ def test():
propulsor_test()

if __name__ == "__main__":
#test()
speed_280_test()
test()
#speed_280_test()
23 changes: 19 additions & 4 deletions gpkitmodels/GP/aircraft/prop/prop_test.py
@@ -1,19 +1,33 @@
" propelle tests "
from propeller import Propeller
from propeller import Actuator_Propeller
from propeller import One_Element_Propeller
from gpkit import units
#from qprop import QProp
from gpkitmodels.GP.aircraft.wing.wing_test import FlightState

def eta_test():

fs = FlightState()
p = Propeller()
pp = p.flight_model(fs)
p = Actuator_Propeller()
pp = p.flight_model(p,fs)
pp.substitutions[pp.T] = 100
pp.cost = 1/pp.eta + pp.Q/(100.*units("N*m"))
sol = pp.solve()
print sol.table()

def OE_eta_test():

fs = FlightState()
p = One_Element_Propeller()
pp = p.flight_model(p,fs)
pp.substitutions[pp.T] = 1000
#pp.substitutions[pp.omega] = 500
pp.substitutions[pp.AR_b] = 12
pp.cost = 1/pp.eta + pp.Q/(10.*units("N*m"))
sol = pp.localsolve()
#sol = pp.debug()
print sol.table()

#def qprop_test():
#
# fs = FlightState()
Expand All @@ -25,7 +39,8 @@ def eta_test():

def test():
"tests"
eta_test()
#eta_test()
OE_eta_test()
#qprop_test()

if __name__ == "__main__":
Expand Down
91 changes: 74 additions & 17 deletions gpkitmodels/GP/aircraft/prop/propeller.py
@@ -1,6 +1,10 @@
" propeller model "
from numpy import pi
from gpkit import Model, parse_variables, SignomialsEnabled, SignomialEquality
from gpkit.constraints.tight import Tight as TCS
from gpfit.fit_constraintset import XfoilFit
import os
import pandas as pd


class Actuator_Propeller_Performance(Model):
Expand Down Expand Up @@ -31,7 +35,7 @@ def helper(self, c):
return 2. - 1./c[self.etaadd]

def setup(self,parent, state):
exec parse_variables(Propeller_Performance.__doc__)
exec parse_variables(Actuator_Propeller_Performance.__doc__)

V = state.V
rho = state.rho
Expand Down Expand Up @@ -64,9 +68,9 @@ class Actuator_Propeller(Model):
T_m_static 40. [lbf] prop max static thrust
"""

flight_model = Propeller_Performance
flight_model = Actuator_Propeller_Performance
def setup(self):
exec parse_variables(Propeller.__doc__)
exec parse_variables(Actuator_Propeller.__doc__)

constraints = [W >= K*T_m_static*R**2]

Expand All @@ -80,7 +84,7 @@ class One_Element_Propeller_Performance(Model):
T [lbf] thrust
Tc [-] coefficient of thrust
etaadd 0.7 [-] swirl and nonuniformity losses
etav 0.85 [-] viscous losses
etav [-] viscous losses
etai [-] inviscid losses
eta [-] overall efficiency
z1 self.helper [-] efficiency helper 1
Expand All @@ -94,30 +98,83 @@ class One_Element_Propeller_Performance(Model):
P_shaft [kW] shaft power
M_tip .5 [-] Tip mach number
a 295 [m/s] Speed of sound at altitude
Wa [m/s] Axial total relative velocity
Wt [m/s] Tangential total relative velocity
W [m/s] Total relative velocity
va [m/s] Axial induced velocity
vt [m/s] Tangential induced velocity
F .1 [-] Prandtl tip loss factor
G [m^2/s] Circulation
c [m] local chord
cl [-] local lift coefficient
cd [-] local drag coefficient
B 2 [-] number of blades
r [m] local radius
lam_w [-] advance ratio
eps [-] blade efficiency
AR_b [-] blade aspect ratio
AR_b_max 18 [-] max blade aspect ratio
Ut [m/s] tangential freestreem
Re [-] blade reynolds number
"""

def helper(self, c):
return 2. - 1./c[self.etaadd]

def setup(self,parent, state):
exec parse_variables(Propeller_Performance.__doc__)
exec parse_variables(One_Element_Propeller_Performance.__doc__)

V = state.V
rho = state.rho
R = parent.R
mu = state.mu
path = os.path.dirname(__file__)
fd = pd.read_csv(path + os.sep + "dae51_fitdata.csv").to_dict(
orient="records")[0]

with SignomialsEnabled():
constraints = [TCS([eta == etav*etai]),
#Tc == T/(0.5*rho*V**2*pi*R**2),
#TCS([z2 >= Tc + 1]),
#SignomialEquality(z2,Tc + 1),
#SignomialEquality(etai*(z1 + z2**0.5/etaadd),2),
#TCS([etai*(z1 + z2**0.5/etaadd)<=2]),
#lam == V/(omega*R),
#TCS([CT == Tc*lam**2]),
#TCS([CP == Q*omega/(.5*rho*(omega*R)**3*pi*R**2)]),
#eta == CT*lam/CP,
omega <= omega_max,
P_shaft == Q*omega,
(M_tip*a)**2 >= Wa**2 + Wt**2,
SignomialEquality(Wa,V + va),
#TCS([Wa>=V + va]),
SignomialEquality(Wt,omega*r-vt),
#TCS([Wt<=omega*r-vt]),
SignomialEquality(W**2,(Wa**2+Wt**2)),
#TCS([W**2 >= (Wa**2+Wt**2)]),
Ut == omega*r,
TCS([G == (1./2.)*W*c*cl]),
r == 1.0*R,
#vt**2. >= (B*G/(4.*pi*r))**2*(1./(F**2.*(1.+(4.*lam_w*R/(pi*B*r))**2.))),
TCS([vt == (B*G/(4.*pi*r*F))]),
lam_w == (r/R)*(Wa/Wt),
va == vt*(Wt/Wa),
eps == cd/cl,
SignomialEquality(1,etav*(1+eps*Wt/Wa)+eps*Wa/Wt),
SignomialEquality(1,etai*(1+va/V)+vt/Ut),
#TCS([1 >= etav*(1+eps*Wt/Wa)+eps*Wt/Wa]),
#TCS([Q >= rho*B*G*(Wa+eps*Wt)*R**2]),
SignomialEquality(Q,rho*B*G*(Wa+eps*Wt)*R**2),
SignomialEquality(T,rho*B*G*(Wt-eps*Wa)*R),
eta == V*T/(omega*Q),

#TCS([T<=rho*B*G*(Wt-eps*Wa)*R]),
AR_b == R/c,
AR_b <= AR_b_max,
Re == V*c*rho/mu,
XfoilFit(fd, cd, [cl,Re], name="polar"),


constraints = [eta <= etav*etai,
Tc >= T/(0.5*rho*V**2*pi*R**2),
z2 >= Tc + 1,
etai*(z1 + z2**0.5/etaadd) <= 2,
lam >= V/(omega*R),
CT >= Tc*lam**2,
CP <= Q*omega/(.5*rho*(omega*R)**3*pi*R**2),
eta >= CT*lam/CP,
omega <= omega_max,
P_shaft == Q*omega,
(M_tip*a)**2 >= (omega*R)**2 + V**2

]
return constraints, state
Expand All @@ -135,7 +192,7 @@ class One_Element_Propeller(Model):

flight_model = One_Element_Propeller_Performance
def setup(self):
exec parse_variables(Propeller.__doc__)
exec parse_variables(One_Element_Propeller.__doc__)

constraints = [W >= K*T_m_static*R**2]

Expand Down

0 comments on commit 7aee43c

Please sign in to comment.