*ARCHIVED* development moved to aircraft-studio.
start work
Changed files
creator.py
@@ -53,14 +53,9 @@
53
53
self.area = float()
54
54
# Component material
55
55
self.material = str()
56
Removed:
# Upper coordinates
57
Removed:
self.x_u = []
58
Removed:
self.z_u = []
59
Removed:
# Lower coordinates
60
Removed:
self.x_l = []
61
Removed:
self.z_l = []
62
Removed:
# Coordinates x_u, z_u, x_l, z_l packed in single list
63
Removed:
self.coord = []
56
Added:
# Coordinates
57
Added:
self.x = []
58
Added:
self.z = []
64
59
65
60
# The airfoil components know the Coordinates instance's coords
66
61
global parent
@@ -85,10 +80,8 @@
85
80
print('Semi-span:', self.semi_span)
86
81
print('Mass:', self.mass)
87
82
print(num_of_dashes * '-')
88
Removed:
print('x_u the upper x-coordinates:\n', np.around(self.x_u, round))
89
Removed:
print('z_u the upper z-coordinates:\n', np.around(self.z_u, round))
90
Removed:
print('x_l the lower x-coordinates:\n', np.around(self.x_l, round))
91
Removed:
print('z_l the lower z-coordinates:\n', np.around(self.z_l, round))
83
Added:
print('x-coordinates:\n', np.around(self.x, round))
84
Added:
print('z-coordinates:\n', np.around(self.z, round))
92
85
return None
93
86
94
87
def info_save(self, save_path, number):
@@ -182,14 +175,14 @@
182
175
return theta
183
176
184
177
def get_upper_coord(x):
185
Removed:
x_u = x - get_thickness(x) * sin(get_theta(x))
186
Removed:
z_u = get_camber(x) + get_thickness(x) * cos(get_theta(x))
187
Removed:
return (x_u, z_u)
178
Added:
x = x - get_thickness(x) * sin(get_theta(x))
179
Added:
z = get_camber(x) + get_thickness(x) * cos(get_theta(x))
180
Added:
return (x, z)
188
181
189
182
def get_lower_coord(x):
190
Removed:
x_l = x + get_thickness(x) * sin(get_theta(x))
191
Removed:
z_l = get_camber(x) - get_thickness(x) * cos(get_theta(x))
192
Removed:
return (x_l, z_l)
183
Added:
x = x + get_thickness(x) * sin(get_theta(x))
184
Added:
z = get_camber(x) - get_thickness(x) * cos(get_theta(x))
185
Added:
return (x, z)
193
186
194
187
# Densify x-coordinates 10 times for first 1/4 chord length
195
188
x_chord_25_percent = round(self.chord / 4)
@@ -200,10 +193,13 @@
200
193
for x in x_chord:
201
194
self.x_c.append(x)
202
195
self.y_c.append(get_camber(x))
203
Removed:
self.x_u.append(get_upper_coord(x)[0])
204
Removed:
self.z_u.append(get_upper_coord(x)[1])
205
Removed:
self.x_l.append(get_lower_coord(x)[0])
206
Removed:
self.z_l.append(get_lower_coord(x)[1])
196
Added:
self.x.append(get_upper_coord(x)[0])
197
Added:
self.z.append(get_upper_coord(x)[1])
198
Added:
# Behold the true power of Python list slicing!
199
Added:
# (This special list index reverses the list.)
200
Added:
for x in x_chord[::-1]:
201
Added:
self.x.append(get_lower_coord(x)[0])
202
Added:
self.z.append(get_lower_coord(x)[1])
207
203
return None
208
204
209
205
def add_mass(self, mass):
@@ -211,8 +207,8 @@
211
207
212
208
def info_print(self, round):
213
209
super().info_print(round)
214
Removed:
print('x_c the camber x-coordinates:\n', np.around(self.x_u, round))
215
Removed:
print('z_c the camber z-coordinates:\n', np.around(self.x_u, round))
210
Added:
print('x_c the camber x-coordinates:\n', np.around(self.x, round))
211
Added:
print('z_c the camber z-coordinates:\n', np.around(self.x, round))
216
212
return None
217
213
218
214
@@ -223,12 +219,12 @@
223
219
def __init__(self):
224
220
super().__init__(parent.chord, parent.semi_span)
225
221
226
Removed:
def add_coord(self, airfoil, spar_x):
222
Added:
def add_coord(self, airfoil, x_loc_percent):
227
223
'''
228
224
Add a single spar at the % chord location given to function.
229
225
230
226
Parameters:
231
Removed:
coordinates: provided by Airfoil.coordinates[x_u, z_u, x_l, z_l].
227
Added:
coordinates: provided by Airfoil.coordinates[x, z, x, z].
232
228
material: spar's material. Assumes homogeneous material.
233
229
spar_x: spar's location as a % of total chord length.
234
230
@@ -237,21 +233,22 @@
237
233
'''
238
234
# Airfoil surface coordinates
239
235
# unpacked from 'coordinates' (list of lists in 'Coordinates').
240
Removed:
x_u = airfoil.x_u
241
Removed:
z_u = airfoil.z_u
242
Removed:
x_l = airfoil.x_l
243
Removed:
z_l = airfoil.z_l
236
Added:
x = airfoil.x
237
Added:
z = airfoil.z
244
238
# Scaled spar location with regards to chord
245
Removed:
loc = spar_x * self.chord
246
Removed:
# bisect_left: returns index of first value in x_u > loc.
247
Removed:
# Ensures that the spar coordinates intersect with airfoil surface.
248
Removed:
spar_x_u = bi.bisect_left(x_u, loc) # index of spar's x_u
249
Removed:
spar_x_l = bi.bisect_left(x_l, loc) # index of spar's x_l
239
Added:
loc = x_loc_percent * self.chord
240
Added:
# bisect_left: returns index of first value in x > loc
241
Added:
# starting from [0]
242
Added:
# bisect_right: returns index of first value in x > loc
243
Added:
# starting from [-1] (last list element).
244
Added:
# This ensures that the spar geom intersects with airfoil geom.
245
Added:
spar_x = bi.bisect_left(x, loc) # index of spar's x
246
Added:
spar_x = bi.bisect_left(x, loc) # index of spar's x
250
247
# These x and y coordinates are assigned to the spar, NOT airfoil.
251
Removed:
self.x_u.append(x_u[spar_x_u])
252
Removed:
self.z_u.append(z_u[spar_x_u])
253
Removed:
self.x_l.append(x_l[spar_x_l])
254
Removed:
self.z_l.append(z_l[spar_x_l])
248
Added:
self.x.append(x[spar_x])
249
Added:
self.z.append(z[spar_x])
250
Added:
self.x.append(x[spar_x])
251
Added:
self.z.append(z[spar_x])
255
252
return None
256
253
257
254
def add_spar_caps(self, spar_cap_area):
@@ -259,7 +256,7 @@
259
256
return None
260
257
261
258
def add_mass(self, mass):
262
Removed:
self.mass = len(self.x_u) * mass
259
Added:
self.mass = len(self.x) * mass
263
260
return None
264
261
265
262
@@ -291,44 +288,44 @@
291
288
'''
292
289
293
290
# Find distance between leading edge and first upper stringer
294
Removed:
interval = airfoil.spar.x_u[0] / (stringer_u_1 + 1)
295
Removed:
# initialise first self.stringer_x_u at first interval
291
Added:
interval = airfoil.spar.x[0] / (stringer_u_1 + 1)
292
Added:
# initialise first self.stringer_x at first interval
296
293
x = interval
297
294
# Add upper stringers from leading edge until first spar.
298
295
for _ in range(0, stringer_u_1):
299
Removed:
# Index of the first value of airfoil_x_u > x
300
Removed:
index = bi.bisect_left(airfoil.x_u, x)
301
Removed:
self.x_u.append(airfoil.x_u[index])
302
Removed:
self.z_u.append(airfoil.z_u[index])
296
Added:
# Index of the first value of airfoil_x > x
297
Added:
index = bi.bisect_left(airfoil.x, x)
298
Added:
self.x.append(airfoil.x[index])
299
Added:
self.z.append(airfoil.z[index])
303
300
x += interval
304
301
# Add upper stringers from first spar until last spar
305
302
# TODO: stringer placement if only one spar is created
306
Removed:
interval = (airfoil.spar.x_u[-1]
307
Removed:
- airfoil.spar.x_u[0]) / (stringer_u_2 + 1)
308
Removed:
x = interval + airfoil.spar.x_u[0]
303
Added:
interval = (airfoil.spar.x[-1]
304
Added:
- airfoil.spar.x[0]) / (stringer_u_2 + 1)
305
Added:
x = interval + airfoil.spar.x[0]
309
306
for _ in range(0, stringer_u_2):
310
Removed:
index = bi.bisect_left(airfoil.x_u, x)
311
Removed:
self.x_u.append(airfoil.x_u[index])
312
Removed:
self.z_u.append(airfoil.z_u[index])
307
Added:
index = bi.bisect_left(airfoil.x, x)
308
Added:
self.x.append(airfoil.x[index])
309
Added:
self.z.append(airfoil.z[index])
313
310
x += interval
314
311
315
312
# Find distance between leading edge and first lower stringer
316
Removed:
interval = airfoil.spar.x_l[0] / (stringer_l_1 + 1)
313
Added:
interval = airfoil.spar.x[0] / (stringer_l_1 + 1)
317
314
x = interval
318
315
# Add lower stringers from leading edge until first spar.
319
316
for _ in range(0, stringer_l_1):
320
Removed:
index = bi.bisect_left(airfoil.x_l, x)
321
Removed:
self.x_l.append(airfoil.x_l[index])
322
Removed:
self.z_l.append(airfoil.z_l[index])
317
Added:
index = bi.bisect_left(airfoil.x, x)
318
Added:
self.x.append(airfoil.x[index])
319
Added:
self.z.append(airfoil.z[index])
323
320
x += interval
324
321
# Add lower stringers from first spar until last spar
325
Removed:
interval = (airfoil.spar.x_l[-1]
326
Removed:
- airfoil.spar.x_l[0]) / (stringer_l_2 + 1)
327
Removed:
x = interval + airfoil.spar.x_l[0]
322
Added:
interval = (airfoil.spar.x[-1]
323
Added:
- airfoil.spar.x[0]) / (stringer_l_2 + 1)
324
Added:
x = interval + airfoil.spar.x[0]
328
325
for _ in range(0, stringer_l_2):
329
Removed:
index = bi.bisect_left(airfoil.x_l, x)
330
Removed:
self.x_l.append(airfoil.x_l[index])
331
Removed:
self.z_l.append(airfoil.z_l[index])
326
Added:
index = bi.bisect_left(airfoil.x, x)
327
Added:
self.x.append(airfoil.x[index])
328
Added:
self.z.append(airfoil.z[index])
332
329
x += interval
333
330
return None
334
331
@@ -337,7 +334,7 @@
337
334
return None
338
335
339
336
def add_mass(self, mass):
340
Removed:
self.mass = len(self.x_u) * mass + len(self.x_l) * mass
337
Added:
self.mass = len(self.x) * mass + len(self.x) * mass
341
338
return None
342
339
343
340
def info_print(self, round):
@@ -361,34 +358,34 @@
361
358
'-.', color='r', linewidth='2',
362
359
label='Mean camber line')
363
360
# Plot upper surface
364
Removed:
plt.plot(airfoil.x_u, airfoil.z_u,
361
Added:
plt.plot(airfoil.x, airfoil.z,
365
362
'', color='b', linewidth='1')
366
363
# Plot lower surface
367
Removed:
plt.plot(airfoil.x_l, airfoil.z_l,
364
Added:
plt.plot(airfoil.x, airfoil.z,
368
365
'', color='b', linewidth='1')
369
366
370
367
# Plot spars
371
Removed:
for _ in range(0, len(airfoil.spar.x_u)):
372
Removed:
x = (airfoil.spar.x_u[_], airfoil.spar.x_l[_])
373
Removed:
y = (airfoil.spar.z_u[_], airfoil.spar.z_l[_])
368
Added:
for _ in range(0, len(airfoil.spar.x)):
369
Added:
x = (airfoil.spar.x[_], airfoil.spar.x[_])
370
Added:
y = (airfoil.spar.z[_], airfoil.spar.z[_])
374
371
plt.plot(x, y, '.-', color='b')
375
372
376
373
# Plot upper stringers
377
Removed:
for _ in range(0, len(airfoil.stringer.x_u)):
378
Removed:
x = airfoil.stringer.x_u[_]
379
Removed:
y = airfoil.stringer.z_u[_]
374
Added:
for _ in range(0, len(airfoil.stringer.x)):
375
Added:
x = airfoil.stringer.x[_]
376
Added:
y = airfoil.stringer.z[_]
380
377
plt.plot(x, y, '.', color='y', markersize=12)
381
378
# Plot lower stringers
382
Removed:
for _ in range(0, len(airfoil.stringer.x_l)):
383
Removed:
x = airfoil.stringer.x_l[_]
384
Removed:
y = airfoil.stringer.z_l[_]
379
Added:
for _ in range(0, len(airfoil.stringer.x)):
380
Added:
x = airfoil.stringer.x[_]
381
Added:
y = airfoil.stringer.z[_]
385
382
plt.plot(x, y, '.', color='y', markersize=12)
386
383
387
384
# Graph formatting
388
385
plt.xlabel('X axis')
389
386
plt.ylabel('Z axis')
390
387
391
Removed:
plot_bound = airfoil.x_u[-1]
388
Added:
plot_bound = airfoil.x[-1]
392
389
plt.xlim(- 0.10 * plot_bound, 1.10 * plot_bound)
393
390
plt.ylim(- (1.10 * plot_bound / 2), (1.10 * plot_bound / 2))
394
391
plt.gca().set_aspect('equal', adjustable='box')
evaluator.py
@@ -39,11 +39,11 @@
39
39
+ airfoil.stringer.mass)
40
40
self.mass_dist = []
41
41
# Upper coordinates
42
Removed:
self.x_u = airfoil.x_u
43
Removed:
self.z_u = airfoil.z_u
42
Added:
self.x = airfoil.x
43
Added:
self.z = airfoil.z
44
44
# Lower coordinates
45
Removed:
self.x_l = airfoil.x_l
46
Removed:
self.z_l = airfoil.z_l
45
Added:
self.x = airfoil.x
46
Added:
self.z = airfoil.z
47
47
self.lift_rectangular = []
48
48
self.lift_elliptical = []
49
49
self.lift_total = []
@@ -140,15 +140,15 @@
140
140
stringer_area = self.stringer.area
141
141
caps_area = self.spar.cap_area
142
142
143
Removed:
x_spars = self.spar.x_u + self.spar.x_l
144
Removed:
x_stringers = self.stringer.x_u + self.stringer.x_l
145
Removed:
z_stringers = self.stringer.z_u + self.stringer.z_l
143
Added:
x_spars = self.spar.x + self.spar.x
144
Added:
x_stringers = self.stringer.x + self.stringer.x
145
Added:
z_stringers = self.stringer.z + self.stringer.z
146
146
denom = float(len(x_spars) * caps_area
147
147
+ len(x_stringers) * stringer_area)
148
148
149
Removed:
x_ctr = (sum([i * caps_area for i in self.spar.x_u])
149
Added:
x_ctr = (sum([i * caps_area for i in self.spar.x])
150
150
+ sum([i * stringer_area for i in x_stringers])) / denom
151
Removed:
z_ctr = (sum([i * caps_area for i in self.spar.z_u])
151
Added:
z_ctr = (sum([i * caps_area for i in self.spar.z])
152
152
+ sum([i * stringer_area for i in z_stringers])) / denom
153
153
return(x_ctr, z_ctr)
154
154
@@ -159,12 +159,12 @@
159
159
caps_area = self.spar.cap_area
160
160
161
161
# Adds upper and lower components' coordinates to list
162
Removed:
x_stringers = self.stringer.x_u + self.stringer.x_l
163
Removed:
z_stringers = self.stringer.z_u + self.stringer.z_l
164
Removed:
x_spars = self.spar.x_u + self.spar.x_l
165
Removed:
z_spars = self.spar.z_u + self.spar.z_l
162
Added:
x_stringers = self.stringer.x + self.stringer.x
163
Added:
z_stringers = self.stringer.z + self.stringer.z
164
Added:
x_spars = self.spar.x + self.spar.x
165
Added:
z_spars = self.spar.z + self.spar.z
166
166
stringer_count = range(len(x_stringers))
167
Removed:
spar_count = range(len(self.spar.x_u))
167
Added:
spar_count = range(len(self.spar.x))
168
168
169
169
# I_x is the sum of the contributions of the spar caps and stringers
170
170
I_x = (sum([caps_area * (z_spars[i] - self.centroid[1]) ** 2
@@ -212,27 +212,27 @@
212
212
q = evaluator.chord / 4
213
213
plt.plot(q, 0, '.', color='g', markersize=24, label='Quarter-chord')
214
214
# Plot upper surface
215
Removed:
plt.plot(evaluator.x_u, evaluator.z_u,
215
Added:
plt.plot(evaluator.x, evaluator.z,
216
216
'', color='b', linewidth='1')
217
217
# Plot lower surface
218
Removed:
plt.plot(evaluator.x_l, evaluator.z_l,
218
Added:
plt.plot(evaluator.x, evaluator.z,
219
219
'', color='b', linewidth='1')
220
220
221
221
# Plot spars
222
Removed:
for _ in range(0, len(evaluator.spar.x_u)):
223
Removed:
x = (evaluator.spar.x_u[_], evaluator.spar.x_l[_])
224
Removed:
y = (evaluator.spar.z_u[_], evaluator.spar.z_l[_])
222
Added:
for _ in range(0, len(evaluator.spar.x)):
223
Added:
x = (evaluator.spar.x[_], evaluator.spar.x[_])
224
Added:
y = (evaluator.spar.z[_], evaluator.spar.z[_])
225
225
plt.plot(x, y, '.-', color='b')
226
226
227
227
# Plot upper stringers
228
Removed:
for _ in range(0, len(evaluator.stringer.x_u)):
229
Removed:
x = evaluator.stringer.x_u[_]
230
Removed:
y = evaluator.stringer.z_u[_]
228
Added:
for _ in range(0, len(evaluator.stringer.x)):
229
Added:
x = evaluator.stringer.x[_]
230
Added:
y = evaluator.stringer.z[_]
231
231
plt.plot(x, y, '.', color='y', markersize=12)
232
232
# Plot lower stringers
233
Removed:
for _ in range(0, len(evaluator.stringer.x_l)):
234
Removed:
x = evaluator.stringer.x_l[_]
235
Removed:
y = evaluator.stringer.z_l[_]
233
Added:
for _ in range(0, len(evaluator.stringer.x)):
234
Added:
x = evaluator.stringer.x[_]
235
Added:
y = evaluator.stringer.z[_]
236
236
plt.plot(x, y, '.', color='y', markersize=12)
237
237
238
238
# Plot centroid
@@ -244,7 +244,7 @@
244
244
plt.xlabel('X axis')
245
245
plt.ylabel('Z axis')
246
246
247
Removed:
plot_bound = evaluator.x_u[-1]
247
Added:
plot_bound = evaluator.x[-1]
248
248
plt.xlim(- 0.10 * plot_bound, 1.10 * plot_bound)
249
249
plt.ylim(- (1.10 * plot_bound / 2), (1.10 * plot_bound / 2))
250
250
plt.gca().set_aspect('equal', adjustable='box')