hydraulicActuatorSimpleTest.py
You can view and download this file on Github: hydraulicActuatorSimpleTest.py
1#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2# This is an EXUDYN example
3#
4# Details: A one arm mechanism is actuated by the HydraulicActuatorSimple;
5# The actuator contains internal dynamics based on GenericODE1 node
6#
7# Author: Johannes Gerstmayr
8# Date: 2022-06-16
9#
10# 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.
11#
12#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
13
14import exudyn as exu
15from exudyn.utilities import * #includes itemInterface and rigidBodyUtilities
16import exudyn.graphics as graphics #only import if it does not conflict
17
18useGraphics = True #without test
19#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
20#you can erase the following lines and all exudynTestGlobals related operations if this is not intended to be used as TestModel:
21try: #only if called from test suite
22 from modelUnitTests import exudynTestGlobals #for globally storing test results
23 useGraphics = exudynTestGlobals.useGraphics
24except:
25 class ExudynTestGlobals:
26 pass
27 exudynTestGlobals = ExudynTestGlobals()
28#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
29
30import numpy as np
31from math import sin, cos, sqrt,pi
32
33SC = exu.SystemContainer()
34mbs = SC.AddSystem()
35
36L = 1 #x-dim of arm
37b = 0.1 #y-dim of arm
38
39
40#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
41#one arm mechanism
42background = graphics.CheckerBoard(point=[0,0.5*L*0,-2*b],size=2)
43oGround=mbs.AddObject(ObjectGround(referencePosition= [0,0,0], visualization=VObjectGround(graphicsData= [background])))
44massRigid = 12*10
45inertiaRigid = massRigid/12*(L)**2
46g = 9.81 # gravity
47
48graphicsList = [graphics.Brick(size= [L,b,0.1*b], color= graphics.color.dodgerblue, addEdges=True)]
49
50graphicsList += [graphics.Cylinder(pAxis=[-0.5*L,0,-0.7*b], vAxis= [0,0,1.4*b], radius = 0.55*b,
51 color= graphics.color.lightgrey, addEdges=True, nTiles=32)]
52#print(graphicsList[2])
53nRigid = mbs.AddNode(Rigid2D(referenceCoordinates=[0.5*L,0,0], initialVelocities=[0,0,0]));
54oRigid = mbs.AddObject(RigidBody2D(physicsMass=massRigid, physicsInertia=inertiaRigid,nodeNumber=nRigid,
55 visualization=VObjectRigidBody2D(graphicsData= graphicsList)))
56
57mR1 = mbs.AddMarker(MarkerBodyPosition(bodyNumber=oRigid, localPosition=[-0.5*L,0.,0.])) #support point
58mR2 = mbs.AddMarker(MarkerBodyPosition(bodyNumber=oRigid, localPosition=[ 0.,0.,0.])) #end point
59
60#add joint
61mG0 = mbs.AddMarker(MarkerBodyPosition(bodyNumber=oGround, localPosition=[0,0,0]))
62mbs.AddObject(RevoluteJoint2D(markerNumbers=[mG0,mR1]))
63
64mbs.AddLoad(Force(markerNumber = mR2, loadVector = [0, -massRigid*g, 0]))
65
66#%%+++++++++++++++++++++++++++++++++++++++++++++++++++++
67#add hydraulics actuator:
68mGH = mbs.AddMarker(MarkerBodyPosition(bodyNumber=oGround, localPosition=[0,-0.25*L-0.5*b*0,0.]))
69mRH = mbs.AddMarker(MarkerBodyPosition(bodyNumber=oRigid, localPosition=[-0.25*L,-0.5*b*0,0.]))
70
71
72LH0 = sqrt(2*(0.25*L)**2) #zero length of actuator
73
74#hydraulics parameters:
75V0 = 1. #oil volume (could actually change ...)
76V1 = V0 #oil volume (could actually change ...)
77A=[0.01,0.01] #piston area side 1/2
78Eoil = 1e11
79Av1 = 1 #valve opening (factor)
80Av2 = 0.0 #valve opening (factor)
81Qn = 2e-5 #nominal flow
82pS = 200.*1e5 #system pressure (200bar)
83pT = 0.*1e5 #tank pressure;
84dampingHA = 2e5
85
86
87#ODE1 for pressures:
88nODE1 = mbs.AddNode(NodeGenericODE1(referenceCoordinates=[0,0],
89 initialCoordinates=[2e6,2e6], #initialize with 20 bar
90 numberOfODE1Coordinates=2))
91
92oHA = mbs.AddObject(HydraulicActuatorSimple(markerNumbers=[mGH, mRH],
93 nodeNumbers=[nODE1],
94 offsetLength=LH0, strokeLength=LH0*0.5,
95 chamberCrossSection0=A[0], chamberCrossSection1=A[1],
96 hoseVolume0=V0, hoseVolume1=V1,
97 valveOpening0=0, valveOpening1=0,
98 oilBulkModulus=Eoil, actuatorDamping=dampingHA, nominalFlow=Qn,
99 systemPressure=pS, tankPressure=pT,
100 useChamberVolumeChange=False,
101 visualization=VHydraulicActuatorSimple(cylinderRadius= 0.6*b, rodRadius= 0.3*b,
102 baseMountLength = 0.4*b, baseMountRadius = 0.4*b,
103 rodMountRadius = 0.3*b, pistonLength = 0.2*b, pistonRadius = 0.55*b,
104 colorCylinder=graphics.color.blue, colorPiston=graphics.color.lightgrey),
105 ))
106
107
108def PreStepUserFunction(mbs, t):
109 LHact = mbs.GetObjectOutput(oHA, variableType=exu.OutputVariableType.Distance)
110 x = (max(0.5, min(1.5,(1-cos(t*pi*2*0.5))) ) - 0.5)*0.1+LH0
111 #if t>2: x=LH0
112
113 Av0 = (x-LHact)*2 #valve position control ==> penalize set value LH0
114 #print('Av0=',Av0)
115 Av1 = -Av0
116 mbs.SetObjectParameter(oHA, "valveOpening0", Av0)
117 mbs.SetObjectParameter(oHA, "valveOpening1", Av1)
118 return True
119
120mbs.SetPreStepUserFunction(PreStepUserFunction)
121
122
123sForce = mbs.AddSensor(SensorObject(objectNumber=oHA, storeInternal=True, outputVariableType=exu.OutputVariableType.Force))
124sDistance = mbs.AddSensor(SensorObject(objectNumber=oHA, storeInternal=True, outputVariableType=exu.OutputVariableType.Distance))
125sVelocity = mbs.AddSensor(SensorObject(objectNumber=oHA, storeInternal=True, outputVariableType=exu.OutputVariableType.Velocity))
126sPressures = mbs.AddSensor(SensorNode(nodeNumber=nODE1, storeInternal=True, outputVariableType=exu.OutputVariableType.Coordinates))
127
128mbs.Assemble()
129
130#%%+++++++++++++++++++++++++++++++++++++++++++++++++++++
131
132simulationSettings = exu.SimulationSettings() #takes currently set values or default values
133
134
135tEnd = 0.4
136stepSize = 1e-3
137simulationSettings.timeIntegration.numberOfSteps = int(tEnd/stepSize)
138simulationSettings.timeIntegration.endTime = tEnd
139simulationSettings.timeIntegration.startTime = 0
140simulationSettings.timeIntegration.newton.relativeTolerance = 1e-8*100 #10000
141simulationSettings.timeIntegration.newton.absoluteTolerance = 1e-10
142simulationSettings.timeIntegration.verboseMode = 1
143# simulationSettings.timeIntegration.simulateInRealtime = True #to see what happens ...
144
145simulationSettings.timeIntegration.newton.useModifiedNewton = True
146simulationSettings.timeIntegration.newton.numericalDifferentiation.minimumCoordinateSize = 1
147simulationSettings.timeIntegration.generalizedAlpha.spectralRadius = 0.5
148simulationSettings.displayStatistics = True
149
150simulationSettings.solutionSettings.solutionInformation = 'Hydraulics user function test'
151
152SC.visualizationSettings.openGL.multiSampling = 4
153SC.visualizationSettings.openGL.lineWidth = 2
154
155if useGraphics:
156 exu.StartRenderer()
157 mbs.WaitForUserToContinue()
158
159mbs.SolveDynamic(simulationSettings, showHints=False)
160
161if useGraphics:
162 SC.WaitForRenderEngineStopFlag()
163 exu.StopRenderer() #safely close rendering window!
164
165exu.Print('hydraulics C++:')
166exu.Print('pressures=', mbs.GetSensorValues(sPressures))
167exu.Print('velocity=', mbs.GetSensorValues(sVelocity))
168#for stepSize=1e-6: error about 1e-5 compared to user function implementation; with initialVelocities=[0,0,2] and tEnd=0.4
169# hydraulics C++:
170# pressures= [6441296.09086297 3008420.04232005]
171# velocity= [-0.0050061 0.20338669 0. ]
172
173#
174# mbs.PlotSensor(sensorNumbers=sForce, components=exudyn.plot.componentNorm, labels=['connector force norm'], yLabel='force (N)', closeAll=True)
175# mbs.PlotSensor(sensorNumbers=sDistance, components=0)
176# mbs.PlotSensor(sensorNumbers=[sPressures]*2, components=[0,1], labels=['p1', 'p2'], yLabel='pressure (N/m^2)')
177
178#mbs.PlotSensor(sensorNumbers=p01, components=0, labels=['differential hydraulic force'], yLabel='hydraulic force (N)')
179
180#compute error for test suite:
181sol2 = mbs.systemData.GetODE2Coordinates();
182sol1 = mbs.systemData.GetODE1Coordinates();
183u = np.linalg.norm(sol2);
184u += np.linalg.norm(sol1)*1e-6;
185exu.Print('solution of hydraulicActuatorSimpleTest =',u)
186
187exudynTestGlobals.testResult = u