Coverage for /opt/hostedtoolcache/Python/3.11.10/x64/lib/python3.11/site-packages/hypervehicle/hangar/finner.py: 92%
49 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
1from copy import copy, deepcopy
2from hypervehicle import Vehicle
3from hypervehicle.generator import Generator
4from hypervehicle.geometry import Vector3, Line
5from hypervehicle.components import (
6 RevolvedComponent,
7 SweptComponent,
8 CompositeComponent,
9)
12class ParametricFinner(Generator):
13 """Parametric generator for generic finned rocket."""
15 def __init__(self, **kwargs) -> None:
16 """Create a parametric generator for the basic finner.
18 Parameters
19 ----------
20 diameter : float, optional
21 The diameter of the body. The default is 1.
23 total_length : float, optional
24 The total length of the rocket. The default is 10.
26 nose_length : float, optional
27 The length of the nose. The default is 2.84.
29 fin_height : float, optional
30 The height of the fins. The default is 1.0.
32 fin_length : float, optional
33 The length of the fins. The default is 1.0.
35 max_fin_thickness : float, optional
36 The maximum thickness of the fins. The default is 0.08.
38 References
39 ----------
40 https://hisa.gitlab.io/archive/asc/basicFinner/notes/basicFinner.html
41 """
42 # Vehicle parameters
43 self.diameter = 1.0
44 self.total_length = 10.0
45 self.nose_length = 2.84
46 self.fin_height = 1.0
47 self.fin_length = 1.0
48 self.max_fin_thickness = 0.08
50 # Complete instantiation
51 super().__init__(**kwargs)
53 def create_instance(self) -> Vehicle:
54 # Instantiate Vehicle
55 finner = Vehicle()
56 finner.configure(
57 name="Finner",
58 verbosity=1,
59 )
61 # Define key points
62 origin = Vector3(0, 0, 0)
63 nose_base = origin + Vector3(x=self.nose_length, y=self.diameter / 2)
64 rocket_base = origin + Vector3(x=self.total_length, y=self.diameter / 2)
66 # Construct nose-body revolve lines
67 nose_line = Line(p0=origin, p1=nose_base)
68 fuselage_line = Line(p0=nose_base, p1=rocket_base)
69 fuselage_base_line = Line(
70 p0=rocket_base, p1=rocket_base - Vector3(x=0, y=rocket_base.y)
71 )
73 # Construct revolved surfaces
74 nose = RevolvedComponent(nose_line)
75 fuselage_outer = RevolvedComponent(fuselage_line)
76 fuselage_base = RevolvedComponent(fuselage_base_line)
78 # Define fuselage component
79 fuselage = CompositeComponent(stl_resolution=8, name="fuselage")
80 fuselage.add_component(nose)
81 fuselage.add_component(fuselage_outer)
82 fuselage.add_component(fuselage_base)
84 # Define nominal fin and transformations
85 a = Vector3(x=0, y=self.fin_length)
86 b = Vector3(x=0, y=0)
87 c = Vector3(x=-0.5 * self.max_fin_thickness, y=0)
88 d = Vector3(x=0.5 * self.max_fin_thickness, y=0)
90 # Create cross section paths for swept component
91 cs1 = [
92 Line(a, d),
93 Line(d, b),
94 Line(b, c),
95 Line(c, a),
96 ]
97 cs2 = [line + Vector3(x=0, y=0, z=self.fin_height) for line in cs1]
99 # Create swept fin component
100 fin = SweptComponent(cross_sections=[cs1, cs2], stl_resolution=4)
102 tf = [
103 ("rotate", 90, "z"), # align
104 ("translate", Vector3(x=self.total_length, y=0, z=self.diameter / 2)),
105 None,
106 ]
108 # Add components
109 finner.add_component(fuselage)
110 for i in range(4):
111 angle = i * 90
112 tf[2] = ("rotate", angle, "x")
113 finner.add_component(
114 deepcopy(fin), transformations=copy(tf), name=f"fin_{i+1}"
115 )
117 return finner
120if __name__ == "__main__":
121 # To create the nominal geometry
122 parametric_generator = ParametricFinner()
123 finner = parametric_generator.create_instance()
124 finner.generate()
125 finner.to_stl()