involuteGearGraphics.py
You can view and download this file on Github: involuteGearGraphics.py
1#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2# This is an EXUDYN example
3#
4# Details: Test bearing model with two ball bearings on rigid shaft
5#
6# Author: Johannes Gerstmayr
7# Date: 2025-05-17
8#
9# Copyright:This file is part of Exudyn. Exudyn is free software. You can redistribute it and/or modify it under the terms of the Exudyn license. See 'LICENSE.txt' for more details.
10#
11#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
12
13import exudyn as exu
14from exudyn.utilities import *
15import exudyn.graphics as graphics
16import numpy as np
17from exudyn.machines import InvoluteGear
18
19# from exudyn.graphics import color
20# from math import radians, tan
21
22
23useGraphics = True #without test
24SC = exu.SystemContainer()
25mbs = SC.AddSystem()
26
27
28#+++++++++++++++++++++++++++++++++++++++++++
29#we need to create markers for outer ring and inner ring:
30shaftRadius = 0.025
31shaftLength = 0.200
32shaftRadius2 = 0.012
33shaftLength2 = 0.100
34density = 7800
35gBack = graphics.CheckerBoard([0,0,0], normal=[0,1,0], size=1)
36
37oGround = mbs.CreateGround(graphicsDataList=[gBack])
38
39#create body for shaft:
40offY = 0.15 #y-position of shaft
41axis = np.array([0,0,1])
42omega = 0.5*pi*2
43gravity = [0,-g,0]
44f = 0.002
45hShoulder = 0.004
46gearWidth = 0.024
47nTeeth0 = 16
48nTeeth1 = 16*3
49nTeeth2 = 10
50module = 0.005
51baseCircleDiameter0 = module*nTeeth0
52baseCircleDiameter1 = module*nTeeth1
53baseCircleDiameter2 = module*nTeeth2
54helixAngleDeg = 20
55shaftGraphics = graphics.SolidOfRevolution([0,0,0], axis,
56 contour=[[-0.5*shaftLength,0],[-0.5*shaftLength,shaftRadius-f],
57 [-0.5*shaftLength+f,shaftRadius],
58 [-0.2*shaftLength,shaftRadius],[-0.2*shaftLength,shaftRadius+hShoulder],
59 [0.2*shaftLength,shaftRadius+hShoulder],[0.2*shaftLength,shaftRadius],
60 [0.5*shaftLength-f,shaftRadius],
61 [0.5*shaftLength,shaftRadius-f],[0.5*shaftLength,0],],
62 nTiles=64, color=graphics.color.steelblue)
63
64gear0CenterPoint=[0,0,0.2*shaftLength+0.5*gearWidth]
65gear1CenterPoint=[0,0,-0.2*shaftLength-0.5*gearWidth]
66involuteGear0 = InvoluteGear(module=module, nTeeth=nTeeth0)
67graphicsGear0 = graphics.InvoluteGear(involuteGear0, width=gearWidth,
68 centerPoint=gear0CenterPoint,
69 radius=shaftRadius,
70 color=graphics.color.red, smoothNormals=True)
71
72involuteGear1 = InvoluteGear(module=module, nTeeth=nTeeth1)
73graphicsGear1 = graphics.InvoluteGear(involuteGear1, width=gearWidth*2, helixAngleDeg=helixAngleDeg,
74 centerPoint=gear1CenterPoint,
75 radius=shaftRadius,
76 color=graphics.color.lawngreen, smoothNormals=True)
77
78bodyShaft = mbs.CreateRigidBody(referencePosition=[0,offY,0],
79 nodeType=exu.NodeType.RotationRxyz,
80 inertia=InertiaCylinder(density, shaftLength, shaftRadius, axis=2),
81 initialAngularVelocity=[0,0,0],
82 gravity = gravity,
83 graphicsDataList=[shaftGraphics,
84 graphics.Basis(length=shaftRadius*1.4),
85 graphicsGear0,
86 graphicsGear1
87 ]
88 )
89mbs.CreateRevoluteJoint(bodyNumbers=[oGround,bodyShaft], position=[0,offY,0],axis=axis,show=False)
90sAngVel0 = mbs.AddSensor(SensorBody(bodyNumber=bodyShaft, storeInternal=True,
91 outputVariableType=exu.OutputVariableType.AngularVelocity))
92
93
94involuteGear2 = InvoluteGear(module=module, nTeeth=nTeeth2)
95graphicsGear2 = graphics.InvoluteGear(involuteGear2, width=gearWidth*2, helixAngleDeg=-helixAngleDeg,
96 centerPoint=[0,0,0],
97 radius=shaftRadius2,
98 color=graphics.color.dodgerblue, smoothNormals=True)
99
100posShaft2=[0,offY+0.503*(baseCircleDiameter1+baseCircleDiameter2),gear1CenterPoint[2]]
101bodyShaft2 = mbs.CreateRigidBody(referencePosition=posShaft2,
102 inertia=InertiaCylinder(density, shaftLength2, shaftRadius2, axis=2),
103 initialAngularVelocity=[0,0,0], #not initialized and will follow transmission
104 gravity = gravity,
105 graphicsDataList=[graphics.Cylinder(pAxis=[0,0,-0.5*shaftLength2],vAxis=[0,0,shaftLength2],radius=shaftRadius2,
106 color=graphics.color.steelblue,nTiles=32,
107 alternatingColor=graphics.color.grey),
108 graphics.Basis(length=shaftRadius*1.4),
109 graphicsGear2,
110 ]
111 )
112mbs.CreateRevoluteJoint(bodyNumbers=[oGround,bodyShaft2], position=posShaft2,axis=axis,show=False)
113sAngVel2 = mbs.AddSensor(SensorBody(bodyNumber=bodyShaft2, storeInternal=True,
114 outputVariableType=exu.OutputVariableType.AngularVelocity))
115
116#add coordinate constraint to keep velocity constant:
117# mbs.CreateCoordinateConstraint(bodyNumbers=[bodyShaft, None],
118# coordinates=[5,None],
119# velocityLevel=True, offset=omega, show=False)
120
121
122#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
123#toothed rack
124rackToothHeight=module*2.25
125rackBaseHeight = 0.008
126gRack = graphics.ToothedRack(module=module, nTeeth=20, width=gearWidth,
127 toothHeight=rackToothHeight*0.95,
128 rackBaseHeight = rackBaseHeight,
129 color=graphics.color.orange, addEdges=True)
130
131rackXoff = -module*pi
132positionRack = [rackXoff,offY-module*nTeeth0*0.5-rackBaseHeight-0.5*rackToothHeight,gear0CenterPoint[2]]
133bodyRack = mbs.CreateRigidBody(referencePosition=positionRack,
134 inertia=InertiaCuboid(density,sideLengths=[0.2,0.05,0.05]),
135 gravity = gravity,
136 graphicsDataList=[gRack]
137 )
138
139mbs.CreatePrismaticJoint(bodyNumbers=[oGround, bodyRack], position=positionRack,axis=[1,0,0],
140 show=False)
141sVelRack = mbs.AddSensor(SensorBody(bodyNumber=bodyRack, storeInternal=True,
142 outputVariableType=exu.OutputVariableType.Velocity))
143
144#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
145#add transmission constraints and connectors:
146nGround = mbs.AddNode(NodePointGround())
147mcGround = mbs.AddMarker(MarkerNodeCoordinate(nodeNumber=nGround, coordinate=0))
148
149nGenericShaft = mbs.AddNode(NodeGenericData(initialCoordinates=[0], numberOfDataCoordinates=1))
150mRotationShaft = mbs.AddMarker(MarkerBodiesRelativeRotationCoordinate(bodyNumbers=[oGround,bodyShaft],
151 nodeNumber=nGenericShaft,
152 axis0=axis))
153nGenericShaft2 = mbs.AddNode(NodeGenericData(initialCoordinates=[0], numberOfDataCoordinates=1))
154mRotationShaft2 = mbs.AddMarker(MarkerBodiesRelativeRotationCoordinate(bodyNumbers=[oGround,bodyShaft2],
155 nodeNumber=nGenericShaft2,
156 axis0=axis))
157mTranslationRack = mbs.AddMarker(MarkerBodiesRelativeTranslationCoordinate(bodyNumbers=[oGround,bodyRack],
158 offset=rackXoff,
159 axis0=[1,0,0]))
160
161#now add constraints and spring-dampers
162mbs.AddObject(CoordinateConstraint(markerNumbers=[mRotationShaft,mTranslationRack],
163 factorValue1=1/(baseCircleDiameter0*0.5),
164 visualization=VCoordinateConstraint(show=False)))
165
166mbs.AddObject(CoordinateSpringDamperExt(markerNumbers=[mRotationShaft,mRotationShaft2],
167 factor1=-baseCircleDiameter2/baseCircleDiameter1,
168 stiffness=1e3, damping=20))
169
170#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
171#finally we prescribe the position of toothed rack by spring-damper (similar to PD control)
172def UFspring(mbs, t, itemNumber, u, v, k, d, offset):
173 off = 0.5*(cos(t*2*pi)-1)*0.2
174 return k*(u-off)+d*v
175
176mbs.AddObject(CoordinateSpringDamper(markerNumbers=[mcGround,mTranslationRack],
177 stiffness=2e3, damping=50,
178 springForceUserFunction=UFspring))
179
180#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
181
182mbs.Assemble()
183
184stepSize = 1e-4
185tEnd = 2
186
187simulationSettings = exu.SimulationSettings()
188simulationSettings.solutionSettings.writeSolutionToFile = True
189simulationSettings.solutionSettings.solutionWritePeriod = 0.001
190simulationSettings.solutionSettings.sensorsWritePeriod = stepSize #output interval
191simulationSettings.timeIntegration.numberOfSteps = int(tEnd/stepSize)
192simulationSettings.timeIntegration.endTime = tEnd
193simulationSettings.displayStatistics = True
194simulationSettings.displayComputationTime = True
195# simulationSettings.timeIntegration.simulateInRealtime = True
196#simulationSettings.timeIntegration.realtimeFactor = 0.5
197simulationSettings.linearSolverType = exu.LinearSolverType.EigenSparse
198simulationSettings.timeIntegration.newton.useModifiedNewton = True
199
200simulationSettings.displayStatistics = True
201simulationSettings.timeIntegration.verboseMode = 1
202
203SC.visualizationSettings.window.renderWindowSize=[1600,1200]
204SC.visualizationSettings.general.graphicsUpdateInterval = 0.01
205
206SC.visualizationSettings.openGL.multiSampling=2
207SC.visualizationSettings.openGL.shadow = 0.25
208SC.visualizationSettings.openGL.light0position = [0.2,1,0.2,1]
209#SC.visualizationSettings.nodes.showBasis = True
210SC.visualizationSettings.loads.show = False
211SC.visualizationSettings.loads.drawSimplified=False
212SC.visualizationSettings.nodes.drawNodesAsPoint = False
213
214useGraphics=True
215if useGraphics:
216 SC.renderer.Start() #start graphics visualization
217 SC.renderer.DoIdleTasks() #wait for pressing SPACE bar to continue
218
219#start solver:q
220mbs.SolveDynamic(simulationSettings)
221
222if useGraphics:
223 SC.renderer.Stop() #safely close rendering window!
224
225mbs.PlotSensor(sensorNumbers=[sAngVel0,sAngVel2,sVelRack],components=[2,2,0])
226
227if True:
228 #%%
229 mbs.SolutionViewer()