Module: advancedUtilities
Advanced utility functions only depending on numpy or specified exudyn modules; Here, we gather special functions, which are depending on other modules and do not fit into exudyn.utilities as they cannot be imported e.g. in rigidBodyUtilities
Author: Johannes Gerstmayr
Date: 2023-01-06 (created)
Function: PlotLineCode
function description: helper functions for matplotlib, returns a list of 28 line codes to be used in plot, e.g. ‘r-’ for red solid line
input: index in range(0:28)
output: a color and line style code for matplotlib plot
Relevant Examples (Ex) and TestModels (TM) with weblink to github: serialRobotInteractiveLimits.py (Ex), serialRobotTSD.py (Ex)
Function: FindObjectIndex
FindObjectIndex(i, globalVariables)
function description: simple function to find object index i within the local or global scope of variables
input: i, the integer object number and globalVariables=globals()
example:
FindObjectIndex(2, locals() ) #usually sufficient
FindObjectIndex(2, globals() ) #wider search
Function: FindNodeIndex
FindNodeIndex(i, globalVariables)
function description: simple function to find node index i within the local or global scope of variables
input: i, the integer node number and globalVariables=globals()
example:
FindObjectIndex(2, locals() ) #usually sufficient
FindObjectIndex(2, globals() ) #wider search
Function: IsListOrArray
IsListOrArray(data, checkIfNoneEmpty = False)
function description: checks, if data is of type list or np.array; used in functions to check input data
input:
data: any type, preferrably list or numpy.arraycheckIfNoneEmpty: if True, function only returns True if type is list or array AND if length is non-zero
output: returns True/False
Function: RaiseTypeError
function description: internal function which is used to raise common errors in case of wrong types; dim is used for vectors and square matrices, cols is used for non-square matrices
Relevant Examples (Ex) and TestModels (TM) with weblink to github: createSphereTriangleContact.py (TM)
Function: IsNone
function description: return True, if x is None; works also for numpy arrays or structures
Function: IsNotNone
function description: return True, if x is not None; works also for numpy arrays or structures
Relevant Examples (Ex) and TestModels (TM) with weblink to github: createSphereTriangleContact.py (TM)
Function: IsValidBool
function description: return True, if x is int, float, np.double, np.integer or similar types that can be automatically casted to pybind11
Function: IsValidRealInt
function description: return True, if x is int, float, np.double, np.integer or similar types that can be automatically casted to pybind11
Function: IsValidInt
function description: return True, if x is int, np.integer or similar types that can be automatically casted to pybind11
Relevant Examples (Ex) and TestModels (TM) with weblink to github: createSphereTriangleContact.py (TM)
Function: IsValidPRealInt
function description: return True, if x is valid Real/Int and positive
Function: IsValidURealInt
function description: return True, if x is valid Real/Int and unsigned (non-negative)
Function: IsReal
function description: return True, if x is any python or numpy float type; could also be called IsFloat(), but Real has special meaning in Exudyn
Function: IsInteger
function description: return True, if x is any python or numpy float type
Function: IsVector
IsVector(v, expectedSize = None)
function description: check if v is a valid vector with floats or ints; if expectedSize!=None, the length is also checked
Function: IsIntVector
IsIntVector(v, expectedSize = None)
function description: check if v is a valid vector with floats or ints; if expectedSize!=None, the length is also checked
Function: IsSquareMatrix
IsSquareMatrix(m, expectedSize = None)
function description: check if v is a valid vector with floats or ints; if expectedSize!=None, the length is also checked
Function: IsValidObjectIndex
function description: return True, if x is valid exudyn object index
Function: IsValidNodeIndex
function description: return True, if x is valid exudyn node index
Function: IsValidMarkerIndex
function description: return True, if x is valid exudyn marker index
Function: IsEmptyList
function description: return True, if x is an empty list (or empty list converted from numpy array), otherwise return False
Function: FillInSubMatrix
FillInSubMatrix(subMatrix, destinationMatrix, destRow, destColumn)
function description: fill submatrix into given destinationMatrix; all matrices must be numpy arrays
input:
subMatrix: input matrix, which is filled into destinationMatrixdestinationMatrix: the subMatrix is entered heredestRow: row destination of subMatrixdestColumn: column destination of subMatrix
output: destinationMatrix is changed after function call
notes: may be erased in future!
Relevant Examples (Ex) and TestModels (TM) with weblink to github: objectFFRFTest.py (TM)
Function: SweepSin
function description: compute sin sweep at given time t
input:
t: evaluate of sweep at time tt1: end time of sweep frequency rangef0: start of frequency interval [f0,f1] in Hzf1: end of frequency interval [f0,f1] in Hz
output: evaluation of sin sweep (in range -1..+1)
Relevant Examples (Ex) and TestModels (TM) with weblink to github: objectGenericODE2Test.py (TM)
Function: SweepCos
function description: compute cos sweep at given time t
input:
t: evaluate of sweep at time tt1: end time of sweep frequency rangef0: start of frequency interval [f0,f1] in Hzf1: end of frequency interval [f0,f1] in Hz
output: evaluation of cos sweep (in range -1..+1)
Relevant Examples (Ex) and TestModels (TM) with weblink to github: rigidRotor3DbasicBehaviour.py (Ex), rigidRotor3Drunup.py (Ex), objectGenericODE2Test.py (TM)
Function: FrequencySweep
function description: frequency according to given sweep functions SweepSin, SweepCos
input:
t: evaluate of frequency at time tt1: end time of sweep frequency rangef0: start of frequency interval [f0,f1] in Hzf1: end of frequency interval [f0,f1] in Hz
output: frequency in Hz
Relevant Examples (Ex) and TestModels (TM) with weblink to github: objectGenericODE2Test.py (TM)
Function: SmoothStep
SmoothStep(x, x0, x1, value0, value1)
function description: step function with smooth transition from value0 to value1; transition is computed with cos function
input:
x: argument at which function is evaluatedx0: start of step (f(x) = value0)x1: end of step (f(x) = value1)value0: value before smooth stepvalue1: value at end of smooth step
output: returns f(x)
Relevant Examples (Ex) and TestModels (TM) with weblink to github: beltDriveALE.py (Ex), beltDriveReevingSystem.py (Ex), chainDriveExample.py (Ex), craneReevingSystem.py (Ex), leggedRobot.py (Ex), createKinematicTreeTest.py (TM), …
Function: SmoothStepDerivative
SmoothStepDerivative(x, x0, x1, value0, value1)
function description: derivative of SmoothStep using same arguments
input:
x: argument at which function is evaluatedx0: start of step (f(x) = value0)x1: end of step (f(x) = value1)value0: value before smooth stepvalue1: value at end of smooth step
output: returns d/dx(f(x))
Relevant Examples (Ex) and TestModels (TM) with weblink to github: leggedRobot.py (Ex)
Function: IndexFromValue
IndexFromValue(data, value, tolerance = 1e-7, assumeConstantSampleRate = False, rangeWarning = True)
function description: get index from value in given data vector (numpy array); usually used to get specific index of time vector; this function is slow (linear search), if sampling rate is non-constant; otherwise set assumeConstantSampleRate=True!
input:
data: containing (almost) equidistant values of timevalue: e.g., time to be found in datatolerance: tolerance, which is accepted (default: tolerance=1e-7)rangeWarning: warn, if index returns out of range; if warning is deactivated, function uses the closest value
output: index
notes: to obtain the interpolated value of a time-signal array, use GetInterpolatedSignalValue() in exudyn.signalProcessing
Function: RoundMatrix
RoundMatrix(matrix, treshold = 1e-14)
function description: set all entries in matrix to zero which are smaller than given treshold; operates directly on matrix
input: matrix as np.array, treshold as positive value
output: changes matrix
Function: ConvertScipySparseToDict
ConvertScipySparseToDict(sparseMatrix)
function description: Function to convert a scipy sparse matrix to a dictionary
Function: ConvertDictToScipySparse
ConvertDictToScipySparse(sparseDict)
function description: Function to convert a dictionary back to a scipy sparse matrix
Function: SaveDictToHDF5
SaveDictToHDF5(fileName, dataDict)
function description: recursively saves a hierarchical dictionary dataDict to a HDF5 file with given fileName; limitations for certain types and Python or symbolic user functions
input:
fileName: file name (possibly including path) for HDF5 file, including file endingdataDict: the dictionary containing the hierarchical data to be saved; the data may contain the following data types in hierarchical form: int, bool, float, str (utf-8), list, dict, numpy array, scipy csr_matrix, Python function
output: None
Relevant Examples (Ex) and TestModels (TM) with weblink to github: NGsolvePistonEngine.py (Ex), serialRobotURDF.py (Ex), testHDF5loadSave.py (Ex), pickleCopyMbs.py (TM)
Function: LoadDictFromHDF5
LoadDictFromHDF5(fileName, callerGlobals = None)
function description: recursively loads a hierarchical dictionary from a HDF5 file with given fileName
input:
fileName: file name (possibly including path) for HDF5 file, including file endingcallerGlobals: optional: if your data contains functions, the callerGlobals must contain, e.g., globals() of the caller, where the Python functions are defined at which the HDF5 function refers to
output: dict which contains loaded data
Relevant Examples (Ex) and TestModels (TM) with weblink to github: serialRobotURDF.py (Ex), testHDF5loadSave.py (Ex), pickleCopyMbs.py (TM)
Function: ConvertFunctionToSymbolic
function description: Internal function to convert a Python user function into a dictionary containing the symbolic representation; this function is under development and should be used with care
input:
mbs: MainSystem, needed currently for interfacefunction: Python function with interface according to desired user functionitemIndex: item index, such as ObjectIndex or LoadIndex; -1 indicates MainSystem; if None, itemTypeName must be provided insteaditemTypeName: use of type name, such as ObjectConnectorSpringDamper; in this case, itemIndex must be NoneitemIndex: item index, such as ObjectIndex or LoadIndex; -1 indicates MainSystemuserFunctionName: name of user function item, see documentation; this is required, because some items have several user functions, which need to be distinguishedverbose: if > 0, according output is printed
output: return dictionary with ‘functionName’, ‘argList’, and ‘returnList’
Function: CreateSymbolicUserFunction
function description: Helper function to convert a Python user function into a symbolic user function; this function is under development and should be used with care
input:
mbs: MainSystem, needed currently for interfacefunction: Python function with interface according to desired user functionitemIndex: item index, such as ObjectIndex or LoadIndex; -1 indicates MainSystem; if None, itemTypeName must be provided insteaditemTypeName: use of type name, such as ObjectConnectorSpringDamper; in this case, itemIndex must be NoneuserFunctionName: name of user function item, see documentation; this is required, because some items have several user functions, which need to be distinguishedverbose: if > 0, according output may be printed
output: returns symbolic user function; this can be transfered into an item using TransferUserFunction2Item
notes: keep the return value alive in a variable (or list), as it contains the expression tree which must exist for the lifetime of the user function
example:
oGround = mbs.AddObject(ObjectGround())
node = mbs.AddNode(NodePoint(referenceCoordinates = [1.05,0,0]))
oMassPoint = mbs.AddObject(MassPoint(nodeNumber = node, mass=1))
symbolicFunc = CreateSymbolicUserFunction(mbs, function=springForceUserFunction,
userFunctionName='springForceUserFunction',
itemTypeName='ObjectConnectorSpringDamper')
m0 = mbs.AddMarker(MarkerBodyPosition(bodyNumber=oGround, localPosition=[0,0,0]))
m1 = mbs.AddMarker(MarkerBodyPosition(bodyNumber=oMassPoint, localPosition=[0,0,0]))
co = mbs.AddObject(ObjectConnectorSpringDamper(markerNumbers=[m0,m1],
referenceLength = 1, stiffness = 100, damping = 1,
springForceUserFunction=symbolicFunc))
exudyn.Print(symbolicFunc.Evaluate(mbs, 0., 0, 1.1, 0., 100., 0., 13.) )
Relevant Examples (Ex) and TestModels (TM) with weblink to github: cartesianSpringDamperUserFunction.py (Ex), SpringDamperMassUserFunction.py (Ex), symbolicUserFunctionMasses.py (Ex), loadUserFunctionTest.py (TM), symbolicUserFunctionCopyTest.py (TM), symbolicUserFunctionTest.py (TM)
Function: CreateTCPIPconnection
function description: function which has to be called before simulation to setup TCP/IP socket (server) for sending and receiving data; can be used to communicate with other Python interpreters or 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]
exudyn.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 with other 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.]))
exudyn.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)
Function: LoadPotentialEnergy
LoadPotentialEnergy(mbs, loadNumber, configuration = exudyn.ConfigurationType.Current)
function description: the potential energy of a constant load, zero in the reference configuration: \(-\fv\tp \uv\) of the displacement \(\uv\) of its marker point; None if the load has none that can be computed
input:
mbs: the MainSystem of the loadloadNumber: the load, a LoadIndexconfiguration: the configuration its marker is evaluated in
output: the potential energy as a float, or None for a load whose potential is not available: a load with a user function (it may depend on time), a body-fixed load, a torque (not conservative in 3D), a mass-proportional load on a body other than a mass point, a 1D mass or a rigid body
notes: Covered are ForceVector and Coordinate loads on any marker that gives a position or a coordinate, and MassProportional loads on the bodies named above.
Function: CreateLoadEnergySensor
CreateLoadEnergySensor(mbs, loadNumber, storeInternal = True, writeToFile = False, fileName = '')
function description: a SensorUserFunction that measures the potential energy of a constant load, LoadPotentialEnergy(…)
input:
mbs: the MainSystem of the loadloadNumber: the load, a LoadIndex; raises if its potential energy is not availablestoreInternal: store the values in the sensor, as for every sensorwriteToFile: write the values to a filefileName: the file, if written
output: the SensorIndex of the new sensor
Function: ItemODE2Coordinates
ItemODE2Coordinates(mbs, itemIndex)
function description: the global ODE2 coordinate indices of an object (its local-to-global list) or of a node, in the order of the matrices and vectors mbs.ComputeItem returns for it; the system must be assembled
Relevant Examples (Ex) and TestModels (TM) with weblink to github: computeItemTest.py (TM)
Function: NumericalJacobian
NumericalJacobian(mbs, function, coordinates, velocities = False, epsilon = 1e-6)
function description: the derivative of function() - any computation of the current state, e.g. an output variable or mbs.ComputeItem - by the given global ODE2 coordinates (velocities=True: by their time derivatives), by central differences with step epsilon; the state is restored afterwards; returns an array (number of values of function) x (number of coordinates); with ItemODE2Coordinates, the comparison with mbs.ComputeItem is one line: NumericalJacobian(mbs, lambda: mbs.GetObjectOutputBody(oBody, exu.OutputVariableType.Velocity, localPosition), ItemODE2Coordinates(mbs, oBody), velocities=True) against mbs.ComputeItem(oBody, exu.ComputeItemType.PositionJacobian, localPosition)
Relevant Examples (Ex) and TestModels (TM) with weblink to github: computeItemTest.py (TM)
CLASS ExpectedType(Enum) (in module advancedUtilities)
class description: internal type which is used for type checking in exudyn Python user functions; used to create unique error messages
CLASS TCPIPdata (in module advancedUtilities)
class description: helper class for CreateTCPIPconnection and for TCPIPsendReceive
CLASS SystemEnergy (in module advancedUtilities)
class description: the kinetic and potential energies of a whole system, from the output variables KineticEnergy and PotentialEnergy of its objects and from the potential of its constant loads (#2202)
input:
mbs: the MainSystem, assembledskipUnavailable: if True, an item that cannot give its energy (a user function, a type without the output variable) is left out and listed in .unavailable; if False, it raises
notes: The lists are made once, in init: .kineticObjects, .potentialObjects, .loads and .unavailable - the items that have the energy as an output variable and cannot give it with their parameters (a user function), and the loads without a potential, each with the reason. ComputeSystemEnergies() returns the four numbers; AddSensor() adds a SensorUserFunction that records them - call mbs.Assemble() again after it.
Class function: ComputeSystemEnergies
ComputeSystemEnergies(self, configuration = exudyn.ConfigurationType.Current)
class function description: [kinetic, potential of the objects, potential of the loads, total] in the given configuration; the kinetic energy of bodies computed from their mass matrix is available in the current configuration only
Class function: AddSensor
AddSensor(self, storeInternal = True, writeToFile = False, fileName = '')
class function description: a SensorUserFunction recording ComputeSystemEnergies(): [kinetic, potential of the objects, potential of the loads, total]; returns its SensorIndex
Relevant Examples (Ex) and TestModels (TM) with weblink to github: energiesTest.py (TM)