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 *
 18import numpy as np
 19from exudyn.utilities import * #includes itemInterface and rigidBodyUtilities
 20import exudyn.graphics as graphics
 21
 22from math import sin, cos, pi
 23
 24SC = exu.SystemContainer()
 25mbs = SC.AddSystem()
 26
 27activateWithKeyPress = True #activate mouse drag with keypress 'D'
 28
 29color = [0.1,0.1,0.8,1]
 30
 31sx = 0.25
 32sy = 0.1
 33sz = 0.1
 34
 35nBodies = 16
 36
 37Ltot = nBodies*sx
 38sc = 4 #size of coordinate system
 39coordSys0 = graphics.Cylinder([0,0,0], [sz,0,0], 0.01, color=graphics.color.red)
 40coordSys1 = graphics.Cylinder([0,0,0], [0,sz,0], 0.01, color=graphics.color.green)
 41coordSys2 = graphics.Cylinder([0,0,0], [0,0,sz], 0.01, color=graphics.color.blue)
 42oGround=mbs.AddObject(ObjectGround(referencePosition= [0,0,0], 
 43                                   visualization=VObjectGround(graphicsData= [coordSys0, coordSys1, coordSys2])))
 44
 45m=1 #mass
 46density = 2000
 47
 48nodeList=[]
 49objectList=[]
 50
 51nRB=-1
 52com=[0,0,0]
 53 
 54RBinertia = InertiaCuboid(density=density, sideLengths=[sx,sy,sz])
 55
 56mPosGround = mbs.AddMarker(MarkerBodyRigid(bodyNumber = oGround, 
 57                                            localPosition=[0,0,0]))
 58mPosLast  = mPosGround
 59
 60deltaAngleZ = 0.05*pi/nBodies
 61p0 = np.array([0,0,0])
 62
 63#create a chain of bodies:
 64for i in range(nBodies):
 65    
 66    A = RotationMatrixZ(i*deltaAngleZ)
 67    deltaRot2 = RotationMatrixZ(0.5*deltaAngleZ)
 68    p0 = p0 + A@[0.5*sx,0,0]
 69
 70    omega0 = [0,0,0] #arbitrary initial angular velocity
 71    v0 = [0.,0.,0.] #initial translational velocity
 72
 73    color=[1,0.1,0.1,1]
 74
 75    oGraphics = graphics.Brick(centerPoint=[0, 0, 0], size=[sx, sy, sz], color=color)
 76 
 77    dictRB = mbs.CreateRigidBody(
 78                  inertia=RBinertia, 
 79                  referencePosition=p0, 
 80                  referenceRotationMatrix=A,
 81                  initialVelocity=v0,
 82                  initialAngularVelocity=omega0,
 83                  gravity=[0., 0., -9.81],
 84                  graphicsDataList=[oGraphics],
 85                  returnDict=True)
 86    [nRB, oRB] = [dictRB['nodeNumber'], dictRB['bodyNumber']]
 87
 88    nodeList += [nRB]
 89    objectList += [oRB]
 90    lastDeltaRot2 = deltaRot2
 91    if i == 0:
 92         lastDeltaRot2 = RotationMatrixZ(0)
 93    #the joint frame is the markers': turned back on this body, as the end marker of the last body is turned forward
 94    mPos = mbs.AddMarker(MarkerBodyRigid(bodyNumber = oRB, localHT=exu.HT(rotation=lastDeltaRot2.T, translation=[-0.5*sx,0,0])))
 95        
 96    mbs.AddObject(GenericJoint(markerNumbers = [mPos, mPosLast], 
 97                               constrainedAxes=[1,1,1, 1,0,1],
 98                               visualization=VGenericJoint(axesRadius = 0.5*sy, axesLength=1.1*sz)))
 99
100    #marker for next chain body, turned for the joint to it
101    mPosLast = mbs.AddMarker(MarkerBodyRigid(bodyNumber = oRB, localHT=exu.HT(rotation=deltaRot2, translation=[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
110#activate by keypress 'D':
111mbs.variables['activateMouseDrag'] = True
112if activateWithKeyPress:
113    mbs.variables['activateMouseDrag'] = False
114    
115def UFmouseDrag0(mbs, t, itemIndex, u, v, k, d, offset): #changed 2023-01-21:, mu, muPropZone):
116    if not mbs.variables['activateMouseDrag'] == True:
117        return 0
118    p = SC.renderer.GetMouseCoordinates(True)
119    p = SC.renderer.GetState()['openGLcoordinates']
120    #print("u=",u)
121    return k*(Ltot-0.5*sx+u-p[0]) + d*v
122
123def UFmouseDrag1(mbs, t, itemIndex, u, v, k, d, offset): #changed 2023-01-21:, mu, muPropZone):
124    if not mbs.variables['activateMouseDrag'] == True:
125        return 0
126    p = SC.renderer.GetMouseCoordinates(True)
127    return k*(u-p[1]) + d*v
128
129def UFmouseDrag2(mbs, t, itemIndex, u, v, k, d, offset): #changed 2023-01-21:, mu, muPropZone):
130    if not mbs.variables['activateMouseDrag'] == True:
131        return 0
132    p = SC.renderer.GetMouseCoordinates(True)
133    return k*(u-p[1]) + d*v
134
135if True:
136    nGround = mbs.AddNode(NodePointGround())
137    mGroundCoordinate = mbs.AddMarker(MarkerNodeCoordinate(nodeNumber=nGround, coordinate = 0))
138    k=5.*1e4
139    mCoord0 = mbs.AddMarker(MarkerNodeCoordinate(nodeNumber=nodeList[-1], coordinate = 0))
140    mCoord1 = mbs.AddMarker(MarkerNodeCoordinate(nodeNumber=nodeList[-1], coordinate = 1))
141    mCoord2 = mbs.AddMarker(MarkerNodeCoordinate(nodeNumber=nodeList[-1], coordinate = 2))
142    
143    mbs.AddObject(CoordinateSpringDamper(markerNumbers=[mGroundCoordinate, mCoord0], 
144                                         stiffness=k, damping=0.01*k, 
145                                         springForceUserFunction=UFmouseDrag0,
146                                         visualization=VCoordinateSpringDamper(show=False),
147                                        ))
148    mbs.AddObject(CoordinateSpringDamper(markerNumbers=[mGroundCoordinate, mCoord2], 
149                                         stiffness=k, damping=0.01*k, 
150                                         springForceUserFunction=UFmouseDrag2,
151                                         visualization=VCoordinateSpringDamper(show=False),
152                                        ))
153
154mbs.Assemble()
155#exu.Print(mbs)
156
157simulationSettings = exu.SimulationSettings() #takes currently set values or default values
158
159tEnd = 10000
160h = 0.001
161simulationSettings.timeIntegration.numberOfSteps = int(tEnd/h)
162simulationSettings.timeIntegration.endTime = tEnd
163simulationSettings.solution.file.write = False
164simulationSettings.solution.file.writePeriod = simulationSettings.timeIntegration.endTime/1000
165simulationSettings.timeIntegration.verboseMode = 1
166
167#good for interactive examples, as it is independent of CPU power ...
168simulationSettings.timeIntegration.realtime.active = True
169simulationSettings.linearSolver.solverType = exu.LinearSolverType.EigenSparse
170
171simulationSettings.timeIntegration.newton.absoluteTolerance = 1e2 #if no force acts
172simulationSettings.timeIntegration.newton.useModifiedNewton = True
173simulationSettings.timeIntegration.generalizedAlpha.spectralRadius = 0.5 #0.6 works well 
174
175simulationSettings.solution.file.information = "mouse interaction example: press 'D' to (de-)activate mouse drag, F2 to switch key functionality"
176
177#+++++++++++++++++++++++++++++++++++
178#these options are not necessary:
179SC.visualizationSettings.nodes.defaultSize = 0.025
180SC.visualizationSettings.nodes.drawNodesAsPoint = False
181SC.visualizationSettings.nodes.showBasis = False
182
183SC.visualizationSettings.openGL.light0.position = [0.2,0.2,10,0]
184
185SC.visualizationSettings.openGL.light1.position = [1,1,-10,0]
186SC.visualizationSettings.openGL.light1.diffuse= 0.5 #0.4
187SC.visualizationSettings.openGL.light1.specular= 0.6 #0.4
188SC.visualizationSettings.openGL.light1.enable = True
189
190SC.visualizationSettings.openGL.advanced.lightModelTwoSide= True
191
192SC.visualizationSettings.view0.scene.drawWorldBasis= True
193SC.visualizationSettings.general.graphicsUpdateInterval = 0.01
194
195SC.visualizationSettings.openGL.multiSampling = 4
196SC.visualizationSettings.openGL.lineWidth = 2
197SC.visualizationSettings.interactive.ignoreKeys = True #otherwise keyPressUserFunction not called!
198SC.visualizationSettings.general.useMultiThreadedRendering = True
199
200useGraphics = True
201if useGraphics:
202    SC.renderer.Start()
203    if not SC.renderer.RestoreSavedState(): #no view saved yet: start from this one
204        renderState = {'centerPoint': [-0.33064934611320496,
205                         -0.5762133598327637,
206                         0.41875001788139343],
207                        'maxSceneSize': 1.75,
208                        'zoom': 4.042552471160889,
209                        'currentWindowSize': [1024, 768],
210                        'modelRotation': [[1.0, 0.0, 0.0],
211                         [0.0, -4.371138828673793e-08, -1.0],
212                         [0.0, 1.0, -4.371138828673793e-08]],
213                        'mouseCoordinates': [713.0, 379.0],
214                        'openGLcoordinates': [1.7853742130100727, -0.5235759578645229]}
215        SC.renderer.SetState(renderState)
216    SC.renderer.DoIdleTasks()
217
218#+++++++++++++++++++++++++++++++++++
219#react on key press, in development state:
220#causes crash at termination of python code ...
221def UFkeyPress(key, action, mods):
222    #print('key:',key)
223    if chr(key) == 'D' and action == 1: #use capital letters for comparison!!! action 1 == press
224        mbs.variables['activateMouseDrag'] = not mbs.variables['activateMouseDrag']
225    
226if activateWithKeyPress:
227    SC.visualizationSettings.interactive.keyPressUserFunction = UFkeyPress
228
229
230mbs.SolveDynamic(simulationSettings)
231SC.visualizationSettings.interactive.keyPressUserFunction = 0
232
233if useGraphics:
234    SC.renderer.Stop() #safely close rendering window!