Source code for boxes.generators.planetary2

#!/usr/bin/env python3
# Copyright (C) 2013-2016 Florian Festi
#
#   This program is free software: you can redistribute it and/or modify
#   it under the terms of the GNU General Public License as published by
#   the Free Software Foundation, either version 3 of the License, or
#   (at your option) any later version.
#
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with this program.  If not, see <http://www.gnu.org/licenses/>.

from boxes import *
import math

[docs]class Planetary2(Boxes): """Balanced force Difference Planetary Gear""" ui_group = "Part" def __init__(self): Boxes.__init__(self) self.buildArgParser("nema_mount") self.argparser.add_argument( "--profile", action="store", type=str, default="GT2_2mm", choices=pulley.Pulley.getProfiles(), help="profile of the teeth/belt") self.argparser.add_argument( "--sunteeth", action="store", type=int, default=20, help="number of teeth on sun gear") self.argparser.add_argument( "--planetteeth", action="store", type=int, default=20, help="number of teeth on planets") self.argparser.add_argument( "--maxplanets", action="store", type=int, default=0, help="limit the number of planets (0 for as much as fit)") self.argparser.add_argument( "--deltateeth", action="store", type=int, default=1, help="enable secondary ring with given delta to the ring gear") self.argparser.add_argument( "--modulus", action="store", type=float, default=3, help="modulus of the theeth in mm") self.argparser.add_argument( "--shaft", action="store", type=float, default=6., help="diameter of the shaft") self.argparser.add_argument( "--screw1", action="store", type=float, default=2.4, help="diameter of lower part of the screw hole") self.argparser.add_argument( "--screw2", action="store", type=float, default=4., help="diameter of upper part of the screw hole") self.argparser.add_argument( "--pinsize", action="store", type=float, default=3.1, help="diameter of alignment pins") # self.argparser.add_argument( # "--stages", action="store", type=int, default=4, # help="number of stages in the gear reduction") def pins(self, r, rh, nr=0, angle=0.0): self.moveTo(0, 0, angle) if nr < 8: ang = 20 + 10 * nr else: ang = 15 + 10 * (nr-8) ang = 180 - ang for a in (0, ang, -ang): self.moveTo(0, 0, a) self.hole(r, 0, rh) self.moveTo(0, 0, -a) def render(self): ringteeth = self.sunteeth + 2 * self.planetteeth t = self.thickness spoke_width = 4 * t pinsize = self.pinsize / 2. pitch1, size1, xxx = self.gears.sizes(teeth=self.sunteeth, dimension=self.modulus) pitch2, size2, xxx = self.gears.sizes(teeth=self.planetteeth, dimension=self.modulus) pitch3, size3, xxx = self.gears.sizes( teeth=ringteeth, internal_ring=True, spoke_width=spoke_width, dimension=self.modulus) planets = int(math.pi / (math.asin(float(self.planetteeth + 2) / (self.planetteeth + self.sunteeth)))) if self.maxplanets: planets = min(self.maxplanets, planets) # Make sure the teeth mash ta = self.sunteeth + ringteeth # There are sunteeth+ringteeth mashing positions for the planets planetpositions = [round(i * ta / planets) * 360 / ta for i in range(planets)] secondary_offsets = [((pos % (360. / (ringteeth - self.deltateeth))) - (pos % (360. / ringteeth)) * ringteeth / self.planetteeth) for pos in planetpositions] ratio = (1 + (ringteeth / self.sunteeth)) * (-ringteeth/self.deltateeth) # XXX make configurable? profile_shift = 20 pressure_angle = 20 screw = self.screw1 / 2 # output # XXX simple guess belt = self.profile pulleyteeth = int((size3-2*t) * math.pi / pulley.Pulley.spacing[belt][1]) numplanets = planets deltamodulus = self.modulus * ringteeth / (ringteeth - self.deltateeth) def holes(r): def h(): self.hole(2*t, 2*t, r) self.hole(size3-2*t, 2*t, r) self.hole(2*t, size3-2*t, r) self.hole(size3-2*t, size3-2*t, r) return h def planets(): self.moveTo(size3/2, size3/2) for angle in planetpositions: angle += 180 # compensate for 3 postion in callback self.moveTo(0, 0, angle) self.hole((pitch1+pitch2), 0, size2/2) self.moveTo(0, 0, -angle) # Base self.rectangularWall(size3, size3, callback=[ lambda: self.NEMA(self.nema_mount, size3 / 2, size3 / 2), holes(screw), planets], move="up") def gear(): self.moveTo(size3 / 2, size3 / 2) self.gears(teeth=ringteeth, dimension=self.modulus, angle=pressure_angle, internal_ring=True, spoke_width=spoke_width, teeth_only=True, profile_shift=profile_shift, move="up") # Lower primary ring gear self.rectangularWall(size3, size3, callback=[gear, holes(screw)], move="up") tl = 0.5*size3*(2**0.5-1)*2**0.5 screw = self.screw2 / 2 self.rectangularTriangle(tl, tl, num=8, callback=[ None, lambda:self.hole(2*t, 2*t, screw)], move='up') # Secondary ring gears def ring(): self.gears(teeth=ringteeth - self.deltateeth, dimension=deltamodulus, angle=pressure_angle, internal_ring=True, spoke_width=spoke_width, teeth_only=True, profile_shift=profile_shift) for i in range(3): self.hole((size3-6*t)/2+0.5*pinsize, 0, pinsize) self.moveTo(0, 0, 120) self.pulley(pulleyteeth, belt, callback=ring, move="up") self.pulley(pulleyteeth, belt, callback=ring, move="up") # Upper primary ring gear self.rectangularWall(size3, size3, callback=[gear, holes(screw)], move="up") # top cover plate self.rectangularWall(size3, size3, callback=[holes(screw)], move="up") # Sun gear def sunpins(): self.hole(0.5*self.shaft+1.5*pinsize ,0, pinsize) self.hole(-0.5*self.shaft-1.5*pinsize ,0, pinsize) self.partsMatrix(4, 4, 'up', self.gears, teeth=self.sunteeth, dimension=self.modulus, callback=sunpins, angle=pressure_angle, mount_hole=self.shaft, profile_shift=profile_shift) # Planets for i in range(numplanets): with self.saved_context(): self.gears(teeth=self.planetteeth, dimension=self.modulus, angle=pressure_angle, callback=lambda:self.pins(0.25*size2, pinsize, i), profile_shift=profile_shift, move="right") for j in range(2): self.gears(teeth=self.planetteeth, dimension=self.modulus, angle=pressure_angle, callback=lambda:self.pins(0.25*size2, pinsize, i, secondary_offsets[i]), profile_shift=profile_shift, move="right") self.gears(teeth=self.planetteeth, dimension=self.modulus, angle=pressure_angle, callback=lambda:self.pins(0.25*size2, pinsize, i), profile_shift=profile_shift, move="right") self.gears(teeth=self.planetteeth, dimension=self.modulus, angle=pressure_angle, profile_shift=profile_shift, move="up only") self.text("1:%.1f" % abs(ratio))