|
@@ -1,108 +1,154 @@
|
1
|
|
-//parametric micro quadcopter frame for lulfro and others
|
2
|
|
-//Patrick Sapinski
|
3
|
|
-//v1
|
4
|
|
-//22/05/15
|
5
|
|
-
|
6
|
|
-motorDiameter = 7;
|
7
|
|
-motorHeight = 18;
|
8
|
|
-shellThickness = 3;
|
9
|
|
-armThickness = 6;
|
10
|
|
-m2mDistance = 90;
|
11
|
|
-batteryWidth = 40;
|
12
|
|
-
|
13
|
|
-propLength = 50;
|
14
|
|
-
|
15
|
|
-module makeArm() {
|
16
|
|
- translate([m2mDistance/2,0,0])
|
|
1
|
+/*
|
|
2
|
+ * Created by:
|
|
3
|
+ * Thomas Buck <xythobuz@xythobuz.de> in April 2016
|
|
4
|
+ *
|
|
5
|
+ * Licensed under the
|
|
6
|
+ * Creative Commons - Attribution - Share Alike license.
|
|
7
|
+ *
|
|
8
|
+ * Idea based on the "Parametric brushed micro quadcopter"
|
|
9
|
+ * by "drkow" / Patrick Sapinski:
|
|
10
|
+ * http://www.thingiverse.com/thing:843597
|
|
11
|
+ */
|
|
12
|
+
|
|
13
|
+// -----------------------------------------------------------
|
|
14
|
+
|
|
15
|
+wallSize = 2;
|
|
16
|
+armSize = 6;
|
|
17
|
+motorDiameter = 7.3;
|
|
18
|
+baseWidth = 41;
|
|
19
|
+diameter = 78;
|
|
20
|
+height = 5;
|
|
21
|
+bodyHeight = 8;
|
|
22
|
+
|
|
23
|
+motorHeight = 15;
|
|
24
|
+
|
|
25
|
+wireWidth = 2;
|
|
26
|
+wireHeight = 1;
|
|
27
|
+
|
|
28
|
+// size of a Turnigy nano-tech 1S 750mAh LiPo
|
|
29
|
+batteryWidth = 25;
|
|
30
|
+batteryLength = 45;
|
|
31
|
+batteryHeight = 10;
|
|
32
|
+
|
|
33
|
+// Hubsan compatible propellers/motors
|
|
34
|
+propeller = 55;
|
|
35
|
+realMotorHeight = 20;
|
|
36
|
+
|
|
37
|
+$fn = 25;
|
|
38
|
+
|
|
39
|
+// -----------------------------------------------------------
|
|
40
|
+
|
|
41
|
+baseLength = baseWidth + (2 * wallSize);
|
|
42
|
+realBaseLength = 2 * sqrt(2 * (baseLength / 2) * (baseLength / 2));
|
|
43
|
+armDiameter = motorDiameter + (wallSize * 2);
|
|
44
|
+realDiameter = 2 * sqrt(2 * (diameter / 2) * (diameter / 2));
|
|
45
|
+armLength = ((realDiameter - realBaseLength) / 2) - armDiameter;
|
|
46
|
+
|
|
47
|
+// -----------------------------------------------------------
|
|
48
|
+
|
|
49
|
+module arm() {
|
17
|
50
|
difference() {
|
18
|
|
- //create the motor holder and arm
|
19
|
|
- union(){
|
20
|
|
- translate([-m2mDistance/2 + motorDiameter/2,-armThickness/2,motorHeight/2 - armThickness])
|
21
|
|
- cube([m2mDistance/2,armThickness,armThickness]);
|
22
|
|
- cylinder(h = motorHeight/2, r=motorDiameter/2 + shellThickness/2);
|
23
|
|
- sphere(r=motorDiameter/2 + shellThickness/2);
|
|
51
|
+ // arm
|
|
52
|
+ translate([0, -armSize / 2, 0])
|
|
53
|
+ cube([armLength, armSize, height]);
|
|
54
|
+
|
|
55
|
+ // wire grooves
|
|
56
|
+ translate([armLength / 3, -wireWidth / 2, 0])
|
|
57
|
+ cube([armLength * 2 / 3, wireWidth, wireHeight]);
|
|
58
|
+ translate([armLength / 3, -wireWidth / 2, 0])
|
|
59
|
+ cube([wireWidth, armSize, wireHeight]);
|
|
60
|
+ translate([armLength / 3, armSize / 2 - wireHeight, -height / 2])
|
|
61
|
+ cube([wireWidth, wireHeight, height * 2]);
|
|
62
|
+ translate([armLength / 3, -wireWidth / 2, height - wireHeight])
|
|
63
|
+ cube([wireWidth, armSize, wireHeight]);
|
|
64
|
+ translate([-wireWidth, -wireWidth / 2, height - wireHeight])
|
|
65
|
+ cube([armLength / 2, wireWidth, wireHeight]);
|
|
66
|
+ }
|
|
67
|
+
|
|
68
|
+ // motor mount
|
|
69
|
+ translate([armLength + (armDiameter * 2 / 5), 0, 0])
|
|
70
|
+ union() {
|
|
71
|
+ difference() {
|
|
72
|
+ // wall
|
|
73
|
+ cylinder(d = armDiameter, h = motorHeight);
|
|
74
|
+
|
|
75
|
+ // motor hole
|
|
76
|
+ cylinder(d = motorDiameter, h = motorHeight);
|
24
|
77
|
|
25
|
|
- //prop preview
|
26
|
|
- %rotate([0,0,45])cube([propLength,5,5],center=true);
|
|
78
|
+ // wire groove
|
|
79
|
+ translate([-(motorDiameter / 2) - (wallSize * 3 / 2), -wireWidth / 2, 0])
|
|
80
|
+ cube([2 * wallSize, wireWidth, wireHeight]);
|
27
|
81
|
}
|
28
|
|
- //hollow out the motor holder
|
29
|
|
- sphere(r=motorDiameter/2);
|
30
|
|
- cylinder(h = motorHeight/2, r=motorDiameter/2);
|
31
|
82
|
|
32
|
|
- //hollow out the groove for the wire in the motor holder
|
33
|
|
- translate([-shellThickness,0,-shellThickness])
|
34
|
|
- cube([m2mDistance,armThickness - shellThickness,motorHeight],center=true);
|
|
83
|
+ // visualize motors
|
|
84
|
+ %cylinder(d = motorDiameter, h = realMotorHeight);
|
35
|
85
|
|
36
|
|
- //???
|
37
|
|
- translate([-shellThickness*2,-armThickness/2 + shellThickness/2,-motorHeight/2])
|
38
|
|
- cube([motorHeight,armThickness - shellThickness,motorHeight + shellThickness]);
|
|
86
|
+ // visualize propellers
|
|
87
|
+ %translate([0, 0, realMotorHeight])
|
|
88
|
+ cylinder(d = propeller, h = 2);
|
39
|
89
|
}
|
40
|
90
|
}
|
41
|
91
|
|
|
92
|
+// -----------------------------------------------------------
|
|
93
|
+
|
|
94
|
+// visualize real diameter (print bed size)
|
|
95
|
+%translate([-diameter / 2, -diameter / 2, -height - batteryHeight])
|
|
96
|
+ cube([diameter, diameter, height]);
|
|
97
|
+
|
|
98
|
+// four arms
|
|
99
|
+rotate([0, 0, 45])
|
|
100
|
+for (i = [0 : 90 : 360]) {
|
|
101
|
+ rotate([0, 0, i])
|
|
102
|
+ translate([realBaseLength / 2 - (wallSize * 11 / 7), 0, 0])
|
|
103
|
+ arm();
|
|
104
|
+}
|
|
105
|
+
|
42
|
106
|
difference() {
|
43
|
|
- union(){
|
44
|
|
- //create each arm
|
45
|
|
- rotate([0,0,45]){
|
46
|
|
- rotate([0,0,90]) makeArm();
|
47
|
|
- rotate([0,0,180]) makeArm();
|
48
|
|
- rotate([0,0,270]) makeArm();
|
49
|
|
- rotate([0,0,360]) makeArm();
|
50
|
|
- }
|
51
|
|
-
|
52
|
|
- //create the FC cube
|
53
|
|
- translate([0,0,motorHeight/2 - armThickness/2])
|
54
|
|
- cube([batteryWidth + shellThickness,batteryWidth + shellThickness,armThickness],center=true);
|
55
|
|
- }
|
56
|
|
- translate([0,0,motorHeight/2 - armThickness/2 - motorHeight/2 + shellThickness/2])
|
57
|
|
- union(){
|
58
|
|
- //hollow out some grooves in the arms for the wires
|
59
|
|
- rotate([0,0,45])
|
60
|
|
- cube([armThickness - shellThickness,m2mDistance/2,motorHeight/1.5],center=true);
|
61
|
|
- rotate([0,0,45])
|
62
|
|
- cube([m2mDistance/2,armThickness - shellThickness,motorHeight/1.5],center=true);
|
63
|
|
- }
|
|
107
|
+ // body
|
|
108
|
+ translate([-baseLength / 2, -baseLength / 2, 0])
|
|
109
|
+ cube([baseLength, baseLength, bodyHeight]);
|
64
|
110
|
|
65
|
|
- //hollow out the FC hole
|
66
|
|
- translate([0,0,motorHeight/2 - armThickness/2 - shellThickness/2])
|
67
|
|
- cube([batteryWidth,batteryWidth,armThickness],center=true);
|
|
111
|
+ // space for flight control
|
|
112
|
+ translate([-baseWidth / 2, -baseWidth / 2, -bodyHeight / 2])
|
|
113
|
+ cube([baseWidth, baseWidth, bodyHeight * 2]);
|
68
|
114
|
|
69
|
|
- //drunk code below
|
70
|
|
- b = 20;
|
71
|
|
- h = 20;
|
72
|
|
- w = 4;
|
73
|
|
- rotate(a=[0,0,45])
|
74
|
|
- translate([2,2,motorHeight/2])
|
75
|
|
- linear_extrude(height = w, center = true, convexity = 10, twist = 0)
|
76
|
|
- polygon(points=[[0,0],[h,0],[0,b]], paths=[[0,1,2]]);
|
77
|
|
-
|
78
|
|
- rotate(a=[0,0,45 + 180])
|
79
|
|
- translate([2,2,motorHeight/2])
|
80
|
|
- linear_extrude(height = w, center = true, convexity = 10, twist = 0)
|
81
|
|
- polygon(points=[[0,0],[h,0],[0,b]], paths=[[0,1,2]]);
|
82
|
|
-
|
83
|
|
- rotate(a=[0,0,45 + 90])
|
84
|
|
- translate([2,2,motorHeight/2])
|
85
|
|
- linear_extrude(height = w, center = true, convexity = 10, twist = 0)
|
86
|
|
- polygon(points=[[0,0],[h,0],[0,b]], paths=[[0,1,2]]);
|
87
|
|
-
|
88
|
|
- rotate(a=[0,0,45 + 270])
|
89
|
|
- translate([2,2,motorHeight/2])
|
90
|
|
- linear_extrude(height = w, center = true, convexity = 10, twist = 0)
|
91
|
|
- polygon(points=[[0,0],[h,0],[0,b]], paths=[[0,1,2]]);
|
|
115
|
+ // wire grooves
|
|
116
|
+ for (i = [0 : 3]) {
|
|
117
|
+ a = (i % 2) ? 1 : -1;
|
|
118
|
+ b = (i < 2) ? 1 : -1;
|
|
119
|
+ translate([a * (baseWidth + wallSize) / 2
|
|
120
|
+ - ((a == 1) ? (
|
|
121
|
+ (b == 1) ? wallSize / 2 : wallSize / 2)
|
|
122
|
+ : 0),
|
|
123
|
+ b * (baseWidth + wallSize) / 2
|
|
124
|
+ - ((a == 1) ? (
|
|
125
|
+ (b == 1) ? wallSize / 2 : -wallSize / 2)
|
|
126
|
+ : 0),
|
|
127
|
+ height - wireHeight])
|
|
128
|
+ rotate([0, 0, a * b * 45])
|
|
129
|
+ translate([-wallSize, -wireWidth / 2, 0])
|
|
130
|
+ cube([wallSize * 3, wireWidth, bodyHeight]);
|
|
131
|
+ }
|
92
|
132
|
}
|
93
|
|
-/*
|
94
|
|
-//parabolic arm attempt...
|
95
|
133
|
|
96
|
|
-module oval(w,h, height, center = false) {
|
97
|
|
- scale([1, h/w, 1]) cylinder(h=height, r=w, center=center);
|
|
134
|
+// battery holder / bottom part
|
|
135
|
+union() {
|
|
136
|
+ translate([-baseWidth / 2, -batteryWidth / 3, 0])
|
|
137
|
+ cube([baseWidth, batteryWidth * 2 / 3, wallSize]);
|
|
138
|
+
|
|
139
|
+ translate([baseWidth / 4, batteryWidth / 3, 0])
|
|
140
|
+ cube([baseWidth / 8, (baseWidth - batteryWidth * 2 / 3) / 2, wallSize]);
|
|
141
|
+
|
|
142
|
+ translate([-baseWidth * 6 / 16, batteryWidth / 3, 0])
|
|
143
|
+ cube([baseWidth / 8, (baseWidth - batteryWidth * 2 / 3) / 2, wallSize]);
|
|
144
|
+
|
|
145
|
+ translate([baseWidth / 4, - batteryWidth / 2 - (baseWidth - batteryWidth) / 2, 0])
|
|
146
|
+ cube([baseWidth / 8, (baseWidth - batteryWidth * 2 / 3) / 2, wallSize]);
|
|
147
|
+
|
|
148
|
+ translate([-baseWidth * 6 / 16, - batteryWidth / 2 - (baseWidth - batteryWidth) / 2, 0])
|
|
149
|
+ cube([baseWidth / 8, (baseWidth - batteryWidth * 2 / 3) / 2, wallSize]);
|
98
|
150
|
}
|
99
|
151
|
|
100
|
|
- translate([0,0,2])
|
101
|
|
- difference() {
|
102
|
|
- cube([m2mDistance,m2mDistance,fcHeight],center=true);
|
103
|
|
- for (i = [0 : 3])
|
104
|
|
- rotate([0,0,i * 90])
|
105
|
|
- translate([m2mDistance + 10,0,0])
|
106
|
|
- oval(m2mDistance/2 + 40,m2mDistance/2, 5);
|
107
|
|
- }
|
108
|
|
-*/
|
|
152
|
+// visualize battery
|
|
153
|
+%translate([-batteryLength / 2, -batteryWidth / 2, -batteryHeight])
|
|
154
|
+ cube([batteryLength, batteryWidth, batteryHeight]);
|