contactCurveWithLongCurve.py

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

  1#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2# This is an EXUDYN example
  3#
  4# Details:  Test for ObjectContactCurveCircles, curves generated from reeving system functionality
  5#
  6# Author:   Johannes Gerstmayr
  7# Date:     2025-05-10
  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#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 12import exudyn as exu
 13from exudyn.utilities import *
 14import exudyn.graphics as graphics
 15import numpy as np
 16from exudyn.beams import CreateReevingCurve
 17
 18useGraphics = True #without test
 19
 20SC = exu.SystemContainer()
 21mbs = SC.AddSystem()
 22
 23#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 24#create curve using reeving system functionality
 25nNodes = 200*2
 26circleList = [
 27              [[0,0.4],0.4,'L'],
 28              [[0,2.4],0.4,'L'],
 29              [[1,2.4],0.25,'R'],
 30              [[2,2.4],0.4,'L'],
 31              [[3,2.4],0.4,'R'],
 32              [[4,2.4],0.4,'L'],
 33              #[[5,2.4],0.4,'R'],
 34              [[4,0.4],0.4,'L'],
 35              [[0,0.4],0.4,'L'],
 36              [[0,2.4],0.4,'L'],
 37              ]
 38
 39reevingDict = CreateReevingCurve(circleList, drawingLinesPerCircle = 64,
 40                                 removeLastLine=True, #allows closed curve
 41                                 numberOfANCFnodes=nNodes, graphicsNodeSize= 0.01)
 42
 43#here we only use points and slopes: reevingDict['ancfPointsSlopes']
 44
 45if False: #draw reeving system
 46    gList=[]
 47    if True: #visualize reeving curve, without simulation
 48        gList = reevingDict['graphicsDataLines'] + reevingDict['graphicsDataCircles']
 49
 50    oGround=mbs.AddObject(ObjectGround(referencePosition= [0,0,0],
 51                                       visualization=VObjectGround(graphicsData= gList)))
 52
 53
 54#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 55
 56
 57L = 2
 58# a = 0.1
 59b = 0.1
 60rBall = 0.05
 61mBall = 0.1
 62
 63oGround = mbs.CreateGround(graphicsDataList=[graphics.CheckerBoard(point=[L,0.5*L,-b], size=3*L)])
 64
 65contactStiffness = 2e5
 66contactDamping = 5e1
 67
 68nBalls = 5
 69listBalls = []
 70listMarkers = []
 71listSensors = []
 72lastBody = None
 73for i in range(nBalls):
 74    #ObjectContactCurveCircles currently requires rigid bodies!
 75    oBall = mbs.CreateRigidBody(referencePosition=[i*3*rBall,0,0],
 76                                inertia=InertiaSphere(mBall, rBall),
 77                                initialVelocity=[-5,0,0],
 78                                gravity=[0,-9.81*0.1,0],
 79                                drawSize=2*rBall,
 80                                color=graphics.color.dodgerblue)
 81
 82    markerBall = mbs.AddMarker(MarkerBodyRigid(bodyNumber=oBall))
 83    listBalls.append(oBall)
 84    listMarkers.append(markerBall)
 85
 86    listSensors.append(mbs.AddSensor(SensorBody(bodyNumber=oBall, storeInternal=True,
 87                                                outputVariableType=exu.OutputVariableType.Velocity)))
 88
 89    #approx. constant distance between bodies
 90    if lastBody is not None:
 91        mbs.CreateSpringDamper(bodyNumbers=[lastBody, oBall],stiffness=2000, damping=1)
 92
 93    lastBody = oBall
 94
 95#create 2D points for contact curve (linear segments)
 96pList0 = []
 97pList1 = []
 98width = 2.08*rBall #some additional width as we approximate with lines
 99
100for ps in reevingDict['ancfPointsSlopes']:
101    pMid = np.array(ps[0:2])
102    slope = Normalize(np.array(ps[2:4]))
103    normal = np.array([-slope[1],slope[0]])
104
105    p0 = pMid + 0.5*width*normal
106    p1 = pMid - 0.5*width*normal
107
108    pList0.append(p0)
109    pList1.append(p1)
110
111
112#transform points into contact segments:
113nPoints = len(pList0)
114segmentsData0 = np.zeros((nPoints,4))
115segmentsData0[:,0:2] = pList0
116segmentsData0[:,2:4] = np.roll(pList0,2) #roll is element wise on rows and columns, therefore 2>shift one row
117
118segmentsData1 = np.zeros((nPoints,4))
119segmentsData1[:,0:2] = pList1
120segmentsData1[:,2:4] = np.roll(pList1,2) #roll is element wise on rows and columns, therefore 2>shift one row
121
122segmentsData = np.vstack((segmentsData0,segmentsData1))
123#segmentsData = segmentsData0
124print('len(segmentsData)=',len(segmentsData))
125nSeg = len(segmentsData)
126
127mGround = mbs.AddMarker(MarkerBodyRigid(bodyNumber=oGround, localPosition=[0,0,0]))
128nGenericData = mbs.AddNode(NodeGenericData(initialCoordinates=[-1,0,0]*nSeg,
129                                           numberOfDataCoordinates=3*nSeg))
130
131mbs.AddObject(ObjectContactCurveCircles(markerNumbers=[mGround]+listMarkers,
132                                        nodeNumber=nGenericData,
133                                        circlesRadii=[rBall]*len(listBalls),
134                                        segmentsData=exu.MatrixContainer(segmentsData),
135                                        contactStiffness=contactStiffness, contactDamping=contactDamping,
136                                        visualization=VObjectContactCurveCircles(show=True, color=graphics.color.blue)
137                                        ))
138
139
140mbs.Assemble()
141
142stepSize=0.001
143tEnd = 20
144simulationSettings = exu.SimulationSettings()
145simulationSettings.solutionSettings.writeSolutionToFile = useGraphics
146simulationSettings.solutionSettings.solutionWritePeriod = 0.02
147simulationSettings.solutionSettings.sensorsWritePeriod = stepSize  #output interval
148simulationSettings.timeIntegration.numberOfSteps = int(tEnd/stepSize)
149simulationSettings.timeIntegration.endTime = tEnd
150# simulationSettings.timeIntegration.simulateInRealtime = True
151#simulationSettings.timeIntegration.realtimeFactor = 0.5
152# simulationSettings.timeIntegration.discontinuous.iterationTolerance = 1e-2
153# simulationSettings.timeIntegration.discontinuous.useRecommendedStepSize = False
154
155#simulationSettings.linearSolverType = exu.LinearSolverType.EigenSparse
156simulationSettings.timeIntegration.newton.useModifiedNewton = True
157#simulationSettings.timeIntegration.generalizedAlpha.spectralRadius = 1
158
159simulationSettings.timeIntegration.verboseMode = 1
160SC.visualizationSettings.connectors.contactPointsDefaultSize = 0
161
162SC.visualizationSettings.general.graphicsUpdateInterval = 0.02
163SC.visualizationSettings.general.drawWorldBasis = True
164SC.visualizationSettings.window.renderWindowSize=[1600,1200]
165SC.visualizationSettings.openGL.multiSampling=4
166#SC.visualizationSettings.openGL.facesTransparent=True
167SC.visualizationSettings.openGL.shadow=0.3*useGraphics
168SC.visualizationSettings.loads.show = False
169
170SC.renderer.Start()              #start graphics visualization
171SC.renderer.DoIdleTasks()    #wait for pressing SPACE bar to continue
172
173mbs.SolveDynamic(simulationSettings)
174
175SC.renderer.DoIdleTasks()#wait for pressing 'Q' to quit
176SC.renderer.Stop()               #safely close rendering window!
177
178mbs.PlotSensor(sensorNumbers=listSensors,
179               components=exu.plot.componentNorm)
180
181if useGraphics and True:
182    #%%
183    mbs.SolutionViewer()