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

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) 

10 

11 

12class ParametricFinner(Generator): 

13 """Parametric generator for generic finned rocket.""" 

14 

15 def __init__(self, **kwargs) -> None: 

16 """Create a parametric generator for the basic finner. 

17 

18 Parameters 

19 ---------- 

20 diameter : float, optional 

21 The diameter of the body. The default is 1. 

22 

23 total_length : float, optional 

24 The total length of the rocket. The default is 10. 

25 

26 nose_length : float, optional 

27 The length of the nose. The default is 2.84. 

28 

29 fin_height : float, optional 

30 The height of the fins. The default is 1.0. 

31 

32 fin_length : float, optional 

33 The length of the fins. The default is 1.0. 

34 

35 max_fin_thickness : float, optional 

36 The maximum thickness of the fins. The default is 0.08. 

37 

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 

49 

50 # Complete instantiation 

51 super().__init__(**kwargs) 

52 

53 def create_instance(self) -> Vehicle: 

54 # Instantiate Vehicle 

55 finner = Vehicle() 

56 finner.configure( 

57 name="Finner", 

58 verbosity=1, 

59 ) 

60 

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) 

65 

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 ) 

72 

73 # Construct revolved surfaces 

74 nose = RevolvedComponent(nose_line) 

75 fuselage_outer = RevolvedComponent(fuselage_line) 

76 fuselage_base = RevolvedComponent(fuselage_base_line) 

77 

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) 

83 

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) 

89 

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] 

98 

99 # Create swept fin component 

100 fin = SweptComponent(cross_sections=[cs1, cs2], stl_resolution=4) 

101 

102 tf = [ 

103 ("rotate", 90, "z"), # align 

104 ("translate", Vector3(x=self.total_length, y=0, z=self.diameter / 2)), 

105 None, 

106 ] 

107 

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 ) 

116 

117 return finner 

118 

119 

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()