57 Commits

Author SHA1 Message Date
looooo
4e6223bffa Merge branch 'develop' of https://github.com/looooo/freecad.gears into develop 2022-06-10 14:18:54 +02:00
looooo
07bfe0446d do not use pythonocc-core 2022-06-10 14:18:37 +02:00
lorenz
05d2afef44 InvoluteGearRack: properties_from_tool default = False 2022-05-03 14:48:55 +02:00
looooo
2ede7f0bdc Merge branch 'develop' of https://github.com/looooo/freecad.gears into develop 2022-02-22 11:07:24 +01:00
looooo
6042cb8b4d add root-fillet for cycloid rack 2022-02-22 11:07:02 +01:00
luz paz
2e25ba6b97 Add extra metadata to package.xml 2022-02-21 10:34:55 +01:00
looooo
6a9baf4fed add package.xml 2022-02-20 12:14:04 +01:00
looooo
1cf83e7344 gear-rack add fillets 2022-02-10 14:15:19 +01:00
looooo
39e5ce1378 add head-fillet for cycloid gear racks 2022-02-02 23:33:47 +01:00
Jonas Bähr
9f1e87bedb Calculate pitch diameter and angular backlash via expressions
Using expressions instead of filling these values in the `execute` method
has the advantage that the values can be used in other expressions on the
same object. First, the expressions are evaluated, then the feature is
"executed". Previously, the changed values are only available after the
execution and thus had no effect if e.g. used in calculating the
placement of the very same gear (until another recompute happens).
2022-01-12 11:24:06 +01:00
Jonas Bähr
7c4723c9b7 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.
2022-01-08 11:03:26 +01:00
Jonas Bähr
d0e7720988 Fix head and clearance for the cycloid gear
Head and cleance values have been applied only once, but as we're dealing
with a diameter, not a radius, they are needed twice. (The involute gear
does not suffer from this bug)
2022-01-04 20:08:52 +01:00
Jonas Bähr
da42164552 Use expression as inner_diameter for cycloid gear
The cycloid gear is created with a default number of teeth of 15 and an
`inner_diameter` of 7.5. That is half the number of teeth and results in
an hypocycloid going orthogonal from the pitch circle right to the center.
This change now replaces the hard coded value "7.5" with the expression
"teeth / 2" so that this straight hypocycloid is kept, even if the number
of teeth is adapted. This allows easy reduction of the number of teeth
(down to two, in fact) without the recomputation to fail.
2022-01-04 20:05:28 +01:00
looooo
73f6b7f1f7 Merge branch 'develop' of https://github.com/looooo/freecad.gears into develop 2021-12-16 13:20:43 +01:00
looooo
590994984f connector: add support for internal involute gears 2021-12-16 13:20:11 +01:00
luz paz
b4783df755 Fix source comment typos 2021-12-07 21:19:20 +01:00
looooo
2ecc0e8744 cycloid gear rack: some fixes 2021-12-07 11:58:10 +01:00
looooo
d77f5c1ab4 connector: add support for racks 2021-12-06 21:03:14 +01:00
looooo
4aa2559629 connector: add support for cycloid gears 2021-12-04 14:07:08 +01:00
looooo
5846ffbfdc connector: add support for shifted gears 2021-12-04 13:25:20 +01:00
looooo
7edc50c32d some clean up 2021-12-02 15:14:06 +01:00
looooo
05abf3054d first prototyp for gear connector 2021-12-02 15:09:21 +01:00
looooo
10d4bf0bbf add missing files for gear connector 2021-12-02 12:45:49 +01:00
looooo
ea904a2a7d add prototype for gear connector 2021-12-02 12:44:34 +01:00
looooo
0eca70d832 change size of image 2021-12-01 13:28:57 +01:00
looooo
469e00cd98 add cycloid rack image 2021-12-01 13:26:12 +01:00
looooo
3668892abe cycloidgearrack additions 2021-12-01 11:10:27 +01:00
looooo
8b8f8e0779 cycloide gear rack 2021-11-30 15:27:52 +01:00
Scott Mudge
ef73b66040 add icon in same style as existing cycloid gear 2021-11-27 13:39:36 +01:00
Scott Mudge
89e99bef0e fix bugs 2021-11-24 15:00:51 +01:00
looooo
15f3f2410d add proto cycloide rack, fix icons-issue 2021-11-23 14:46:39 +01:00
looooo
fd363e2b84 some simplifications 2021-11-03 14:53:27 +01:00
looooo
81d6a77218 refactoring involute gear 2021-10-21 12:01:49 +02:00
lorenz
b75336b0ea fix lgtm allert 2021-10-19 10:46:32 +02:00
looooo
95a14777b9 use icons in treeview 2021-10-19 10:44:36 +02:00
looooo
7cb84f17e1 minor fix for the cycloide gear 2021-09-30 11:26:58 +02:00
looooo
b7a4192f70 fix internalgear, to work with head-, rootfillets 2021-09-29 10:40:45 +02:00
looooo
4db17dd2b0 fix internal gear 2021-09-29 10:21:00 +02:00
Jonas Bähr
165b52d967 Speedup the double helical gear generation significantly
It turned out that the "moving up" of the gear shape was responsible for
the majority of processing time: it took 10x longer then the pipe
creation and 100x longer then the mirroring.
Now the moving is done of the helix and base face so that the other faces
are generated directly where they should be, thus preventing a movement
of all of them.
In addition, as we don't have to transform the final shape, we don't have
to use transformGeometry, but just change the placement via translate --
again much faster.
2021-09-29 10:17:20 +02:00
Jonas Bähr
f1531a183b Cleanup: harmonize helicalextrusion and helicalextrusion2
The now only helicalextrusion is the one working on a face, not a wire,
and allows extrusions of "faces with holes". This is required for the
internal gears but also allows e.g. center holes for ordinary gears as
well (not in this commit).
2021-09-29 10:17:11 +02:00
Jonas Bähr
055aab2e07 Build the helical internal gear directly, not via boolen cut
The original, now replaced, way had the benefit of reusing the existing
helicalextrusion method, but the following boolean cut operation was a)
slow and b) suffered from co-planar issues. The new way extrudes the
face directly which does not have these shortcommings.
Unfortunaly, we had to use a different API: the original one is simple
and straight forward, gives no easy way to access the end of the sweep.
Collecting the wires manually, filtering on the position of all vertexes,
unvailed tolerances heigher then 0.1, so that a face created from it was
not planar and prevented ceating a valid solid.
The now used API requires more manual work in the initial setup, but the
end wires for construction the top face are directly accesible and the
tolerances are below 0.001 so we can create a planar face and valid solid.
This new way also much faster (1.6 sec vs. 5.0 sec on my machine
using default gear parameters on a double helix, naively measured via
`time.perf_counter()`).
Currently, the new helical extusion method is only used for the internal
gear. Migrating the other usages will be done as a separate commit.
2021-09-29 10:15:10 +02:00
Jonas Bähr
c40bae47b3 Give the internal involute gear its own icon 2021-09-29 10:14:41 +02:00
Jonas Bähr
6daa3114be Add an "internal involute gear" command and feature
This reuses the same (external) tooth profile from pygear but swap some
parameters to make the resulting gear internal.
This prototype is mostly a copy of the external involute gear. Eventually
we should refactor this to share more code but this has to be coordinated
with the megagrant endevour. Otherwise merging becomes a nightmere.
Note that in contrast to the involute rack I choose to base the
"thickness" on the pitch diameter, not the root diameter. This has the
benefit of keeping the outside diameter stable when e.g. adjusting the
clearance. And setting the outside diameter directly could result in an
invalid shape when chaning the numnber of teeth.
The default head value of "-0.4" is choosen to match the invernal gear
profile from the PartDewign WB.
2021-09-29 10:14:26 +02:00
looooo
4e16fd2560 merge error 2021-07-21 14:54:37 +02:00
looooo
56acace6ef Merge branch 'feature/fix-partdesign-tip' into megagrants 2021-07-21 14:39:43 +02:00
Jonas Bähr
37b99b119d Fix crown gear preview mode in PartDesign Bodies
Previously, the `preview_mode` of the crown gear returned a compound of
the base and the cut-outs. This caused problems in PD::Bodies where a
single solid is requried.
The solution in this commit changes the preview_mode to only output the
base, not generating the cutout shapes at all. This is consistent with
the involute gears having "simple=true" and saves again 0.5 Seconds
processsing time on my system using defaults (15 teeth, 4 loft profiles).

In addition, "preview = false" is also speed up by first collecting all
cut-outs, and then passing them all at once to a single cut operation.
This reduced the cutting time from 3.0 Seconds to 2.2 Seconds here.
So preview now generats the shape immediately (0.0008s vs 0.5s) and the
actual crown is generated in 2.7s instead of 3.5s (again, using the
defaut parameters, measued via Python's time.perf_counter).
2021-07-08 23:23:36 +02:00
Jonas Bähr
9983f5ee61 Extend the "additiveness" to all gears when used in PD:Bodies
There are still some issues when the generated Shape is not a solid,
e.g. in the preview mode of the Crown Gear.
2021-07-07 01:09:16 +02:00
Jonas Bähr
bd6c2107ee First proof of concept of "additive gears" in PartDesign bodies
In this PoC only the involute gears work, and there is still a lot of
cleanup pending.
What does work, however, is that those gears now play nicely with
PartDesign's concept of stacking features onto each other, i.e. that the
result of a feature is the fusion of all previous ones.

Special Thanks goes to DeepSOIC for his tutorial in the forum at [1] as
well as this Part-o-Matic which showed me how this works in real live [2]
[1]: https://forum.freecadweb.org/viewtopic.php?f=22&t=21097#p163340
[2]: https://github.com/DeepSOIC/Part-o-magic/blob/master/PartOMagic/Features/PartDesign/PDShapeFeature.py
2021-07-06 00:56:22 +02:00
luz paz
9225b5b4ed Fix source comment typo 2021-07-04 21:54:27 +02:00
looooo
175b746a7a foot -> root, bevelgear add warning for max height 2021-07-04 21:54:27 +02:00
looooo
1f70e28ac1 root fillet 2021-07-04 21:54:27 +02:00
looooo
403505ae95 add cycloide gear foot- and headfillet 2021-07-04 21:54:27 +02:00
looooo
ae1c272c42 use correct license headers 2021-07-04 21:54:27 +02:00
looooo
9ddd493b82 add head parameter for cycloide gear 2021-07-04 21:54:27 +02:00
looooo
3c9f6f0c6b add property for fillets (head, foot) 2021-07-04 21:54:27 +02:00
looooo
8174345a38 refactor 2021-07-04 21:54:27 +02:00
looooo
3dedcf3e21 add todo list 2021-07-04 21:54:27 +02:00
18 changed files with 2620 additions and 487 deletions

View File

@@ -26,6 +26,10 @@ __python > 3 (for python2 use branch py2)__
![cycloid-gear](examples/cycloid-gear.png) ![cycloid-gear](examples/cycloid-gear.png)
### Cycloid Rack
![cycloid-rack](examples/cycloid-rack.png)
### Spherical Involute Bevel-Gear ### Spherical Involute Bevel-Gear
* Spiral * Spiral

6
TODO.md Normal file
View File

@@ -0,0 +1,6 @@
#TODO:
## refactoring
- [ ] fp.gear.z -> fp.gear.num_teeth
- [ ] fp.teeth -> fp.gear.num_teeth

BIN
examples/cycloid-rack.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 188 KiB

View File

@@ -1,21 +1,18 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# *************************************************************************** # ***************************************************************************
# * * # * *
# * This program is free software; you can redistribute it and/or modify * # * This program is free software: you can redistribute it and/or modify *
# * it under the terms of the GNU Lesser General Public License (LGPL) * # * it under the terms of the GNU General Public License as published by *
# * as published by the Free Software Foundation; either version 2 of * # * the Free Software Foundation, either version 3 of the License, or *
# * the License, or (at your option) any later version. * # * (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, * # * This program is distributed in the hope that it will be useful, *
# * but WITHOUT ANY WARRANTY; without even the implied warranty of * # * but WITHOUT ANY WARRANTY; without even the implied warranty of *
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * # * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
# * GNU Library General Public License for more details. * # * GNU General Public License for more details. *
# * * # * *
# * You should have received a copy of the GNU Library General Public * # * You should have received a copy of the GNU General Public License *
# * License along with this program; if not, write to the Free Software * # * along with this program. If not, see <http://www.gnu.org/licenses/>. *
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
# * USA *
# * * # * *
# *************************************************************************** # ***************************************************************************

View File

@@ -1,29 +1,27 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# *************************************************************************** # ***************************************************************************
# * * # * *
# * This program is free software; you can redistribute it and/or modify * # * This program is free software: you can redistribute it and/or modify *
# * it under the terms of the GNU Lesser General Public License (LGPL) * # * it under the terms of the GNU General Public License as published by *
# * as published by the Free Software Foundation; either version 2 of * # * the Free Software Foundation, either version 3 of the License, or *
# * the License, or (at your option) any later version. * # * (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, * # * This program is distributed in the hope that it will be useful, *
# * but WITHOUT ANY WARRANTY; without even the implied warranty of * # * but WITHOUT ANY WARRANTY; without even the implied warranty of *
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * # * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
# * GNU Library General Public License for more details. * # * GNU General Public License for more details. *
# * * # * *
# * You should have received a copy of the GNU Library General Public * # * You should have received a copy of the GNU General Public License *
# * License along with this program; if not, write to the Free Software * # * along with this program. If not, see <http://www.gnu.org/licenses/>. *
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
# * USA *
# * * # * *
# *************************************************************************** # ***************************************************************************
import os import os
import FreeCAD import FreeCAD
import FreeCADGui as Gui import FreeCADGui as Gui
from .features import ViewProviderGear, InvoluteGear, InvoluteGearRack from .features import ViewProviderGear, InvoluteGear, InternalInvoluteGear, InvoluteGearRack, CycloidGearRack
from .features import CycloidGear, BevelGear, CrownGear, WormGear, TimingGear, LanternGear, HypoCycloidGear from .features import CycloidGear, BevelGear, CrownGear, WormGear, TimingGear, LanternGear, HypoCycloidGear, BaseGear
from .connector import GearConnector, ViewProviderGearConnector
class BaseCommand(object): class BaseCommand(object):
@@ -59,11 +57,11 @@ class BaseCommand(object):
obj = FreeCAD.ActiveDocument.addObject("PartDesign::FeaturePython", cls.NAME) obj = FreeCAD.ActiveDocument.addObject("PartDesign::FeaturePython", cls.NAME)
else: else:
obj = FreeCAD.ActiveDocument.addObject("Part::FeaturePython", cls.NAME) obj = FreeCAD.ActiveDocument.addObject("Part::FeaturePython", cls.NAME)
ViewProviderGear(obj.ViewObject) ViewProviderGear(obj.ViewObject, cls.Pixmap)
cls.GEAR_FUNCTION(obj) cls.GEAR_FUNCTION(obj)
if body: if body:
body.Group += [obj] body.addObject(obj)
elif part: elif part:
part.Group += [obj] part.Group += [obj]
else: else:
@@ -78,70 +76,108 @@ class BaseCommand(object):
class CreateInvoluteGear(BaseCommand): class CreateInvoluteGear(BaseCommand):
NAME = "involutegear" NAME = "InvoluteGear"
GEAR_FUNCTION = InvoluteGear GEAR_FUNCTION = InvoluteGear
Pixmap = os.path.join(BaseCommand.ICONDIR, 'involutegear.svg') Pixmap = os.path.join(BaseCommand.ICONDIR, 'involutegear.svg')
MenuText = 'Involute gear' MenuText = 'Involute Gear'
ToolTip = 'Create an Involute gear' ToolTip = 'Create an external involute gear'
class CreateInternalInvoluteGear(BaseCommand):
NAME = "InternalInvoluteGear"
GEAR_FUNCTION = InternalInvoluteGear
Pixmap = os.path.join(BaseCommand.ICONDIR, 'internalinvolutegear.svg')
MenuText = 'Internal Involute Gear'
ToolTip = 'Create an internal involute gear'
class CreateInvoluteRack(BaseCommand): class CreateInvoluteRack(BaseCommand):
NAME = "involuterack" NAME = "InvoluteRack"
GEAR_FUNCTION = InvoluteGearRack GEAR_FUNCTION = InvoluteGearRack
Pixmap = os.path.join(BaseCommand.ICONDIR, 'involuterack.svg') Pixmap = os.path.join(BaseCommand.ICONDIR, 'involuterack.svg')
MenuText = 'Involute rack' MenuText = 'Involute Rack'
ToolTip = 'Create an Involute rack' ToolTip = 'Create an Involute rack'
class CreateCycloidRack(BaseCommand):
NAME = "CycloidRack"
GEAR_FUNCTION = CycloidGearRack
Pixmap = os.path.join(BaseCommand.ICONDIR, 'cycloidrack.svg')
MenuText = 'Cycloid Rack'
ToolTip = 'Create an Cycloid rack'
class CreateCrownGear(BaseCommand): class CreateCrownGear(BaseCommand):
NAME = "crowngear" NAME = "CrownGear"
GEAR_FUNCTION = CrownGear GEAR_FUNCTION = CrownGear
Pixmap = os.path.join(BaseCommand.ICONDIR, 'crowngear.svg') Pixmap = os.path.join(BaseCommand.ICONDIR, 'crowngear.svg')
MenuText = 'Crown gear' MenuText = 'Crown Gear'
ToolTip = 'Create a Crown gear' ToolTip = 'Create a Crown gear'
class CreateCycloidGear(BaseCommand): class CreateCycloidGear(BaseCommand):
NAME = "cycloidgear" NAME = "CycloidGear"
GEAR_FUNCTION = CycloidGear GEAR_FUNCTION = CycloidGear
Pixmap = os.path.join(BaseCommand.ICONDIR, 'cycloidgear.svg') Pixmap = os.path.join(BaseCommand.ICONDIR, 'cycloidgear.svg')
MenuText = 'Cycloid gear' MenuText = 'Cycloid Gear'
ToolTip = 'Create a Cycloid gear' ToolTip = 'Create a Cycloid gear'
class CreateBevelGear(BaseCommand): class CreateBevelGear(BaseCommand):
NAME = "bevelgear" NAME = "BevelGear"
GEAR_FUNCTION = BevelGear GEAR_FUNCTION = BevelGear
Pixmap = os.path.join(BaseCommand.ICONDIR, 'bevelgear.svg') Pixmap = os.path.join(BaseCommand.ICONDIR, 'bevelgear.svg')
MenuText = 'Bevel gear' MenuText = 'Bevel Gear'
ToolTip = 'Create a Bevel gear' ToolTip = 'Create a Bevel gear'
class CreateHypoCycloidGear(BaseCommand): class CreateHypoCycloidGear(BaseCommand):
NAME = "hypocycloidgear" NAME = "HypocycloidGear"
GEAR_FUNCTION = HypoCycloidGear GEAR_FUNCTION = HypoCycloidGear
Pixmap = os.path.join(BaseCommand.ICONDIR, 'hypocycloidgear.svg') Pixmap = os.path.join(BaseCommand.ICONDIR, 'hypocycloidgear.svg')
MenuText = 'HypoCycloid gear' MenuText = 'HypoCycloid Gear'
ToolTip = 'Create a HypoCycloid gear with its pins' ToolTip = 'Create a HypoCycloid gear with its pins'
class CreateWormGear(BaseCommand): class CreateWormGear(BaseCommand):
NAME = "wormgear" NAME = "WormGear"
GEAR_FUNCTION = WormGear GEAR_FUNCTION = WormGear
Pixmap = os.path.join(BaseCommand.ICONDIR, 'wormgear.svg') Pixmap = os.path.join(BaseCommand.ICONDIR, 'wormgear.svg')
MenuText = 'Worm gear' MenuText = 'Worm Gear'
ToolTip = 'Create a Worm gear' ToolTip = 'Create a Worm gear'
class CreateTimingGear(BaseCommand): class CreateTimingGear(BaseCommand):
NAME = "timinggear" NAME = "TimingGear"
GEAR_FUNCTION = TimingGear GEAR_FUNCTION = TimingGear
Pixmap = os.path.join(BaseCommand.ICONDIR, 'timinggear.svg') Pixmap = os.path.join(BaseCommand.ICONDIR, 'timinggear.svg')
MenuText = 'Timing gear' MenuText = 'Timing Gear'
ToolTip = 'Create a Timing gear' ToolTip = 'Create a Timing gear'
class CreateLanternGear(BaseCommand): class CreateLanternGear(BaseCommand):
NAME = "lanterngear" NAME = "LanternGear"
GEAR_FUNCTION = LanternGear GEAR_FUNCTION = LanternGear
Pixmap = os.path.join(BaseCommand.ICONDIR, 'lanterngear.svg') Pixmap = os.path.join(BaseCommand.ICONDIR, 'lanterngear.svg')
MenuText = 'Lantern gear' MenuText = 'Lantern Gear'
ToolTip = 'Create a Lantern gear' ToolTip = 'Create a Lantern gear'
class CreateGearConnector(BaseCommand):
NAME = "GearConnector"
GEAR_FUNCTION = GearConnector
Pixmap = os.path.join(BaseCommand.ICONDIR, 'gearconnector.svg')
MenuText = 'Combine two gears'
ToolTip = 'Combine two gears'
def Activated(self):
gear1 = Gui.Selection.getSelection()[0]
assert isinstance(gear1.Proxy, BaseGear)
gear2 = Gui.Selection.getSelection()[1]
assert isinstance(gear2.Proxy, BaseGear)
# check if selected objects are beams
obj = FreeCAD.ActiveDocument.addObject("Part::FeaturePython", self.NAME)
GearConnector(obj, gear1, gear2)
ViewProviderGearConnector(obj.ViewObject)
FreeCAD.ActiveDocument.recompute()
return obj

161
freecad/gears/connector.py Normal file
View File

@@ -0,0 +1,161 @@
# -*- coding: utf-8 -*-
# ***************************************************************************
# * *
# * This program is free software: you can redistribute it and/or modify *
# * it under the terms of the GNU General Public License as published by *
# * the Free Software Foundation, either version 3 of the License, or *
# * (at your option) any later version. *
# * *
# * This program is distributed in the hope that it will be useful, *
# * but WITHOUT ANY WARRANTY; without even the implied warranty of *
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
# * GNU General Public License for more details. *
# * *
# * You should have received a copy of the GNU General Public License *
# * along with this program. If not, see <http://www.gnu.org/licenses/>. *
# * *
# ***************************************************************************
import os
import copy
import numpy as np
import FreeCAD
from pygears import __version__
from .features import InvoluteGear, CycloidGear, InvoluteGearRack, CycloidGearRack, InternalInvoluteGear
from pygears.computation import compute_shifted_gears
class ViewProviderGearConnector(object):
def __init__(self, vobj, icon_fn=None):
# Set this object to the proxy object of the actual view provider
vobj.Proxy = self
dirname = os.path.dirname(__file__)
self.icon_fn = icon_fn or os.path.join(dirname, "icons", "gearconnector.svg")
def attach(self, vobj):
self.vobj = vobj
def getIcon(self):
return self.icon_fn
def __getstate__(self):
return {"icon_fn": self.icon_fn}
def __setstate__(self, state):
self.icon_fn = state["icon_fn"]
class GearConnector(object):
def __init__(self, obj, master_gear, slave_gear):
obj.addProperty("App::PropertyString", "version", "version", "freecad.gears-version", 1)
obj.addProperty("App::PropertyLink","master_gear","gear","master gear", 1)
obj.addProperty("App::PropertyLink","slave_gear","gear","slave gear", 1)
obj.addProperty("App::PropertyAngle", "angle1", "gear", "angle at which second gear is placed", 0)
obj.addProperty("App::PropertyAngle", "angle2", "gear", "angle at which second gear is placed", 1)
obj.version = __version__
obj.master_gear = master_gear
obj.slave_gear = slave_gear
obj.angle1 = 0
obj.angle2 = 0
obj.Proxy = self
def onChanged(self, fp, prop):
# fp.angle2 = fp.master_gear.Placement.Rotation.Angle
if isinstance(fp.master_gear.Proxy, InvoluteGear) and isinstance(fp.slave_gear.Proxy, InvoluteGear):
angle_master = fp.master_gear.Placement.Rotation.Angle * sum(fp.master_gear.Placement.Rotation.Axis)
dw_master = fp.master_gear.dw
dw_slave = fp.slave_gear.dw
dist = (dw_master + dw_slave) / 2
if fp.master_gear.shift != 0 or fp.slave_gear.shift != 0:
dist, alpha_w = compute_shifted_gears(
fp.master_gear.module,
np.deg2rad(fp.master_gear.pressure_angle.Value),
fp.master_gear.teeth,
fp.slave_gear.teeth,
fp.master_gear.shift,
fp.slave_gear.shift)
mat0 = FreeCAD.Matrix() # unity matrix
trans = FreeCAD.Vector(dist)
mat0.move(trans)
rot = FreeCAD.Rotation(FreeCAD.Vector(0,0,1), fp.angle1).toMatrix()
angle2 = dw_master / dw_slave * fp.angle1.Value
angle4 = dw_master / dw_slave * np.rad2deg(angle_master)
rot2 = FreeCAD.Rotation(FreeCAD.Vector(0,0,1), angle2).toMatrix()
angle3 = abs(fp.slave_gear.teeth % 2 - 1) * 180. / fp.slave_gear.teeth
rot3 = FreeCAD.Rotation(FreeCAD.Vector(0,0,1), angle3).toMatrix()
rot4 = FreeCAD.Rotation(FreeCAD.Vector(0,0,1), -angle4).toMatrix()
mat1 = rot * mat0 * rot2 * rot3 * rot4
mat1.move(fp.master_gear.Placement.Base)
fp.slave_gear.Placement = mat1
if isinstance(fp.master_gear.Proxy, InternalInvoluteGear) and isinstance(fp.slave_gear.Proxy, InvoluteGear):
angle_master = fp.master_gear.Placement.Rotation.Angle * sum(fp.master_gear.Placement.Rotation.Axis)
dw_master = fp.master_gear.dw
dw_slave = fp.slave_gear.dw
dist = (dw_master - dw_slave) / 2
if fp.master_gear.shift != 0 or fp.slave_gear.shift != 0:
dist, alpha_w = compute_shifted_gears(
fp.master_gear.module,
np.deg2rad(fp.master_gear.pressure_angle.Value),
fp.master_gear.teeth,
fp.slave_gear.teeth,
fp.master_gear.shift,
fp.slave_gear.shift)
mat0 = FreeCAD.Matrix() # unity matrix
trans = FreeCAD.Vector(dist)
mat0.move(trans)
rot = FreeCAD.Rotation(FreeCAD.Vector(0,0,1), fp.angle1).toMatrix()
angle2 = -dw_master / dw_slave * fp.angle1.Value
angle4 = -dw_master / dw_slave * np.rad2deg(angle_master)
rot2 = FreeCAD.Rotation(FreeCAD.Vector(0,0,1), angle2).toMatrix()
angle3 = abs(fp.slave_gear.teeth % 2 - 1) * 180. / fp.slave_gear.teeth
rot3 = FreeCAD.Rotation(FreeCAD.Vector(0,0,1), angle3).toMatrix()
rot4 = FreeCAD.Rotation(FreeCAD.Vector(0,0,1), -angle4).toMatrix()
mat1 = rot * mat0 * rot2 * rot3 * rot4
mat1.move(fp.master_gear.Placement.Base)
fp.slave_gear.Placement = mat1
if ((isinstance(fp.master_gear.Proxy, InvoluteGear) and isinstance(fp.slave_gear.Proxy, InvoluteGearRack))
or (isinstance(fp.master_gear.Proxy, CycloidGear) and isinstance(fp.slave_gear.Proxy, CycloidGearRack))):
angle_master = fp.master_gear.Placement.Rotation.Angle * sum(fp.master_gear.Placement.Rotation.Axis)
dw_master = fp.master_gear.dw.Value
dw_slave = 0
dist = -(dw_master + dw_slave) / 2
mat0 = FreeCAD.Matrix() # unity matrix
mat0.move(FreeCAD.Vector(dist, 0, 0))
mat1 = FreeCAD.Matrix()
mat1.move(FreeCAD.Vector(0, np.deg2rad(fp.angle1.Value) * dw_master / 2, 0))
mat2 = FreeCAD.Matrix()
mat2.move(FreeCAD.Vector(0, -np.deg2rad(fp.angle2.Value) * dw_master / 2, 0))
rot = FreeCAD.Rotation(FreeCAD.Vector(0,0,1), fp.angle1).toMatrix()
mat3 = rot * mat2 *mat1 * mat0
mat3.move(fp.master_gear.Placement.Base)
fp.slave_gear.Placement = mat3
if isinstance(fp.master_gear.Proxy, CycloidGear) and isinstance(fp.slave_gear.Proxy, CycloidGear):
angle_master = fp.master_gear.Placement.Rotation.Angle * sum(fp.master_gear.Placement.Rotation.Axis)
dw_master = fp.master_gear.dw
dw_slave = fp.slave_gear.dw
dist = (dw_master + dw_slave) / 2
mat0 = FreeCAD.Matrix() # unity matrix
trans = FreeCAD.Vector(dist, 0, 0)
mat0.move(trans)
rot = FreeCAD.Rotation(FreeCAD.Vector(0,0,1), fp.angle1).toMatrix()
angle2 = dw_master / dw_slave * fp.angle1.Value
angle4 = dw_master / dw_slave * np.rad2deg(angle_master)
rot2 = FreeCAD.Rotation(FreeCAD.Vector(0,0,1), angle2).toMatrix()
angle3 = abs(fp.slave_gear.teeth % 2 - 1) * 180. / fp.slave_gear.teeth
rot3 = FreeCAD.Rotation(FreeCAD.Vector(0,0,1), angle3).toMatrix()
rot4 = FreeCAD.Rotation(FreeCAD.Vector(0,0,1), -angle4).toMatrix()
mat1 = rot * mat0 * rot2 * rot3 * rot4
mat1.move(fp.master_gear.Placement.Base)
fp.slave_gear.Placement = mat1
def execute(self, fp):
self.onChanged(fp, None)

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 21 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 18 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 14 KiB

View File

@@ -1,21 +1,18 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# *************************************************************************** # ***************************************************************************
# * * # * *
# * This program is free software; you can redistribute it and/or modify * # * This program is free software: you can redistribute it and/or modify *
# * it under the terms of the GNU Lesser General Public License (LGPL) * # * it under the terms of the GNU General Public License as published by *
# * as published by the Free Software Foundation; either version 2 of * # * the Free Software Foundation, either version 3 of the License, or *
# * the License, or (at your option) any later version. * # * (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, * # * This program is distributed in the hope that it will be useful, *
# * but WITHOUT ANY WARRANTY; without even the implied warranty of * # * but WITHOUT ANY WARRANTY; without even the implied warranty of *
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * # * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
# * GNU Library General Public License for more details. * # * GNU General Public License for more details. *
# * * # * *
# * You should have received a copy of the GNU Library General Public * # * You should have received a copy of the GNU General Public License *
# * License along with this program; if not, write to the Free Software * # * along with this program. If not, see <http://www.gnu.org/licenses/>. *
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
# * USA *
# * * # * *
# *************************************************************************** # ***************************************************************************
@@ -40,29 +37,35 @@ class GearWorkbench(Workbench):
Icon = os.path.join(__dirname__, 'icons', 'gearworkbench.svg') Icon = os.path.join(__dirname__, 'icons', 'gearworkbench.svg')
commands = [ commands = [
"CreateInvoluteGear", "CreateInvoluteGear",
"CreateInternalInvoluteGear",
"CreateInvoluteRack", "CreateInvoluteRack",
"CreateCycloidGear", "CreateCycloidGear",
"CreateCycloidRack",
"CreateBevelGear", "CreateBevelGear",
"CreateCrownGear", "CreateCrownGear",
"CreateWormGear", "CreateWormGear",
"CreateTimingGear", "CreateTimingGear",
"CreateLanternGear", "CreateLanternGear",
"CreateHypoCycloidGear"] "CreateHypoCycloidGear",
"CreateGearConnector"]
def GetClassName(self): def GetClassName(self):
return "Gui::PythonWorkbench" return "Gui::PythonWorkbench"
def Initialize(self): def Initialize(self):
from .commands import CreateCycloidGear, CreateInvoluteGear from .commands import CreateCycloidGear, CreateInvoluteGear, CreateInternalInvoluteGear
from .commands import CreateBevelGear, CreateInvoluteRack, CreateCrownGear from .commands import CreateBevelGear, CreateInvoluteRack, CreateCrownGear
from .commands import CreateWormGear, CreateTimingGear, CreateLanternGear from .commands import CreateWormGear, CreateTimingGear, CreateLanternGear
from .commands import CreateHypoCycloidGear from .commands import CreateHypoCycloidGear, CreateCycloidRack
from .commands import CreateGearConnector
self.appendToolbar("Gear", self.commands) self.appendToolbar("Gear", self.commands)
self.appendMenu("Gear", self.commands) self.appendMenu("Gear", self.commands)
# Gui.addIconPath(App.getHomePath()+"Mod/gear/icons/") # Gui.addIconPath(App.getHomePath()+"Mod/gear/icons/")
Gui.addCommand('CreateInvoluteGear', CreateInvoluteGear()) Gui.addCommand('CreateInvoluteGear', CreateInvoluteGear())
Gui.addCommand('CreateInternalInvoluteGear', CreateInternalInvoluteGear())
Gui.addCommand('CreateCycloidGear', CreateCycloidGear()) Gui.addCommand('CreateCycloidGear', CreateCycloidGear())
Gui.addCommand('CreateCycloidRack', CreateCycloidRack())
Gui.addCommand('CreateBevelGear', CreateBevelGear()) Gui.addCommand('CreateBevelGear', CreateBevelGear())
Gui.addCommand('CreateInvoluteRack', CreateInvoluteRack()) Gui.addCommand('CreateInvoluteRack', CreateInvoluteRack())
Gui.addCommand('CreateCrownGear', CreateCrownGear()) Gui.addCommand('CreateCrownGear', CreateCrownGear())
@@ -70,6 +73,7 @@ class GearWorkbench(Workbench):
Gui.addCommand('CreateTimingGear', CreateTimingGear()) Gui.addCommand('CreateTimingGear', CreateTimingGear())
Gui.addCommand('CreateLanternGear', CreateLanternGear()) Gui.addCommand('CreateLanternGear', CreateLanternGear())
Gui.addCommand('CreateHypoCycloidGear', CreateHypoCycloidGear()) Gui.addCommand('CreateHypoCycloidGear', CreateHypoCycloidGear())
Gui.addCommand('CreateGearConnector', CreateGearConnector())
def Activated(self): def Activated(self):
pass pass

24
package.xml Normal file
View File

@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<package format="1" xmlns="https://wiki.freecad.org/Package_Metadata">
<name>freecad.gears workbench</name>
<description>A gear workbench for FreeCAD</description>
<version>1.0</version>
<date>2022-02-07</date>
<maintainer email="sppedflyer@gmail.com">looooo</maintainer>
<license file="LICENSE">GPL 3</license>
<url type="repository" branch="develop">https://github.com/looooo/freecad.gears</url>
<url type="bugtracker">https://github.com/looooo/freecad.gears/issues</url>
<url type="documentation">https://wiki.freecad.org/FCGear_Workbench</url>
<icon>freecad/gears/icons/gearworkbench.svg</icon>
<content>
<workbench>
<classname>GearWorkbench</classname>
<subdirectory>./</subdirectory>
<freecadmin>0.19</freecadmin>
<tag>gear</tag>
<tag>gears</tag>
</workbench>
</content>
</package>

View File

@@ -1,22 +1,19 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# *************************************************************************** # ***************************************************************************
# * * # * *
# * This program is free software; you can redistribute it and/or modify * # * This program is free software: you can redistribute it and/or modify *
# * it under the terms of the GNU Lesser General Public License (LGPL) * # * it under the terms of the GNU General Public License as published by *
# * as published by the Free Software Foundation; either version 2 of * # * the Free Software Foundation, either version 3 of the License, or *
# * the License, or (at your option) any later version. * # * (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, * # * This program is distributed in the hope that it will be useful, *
# * but WITHOUT ANY WARRANTY; without even the implied warranty of * # * but WITHOUT ANY WARRANTY; without even the implied warranty of *
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * # * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
# * GNU Library General Public License for more details. * # * GNU General Public License for more details. *
# * * # * *
# * You should have received a copy of the GNU Library General Public * # * You should have received a copy of the GNU General Public License *
# * License along with this program; if not, write to the Free Software * # * along with this program. If not, see <http://www.gnu.org/licenses/>. *
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
# * USA *
# * * # * *
# *************************************************************************** # ***************************************************************************
__version__ = "0.0.3" __version__ = "0.0.4"

View File

@@ -1,21 +1,18 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# *************************************************************************** # ***************************************************************************
# * * # * *
# * This program is free software; you can redistribute it and/or modify * # * This program is free software: you can redistribute it and/or modify *
# * it under the terms of the GNU Lesser General Public License (LGPL) * # * it under the terms of the GNU General Public License as published by *
# * as published by the Free Software Foundation; either version 2 of * # * the Free Software Foundation, either version 3 of the License, or *
# * the License, or (at your option) any later version. * # * (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, * # * This program is distributed in the hope that it will be useful, *
# * but WITHOUT ANY WARRANTY; without even the implied warranty of * # * but WITHOUT ANY WARRANTY; without even the implied warranty of *
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * # * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
# * GNU Library General Public License for more details. * # * GNU General Public License for more details. *
# * * # * *
# * You should have received a copy of the GNU Library General Public * # * You should have received a copy of the GNU General Public License *
# * License along with this program; if not, write to the Free Software * # * along with this program. If not, see <http://www.gnu.org/licenses/>. *
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
# * USA *
# * * # * *
# *************************************************************************** # ***************************************************************************

View File

@@ -1,21 +1,18 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# *************************************************************************** # ***************************************************************************
# * * # * *
# * This program is free software; you can redistribute it and/or modify * # * This program is free software: you can redistribute it and/or modify *
# * it under the terms of the GNU Lesser General Public License (LGPL) * # * it under the terms of the GNU General Public License as published by *
# * as published by the Free Software Foundation; either version 2 of * # * the Free Software Foundation, either version 3 of the License, or *
# * the License, or (at your option) any later version. * # * (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, * # * This program is distributed in the hope that it will be useful, *
# * but WITHOUT ANY WARRANTY; without even the implied warranty of * # * but WITHOUT ANY WARRANTY; without even the implied warranty of *
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * # * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
# * GNU Library General Public License for more details. * # * GNU General Public License for more details. *
# * * # * *
# * You should have received a copy of the GNU Library General Public * # * You should have received a copy of the GNU General Public License *
# * License along with this program; if not, write to the Free Software * # * along with this program. If not, see <http://www.gnu.org/licenses/>. *
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
# * USA *
# * * # * *
# *************************************************************************** # ***************************************************************************
@@ -33,6 +30,7 @@ class BevelTooth(object):
self.z = z self.z = z
self.clearance = clearance self.clearance = clearance
self.backlash = backlash self.backlash = backlash
self.angular_backlash = backlash / (z * module / 2)
self.module = module self.module = module
self.involute_end = arccos( self.involute_end = arccos(
@@ -111,7 +109,7 @@ class BevelTooth(object):
intersection_point = intersection_line_circle(xy[i], point, r_cut) 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] 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) xyz = backlash_rot(xyz)
return(xyz) return(xyz)

View File

@@ -1,26 +1,22 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# *************************************************************************** # ***************************************************************************
# * * # * *
# * This program is free software; you can redistribute it and/or modify * # * This program is free software: you can redistribute it and/or modify *
# * it under the terms of the GNU Lesser General Public License (LGPL) * # * it under the terms of the GNU General Public License as published by *
# * as published by the Free Software Foundation; either version 2 of * # * the Free Software Foundation, either version 3 of the License, or *
# * the License, or (at your option) any later version. * # * (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, * # * This program is distributed in the hope that it will be useful, *
# * but WITHOUT ANY WARRANTY; without even the implied warranty of * # * but WITHOUT ANY WARRANTY; without even the implied warranty of *
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * # * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
# * GNU Library General Public License for more details. * # * GNU General Public License for more details. *
# * * # * *
# * You should have received a copy of the GNU Library General Public * # * You should have received a copy of the GNU General Public License *
# * License along with this program; if not, write to the Free Software * # * along with this program. If not, see <http://www.gnu.org/licenses/>. *
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
# * USA *
# * * # * *
# *************************************************************************** # ***************************************************************************
import numpy as np import numpy as np
from scipy import optimize as opt
def compute_shifted_gears(m, alpha, t1, t2, x1, x2): def compute_shifted_gears(m, alpha, t1, t2, x1, x2):
@@ -37,10 +33,32 @@ def compute_shifted_gears(m, alpha, t1, t2, x1, x2):
Returns: Returns:
(float, float): distance between gears [length], pressure angle of the assembly [rad] (float, float): distance between gears [length], pressure angle of the assembly [rad]
""" """
def inv(x): return 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) inv_alpha_w = inv(alpha) + 2 * np.tan(alpha) * (x1 + x2) / (t1 + t2)
def root_inv(x): return inv(x) - inv_alpha_w def root_inv(x):
alpha_w = opt.fsolve(root_inv, 0.) return inv(x) - inv_alpha_w
def d_root_inv(x):
return 1. / 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) dist = m * (t1 + t2) / 2 * np.cos(alpha) / np.cos(alpha_w)
return dist, alpha_w return dist, alpha_w
def find_root(x0, f, df, epsilon=2e-10, max_iter=100):
x_n = x0
for i in range(max_iter):
f_xn = f(x_n)
if abs(f_xn) < epsilon:
return x_n
else:
df_xn = df(x_n)
if df_xn == 0:
return None
else:
x_n = x_n - f_xn / df_xn / 2 # adding (/ 2) to avoid oscillation
return None

View File

@@ -1,21 +1,18 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# *************************************************************************** # ***************************************************************************
# * * # * *
# * This program is free software; you can redistribute it and/or modify * # * This program is free software: you can redistribute it and/or modify *
# * it under the terms of the GNU Lesser General Public License (LGPL) * # * it under the terms of the GNU General Public License as published by *
# * as published by the Free Software Foundation; either version 2 of * # * the Free Software Foundation, either version 3 of the License, or *
# * the License, or (at your option) any later version. * # * (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, * # * This program is distributed in the hope that it will be useful, *
# * but WITHOUT ANY WARRANTY; without even the implied warranty of * # * but WITHOUT ANY WARRANTY; without even the implied warranty of *
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * # * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
# * GNU Library General Public License for more details. * # * GNU General Public License for more details. *
# * * # * *
# * You should have received a copy of the GNU Library General Public * # * You should have received a copy of the GNU General Public License *
# * License along with this program; if not, write to the Free Software * # * along with this program. If not, see <http://www.gnu.org/licenses/>. *
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
# * USA *
# * * # * *
# *************************************************************************** # ***************************************************************************
@@ -25,13 +22,14 @@ from ._functions import rotation, reflection
class CycloidTooth(): class CycloidTooth():
def __init__(self, z1=5, z2=5, z=14, m=5, clearance=0.12, backlash=0.00): def __init__(self, z1=5, z2=5, z=14, m=5, clearance=0.25, backlash=0.00, head=0.0):
self.m = m self.m = m
self.z = z self.z = z
self.clearance = clearance self.clearance = clearance
self.backlash = backlash self.backlash = backlash
self.z1 = z1 self.z1 = z1
self.z2 = z2 self.z2 = z2
self.head = head
self._calc_gear_factors() self._calc_gear_factors()
def _calc_gear_factors(self): def _calc_gear_factors(self):
@@ -39,9 +37,10 @@ class CycloidTooth():
self.d2 = self.z2 * self.m self.d2 = self.z2 * self.m
self.phi = self.m * pi self.phi = self.m * pi
self.d = self.z * self.m self.d = self.z * self.m
self.da = self.d + 2*self.m self.da = self.d + 2 * (1 + self.head) * self.m
self.di = self.d - 2*self.m - self.clearance * self.m self.di = self.d - 2 * (1 + self.clearance) * self.m
self.phipart = 2 * pi / self.z self.phipart = 2 * pi / self.z
self.angular_backlash = self.backlash / (self.d / 2)
def epicycloid_x(self): def epicycloid_x(self):
def func(t): def func(t):
@@ -94,7 +93,7 @@ class CycloidTooth():
pts_outer = transpose([pts_outer_x, pts_outer_y]) pts_outer = transpose([pts_outer_x, pts_outer_y])
pts_inner = transpose([pts_inner_x, pts_inner_y]) pts_inner = transpose([pts_inner_x, pts_inner_y])
pts1 = vstack([pts_inner[:-2], pts_outer]) 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) pts1 = rot(pts1)
ref = reflection(0.) ref = reflection(0.)
pts2 = ref(pts1)[::-1] pts2 = ref(pts1)[::-1]
@@ -103,5 +102,5 @@ class CycloidTooth():
def _update(self): def _update(self):
self.__init__(m=self.m, z=self.z, z1=self.z1, z2=self.z2, self.__init__(m=self.m, z=self.z, z1=self.z1, z2=self.z2,
clearance=self.clearance, backlash=self.backlash) clearance=self.clearance, backlash=self.backlash, head=self.head)

View File

@@ -1,21 +1,18 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# *************************************************************************** # ***************************************************************************
# * * # * *
# * This program is free software; you can redistribute it and/or modify * # * This program is free software: you can redistribute it and/or modify *
# * it under the terms of the GNU Lesser General Public License (LGPL) * # * it under the terms of the GNU General Public License as published by *
# * as published by the Free Software Foundation; either version 2 of * # * the Free Software Foundation, either version 3 of the License, or *
# * the License, or (at your option) any later version. * # * (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, * # * This program is distributed in the hope that it will be useful, *
# * but WITHOUT ANY WARRANTY; without even the implied warranty of * # * but WITHOUT ANY WARRANTY; without even the implied warranty of *
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * # * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
# * GNU Library General Public License for more details. * # * GNU General Public License for more details. *
# * * # * *
# * You should have received a copy of the GNU Library General Public * # * You should have received a copy of the GNU General Public License *
# * License along with this program; if not, write to the Free Software * # * along with this program. If not, see <http://www.gnu.org/licenses/>. *
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
# * USA *
# * * # * *
# *************************************************************************** # ***************************************************************************
@@ -72,6 +69,7 @@ class InvoluteTooth():
self.involute_rot2 = 1 / self.z * \ self.involute_rot2 = 1 / self.z * \
(pi / 2 + 2 * self.shift * tan(self.pressure_angle_t)) (pi / 2 + 2 * self.shift * tan(self.pressure_angle_t))
self.involute_rot = self.involute_rot1 + self.involute_rot2 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.
if self.dg <= self.df: 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
@@ -84,7 +82,7 @@ class InvoluteTooth():
y = array(list(map(fy, pts))) y = array(list(map(fy, pts)))
xy = transpose([x, y]) xy = transpose([x, y])
rotate = rotation( rotate = rotation(
self.undercut_rot + self.phipart / 2 - self.backlash / 4) self.undercut_rot + self.phipart / 2 - self.angular_backlash / 2)
xy = rotate(xy) xy = rotate(xy)
return(array(xy)) return(array(xy))
@@ -94,7 +92,7 @@ class InvoluteTooth():
x = array(list(map(fx, pts))) x = array(list(map(fx, pts)))
fy = self.involute_function_y() fy = self.involute_function_y()
y = array(list(map(fy, pts))) 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]))) xy = rot(transpose(array([x, y])))
return(xy) return(xy)