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()