camFollowerExample.py

You can view and download this file on Github: camFollowerExample.py

  1#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2# This is an EXUDYN example
  3#
  4# Details:  Test for ObjectContactCurveCircles as Cam-follower
  5#           We can either Cam with a curve (here; more smooth) and follower with circles, or Cam with circles and follower with the curve
  6#
  7# Author:   Johannes Gerstmayr
  8# Date:     2025-05-11
  9#
 10# 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.
 11#
 12#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 13import exudyn as exu
 14from exudyn.utilities import *
 15import exudyn.graphics as graphics
 16import numpy as np
 17from exudyn.beams import CreateReevingCurve
 18
 19useGraphics = True #without test
 20
 21SC = exu.SystemContainer()
 22mbs = SC.AddSystem()
 23
 24rDisc = 0.05
 25wDisc = 0.02
 26rContact = 0.005 #needed for representation of contact points
 27lFollower = 0.08
 28wFollower = 0.06
 29
 30oGround = mbs.CreateGround(graphicsDataList=[graphics.CheckerBoard(point=[0.5*lFollower,0,-wFollower], size=0.25)])
 31
 32contactStiffness = 2e6
 33contactDamping = 1e4
 34
 35#++++++++++++++++++++++++++++++++
 36#model Cam
 37rCam = 0.7*rDisc
 38deltaCam = 0.5*rDisc #center of rCam
 39#++++++++++++++++++++++++++++++++
 40#create 2D points for contact curve (linear segments)
 41
 42nMarkers = 2
 43
 44
 45omegaCam=2*pi*4
 46pCam = np.array([0,0,0])
 47oCam = mbs.CreateRigidBody(
 48                            referencePosition=pCam,
 49                            initialAngularVelocity=[0,0,omegaCam],
 50                            inertia=InertiaCylinder(2800, wDisc, rDisc, axis=2),
 51                            gravity = [0,-g,0],
 52                            graphicsDataList=[graphics.Cylinder(pAxis=[0,0,-0.5*wDisc], vAxis=[0,0,wDisc],radius=rDisc, nTiles=64, color=graphics.color.orange),
 53                                              graphics.Cylinder(pAxis=[deltaCam,0,-0.5*wDisc], vAxis=[0,0,wDisc],radius=rCam, nTiles=64, color=graphics.color.orange),
 54                                              graphics.Basis(length=rDisc*1.5)],
 55                            create2D=True, #not possible here, as COM must be 0 with 2D
 56                            )
 57
 58mCam = mbs.AddMarker(MarkerBodyRigid(bodyNumber=oCam, localPosition=[0,0,0]))
 59mbs.CreateCoordinateConstraint(bodyNumbers=[None, oCam], coordinates=[None,0], show=False)
 60mbs.CreateCoordinateConstraint(bodyNumbers=[None, oCam], coordinates=[None,1], show=False)
 61oCCtorqueCam = mbs.CreateCoordinateConstraint(bodyNumbers=[None, oCam], coordinates=[None,2],
 62                               velocityLevel=True, offset=omegaCam, show=False)
 63sTorque = mbs.AddSensor(SensorObject(objectNumber=oCCtorqueCam, storeInternal=True,
 64                                     outputVariableType=exu.OutputVariableType.Force))
 65
 66pLocalList = [[0,0,0],[deltaCam,0,0]]
 67circlesRadii = [rDisc, rCam]
 68circleMarkers = []
 69for p in pLocalList:
 70    circleMarkers.append(mbs.AddMarker(MarkerBodyRigid(bodyNumber=oCam, localPosition=p)))
 71
 72#++++++++++++++++++++++++++++++++
 73#follower:
 74nPoints = 7
 75segmentsData = np.zeros((nPoints,4))
 76pList = []
 77pList.append([-0.5*lFollower+0.1*lFollower, 0.5*wFollower])
 78pList.append([-0.5*lFollower, 0.5*wFollower])
 79pList.append([-0.5*lFollower, 0.25*wFollower])
 80pList.append([-0.5*lFollower, 0.*wFollower])
 81pList.append([-0.5*lFollower,-0.25*wFollower])
 82pList.append([-0.5*lFollower,-0.5*wFollower])
 83pList.append([-0.5*lFollower+0.1*lFollower, -0.5*wFollower])
 84segmentsData[:,0:2] = pList
 85segmentsData[:,2:4] = np.roll(pList,2) #roll is element wise on rows and columns, therefore 2>shift one row
 86
 87
 88nMarkers = len(circleMarkers)
 89
 90vFollower = [deltaCam+rCam+0.5*lFollower+0.,0,0]
 91oFollower = mbs.CreateRigidBody(referencePosition=pCam+vFollower,
 92                            inertia=InertiaCuboid(1000, [lFollower,wFollower,wFollower]),
 93                            gravity = [0,-g,0],
 94                            graphicsDataList=[graphics.Brick(centerPoint=[-0.4*lFollower,0,0], size=[0.2*lFollower,wFollower,0.4*wFollower],
 95                                                             color=graphics.color.dodgerblue, addEdges=True),
 96                                              graphics.Cylinder(pAxis=[-0.3*lFollower,0,0], vAxis=[0.8*lFollower,0,0],
 97                                                                radius=0.15*wFollower, addEdges=True,
 98                                                                nTiles=32, color=graphics.color.dodgerblue),
 99                                              ],
100                            create2D=True, #not possible here, as COM must be 0 with 2D
101                            )
102mFollower = mbs.AddMarker(MarkerBodyRigid(bodyNumber=oFollower, localPosition=[0,0,0]))
103sPosFollower = mbs.AddSensor(SensorBody(bodyNumber=oFollower, storeInternal=True,
104                                        outputVariableType=exu.OutputVariableType.Position))
105
106mbs.CreateCoordinateConstraint(bodyNumbers=[None, oFollower], coordinates=[None,1], show=False)
107mbs.CreateCoordinateConstraint(bodyNumbers=[None, oFollower], coordinates=[None,2], show=False) #rotation
108
109lSpring = 0.02
110mbs.CreateSpringDamper(bodyNumbers=[oGround, oFollower],
111                       localPosition0=pCam+vFollower+[0.5*lFollower+lSpring,0,0],
112                       localPosition1=[0.5*lFollower,0,0],
113                       referenceLength=lSpring*2,
114                       stiffness=1000, damping=20, drawSize = 0.4*wFollower)
115
116
117
118#++++++++++++++++++++++++++++++++
119nGenericData = mbs.AddNode(NodeGenericData(initialCoordinates=[-1,0,0]*nPoints,
120                                           numberOfDataCoordinates=3*nPoints))
121
122mbs.AddObject(ObjectContactCurveCircles(markerNumbers=[mFollower]+circleMarkers,
123                                        nodeNumber=nGenericData,
124                                        circlesRadii=circlesRadii,
125                                        segmentsData=exu.MatrixContainer(segmentsData),
126                                        contactStiffness=contactStiffness, contactDamping=contactDamping,
127                                        visualization=VObjectContactCurveCircles(show=False, color=graphics.color.blue)
128                                        ))
129
130
131
132mbs.Assemble()
133
134stepSize=2e-4
135tEnd = 2
136simulationSettings = exu.SimulationSettings()
137simulationSettings.solutionSettings.writeSolutionToFile = useGraphics
138simulationSettings.solutionSettings.solutionWritePeriod = 0.005
139simulationSettings.solutionSettings.sensorsWritePeriod = stepSize  #output interval
140simulationSettings.timeIntegration.numberOfSteps = int(tEnd/stepSize)
141simulationSettings.timeIntegration.endTime = tEnd
142# simulationSettings.timeIntegration.simulateInRealtime = True
143#simulationSettings.timeIntegration.realtimeFactor = 0.5
144# simulationSettings.timeIntegration.discontinuous.iterationTolerance = 1e-2
145# simulationSettings.timeIntegration.discontinuous.useRecommendedStepSize = False
146
147#simulationSettings.linearSolverType = exu.LinearSolverType.EigenSparse
148simulationSettings.timeIntegration.newton.useModifiedNewton = True
149#simulationSettings.timeIntegration.generalizedAlpha.spectralRadius = 1
150
151simulationSettings.timeIntegration.verboseMode = 1
152SC.visualizationSettings.connectors.contactPointsDefaultSize = 0.0005
153SC.visualizationSettings.connectors.showContact = True
154
155SC.visualizationSettings.general.graphicsUpdateInterval = 0.02
156# SC.visualizationSettings.general.drawWorldBasis = True
157SC.visualizationSettings.window.renderWindowSize=[1600,1200]
158SC.visualizationSettings.openGL.multiSampling=4
159#SC.visualizationSettings.openGL.facesTransparent=True
160SC.visualizationSettings.openGL.shadow=0.3
161SC.visualizationSettings.openGL.lineWidth=2
162SC.visualizationSettings.loads.show = False
163
164
165SC.renderer.Start()              #start graphics visualization
166SC.renderer.DoIdleTasks()    #wait for pressing SPACE bar to continue
167
168mbs.SolveDynamic(simulationSettings)
169
170SC.renderer.DoIdleTasks()#wait for pressing 'Q' to quit
171SC.renderer.Stop()               #safely close rendering window!
172
173mbs.PlotSensor(sensorNumbers=[sTorque], closeAll=True)
174mbs.PlotSensor(sensorNumbers=[sPosFollower])
175
176if useGraphics and True:
177    #%%
178    mbs.SolutionViewer()