pickleCopyMbs.py
You can view and download this file on Github: pickleCopyMbs.py
1#%%+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2# This is an EXUDYN example
3#
4# Details: Two rigid bodies, where the first body moves on a straight rail (fixed on ground) and the second is mounted with a revolute joint on the first body;
5# the particular reason for this test example is the copying of the model as well as load save;
6# shows reading and writing mbs with dictionaries and export by HDF5 files
7#
8# Author: Johannes Gerstmayr
9# Date: 2024-10-13
10#
11# 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.
12#
13#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
14
15import exudyn as exu
16from exudyn.utilities import * #includes itemInterface and rigidBodyUtilities
17import numpy as np
18import exudyn.graphics as graphics
19from math import sin, cos
20import copy
21
22testIsActive = exu.sys.get('testIsActive', False)
23
24
25SC = exu.SystemContainer()
26mbs = SC.AddSystem()
27
28
29#%%+++++++++++++++++++++++++++++++++++
30L = 0.5
31w = 0.05
32ground = mbs.CreateGround(graphicsDataList=[graphics.CheckerBoard(point=[0,0,-0.1*L], size=10)])
33
34b0size = [0.5*L,L,0.2*L]
35p0 = np.array([0.5,1,0])
36b0 = mbs.CreateRigidBody(referencePosition=p0,
37 initialVelocity=[0,1,0],
38 inertia=InertiaCuboid(500, b0size),
39 graphicsDataList=[graphics.Brick(size=b0size,
40 color=graphics.color.dodgerblue)])
41b1size=[w,L,w]
42p1 = p0 + [0,0.5*L,0.5*b0size[2]+w]
43b1 = mbs.CreateRigidBody(referencePosition=p1,
44 initialVelocity=[0,1,0],
45 initialAngularVelocity=[0,0,4*pi],
46 inertia=InertiaCuboid(1000, b1size),
47 graphicsDataList=[graphics.Brick(size=b1size,
48 color=graphics.color.red)])
49
50mbs.CreateRevoluteJoint(itemNumbers=[b0,b1],
51 position=p1-[0,0.5*L,0.5*w],
52 axis = [0,0,1],
53 axisRadius=0.5*w, axisLength=2.2*w)
54
55mbs.CreatePrismaticJoint(itemNumbers=[ground,b0],
56 position=p0,
57 axis = [0,1,0],
58 axisRadius=0.5*w, axisLength=5*L)
59
60# UFtorque = 0
61def UFtorque(mbs, t, loadVector):
62 f = np.heaviside(t - 1,1)
63 return [0,0,-f*2*cos(pi*2*t)]
64
65load = mbs.CreateTorque(itemNumber=b1, loadVector=[0,0,0],
66 loadVectorUserFunction=UFtorque)
67
68sPos = mbs.AddSensor(SensorBody(bodyNumber=b0, storeInternal=True,
69 outputVariableType=exu.OutputVariableType.Position))
70
71
72#del mbs
73
74#%%+++++++++++++++++++++++++++++++++++
75#use dictionaries and pickle to load/save MBS
76import pickle
77
78mbsDict = mbs.GetDictionary()
79
80#save MUST be done before solving, as solver structures and settings cannot be saved!
81#erase variables and system variables as they may contain some solver stuff (if solved once)
82# that should not / can not be pickled
83mbsDict['variables'] = {}
84mbsDict['systemVariables'] = {}
85
86#save mbs data (could also use dill); the files are output of the test, so they go into
87#exudyn.config.outputDirectory, which the test suite sets per model (#2418)
88import os
89from exudyn.basicUtilities import OutputFilePath
90pickleFileName = OutputFilePath('solution/mbs.pkl', 'pickleCopyMbs')
91hdf5FileName = OutputFilePath('solution/mbs.h5', 'pickleCopyMbs')
92os.makedirs(os.path.dirname(pickleFileName), exist_ok=True)
93
94with open(pickleFileName, 'wb') as f:
95 pickle.dump(mbsDict, f) #, pickle.HIGHEST_PROTOCOL)
96
97#load mbs data
98with open(pickleFileName, 'rb') as f:
99 mbsCopy = pickle.load(f)
100
101SC = exu.SystemContainer()
102mbs2 = SC.AddSystem()
103mbs2.SetDictionary(mbsDict)
104
105#+++++++++++++++++++++++
106
107hasH5py = False
108try:
109 import h5py
110 hasH5py = True
111except ImportError:
112 exu.Print('h5py not available; skipping HDF5 test')
113
114if hasH5py:
115 from exudyn.advancedUtilities import SaveDictToHDF5, LoadDictFromHDF5
116 #use HDF5 load / save may not work for all cases, as some types are not implemented
117 #save MUST be done before solving, as solver structures and settings cannot be saved!
118 mbsDict = mbs.GetDictionary()
119 mbsDict['variables'] = {}
120 mbsDict['systemVariables'] = {}
121 SaveDictToHDF5(hdf5FileName, mbsDict) #problems with Python functions as sub-dicts
122 mbsCopy2 = LoadDictFromHDF5(hdf5FileName, globals())
123 # print('loaded_data:\n', mbsCopy2)
124
125 SC = exu.SystemContainer()
126 mbs2 = SC.AddSystem()
127 mbs2.SetDictionary(mbsCopy)
128
129#%%+++++++++++++++++++++++++++++++++++
130#ALTERNATIVE: work with copy of mbs:
131#we have to create a new Systemcontainer:
132#mbs2 = copy.copy(mbs) #alternative way to directly copy
133# SC = exu.SystemContainer()
134# SC.AppendSystem(mbs2)
135
136mbs2.Assemble()
137
138#check mbs2:
139#print(mbs2)
140
141simulationSettings = exu.SimulationSettings() #takes currently set values or default values
142
143tEnd = 1
144h = 1e-3
145simulationSettings.timeIntegration.numberOfSteps = int(tEnd/h)
146simulationSettings.timeIntegration.endTime = tEnd
147simulationSettings.timeIntegration.verboseMode = 1
148# simulationSettings.timeIntegration.realtime.active = True
149
150simulationSettings.timeIntegration.newton.useModifiedNewton = True
151simulationSettings.timeIntegration.generalizedAlpha.spectralRadius = 0.6 #0.6 works well
152# simulationSettings.show.computationTime = True
153
154simulationSettings.solution.file.information = "rigid body tests"
155SC.visualizationSettings.nodes.defaultSize = 0.05
156SC.visualizationSettings.openGL.multiSampling = 4
157SC.visualizationSettings.openGL.lineWidth = 2
158SC.visualizationSettings.view0.window.renderWindowSize = [2000,1600]
159
160if not testIsActive:
161 SC.renderer.Start()
162 SC.renderer.DoIdleTasks()
163
164mbs2.SolveDynamic(simulationSettings)
165
166if not testIsActive:
167 SC.renderer.DoIdleTasks()
168 SC.renderer.Stop() #safely close rendering window!
169
170
171#+++++++++++++++++++++++++++++++++++++++++++++
172uTotal = 0.1 * sum(mbs2.GetSensorValues(sPos)) #sPos is still the correct index
173exu.Print('uTotal=',uTotal)
174
175exu.sys['testResult'] = uTotal
176#+++++++++++++++++++++++++++++++++++++++++++++