]> www.fi.muni.cz Git - things.git/blob - rocket.scad
rocket.scad: three-part model rocket
[things.git] / rocket.scad
1
2 // The Estes A8-3 and C6-7 motors have diameter of 17.7 mm,
3 // length 69.5 mm. The Estes Alpha launch pad has rod diameter 3.4 mm.
4
5 motor_diam = 17.7 + 0.5; // add some tolerance
6 motor_len  = 69.5 + 0.5;
7 motor_wall = 2;
8
9 segment_overlap = 15;
10
11 thin_wall = 1.0; // depends on the print width
12 thick_wall = 2.5*thin_wall;
13
14 clip_spring_angle = 45;
15 clip_spring_depth = 20;
16
17 rod_diam = 4;
18
19 eps = 0.01;
20 infty = 1000;
21
22 //----------------- MOTOR MODULE -----------------------------
23
24 module fin() {
25         assign(h1 = 2*motor_len/3, // near end height
26                 h2 = 20,        // far end height
27                 h_off = motor_len, // height offset of the far height
28                 w = 30, // distance of the far height
29                 fin_w = thin_wall)
30         translate([0, -fin_w/2, -h1])
31         hull() { 
32                 cube([eps, fin_w, h1]); // near end
33                 translate([w, 0, h_off]) // far end
34                         cube([eps, fin_w, h2]);
35         };
36 };
37
38 // alternative fin layout
39 module fin2() {
40         assign(h1 = motor_len/2, // near end height
41                 w2 = 18,        // bottom/far end width
42                 h_off = 50, // height offset of the far height
43                 w = 30, // distance of the far height
44                 fin_w = thin_wall)
45         translate([0, -fin_w/2, -h1])
46         hull() { 
47                 cube([eps, fin_w, h1]); // near end
48                 translate([w-w2, 0, h_off]) // far end
49                         cube([w2, fin_w, eps]);
50         };
51 };
52
53 rod_hole_height = 15;
54 rod_hole_side = 1.5*(rod_diam + thin_wall);
55
56 module motor_module_solid()
57 {
58         // the lowest part is for joining the segments
59         cylinder(r = motor_diam/2 + thin_wall, h = segment_overlap + eps);
60
61         // conical joint between the two cylinders
62         translate([0, 0, segment_overlap - thick_wall + thin_wall])
63                 cylinder(r1 = motor_diam/2 + thin_wall,
64                         r2 = motor_diam/2 + thick_wall,
65                         h = thick_wall - thin_wall + eps);
66
67         // protrusions to hold the main tube in place
68         for (a = [60, 180, 300]) {
69                 rotate([0, 0, a]) {
70                         translate([motor_diam/2 - thin_wall, 0, 0])
71                                 cylinder(r1 = thick_wall-thin_wall/2, r2 = thick_wall, h = segment_overlap/3 + eps);
72                         translate([motor_diam/2 - thin_wall, 0, segment_overlap/3])
73                                 cylinder(r = thick_wall, h = 2*segment_overlap/3 + eps);
74                 };
75         };
76
77         // the thick cylinder above it
78         translate([0, 0, segment_overlap])
79                 cylinder(r = motor_diam/2 + thick_wall,
80                 h = motor_len + motor_wall - segment_overlap);
81
82         // clip spring
83         translate([0, 0, motor_len + motor_wall])
84                 intersection() {
85                         translate([motor_diam/2+6, infty/2, 4])
86                         rotate([90, 0, 0])
87                                 cylinder(r = 8, h = infty);
88                         cylinder(r = motor_diam/2 + thick_wall, h = infty);
89                         rotate([0, 0, -clip_spring_angle/2+eps])
90                                 cube(infty);
91                         rotate([0, 0, clip_spring_angle/2-eps])
92                                 scale([1, -1, 1])
93                                 cube([infty, infty, 8]);
94                 };
95
96         // fins
97         for (a = [60, 180, 300]) {
98                 rotate([0, 0, a])
99                 translate([motor_diam/2 + thick_wall-thin_wall, 0, motor_wall + motor_len])
100                         // fin();
101                         fin2();
102         };
103
104         // rod hole holder
105         hull() {
106                 translate([motor_diam/2 + thick_wall - rod_diam/2 - thin_wall,
107                         0, segment_overlap])
108                         scale([1, 1.4, 1])
109                         cylinder(r = rod_diam/2 + thin_wall, h = eps);
110                 translate([motor_diam/2 + thick_wall + rod_diam/2, 0, segment_overlap + rod_hole_side])
111                         scale([1, 1.1, 1])
112                         cylinder(r = rod_diam/2 + thin_wall, h = rod_hole_height);
113                 translate([motor_diam/2 + thick_wall - rod_diam/2 - thin_wall,
114                         0, segment_overlap + 2*rod_hole_side + rod_hole_height])
115                         scale([1, 1.4, 1])
116                         cylinder(r = rod_diam/2 + thin_wall, h = eps);
117         };
118
119 };
120         
121 module motor_module() {
122         difference() {
123                 motor_module_solid();
124
125                 // top ring to hold the motor inside
126                 translate([0, 0, -eps])
127                         cylinder(r = motor_diam/2 - motor_wall,
128                                 h = motor_wall + 2*eps);
129
130                 // motor hole
131                 translate([0, 0, motor_wall - eps])
132                         cylinder(r = motor_diam/2, h = motor_len + 2*eps);
133
134                 // three rails inside the motor hole
135                 translate([0, 0, segment_overlap + thick_wall]) difference() {
136                         union() {
137                                 cylinder(r = motor_diam/2 + thin_wall,
138                                         h = motor_len - segment_overlap - 2*thick_wall + eps);
139                                 translate([0, 0, motor_len - segment_overlap - 2*thick_wall])
140                                         cylinder(r1 = motor_diam/2 + thin_wall, r2 = motor_diam/2, h = thick_wall + eps);
141                         };
142                         for (a = [60, 180, 300]) rotate([0, 0, a])
143                                 translate([motor_diam/2 + 2.5, 0, -eps])
144                                         cylinder(r = 3, h = infty);
145                 };
146
147                 // clip spring
148                 for (r = [-clip_spring_angle/2, clip_spring_angle/2]) {
149                         rotate([0, 0, r])
150                         translate([-thin_wall/2, 0, motor_len + motor_wall - clip_spring_depth])
151                                 cube([infty, thin_wall, infty]);
152                 };
153                 translate([0, 0, motor_len - eps])
154                 intersection() {
155                         cylinder(r = motor_diam/2 + thin_wall,
156                                 h = thick_wall + 2*eps);
157                         rotate([0, 0, -clip_spring_angle/2+eps])
158                                 cube(infty);
159                         rotate([0, 0, clip_spring_angle/2-eps])
160                                 scale([1, -1, 1])
161                                 cube([infty, infty, 8]);
162                 };
163                 
164
165                 // rod hole
166                 translate([motor_diam/2 + thick_wall + eps + rod_diam/2, 0, 0])
167                         cylinder(r = rod_diam/2, h = infty);
168         };
169 };
170
171 // -------------------- CENTRAL TUBE ---------------------
172
173 central_tube_h = 80;
174
175 module central_tube_solid() {
176         cylinder(r = motor_diam/2 + thick_wall, h = central_tube_h);
177 };
178
179 module central_tube() {
180         difference() {
181                 central_tube_solid();
182                 translate([0, 0, -eps])
183                         cylinder(r = motor_diam/2 + thick_wall - thin_wall,
184                                 h = infty);
185         };
186 };
187
188 //------------------------- FRONT CONE -----------------------
189 cone_h = 45;
190 cone_resolution = 40;
191
192 function bez_i4(t, ctls) =
193         (pow(1-t, 3) * ctls[0])
194         + (3 * t * pow(1-t, 2) * ctls[1])
195         + (3 * pow(t, 2) * (1-t) * ctls[2])
196         + (pow(t, 3) * ctls[3]);
197
198 module bezier_cone(cps, res)
199 {
200         for (t = [0:1:res])
201                 translate([0, 0, (bez_i4(t/res, cps))[0]])
202                         cylinder(r1 = (bez_i4(t/res, cps))[1],
203                                 r2 = (bez_i4((t + 1)/res, cps))[1],
204                                 h = (bez_i4((t + 1)/res, cps))[0]
205                                     - (bez_i4(t/res, cps))[0] + eps);
206 };
207
208 module front_cone_body() {
209         translate([0, 0, segment_overlap])
210                 bezier_cone([
211                         [ 0, motor_diam/2 + thick_wall ], // start
212                         [ cone_h/2, motor_diam/2 + thick_wall ], // cp 1
213                         [ cone_h - motor_diam/2 - thick_wall, motor_diam/2 + thick_wall ], // cp 2
214                         [ cone_h, 0 ],
215                 ], 40);
216
217         translate([0, 0, segment_overlap-thick_wall+thin_wall])
218                 cylinder(r1 = motor_diam/2+thin_wall,
219                         r2 = motor_diam/2 + thick_wall,
220                         h = thick_wall - thin_wall + eps);
221
222         cylinder(r = motor_diam/2+thin_wall, h = segment_overlap + eps);
223 };
224
225 module front_cone() {
226         difference() {
227                 front_cone_body();
228                 translate([0, 0, segment_overlap])
229                         bezier_cone([
230                                 [ 0.7*thin_wall, motor_diam/2 + thick_wall - thin_wall ], // start
231                         [ cone_h/2-0.7*thin_wall, motor_diam/2 + thick_wall - thin_wall], // cp 1
232                         [ cone_h - motor_diam/2 - thick_wall + thin_wall - 1.4*thin_wall, motor_diam/2 + thick_wall - thin_wall ], // cp 2
233                         [ cone_h - 1.4*thin_wall, 0 ],
234                 ], 40);
235
236                 translate([0, 0, segment_overlap-thick_wall+1.7*thin_wall])
237                         cylinder(r1 = motor_diam/2,
238                                 r2 = motor_diam/2 + thick_wall-thin_wall,
239                                 h = thick_wall-thin_wall + eps);
240
241                 translate([0, 0, -eps])
242                         cylinder(r = motor_diam/2, h = segment_overlap + 2*eps);
243
244                 // debug
245                 // translate([0, 0, -eps]) cube(infty);
246         };
247 };
248
249 module thread_holder() {
250         rotate([0, 90, 0]) {
251                 translate([0, 0, -1.5]) difference() {
252                         cylinder(r = 10, h = 3);
253                         translate([0, 0, -eps])
254                                 cylinder(r = 8, h = 3 + 2*eps);
255                 };
256         };
257 }
258
259 // thread_holder();
260
261 $fn = 128;
262
263 translate([motor_diam + thick_wall, 0, 0])
264         motor_module();
265
266 rotate([0, 0, 120])
267 translate([motor_diam + thick_wall, 0, 0])
268         central_tube();
269
270 rotate([0, 0, 240])
271 translate([motor_diam + thick_wall, 0, 0])
272         front_cone();
273