From dddb6c5bc47aedce561f6f292617852108607652 Mon Sep 17 00:00:00 2001 From: looooo Date: Sun, 5 Jan 2020 23:50:26 +0100 Subject: [PATCH] formating --- freecad/gears/__init__.py | 21 +++++ freecad/gears/commands.py | 69 +++++++++-------- freecad/gears/features.py | 158 +++++++++++++++++++++----------------- freecad/gears/init_gui.py | 60 ++++++++------- pygears/__init__.py | 21 +++++ pygears/_functions.py | 42 +++++----- pygears/bevel_tooth.py | 83 ++++++++++---------- pygears/computation.py | 35 +++++++-- pygears/cycloide_tooth.py | 92 +++++++++++----------- pygears/involute_tooth.py | 81 ++++++++++--------- 10 files changed, 378 insertions(+), 284 deletions(-) diff --git a/freecad/gears/__init__.py b/freecad/gears/__init__.py index 73872cf..5fd34f8 100644 --- a/freecad/gears/__init__.py +++ b/freecad/gears/__init__.py @@ -1,2 +1,23 @@ +# -*- coding: utf-8 -*- +# *************************************************************************** +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * 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 Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with this program; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# *************************************************************************** + import pygears __version__ = pygears.__version__ diff --git a/freecad/gears/commands.py b/freecad/gears/commands.py index 87ce531..6253be7 100644 --- a/freecad/gears/commands.py +++ b/freecad/gears/commands.py @@ -1,28 +1,29 @@ -#*************************************************************************** -#* * -#* This program is free software; you can redistribute it and/or modify * -#* it under the terms of the GNU Lesser General Public License (LGPL) * -#* as published by the Free Software Foundation; either version 2 of * -#* the License, or (at your option) any later version. * -#* for detail see the LICENCE text file. * -#* * -#* 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 Library General Public License for more details. * -#* * -#* You should have received a copy of the GNU Library General Public * -#* License along with this program; if not, write to the Free Software * -#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * -#* USA * -#* * -#*************************************************************************** +# -*- coding: utf-8 -*- +# *************************************************************************** +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * 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 Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with this program; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# *************************************************************************** import os import FreeCAD import FreeCADGui as Gui -from .features import ViewProviderGear, involute_gear, involute_gear_rack -from .features import cycloide_gear, bevel_gear, crown_gear, worm_gear +from .features import ViewProviderGear, InvoluteGear, InvoluteGearRack +from .features import CycloideGear, BevelGear, CrownGear, WormGear class BaseCommand(object): @@ -41,7 +42,8 @@ class BaseCommand(object): def Activated(self): Gui.doCommandGui("import freecad.gears.commands") - Gui.doCommandGui("freecad.gears.commands.{}.create()".format(self.__class__.__name__)) + Gui.doCommandGui("freecad.gears.commands.{}.create()".format( + self.__class__.__name__)) FreeCAD.ActiveDocument.recompute() Gui.SendMsgToActiveView("ViewFit") @@ -53,49 +55,54 @@ class BaseCommand(object): return obj def GetResources(self): - return {'Pixmap': self.Pixmap, - 'MenuText': self.MenuText, + return {'Pixmap': self.Pixmap, + 'MenuText': self.MenuText, 'ToolTip': self.ToolTip} class CreateInvoluteGear(BaseCommand): NAME = "InvoluteGear" - GEAR_FUNCTION = involute_gear + GEAR_FUNCTION = InvoluteGear Pixmap = os.path.join(BaseCommand.ICONDIR, 'involutegear.svg') MenuText = 'involute gear' ToolTip = 'involute gear' + class CreateInvoluteRack(BaseCommand): NAME = "InvoluteRack" - GEAR_FUNCTION = involute_gear_rack + GEAR_FUNCTION = InvoluteGearRack Pixmap = os.path.join(BaseCommand.ICONDIR, 'involuterack.svg') MenuText = 'involute rack' ToolTip = 'involute rack' + class CreateCrownGear(BaseCommand): NAME = "CrownGear" - GEAR_FUNCTION = crown_gear + GEAR_FUNCTION = CrownGear Pixmap = os.path.join(BaseCommand.ICONDIR, 'crowngear.svg') MenuText = 'crown gear' ToolTip = 'crown gear' + class CreateCycloideGear(BaseCommand): NAME = "CycloidGear" - GEAR_FUNCTION = cycloide_gear + GEAR_FUNCTION = CycloideGear Pixmap = os.path.join(BaseCommand.ICONDIR, 'cycloidegear.svg') MenuText = 'cycloide gear' ToolTip = 'cycloide gear' + class CreateBevelGear(BaseCommand): NAME = "BevelGear" - GEAR_FUNCTION = bevel_gear + GEAR_FUNCTION = BevelGear Pixmap = os.path.join(BaseCommand.ICONDIR, 'bevelgear.svg') MenuText = 'bevel gear' ToolTip = 'bevel gear' + class CreateWormGear(BaseCommand): NAME = "WormGear" - GEAR_FUNCTION = worm_gear + GEAR_FUNCTION = WormGear Pixmap = os.path.join(BaseCommand.ICONDIR, 'wormgear.svg') MenuText = 'worm gear' - ToolTip = 'worm gear' \ No newline at end of file + ToolTip = 'worm gear' diff --git a/freecad/gears/features.py b/freecad/gears/features.py index 121bf23..79c509a 100644 --- a/freecad/gears/features.py +++ b/freecad/gears/features.py @@ -1,31 +1,31 @@ # -*- coding: utf-8 -*- -#*************************************************************************** -#* * -#* This program is free software; you can redistribute it and/or modify * -#* it under the terms of the GNU Lesser General Public License (LGPL) * -#* as published by the Free Software Foundation; either version 2 of * -#* the License, or (at your option) any later version. * -#* for detail see the LICENCE text file. * -#* * -#* 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 Library General Public License for more details. * -#* * -#* You should have received a copy of the GNU Library General Public * -#* License along with this program; if not, write to the Free Software * -#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * -#* USA * -#* * -#*************************************************************************** +# *************************************************************************** +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * 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 Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with this program; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# *************************************************************************** from __future__ import division import os import numpy as np -from pygears.involute_tooth import involute_tooth, involute_rack -from pygears.cycloide_tooth import cycloide_tooth -from pygears.bevel_tooth import bevel_tooth +from pygears.involute_tooth import InvoluteTooth, InvoluteRack +from pygears.cycloide_tooth import CycloideTooth +from pygears.bevel_tooth import BevelTooth from pygears._functions import rotation3D, rotation @@ -36,20 +36,20 @@ from Part import BSplineCurve, Shape, Wire, Face, makePolygon, \ show, makePolygon, makeHelix, makeShell, makeSolid +__all__ = ["involute_gear", + "cycloide_gear", + "bevel_gear", + "involute_gear_rack", + "ViewProviderGear"] -__all__=["involute_gear", - "cycloide_gear", - "bevel_gear", - "involute_gear_rack", - "ViewProviderGear"] - def fcvec(x): if len(x) == 2: return(App.Vector(x[0], x[1], 0)) else: return(App.Vector(x[0], x[1], x[2])) + class ViewProviderGear(object): def __init__(self, obj): ''' Set this object to the proxy object of the actual view provider ''' @@ -68,12 +68,13 @@ class ViewProviderGear(object): def __setstate__(self, state): return None -class involute_gear(object): + +class InvoluteGear(object): """FreeCAD gear""" def __init__(self, obj): - self.involute_tooth = involute_tooth() + self.involute_tooth = InvoluteTooth() obj.addProperty( "App::PropertyBool", "simple", "gear_parameter", "simple") obj.addProperty("App::PropertyInteger", @@ -102,8 +103,10 @@ class involute_gear(object): "App::PropertyBool", "reversed_backlash", "tolerance", "backlash direction") obj.addProperty( "App::PropertyFloat", "head", "gear_parameter", "head_value * modul_value = additional length of head") - obj.addProperty("App::PropertyPythonObject", "gear", "gear_parameter", "test") - obj.addProperty("App::PropertyFloat", "dw", "computed", "pitch diameter", 1) + obj.addProperty("App::PropertyPythonObject", + "gear", "gear_parameter", "test") + obj.addProperty("App::PropertyFloat", "dw", + "computed", "pitch diameter", 1) obj.gear = self.involute_tooth obj.simple = False obj.undercut = False @@ -131,7 +134,8 @@ class involute_gear(object): fp.gear.pressure_angle = fp.pressure_angle.Value * np.pi / 180. fp.gear.beta = fp.beta.Value * np.pi / 180 fp.gear.clearance = fp.clearance - fp.gear.backlash = fp.backlash.Value * (-fp.reversed_backlash + 0.5) * 2. + fp.gear.backlash = fp.backlash.Value * \ + (-fp.reversed_backlash + 0.5) * 2. fp.gear.head = fp.head fp.gear._update() pts = fp.gear.points(num=fp.numpoints) @@ -157,7 +161,7 @@ class involute_gear(object): wi, fp.height.Value, fp.height.Value * np.tan(fp.gear.beta) * 2 / fp.gear.d, fp.double_helix) else: rw = fp.gear.dw / 2 - fp.Shape=Part.makeCylinder(rw,fp.height.Value) + fp.Shape = Part.makeCylinder(rw, fp.height.Value) fp.dw = fp.gear.dw @@ -168,12 +172,12 @@ class involute_gear(object): return None -class involute_gear_rack(object): +class InvoluteGearRack(object): """FreeCAD gear rack""" def __init__(self, obj): - self.involute_rack = involute_rack() + self.involute_rack = InvoluteRack() obj.addProperty("App::PropertyInteger", "teeth", "gear_parameter", "number of teeth") obj.addProperty( @@ -217,14 +221,16 @@ class involute_gear_rack(object): elif fp.double_helix: beta = fp.beta.Value * np.pi / 180. pol2 = Part.Wire(pol) - pol2.translate(fcvec([0., np.tan(beta) * fp.height.Value / 2, fp.height.Value / 2])) + pol2.translate( + fcvec([0., np.tan(beta) * fp.height.Value / 2, fp.height.Value / 2])) pol3 = Part.Wire(pol) pol3.translate(fcvec([0., 0., fp.height.Value])) fp.Shape = makeLoft([pol, pol2, pol3], True, True) else: beta = fp.beta.Value * np.pi / 180. pol2 = Part.Wire(pol) - pol2.translate(fcvec([0., np.tan(beta) * fp.height.Value, fp.height.Value])) + pol2.translate( + fcvec([0., np.tan(beta) * fp.height.Value, fp.height.Value])) fp.Shape = makeLoft([pol, pol2], True) def __getstate__(self): @@ -234,7 +240,7 @@ class involute_gear_rack(object): return None -class crown_gear(object): +class CrownGear(object): def __init__(self, obj): obj.addProperty("App::PropertyInteger", "teeth", "gear_parameter", "number of teeth") @@ -263,7 +269,6 @@ class crown_gear(object): self.obj = obj obj.Proxy = self - def profile(self, m, r, r0, t_c, t_i, alpha_w, y0, y1, y2): r_ew = m * t_i / 2 @@ -274,7 +279,8 @@ class crown_gear(object): alpha = np.arccos(r0 / r * np.cos(alpha_w)) # 3: winkel phi bei senkrechter stellung eines zahns: - phi = np.pi / t_i / 2 + (alpha - alpha_w) + (np.tan(alpha_w) - np.tan(alpha)) + phi = np.pi / t_i / 2 + (alpha - alpha_w) + \ + (np.tan(alpha_w) - np.tan(alpha)) # 4: Position des Eingriffspunktes: x_c = r_e * np.sin(phi) @@ -309,7 +315,7 @@ class crown_gear(object): face = Part.Face([outer_circle, inner_circle]) solid = face.extrude(App.Vector([0., 0., -fp.thickness.Value])) - ### cutting obj + # cutting obj alpha_w = np.deg2rad(fp.pressure_angle.Value) m = fp.module.Value t = fp.teeth @@ -340,7 +346,6 @@ class crown_gear(object): loft = loft.transformGeometry(rot) solid = solid.cut(loft) fp.Shape = solid - def __getstate__(self): pass @@ -349,10 +354,11 @@ class crown_gear(object): pass -class cycloide_gear(object): +class CycloideGear(object): """FreeCAD gear""" + def __init__(self, obj): - self.cycloide_tooth = cycloide_tooth() + self.cycloide_tooth = CycloideTooth() obj.addProperty("App::PropertyInteger", "teeth", "gear_parameter", "number of teeth") obj.addProperty( @@ -372,7 +378,8 @@ class cycloide_gear(object): obj.addProperty("App::PropertyAngle", "beta", "gear_parameter", "beta") obj.addProperty( "App::PropertyLength", "backlash", "gear_parameter", "backlash in mm") - obj.addProperty("App::PropertyPythonObject", "gear", "gear_parameter", "the python object") + obj.addProperty("App::PropertyPythonObject", "gear", + "gear_parameter", "the python object") obj.gear = self.cycloide_tooth obj.teeth = 15 obj.module = '1. mm' @@ -422,7 +429,7 @@ class cycloide_gear(object): return None -class bevel_gear(object): +class BevelGear(object): """parameters: pressure_angle: pressureangle, 10-30° @@ -430,7 +437,7 @@ class bevel_gear(object): """ def __init__(self, obj): - self.bevel_tooth = bevel_tooth() + self.bevel_tooth = BevelTooth() obj.addProperty("App::PropertyInteger", "teeth", "gear_parameter", "number of teeth") obj.addProperty( @@ -445,11 +452,13 @@ class bevel_gear(object): obj.addProperty("App::PropertyInteger", "numpoints", "gear_parameter", "number of points for spline") obj.addProperty("App::PropertyBool", "reset_origin", "gear_parameter", - "if value is true the gears outer face will match the z=0 plane") + "if value is true the gears outer face will match the z=0 plane") obj.addProperty( "App::PropertyLength", "backlash", "gear_parameter", "backlash in mm") - obj.addProperty("App::PropertyPythonObject", "gear", "gear_paramenter", "test") - obj.addProperty("App::PropertyAngle", "beta", "gear_paramenter", "test") + obj.addProperty("App::PropertyPythonObject", + "gear", "gear_paramenter", "test") + obj.addProperty("App::PropertyAngle", "beta", + "gear_paramenter", "test") obj.gear = self.bevel_tooth obj.m = '1. mm' obj.teeth = 15 @@ -470,11 +479,12 @@ class bevel_gear(object): fp.gear.pressure_angle = (90 - fp.pressure_angle.Value) * np.pi / 180. fp.gear.pitch_angle = fp.pitch_angle.Value * np.pi / 180 fp.gear.backlash = fp.backlash.Value - scale = fp.m.Value * fp.gear.z / 2 / np.tan(fp.pitch_angle.Value * np.pi / 180) + scale = fp.m.Value * fp.gear.z / 2 / \ + np.tan(fp.pitch_angle.Value * np.pi / 180) fp.gear.clearance = fp.clearance / scale fp.gear._update() pts = list(fp.gear.points(num=fp.numpoints)) - rot = rotation3D(2 * np.pi / fp.teeth) + rot = rotation3D(2 * np.pi / fp.teeth) # if fp.beta.Value != 0: # pts = [np.array([self.spherical_rot(j, fp.beta.Value * np.pi / 180.) for j in i]) for i in pts] @@ -491,12 +501,15 @@ class bevel_gear(object): wires.append(makeBSplineWire([scale_0 * p for p in pts])) wires.append(makeBSplineWire([scale_1 * p for p in pts])) else: - for scale_i in np.linspace(scale_0, scale_1, 20): + for scale_i in np.linspace(scale_0, scale_1, 20): # beta_i = (scale_i - scale_0) * fp.beta.Value * np.pi / 180 # rot = rotation3D(beta_i) # points = [rot(pt) * scale_i for pt in pts] - angle = fp.beta.Value * np.pi / 180. * np.sin(np.pi / 4) / np.sin(fp.pitch_angle.Value * np.pi / 180.) - points = [np.array([self.spherical_rot(p, angle) for p in scale_i * pt]) for pt in pts] + angle = fp.beta.Value * np.pi / 180. * \ + np.sin(np.pi / 4) / \ + np.sin(fp.pitch_angle.Value * np.pi / 180.) + points = [np.array([self.spherical_rot(p, angle) + for p in scale_i * pt]) for pt in pts] wires.append(makeBSplineWire(points)) shape = makeLoft(wires, True) if fp.reset_origin: @@ -507,7 +520,6 @@ class bevel_gear(object): fp.Shape = shape # fp.Shape = self.create_teeth(pts, pos1, fp.teeth) - def create_tooth(self): w = [] scal1 = self.obj.m.Value * self.obj.gear.z / 2 / np.tan( @@ -518,7 +530,8 @@ class bevel_gear(object): pts = self.obj.gear.points(num=self.obj.numpoints) for j, pos in enumerate(s): w1 = [] - scale = lambda x: fcvec(x * pos) + + def scale(x): return fcvec(x * pos) for i in pts: i_scale = list(map(scale, i)) w1.append(i_scale) @@ -567,12 +580,11 @@ class bevel_gear(object): return None -class worm_gear(object): +class WormGear(object): """FreeCAD gear rack""" def __init__(self, obj): - self.involute_rack = involute_rack() obj.addProperty("App::PropertyInteger", "teeth", "gear_parameter", "number of teeth") obj.addProperty( @@ -585,8 +597,6 @@ class worm_gear(object): "App::PropertyAngle", "beta", "gear_parameter", "beta ", 1) obj.addProperty( "App::PropertyAngle", "pressure_angle", "involute_parameter", "pressure angle") - obj.addProperty("App::PropertyPythonObject", "rack", "test", "test") - obj.rack = self.involute_rack obj.teeth = 3 obj.module = '1. mm' obj.pressure_angle = '20. deg' @@ -622,7 +632,8 @@ class worm_gear(object): # create a circle from phi=0 to phi_1 with r_1 phi_1 = 2 * z_1 / m / t - c1 = Part.makeCircle(r_1, App.Vector(0,0,0), App.Vector(0,0, 1), 0, np.rad2deg(phi_1)) + c1 = Part.makeCircle(r_1, App.Vector(0, 0, 0), + App.Vector(0, 0, 1), 0, np.rad2deg(phi_1)) # create first bspline z_values = np.linspace(z_1, z_2, 10) @@ -635,7 +646,8 @@ class worm_gear(object): # create circle from phi_2 to phi_3 phi_2 = 2 * z_2 / m / t phi_3 = 2 * z_3 / m / t - c2 = Part.makeCircle(r_2, App.Vector(0,0,0), App.Vector(0,0, 1), np.rad2deg(phi_2), np.rad2deg(phi_3)) + c2 = Part.makeCircle(r_2, App.Vector(0, 0, 0), App.Vector( + 0, 0, 1), np.rad2deg(phi_2), np.rad2deg(phi_3)) # create second bspline z_values = np.linspace(z_3, z_4, 10) @@ -664,25 +676,28 @@ class worm_gear(object): return None -def helicalextrusion(wire, height, angle, double_helix = False): +def helicalextrusion(wire, height, angle, double_helix=False): direction = bool(angle < 0) if double_helix: - first_spine = makeHelix(height * 2. * np.pi / abs(angle), 0.5 * height, 10., 0, direction) + first_spine = makeHelix(height * 2. * np.pi / + abs(angle), 0.5 * height, 10., 0, direction) first_solid = first_spine.makePipeShell([wire], True, True) - second_solid = first_solid.mirror(fcvec([0.,0.,0.]), fcvec([0,0,1])) + second_solid = first_solid.mirror( + fcvec([0., 0., 0.]), fcvec([0, 0, 1])) faces = first_solid.Faces + second_solid.Faces - faces = [f for f in faces if not on_mirror_plane(f, 0., fcvec([0., 0., 1.]))] + faces = [f for f in faces if not on_mirror_plane( + f, 0., fcvec([0., 0., 1.]))] solid = makeSolid(makeShell(faces)) mat = App.Matrix() mat.move(fcvec([0, 0, 0.5 * height])) return solid.transformGeometry(mat) else: - first_spine = makeHelix(height * 2 * np.pi / abs(angle), height, 10., 0, direction) + first_spine = makeHelix(height * 2 * np.pi / + abs(angle), height, 10., 0, direction) first_solid = first_spine.makePipeShell([wire], True, True) return first_solid - def make_face(edge1, edge2): v1, v2 = edge1.Vertexes v3, v4 = edge2.Vertexes @@ -702,7 +717,8 @@ def makeBSplineWire(pts): wi.append(out.toShape()) return Wire(wi) + def on_mirror_plane(face, z, direction, small_size=0.000001): # the tolerance is very high. Maybe there is a bug in Part.makeHelix. return (face.normalAt(0, 0).cross(direction).Length < small_size and - abs(face.CenterOfMass.z - z) < small_size) + abs(face.CenterOfMass.z - z) < small_size) diff --git a/freecad/gears/init_gui.py b/freecad/gears/init_gui.py index 96a54b0..e92d43a 100644 --- a/freecad/gears/init_gui.py +++ b/freecad/gears/init_gui.py @@ -1,22 +1,23 @@ -#*************************************************************************** -#* * -#* This program is free software; you can redistribute it and/or modify * -#* it under the terms of the GNU Lesser General Public License (LGPL) * -#* as published by the Free Software Foundation; either version 2 of * -#* the License, or (at your option) any later version. * -#* for detail see the LICENCE text file. * -#* * -#* 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 Library General Public License for more details. * -#* * -#* You should have received a copy of the GNU Library General Public * -#* License along with this program; if not, write to the Free Software * -#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * -#* USA * -#* * -#*************************************************************************** +# -*- coding: utf-8 -*- +# *************************************************************************** +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * 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 Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with this program; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# *************************************************************************** import os import FreeCADGui as Gui @@ -26,8 +27,11 @@ __dirname__ = os.path.dirname(__file__) try: from FreeCADGui import Workbench except ImportError as e: - App.Console.PrintWarning("you are using the GearWorkbench with an old version of FreeCAD (<0.16)") - App.Console.PrintWarning("the class Workbench is loaded, although not imported: magic") + App.Console.PrintWarning( + "you are using the GearWorkbench with an old version of FreeCAD (<0.16)") + App.Console.PrintWarning( + "the class Workbench is loaded, although not imported: magic") + class gearWorkbench(Workbench): """glider workbench""" @@ -35,12 +39,12 @@ class gearWorkbench(Workbench): ToolTip = "Gear Workbench" Icon = os.path.join(__dirname__, 'icons', 'gearworkbench.svg') commands = [ - "CreateInvoluteGear", - "CreateInvoluteRack", - "CreateCycloideGear", - "CreateBevelGear", - "CreateCrownGear", - "CreateWormGear"] + "CreateInvoluteGear", + "CreateInvoluteRack", + "CreateCycloideGear", + "CreateBevelGear", + "CreateCrownGear", + "CreateWormGear"] def GetClassName(self): return "Gui::PythonWorkbench" @@ -62,8 +66,8 @@ class gearWorkbench(Workbench): def Activated(self): pass - def Deactivated(self): pass + Gui.addWorkbench(gearWorkbench()) diff --git a/pygears/__init__.py b/pygears/__init__.py index bbca881..5af77c2 100644 --- a/pygears/__init__.py +++ b/pygears/__init__.py @@ -1 +1,22 @@ +# -*- coding: utf-8 -*- +# *************************************************************************** +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * 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 Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with this program; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# *************************************************************************** + __version__ = "0.01" \ No newline at end of file diff --git a/pygears/_functions.py b/pygears/_functions.py index 4ff2f43..4211c34 100644 --- a/pygears/_functions.py +++ b/pygears/_functions.py @@ -1,23 +1,23 @@ # -*- coding: utf-8 -*- -#*************************************************************************** -#* * -#* This program is free software; you can redistribute it and/or modify * -#* it under the terms of the GNU Lesser General Public License (LGPL) * -#* as published by the Free Software Foundation; either version 2 of * -#* the License, or (at your option) any later version. * -#* for detail see the LICENCE text file. * -#* * -#* 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 Library General Public License for more details. * -#* * -#* You should have received a copy of the GNU Library General Public * -#* License along with this program; if not, write to the Free Software * -#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * -#* USA * -#* * -#*************************************************************************** +# *************************************************************************** +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * 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 Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with this program; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# *************************************************************************** from __future__ import division from numpy import sin, cos, dot, array, ndarray, vstack, transpose, sqrt @@ -45,7 +45,8 @@ def reflection3D(pressure_angle): def rotation(pressure_angle, midpoint=None): midpoint = midpoint or [0., 0.] - mat = array([[cos(pressure_angle), -sin(pressure_angle)], [sin(pressure_angle), cos(pressure_angle)]]) + mat = array([[cos(pressure_angle), -sin(pressure_angle)], + [sin(pressure_angle), cos(pressure_angle)]]) midpoint = array(midpoint) vec = midpoint - dot(midpoint, mat) trans = translation(vec) @@ -161,7 +162,6 @@ def nearestpts(evolv, underc): 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 midpoint 0,0,0""" diff --git a/pygears/bevel_tooth.py b/pygears/bevel_tooth.py index 714a092..243ad7d 100644 --- a/pygears/bevel_tooth.py +++ b/pygears/bevel_tooth.py @@ -1,23 +1,23 @@ # -*- coding: utf-8 -*- -#*************************************************************************** -#* * -#* This program is free software; you can redistribute it and/or modify * -#* it under the terms of the GNU Lesser General Public License (LGPL) * -#* as published by the Free Software Foundation; either version 2 of * -#* the License, or (at your option) any later version. * -#* for detail see the LICENCE text file. * -#* * -#* 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 Library General Public License for more details. * -#* * -#* You should have received a copy of the GNU Library General Public * -#* License along with this program; if not, write to the Free Software * -#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * -#* USA * -#* * -#*************************************************************************** +# *************************************************************************** +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * 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 Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with this program; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# *************************************************************************** from __future__ import division from __future__ import division @@ -26,8 +26,7 @@ import numpy as np from ._functions import rotation3D, reflection3D, intersection_line_circle - -class bevel_tooth(object): +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): self.pressure_angle = pressure_angle @@ -39,24 +38,26 @@ class bevel_tooth(object): 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)) + 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)) - self.involute_start = -pi/2. + arctan(1/tan(self.pitch_angle)*1/cos(self.pressure_angle)) + self.involute_start = -pi/2. + \ + 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 @@ -85,7 +86,7 @@ class bevel_tooth(object): 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))* + (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) @@ -93,7 +94,7 @@ class bevel_tooth(object): 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)* + 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) @@ -150,7 +151,7 @@ class bevel_tooth(object): array([pts[-1], pts1[0]]), pts1[:-1], array([pts1[-2], pts1[-1]]) - ])) + ])) else: return(array([pts, array([pts[-1], pts1[0]]), pts1])) @@ -163,7 +164,7 @@ class bevel_tooth(object): if __name__ == "__main__": from matplotlib import pyplot - gear = bevel_tooth(z=60, clearance=0.0, pitch_angle=np.deg2rad(45)) + gear = BevelTooth(z=60, clearance=0.0, pitch_angle=np.deg2rad(45)) x, y, z = gear.involute_points().T pyplot.plot(x, y) pyplot.show() diff --git a/pygears/computation.py b/pygears/computation.py index f63aefb..53cc398 100644 --- a/pygears/computation.py +++ b/pygears/computation.py @@ -1,9 +1,31 @@ +# -*- coding: utf-8 -*- +# *************************************************************************** +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * 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 Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with this program; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# *************************************************************************** + import numpy as np from scipy import optimize as opt + def computeShiftedGears(m, alpha, t1, t2, x1, x2): """Summary - + Args: m (float): common module of both gears [length] alpha (float): pressure-angle [rad] @@ -11,13 +33,14 @@ def computeShiftedGears(m, alpha, t1, t2, x1, x2): t2 (int): number of teeth of gear2 x1 (float): relative profile-shift of gear1 x2 (float): relative profile-shift of gear2 - + Returns: (float, float): distance between gears [length], pressure angle of the assembly [rad] """ - inv = lambda x: np.tan(x) - x + def inv(x): return np.tan(x) - x inv_alpha_w = inv(alpha) + 2 * np.tan(alpha) * (x1 + x2) / (t1 + t2) - root_inv = lambda x: inv(x) - inv_alpha_w + + def root_inv(x): return inv(x) - inv_alpha_w alpha_w = opt.fsolve(root_inv, 0.) - dist = m * (t1+ t2) / 2 * np.cos(alpha) / np.cos(alpha_w) - return dist, alpha_w \ No newline at end of file + dist = m * (t1 + t2) / 2 * np.cos(alpha) / np.cos(alpha_w) + return dist, alpha_w diff --git a/pygears/cycloide_tooth.py b/pygears/cycloide_tooth.py index c7f8336..b1ec9fe 100644 --- a/pygears/cycloide_tooth.py +++ b/pygears/cycloide_tooth.py @@ -1,30 +1,31 @@ # -*- coding: utf-8 -*- -#*************************************************************************** -#* * -#* This program is free software; you can redistribute it and/or modify * -#* it under the terms of the GNU Lesser General Public License (LGPL) * -#* as published by the Free Software Foundation; either version 2 of * -#* the License, or (at your option) any later version. * -#* for detail see the LICENCE text file. * -#* * -#* 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 Library General Public License for more details. * -#* * -#* You should have received a copy of the GNU Library General Public * -#* License along with this program; if not, write to the Free Software * -#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * -#* USA * -#* * -#*************************************************************************** +# *************************************************************************** +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * 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 Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with this program; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# *************************************************************************** from __future__ import division from numpy import cos, sin, arccos, pi, array, linspace, transpose, vstack from ._functions import rotation, reflection -class cycloide_tooth(): - def __init__(self, z1 = 5, z2 = 5, z = 14, m = 5, clearance = 0.12, backlash = 0.00): + +class CycloideTooth(): + def __init__(self, z1=5, z2=5, z=14, m=5, clearance=0.12, backlash=0.00): self.m = m self.z = z self.clearance = clearance @@ -59,24 +60,24 @@ class cycloide_tooth(): def hypocycloide_y(self): def func(t): - return((self.d - self.d1)*sin(t)/2 - self.d1/2 *sin((self.d/self.d1 - 1)*t)) + 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) - ) + 2*self.d1*self.d + self.d**2)/(2.*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 - ) + 2*self.d2*self.d + self.d**2) / + (2.*self.d2*(self.d2 + self.d))))/self.d + ) - def points(self, num = 10): + def points(self, num=10): inner_x = self.hypocycloide_x() inner_y = self.hypocycloide_y() @@ -85,33 +86,34 @@ class cycloide_tooth(): t_inner_end = self.inner_end() t_outer_end = self.outer_end() t_vals_outer = linspace(0, t_outer_end, num) - t_vals_inner = linspace(t_inner_end,0,num) + t_vals_inner = linspace(t_inner_end, 0, num) pts_outer_x = list(map(outer_x, t_vals_outer)) pts_outer_y = list(map(outer_y, t_vals_outer)) pts_inner_x = list(map(inner_x, t_vals_inner)) pts_inner_y = list(map(inner_y, t_vals_inner)) 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) + pts1 = vstack([pts_inner[:-2], pts_outer]) + rot = rotation(self.phipart / 4 - self.backlash) pts1 = rot(pts1) ref = reflection(0.) pts2 = ref(pts1)[::-1] - one_tooth = [pts1,array([pts1[-1],pts2[0]]), pts2] + one_tooth = [pts1, array([pts1[-1], pts2[0]]), pts2] 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) + self.__init__(m=self.m, z=self.z, z1=self.z1, z2=self.z2, + clearance=self.clearance, backlash=self.backlash) + if __name__ == "__main__": - from matplotlib import pyplot - gear = cycloide_tooth() - x = [] - y = [] - for i in gear.points(30): - for j in i: - x.append(j[0]) - y.append(j[1]) - pyplot.plot(x[-60:],y[-60:]) - pyplot.show() + from matplotlib import pyplot + gear = CycloideTooth() + x = [] + y = [] + for i in gear.points(30): + for j in i: + x.append(j[0]) + y.append(j[1]) + pyplot.plot(x[-60:], y[-60:]) + pyplot.show() diff --git a/pygears/involute_tooth.py b/pygears/involute_tooth.py index 9f0fd04..221098b 100644 --- a/pygears/involute_tooth.py +++ b/pygears/involute_tooth.py @@ -1,32 +1,33 @@ # -*- coding: utf-8 -*- -#*************************************************************************** -#* * -#* This program is free software; you can redistribute it and/or modify * -#* it under the terms of the GNU Lesser General Public License (LGPL) * -#* as published by the Free Software Foundation; either version 2 of * -#* the License, or (at your option) any later version. * -#* for detail see the LICENCE text file. * -#* * -#* 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 Library General Public License for more details. * -#* * -#* You should have received a copy of the GNU Library General Public * -#* License along with this program; if not, write to the Free Software * -#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * -#* USA * -#* * -#*************************************************************************** +# *************************************************************************** +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * 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 Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with this program; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# *************************************************************************** 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, norm, translation import numpy as np -class involute_tooth(): + +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): + undercut=False, backlash=0.00, head=0.00): self.pressure_angle = pressure_angle self.beta = beta self.m_n = m @@ -39,13 +40,15 @@ class involute_tooth(): self._calc_gear_factors() def _calc_gear_factors(self): - 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) self.c = self.clearance * self.m_n self.midpoint = [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.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.dg = self.d * cos(self.pressure_angle_t) @@ -53,20 +56,20 @@ class involute_tooth(): 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.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_rot2 = 1 / self.z * \ + (pi / 2 + 2 * self.shift * tan(self.pressure_angle_t)) self.involute_rot = self.involute_rot1 + self.involute_rot2 self.involute_start = 0. if self.dg <= self.df: 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) fx = self.undercut_function_x() @@ -124,15 +127,15 @@ class involute_tooth(): 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.)) + cos(psi - (self.df * tan(psi)) / self.dw) * sqrt(self.df ** 2 / 4 + + (self.df ** 2 * tan(psi) ** 2) / 4.)) 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.)) + (self.df ** 2 * tan(psi) ** 2) / 4.)) return(func) def involute_function_x(self): @@ -146,12 +149,12 @@ class involute_tooth(): return(func) def _update(self): - self.__init__(m = self.m_n, z = self.z, - pressure_angle = self.pressure_angle, clearance = self.clearance, shift = self.shift, - beta = self.beta, undercut = self.undercut, backlash = self.backlash, head = self.head) + self.__init__(m=self.m_n, z=self.z, + pressure_angle=self.pressure_angle, clearance=self.clearance, shift=self.shift, + beta=self.beta, undercut=self.undercut, backlash=self.backlash, head=self.head) -class involute_rack(object): +class InvoluteRack(object): def __init__(self, m=5, z=15, pressure_angle=20 * pi / 180., thickness=5, beta=0, head=0): self.pressure_angle = pressure_angle self.thickness = thickness @@ -161,7 +164,7 @@ class involute_rack(object): self.head = head def _update(self): - self.__init__(m = self.m, z = self.z, pressure_angle = self.pressure_angle, + self.__init__(m=self.m, z=self.z, pressure_angle=self.pressure_angle, thickness=self.thickness, beta=self.beta, head=self.head) def points(self, num=10): @@ -170,12 +173,12 @@ class involute_rack(object): a = (2 + self.head) * m * tan(pressure_angle_t) b = (m * pi) / 4 - (1 + self.head) * m * tan(pressure_angle_t) - tooth= [ + tooth = [ [-self.m, -a - b], [self.m * (1 + self.head), -b], [self.m * (1 + self.head), b], [-self.m, a + b] - ] + ] teeth = [tooth] trans = translation([0., m * pi, 0.]) for i in range(self.z - 1): @@ -189,12 +192,9 @@ class involute_rack(object): return(teeth) - - - if __name__ == "__main__": from matplotlib import pyplot - gear = involute_rack() + gear = InvoluteRack() x = [] y = [] for i in gear.points(30): @@ -202,4 +202,3 @@ if __name__ == "__main__": y.append(i[1]) pyplot.plot(x, y) pyplot.show() -