boxespy/boxes/generators/planetary.py

119 lines
4.6 KiB
Python
Raw Normal View History

2016-07-25 18:50:36 +02:00
#!/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
2016-08-17 15:07:41 +02:00
2016-07-25 18:50:36 +02:00
class Planetary(Boxes):
2016-08-22 20:46:53 +02:00
"""Planetary Gear with possibly multiple identical stages"""
2016-08-17 15:07:41 +02:00
ui_group = "Part"
2016-07-25 18:50:36 +02:00
def __init__(self):
Boxes.__init__(self)
self.argparser.add_argument(
2016-08-17 15:07:41 +02:00
"--sunteeth", action="store", type=int, default=8,
2016-07-25 18:50:36 +02:00
help="number of teeth on sun gear")
self.argparser.add_argument(
2016-08-17 15:07:41 +02:00
"--planetteeth", action="store", type=int, default=20,
2016-07-25 18:50:36 +02:00
help="number of teeth on planets")
self.argparser.add_argument(
2016-08-17 15:07:41 +02:00
"--maxplanets", action="store", type=int, default=0,
help="limit the number of planets (0 for as much as fit)")
self.argparser.add_argument(
2016-08-17 15:07:41 +02:00
"--deltateeth", action="store", type=int, default=0,
help="enable secondary ring with given delta to the ring gear")
2016-07-25 18:50:36 +02:00
self.argparser.add_argument(
2016-08-17 15:07:41 +02:00
"--modulus", action="store", type=float, default=3,
2016-07-25 18:50:36 +02:00
help="modulus of the theeth in mm")
self.argparser.add_argument(
2016-08-17 15:07:41 +02:00
"--shaft", action="store", type=float, default=6.,
2016-07-25 18:50:36 +02:00
help="diameter of the shaft")
2016-08-17 15:07:41 +02:00
# self.argparser.add_argument(
2016-07-25 18:50:36 +02:00
# "--stages", action="store", type=int, default=4,
# help="number of stages in the gear reduction")
def render(self):
# Initialize canvas
self.open()
2016-08-17 15:07:41 +02:00
ringteeth = self.sunteeth + 2 * self.planetteeth
spoke_width = 3 * self.shaft
2016-07-25 18:50:36 +02:00
pitch1, size1, xxx = self.gears.sizes(teeth=self.sunteeth,
2016-08-17 15:07:41 +02:00
dimension=self.modulus)
2016-07-25 18:50:36 +02:00
pitch2, size2, xxx = self.gears.sizes(teeth=self.planetteeth,
2016-08-17 15:07:41 +02:00
dimension=self.modulus)
2016-07-25 18:50:36 +02:00
pitch3, size3, xxx = self.gears.sizes(
teeth=ringteeth, internal_ring=True, spoke_width=spoke_width,
2016-07-25 18:50:36 +02:00
dimension=self.modulus)
t = self.thickness
planets = int(math.pi / (math.asin(float(self.planetteeth + 2) / (self.planetteeth + self.sunteeth))))
2016-08-17 15:07:41 +02:00
if self.maxplanets:
planets = min(self.maxplanets, planets)
2016-07-25 18:50:36 +02:00
# Make sure the teeth mash
2016-08-17 15:07:41 +02:00
ta = self.sunteeth + ringteeth
2016-07-25 18:50:36 +02:00
# There are sunteeth+ringteeth mashing positions for the planets
if ta % planets:
2016-08-17 15:07:41 +02:00
planetpositions = [round(i * ta / planets) * 360 / ta for i in range(planets)]
2016-07-25 18:50:36 +02:00
else:
planetpositions = planets
# XXX make configurable?
profile_shift = 20
pressure_angle = 20
2016-08-17 15:07:41 +02:00
self.parts.disc(size3, callback=lambda: self.hole(0, 0, self.shaft / 2), move="up")
2016-07-25 18:50:36 +02:00
self.gears(teeth=ringteeth, dimension=self.modulus,
angle=pressure_angle, internal_ring=True,
spoke_width=spoke_width, mount_hole=self.shaft,
profile_shift=profile_shift, move="up")
2016-08-17 15:07:41 +02:00
self.gears.gearCarrier(pitch1 + pitch2, spoke_width, planetpositions,
2 * spoke_width, self.shaft / 2, move="up")
2016-07-25 18:50:36 +02:00
self.gears(teeth=self.sunteeth, dimension=self.modulus,
angle=pressure_angle,
mount_hole=self.shaft, profile_shift=profile_shift, move="up")
numplanets = planets
2016-08-17 15:07:41 +02:00
if self.deltateeth:
numplanets += planets
2016-08-17 15:07:41 +02:00
deltamodulus = self.modulus * ringteeth / (ringteeth - self.deltateeth)
self.gears(teeth=ringteeth - self.deltateeth, dimension=deltamodulus,
angle=pressure_angle, internal_ring=True,
spoke_width=spoke_width, mount_hole=self.shaft,
profile_shift=profile_shift, move="up")
for i in range(numplanets):
2016-07-25 18:50:36 +02:00
self.gears(teeth=self.planetteeth, dimension=self.modulus,
angle=pressure_angle,
mount_hole=self.shaft, profile_shift=profile_shift, move="up")
2016-08-17 15:07:41 +02:00
2016-07-25 18:50:36 +02:00
self.close()
2016-08-17 15:07:41 +02:00
2016-07-25 18:50:36 +02:00
def main():
b = Planetary()
2016-07-25 18:50:36 +02:00
b.parseArgs()
b.render()
2016-08-17 15:07:41 +02:00
2016-07-25 18:50:36 +02:00
if __name__ == '__main__':
main()