Module: utilities
Basic support functions for simpler creation of Exudyn models. Advanced functions for loading and animating solutions and for drawing a graph of the mbs system. This library requires numpy (as well as time and copy)
Author: Johannes Gerstmayr
Date: 2019-07-26 (created)
Function: ShowOnlyObjects
ShowOnlyObjects(mbs
, objectNumbers = []
, showOthers = False
)
- function description:function to hide all objects in mbs except for those listed in objectNumbers
- input:
mbs
: mbs containing objectobjectNumbers
: integer object number or list of object numbers to be shown; if empty list [], then all objects are shownshowOthers
: if True, then all other objects are shown again - output:changes all colors in mbs, which is NOT reversible
Function: HighlightItem
HighlightItem(SC
, mbs
, itemNumber
, itemType = exudyn.ItemType.Object
, showNumbers = True
)
- function description:highlight a certain item with number itemNumber; set itemNumber to -1 to show again all objects
- input:
mbs
: mbs containing objectitemNumbers
: integer object/node/etc number to be highlighteditemType
: type of items to be highlightedshowNumbers
: if True, then the numbers of these items are shown
Function: __UFsensorDistance
__UFsensorDistance(mbs
, t
, sensorNumbers
, factors
, configuration
)
- function description:internal function used for CreateDistanceSensor
Function: CreateDistanceSensorGeometry
CreateDistanceSensorGeometry(mbs
, meshPoints
, meshTrigs
, rigidBodyMarkerIndex
, searchTreeCellSize = [8,8,8]
)
- NOTE: this function is directly available in MainSystem (mbs); it should be directly called as mbs.CreateDistanceSensorGeometry(…). For description of the interface, see the MainSystem Python extensions, Function: CreateDistanceSensorGeometry
Function: CreateDistanceSensor
CreateDistanceSensor(mbs
, generalContactIndex
, positionOrMarker
, dirSensor
, minDistance = -1e7
, maxDistance = 1e7
, cylinderRadius = 0
, selectedTypeIndex = exudyn.ContactTypeIndex.IndexEndOfEnumList
, storeInternal = False
, fileName = ''
, measureVelocity = False
, addGraphicsObject = False
, drawDisplaced = True
, color = exudyn.graphics.color.red
)
- NOTE: this function is directly available in MainSystem (mbs); it should be directly called as mbs.CreateDistanceSensor(…). For description of the interface, see the MainSystem Python extensions, Function: CreateDistanceSensor
Function: UFsensorRecord
UFsensorRecord(mbs
, t
, sensorNumbers
, factors
, configuration
)
- function description:DEPRECATED: Internal SensorUserFunction, used in function AddSensorRecorder
- notes:Warning: this method is DEPRECATED, use storeInternal in Sensors, which is much more performant; Note, that a sensor usually just passes through values of an existing sensor, while recording the values to a numpy array row-wise (time in first column, data in remaining columns)
Function: AddSensorRecorder
AddSensorRecorder(mbs
, sensorNumber
, endTime
, sensorsWritePeriod
, sensorOutputSize = 3
)
- function description:DEPRECATED: Add a SensorUserFunction object in order to record sensor output internally; this avoids creation of files for sensors, which can speedup and simplify evaluation in ParameterVariation and GeneticOptimization; values are stored internally in mbs.variables[‘sensorRecord’+str(sensorNumber)] where sensorNumber is the mbs sensor number
- input:
mbs
: mbs containing objectsensorNumber
: integer sensor number to be recordedendTime
: end time of simulation, as given in simulationSettings.timeIntegration.endTimesensorsWritePeriod
: as given in simulationSettings.solutionSettings.sensorsWritePeriodsensorOutputSize
: size of sensor data: 3 for Displacement, Position, etc. sensors; may be larger for RotationMatrix or Coordinates sensors; check this size by calling mbs.GetSensorValues(sensorNumber) - output:adds an according SensorUserFunction sensor to mbs; returns new sensor number; during initialization a new numpy array is allocated in mbs.variables[‘sensorRecord’+str(sensorNumber)] and the information is written row-wise: [time, sensorValue1, sensorValue2, …]
- notes:Warning: this method is DEPRECATED, use storeInternal in Sensors, which is much more performant; Note, that a sensor usually just passes through values of an existing sensor, while recording the values to a numpy array row-wise (time in first column, data in remaining columns)
Relevant Examples (Ex) and TestModels (TM) with weblink to github:
Function: LoadSolutionFile
LoadSolutionFile(fileName
, safeMode = False
, maxRows = -1
, verbose = True
, hasHeader = True
)
- function description:read coordinates solution file (exported during static or dynamic simulation with option exu.SimulationSettings().solutionSettings.coordinatesSolutionFileName=’…’) into dictionary:
- input:
fileName
: string containing directory and filename of stored coordinatesSolutionFilesaveMode
: if True, it loads lines directly to load inconsistent lines as well; use this for huge files (>2GB); is slower but needs less memory!verbose
: if True, some information is written when importing file (use for huge files to track progress)maxRows
: maximum number of data rows loaded, if saveMode=True; use this for huge files to reduce loading time; set -1 to load all rowshasHeader
: set to False, if file is expected to have no header; if False, then some error checks related to file header are not performed - output:dictionary with ‘data’: the matrix of stored solution vectors, ‘columnsExported’: a list with integer values showing the exported sizes [nODE2, nVel2, nAcc2, nODE1, nVel1, nAlgebraic, nData], ‘nColumns’: the number of data columns and ‘nRows’: the number of data rows
Relevant Examples (Ex) and TestModels (TM) with weblink to github:
beltDriveALE.py (Ex), beltDriveReevingSystem.py (Ex), beltDrivesComparison.py (Ex), fourBarMechanism3D.py (Ex), kinematicTreeAndMBS.py (Ex), ACFtest.py (TM), ANCFbeltDrive.py (TM), ANCFgeneralContactCircle.py (TM)
Function: NumpyInt8ArrayToString
NumpyInt8ArrayToString(npArray
)
- function description:simple conversion of int8 arrays into strings (not highly efficient, so use only for short strings)
Function: BinaryReadIndex
BinaryReadIndex(file
, intType
)
- function description:read single Index from current file position in binary solution file
Function: BinaryReadReal
BinaryReadReal(file
, realType
)
- function description:read single Real from current file position in binary solution file
Function: BinaryReadString
BinaryReadString(file
, intType
)
- function description:read string from current file position in binary solution file
Function: BinaryReadArrayIndex
BinaryReadArrayIndex(file
, intType
)
- function description:read Index array from current file position in binary solution file
Function: BinaryReadRealVector
BinaryReadRealVector(file
, intType
, realType
)
- function description:read Real vector from current file position in binary solution file
- output:return data as numpy array, or False if no data read
Function: LoadBinarySolutionFile
LoadBinarySolutionFile(fileName
, maxRows = -1
, verbose = True
)
- function description:read BINARY coordinates solution file (exported during static or dynamic simulation with option exu.SimulationSettings().solutionSettings.coordinatesSolutionFileName=’…’) into dictionary
- input:
fileName
: string containing directory and filename of stored coordinatesSolutionFileverbose
: if True, some information is written when importing file (use for huge files to track progress)maxRows
: maximum number of data rows loaded, if saveMode=True; use this for huge files to reduce loading time; set -1 to load all rows - output:dictionary with ‘data’: the matrix of stored solution vectors, ‘columnsExported’: a list with integer values showing the exported sizes [nODE2, nVel2, nAcc2, nODE1, nVel1, nAlgebraic, nData], ‘nColumns’: the number of data columns and ‘nRows’: the number of data rows
Function: RecoverSolutionFile
RecoverSolutionFile(fileName
, newFileName
, verbose = 0
)
- function description:recover solution file with last row not completely written (e.g., if crashed, interrupted or no flush file option set)
- input:
fileName
: string containing directory and filename of stored coordinatesSolutionFilenewFileName
: string containing directory and filename of new coordinatesSolutionFileverbose
: 0=no information, 1=basic information, 2=information per row - output:writes only consistent rows of file to file with name newFileName
Function: InitializeFromRestartFile
InitializeFromRestartFile(mbs
, simulationSettings
, restartFileName
, verbose = True
)
- function description:recover initial coordinates, time, etc. from given restart file
- input:
mbs
: MainSystem to be operated withsimulationSettings
: simulationSettings which is updated and shall be used afterwards for SolveDynamic(…) or SolveStatic(…)restartFileName
: string containing directory and filename of stored restart file, as given in solutionSettings.restartFileNameverbose
: False=no information, True=basic information - output:modifies simulationSettings and sets according initial conditions in mbs
Function: SetSolutionState
SetSolutionState(mbs
, solution
, row
, configuration = exudyn.ConfigurationType.Current
, sendRedrawSignal = True
)
- function description:load selected row of solution dictionary (previously loaded with LoadSolutionFile) into specific state; flag sendRedrawSignal is only used if configuration = exudyn.ConfigurationType.Visualization
Function: AnimateSolution
AnimateSolution(mbs
, solution
, rowIncrement = 1
, timeout = 0.04
, createImages = False
, runLoop = False
)
- function description:This function is not further maintaned and should only be used if you do not have tkinter (like on some MacOS versions); use exudyn.interactive.SolutionViewer() instead! AnimateSolution consecutively load the rows of a solution file and visualize the result
- input:
mbs
: the system used for animationsolution
: solution dictionary previously loaded with LoadSolutionFile; will be played from first to last rowrowIncrement
: can be set larger than 1 in order to skip solution frames: e.g. rowIncrement=10 visualizes every 10th row (frame)timeout
: in seconds is used between frames in order to limit the speed of animation; e.g. use timeout=0.04 to achieve approximately 25 frames per secondcreateImages
: creates consecutively images from the animation, which can be converted into an animationrunLoop
: if True, the animation is played in a loop until ‘q’ is pressed in render window - output:renders the scene in mbs and changes the visualization state in mbs continuously
Relevant Examples (Ex) and TestModels (TM) with weblink to github:
NGsolvePistonEngine.py (Ex), SliderCrank.py (Ex), slidercrankWithMassSpring.py (Ex), sliderCrankFloatingTest.py (TM)
Function: DrawSystemGraph
DrawSystemGraph(mbs
, showLoads = True
, showSensors = True
, useItemNames = False
, useItemTypes = False
, addItemTypeNames = True
, multiLine = True
, fontSizeFactor = 1.
, layoutDistanceFactor = 3.
, layoutIterations = 100
, showLegend = True
, tightLayout = True
)
- NOTE: this function is directly available in MainSystem (mbs); it should be directly called as mbs.DrawSystemGraph(…). For description of the interface, see the MainSystem Python extensions, Function: DrawSystemGraph
Function: CreateTCPIPconnection
CreateTCPIPconnection(sendSize
, receiveSize
, IPaddress = '127.0.0.1'
, port = 52421
, bigEndian = False
, verbose = False
)
- function description:function which has to be called before simulation to setup TCP/IP socket (server) forsending and receiving data; can be used to communicate with other Python interpretersor for communication with MATLAB/Simulink
- input:
sendSize
: number of double values to be sent to TCPIP clientreceiveSize
: number of double values to be received from TCPIP clientIPaddress
: string containing IP address of client (e.g., ‘127.0.0.1’)port
: port for communication with clientbigEndian
: if True, it uses bigEndian, otherwise littleEndian is used for byte order - output:returns information (TCPIPdata class) on socket; recommended to store this in mbs.sys[‘TCPIPobject’]
- example:
mbs.sys['TCPIPobject'] = CreateTCPIPconnection(sendSize=3, receiveSize=2,
bigEndian=True, verbose=True)
sampleTime = 0.01 #sample time in MATLAB! must be same!
mbs.variables['tLast'] = 0 #in case that exudyn makes finer steps than sample time
def PreStepUserFunction(mbs, t):
if t >= mbs.variables['tLast'] + sampleTime:
mbs.variables['tLast'] += sampleTime
tcp = mbs.sys['TCPIPobject']
y = TCPIPsendReceive(tcp, np.array([t, np.sin(t), np.cos(t)])) #time, torque
tau = y[1]
print('tau=',tau)
return True
try:
mbs.SetPreStepUserFunction(PreStepUserFunction)
#%%++++++++++++++++++++++++++++++++++++++++++++++++++
mbs.Assemble()
[...] #start renderer; simulate model
finally: #use this to always close connection, even in case of errors
CloseTCPIPconnection(mbs.sys['TCPIPobject'])
#*****************************************
#the following settings work between Python and MATLAB-Simulink (client), and gives stable results(with only delay of one step):
# TCP/IP Client Send:
# priority = 2 (in properties)
# blocking = false
# Transfer Delay on (but off also works)
# TCP/IP Client Receive:
# priority = 1 (in properties)
# blocking = true
# Sourec Data type = double
# data size = number of double in packer
# Byte order = BigEndian
# timeout = 10
Relevant Examples (Ex) and TestModels (TM) with weblink to github:
TCPIPexudynMatlab.py (Ex)
Function: TCPIPsendReceive
TCPIPsendReceive(TCPIPobject
, sendData
)
- function description:call this function at every simulation step at which you intend to communicate withother programs via TCPIP; e.g., call this function in preStepUserFunction of a mbs model
- input:
TCPIPobject
: the object returned by CreateTCPIPconnection(…)sendData
: numpy array containing data (double array) to be sent; must agree with sendSize - output:returns array as received from TCPIP
- example:
mbs.sys['TCPIPobject']=CreateTCPIPconnection(sendSize=2, receiveSize=1, IPaddress='127.0.0.1')
y = TCPIPsendReceive(mbs.sys['TCPIPobject'], np.array([1.,2.]))
print(y)
Relevant Examples (Ex) and TestModels (TM) with weblink to github:
TCPIPexudynMatlab.py (Ex)
Function: CloseTCPIPconnection
CloseTCPIPconnection(TCPIPobject
)
- function description:close a previously created TCPIP connection
Relevant Examples (Ex) and TestModels (TM) with weblink to github:
TCPIPexudynMatlab.py (Ex)
CLASS TCPIPdata (in module utilities)
class description:
helper class for CreateTCPIPconnection and for TCPIPsendReceive