├── MPRT.scad ├── README.md ├── images ├── oshw-logo-200-px.png └── trans.png ├── involute_gears.scad └── output ├── housing_ring.stl ├── output_ring.stl ├── output_ring_bearing.stl ├── planet.stl ├── planet_2.stl ├── sun.stl └── sun_os.stl /MPRT.scad: -------------------------------------------------------------------------------- 1 | // MPRT - Modified planetary robotics transmission OpenSCAD source 2 | 3 | // Project home: https://hackaday.io/project/164732 4 | // Author: https://hackaday.io/daren 5 | // 6 | // Creative Commons License exists for this work. You may copy and alter the content 7 | // of this file for private use only, and distribute it only with the associated 8 | // MPRT content. This license must be included withthe file and content. 9 | // For a copy of the current license, please visit http://creativecommons.org/licenses/by-sa/3.0/ 10 | 11 | use <./involute_gears.scad> 12 | 13 | 14 | extra=0.02; // for differencing 15 | $fs=.01; // circle/face accuracy 16 | $fn=120; 17 | 18 | //gear settings 19 | 20 | pitch=1.05; //diametric pitch = teeth/diam 21 | pressure_angle=24; 22 | clearance=0.2; // extra depth at the base of the gear profile 23 | backlash=0.10; // inter-tooth clearance following the tooth profile. 24 | 25 | num_planets=3; 26 | // (ring_teeth - sun_teeth) must be an even number for planet_teeth to work! 27 | ring_teeth=60; // needs to be divisable by both and 2. 28 | sun_teeth=18; // needs to be divisable by both and 2. 29 | output_teeth=ring_teeth-num_planets; 30 | output_pilot_d=16+clearance/2; 31 | output_pilot_h=0; 32 | output_bolt_offset_1=15; 33 | output_bolt_offset_2=26; 34 | output_bolt_d=3-clearance; 35 | 36 | planet_teeth=(ring_teeth-sun_teeth)/2; 37 | planet_cutout_r=0; 38 | orbit_r=((planet_teeth+sun_teeth)/pitch)/2; 39 | 40 | wall=5.0+pitch*2+clearance; 41 | ring_gear_h=2; 42 | ring_gear_r=ring_teeth/pitch/2; 43 | 44 | // housing/motor settings 45 | sun_bore_r=6.65/2; // Nema 23 D shaft dia 46 | housing_size=60; 47 | housing_bolt_spacing=47.5; // .5 larger than actual 48 | housing_bolt_d=5.0; 49 | housing_pilot_h=1; 50 | housing_pilot_d=38+clearance; 51 | 52 | 53 | // uncomment each of these, render, print. 54 | // sun(); 55 | // planet(); 56 | // housing_ring(); 57 | // translate([0,0,output_pilot_h+ring_gear_h]) rotate([0,180,0]) output_ring(); 58 | 59 | // assembly view. 60 | view_assembly(); 61 | 62 | 63 | 64 | module view_assembly() { 65 | translate([0,0,housing_pilot_h+extra]) { 66 | rotate([0,0,0]) sun(); 67 | for (planetnum=[1:num_planets]) rotate([0,0,(360/num_planets)*(planetnum-1)]) translate([orbit_r,0,0]) rotate([0,0,0]) planet(); 68 | } 69 | translate([0,0,ring_gear_h+clearance+housing_pilot_h]) { 70 | #output_ring(); 71 | } 72 | housing_ring(); 73 | ratio=ring_teeth/sun_teeth*ring_teeth/num_planets; 74 | echo("Final drive ratio:", ratio); 75 | } 76 | module output_ring() { 77 | difference() { 78 | // body 79 | translate([0,0,ring_gear_h/2+output_pilot_h/2]) hull() { 80 | cylinder(r=ring_gear_r+wall/2,h=ring_gear_h+output_pilot_h-extra,center=true); 81 | //translate([60,0,0]) cylinder(r=5,h=ring_gear_h+output_pilot_h-extra,center=true); 82 | } 83 | // gear cutout 84 | translate([0,0,-extra/2]) gear(number_of_teeth=output_teeth, diametral_pitch=pitch*output_teeth/ring_teeth, hub_diameter=0, bore_diameter=0, rim_thickness=ring_gear_h+extra*4, gear_thickness=ring_gear_h+clearance,clearance=-clearance, backlash=-backlash*2, pressure_angle=pressure_angle+2.5); 85 | // output hole cutout 86 | //translate([60,0,0]) cylinder(r=3,h=ring_gear_h*4+extra,center=true); 87 | translate([0,0,ring_gear_h+output_pilot_h/2+1]) cylinder(r=output_pilot_d/2,h=output_pilot_h+extra,center=true); 88 | translate([0,0,ring_gear_h+1/2]) cylinder(r2=output_pilot_d/2,r1=output_pilot_d/2-1,h=1+extra,center=true); 89 | for (i=[1:6]) rotate([0,0,(360/6)*(i-1)]) translate([output_bolt_offset_1,0,ring_gear_h+output_pilot_h/2+0.8]) cylinder(r=output_bolt_d/2,h=output_pilot_h,center=true); 90 | for (i=[1:6]) rotate([0,0,(360/6)*(i-1)+360/12]) translate([output_bolt_offset_2,0,ring_gear_h+output_pilot_h/2+0.8]) cylinder(r=output_bolt_d/2,h=output_pilot_h,center=true); 91 | } 92 | } 93 | 94 | module planet() { 95 | gear(number_of_teeth=planet_teeth, diametral_pitch=pitch, hub_diameter=0, bore_diameter=planet_cutout_r*2, rim_thickness=ring_gear_h*2-clearance/2, gear_thickness=ring_gear_h*2-clearance/2,clearance=clearance, backlash=backlash, pressure_angle=pressure_angle); 96 | } 97 | 98 | module housing_ring() { 99 | spool_offset=0.0; 100 | total_height=ring_gear_h+housing_pilot_h; 101 | translate([0,0,total_height/2]) difference() { 102 | // body 103 | union() { 104 | hull() for (xnum=[-1,1]) for (ynum=[-1,1]) translate([xnum*housing_bolt_spacing/2,ynum*housing_bolt_spacing/2,0]) cylinder(r=(housing_bolt_d+wall)/2, h=total_height, center=true); 105 | cylinder(r=ring_gear_r+wall/2, h=total_height,center=true); 106 | } 107 | // bolt holes 108 | for (xnum=[-1,1]) for (ynum=[-1,1]) { 109 | translate([xnum*housing_bolt_spacing/2,ynum*housing_bolt_spacing/2,0]) { 110 | cylinder(r=housing_bolt_d/2+extra, h=total_height+extra, center=true); 111 | translate([0,0,total_height/2-housing_bolt_d/4+extra]) cylinder(r2=housing_bolt_d*.75,r1=housing_bolt_d*.75/2, h=housing_bolt_d/2, center=true); 112 | } 113 | 114 | } 115 | translate([0,0,-total_height/2]) { 116 | // stepper center pilot 117 | translate([0,0,housing_pilot_h/2]) cylinder(r=housing_pilot_d/2,h=housing_pilot_h+extra*4,center=true); 118 | // gear cutout 119 | translate([0,0,housing_pilot_h]) gear(number_of_teeth=ring_teeth, diametral_pitch=pitch, hub_diameter=0, bore_diameter=0, rim_thickness=ring_gear_h+extra, gear_thickness=ring_gear_h+extra,clearance=0, backlash=-backlash, pressure_angle=pressure_angle ); 120 | } 121 | } 122 | } 123 | 124 | module sun() { 125 | union() { 126 | gear(number_of_teeth=sun_teeth, diametral_pitch=pitch, hub_diameter=pitch*sun_teeth, hub_thickness=ring_gear_h*2, bore_diameter=sun_bore_r*2, rim_thickness=ring_gear_h*2, rim_width=0, gear_thickness=ring_gear_h*2,clearance=clearance, backlash=backlash, pressure_angle=pressure_angle); 127 | // D shaft flat 128 | translate([sun_bore_r*2/1.9,0,ring_gear_h]) cube([sun_bore_r*2/5,sun_bore_r,ring_gear_h*2],center=true); 129 | } 130 | } 131 | 132 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## MPRT - Modified Planetary Robotics Transmission. 2 | The reduction of strain-wave, using a 'single' stage planetary system. 3 | ![trans.png](images/trans.png) 4 | 5 | The [MPRT - Modified Planetary Robotics Transmission](https://hackaday.io/project/164732) project is open source hardware. 6 | This github repository hosts the [OpenSCAD](http://www.openscad.org) source and eventually, the rendered STL images for quick access. 7 | 8 | ![oshw-logo-200-px.png](images/oshw-logo-200-px.png) 9 | 10 | Hardware designs (schematics and CAD) files are licensed under the [Creative Commons Attribution-ShareAlike 3.0 Unported License](http://creativecommons.org/licenses/by-sa/3.0/) and follow the terms of the [OSHW (Open-source hardware) Statement of Principles 1.0.](http://freedomdefined.org/OSHW) 11 | -------------------------------------------------------------------------------- /images/oshw-logo-200-px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Arcus-3d/MPRT/309433d1b6cd9dfe8b7c9cfe864413c0c2f58a78/images/oshw-logo-200-px.png -------------------------------------------------------------------------------- /images/trans.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Arcus-3d/MPRT/309433d1b6cd9dfe8b7c9cfe864413c0c2f58a78/images/trans.png -------------------------------------------------------------------------------- /involute_gears.scad: -------------------------------------------------------------------------------- 1 | // Parametric Involute Bevel and Spur Gears by GregFrost 2 | // It is licensed under the Creative Commons - GNU LGPL 2.1 license. 3 | // © 2010 by GregFrost, thingiverse.com/Amp 4 | // http://www.thingiverse.com/thing:3575 and http://www.thingiverse.com/thing:3752 5 | 6 | 7 | // 5/25/11 - modification by jag to add dedendum_adjustment and addendum_adjustment to allow for more clearance with internal gears 8 | // 3/29/19 - updated to remove warnings in newer OpenSCAD - https://hackaday.io/daren 9 | 10 | // Simple Test: 11 | //gear (circular_pitch=700, 12 | // gear_thickness = 12, 13 | // rim_thickness = 15, 14 | // hub_thickness = 17, 15 | // circles=8); 16 | 17 | //Complex Spur Gear Test: 18 | //test_gears (); 19 | 20 | // Meshing Double Helix: 21 | //test_meshing_double_helix (); 22 | 23 | module test_meshing_double_helix(){ 24 | meshing_double_helix (); 25 | } 26 | 27 | // Demonstrate the backlash option for Spur gears. 28 | //test_backlash (); 29 | 30 | // Demonstrate how to make meshing bevel gears. 31 | //test_bevel_gear_pair(); 32 | 33 | module test_bevel_gear_pair(){ 34 | bevel_gear_pair (); 35 | } 36 | 37 | module test_bevel_gear(){bevel_gear();} 38 | 39 | //bevel_gear(); 40 | 41 | pi=3.1415926535897932384626433832795; 42 | 43 | //================================================== 44 | // Bevel Gears: 45 | // Two gears with the same cone distance, circular pitch (measured at the cone distance) 46 | // and pressure angle will mesh. 47 | 48 | module bevel_gear_pair ( 49 | gear1_teeth = 41, 50 | gear2_teeth = 7, 51 | axis_angle = 90, 52 | outside_circular_pitch=1000) 53 | { 54 | outside_pitch_radius1 = gear1_teeth * outside_circular_pitch / 360; 55 | outside_pitch_radius2 = gear2_teeth * outside_circular_pitch / 360; 56 | pitch_apex1=outside_pitch_radius2 * sin (axis_angle) + 57 | (outside_pitch_radius2 * cos (axis_angle) + outside_pitch_radius1) / tan (axis_angle); 58 | cone_distance = sqrt (pow (pitch_apex1, 2) + pow (outside_pitch_radius1, 2)); 59 | pitch_apex2 = sqrt (pow (cone_distance, 2) - pow (outside_pitch_radius2, 2)); 60 | echo ("cone_distance", cone_distance); 61 | pitch_angle1 = asin (outside_pitch_radius1 / cone_distance); 62 | pitch_angle2 = asin (outside_pitch_radius2 / cone_distance); 63 | echo ("pitch_angle1, pitch_angle2", pitch_angle1, pitch_angle2); 64 | echo ("pitch_angle1 + pitch_angle2", pitch_angle1 + pitch_angle2); 65 | 66 | rotate([0,0,90]) 67 | translate ([0,0,pitch_apex1+20]) 68 | { 69 | translate([0,0,-pitch_apex1]) 70 | bevel_gear ( 71 | number_of_teeth=gear1_teeth, 72 | cone_distance=cone_distance, 73 | pressure_angle=30, 74 | outside_circular_pitch=outside_circular_pitch); 75 | 76 | rotate([0,-(pitch_angle1+pitch_angle2),0]) 77 | translate([0,0,-pitch_apex2]) 78 | bevel_gear ( 79 | number_of_teeth=gear2_teeth, 80 | cone_distance=cone_distance, 81 | pressure_angle=30, 82 | outside_circular_pitch=outside_circular_pitch); 83 | } 84 | } 85 | 86 | //Bevel Gear Finishing Options: 87 | bevel_gear_flat = 0; 88 | bevel_gear_back_cone = 1; 89 | 90 | module bevel_gear ( 91 | number_of_teeth=11, 92 | cone_distance=100, 93 | face_width=20, 94 | outside_circular_pitch=1000, 95 | pressure_angle=30, 96 | clearance = 0.2, 97 | bore_diameter=5, 98 | gear_thickness = 15, 99 | backlash = 0, 100 | involute_facets=0, 101 | finish = -1) 102 | { 103 | echo ("bevel_gear", 104 | "teeth", number_of_teeth, 105 | "cone distance", cone_distance, 106 | face_width, 107 | outside_circular_pitch, 108 | pressure_angle, 109 | clearance, 110 | bore_diameter, 111 | involute_facets, 112 | finish); 113 | 114 | // Pitch diameter: Diameter of pitch circle at the fat end of the gear. 115 | outside_pitch_diameter = number_of_teeth * outside_circular_pitch / 180; 116 | outside_pitch_radius = outside_pitch_diameter / 2; 117 | 118 | // The height of the pitch apex. 119 | pitch_apex = sqrt (pow (cone_distance, 2) - pow (outside_pitch_radius, 2)); 120 | pitch_angle = asin (outside_pitch_radius/cone_distance); 121 | 122 | echo ("Num Teeth:", number_of_teeth, " Pitch Angle:", pitch_angle); 123 | 124 | finish = (finish != -1) ? finish : (pitch_angle < 45) ? bevel_gear_flat : bevel_gear_back_cone; 125 | 126 | apex_to_apex=cone_distance / cos (pitch_angle); 127 | back_cone_radius = apex_to_apex * sin (pitch_angle); 128 | 129 | // Calculate and display the pitch angle. This is needed to determine the angle to mount two meshing cone gears. 130 | 131 | // Base Circle for forming the involute teeth shape. 132 | base_radius = back_cone_radius * cos (pressure_angle); 133 | 134 | // Diametrial pitch: Number of teeth per unit length. 135 | pitch_diametrial = number_of_teeth / outside_pitch_diameter; 136 | 137 | // Addendum: Radial distance from pitch circle to outside circle. 138 | addendum = 1 / pitch_diametrial; 139 | // Outer Circle 140 | outer_radius = back_cone_radius + addendum; 141 | 142 | // Dedendum: Radial distance from pitch circle to root diameter 143 | dedendum = addendum + clearance; 144 | dedendum_angle = atan (dedendum / cone_distance); 145 | root_angle = pitch_angle - dedendum_angle; 146 | 147 | root_cone_full_radius = tan (root_angle)*apex_to_apex; 148 | back_cone_full_radius=apex_to_apex / tan (pitch_angle); 149 | 150 | back_cone_end_radius = 151 | outside_pitch_radius - 152 | dedendum * cos (pitch_angle) - 153 | gear_thickness / tan (pitch_angle); 154 | back_cone_descent = dedendum * sin (pitch_angle) + gear_thickness; 155 | 156 | // Root diameter: Diameter of bottom of tooth spaces. 157 | root_radius = back_cone_radius - dedendum; 158 | 159 | half_tooth_thickness = outside_pitch_radius * sin (360 / (4 * number_of_teeth)) - backlash / 4; 160 | half_thick_angle = asin (half_tooth_thickness / back_cone_radius); 161 | 162 | face_cone_height = apex_to_apex-face_width / cos (pitch_angle); 163 | face_cone_full_radius = face_cone_height / tan (pitch_angle); 164 | face_cone_descent = dedendum * sin (pitch_angle); 165 | face_cone_end_radius = 166 | outside_pitch_radius - 167 | face_width / sin (pitch_angle) - 168 | face_cone_descent / tan (pitch_angle); 169 | 170 | // For the bevel_gear_flat finish option, calculate the height of a cube to select the portion of the gear that includes the full pitch face. 171 | bevel_gear_flat_height = pitch_apex - (cone_distance - face_width) * cos (pitch_angle); 172 | 173 | // translate([0,0,-pitch_apex]) 174 | difference () 175 | { 176 | intersection () 177 | { 178 | union() 179 | { 180 | rotate (half_thick_angle) 181 | translate ([0,0,pitch_apex-apex_to_apex]) 182 | cylinder ($fn=number_of_teeth*2, r1=root_cone_full_radius,r2=0,h=apex_to_apex); 183 | for (i = [1:number_of_teeth]) 184 | // for (i = [1:1]) 185 | { 186 | rotate ([0,0,i*360/number_of_teeth]) 187 | { 188 | involute_bevel_gear_tooth ( 189 | back_cone_radius = back_cone_radius, 190 | root_radius = root_radius, 191 | base_radius = base_radius, 192 | outer_radius = outer_radius, 193 | pitch_apex = pitch_apex, 194 | cone_distance = cone_distance, 195 | half_thick_angle = half_thick_angle, 196 | involute_facets = involute_facets); 197 | } 198 | } 199 | } 200 | 201 | if (finish == bevel_gear_back_cone) 202 | { 203 | translate ([0,0,-back_cone_descent]) 204 | cylinder ( 205 | $fn=number_of_teeth*2, 206 | r1=back_cone_end_radius, 207 | r2=back_cone_full_radius*2, 208 | h=apex_to_apex + back_cone_descent); 209 | } 210 | else 211 | { 212 | translate ([-1.5*outside_pitch_radius,-1.5*outside_pitch_radius,0]) 213 | cube ([3*outside_pitch_radius, 214 | 3*outside_pitch_radius, 215 | bevel_gear_flat_height]); 216 | } 217 | } 218 | 219 | if (finish == bevel_gear_back_cone) 220 | { 221 | translate ([0,0,-face_cone_descent]) 222 | cylinder ( 223 | r1=face_cone_end_radius, 224 | r2=face_cone_full_radius * 2, 225 | h=face_cone_height + face_cone_descent+pitch_apex); 226 | } 227 | 228 | translate ([0,0,pitch_apex - apex_to_apex]) 229 | cylinder (r=bore_diameter/2,h=apex_to_apex); 230 | } 231 | } 232 | 233 | module involute_bevel_gear_tooth ( 234 | back_cone_radius, 235 | root_radius, 236 | base_radius, 237 | outer_radius, 238 | pitch_apex, 239 | cone_distance, 240 | half_thick_angle, 241 | involute_facets) 242 | { 243 | // echo ("involute_bevel_gear_tooth", 244 | // back_cone_radius, 245 | // root_radius, 246 | // base_radius, 247 | // outer_radius, 248 | // pitch_apex, 249 | // cone_distance, 250 | // half_thick_angle); 251 | 252 | min_radius = max (base_radius*2,root_radius*2); 253 | 254 | pitch_point = 255 | involute ( 256 | base_radius*2, 257 | involute_intersect_angle (base_radius*2, back_cone_radius*2)); 258 | pitch_angle = atan2 (pitch_point[1], pitch_point[0]); 259 | centre_angle = pitch_angle + half_thick_angle; 260 | 261 | start_angle = involute_intersect_angle (base_radius*2, min_radius); 262 | stop_angle = involute_intersect_angle (base_radius*2, outer_radius*2); 263 | 264 | res=(involute_facets!=0)?involute_facets:($fn==0)?5:$fn/4; 265 | 266 | translate ([0,0,pitch_apex]) 267 | rotate ([0,-atan(back_cone_radius/cone_distance),0]) 268 | translate ([-back_cone_radius*2,0,-cone_distance*2]) 269 | union () 270 | { 271 | for (i=[1:res]) 272 | { 273 | point1=involute (base_radius*2,start_angle+(stop_angle - start_angle)*(i-1)/res); 274 | point2=involute (base_radius*2,start_angle+(stop_angle - start_angle)*(i)/res); 275 | side1_point1 = rotate_point (centre_angle, point1); 276 | side1_point2 = rotate_point (centre_angle, point2); 277 | side2_point1 = mirror_point (rotate_point (centre_angle, point1)); 278 | side2_point2 = mirror_point (rotate_point (centre_angle, point2)); 279 | polyhedron ( 280 | points=[ 281 | [back_cone_radius*2+0.1,0,cone_distance*2], 282 | [side1_point1[0],side1_point1[1],0], 283 | [side1_point2[0],side1_point2[1],0], 284 | [side2_point2[0],side2_point2[1],0], 285 | [side2_point1[0],side2_point1[1],0], 286 | [0.1,0,0]], 287 | triangles=[[0,1,2],[0,2,3],[0,3,4],[0,5,1],[1,5,2],[2,5,3],[3,5,4],[0,4,5]]); 288 | 289 | } 290 | } 291 | } 292 | 293 | module gear ( 294 | number_of_teeth=15, 295 | circular_pitch=false, diametral_pitch=false, 296 | pressure_angle=28, 297 | clearance = 0.2, 298 | gear_thickness=5, 299 | rim_thickness=8, 300 | rim_width=5, 301 | hub_thickness=10, 302 | hub_diameter=15, 303 | bore_diameter=5, 304 | circles=0, 305 | backlash=0, 306 | twist=0, 307 | involute_facets=0, 308 | addendum_adjustment=1, 309 | dedendum_adjustment=1, 310 | flat=false) 311 | { 312 | if (circular_pitch==false && diametral_pitch==false) 313 | echo("MCAD ERROR: gear module needs either a diametral_pitch or circular_pitch"); 314 | 315 | //Convert diametrial pitch to our native circular pitch 316 | circular_pitch = (circular_pitch!=false?circular_pitch:180/diametral_pitch); 317 | 318 | // Pitch diameter: Diameter of pitch circle. 319 | pitch_diameter = number_of_teeth * circular_pitch / 180; 320 | pitch_radius = pitch_diameter/2; 321 | echo ("Teeth:", number_of_teeth, " Pitch radius:", pitch_radius); 322 | 323 | // Base Circle 324 | base_radius = pitch_radius*cos(pressure_angle); 325 | 326 | // Diametrial pitch: Number of teeth per unit length. 327 | pitch_diametrial = number_of_teeth / pitch_diameter; 328 | 329 | // Addendum: Radial distance from pitch circle to outside circle. 330 | addendum = addendum_adjustment/pitch_diametrial; 331 | 332 | //Outer Circle 333 | outer_radius = pitch_radius+addendum; 334 | 335 | // Dedendum: Radial distance from pitch circle to root diameter 336 | dedendum = dedendum_adjustment/pitch_diametrial + clearance; 337 | 338 | // Root diameter: Diameter of bottom of tooth spaces. 339 | root_radius = pitch_radius-dedendum; 340 | backlash_angle = backlash / pitch_radius * 180 / pi; 341 | half_thick_angle = (360 / number_of_teeth - backlash_angle) / 4; 342 | 343 | // Variables controlling the rim. 344 | rim_radius = root_radius - rim_width; 345 | 346 | // Variables controlling the circular holes in the gear. 347 | circle_orbit_diameter=hub_diameter/2+rim_radius; 348 | circle_orbit_curcumference=pi*circle_orbit_diameter; 349 | 350 | // Limit the circle size to 90% of the gear face. 351 | circle_diameter= 352 | min ( 353 | 0.70*circle_orbit_curcumference/circles, 354 | (rim_radius-hub_diameter/2)*0.9); 355 | 356 | difference() 357 | { 358 | union () 359 | { 360 | difference () 361 | { 362 | linear_exturde_flat_option(flat=flat, height=rim_thickness, convexity=10, twist=twist) 363 | gear_shape ( 364 | number_of_teeth, 365 | pitch_radius = pitch_radius, 366 | root_radius = root_radius, 367 | base_radius = base_radius, 368 | outer_radius = outer_radius, 369 | half_thick_angle = half_thick_angle, 370 | involute_facets=involute_facets); 371 | 372 | if (gear_thickness < rim_thickness) 373 | translate ([0,0,gear_thickness]) 374 | cylinder (r=rim_radius,h=rim_thickness-gear_thickness+1); 375 | } 376 | if (gear_thickness > rim_thickness) 377 | linear_exturde_flat_option(flat=flat, height=gear_thickness) 378 | circle (r=rim_radius); 379 | if (flat == false && hub_thickness > gear_thickness) 380 | translate ([0,0,gear_thickness]) 381 | linear_exturde_flat_option(flat=flat, height=hub_thickness-gear_thickness) 382 | circle (r=hub_diameter/2); 383 | } 384 | translate ([0,0,-1]) 385 | linear_exturde_flat_option(flat =flat, height=2+max(rim_thickness,hub_thickness,gear_thickness)) 386 | circle (r=bore_diameter/2); 387 | if (circles>0) 388 | { 389 | for(i=[0:circles-1]) 390 | rotate([0,0,i*360/circles]) 391 | translate([circle_orbit_diameter/2,0,-1]) 392 | linear_exturde_flat_option(flat =flat, height=max(gear_thickness,rim_thickness)+3) 393 | circle(r=circle_diameter/2); 394 | } 395 | } 396 | } 397 | 398 | module linear_exturde_flat_option(flat =false, height = 10, center = false, convexity = 2, twist = 0) 399 | { 400 | if(flat==false) 401 | { 402 | linear_extrude(height = height, center = center, convexity = convexity, twist= twist) children(); 403 | } 404 | else 405 | { 406 | children(); 407 | } 408 | 409 | } 410 | 411 | module gear_shape ( 412 | number_of_teeth, 413 | pitch_radius, 414 | root_radius, 415 | base_radius, 416 | outer_radius, 417 | half_thick_angle, 418 | involute_facets) 419 | { 420 | union() 421 | { 422 | rotate (half_thick_angle) circle ($fn=number_of_teeth*2, r=root_radius); 423 | 424 | for (i = [1:number_of_teeth]) 425 | { 426 | rotate ([0,0,i*360/number_of_teeth]) 427 | { 428 | involute_gear_tooth ( 429 | pitch_radius = pitch_radius, 430 | root_radius = root_radius, 431 | base_radius = base_radius, 432 | outer_radius = outer_radius, 433 | half_thick_angle = half_thick_angle, 434 | involute_facets=involute_facets); 435 | } 436 | } 437 | } 438 | } 439 | 440 | module involute_gear_tooth ( 441 | pitch_radius, 442 | root_radius, 443 | base_radius, 444 | outer_radius, 445 | half_thick_angle, 446 | involute_facets) 447 | { 448 | min_radius = max (base_radius,root_radius); 449 | 450 | pitch_point = involute (base_radius, involute_intersect_angle (base_radius, pitch_radius)); 451 | pitch_angle = atan2 (pitch_point[1], pitch_point[0]); 452 | centre_angle = pitch_angle + half_thick_angle; 453 | 454 | start_angle = involute_intersect_angle (base_radius, min_radius); 455 | stop_angle = involute_intersect_angle (base_radius, outer_radius); 456 | 457 | res=(involute_facets!=0)?involute_facets:($fn==0)?5:$fn/4; 458 | 459 | union () for (i=[1:res]) { 460 | point1=involute (base_radius,start_angle+(stop_angle - start_angle)*(i-1)/res); 461 | point2=involute (base_radius,start_angle+(stop_angle - start_angle)*i/res); 462 | side1_point1=rotate_point (centre_angle, point1); 463 | side1_point2=rotate_point (centre_angle, point2); 464 | side2_point1=mirror_point (rotate_point (centre_angle, point1)); 465 | side2_point2=mirror_point (rotate_point (centre_angle, point2)); 466 | polygon ( 467 | points=[[0,0],side1_point1,side1_point2,side2_point2,side2_point1], 468 | paths=[[0,1,2,3,4,0]]); 469 | } 470 | } 471 | 472 | // Mathematical Functions 473 | //=============== 474 | 475 | // Finds the angle of the involute about the base radius at the given distance (radius) from it's center. 476 | //source: http://www.mathhelpforum.com/math-help/geometry/136011-circle-involute-solving-y-any-given-x.html 477 | 478 | function involute_intersect_angle (base_radius, radius) = sqrt (pow (radius/base_radius, 2) - 1) * 180 / pi; 479 | 480 | // Calculate the involute position for a given base radius and involute angle. 481 | 482 | function rotated_involute (rotate, base_radius, involute_angle) = 483 | [ 484 | cos (rotate) * involute (base_radius, involute_angle)[0] + sin (rotate) * involute (base_radius, involute_angle)[1], 485 | cos (rotate) * involute (base_radius, involute_angle)[1] - sin (rotate) * involute (base_radius, involute_angle)[0] 486 | ]; 487 | 488 | function mirror_point (coord) = 489 | [ 490 | coord[0], 491 | -coord[1] 492 | ]; 493 | 494 | function rotate_point (rotate, coord) = 495 | [ 496 | cos (rotate) * coord[0] + sin (rotate) * coord[1], 497 | cos (rotate) * coord[1] - sin (rotate) * coord[0] 498 | ]; 499 | 500 | function involute (base_radius, involute_angle) = 501 | [ 502 | base_radius*(cos (involute_angle) + involute_angle*pi/180*sin (involute_angle)), 503 | base_radius*(sin (involute_angle) - involute_angle*pi/180*cos (involute_angle)) 504 | ]; 505 | 506 | 507 | // Test Cases 508 | //=============== 509 | 510 | module test_gears() 511 | { 512 | translate([17,-15]) 513 | { 514 | gear (number_of_teeth=17, 515 | circular_pitch=500, 516 | circles=8); 517 | 518 | rotate ([0,0,360*4/17]) 519 | translate ([39.088888,0,0]) 520 | { 521 | gear (number_of_teeth=11, 522 | circular_pitch=500, 523 | hub_diameter=0, 524 | rim_width=65); 525 | translate ([0,0,8]) 526 | { 527 | gear (number_of_teeth=6, 528 | circular_pitch=300, 529 | hub_diameter=0, 530 | rim_width=5, 531 | rim_thickness=6, 532 | pressure_angle=31); 533 | rotate ([0,0,360*5/6]) 534 | translate ([22.5,0,1]) 535 | gear (number_of_teeth=21, 536 | circular_pitch=300, 537 | bore_diameter=2, 538 | hub_diameter=4, 539 | rim_width=1, 540 | hub_thickness=4, 541 | rim_thickness=4, 542 | gear_thickness=3, 543 | pressure_angle=31); 544 | } 545 | } 546 | 547 | translate ([-61.1111111,0,0]) 548 | { 549 | gear (number_of_teeth=27, 550 | circular_pitch=500, 551 | circles=5, 552 | hub_diameter=2*8.88888889); 553 | 554 | translate ([0,0,10]) 555 | { 556 | gear ( 557 | number_of_teeth=14, 558 | circular_pitch=200, 559 | pressure_angle=5, 560 | clearance = 0.2, 561 | gear_thickness = 10, 562 | rim_thickness = 10, 563 | rim_width = 15, 564 | bore_diameter=5, 565 | circles=0); 566 | translate ([13.8888888,0,1]) 567 | gear ( 568 | number_of_teeth=11, 569 | circular_pitch=200, 570 | pressure_angle=5, 571 | clearance = 0.2, 572 | gear_thickness = 10, 573 | rim_thickness = 10, 574 | rim_width = 15, 575 | hub_thickness = 20, 576 | hub_diameter=2*7.222222, 577 | bore_diameter=5, 578 | circles=0); 579 | } 580 | } 581 | 582 | rotate ([0,0,360*-5/17]) 583 | translate ([44.444444444,0,0]) 584 | gear (number_of_teeth=15, 585 | circular_pitch=500, 586 | hub_diameter=10, 587 | rim_width=5, 588 | rim_thickness=5, 589 | gear_thickness=4, 590 | hub_thickness=6, 591 | circles=9); 592 | 593 | rotate ([0,0,360*-1/17]) 594 | translate ([30.5555555,0,-1]) 595 | gear (number_of_teeth=5, 596 | circular_pitch=500, 597 | hub_diameter=0, 598 | rim_width=5, 599 | rim_thickness=10); 600 | } 601 | } 602 | 603 | module meshing_double_helix () 604 | { 605 | test_double_helix_gear (); 606 | 607 | mirror ([0,1,0]) 608 | translate ([58.33333333,0,0]) 609 | test_double_helix_gear (teeth=13,circles=6); 610 | } 611 | 612 | module test_double_helix_gear ( 613 | teeth=17, 614 | circles=8) 615 | { 616 | //double helical gear 617 | { 618 | twist=200; 619 | height=20; 620 | pressure_angle=30; 621 | 622 | gear (number_of_teeth=teeth, 623 | circular_pitch=700, 624 | pressure_angle=pressure_angle, 625 | clearance = 0.2, 626 | gear_thickness = height/2*0.5, 627 | rim_thickness = height/2, 628 | rim_width = 5, 629 | hub_thickness = height/2*1.2, 630 | hub_diameter=15, 631 | bore_diameter=5, 632 | circles=circles, 633 | twist=twist/teeth); 634 | mirror([0,0,1]) 635 | gear (number_of_teeth=teeth, 636 | circular_pitch=700, 637 | pressure_angle=pressure_angle, 638 | clearance = 0.2, 639 | gear_thickness = height/2, 640 | rim_thickness = height/2, 641 | rim_width = 5, 642 | hub_thickness = height/2, 643 | hub_diameter=15, 644 | bore_diameter=5, 645 | circles=circles, 646 | twist=twist/teeth); 647 | } 648 | } 649 | 650 | module test_backlash () 651 | { 652 | backlash = 2; 653 | teeth = 15; 654 | 655 | translate ([-29.166666,0,0]) 656 | { 657 | translate ([58.3333333,0,0]) 658 | rotate ([0,0,-360/teeth/4]) 659 | gear ( 660 | number_of_teeth = teeth, 661 | circular_pitch=700, 662 | gear_thickness = 12, 663 | rim_thickness = 15, 664 | rim_width = 5, 665 | hub_thickness = 17, 666 | hub_diameter=15, 667 | bore_diameter=5, 668 | backlash = 2, 669 | circles=8); 670 | 671 | rotate ([0,0,360/teeth/4]) 672 | gear ( 673 | number_of_teeth = teeth, 674 | circular_pitch=700, 675 | gear_thickness = 12, 676 | rim_thickness = 15, 677 | rim_width = 5, 678 | hub_thickness = 17, 679 | hub_diameter=15, 680 | bore_diameter=5, 681 | backlash = 2, 682 | circles=8); 683 | } 684 | 685 | color([0,0,128,0.5]) 686 | translate([0,0,-5]) 687 | cylinder ($fn=20,r=backlash / 4,h=25); 688 | } 689 | 690 | --------------------------------------------------------------------------------