0% found this document useful (0 votes)
82 views

Compound Gear Train Python

This document describes functions for modeling compound gear trains. It defines functions to calculate the gear ratios and error for a given input gear ratio and allowable number of gear stages. It also defines functions for generating individual gear shapes and combining multiple gears by translation and rotation to model a compound gear train. The functions are used to find the gear ratios and number of stages needed to achieve a target 30:400 gear ratio within 0.1% error using up to 5 stages, and the resulting gear train is plotted.

Uploaded by

Jorge Lara
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
82 views

Compound Gear Train Python

This document describes functions for modeling compound gear trains. It defines functions to calculate the gear ratios and error for a given input gear ratio and allowable number of gear stages. It also defines functions for generating individual gear shapes and combining multiple gears by translation and rotation to model a compound gear train. The functions are used to find the gear ratios and number of stages needed to achieve a target 30:400 gear ratio within 0.1% error using up to 5 stages, and the resulting gear train is plotted.

Uploaded by

Jorge Lara
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 7

5/3/2019 Compound-Gear-Train

In [7]: from math import *


import matplotlib.pyplot as plt
import numpy as np
%matplotlib nbagg

In [8]: def compound_train(mv, maxstages=5, eps=0.001):


r = (mv)**(-1)
n = 1
while True and n < maxstages:
N1, N2 = nstage(r, n, eps)
if not(N1 is None):
if isacceptable((N1/N2)**n, mv, eps):
break
n += 1
if N1 is None:
print("Solution not found")
return None
mvc = (N1/N2)**n
err = abs((mv-mvc)/mv)
return N1,N2,n,err

def nstage(r,n,eps):
f = r**(1/n)
if f > 10:
return None, None
for N1 in range(14,20):
N2 = N1*f
if isacceptable(N2,round(N2),eps):
return N1,round(N2)
return None,None

def isacceptable(xreal,xcalc,eps=0.2/100):
err = abs((xreal-xcalc)/xreal)
if err >= eps:
return False
return True

def draw_train(N1,N2,n,Pd,pa=20):
for k in range(n):
dx1,dy1 = gears_make_gear(pa, N1, Pd)
dx2,dy2 = gears_make_gear(pa, N2, Pd)
C = 0.5*(N1/Pd) + 0.5*(N2/Pd)
plt.fill(np.array(dx1)+C*(k-1), dy1)
plt.fill(np.array(dx2)+C*k, np.array(dy2))
plt.axis('square')

http://localhost:8888/notebooks/Google%20Drive/Scribd%20Gen/Compound-Gear-Train.ipynb# 1/7
5/3/2019 Compound-Gear-Train

In [9]: N1,N2,n,*_ = compound_train(30/400, eps=1/100)


Pd = 14
draw_train(N1,N2,n,Pd)

Figure 1 

     

In [ ]:

In [ ]:

In [ ]:

http://localhost:8888/notebooks/Google%20Drive/Scribd%20Gen/Compound-Gear-Train.ipynb# 2/7
5/3/2019 Compound-Gear-Train

In [6]: import math

# =================================================================================
# =================================================================================
# Spur-gear generation script
# (c) James Gregson, 2012
# Free for all use, including commercial, but do not redistribute.
# Use at your own risk.
#
# Notes:
# - seems to work well for pressure angles up to about 30 degrees
# =================================================================================
# =================================================================================

# compute the root diameter of a gear with a given pressure-angle (pa)


# number of teeth (N), and pitch (P)
def gears_root_diameter( pa, N, P ):
return (N-2.5)/P

# compute the base diameter of a gear with a given pressure-angle (pa)


# number of teeth (N), and pitch (P)
def gears_base_diameter( pa, N, P ):
return gears_pitch_diameter( pa, N, P )*math.cos( pa*math.pi/180.0 )

# compute the outer diameter of a gear with a given pressure-angle (pa)


# number of teeth (N), and pitch (P)
def gears_outer_diameter( pa, N, P ):
return gears_pitch_diameter( pa, N, P ) + 2.0*gears_addendum( pa, N, P )

# compute the outer diameter of a gear with a given pressure-angle (pa)


# number of teeth (N), and pitch (P)
def gears_pitch_diameter( pa, N, P ):
return float(N)/float(P)

# compute the outer diameter of a gear with a given pressure-angle (pa)


# number of teeth (N) and pitch (P)
def gears_circular_pitch( pa, N, P ):
return math.pi/float(P)

# compute the circular tooth thickness of a gear with a given


# pressure-angle (pa), number of teeth (N) and pitch (P)
def gears_circular_tooth_thickness( pa, N, P, backlash=0.05 ):
return gears_circular_pitch( pa, N, P )/(2.0+backlash)

# compute the circular tooth angle of a gear with a given


# pressure-angle (pa), number of teeth (N) and pitch (P)
def gears_circular_tooth_angle( pa, N, P ):
return gears_circular_tooth_thickness( pa, N, P )*2.0/gears_pitch_diameter( pa, N, P )

# compute the addendum height for a gear with a given


# pressure-angle (pa), number of teeth (N) and pitch (P)
def gears_addendum( pa, N, P ):
return 1.0/float(P)

# compute the dedendum depth for a gear with a given


# pressur-angle (pa), number of teeth (N) and pitch (P)
def gears_dedendum( pa, N, P ):
return 1.25/float(P)

# generates an involute curve from a circle of radius r up to theta_max radians


# with a specified number of steps
def gears_generate_involute( r, r_max, theta_max, steps=80 ):
dtheta = theta_max / float(steps)
x = []
y = []
theta = []
rlast = r;
for i in range( 0, steps+1 ):
c = math.cos( i*dtheta )
s = math.sin( i*dtheta )
tx = r*( c + i*dtheta*s )

http://localhost:8888/notebooks/Google%20Drive/Scribd%20Gen/Compound-Gear-Train.ipynb# 3/7
5/3/2019 Compound-Gear-Train
ty = r*( s - i*dtheta*c )
d = math.sqrt(tx*tx+ty*ty)
if d > r_max:
a = (r_max-rlast)/(d-rlast)
tx = x[-1]*(1.0-a) + tx*a
ty = y[-1]*(1.0-a) + ty*a
ttheta = theta[-1]*(1.0-a) + math.atan2( ty, tx )*a
x.append( tx )
y.append( ty )
theta.append( ttheta )
break
else:
x.append( tx )
y.append( ty )
theta.append( math.atan2( ty, tx) )
return x, y, theta

# returns the angle where an involute curve crosses a circle with a given radius
# or -1 on failure
def gears_locate_involute_cross_angle_for_radius( r, ix, iy, itheta ):
for i in range( 0, len(ix)-1 ):
r2 = ix[i+1]*ix[i+1] + iy[i+1]*iy[i+1]
if r2 > r*r:
r1 = math.sqrt( ix[i]*ix[i] + iy[i]*iy[i] )
r2 = math.sqrt( r2 )
a = (r-r1)/(r2-r1)
return itheta[i]*(1.0-a) + itheta[i+1]*a
return -1.0

# rotates the involute curve around the gear center in order to have the involute
# cross the x-axis at the pitch diameter
def gears_align_involute( Dp, ix, iy, itheta ):
theta = -gears_locate_involute_cross_angle_for_radius( Dp/2.0, ix, iy, itheta )
c = math.cos(theta)
s = math.sin(theta)
for i in range( 0, len(ix) ):
tx = c*ix[i] - s*iy[i]
ty = s*ix[i] + c*iy[i]
ix[i] = tx
iy[i] = ty
return ix, iy

# reflects the input curve about the x-axis to generate the opposing face of
# a tooth
def gears_mirror_involute( ix, iy ):
tx = []
ty = []
for i in range( 0, len(iy) ):
tx.append( ix[len(iy)-1-i] )
ty.append( -iy[len(iy)-1-i] )
return tx, ty

# rotates the input curve by a given angle (in radians)


def gears_rotate( theta, ix, iy ):
c = math.cos(theta)
s = math.sin(theta)
x = []
y = []
for i in range( 0, len(ix) ):
tx = c*ix[i] - s*iy[i]
ty = s*ix[i] + c*iy[i]
x.append( tx )
y.append( ty )
return x, y

# translates the input curve by [dx, dy]


def gears_translate( dx, dy, ix, iy ):
x = []
y = []
for i in range( 0, len(ix) ):
x.append( ix[i]+dx )
y.append( iy[i]+dy )
http://localhost:8888/notebooks/Google%20Drive/Scribd%20Gen/Compound-Gear-Train.ipynb# 4/7
5/3/2019 Compound-Gear-Train
return x, y

# generates a single tooth profile of a spur gear


def gears_make_tooth( pa, N, P ):
ix, iy, itheta = gears_generate_involute( gears_base_diameter( pa, N, P )/2.0, gears_outer_diameter( p
ix.insert( 0, min( gears_base_diameter( pa, N, P )/2.0, gears_root_diameter( pa, N, P )/2.0 ) )
iy.insert( 0, 0.0 )
itheta.insert( 0, 0.0 )
ix, iy = gears_align_involute( gears_pitch_diameter(pa, N, P), ix, iy, itheta )
mx, my = gears_mirror_involute( ix, iy )
mx, my = gears_rotate( gears_circular_tooth_angle( pa, N, P ), mx, my )
ix.extend( mx )
iy.extend( my )
return ix, iy

# generates a spur gear with a given pressure angle (pa),


# number of teeth (N) and pitch (P)
def gears_make_gear( pa, N, P ):
tx, ty = gears_make_tooth( pa, N, P )
x = []
y = []
for i in range( 0, N ):
rx, ry = gears_rotate( float(i)*2.0*math.pi/float(N), tx, ty )
x.extend( rx )
y.extend( ry )
x.append( x[0] )
y.append( y[0] )
return x, y

# write output as svg, for laser-cutters, graphic design, etc.


def gears_svg_out( px, py, filename, scale=1.0 ):
out = open( filename, 'w' )

minx = min( px )
maxx = max( px )
miny = min( py )
maxy = max( py )
cenx = (minx + maxx)/2.0
ceny = (miny + maxy)/2.0
sx = ( maxx - cenx )*1.1
sy = ( maxy - ceny )*1.1

minx = scale*(cenx - sx)


maxx = scale*(cenx + sx)
miny = scale*(ceny - sy)
maxy = scale*(ceny + sy)

out.write('<?xml version="1.0" standalone="no" ?>\n' )


out.write('<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg1
out.write('<svg xmlns="http://www.w3.org/2000/svg" version="1.1" x="%fpx" y="%fpx" width="%fpx" height
out.write('<polyline style="fill:none;stroke:black;stroke-width:1" points="' );

for i in range( 0, len(px) ):


out.write( '%f,%f ' % ( scale*(px[i]+sx), scale*(py[i]+sy) ) )

out.write('" />\n' )
out.write('</svg>\n')
out.close()

# write output as dxf profile in x-y plane, for use with OpenSCAD
def gears_dxf_out( px, py, filename, scale=1.0 ):
out = open( filename, 'w' )
out.write(' 0\n')
out.write('SECTION\n')
out.write(' 2\n')
out.write('HEADER\n')
out.write('999\n')
out.write('%s by gears.py\n' % filename )
out.write('999\n')
out.write('contact [email protected] for gears.py details\n')
out.write(' 0\n')
out.write('ENDSEC\n')
http://localhost:8888/notebooks/Google%20Drive/Scribd%20Gen/Compound-Gear-Train.ipynb# 5/7
5/3/2019 Compound-Gear-Train
out.write(' 0\n')
out.write('SECTION\n')
out.write(' 2\n')
out.write('TABLES\n')
out.write(' 0\n')
out.write('ENDSEC\n')
out.write(' 0\n')
out.write('SECTION\n')
out.write(' 2\n')
out.write('BLOCKS\n')
out.write(' 0\n')
out.write('ENDSEC\n')
out.write(' 0\n')
out.write('SECTION\n')
out.write(' 2\n')
out.write('ENTITIES\n')

for i in range( 0, len(px)-1 ):


out.write(' 0\n')
out.write('LINE\n')
out.write(' 8\n')
out.write(' 2\n')
out.write(' 62\n')
out.write(' 4\n')
out.write(' 10\n')
out.write('%f\n' % (scale*px[i]))
out.write(' 20\n')
out.write('%f\n' % (scale*py[i]))
out.write(' 30\n')
out.write('0.0\n')
out.write(' 11\n')
out.write('%f\n' % (scale*px[i+1]))
out.write(' 21\n')
out.write('%f\n' % (scale*py[i+1]))
out.write(' 31\n')
out.write('0.0\n')

out.write(' 0\n')
out.write('ENDSEC\n')
out.write(' 0\n')
out.write('EOF\n')
out.close()

# import matplotlib.pyplot as plt


# import numpy as np

# pa = 20
# N1 = 12
# N2 = N1*6
# PD = 32
# C = 0.5*(N1/PD) + 0.5*(N2/PD)
# print(C)

# dx,dy = gears_make_gear(pa, N1, PD)


# dx1,dy1 = gears_make_gear(pa, N2, PD)
# plt.plot(dx,dy)
# plt.plot(C + np.array(dx1), np.array(dy1))
# plt.axis('square')
# plt.grid(ls="--")
# plt.show()

In [ ]:

In [ ]:

In [ ]:

http://localhost:8888/notebooks/Google%20Drive/Scribd%20Gen/Compound-Gear-Train.ipynb# 6/7
5/3/2019 Compound-Gear-Train

In [ ]:

http://localhost:8888/notebooks/Google%20Drive/Scribd%20Gen/Compound-Gear-Train.ipynb# 7/7

You might also like