*ARCHIVED* development moved to aircraft-studio.
delete Coordinates class
Changed files
creator.py
@@ -18,10 +18,9 @@
18
18
and various components we add to an airfoil (spars, stringers, and ribs.)
19
19
20
20
Classes:
21
Removed:
Coordinates: always instantiated first, but never assigned to object.
22
Removed:
Airfoil: inherits from Coordinates & automatically aware of airfoil size.
23
Removed:
Spar: also inherits from Coordinates.
24
Removed:
Stringer: also inherits from Coordinates.
21
Added:
Airfoil: instantiated with class method to provide coordinates to heirs
22
Added:
Spar: inherits from Airfoil.
23
Added:
Stringer: also inherits from Airfoil.
25
24
26
25
Functions:
27
26
plot_geom(airfoil): generates a 2D plot of the airfoil & any components.
@@ -35,19 +34,18 @@
35
34
import matplotlib.pyplot as plt
36
35
37
36
38
Removed:
class Coordinates:
37
Added:
class Airfoil:
39
38
"""
40
Removed:
All airfoil components need the following:
39
Added:
This class represents a single NACA airfoil.
41
40
42
Removed:
Parameters:
43
Removed:
Component material
44
Removed:
Coordinates relative to the chord & semi-span
41
Added:
Please note: the coordinates are saved as two lists
42
Added:
for the x- and z-coordinates. The coordinates start at
43
Added:
the leading edge, travel over the airfoil's upper edge,
44
Added:
then loop back to the leading edge via the lower edge.
45
45
46
Removed:
Methods:
47
Removed:
Print component coordinates
48
Removed:
Save component coordinates to file specified in main.py
49
Removed:
50
Removed:
So, all component classes inherit from class Coordinates.
46
Added:
This method was chosen for easier future exports
47
Added:
to 3D CAD packages like SolidWorks, which can import such
48
Added:
geometry as coordinates written in a CSV file.
51
49
"""
52
50
53
51
# Defaults
@@ -65,78 +63,14 @@
65
63
self.z = []
66
64
67
65
@classmethod
68
Removed:
def from_chord(cls, chord, semi_span):
66
Added:
def from_dimensions(cls, chord, semi_span):
69
67
cls.chord = chord
70
68
cls.semi_span = semi_span
71
Removed:
return None
69
Added:
return Airfoil()
72
70
73
71
def __str__(self):
74
72
return type(self).__name__
75
73
76
Removed:
def info_print(self, round):
77
Removed:
"""
78
Removed:
Print all the component's coordinates to the terminal.
79
Removed:
80
Removed:
This function's output is piped to the 'save_coord' function below.
81
Removed:
"""
82
Removed:
83
Removed:
name = ' CREATOR DATA '
84
Removed:
num_of_dashes = len(name)
85
Removed:
86
Removed:
print(num_of_dashes * '-')
87
Removed:
print(name)
88
Removed:
print('Component:', str(self))
89
Removed:
print('Chord length:', self.chord)
90
Removed:
print('Semi-span:', self.semi_span)
91
Removed:
print('Mass:', self.mass)
92
Removed:
print(num_of_dashes * '-')
93
Removed:
print('x-coordinates:\n', np.around(self.x, round))
94
Removed:
print('z-coordinates:\n', np.around(self.z, round))
95
Removed:
return None
96
Removed:
97
Removed:
def info_save(self, save_path, number):
98
Removed:
"""
99
Removed:
Save all the object's coordinates (must be full path).
100
Removed:
"""
101
Removed:
102
Removed:
file_name = '{}_{}.txt'.format(str(self).lower(), number)
103
Removed:
full_path = os.path.join(save_path, file_name)
104
Removed:
try:
105
Removed:
with open(full_path, 'w') as sys.stdout:
106
Removed:
self.info_print(6)
107
Removed:
# This line required to reset behavior of sys.stdout
108
Removed:
sys.stdout = sys.__stdout__
109
Removed:
print('Successfully wrote to file {}'.format(full_path))
110
Removed:
except IOError:
111
Removed:
print('Unable to write {} to specified directory.\n'
112
Removed:
.format(file_name),
113
Removed:
'Was the full path passed to the function?')
114
Removed:
return None
115
Removed:
116
Removed:
117
Removed:
class Airfoil(Coordinates):
118
Removed:
"""
119
Removed:
This class represents a single NACA airfoil.
120
Removed:
121
Removed:
Please note: the coordinates are saved as two lists
122
Removed:
for the x- and z-coordinates. The coordinates start at
123
Removed:
the leading edge, travel over the airfoil's upper edge,
124
Removed:
then loop back to the leading edge via the lower edge.
125
Removed:
126
Removed:
This method was chosen for easier future exports
127
Removed:
to 3D CAD packages like SolidWorks, which can import such
128
Removed:
geometry as coordinates written in a CSV file.
129
Removed:
"""
130
Removed:
131
Removed:
def __init__(self):
132
Removed:
# Run 'Coordinates' super class init method with same chord & 1/2 span.
133
Removed:
super().__init__()
134
Removed:
# NACA number
135
Removed:
self.naca_num = int()
136
Removed:
# Mean camber line
137
Removed:
self.x_c = []
138
Removed:
self.z_c = []
139
Removed:
140
74
def add_naca(self, naca_num):
141
75
"""
142
76
This function generates geometry for our chosen NACA airfoil shape.
@@ -213,6 +147,8 @@
213
147
x_chord_rev.extend(extend)
214
148
215
149
# Generate our airfoil geometry from previous sub-functions.
150
Added:
self.x_c = []
151
Added:
self.z_c = []
216
152
for x in x_chord:
217
153
self.x_c.append(x)
218
154
self.z_c.append(get_camber(x))
@@ -227,13 +163,47 @@
227
163
self.mass = mass
228
164
229
165
def info_print(self, round):
230
Removed:
super().info_print(round)
231
Removed:
print('x_c the camber x-coordinates:\n', np.around(self.x_c, round))
232
Removed:
print('z_c the camber z-coordinates:\n', np.around(self.z_c, round))
166
Added:
"""
167
Added:
Print all the component's coordinates to the terminal.
168
Added:
169
Added:
This function's output is piped to the 'save_coord' function below.
170
Added:
"""
171
Added:
172
Added:
name = ' CREATOR DATA '
173
Added:
num_of_dashes = len(name)
174
Added:
175
Added:
print(num_of_dashes * '-')
176
Added:
print(name)
177
Added:
print('Component:', str(self))
178
Added:
print('Chord length:', self.chord)
179
Added:
print('Semi-span:', self.semi_span)
180
Added:
print('Mass:', self.mass)
181
Added:
print(num_of_dashes * '-')
182
Added:
print('x-coordinates:\n', np.around(self.x, round))
183
Added:
print('z-coordinates:\n', np.around(self.z, round))
233
184
return None
234
185
186
Added:
def info_save(self, save_path, number):
187
Added:
"""
188
Added:
Save all the object's coordinates (must be full path).
189
Added:
"""
235
190
236
Removed:
class Spar(Coordinates):
191
Added:
file_name = '{}_{}.txt'.format(str(self).lower(), number)
192
Added:
full_path = os.path.join(save_path, file_name)
193
Added:
try:
194
Added:
with open(full_path, 'w') as sys.stdout:
195
Added:
self.info_print(6)
196
Added:
# This line required to reset behavior of sys.stdout
197
Added:
sys.stdout = sys.__stdout__
198
Added:
print('Successfully wrote to file {}'.format(full_path))
199
Added:
except IOError:
200
Added:
print('Unable to write {} to specified directory.\n'
201
Added:
.format(file_name),
202
Added:
'Was the full path passed to the function?')
203
Added:
return None
204
Added:
205
Added:
206
Added:
class Spar(Airfoil):
237
207
"""Contains a single spar's location."""
238
208
239
209
def __init__(self):
@@ -291,7 +261,7 @@
291
261
return None
292
262
293
263
294
Removed:
class Stringer(Coordinates):
264
Added:
class Stringer(Airfoil):
295
265
"""Contains the coordinates of all stringers."""
296
266
297
267
def __init__(self):
evaluator.py
@@ -13,7 +13,7 @@
13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program. If not, see <https://www.gnu.org/licenses/>.
15
15
"""
16
Removed:
The 'evaluator' module contains a single Evaluator class,
16
Added:
The evaluator.py module contains a single Evaluator class,
17
17
which knows all the attributes of a specified Airfoil instance,
18
18
and contains functions to analyse the airfoil's geometrical
19
19
& structural properties.
generator.py
@@ -13,18 +13,18 @@
13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program. If not, see <https://www.gnu.org/licenses/>.
15
15
"""
16
Removed:
The 'generator' module contains a single Population class,
16
Added:
The generator.py module contains a single Population class,
17
17
which represents a collection of randomized airfoils.
18
18
"""
19
19
20
Removed:
import creator as cr
20
Added:
import creator
21
21
22
22
23
Removed:
class Population(cr.Airfoil, cr.Spar, cr.Stringer):
23
Added:
class Population(creator.Airfoil):
24
24
"""Collection of random airfoils."""
25
25
26
26
def __init__(self, size):
27
Removed:
af = cr.Airfoil
27
Added:
af = creator.Airfoil
28
28
# print(af)
29
29
self.size = size
30
30
self.gen_number = 0 # incremented for every generation
main.py
@@ -57,15 +57,12 @@
57
57
Evaluate an airfoil;
58
58
Generate a population of airfoils & optimize.
59
59
"""
60
Removed:
# Create coordinate system specific to our airfoil dimensions.
61
Removed:
# TODO: imperial + metric unit setting
62
Removed:
creator.Coordinates.from_chord(CHORD_LENGTH, SEMI_SPAN)
63
60
64
61
# Interate through all wings in population, creating and evaluating them.
65
62
for _ in range(1, POP_SIZE + 1):
66
63
67
64
# Create airfoil instance
68
Removed:
af = creator.Airfoil()
65
Added:
af = creator.Airfoil.from_dimensions(CHORD_LENGTH, SEMI_SPAN)
69
66
# Define NACA airfoil coordinates and mass
70
67
af.add_naca(NACA_NUM)
71
68
af.add_mass(AIRFOIL_MASS)
@@ -107,7 +104,7 @@
107
104
eval.analysis(1, 1)
108
105
# eval.info_print(2)
109
106
# eval.info_save(SAVE_PATH, _)
110
Removed:
evaluator.plot_geom(eval)
107
Added:
# evaluator.plot_geom(eval)
111
108
# evaluator.plot_lift(eval)
112
109
113
110
pop = generator.Population(10)