forked from 3660628/pycda
-
Notifications
You must be signed in to change notification settings - Fork 0
/
aircraft.py
276 lines (238 loc) · 9.01 KB
/
aircraft.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
#Ref: http://www.princeton.edu/~stengel/FDcodeB.html
#This file contains aicrafts which can be imported in the flightdynamics model
#Data Structure
#Aicraft
# function: _inertial, define inertia related parameters
# function: _geometry, define geometry related parameters
# function: _calcmach, calculate mach parameters
# function: _CL, calculate CL
# function: _CD, calculate CD
# function: _Cm, calculate Cm
# function: _CY, calculate CY
# function: _Cn, calculate Cn
# function: _Cl, calculate Cl
# function: thrust, calculate thrust
# function: _calc
# -> call: _calcmach, _CL, _CD, _Cm, _CY, _Cn, _Cl and thrust in order
#Note: Once initialized only _calc function need to be called from flight dynamics model,
# at every time step, just before calculating the derivative. After calling the fun-
# ction, value of aircraft parameters are automatically updated which can be used for
# calculataions.
from misc import sign, atmosphere, transformation
from numpy import pi,sqrt,cos,sin, arctan, arcsin, array, exp, zeros, matrix, linspace, arange
from pylab import plot, legend, figure, subplot
degtorad = pi/180
radtodeg = 1/degtorad
class Aircraft:
"""Base class of aircraft, contains aircraft parameters and functions to estimates them.
Parameters
----------
gear <type: bool> : True if gear down, else False
spoilers <type: bool> : True if spoilers deployed, else False
flaps <type: bool> : True if flaps deployed, else False
m <type: float> : Mass
Ixx <type: float> : Moment of Inertia about x axis
Iyy <type: float> : Moment of Inertia about y axis
Izz <type: float> : Moment of Inertia about z axis
Ixz <type: float> : Moment of Inertia about xz axis
c <type: float> : Chord (m)
b <type: float> : Span (m)
S <type: float> : Reference Area (m^2)
ARw <type: float> : Wing Aspect ratio
taperw <type: float> : Wing Taper ratio
sweepw <type: float> : Wing Sweep in rad
ARh <type: float> : H-Tail Aspect ratio
sweeph <type: float> : H-Tail Sweep in rad
ARv <type: float> : V-Tail Aspect ratio
sweepv <type: float> : V-Tail Sweep in rad
lvt <type: float> : V-Tail length
Ts <type: float> : Dry Thrust
CL <type: float> : Coeff of Lift
CD <type: float> : Coeff of Drag
Cm <type: float> : Coeff of Moment
CY <type: float> : Coeff of side force
Cn <type: float> : Coeff of Moment
Cl <type: float> : Coeff of Moment
thrust <type: float> : Thrust (N)
"""
def __init__(self):
self.gear = True #True->down
self.spoilers = True #True->open
self.flaps = True #True->open
self._inertial()
self._geometry()
def _inertial(self):
self.m = 4536.0 #Kg
self.Ixx = 35926.5 #Kg-m2
self.Iyy = 33940.7 #Kg-m2
self.Izz = 67085.5 #Kg-m2
self.Ixz = 3418.17 #Kg-m2
def _geometry(self):
self.c = 2.14 #m
self.b = 10.4 #m
self.S = 21.5 #m2
self.ARw = 5.02
self.taperw = 0.507
self.sweepw = 13*degtorad #rad
self.ARh = 4.0
self.sweeph = 25*degtorad #rad
self.ARv = 0.64
self.sweepv = 40*degtorad #rad
self.lvt = 4.72 #m
self.Ts = 26243.2 #N
def _calcmach(self, Mach):
self.prfac=1 / (sqrt(1 - Mach**2) * 1.015)
self.wingmach = 1 / ((1 + sqrt(1 + ((self.ARw/(2 * cos(self.sweepw)))**2) \
* (1 - Mach*Mach * cos(self.sweepw)))) * 0.268249)
self.htailmach = 1 / ((1 + sqrt(1 + ((self.ARh/(2 * cos(self.sweeph)))**2) \
* (1 - Mach*Mach * cos(self.sweeph)))) * 0.294539);
self.vtailmach = 1 / ((1 + sqrt(1 + ((self.ARv/(2 * cos(self.sweepv)))**2) \
* (1 - Mach*Mach * cos(self.sweepv)))) * 0.480338);
def _CL(self, V,alpha,q,stab,deltae):
Clo = 0.1095
if self.gear:
Clo -= 0.0192
if self.flaps:
Clo += 0.5182
if self.spoilers:
Clo -= 0.1897
CLa = 5.6575
if self.flaps:
CLa -= 0.0947
CLq = 4.231*self.c/(2*V)
CLs = 1.08
if self.flaps:
CLs -= 0.4802
CLe = .5774
if self.flaps:
CLe -= 0.2665
self.CL = Clo + (CLa*alpha + CLq*q + CLs*stab + CLe*deltae)*self.wingmach
def _CD(self):
CDo = 0.0255
if self.gear:
CDo += 0.0191
if self.flaps:
CDo += 0.0836
if self.spoilers:
CDo += 0.0258
epsilon = 0.0718
if self.flaps:
epsilon = 0.079
self.CD = CDo*self.prfac + epsilon*self.CL*self.CL
def _Cm(self, V, alpha, p, q, deltae):
cmo = 0.0
if self.gear:
cmo += 0.0255
if self.flaps:
cmo -= 0.058
if self.spoilers:
cmo -= 0.0154
cmar = -1.231
if self.flaps:
cmar += 0.0138
cmqr = -18.8*self.c/(2*V)
cmdsr = -2.291
if self.flaps:
cmdsr += 0.121
cmder = -1.398
if self.flaps:
cmder += 0.149
self.Cm = cmo + (cmar*alpha + cmqr*q + cmdsr*p + cmder*deltae)*self.htailmach
def _CY(self, beta, rudder, aileron, spoiler):
cybr = -0.7162
if self.flaps:
cybr += 0.0826
cydar = -0.00699
cydrr = 0.1574
if self.flaps:
cydrr -= 0.0093
cydasr = 0.0264
if self.flaps:
cydasr == 0.0766
self.CY = (cybr*beta + cydrr*rudder)*self.vtailmach + (cydar*aileron + cydasr*spoiler )*self.wingmach
def _Cn(self, beta, V, r, p, aileron, rudder, spoiler):
cnbr = 0.1194
if self.flaps:
cnbr -= 0.0092
cnpr = self.CL*(1+3*self.taperw)/(12*(1+self.taperw))*(self.b/(2*V))
cnrr = (-2*(self.lvt/self.b)*cnbr*self.vtailmach - 0.1*self.CL*self.CL)*(self.b/(2*V))
cndar = 0.0
if self.flaps:
cndar += 0.0028
cndrr = -0.0713
if self.flaps:
cndrr -= 0.0185
cndasr = -0.0088
if self.flaps:
cndasr -= 0.0106
self.Cn = (cnbr*beta + cndrr*rudder)*self.vtailmach + cnrr*r + cnpr*p \
+ (cndar*aileron + cndasr*spoiler)*self.wingmach
def _Cl(self, beta,p,r,spoiler,rudder,aileron, V, Mach):
clbr = -0.0918
if self.flaps:
clbr -= 0.0092
clar = 5.6575
if self.flaps:
clar -= 0.0947
clpr = -clar*(1+3*self.taperw)/(12*(1+self.taperw))*(self.b/(2*V))
clrr = (self.CL*(1+3*self.taperw)/(12*(1+self.taperw))*((Mach*cos(self.sweepw))**2-2)/((Mach*cos(self.sweepw))**2-1))*(self.b/(2*V))
cldar = 0.1537
if self.flaps:
cldar += 0.01178
cldrr = 0.01208
if self.flaps:
cldrr += 0.01115
cldasr = -0.01496
if self.flaps:
cldasr -= 0.02376
self.Cl = (clbr*beta+cldrr*rudder)*self.vtailmach + clrr*r + clpr*p + \
(cldar*aileron+cldasr*spoiler)*self.wingmach
def _thrust(self,throttle, rho, h):
self.thrust = throttle*self.Ts*((rho/1.225)**.7)*(1-exp((h-17000)/2000.0))
def _calc(self, Va, x, u):
"""
V: velocity
x: state vector
u: input vector
"""
#Calc Atmospheric Parameters
R = 287.0
gamma = 1.4
#Va = [50.0,0.0,0.0]
V = sqrt(Va[0]**2+Va[1]**2+Va[2]**2)
alpha = arctan(Va[2]/Va[0])
beta = arcsin(Va[1]/V)
#u = array([0.0,0.0,0.0,0.0,0.0,0.0,0.0])
#x = array([V*cos(alpha)*cos(beta),V*sin(beta),V*sin(alpha)*cos(beta),0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0])
elevator = u[0]
aileron = u[1]
rudder = u[2]
throttle = u[3]
spoiler = u[4]
flap = u[5]
stab = u[6]
if flap >= 0.65:
self.flaps = True
else:
self.flaps = False
self.gear = False
self.spoilers = False
height = -x[5]
T,P = atmosphere(height)
rho = P/(R*T)
a = sqrt(gamma*R*T)
p = x[6]
q = x[7]
r = x[8]
#Calc Mach
Mach = V/a
self._calcmach(Mach)
self._thrust(throttle, rho, height)
self._CL(V, alpha, q, stab, elevator)
self._CD()
self._Cm(V, alpha, p, q, elevator)
self._CY(beta, rudder, aileron, spoiler)
self._Cn(beta, V, r, p, aileron, rudder, spoiler)
self._Cl(beta, p, r, spoiler, rudder, aileron, V, Mach)
class SmallBussinessJet(Aircraft):
pass