ruff format pygears
This commit is contained in:
@@ -16,4 +16,4 @@
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
|
||||
__version__ = "0.0.4"
|
||||
__version__ = "0.0.4"
|
||||
|
||||
@@ -22,55 +22,61 @@ from numpy.linalg import solve, norm
|
||||
|
||||
|
||||
def reflection(angle):
|
||||
mat = array(
|
||||
[[cos(2 * angle), -sin(2 * angle)], [-sin(2 * angle), -cos(2 * angle)]])
|
||||
mat = array([[cos(2 * angle), -sin(2 * angle)], [-sin(2 * angle), -cos(2 * angle)]])
|
||||
|
||||
def func(x):
|
||||
return(dot(x, mat))
|
||||
return(func)
|
||||
return dot(x, mat)
|
||||
|
||||
return func
|
||||
|
||||
|
||||
def reflection3D(angle):
|
||||
mat = array([[cos(2 * angle), -sin(2 * angle), 0.],
|
||||
[-sin(2 * angle), -cos(2 * angle), 0.], [0., 0., 1.]])
|
||||
mat = array(
|
||||
[
|
||||
[cos(2 * angle), -sin(2 * angle), 0.0],
|
||||
[-sin(2 * angle), -cos(2 * angle), 0.0],
|
||||
[0.0, 0.0, 1.0],
|
||||
]
|
||||
)
|
||||
|
||||
def func(x):
|
||||
return(dot(x, mat))
|
||||
return(func)
|
||||
return dot(x, mat)
|
||||
|
||||
return func
|
||||
|
||||
|
||||
def rotation(angle, midpoint=None):
|
||||
midpoint = midpoint or [0., 0.]
|
||||
mat = array([[cos(angle), -sin(angle)],
|
||||
[sin(angle), cos(angle)]])
|
||||
midpoint = midpoint or [0.0, 0.0]
|
||||
mat = array([[cos(angle), -sin(angle)], [sin(angle), cos(angle)]])
|
||||
midpoint = array(midpoint)
|
||||
vec = midpoint - dot(midpoint, mat)
|
||||
trans = translation(vec)
|
||||
|
||||
def func(xx):
|
||||
return(trans(dot(xx, mat)))
|
||||
return(func)
|
||||
return trans(dot(xx, mat))
|
||||
|
||||
return func
|
||||
|
||||
|
||||
def rotation3D(angle):
|
||||
mat = array(
|
||||
[
|
||||
[cos(angle), -sin(angle), 0.],
|
||||
[sin(angle), cos(angle), 0.],
|
||||
[0., 0., 1.]])
|
||||
[[cos(angle), -sin(angle), 0.0], [sin(angle), cos(angle), 0.0], [0.0, 0.0, 1.0]]
|
||||
)
|
||||
|
||||
def func(xx):
|
||||
return(dot(xx, mat))
|
||||
return(func)
|
||||
return dot(xx, mat)
|
||||
|
||||
return func
|
||||
|
||||
|
||||
def translation(vec):
|
||||
def trans(x):
|
||||
return([x[0] + vec[0], x[1] + vec[1]])
|
||||
return [x[0] + vec[0], x[1] + vec[1]]
|
||||
|
||||
def func(x):
|
||||
return(array(list(map(trans, x))))
|
||||
return(func)
|
||||
return array(list(map(trans, x)))
|
||||
|
||||
return func
|
||||
|
||||
|
||||
def trim(p1, p2, p3, p4):
|
||||
@@ -80,31 +86,31 @@ def trim(p1, p2, p3, p4):
|
||||
a4 = array(p4)
|
||||
if all(a1 == a2) or all(a3 == a4):
|
||||
if all(a1 == a3):
|
||||
return(a1)
|
||||
return a1
|
||||
else:
|
||||
return(False)
|
||||
return False
|
||||
elif all(a1 == a3):
|
||||
if all(a2 == a4):
|
||||
return((a1 + a2) / 2)
|
||||
return (a1 + a2) / 2
|
||||
else:
|
||||
return(a1)
|
||||
return a1
|
||||
elif all(a1 == a4):
|
||||
if all(a2 == a3):
|
||||
return((a1 + a2) / 2)
|
||||
return (a1 + a2) / 2
|
||||
else:
|
||||
return(a1)
|
||||
return a1
|
||||
elif all(a2 == a3) or all(a2 == a4):
|
||||
return(p2)
|
||||
return p2
|
||||
try:
|
||||
g, h = solve(transpose([-a2 + a1, a4 - a3]), a1 - a3)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
return(False)
|
||||
return False
|
||||
else:
|
||||
if 0. < g < 1. and 0. < h < 1.:
|
||||
return(a1 + g * (a2 - a1))
|
||||
if 0.0 < g < 1.0 and 0.0 < h < 1.0:
|
||||
return a1 + g * (a2 - a1)
|
||||
else:
|
||||
return(False)
|
||||
return False
|
||||
|
||||
|
||||
def trimfunc(l1, l2):
|
||||
@@ -124,12 +130,12 @@ def trimfunc(l1, l2):
|
||||
l2 == [l2[0]]
|
||||
else:
|
||||
l2 = l2[jk::-1]
|
||||
return([vstack([l1, [s]]), vstack([[s], l2])])
|
||||
return [vstack([l1, [s]]), vstack([[s], l2])]
|
||||
j0 = j
|
||||
jk += 1
|
||||
i0 = i
|
||||
ik += 1
|
||||
return(False)
|
||||
return False
|
||||
|
||||
|
||||
def diff_norm(vec1, vec2):
|
||||
@@ -141,7 +147,7 @@ def nearestpts(evolv, underc):
|
||||
ik = 0
|
||||
iout = 0
|
||||
jout = 0
|
||||
outmin = 1000.
|
||||
outmin = 1000.0
|
||||
for i in array(evolv[1:]):
|
||||
jk = 0
|
||||
for j in array(underc[1:]):
|
||||
@@ -154,17 +160,17 @@ def nearestpts(evolv, underc):
|
||||
iout, jout = [ik, jk]
|
||||
jk += 1
|
||||
ik += 1
|
||||
return([vstack([underc[:jout], evolv[iout]]), evolv[iout:]])
|
||||
return [vstack([underc[:jout], evolv[iout]]), evolv[iout:]]
|
||||
|
||||
|
||||
def intersection_line_circle(p1, p2, r):
|
||||
"""return the intersection point of a line from p1 to p2 and a sphere of radius 1 and
|
||||
"""return the intersection point of a line from p1 to p2 and a sphere of radius 1 and
|
||||
midpoint 0,0,0"""
|
||||
d = p2 - p1
|
||||
d /= norm(d)
|
||||
p_half = d.dot(p1)
|
||||
q = p1.dot(p1) - r ** 2
|
||||
t = -p_half + sqrt(p_half ** 2 - q)
|
||||
q = p1.dot(p1) - r**2
|
||||
t = -p_half + sqrt(p_half**2 - q)
|
||||
return p1 + d * t
|
||||
|
||||
|
||||
@@ -176,5 +182,3 @@ def arc_from_points_and_center(p_1, p_2, m):
|
||||
v /= norm(v)
|
||||
p_12 = m + v * r
|
||||
return (p_1, p_12, p_2)
|
||||
|
||||
|
||||
@@ -18,13 +18,32 @@
|
||||
|
||||
from __future__ import division
|
||||
from __future__ import division
|
||||
from numpy import cos, sin, tan, arccos, arctan, pi, array, linspace, transpose, vstack, sqrt
|
||||
from numpy import (
|
||||
cos,
|
||||
sin,
|
||||
tan,
|
||||
arccos,
|
||||
arctan,
|
||||
pi,
|
||||
array,
|
||||
linspace,
|
||||
transpose,
|
||||
vstack,
|
||||
sqrt,
|
||||
)
|
||||
from ._functions import rotation3D, reflection3D, intersection_line_circle
|
||||
|
||||
|
||||
class BevelTooth(object):
|
||||
def __init__(self, pressure_angle=70 * pi / 180, pitch_angle=pi / 4, clearance=0.1,
|
||||
z=21, backlash=0.00, module=0.25):
|
||||
def __init__(
|
||||
self,
|
||||
pressure_angle=70 * pi / 180,
|
||||
pitch_angle=pi / 4,
|
||||
clearance=0.1,
|
||||
z=21,
|
||||
backlash=0.00,
|
||||
module=0.25,
|
||||
):
|
||||
self.pressure_angle = pressure_angle
|
||||
self.pitch_angle = pitch_angle
|
||||
self.z = z
|
||||
@@ -34,58 +53,146 @@ class BevelTooth(object):
|
||||
self.module = module
|
||||
|
||||
self.involute_end = arccos(
|
||||
1 / sqrt(2) * sqrt((42. + 16.*cos(2.*self.pressure_angle) +
|
||||
6.*cos(4.*self.pressure_angle) + cos(4.*self.pressure_angle - 4.*self.pitch_angle) - 8.*cos(2.*self.pressure_angle - 2.*self.pitch_angle) -
|
||||
4.*cos(4.*self.pressure_angle - 2.*self.pitch_angle) + 24.*cos(2.*self.pitch_angle) - 2.*cos(4.*self.pitch_angle) -
|
||||
8.*cos(2.*(self.pressure_angle + self.pitch_angle)) + cos(4.*(self.pressure_angle + self.pitch_angle)) -
|
||||
4.*cos(4.*self.pressure_angle + 2.*self.pitch_angle) + 24.*cos((4.*sin(self.pitch_angle))/self.z) +
|
||||
4.*cos(2.*self.pressure_angle - (4.*sin(self.pitch_angle))/self.z) + 4.*cos(2.*self.pressure_angle -
|
||||
4.*self.pitch_angle - (4.*sin(self.pitch_angle))/self.z) - 8.*cos(2.*self.pressure_angle - 2.*self.pitch_angle -
|
||||
(4.*sin(self.pitch_angle))/self.z) + 24.*cos(4.*(self.pitch_angle + sin(self.pitch_angle)/self.z)) -
|
||||
8.*cos(2.*(self.pressure_angle + self.pitch_angle + (2.*sin(self.pitch_angle))/self.z)) + 4.*cos(2.*self.pressure_angle +
|
||||
(4.*sin(self.pitch_angle))/self.z) + 16.*cos(2.*self.pitch_angle + (4.*sin(self.pitch_angle))/self.z) +
|
||||
4.*cos(2.*self.pressure_angle + 4.*self.pitch_angle + (4.*sin(self.pitch_angle))/self.z) + 32.*abs(cos(self.pitch_angle +
|
||||
(2.*sin(self.pitch_angle))/self.z))*cos(self.pressure_angle)*sqrt(4.*cos(2.*self.pressure_angle) -
|
||||
2.*(-2. + cos(2.*self.pressure_angle - 2.*self.pitch_angle) - 2.*cos(2.*self.pitch_angle) + cos(2.*(self.pressure_angle + self.pitch_angle)) +
|
||||
4.*cos(2.*self.pitch_angle + (4.*sin(self.pitch_angle))/self.z)))*sin(2.*self.pitch_angle))/(-6. - 2.*cos(2.*self.pressure_angle) +
|
||||
cos(2.*self.pressure_angle - 2.*self.pitch_angle) - 2.*cos(2.*self.pitch_angle) + cos(2.*(self.pressure_angle + self.pitch_angle)))**2))
|
||||
1
|
||||
/ sqrt(2)
|
||||
* sqrt(
|
||||
(
|
||||
42.0
|
||||
+ 16.0 * cos(2.0 * self.pressure_angle)
|
||||
+ 6.0 * cos(4.0 * self.pressure_angle)
|
||||
+ cos(4.0 * self.pressure_angle - 4.0 * self.pitch_angle)
|
||||
- 8.0 * cos(2.0 * self.pressure_angle - 2.0 * self.pitch_angle)
|
||||
- 4.0 * cos(4.0 * self.pressure_angle - 2.0 * self.pitch_angle)
|
||||
+ 24.0 * cos(2.0 * self.pitch_angle)
|
||||
- 2.0 * cos(4.0 * self.pitch_angle)
|
||||
- 8.0 * cos(2.0 * (self.pressure_angle + self.pitch_angle))
|
||||
+ cos(4.0 * (self.pressure_angle + self.pitch_angle))
|
||||
- 4.0 * cos(4.0 * self.pressure_angle + 2.0 * self.pitch_angle)
|
||||
+ 24.0 * cos((4.0 * sin(self.pitch_angle)) / self.z)
|
||||
+ 4.0
|
||||
* cos(
|
||||
2.0 * self.pressure_angle
|
||||
- (4.0 * sin(self.pitch_angle)) / self.z
|
||||
)
|
||||
+ 4.0
|
||||
* cos(
|
||||
2.0 * self.pressure_angle
|
||||
- 4.0 * self.pitch_angle
|
||||
- (4.0 * sin(self.pitch_angle)) / self.z
|
||||
)
|
||||
- 8.0
|
||||
* cos(
|
||||
2.0 * self.pressure_angle
|
||||
- 2.0 * self.pitch_angle
|
||||
- (4.0 * sin(self.pitch_angle)) / self.z
|
||||
)
|
||||
+ 24.0
|
||||
* cos(4.0 * (self.pitch_angle + sin(self.pitch_angle) / self.z))
|
||||
- 8.0
|
||||
* cos(
|
||||
2.0
|
||||
* (
|
||||
self.pressure_angle
|
||||
+ self.pitch_angle
|
||||
+ (2.0 * sin(self.pitch_angle)) / self.z
|
||||
)
|
||||
)
|
||||
+ 4.0
|
||||
* cos(
|
||||
2.0 * self.pressure_angle
|
||||
+ (4.0 * sin(self.pitch_angle)) / self.z
|
||||
)
|
||||
+ 16.0
|
||||
* cos(
|
||||
2.0 * self.pitch_angle + (4.0 * sin(self.pitch_angle)) / self.z
|
||||
)
|
||||
+ 4.0
|
||||
* cos(
|
||||
2.0 * self.pressure_angle
|
||||
+ 4.0 * self.pitch_angle
|
||||
+ (4.0 * sin(self.pitch_angle)) / self.z
|
||||
)
|
||||
+ 32.0
|
||||
* abs(
|
||||
cos(self.pitch_angle + (2.0 * sin(self.pitch_angle)) / self.z)
|
||||
)
|
||||
* cos(self.pressure_angle)
|
||||
* sqrt(
|
||||
4.0 * cos(2.0 * self.pressure_angle)
|
||||
- 2.0
|
||||
* (
|
||||
-2.0
|
||||
+ cos(2.0 * self.pressure_angle - 2.0 * self.pitch_angle)
|
||||
- 2.0 * cos(2.0 * self.pitch_angle)
|
||||
+ cos(2.0 * (self.pressure_angle + self.pitch_angle))
|
||||
+ 4.0
|
||||
* cos(
|
||||
2.0 * self.pitch_angle
|
||||
+ (4.0 * sin(self.pitch_angle)) / self.z
|
||||
)
|
||||
)
|
||||
)
|
||||
* sin(2.0 * self.pitch_angle)
|
||||
)
|
||||
/ (
|
||||
-6.0
|
||||
- 2.0 * cos(2.0 * self.pressure_angle)
|
||||
+ cos(2.0 * self.pressure_angle - 2.0 * self.pitch_angle)
|
||||
- 2.0 * cos(2.0 * self.pitch_angle)
|
||||
+ cos(2.0 * (self.pressure_angle + self.pitch_angle))
|
||||
)
|
||||
** 2
|
||||
)
|
||||
)
|
||||
|
||||
self.involute_start = -pi/2. + \
|
||||
arctan(1/tan(self.pitch_angle)*1/cos(self.pressure_angle))
|
||||
self.involute_start = -pi / 2.0 + arctan(
|
||||
1 / tan(self.pitch_angle) * 1 / cos(self.pressure_angle)
|
||||
)
|
||||
self.involute_start_radius = self.get_radius(self.involute_start)
|
||||
self.r_f = sin(self.pitch_angle - sin(pitch_angle) * 2 /
|
||||
self.z) - self.clearance * sin(self.pitch_angle)
|
||||
self.r_f = sin(
|
||||
self.pitch_angle - sin(pitch_angle) * 2 / self.z
|
||||
) - self.clearance * sin(self.pitch_angle)
|
||||
self.z_f = cos(self.pitch_angle - sin(pitch_angle) * 2 / self.z)
|
||||
self.add_foot = True
|
||||
|
||||
def involute_function_x(self):
|
||||
def func(s):
|
||||
return((
|
||||
-(cos(s*1/sin(self.pressure_angle)*1/sin(self.pitch_angle))*sin(self.pressure_angle)*sin(s)) +
|
||||
(cos(s)*sin(self.pitch_angle) + cos(self.pressure_angle)*cos(self.pitch_angle)*sin(s)) *
|
||||
sin(s*1/sin(self.pressure_angle)*1/sin(self.pitch_angle))))
|
||||
return(func)
|
||||
return -(
|
||||
cos(s * 1 / sin(self.pressure_angle) * 1 / sin(self.pitch_angle))
|
||||
* sin(self.pressure_angle)
|
||||
* sin(s)
|
||||
) + (
|
||||
cos(s) * sin(self.pitch_angle)
|
||||
+ cos(self.pressure_angle) * cos(self.pitch_angle) * sin(s)
|
||||
) * sin(s * 1 / sin(self.pressure_angle) * 1 / sin(self.pitch_angle))
|
||||
|
||||
return func
|
||||
|
||||
def involute_function_y(self):
|
||||
def func(s):
|
||||
return((
|
||||
cos(s*1/sin(self.pressure_angle)*1/sin(self.pitch_angle))*(cos(s)*sin(self.pitch_angle) +
|
||||
cos(self.pressure_angle)*cos(self.pitch_angle)*sin(s)) + sin(self.pressure_angle)*sin(s) *
|
||||
sin(s*1/sin(self.pressure_angle)*1/sin(self.pitch_angle))))
|
||||
return(func)
|
||||
return cos(s * 1 / sin(self.pressure_angle) * 1 / sin(self.pitch_angle)) * (
|
||||
cos(s) * sin(self.pitch_angle)
|
||||
+ cos(self.pressure_angle) * cos(self.pitch_angle) * sin(s)
|
||||
) + sin(self.pressure_angle) * sin(s) * sin(
|
||||
s * 1 / sin(self.pressure_angle) * 1 / sin(self.pitch_angle)
|
||||
)
|
||||
|
||||
return func
|
||||
|
||||
def involute_function_z(self):
|
||||
def func(s):
|
||||
return((
|
||||
cos(self.pitch_angle)*cos(s) - cos(self.pressure_angle)*sin(self.pitch_angle)*sin(s)))
|
||||
return(func)
|
||||
return cos(self.pitch_angle) * cos(s) - cos(self.pressure_angle) * sin(
|
||||
self.pitch_angle
|
||||
) * sin(s)
|
||||
|
||||
return func
|
||||
|
||||
def get_radius(self, s):
|
||||
x = self.involute_function_x()
|
||||
y = self.involute_function_y()
|
||||
rx = x(s)
|
||||
ry = y(s)
|
||||
return(sqrt(rx**2 + ry**2))
|
||||
return sqrt(rx**2 + ry**2)
|
||||
|
||||
def involute_points(self, num=10):
|
||||
pts = linspace(self.involute_start, self.involute_end, num=num)
|
||||
@@ -102,36 +209,40 @@ class BevelTooth(object):
|
||||
|
||||
r_cut = self.r_f / self.z_f
|
||||
for i, point in enumerate(xy[1:]):
|
||||
if point.dot(point) >= r_cut ** 2:
|
||||
if point.dot(point) >= r_cut**2:
|
||||
break
|
||||
if i > 0:
|
||||
self.add_foot = False
|
||||
intersection_point = intersection_line_circle(xy[i], point, r_cut)
|
||||
xy = array([intersection_point] + list(xy[i+1:]))
|
||||
xy = array([intersection_point] + list(xy[i + 1 :]))
|
||||
xyz = [[p[0], p[1], 1] for p in xy]
|
||||
backlash_rot = rotation3D(self.angular_backlash / 2)
|
||||
xyz = backlash_rot(xyz)
|
||||
return(xyz)
|
||||
return xyz
|
||||
|
||||
def points(self, num=10):
|
||||
pts = self.involute_points(num=num)
|
||||
rot = rotation3D(-pi/self.z/2)
|
||||
rot = rotation3D(-pi / self.z / 2)
|
||||
pts = rot(pts)
|
||||
ref = reflection3D(pi/2)
|
||||
ref = reflection3D(pi / 2)
|
||||
pts1 = ref(pts)[::-1]
|
||||
if self.add_foot:
|
||||
return([
|
||||
return [
|
||||
array([pts[0], pts[1]]),
|
||||
array(pts[1:]),
|
||||
array([pts[-1], pts1[0]]),
|
||||
array(pts1[:-1]),
|
||||
array([pts1[-2], pts1[-1]])
|
||||
])
|
||||
array([pts1[-2], pts1[-1]]),
|
||||
]
|
||||
else:
|
||||
return([pts, array([pts[-1], pts1[0]]), pts1])
|
||||
return [pts, array([pts[-1], pts1[0]]), pts1]
|
||||
|
||||
def _update(self):
|
||||
self.__init__(z=self.z, clearance=self.clearance,
|
||||
pressure_angle=self.pressure_angle,
|
||||
pitch_angle=self.pitch_angle,
|
||||
backlash=self.backlash, module=self.module)
|
||||
self.__init__(
|
||||
z=self.z,
|
||||
clearance=self.clearance,
|
||||
pressure_angle=self.pressure_angle,
|
||||
pitch_angle=self.pitch_angle,
|
||||
backlash=self.backlash,
|
||||
module=self.module,
|
||||
)
|
||||
|
||||
@@ -33,7 +33,8 @@ def compute_shifted_gears(m, alpha, t1, t2, x1, x2):
|
||||
Returns:
|
||||
(float, float): distance between gears [length], pressure angle of the assembly [rad]
|
||||
"""
|
||||
def inv(x):
|
||||
|
||||
def inv(x):
|
||||
return np.tan(x) - x
|
||||
|
||||
inv_alpha_w = inv(alpha) + 2 * np.tan(alpha) * (x1 + x2) / (t1 + t2)
|
||||
@@ -42,7 +43,7 @@ def compute_shifted_gears(m, alpha, t1, t2, x1, x2):
|
||||
return inv(x) - inv_alpha_w
|
||||
|
||||
def d_root_inv(x):
|
||||
return 1. / np.cos(x) - 1
|
||||
return 1.0 / np.cos(x) - 1
|
||||
|
||||
alpha_w = find_root(alpha, root_inv, d_root_inv)
|
||||
dist = m * (t1 + t2) / 2 * np.cos(alpha) / np.cos(alpha_w)
|
||||
@@ -61,4 +62,4 @@ def find_root(x0, f, df, epsilon=2e-10, max_iter=100):
|
||||
return None
|
||||
else:
|
||||
x_n = x_n - f_xn / df_xn / 2 # adding (/ 2) to avoid oscillation
|
||||
return None
|
||||
return None
|
||||
|
||||
@@ -21,7 +21,7 @@ from numpy import cos, sin, arccos, pi, array, linspace, transpose, vstack
|
||||
from ._functions import rotation, reflection
|
||||
|
||||
|
||||
class CycloidTooth():
|
||||
class CycloidTooth:
|
||||
def __init__(self, z1=5, z2=5, z=14, m=5, clearance=0.25, backlash=0.00, head=0.0):
|
||||
self.m = m
|
||||
self.z = z
|
||||
@@ -44,40 +44,58 @@ class CycloidTooth():
|
||||
|
||||
def epicycloid_x(self):
|
||||
def func(t):
|
||||
return(((self.d2 + self.d) * cos(t))/2. - (self.d2 * cos((1 + self.d / self.d2) * t))/2.)
|
||||
return(func)
|
||||
return ((self.d2 + self.d) * cos(t)) / 2.0 - (
|
||||
self.d2 * cos((1 + self.d / self.d2) * t)
|
||||
) / 2.0
|
||||
|
||||
return func
|
||||
|
||||
def epicycloid_y(self):
|
||||
def func(t):
|
||||
return(((self.d2 + self.d) * sin(t))/2. - (self.d2 * sin((1 + self.d / self.d2) * t))/2.)
|
||||
return(func)
|
||||
return ((self.d2 + self.d) * sin(t)) / 2.0 - (
|
||||
self.d2 * sin((1 + self.d / self.d2) * t)
|
||||
) / 2.0
|
||||
|
||||
return func
|
||||
|
||||
def hypocycloid_x(self):
|
||||
def func(t):
|
||||
return((self.d - self.d1)*cos(t)/2 + self.d1/2 * cos((self.d / self.d1 - 1) * t))
|
||||
return(func)
|
||||
return (self.d - self.d1) * cos(t) / 2 + self.d1 / 2 * cos(
|
||||
(self.d / self.d1 - 1) * t
|
||||
)
|
||||
|
||||
return func
|
||||
|
||||
def hypocycloid_y(self):
|
||||
def func(t):
|
||||
return((self.d - self.d1)*sin(t)/2 - self.d1/2 * sin((self.d/self.d1 - 1)*t))
|
||||
return(func)
|
||||
return (self.d - self.d1) * sin(t) / 2 - self.d1 / 2 * sin(
|
||||
(self.d / self.d1 - 1) * t
|
||||
)
|
||||
|
||||
return func
|
||||
|
||||
def inner_end(self):
|
||||
return(
|
||||
-((self.d1*arccos((2*self.d1**2 - self.di**2 -
|
||||
2*self.d1*self.d + self.d**2)/(2.*self.d1 *
|
||||
(self.d1 - self.d))))/self.d)
|
||||
return -(
|
||||
(
|
||||
self.d1
|
||||
* arccos(
|
||||
(2 * self.d1**2 - self.di**2 - 2 * self.d1 * self.d + self.d**2)
|
||||
/ (2.0 * self.d1 * (self.d1 - self.d))
|
||||
)
|
||||
)
|
||||
/ self.d
|
||||
)
|
||||
|
||||
def outer_end(self):
|
||||
return(
|
||||
(self.d2*arccos((2*self.d2**2 - self.da**2 +
|
||||
2*self.d2*self.d + self.d**2) /
|
||||
(2.*self.d2*(self.d2 + self.d))))/self.d
|
||||
)
|
||||
return (
|
||||
self.d2
|
||||
* arccos(
|
||||
(2 * self.d2**2 - self.da**2 + 2 * self.d2 * self.d + self.d**2)
|
||||
/ (2.0 * self.d2 * (self.d2 + self.d))
|
||||
)
|
||||
) / self.d
|
||||
|
||||
def points(self, num=10):
|
||||
|
||||
inner_x = self.hypocycloid_x()
|
||||
inner_y = self.hypocycloid_y()
|
||||
outer_x = self.epicycloid_x()
|
||||
@@ -95,12 +113,18 @@ class CycloidTooth():
|
||||
pts1 = vstack([pts_inner[:-2], pts_outer])
|
||||
rot = rotation(self.phipart / 4 - self.angular_backlash / 2)
|
||||
pts1 = rot(pts1)
|
||||
ref = reflection(0.)
|
||||
ref = reflection(0.0)
|
||||
pts2 = ref(pts1)[::-1]
|
||||
one_tooth = [pts1, array([pts1[-1], pts2[0]]), pts2]
|
||||
return(one_tooth)
|
||||
return one_tooth
|
||||
|
||||
def _update(self):
|
||||
self.__init__(m=self.m, z=self.z, z1=self.z1, z2=self.z2,
|
||||
clearance=self.clearance, backlash=self.backlash, head=self.head)
|
||||
|
||||
self.__init__(
|
||||
m=self.m,
|
||||
z=self.z,
|
||||
z1=self.z1,
|
||||
z2=self.z2,
|
||||
clearance=self.clearance,
|
||||
backlash=self.backlash,
|
||||
head=self.head,
|
||||
)
|
||||
|
||||
@@ -17,13 +17,43 @@
|
||||
# ***************************************************************************
|
||||
|
||||
from __future__ import division
|
||||
from numpy import tan, cos, sin, sqrt, arctan, pi, array, linspace, transpose, vstack, ndarray
|
||||
from ._functions import nearestpts, rotation, reflection, trimfunc, diff_norm, translation
|
||||
from numpy import (
|
||||
tan,
|
||||
cos,
|
||||
sin,
|
||||
sqrt,
|
||||
arctan,
|
||||
pi,
|
||||
array,
|
||||
linspace,
|
||||
transpose,
|
||||
vstack,
|
||||
ndarray,
|
||||
)
|
||||
from ._functions import (
|
||||
nearestpts,
|
||||
rotation,
|
||||
reflection,
|
||||
trimfunc,
|
||||
diff_norm,
|
||||
translation,
|
||||
)
|
||||
|
||||
|
||||
class InvoluteTooth():
|
||||
def __init__(self, m=5, z=15, pressure_angle=20 * pi / 180., clearance=0.12, shift=0.5, beta=0.,
|
||||
undercut=False, backlash=0.00, head=0.00, properties_from_tool=False):
|
||||
class InvoluteTooth:
|
||||
def __init__(
|
||||
self,
|
||||
m=5,
|
||||
z=15,
|
||||
pressure_angle=20 * pi / 180.0,
|
||||
clearance=0.12,
|
||||
shift=0.5,
|
||||
beta=0.0,
|
||||
undercut=False,
|
||||
backlash=0.00,
|
||||
head=0.00,
|
||||
properties_from_tool=False,
|
||||
):
|
||||
self.pressure_angle = pressure_angle
|
||||
self.beta = beta
|
||||
self.m_n = m
|
||||
@@ -32,14 +62,13 @@ class InvoluteTooth():
|
||||
self.shift = shift
|
||||
self.clearance = clearance
|
||||
self.backlash = backlash
|
||||
self.head = head # factor, rename!!!
|
||||
self.head = head # factor, rename!!!
|
||||
self.properties_from_tool = properties_from_tool
|
||||
self._calc_gear_factors()
|
||||
|
||||
def _calc_gear_factors(self):
|
||||
if self.properties_from_tool:
|
||||
self.pressure_angle_t = arctan(
|
||||
tan(self.pressure_angle) / cos(self.beta))
|
||||
self.pressure_angle_t = arctan(tan(self.pressure_angle) / cos(self.beta))
|
||||
self.m = self.m_n / cos(self.beta)
|
||||
else:
|
||||
self.pressure_angle_t = self.pressure_angle
|
||||
@@ -47,32 +76,47 @@ class InvoluteTooth():
|
||||
|
||||
self.pitch = self.m * pi
|
||||
self.c = self.clearance * self.m_n
|
||||
self.midpoint = [0., 0.]
|
||||
self.midpoint = [0.0, 0.0]
|
||||
self.d = self.z * self.m
|
||||
self.dw = self.m * self.z
|
||||
self.da = self.dw + 2. * self.m_n + 2. * \
|
||||
(self.shift + self.head) * self.m_n
|
||||
self.df = self.dw - 2. * self.m_n - \
|
||||
2 * self.c + 2. * self.shift * self.m_n
|
||||
self.da = self.dw + 2.0 * self.m_n + 2.0 * (self.shift + self.head) * self.m_n
|
||||
self.df = self.dw - 2.0 * self.m_n - 2 * self.c + 2.0 * self.shift * self.m_n
|
||||
self.dg = self.d * cos(self.pressure_angle_t)
|
||||
self.phipart = 2 * pi / self.z
|
||||
|
||||
self.undercut_end = sqrt(-self.df ** 2 + self.da ** 2) / self.da
|
||||
self.undercut_rot = (-self.df / self.dw * tan(arctan((2 * ((self.m * pi) / 4. -
|
||||
(self.c + self.m_n) * tan(self.pressure_angle_t))) / self.df)))
|
||||
self.undercut_end = sqrt(-(self.df**2) + self.da**2) / self.da
|
||||
self.undercut_rot = (
|
||||
-self.df
|
||||
/ self.dw
|
||||
* tan(
|
||||
arctan(
|
||||
(
|
||||
2
|
||||
* (
|
||||
(self.m * pi) / 4.0
|
||||
- (self.c + self.m_n) * tan(self.pressure_angle_t)
|
||||
)
|
||||
)
|
||||
/ self.df
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
self.involute_end = sqrt(self.da ** 2 - self.dg ** 2) / self.dg
|
||||
self.involute_rot1 = sqrt(-self.dg ** 2 + (self.dw) ** 2) / self.dg - arctan(
|
||||
sqrt(-self.dg ** 2 + (self.dw) ** 2) / self.dg)
|
||||
self.involute_rot2 = self.m / \
|
||||
(self.d) * (pi / 2 + 2 * self.shift * tan(self.pressure_angle_t))
|
||||
self.involute_rot2 = 1 / self.z * \
|
||||
(pi / 2 + 2 * self.shift * tan(self.pressure_angle_t))
|
||||
self.involute_end = sqrt(self.da**2 - self.dg**2) / self.dg
|
||||
self.involute_rot1 = sqrt(-(self.dg**2) + (self.dw) ** 2) / self.dg - arctan(
|
||||
sqrt(-(self.dg**2) + (self.dw) ** 2) / self.dg
|
||||
)
|
||||
self.involute_rot2 = (
|
||||
self.m / (self.d) * (pi / 2 + 2 * self.shift * tan(self.pressure_angle_t))
|
||||
)
|
||||
self.involute_rot2 = (
|
||||
1 / self.z * (pi / 2 + 2 * self.shift * tan(self.pressure_angle_t))
|
||||
)
|
||||
self.involute_rot = self.involute_rot1 + self.involute_rot2
|
||||
self.angular_backlash = self.backlash / (self.d / 2)
|
||||
self.involute_start = 0.
|
||||
self.involute_start = 0.0
|
||||
if self.dg <= self.df:
|
||||
self.involute_start = sqrt(self.df ** 2 - self.dg ** 2) / self.dg
|
||||
self.involute_start = sqrt(self.df**2 - self.dg**2) / self.dg
|
||||
|
||||
def undercut_points(self, num=10):
|
||||
pts = linspace(0, self.undercut_end, num=num)
|
||||
@@ -82,9 +126,10 @@ class InvoluteTooth():
|
||||
y = array(list(map(fy, pts)))
|
||||
xy = transpose([x, y])
|
||||
rotate = rotation(
|
||||
self.undercut_rot + self.phipart / 2 - self.angular_backlash / 2)
|
||||
self.undercut_rot + self.phipart / 2 - self.angular_backlash / 2
|
||||
)
|
||||
xy = rotate(xy)
|
||||
return(array(xy))
|
||||
return array(xy)
|
||||
|
||||
def involute_points(self, num=10):
|
||||
pts = linspace(self.involute_start, self.involute_end, num=num)
|
||||
@@ -94,7 +139,7 @@ class InvoluteTooth():
|
||||
y = array(list(map(fy, pts)))
|
||||
rot = rotation(self.involute_rot - self.angular_backlash / 2)
|
||||
xy = rot(transpose(array([x, y])))
|
||||
return(xy)
|
||||
return xy
|
||||
|
||||
def points(self, num=10):
|
||||
l1 = self.undercut_points(num=num)
|
||||
@@ -109,7 +154,8 @@ class InvoluteTooth():
|
||||
u1 = False
|
||||
if self.dg > self.df:
|
||||
u1 = vstack(
|
||||
[[l2[0] * self.df / (diff_norm(l2[0], [0, 0]) * 2)], [l2[0]]])
|
||||
[[l2[0] * self.df / (diff_norm(l2[0], [0, 0]) * 2)], [l2[0]]]
|
||||
)
|
||||
e1 = l2
|
||||
else:
|
||||
e1 = l2
|
||||
@@ -121,35 +167,39 @@ class InvoluteTooth():
|
||||
else:
|
||||
u2 = reflect(u1)[::-1]
|
||||
one_tooth = [u1, e1, [e1[-1], e2[0]], e2, u2]
|
||||
return(one_tooth)
|
||||
return one_tooth
|
||||
|
||||
def gearfunc(self, x):
|
||||
rot = rotation(2 * x / self.dw, self.midpoint)
|
||||
return(rot)
|
||||
return rot
|
||||
|
||||
def undercut_function_x(self):
|
||||
def func(psi):
|
||||
return(
|
||||
cos(psi - (self.df * tan(psi)) / self.dw) * sqrt(self.df ** 2 / 4 +
|
||||
(self.df ** 2 * tan(psi) ** 2) / 4.))
|
||||
return(func)
|
||||
return cos(psi - (self.df * tan(psi)) / self.dw) * sqrt(
|
||||
self.df**2 / 4 + (self.df**2 * tan(psi) ** 2) / 4.0
|
||||
)
|
||||
|
||||
return func
|
||||
|
||||
def undercut_function_y(self):
|
||||
def func(psi):
|
||||
return(
|
||||
sin(psi - (self.df * tan(psi)) / self.dw) * sqrt(self.df ** 2 / 4 +
|
||||
(self.df ** 2 * tan(psi) ** 2) / 4.))
|
||||
return(func)
|
||||
return sin(psi - (self.df * tan(psi)) / self.dw) * sqrt(
|
||||
self.df**2 / 4 + (self.df**2 * tan(psi) ** 2) / 4.0
|
||||
)
|
||||
|
||||
return func
|
||||
|
||||
def involute_function_x(self):
|
||||
def func(phi):
|
||||
return(self.dg / 2 * cos(phi) + phi * self.dg / 2 * sin(phi))
|
||||
return(func)
|
||||
return self.dg / 2 * cos(phi) + phi * self.dg / 2 * sin(phi)
|
||||
|
||||
return func
|
||||
|
||||
def involute_function_y(self):
|
||||
def func(phi):
|
||||
return(self.dg / 2 * sin(phi) - phi * self.dg / 2 * cos(phi))
|
||||
return(func)
|
||||
return self.dg / 2 * sin(phi) - phi * self.dg / 2 * cos(phi)
|
||||
|
||||
return func
|
||||
|
||||
def _update(self):
|
||||
if not hasattr(self, "properties_from_tool"):
|
||||
@@ -158,8 +208,19 @@ class InvoluteTooth():
|
||||
|
||||
|
||||
class InvoluteRack(object):
|
||||
def __init__(self, m=5, z=15, pressure_angle=20 * pi / 180., thickness=5, beta=0, head=0, clearance=0.25,
|
||||
properties_from_tool=False, add_endings=False, simplified=False):
|
||||
def __init__(
|
||||
self,
|
||||
m=5,
|
||||
z=15,
|
||||
pressure_angle=20 * pi / 180.0,
|
||||
thickness=5,
|
||||
beta=0,
|
||||
head=0,
|
||||
clearance=0.25,
|
||||
properties_from_tool=False,
|
||||
add_endings=False,
|
||||
simplified=False,
|
||||
):
|
||||
self.pressure_angle = pressure_angle
|
||||
self.thickness = thickness
|
||||
self.m = m
|
||||
@@ -171,8 +232,7 @@ class InvoluteRack(object):
|
||||
self.add_endings = add_endings
|
||||
self.simplified = simplified
|
||||
|
||||
|
||||
# this is not good. Find better way to stay backward compatible -> versions
|
||||
# this is not good. Find better way to stay backward compatible -> versions
|
||||
def _update(self):
|
||||
if not hasattr(self, "add_endings"):
|
||||
self.add_endings = True
|
||||
@@ -188,10 +248,10 @@ class InvoluteRack(object):
|
||||
[-m_n * (1 + self.clearance), -a - b],
|
||||
[m_n * (1 + self.head), -b],
|
||||
[m_n * (1 + self.head), b],
|
||||
[-m_n * (1 + self.clearance), a + b]
|
||||
[-m_n * (1 + self.clearance), a + b],
|
||||
]
|
||||
teeth = [tooth]
|
||||
trans = translation([0., pitch, 0.])
|
||||
trans = translation([0.0, pitch, 0.0])
|
||||
for i in range(self.z - 1):
|
||||
if self.simplified and i > 3 and i < (self.z - 6):
|
||||
tooth = trans(tooth).tolist()
|
||||
@@ -202,7 +262,7 @@ class InvoluteRack(object):
|
||||
teeth[-1].pop()
|
||||
teeth[-1].pop()
|
||||
teeth[-1][-1][0] = 0
|
||||
teeth[-1][-1][1] -= a / 2
|
||||
teeth[-1][-1][1] -= a / 2
|
||||
if self.simplified and (i == self.z - 6):
|
||||
teeth[-1].pop(0)
|
||||
teeth[-1].pop(0)
|
||||
@@ -211,14 +271,18 @@ class InvoluteRack(object):
|
||||
|
||||
teeth = array([v for t in teeth for v in t]) # flattening
|
||||
if self.add_endings:
|
||||
ext1 = teeth[0] + array([0., a + b - pitch / 2])
|
||||
ext2 = teeth[-1] - array([0., a + b - pitch / 2])
|
||||
teeth = [ext1.tolist(), ext1.tolist()] + teeth.tolist() + [ext2.tolist(), ext2.tolist()]
|
||||
ext1 = teeth[0] + array([0.0, a + b - pitch / 2])
|
||||
ext2 = teeth[-1] - array([0.0, a + b - pitch / 2])
|
||||
teeth = (
|
||||
[ext1.tolist(), ext1.tolist()]
|
||||
+ teeth.tolist()
|
||||
+ [ext2.tolist(), ext2.tolist()]
|
||||
)
|
||||
else:
|
||||
teeth = [teeth[0].tolist()] + teeth.tolist() + [teeth[-1].tolist()]
|
||||
#teeth.append(list(teeth[-1]))
|
||||
# teeth.append(list(teeth[-1]))
|
||||
teeth[0][0] -= self.thickness
|
||||
#teeth.append(list(teeth[0]))
|
||||
# teeth.append(list(teeth[0]))
|
||||
teeth[-1][0] -= self.thickness
|
||||
teeth.append(teeth[0])
|
||||
return array(teeth)
|
||||
@@ -231,7 +295,7 @@ class InvoluteRack(object):
|
||||
else:
|
||||
pressure_angle_t = self.pressure_angle
|
||||
m = self.m
|
||||
m_n = self.m
|
||||
m_n = self.m
|
||||
|
||||
pitch = m * pi
|
||||
return m, m_n, pitch, pressure_angle_t
|
||||
|
||||
@@ -7,13 +7,14 @@ from ._functions import rotation, rotation3D
|
||||
|
||||
class _GearProfile(object):
|
||||
rot3D = False
|
||||
|
||||
def profile(self, num=10):
|
||||
tooth = self.points(num=num)
|
||||
tooth = [list(point) for wire in tooth for point in wire]
|
||||
if self.rot3D:
|
||||
rot = rotation3D( np.pi * 2 / self.z)
|
||||
rot = rotation3D(np.pi * 2 / self.z)
|
||||
else:
|
||||
rot = rotation(- np.pi * 2 / self.z)
|
||||
rot = rotation(-np.pi * 2 / self.z)
|
||||
profile = tooth
|
||||
for i in range(self.z - 1):
|
||||
tooth = rot(tooth).tolist()
|
||||
@@ -21,19 +22,19 @@ class _GearProfile(object):
|
||||
profile.append(profile[0])
|
||||
return np.array(profile)
|
||||
|
||||
|
||||
class InvoluteProfile(InvoluteTooth, _GearProfile):
|
||||
pass
|
||||
|
||||
|
||||
class CycloidProfile(CycloidTooth, _GearProfile):
|
||||
pass
|
||||
|
||||
|
||||
class BevelProfile(BevelTooth, _GearProfile):
|
||||
rot3D = True
|
||||
|
||||
|
||||
class InvoluteRackProfile(InvoluteRack):
|
||||
def profile(self):
|
||||
return self.points()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user