From 7c4723c9b74c869725fa7015b72e239201942de7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20B=C3=A4hr?= Date: Thu, 6 Jan 2022 22:30:41 +0100 Subject: [PATCH] Interpret the backlash as "Circumferential Backlash" This fixes some unit mismatch, as the backlash is specified as length, but the involute tooth generation code used to interpret it as angular value in radians (no idea why it was additionaly diveded by four; we need the half on each side of the tooth). Now half of the value specified as "backlash" can be directly measured at the pitch circle when comparing each tooth flank of a gear with and without backlash. --- freecad/gears/features.py | 12 ++++++++---- pygears/bevel_tooth.py | 3 ++- pygears/cycloid_tooth.py | 3 ++- pygears/involute_tooth.py | 5 +++-- 4 files changed, 15 insertions(+), 8 deletions(-) diff --git a/freecad/gears/features.py b/freecad/gears/features.py index 5ca5988..aa1bca1 100644 --- a/freecad/gears/features.py +++ b/freecad/gears/features.py @@ -194,7 +194,8 @@ class InvoluteGear(BaseGear): "computed", "transverse_pitch", 1) def add_tolerance_properties(self, obj): - obj.addProperty("App::PropertyLength", "backlash", "tolerance", "backlash") + obj.addProperty("App::PropertyLength", "backlash", "tolerance", + "The arc length on the pitch circle by which the tooth thicknes is reduced.") obj.addProperty("App::PropertyBool", "reversed_backlash", "tolerance", "backlash direction") obj.addProperty( "App::PropertyFloat", "clearance", "tolerance", "clearance") @@ -358,7 +359,8 @@ class InternalInvoluteGear(BaseGear): obj.addProperty("App::PropertyFloat", "root_fillet", "fillets", "a fillet for the tooth-root, radius = root_fillet x module") def add_tolerance_properties(self, obj): - obj.addProperty("App::PropertyLength", "backlash", "tolerance", "backlash") + obj.addProperty("App::PropertyLength", "backlash", "tolerance", + "The arc length on the pitch circle by which the tooth thicknes is reduced.") obj.addProperty("App::PropertyBool", "reversed_backlash", "tolerance", "backlash direction") obj.addProperty("App::PropertyFloat", "head", "tolerance", "head_value * modul_value = additional length of head") obj.addProperty("App::PropertyFloat", "clearance", "tolerance", "clearance") @@ -887,7 +889,8 @@ class CycloidGear(BaseGear): def add_tolerance_properties(self, obj): obj.addProperty("App::PropertyFloat", "clearance", "tolerance", "clearance") - obj.addProperty("App::PropertyLength", "backlash", "tolerance", "backlash in mm") + obj.addProperty("App::PropertyLength", "backlash", "tolerance", + "The arc length on the pitch circle by which the tooth thicknes is reduced.") obj.addProperty("App::PropertyFloat", "head", "tolerance", "head_value * modul_value = additional length of head") def add_cycloid_properties(self, obj): @@ -969,7 +972,8 @@ class BevelGear(BaseGear): obj.addProperty("App::PropertyFloat", "clearance", "tolerance", "clearance") obj.addProperty("App::PropertyInteger", "numpoints", "precision", "number of points for spline") obj.addProperty("App::PropertyBool", "reset_origin", "base", "if value is true the gears outer face will match the z=0 plane") - obj.addProperty("App::PropertyLength", "backlash", "tolerance", "backlash in mm") + obj.addProperty("App::PropertyLength", "backlash", "tolerance", + "The arc length on the pitch circle by which the tooth thicknes is reduced.") obj.addProperty("App::PropertyPythonObject", "gear", "base", "test") obj.addProperty("App::PropertyAngle", "beta","helical", "angle used for spiral bevel-gears") obj.gear = self.bevel_tooth diff --git a/pygears/bevel_tooth.py b/pygears/bevel_tooth.py index a425252..1d4246e 100644 --- a/pygears/bevel_tooth.py +++ b/pygears/bevel_tooth.py @@ -30,6 +30,7 @@ class BevelTooth(object): self.z = z self.clearance = clearance self.backlash = backlash + self.angular_backlash = backlash / (z * module / 2) self.module = module self.involute_end = arccos( @@ -108,7 +109,7 @@ class BevelTooth(object): intersection_point = intersection_line_circle(xy[i], point, r_cut) xy = array([intersection_point] + list(xy[i+1:])) xyz = [[p[0], p[1], 1] for p in xy] - backlash_rot = rotation3D(self.backlash / 4) + backlash_rot = rotation3D(self.angular_backlash / 2) xyz = backlash_rot(xyz) return(xyz) diff --git a/pygears/cycloid_tooth.py b/pygears/cycloid_tooth.py index 866a8e7..342a30d 100644 --- a/pygears/cycloid_tooth.py +++ b/pygears/cycloid_tooth.py @@ -40,6 +40,7 @@ class CycloidTooth(): self.da = self.d + 2 * (1 + self.head) * self.m self.di = self.d - 2 * (1 + self.clearance) * self.m self.phipart = 2 * pi / self.z + self.angular_backlash = self.backlash / (self.d / 2) def epicycloid_x(self): def func(t): @@ -92,7 +93,7 @@ class CycloidTooth(): pts_outer = transpose([pts_outer_x, pts_outer_y]) pts_inner = transpose([pts_inner_x, pts_inner_y]) pts1 = vstack([pts_inner[:-2], pts_outer]) - rot = rotation(self.phipart / 4 - self.backlash) + rot = rotation(self.phipart / 4 - self.angular_backlash / 2) pts1 = rot(pts1) ref = reflection(0.) pts2 = ref(pts1)[::-1] diff --git a/pygears/involute_tooth.py b/pygears/involute_tooth.py index 767f231..a350116 100644 --- a/pygears/involute_tooth.py +++ b/pygears/involute_tooth.py @@ -69,6 +69,7 @@ class InvoluteTooth(): 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. if self.dg <= self.df: self.involute_start = sqrt(self.df ** 2 - self.dg ** 2) / self.dg @@ -81,7 +82,7 @@ class InvoluteTooth(): y = array(list(map(fy, pts))) xy = transpose([x, y]) rotate = rotation( - self.undercut_rot + self.phipart / 2 - self.backlash / 4) + self.undercut_rot + self.phipart / 2 - self.angular_backlash / 2) xy = rotate(xy) return(array(xy)) @@ -91,7 +92,7 @@ class InvoluteTooth(): x = array(list(map(fx, pts))) fy = self.involute_function_y() y = array(list(map(fy, pts))) - rot = rotation(self.involute_rot - self.backlash / 4) + rot = rotation(self.involute_rot - self.angular_backlash / 2) xy = rot(transpose(array([x, y]))) return(xy)