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