mouseInteractionExample.py
You can view and download this file on Github: mouseInteractionExample.py
1#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2# This is an EXUDYN example
3#
4# Details: This is the first interactive mouse motion example;
5# use your mouse to drag the end of the chain;
6# models a chain of 3D rigid bodies connected with revolute joints;
7# may require RESTART of python kernel to work properly!
8#
9# Author: Johannes Gerstmayr
10# Date: 2020-12-06
11#
12# 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.
13#
14#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
15
16import exudyn as exu
17from exudyn.itemInterface import *
18from exudyn.utilities import * #includes itemInterface and rigidBodyUtilities
19import exudyn.graphics as graphics #only import if it does not conflict
20from exudyn.graphicsDataUtilities import *
21
22from math import sin, cos, pi
23
24SC = exu.SystemContainer()
25mbs = SC.AddSystem()
26
27activateWithKeyPress = True #activate mouse drag with keypress 'D'
28
29nBodies = 2
30color = [0.1,0.1,0.8,1]
31
32sx = 0.25
33sy = 0.1
34sz = 0.1
35
36nBodies = 16
37
38Ltot = nBodies*sx
39sc = 4 #size of coordinate system
40coordSys0 = graphics.Cylinder([0,0,0], [sz,0,0], 0.01, color=graphics.color.red)
41coordSys1 = graphics.Cylinder([0,0,0], [0,sz,0], 0.01, color=graphics.color.green)
42coordSys2 = graphics.Cylinder([0,0,0], [0,0,sz], 0.01, color=graphics.color.blue)
43oGround=mbs.AddObject(ObjectGround(referencePosition= [0,0,0],
44 visualization=VObjectGround(graphicsData= [coordSys0, coordSys1, coordSys2])))
45
46m=1 #mass
47density = 2000
48
49nodeList=[]
50objectList=[]
51
52nRB=-1
53com=[0,0,0]
54
55RBinertia = InertiaCuboid(density=density, sideLengths=[sx,sy,sz])
56
57mPosGround = mbs.AddMarker(MarkerBodyRigid(bodyNumber = oGround,
58 localPosition=[0,0,0]))
59mPosLast = mPosGround
60
61deltaAngleZ = 0.05*pi/nBodies
62p0 = np.array([0,0,0])
63
64#create a chain of bodies:
65for i in range(nBodies):
66
67 A = RotationMatrixZ(i*deltaAngleZ)
68 deltaRot2 = RotationMatrixZ(0.5*deltaAngleZ)
69 p0 = p0 + A@[0.5*sx,0,0]
70
71 omega0 = [0,0,0] #arbitrary initial angular velocity
72 v0 = [0.,0.,0.] #initial translational velocity
73
74 color=[1,0.1,0.1,1]
75
76 oGraphics = graphics.BrickXYZ(-sx*0.5,-sy*0.5,-sz*0.5, sx*0.5, sy*0.5, sz*0.5, color)
77
78 [nRB, oRB] = AddRigidBody(mainSys=mbs, inertia=RBinertia,
79 #nodeType=exu.NodeType.RotationRxyz,
80 nodeType=exu.NodeType.RotationEulerParameters,
81 position=p0, velocity=v0,
82 rotationParameters=RotationMatrix2EulerParameters(A),
83 angularVelocity=omega0,
84 gravity=[0.,0.,-9.81],
85 graphicsDataList=[oGraphics])
86
87 nodeList += [nRB]
88 objectList += [oRB]
89 mPos = mbs.AddMarker(MarkerBodyRigid(bodyNumber = oRB, localPosition = [-0.5*sx,0,0]))
90 lastDeltaRot2 = deltaRot2
91 if i == 0:
92 lastDeltaRot2 = RotationMatrixZ(0)
93
94 mbs.AddObject(GenericJoint(markerNumbers = [mPos, mPosLast],
95 constrainedAxes=[1,1,1, 1,0,1],
96 rotationMarker0=lastDeltaRot2.T,
97 rotationMarker1=lastDeltaRot2,
98 visualization=VGenericJoint(axesRadius = 0.5*sy, axesLength=1.1*sz)))
99
100 #marker for next chain body
101 mPosLast = mbs.AddMarker(MarkerBodyRigid(bodyNumber = oRB, localPosition = [0.5*sx,0,0]))
102
103 #add damping to bodies:
104 mbs.AddObject(ObjectConnectorCartesianSpringDamper(markerNumbers = [mPosGround, mPosLast],
105 damping = [40]*3,
106 visualization=VCartesianSpringDamper(show=False)))
107
108 p0 = p0 + A@[0.5*sx,0,0]
109 # mbs.AddSensor(SensorNode(nodeNumber=nRB, fileName="solution/sensorPos.txt",
110 # outputVariableType=exu.OutputVariableType.Coordinates))
111
112#activate by keypress 'D':
113mbs.variables['activateMouseDrag'] = True
114if activateWithKeyPress:
115 mbs.variables['activateMouseDrag'] = False
116
117def UFmouseDrag0(mbs, t, itemIndex, u, v, k, d, offset): #changed 2023-01-21:, mu, muPropZone):
118 if not mbs.variables['activateMouseDrag'] == True:
119 return 0
120 p = SC.GetCurrentMouseCoordinates(True)
121 p = SC.GetRenderState()['openGLcoordinates']
122 #print("u=",u)
123 return k*(Ltot-0.5*sx+u-p[0]) + d*v
124
125def UFmouseDrag1(mbs, t, itemIndex, u, v, k, d, offset): #changed 2023-01-21:, mu, muPropZone):
126 if not mbs.variables['activateMouseDrag'] == True:
127 return 0
128 p = SC.GetCurrentMouseCoordinates(True)
129 return k*(u-p[1]) + d*v
130
131def UFmouseDrag2(mbs, t, itemIndex, u, v, k, d, offset): #changed 2023-01-21:, mu, muPropZone):
132 if not mbs.variables['activateMouseDrag'] == True:
133 return 0
134 p = SC.GetCurrentMouseCoordinates(True)
135 return k*(u-p[1]) + d*v
136
137if True:
138 nGround = mbs.AddNode(NodePointGround())
139 mGroundCoordinate = mbs.AddMarker(MarkerNodeCoordinate(nodeNumber=nGround, coordinate = 0))
140 k=5.*1e4
141 mCoord0 = mbs.AddMarker(MarkerNodeCoordinate(nodeNumber=nodeList[-1], coordinate = 0))
142 mCoord1 = mbs.AddMarker(MarkerNodeCoordinate(nodeNumber=nodeList[-1], coordinate = 1))
143 mCoord2 = mbs.AddMarker(MarkerNodeCoordinate(nodeNumber=nodeList[-1], coordinate = 2))
144
145 mbs.AddObject(CoordinateSpringDamper(markerNumbers=[mGroundCoordinate, mCoord0],
146 stiffness=k, damping=0.01*k,
147 springForceUserFunction=UFmouseDrag0,
148 visualization=VCoordinateSpringDamper(show=False),
149 ))
150 mbs.AddObject(CoordinateSpringDamper(markerNumbers=[mGroundCoordinate, mCoord2],
151 stiffness=k, damping=0.01*k,
152 springForceUserFunction=UFmouseDrag2,
153 visualization=VCoordinateSpringDamper(show=False),
154 ))
155
156mbs.Assemble()
157#exu.Print(mbs)
158
159simulationSettings = exu.SimulationSettings() #takes currently set values or default values
160
161tEnd = 10000
162h = 0.001
163simulationSettings.timeIntegration.numberOfSteps = int(tEnd/h)
164simulationSettings.timeIntegration.endTime = tEnd
165simulationSettings.solutionSettings.writeSolutionToFile = False
166simulationSettings.solutionSettings.solutionWritePeriod = simulationSettings.timeIntegration.endTime/1000
167simulationSettings.timeIntegration.verboseMode = 1
168
169#good for interactive examples, as it is independent of CPU power ...
170simulationSettings.timeIntegration.simulateInRealtime = True
171simulationSettings.linearSolverType = exu.LinearSolverType.EigenSparse
172
173simulationSettings.timeIntegration.newton.absoluteTolerance = 1e2 #if no force acts
174simulationSettings.timeIntegration.newton.useModifiedNewton = True
175simulationSettings.timeIntegration.generalizedAlpha.spectralRadius = 0.5 #0.6 works well
176
177simulationSettings.solutionSettings.solutionInformation = "mouse interaction example: press 'D' to (de-)activate mouse drag"
178
179#+++++++++++++++++++++++++++++++++++
180#these options are not necessary:
181SC.visualizationSettings.nodes.defaultSize = 0.025
182SC.visualizationSettings.nodes.drawNodesAsPoint = False
183SC.visualizationSettings.nodes.showBasis = False
184
185SC.visualizationSettings.openGL.light0position = [0.2,0.2,10,0]
186
187SC.visualizationSettings.openGL.light1position = [1,1,-10,0]
188SC.visualizationSettings.openGL.light1ambient= 0. #0.25
189SC.visualizationSettings.openGL.light1diffuse= 0.5 #0.4
190SC.visualizationSettings.openGL.light1specular= 0.6 #0.4
191SC.visualizationSettings.openGL.enableLight1 = True
192
193SC.visualizationSettings.openGL.lightModelTwoSide= True
194
195SC.visualizationSettings.general.drawWorldBasis= True
196
197SC.visualizationSettings.openGL.multiSampling = 4
198SC.visualizationSettings.openGL.lineWidth = 2
199
200SC.visualizationSettings.general.useMultiThreadedRendering = True
201
202useGraphics = True
203if useGraphics:
204 exu.StartRenderer()
205 if 'renderState' in exu.sys:
206 SC.SetRenderState(exu.sys['renderState'])
207 else:
208 renderState = {'centerPoint': [-0.33064934611320496,
209 -0.5762133598327637,
210 0.41875001788139343],
211 'maxSceneSize': 1.75,
212 'zoom': 4.042552471160889,
213 'currentWindowSize': [1024, 768],
214 'modelRotation': [[1.0, 0.0, 0.0],
215 [0.0, -4.371138828673793e-08, -1.0],
216 [0.0, 1.0, -4.371138828673793e-08]],
217 'mouseCoordinates': [713.0, 379.0],
218 'openGLcoordinates': [1.7853742130100727, -0.5235759578645229]}
219 SC.SetRenderState(renderState)
220 SC.SetRenderState(renderState)
221 mbs.WaitForUserToContinue()
222
223#+++++++++++++++++++++++++++++++++++
224#react on key press, in development state:
225#causes crash at termination of python code ...
226def UFkeyPress(key, action, mods):
227 if chr(key) == 'D' and action == 1: #use capital letters for comparison!!! action 1 == press
228 mbs.variables['activateMouseDrag'] = not mbs.variables['activateMouseDrag']
229
230if activateWithKeyPress:
231 SC.visualizationSettings.window.keyPressUserFunction = UFkeyPress
232
233
234mbs.SolveDynamic(simulationSettings)
235SC.visualizationSettings.window.ResetKeyPressUserFunction()
236
237if useGraphics:
238 exu.StopRenderer() #safely close rendering window!