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

PlotLineCode(index)

  • 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.array

    • checkIfNoneEmpty: if True, function only returns True if type is list or array AND if length is non-zero

  • output: returns True/False

Function: RaiseTypeError

RaiseTypeError(where = '', argumentName = '', received = None, expectedType = None, dim = None, cols = None)

  • 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

IsNone(x)

  • function description: return True, if x is None; works also for numpy arrays or structures

Function: IsNotNone

IsNotNone(x)

  • 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

IsValidBool(x)

  • 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

IsValidRealInt(x)

  • 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

IsValidInt(x)

  • 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

IsValidPRealInt(x)

  • function description: return True, if x is valid Real/Int and positive

Function: IsValidURealInt

IsValidURealInt(x)

  • function description: return True, if x is valid Real/Int and unsigned (non-negative)

Function: IsReal

IsReal(x)

  • 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

IsInteger(x)

  • 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

IsValidObjectIndex(x)

  • function description: return True, if x is valid exudyn object index

Function: IsValidNodeIndex

IsValidNodeIndex(x)

  • function description: return True, if x is valid exudyn node index

Function: IsValidMarkerIndex

IsValidMarkerIndex(x)

  • function description: return True, if x is valid exudyn marker index

Function: IsEmptyList

IsEmptyList(x)

  • 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 destinationMatrix

    • destinationMatrix: the subMatrix is entered here

    • destRow: row destination of subMatrix

    • destColumn: 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

SweepSin(t, t1, f0, f1)

  • function description: compute sin sweep at given time t

  • input:

    • t: evaluate of sweep at time t

    • t1: end time of sweep frequency range

    • f0: start of frequency interval [f0,f1] in Hz

    • f1: 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

SweepCos(t, t1, f0, f1)

  • function description: compute cos sweep at given time t

  • input:

    • t: evaluate of sweep at time t

    • t1: end time of sweep frequency range

    • f0: start of frequency interval [f0,f1] in Hz

    • f1: 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

FrequencySweep(t, t1, f0, f1)

  • function description: frequency according to given sweep functions SweepSin, SweepCos

  • input:

    • t: evaluate of frequency at time t

    • t1: end time of sweep frequency range

    • f0: start of frequency interval [f0,f1] in Hz

    • f1: 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 evaluated

    • x0: start of step (f(x) = value0)

    • x1: end of step (f(x) = value1)

    • value0: value before smooth step

    • value1: 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 evaluated

    • x0: start of step (f(x) = value0)

    • x1: end of step (f(x) = value1)

    • value0: value before smooth step

    • value1: 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 time

    • value: e.g., time to be found in data

    • tolerance: 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 ending

    • dataDict: 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 ending

    • callerGlobals: 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

ConvertFunctionToSymbolic(mbs, function, userFunctionName, itemIndex = None, itemTypeName = None, verbose = 0)

  • 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 interface

    • function: Python function with interface according to desired user function

    • itemIndex: item index, such as ObjectIndex or LoadIndex; -1 indicates MainSystem; if None, itemTypeName must be provided instead

    • itemTypeName: use of type name, such as ObjectConnectorSpringDamper; in this case, itemIndex must be None

    • itemIndex: item index, such as ObjectIndex or LoadIndex; -1 indicates MainSystem

    • userFunctionName: name of user function item, see documentation; this is required, because some items have several user functions, which need to be distinguished

    • verbose: if > 0, according output is printed

  • output: return dictionary with ‘functionName’, ‘argList’, and ‘returnList’

Function: CreateSymbolicUserFunction

CreateSymbolicUserFunction(mbs, function, userFunctionName, itemIndex = None, itemTypeName = None, verbose = 0)

  • 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 interface

    • function: Python function with interface according to desired user function

    • itemIndex: item index, such as ObjectIndex or LoadIndex; -1 indicates MainSystem; if None, itemTypeName must be provided instead

    • itemTypeName: use of type name, such as ObjectConnectorSpringDamper; in this case, itemIndex must be None

    • userFunctionName: name of user function item, see documentation; this is required, because some items have several user functions, which need to be distinguished

    • verbose: 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

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) 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 client

    • receiveSize: number of double values to be received from TCPIP client

    • IPaddress: string containing IP address of client (e.g., ‘127.0.0.1’)

    • port: port for communication with client

    • bigEndian: 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 load

    • loadNumber: the load, a LoadIndex

    • configuration: 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 load

    • loadNumber: the load, a LoadIndex; raises if its potential energy is not available

    • storeInternal: store the values in the sensor, as for every sensor

    • writeToFile: write the values to a file

    • fileName: 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, assembled

    • skipUnavailable: 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)