Coverage for /opt/hostedtoolcache/Python/3.11.9/x64/lib/python3.11/site-packages/hypervehicle/hangar/htv.py: 94%

77 statements  

« prev     ^ index     » next       coverage.py v7.6.1, created at 2024-08-25 22:58 +0000

1import numpy as np 

2from copy import deepcopy 

3from hypervehicle import Vehicle 

4from scipy.optimize import bisect 

5from hypervehicle.components import Wing 

6from hypervehicle.generator import Generator 

7from hypervehicle.geometry import Vector3, Line, Polyline 

8 

9 

10class ParametricHTV(Generator): 

11 """Parametric generator for mock-up of the Hypersonic Technology Vehicle 2. 

12 

13 Dimensions have been approximated based on vehicle's visual proportions. 

14 

15 References 

16 ---------- 

17 https://en.wikipedia.org/wiki/Hypersonic_Technology_Vehicle_2 

18 """ 

19 

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

21 # Vehicle parameters 

22 self.L = 1 

23 self.body_width = 0.5 

24 self.h = 0.1 

25 self.t_LE = 0.01 

26 self.flap_angle = 15 

27 

28 # Nominal parameters for proportional scaling 

29 self.L_nom = 1 

30 self.body_width_nom = 0.8 

31 self.h_nom = 0.2 

32 self.t_LE_nom = 0.025 

33 

34 # Complete instantiation 

35 super().__init__(**kwargs) 

36 

37 def create_instance(self) -> Vehicle: 

38 # Create Vehicle instance 

39 htv = Vehicle() 

40 htv.configure( 

41 name="Hypersonic Technology Vehicle", 

42 verbosity=1, 

43 ) 

44 

45 # Create main body 

46 # ================ 

47 A0 = Vector3(x=0, y=0) 

48 A1 = Vector3(x=0.15 * self.L, y=0) 

49 TT = Vector3(x=self.L, y=0) 

50 B0 = Vector3(x=0, y=self.body_width / 2) 

51 

52 B1 = Vector3(x=A1.x, y=B0.y) 

53 B0B1 = Line(p0=B0, p1=B1) 

54 B1TT = Line(p0=B1, p1=TT) 

55 Line_B0TT = Polyline([B0B1, B1TT]) 

56 

57 def get_local_width(x): 

58 """Returns the vehicle width at a given x.""" 

59 func = lambda t: Line_B0TT(t).x - x 

60 t = bisect(func, 0.0, 1.0) 

61 return 2 * Line_B0TT(t).y 

62 

63 def wing1_tf_top(x, y, z=0): 

64 """Thickness function to create the top surface shape 

65 of the vehicle.""" 

66 local_width = get_local_width(x) 

67 

68 if y < 0.5 * (local_width - 2 * self.t_LE): 

69 z_val = 0.5 * (self.h - self.t_LE) * np.cos( 

70 2 * np.pi * y / (local_width - 2 * self.t_LE) 

71 ) + 0.5 * (self.h + self.t_LE) 

72 elif y == 0.5 * (local_width - 2 * self.t_LE): 

73 z_val = self.t_LE 

74 else: 

75 z_val = self.t_LE 

76 

77 # Apply axial tapering 

78 z_val *= (self.L - x) + 0.05 

79 

80 return Vector3(x=0, y=0, z=-z_val) 

81 

82 def wing1_tf_bot(x, y, z=0): 

83 """Bottom thickness function.""" 

84 z_val = 0.2 * self.t_LE 

85 return Vector3(x=0, y=0, z=z_val) 

86 

87 def lewf(r): 

88 """Constant leading edge width function.""" 

89 le_width = 0.01 

90 return le_width 

91 

92 # Add wing 

93 wing = Wing( 

94 A0=A0, 

95 A1=A1, 

96 TT=TT, 

97 B0=B0, 

98 Line_B0TT=Line_B0TT, 

99 top_tf=wing1_tf_top, 

100 bot_tf=wing1_tf_bot, 

101 LE_wf=lewf, 

102 stl_resolution=5, 

103 ) 

104 htv.add_component(wing, reflection_axis="y") 

105 

106 # Create flaps 

107 # ================ 

108 length_scaler = self.L / self.L_nom 

109 width_scaler = self.body_width / self.body_width_nom 

110 

111 flap_length = 0.2 * length_scaler 

112 flap_gap = 0.01 * width_scaler 

113 

114 offset = 0.1 * self.t_LE 

115 

116 A0f = Vector3(x=flap_length, y=0 + 0.5 * flap_gap) 

117 A1f = Vector3(x=flap_length + 0.05 * self.L, y=0 + 0.5 * flap_gap) 

118 TTf = Vector3(x=flap_length + 0.1 * self.L, y=0 + 0.5 * flap_gap) 

119 B0f = Vector3(x=flap_length, y=0.8 * self.body_width / 2 + 0.5 * flap_gap) 

120 

121 B1f = Vector3(x=A1f.x, y=0.5 * B0f.y) 

122 B0B1f = Line(p0=B0f, p1=B1f) 

123 B1TTf = Line(p0=B1f, p1=TTf) 

124 Line_B0TTf = Polyline([B0B1f, B1TTf]) 

125 

126 def wing2_tf_top(x, y, z=0): 

127 return Vector3(x=0, y=0, z=-self.t_LE - offset) 

128 

129 def wing2_tf_bot(x, y, z=0): 

130 return Vector3(x=0, y=0, z=0.2 * self.t_LE - offset) 

131 

132 flap_wing = Wing( 

133 A0=A0f, 

134 A1=A1f, 

135 TT=TTf, 

136 B0=B0f, 

137 Line_B0TT=Line_B0TTf, 

138 top_tf=wing2_tf_top, 

139 bot_tf=wing2_tf_bot, 

140 flap_length=flap_length, 

141 flap_angle=np.deg2rad(self.flap_angle), 

142 stl_resolution=5, 

143 ) 

144 htv.add_component(deepcopy(flap_wing)) 

145 htv.add_component(flap_wing, reflection_axis="y") 

146 

147 return htv 

148 

149 

150if __name__ == "__main__": 

151 # To create the nominal geometry 

152 parametric_generator = ParametricHTV() 

153 htv = parametric_generator.create_instance() 

154 htv.generate() 

155 htv.to_stl(prefix="htv")