rollingCoinTest.py

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

  1#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2# This is an EXUDYN example
  3#
  4# Details:  Rolling coin example; 
  5#           examine example of Rill, Schaeffer, Grundlagen und Methodik der Mehrkörpersimulation, 2010, page 59
  6#           Note that in comparison to the literature, we use the local x-axis for the local axis of the coin, z is the normal to the plane
  7#           mass and inertia do not influence the results, as long as mass and inertia of a infinitely small ring are used
  8#           gravity is set to [0,0,-9.81m/s^2] and the radius is 0.01m
  9#
 10# Author:   Johannes Gerstmayr
 11# Date:     2020-06-19
 12#
 13# 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.
 14#
 15#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 16
 17import exudyn as exu
 18from exudyn.utilities import * #includes itemInterface and rigidBodyUtilities
 19import exudyn.graphics as graphics
 20
 21import numpy as np
 22
 23testIsActive = exu.sys.get('testIsActive', False)
 24
 25SC = exu.SystemContainer()
 26mbs = SC.AddSystem()
 27
 28phi0 = 1./180.*np.pi#initial nick angle of disc, 1 degree
 29g = [0,0,-9.81]     #gravity in m/s^2
 30m = 1               #mass in kg
 31r = 0.01            #radius of disc in m
 32w = 0.001           #width of disc in m, just for drawing
 33p0 = [r*np.sin(phi0),0,r*np.cos(phi0)] #origin of disc center point at reference, such that initial contact point is at [0,0,0]
 34initialRotation = RotationMatrixY(phi0)
 35
 36omega0 = [0,0,1800/180*np.pi]                   #initial angular velocity around z-axis
 37v0 = Skew(omega0) @ initialRotation @ [0,0,r]   #initial angular velocity of center point
 38#v0 = [0,0,0]                                   #initial translational velocity
 39#print("v0=",v0)#," = ", [0,10*np.pi*r*np.sin(phi0),0])
 40
 41#inertia for infinitely small ring:
 42inertiaRing = RigidBodyInertia(mass=1, inertiaTensor= np.diag([0.5*m*r**2, 0.25*m*r**2, 0.25*m*r**2]))
 43#print(inertiaRing)
 44
 45#additional graphics for visualization of rotation:
 46graphicsBody = graphics.Brick(centerPoint=[0,0,0],size=[w*1.1,0.7*r,0.7*r], color=graphics.color.lightred)
 47
 48dict0 = mbs.CreateRigidBody(referencePosition=p0,  
 49                            referenceRotationMatrix=initialRotation,  
 50                            initialVelocity=v0,  
 51                            initialAngularVelocity=omega0,  
 52                            inertia=inertiaRing,  
 53                            gravity=g,  
 54                            graphicsDataList=[graphicsBody],  
 55                            returnDict=True)  
 56[n0, b0] = [dict0['nodeNumber'], dict0['bodyNumber']]
 57
 58#ground body and marker
 59gGround = graphics.Brick(centerPoint=[0,0,-0.001],size=[0.12,0.12,0.002], color=graphics.color.lightgrey)
 60oGround = mbs.AddObject(ObjectGround(visualization=VObjectGround(graphicsData=[gGround])))
 61markerGround = mbs.AddMarker(MarkerBodyRigid(bodyNumber=oGround, localPosition=[0,0,0]))
 62
 63#markers for rigid body:
 64markerBody0J0 = mbs.AddMarker(MarkerBodyRigid(bodyNumber=b0, localPosition=[0,0,0]))
 65
 66#rolling disc:
 67oRolling=mbs.AddObject(ObjectJointRollingDisc(markerNumbers=[markerGround, markerBody0J0], 
 68                                              constrainedAxes=[1,1,1], discRadius=r,
 69                                              visualization=VObjectJointRollingDisc(discWidth=w,color=graphics.color.blue)))
 70
 71sForce=mbs.AddSensor(SensorObject(objectNumber=oRolling, storeInternal=True,#fileName='solution/rollingDiscTrail.txt', 
 72                                  outputVariableType = exu.OutputVariableType.ForceLocal))
 73
 74
 75
 76#sensor for trace of contact point:
 77if not testIsActive:
 78    sTrail=mbs.AddSensor(SensorObject(objectNumber=oRolling, storeInternal=True,#fileName='solution/rollingDiscTrail.txt', 
 79                               outputVariableType = exu.OutputVariableType.Position))
 80    
 81    sVel=mbs.AddSensor(SensorObject(objectNumber=oRolling, storeInternal=True,#fileName='solution/rollingDiscTrailVel.txt', 
 82                               outputVariableType = exu.OutputVariableType.Velocity))
 83    
 84
 85
 86mbs.Assemble()
 87
 88simulationSettings = exu.SimulationSettings() #takes currently set values or default values
 89simulationSettings.timeIntegration.newton.useModifiedNewton = False #Just for the test; modified Newton is usually faster
 90
 91tEnd = 0.5
 92if not testIsActive:
 93    tEnd = 0.5
 94
 95h=0.0005 #no visual differences for step sizes smaller than 0.0005
 96
 97simulationSettings.timeIntegration.numberOfSteps = int(tEnd/h)
 98simulationSettings.timeIntegration.endTime = tEnd
 99#simulationSettings.solution.file.writePeriod = 0.01
100simulationSettings.solution.sensors.writePeriod = 0.0005
101simulationSettings.solution.file.write = False
102simulationSettings.timeIntegration.verboseMode = 1
103# simulationSettings.show.statistics = True
104
105simulationSettings.timeIntegration.generalizedAlpha.useIndex2Constraints = True
106simulationSettings.timeIntegration.generalizedAlpha.useNewmark = True
107simulationSettings.timeIntegration.generalizedAlpha.spectralRadius = 0.5
108simulationSettings.timeIntegration.generalizedAlpha.computeInitialAccelerations=True
109
110
111SC.visualizationSettings.nodes.show = True
112SC.visualizationSettings.nodes.drawNodesAsPoint  = False
113SC.visualizationSettings.nodes.showBasis = True
114SC.visualizationSettings.nodes.basisSize = 0.015
115
116if not testIsActive:
117    SC.renderer.Start()
118    SC.renderer.DoIdleTasks()
119
120mbs.SolveDynamic(simulationSettings)
121
122p0=mbs.GetObjectOutput(oRolling, exu.OutputVariableType.Position)
123force=mbs.GetSensorValues(sForce)
124exu.Print('force in rollingCoinTest=',force) #use x-coordinate
125
126u = p0[0] + 0.1*(force[0]+force[1]+force[2])
127exu.Print('solution of rollingCoinTest=',u) #use x-coordinate
128
129exu.sys['testResult'] = u
130
131
132if not testIsActive:
133    SC.renderer.DoIdleTasks()
134    SC.renderer.Stop() #safely close rendering window!
135
136    ##++++++++++++++++++++++++++++++++++++++++++++++q+++++++
137    #plot results
138    if True:
139        
140        
141        mbs.PlotSensor(sTrail, componentsX=[0],components=[1], closeAll=True, title='wheel trail')
142
143
144        # import matplotlib.pyplot as plt
145        # import matplotlib.ticker as ticker
146
147        # if True:
148        #     data = np.loadtxt('solution/rollingDiscTrail.txt', comments='#', delimiter=',') 
149        #     plt.plot(data[:,1], data[:,2], 'r-',label='contact point trail') #x/y coordinates of trail
150        # else:
151        #     #show trail velocity computed numerically and from sensor:
152        #     data = np.loadtxt('solution/rollingDiscTrail.txt', comments='#', delimiter=',') 
153    
154        #     nData = len(data)
155        #     vVec = np.zeros((nData,2))
156        #     dt = data[1,0]-data[0,0]
157        #     for i in range(nData-1):
158        #         vVec[i+1,0:2] = 1/dt*(data[i+1,1:3]-data[i,1:3])
159    
160        #     plt.plot(data[:,0], vVec[:,0], 'r-',label='contact point vel x') 
161        #     plt.plot(data[:,0], vVec[:,1], 'k-',label='contact point vel y') 
162        #     plt.plot(data[:,0], (vVec[:,0]**2+vVec[:,1]**2)**0.5, 'g-',label='|contact point vel|')
163    
164        #     trailVel = np.loadtxt('solution/rollingDiscTrailVel.txt', comments='#', delimiter=',') 
165        #     plt.plot(data[:,0], trailVel[:,1], 'r--',label='trail vel x')
166        #     plt.plot(data[:,0], trailVel[:,2], 'k--',label='trail vel y')
167        #     plt.plot(data[:,0], trailVel[:,3], 'y--',label='trail vel z')
168        #     plt.plot(data[:,0], (trailVel[:,1]**2+trailVel[:,2]**2)**0.5, 'b--',label='|trail vel|')
169
170        # ax=plt.gca() # get current axes
171        # ax.grid(True, 'major', 'both')
172        # ax.xaxis.set_major_locator(ticker.MaxNLocator(10)) #use maximum of 8 ticks on y-axis
173        # ax.yaxis.set_major_locator(ticker.MaxNLocator(10)) #use maximum of 8 ticks on y-axis
174        # plt.tight_layout()
175        # plt.legend()
176        # plt.show()