Coverage for /opt/hostedtoolcache/Python/3.11.10/x64/lib/python3.11/site-packages/hypervehicle/hangar/hifire4.py: 92%
85 statements
« prev ^ index » next coverage.py v7.6.4, created at 2024-10-29 02:51 +0000
« prev ^ index » next coverage.py v7.6.4, created at 2024-10-29 02:51 +0000
1import numpy as np
2from hypervehicle import Vehicle
3from hypervehicle.generator import Generator
4from hypervehicle.components import Wing, Fin, RevolvedComponent, common
5from hypervehicle.geometry import Vector3, Line, Polyline, Arc
8class ParametricHIFiRE4(Generator):
9 """Parametric generator for mock-up of the HIFiRE 4.
11 Dimensions have been approximated based on vehicle's visual proportions.
13 References
14 ----------
15 https://arc.aiaa.org/doi/10.2514/6.2011-2275
16 """
18 def __init__(self, **kwargs) -> None:
19 # Vehicle parameters
20 self.x_curve_mult = 0.3
21 self.y_curve_mult = 0.5
22 self.R = 0.2
23 self.L_n = 2
24 self.L_b = 4
26 # Complete instantiation
27 super().__init__(**kwargs)
29 def create_instance(self) -> Vehicle:
30 # Initialise
31 hifire4 = Vehicle()
32 hifire4.configure(
33 name="HIFiRE4",
34 verbosity=1,
35 )
37 L_t = self.L_n + self.L_b
39 # Construct tangent ogive nose
40 # --------------------------------------------------
41 rho = (self.R**2 + self.L_n**2) / (2 * self.R)
42 y_o = lambda x: round(np.sqrt(rho**2 - (self.L_n - x) ** 2) + self.R - rho, 6)
43 a_o = Vector3(x=0, y=0)
44 b_o = Vector3(x=-self.L_n, y=y_o(self.L_n))
45 c_o = Vector3(x=b_o.x, y=b_o.y - rho)
46 ogive_arc = Arc(a_o, b_o, c_o)
48 # Construct body
49 b0 = b_o
50 b1 = b0 - Vector3(x=self.L_b, y=0)
51 b2 = b1 - Vector3(x=0, y=self.R)
52 bL1 = Line(b0, b1)
53 bL2 = Line(b1, b2)
55 # Construct fuselage Polyline
56 fuseline = Polyline([ogive_arc, bL1, bL2])
58 # Construct curvature functions
59 def curv_x(x, y):
60 "Curvature in x-direction (about y-axis)"
61 return self.x_curve_mult * 0.05 * x**2
63 def curv_xd(x, y):
64 return self.x_curve_mult * 0.05 * 2 * x
66 def curv_y(x, y):
67 "Curvature in y-direction (about x-axis)"
68 return self.y_curve_mult * 0.1 * y**2
70 def curv_yd(x, y):
71 return self.y_curve_mult * 0.1 * 2 * y
73 # Create curvature operations chain
74 curvatures = [("x", curv_x, curv_xd), ("y", curv_y, curv_yd)]
76 fuselage = RevolvedComponent(
77 revolve_line=fuseline,
78 stl_resolution=20,
79 )
81 # Create wing body
82 # --------------------------------------------------
83 # --- |---B0------________________B1
84 # | | | ----____
85 # | | | ----_____
86 # | | | --____B2
87 # --- |---A0----------------------A1----------------------TT
88 #
89 # |------------------- wing_L ---------------------|
91 wing_L = 0.8 * L_t
92 wing_thickness = 0.25 * self.R
93 wing_span = 3.5 * self.R
94 flap_length = 0.1 * L_t
95 flap_angle = 0
96 wing_LE_shift = Vector3(x=0.3, y=0)
98 # Required points
99 A0 = a_o - Vector3(x=wing_L, y=0)
100 A1 = Vector3(x=A0.x + 0.5 * wing_L, y=0)
101 TT = Vector3(x=A0.x + wing_L, y=0) - wing_LE_shift
102 B0 = Vector3(x=A0.x, y=wing_span)
104 # Construction points
105 B1 = Vector3(x=A1.x, y=0.95 * B0.y)
106 B2 = Vector3(x=TT.x, y=0.15 * wing_span)
108 # Leading edge line
109 B0B1 = Line(p0=B0, p1=B1)
110 B1B2 = Line(p0=B1, p1=B2)
111 B2TT = Line(p0=B2, p1=TT)
112 Line_B0TT = Polyline([B0B1, B1B2, B2TT])
114 wing = Wing(
115 A0=A0,
116 A1=A1,
117 TT=TT,
118 B0=B0,
119 Line_B0TT=Line_B0TT,
120 top_tf=common.uniform_thickness_function(wing_thickness, "top"),
121 bot_tf=common.uniform_thickness_function(wing_thickness, "bot"),
122 flap_length=flap_length,
123 flap_angle=np.deg2rad(flap_angle),
124 stl_resolution=3,
125 )
127 # Create fins
128 # --------------------------------------------------
129 # |--p1-----p2
130 # | | \
131 # | | \
132 # | | \
133 # |--p0______________p3
135 fin_height = self.R
136 fin_thickness = wing_thickness
137 fin_length = 0.2 * wing_L
139 p0 = A0 - Vector3(x=flap_length, y=0)
140 p1 = p0 + Vector3(x=0, y=fin_height)
141 p2 = p1 + Vector3(x=0.5 * fin_length, y=-0.5 * fin_height)
142 p3 = p0 + Vector3(x=fin_length, y=0)
144 # Modifty each point for curvature
145 p0 += Vector3(x=0, y=-curv_x(p0.x, p0.y))
146 p1 += Vector3(x=0, y=-curv_x(p1.x, p1.y))
147 p2 += Vector3(x=0, y=-curv_x(p2.x, p2.y))
148 p3 += Vector3(x=0, y=-curv_x(p3.x, p3.y))
150 # Add fins
151 offset1 = lambda x, y, z: Vector3(x=0, y=wing_span)
152 offset2 = lambda x, y, z: Vector3(x=0, y=-wing_span)
153 offset3 = lambda x, y, z: Vector3(x=0, y=0, z=-0.95 * self.R)
154 stl_res = 3
155 fin1 = Fin(
156 p0=p0,
157 p1=p1,
158 p2=p2,
159 p3=p3,
160 offset_func=offset1,
161 fin_thickness=fin_thickness,
162 fin_angle=np.deg2rad(-90),
163 top_thickness_function=common.uniform_thickness_function(
164 fin_thickness, "top"
165 ),
166 bot_thickness_function=common.uniform_thickness_function(
167 fin_thickness, "bot"
168 ),
169 rudder_type="sharp",
170 rudder_length=fin_thickness,
171 stl_resolution=stl_res,
172 )
173 fin2 = Fin(
174 p0=p0,
175 p1=p1,
176 p2=p2,
177 p3=p3,
178 offset_func=offset2,
179 fin_thickness=fin_thickness,
180 fin_angle=np.deg2rad(-90),
181 top_thickness_function=common.uniform_thickness_function(
182 fin_thickness, "top"
183 ),
184 bot_thickness_function=common.uniform_thickness_function(
185 fin_thickness, "bot"
186 ),
187 rudder_type="sharp",
188 rudder_length=fin_thickness,
189 stl_resolution=stl_res,
190 )
191 fin3 = Fin(
192 p0=p0,
193 p1=p1,
194 p2=p2,
195 p3=p3,
196 offset_func=offset3,
197 fin_thickness=fin_thickness,
198 fin_angle=np.deg2rad(-90),
199 top_thickness_function=common.uniform_thickness_function(
200 fin_thickness, "top"
201 ),
202 bot_thickness_function=common.uniform_thickness_function(
203 fin_thickness, "bot"
204 ),
205 rudder_type="sharp",
206 rudder_length=fin_thickness,
207 stl_resolution=stl_res,
208 )
210 # Add components
211 hifire4.add_component(
212 fuselage,
213 curvatures=curvatures,
214 )
215 hifire4.add_component(
216 wing,
217 reflection_axis="y",
218 curvatures=curvatures,
219 )
220 hifire4.add_component(fin1)
221 hifire4.add_component(fin2)
222 hifire4.add_component(fin3)
224 return hifire4
227if __name__ == "__main__":
228 # To create the nominal geometry
229 parametric_generator = ParametricHIFiRE4()
230 hifire4 = parametric_generator.create_instance()
231 hifire4.generate()
232 hifire4.to_stl("hifire4")