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