ObjectConnectorCoordinateSpringDamperExt

A 1D (scalar) spring-damper element acting on single ODE2 coordinates, same as ObjectConnectorCoordinateSpringDamper but with extended features, such as limit stop and improved friction. It has different user function interface and additional data node as compared to ObjectConnectorCoordinateSpringDamper, but otherwise behaves very similar. The CoordinateSpringDamperExt is very useful for a single axis of a robot or similar machine modelled with a KinematicTree, as it can add friction and limits based on physical properties. It is highly recommended, to use the bristle model for friction with frictionProportionalZone=0 in case of implicit integrators (GeneralizedAlpha) as it converges better.

Interface

Parameters

The parameters of the item; in a dictionary, its type is ‘ConnectorCoordinateSpringDamperExt’:

name

type

size

default

description

name

String

‘’

connector’s unique name

markerNumbers

ArrayMarkerIndex

[ invalid (-1), invalid (-1) ]

list of markers used in connector

nodeNumber

NodeIndex

invalid (-1)

node number of a NodeGenericData for 3 data coordinates (friction mode, last sticking position, limit stop state), see description for details; must exist in case of bristle friction model or limit stops

stiffness

Real

0.

(symbol: \(k\)) stiffness [SI:N/m] of spring; acts against relative value of coordinates

damping

Real

0.

(symbol: \(d\)) damping [SI:N/(m s)] of damper; acts against relative velocity of coordinates

offset

Real

0.

(symbol: \(x_\mathrm{off}\)) offset between two coordinates (reference length of springs), see equation; it can be used to represent the pre-scribed drive coordinate

velocityOffset

Real

0.

(symbol: \(v_\mathrm{off}\)) velocity offset of the damper force, see equation; also passed to springForceUserFunction

factor0

Real

1.

(symbol: \(f_0\)) marker 0 coordinate is multiplied with factor0

factor1

Real

1.

(symbol: \(f_1\)) marker 1 coordinate is multiplied with factor1

dynamicFrictionForce

UReal

0.

(symbol: \(f_{\mu,\mathrm{d}}\)) dynamic (viscous) friction force [SI:N] against relative velocity when sliding; assuming a normal force \(f_N\), the friction force can be interpreted as \(f_\mu = \mu f_N\)

staticFrictionOffsetForce

UReal

0.

(symbol: \(f_{\mu,\mathrm{so}}\)) static (dry) friction offset force [SI:N]; assuming a normal force \(f_N\), the friction force is limited by \(f_\mu \le (\mu_{so} + \mu_d) f_N = f_{\mu_d} + f_{\mu_{so}}\)

stickingStiffness

UReal

0.

(symbol: \(k_\mu\)) stiffness of bristles in sticking case [SI:N/m]

stickingDamping

UReal

0.

(symbol: \(d_\mu\)) damping of bristles in sticking case [SI:N/(m/s)]

exponentialDecayStatic

PReal

0.001

(symbol: \(v_\mathrm{exp}\)) relative velocity for exponential decay of static friction offset force [SI:m/s] against relative velocity; at \(\Delta v = v_\mathrm{exp}\), the static friction offset force is reduced to 36.8%

viscousFrictionFactor

Real

0.

(symbol: \(f_{\mu,\mathrm{v}}\)) viscous friction factor [SI:N s/m]: the friction force part proportional to the relative velocity, acting against it in the sliding case

frictionProportionalZone

UReal

0.

(symbol: \(v_\mathrm{reg}\)) if non-zero, a regularized Stribeck model is used, regularizing friction force around zero velocity - leading to zero friction force in case of zero velocity; this does not require a data node at all; if zero, the bristle model is used, which requires a data node which contains previous friction state and last sticking position

limitStopsUpper

Real

0.

(symbol: \(s_\mathrm{upper}\)) upper (maximum) value [SI:m] of coordinate before limit is activated; defined relative to the two marker coordinates

limitStopsLower

Real

0.

(symbol: \(s_\mathrm{lower}\)) lower (minimum) value [SI:m] of coordinate before limit is activated; defined relative to the two marker coordinates

limitStopsStiffness

UReal

0.

(symbol: \(k_\mathrm{limits}\)) stiffness [SI:N/m] of limit stop (contact stiffness); following a linear contact model

limitStopsDamping

UReal

0.

(symbol: \(d_\mathrm{limits}\)) damping [SI:N/(m/s)] of limit stop (contact damping); following a linear contact model

useLimitStops

bool

False

if True, limit stops are considered and parameters must be set accordingly; furthermore, the NodeGenericData must have 3 data coordinates

activeConnector

Bool

True

flag, which determines, if the connector is active; used to deactivate (temporarily) a connector or constraint

springForceUserFunction

ObjectConnectorCoordinateSpringDamperExtSpringForceUserFunction

0

(symbol: \(\mathrm{UF} \in \Rcal\)) A Python function which defines the spring force with 8 parameters, see equations section / see description below

visualization

VObjectConnectorCoordinateSpringDamperExt

parameters for visualization of item

Renamed parameters, still taken with a DeprecationWarning: fDynamicFriction (deprecated since 1.12.258, removed in 2031): use dynamicFrictionForce; fStaticFrictionOffset (deprecated since 1.12.258, removed in 2031): use staticFrictionOffsetForce; fViscousFriction (deprecated since 1.12.258, removed in 2031): use viscousFrictionFactor.

Visualization parameters

The parameters of VObjectConnectorCoordinateSpringDamperExt, given as visualization:

name

type

size

default

description

show

Bool

True

set true, if item is shown in visualization and false if it is not shown

drawSize

float

-1.

drawing size = diameter of spring; size == -1.f means that default connector size is used

color

Float4

4

[-1.,-1.,-1.,-1.]

RGBA connector color; if R==-1, use default color

Drawing

Drawn as all connectors; a spring of diameter drawSize between the positions of the markers, if they have one, drawn as the spring of ObjectConnectorSpringDamper.

Settings beyond those of all connectors: connectors.curveTiling, connectors.drawSimplified, connectors.springNumberOfWindings, general.cylinderTiling.

Output variables

Available as OutputVariableType in sensors, Get...Output() and other functions:

output variable

symbol

description

Displacement

\(\Delta q\)

relative scalar displacement of marker coordinates

Velocity

\(\Delta v\)

difference of scalar marker velocity coordinates

Force

\(f_{SD}\)

scalar spring force

Detailed description

Definition of quantities

intermediate variables

symbol

description

marker m0 coordinate

\(q_{m0}\)

current displacement coordinate which is provided by marker m0; does NOT include reference coordinate!

marker m1 coordinate

\(q_{m1}\)

marker m0 velocity coordinate

\(v_{m0}\)

current velocity coordinate which is provided by marker m0

marker m1 velocity coordinate

\(v_{m1}\)

Connector forces

Displacement between marker m0 to marker m1 coordinates (does NOT include reference coordinates),

\[ q= f_1 \cdot q_{m1} - f_0 \cdot q_{m0} \]

and relative velocity,

\[ v= f_1 \cdot v_{m1} - f_0 \cdot v_{m0} \]

The friction force is computed from given friction ‘force’ parameters, as there is no normal force in this model. This means, that dynamicFrictionForce represents \(\mu_d \cdot F_N\) in which \(\mu_d\) is the friction parameter and \(F_N\) is an according normal force.

The friction force is computed for different cases:

  • CASE 1: frictionProportionalZone != 0 (\(v_\mathrm{reg} \neq 0\)):

This case works well for explicit integrators and represents simplified friction. It is suited best, e.g., for drives if considered for a specific velocity, but not for the velocity=0 (at which no friction force is produced). If \(f_{\mu,\mathrm{d}} > 0\) or \(f_{\mu,\mathrm{so}} > 0\) or \(f_{\mu,\mathrm{v}} != 0\), the Stribeck friction model is used, with

\[\begin{split} f_\mathrm{friction} = \begin{cases} (f_{\mu,\mathrm{d}} + f_{\mu,\mathrm{so}}) \frac{\Delta v}{v_\mathrm{reg}}, \quad \mathrm{if} \quad |v| <= v_\mathrm{reg} \quad \mathrm{and} \quad v_\mathrm{reg} \neq 0 \\ \mathrm{Sign}(v)\left(f_{\mu,\mathrm{d}} + f_{\mu,\mathrm{so}} \mathrm{e}^{-(|v|-v_{reg})/v_{exp}} + f_{\mu,\mathrm{v}} (|v|-v_\mathrm{reg}) \right), \quad \mathrm{else} \end{cases} \end{split}\]

This case does not use a PostNewton iteration (which may be advantageous in constant step size explicit integration, but may be problematic in implicit integration).

  • CASE 2: frictionProportionalZone != 0 (or useLimitStops=True):

This case is perfectly suited for implicit integration, as it includes special switching variables that help to avoid numerical problems due to switching (e.g., between stick and slip) during a Newton iteration. In this case, a so-called bristle model is used, which requires the nodeNumber (data node) to be defined by a GenericDataNode, which must contain 3 data variables. In case of sticking, the sticking force results from a spring-damper model with parameters \(k_\mathrm{limits}\) and \(d_\mathrm{limits}\), which resolves sticking very well. The last sticking position is tracked, which allows to change between stick and slip; however, transition means a reduction of accuracy and requires additional computation of system Jacobians and Newton or discontinuous iterations. This case includes a PostNewton iteration to switch between stick and slip.

In CASE 2, the GenericDataNode has the 3 data variables (friction mode, last sticking position, limit stop state):

  • friction mode \(d_{\mu}\):

  • \(d_{\mu}=0\): stick,

  • \(d_{\mu}=\pm f_\mathrm{slip}\): slip (in according positive or negative direction); \(f_\mathrm{slip}\) representing the slipping force

  • last sticking position \(x_{lsp}\): contains relative coordinate \(q\) at last sticking position; in the sticking case, any deviation from that position leads to an additional bristle force

\[ f_\mathrm{friction}^* = (q-x_{lsp}) \cdot k_\mathrm{\mu} + v \cdot d_\mathrm{\mu} \]
  • limit stop state \(d_{ls}\): \(d_{ls} = 0\): no limit reached (no contact, \(d_{ls}<0\): limitStopsLower surpassed, \(d_{ls}>0\): limitStopsUpper surpassed; \(|d_{ls}|\) contains the penetration value of the soft contact model

Initialization of the GenericDataNode should be done such that the initial state (e.g. stick) is already set within this variable. Not doing so may change results (as the solver assumes that the model is already slipping) and requires additional iterations. NOTE, that in particular, if \(d_{\mu}\) is initilized with 0 (stick) and \(x_{lsp}\) (last sticking position) differs largely from the current \(q\), a large initial force may result.

The contact force \(f_\mathrm{contact}\) is computed if limit stops are reached. The contact is represented by a spring-damper, which is activated as soon as the limit is reached and deactivated, if the limit is left again. Contact forces are computed from stiffness \(k_\mathrm{limits}\) and damping \(d_\mathrm{limits}\), penetration into stop and velocity,

\[\begin{split} f_\mathrm{contact} = \begin{cases} k_\mathrm{limits} \cdot (q-s_\mathrm{upper}) + d_\mathrm{limits} \cdot v \quad \mathrm{if} \quad q > s_\mathrm{upper}\\ k_\mathrm{limits} \cdot (q-s_\mathrm{lower}) + d_\mathrm{limits} \cdot v \quad \mathrm{if} \quad q < s_\mathrm{lower} \end{cases} \end{split}\]

NOTE: while a combination of friction and limit stop is possible, it may be wanted to put a friction with frictionProportionalZone != 0 and a limit stop into two different objects, as the combined behavior would switch to a PostNewton method for the regularized friction model.

If activeConnector = True, the scalar spring force vector is computed as

\[ f_{SD} = k \cdot \left( q - x_\mathrm{off} \right) + d \cdot \left( v - v_\mathrm{off} \right) + f_\mathrm{friction} + f_\mathrm{contact} \]

If the springForceUserFunction \(\mathrm{UF}\) is defined, \(\fv_{SD}\) instead becomes (\(t\) is current time)

\[ f_{SD} = \mathrm{UF}(mbs, t, i_N, q, v, k, d, x_\mathrm{off}, v_\mathrm{off}, f_{\mu,\mathrm{d}}, f_{\mu,\mathrm{so}}, v_\mathrm{exp}, f_{\mu,\mathrm{v}}, v_\mathrm{reg}) \]

and iN represents the itemNumber (=objectNumber).

The virtual work of the connector force is computed from the virtual displacement

\[ \delta q = f_1 \cdot \delta q_{m1} - f_0 \cdot \delta q_{m0} \, , \]

and the virtual work results as

\[ \delta W_{SD} = f_{SD} \cdot \delta q = f_{SD} \cdot \left( f_1 \cdot \delta q_{m1} - f_0 \cdot \delta q_{m0} \right) \, . \]

The generalized (elastic) forces thus read for the markers \(m0\) and \(m1\),

\[ \Qm_{SD, m0} = -f_{SD} \cdot f_0 \cdot \Jm_{coord,m0} \, , \quad \Qm_{SD, m1} = f_{SD} \cdot f_1 \cdot \Jm_{coord,m1} \, , \]

in which \(\Jm_{coord,m0}\) and \(\Jm_{coord,m1}\) represent the coordinate Jacobians of the respective markers. As can be seen in generalized force \(\Qm\), the factors \(f_0\) and \(f_1\) are added accordingly which increase the force on ‘slower’ coordinates for certain gear ratios.

If activeConnector = False, \(f_{SD}\) is set to zero.

Userfunction: springForceUserFunction(mbs, t, itemNumber, displacement, velocity, stiffness, damping, offset, velocityOffset, dynamicFrictionForce, staticFrictionOffsetForce, exponentialDecayStatic, viscousFrictionFactor, frictionProportionalZone) A user function, which computes the scalar spring force depending on time, object variables (displacement, velocity) and several object parameters. Note that itemNumber represents the index of the object in mbs, which can be used to retrieve additional data from the object through mbs.GetObjectParameter(itemNumber, ...), see the according description of GetObjectParameter.

Only a subset of object variables is passed to the function using the current values of the CoordinateSpringDamperExt object. For parameters that are not passed via the user function interface, use mbs.GetObject(itemNumber) or, e.g., mbs.GetObjectParameter(itemNumber, ‘limitStopsUpper’) to obtain these parameters inside the user function.

arguments / return

type or size

description

mbs

MainSystem

provides MainSystem mbs in which underlying item is defined

t

Real

current time in mbs

itemNumber

Index

integer number \(i_N\) of the object in mbs, allowing easy access to all object data via mbs.GetObjectParameter(itemNumber, …)

displacement

Real

\(\Delta q\)

velocity

Real

\(\Delta v\)

stiffness

Real

copied from object

damping

Real

copied from object

offset

Real

copied from object

velocityOffset

Real

copied from object

dynamicFrictionForce

Real

copied from object

staticFrictionOffsetForce

Real

copied from object

exponentialDecayStatic

Real

copied from object

viscousFrictionFactor

Real

copied from object

frictionProportionalZone

Real

copied from object, also called regularization velocity or regVel

return value

Real

scalar value of computed force

Example:

#see also mini example!
#For further parameters, use mbs.GetObject(itemNumber) or
#  e.g. mbs.GetObjectParameter(itemNumber, 'limitStopsUpper')
def UFforce(mbs, t, itemNumber, u, v, k, d, offset, vOffset, muDynamic, myStaticOffset, muExpVel, muViscous, muRegVel):
    return k*(u-offset) + d*v

Mini example

#a coordinate spring with a limit stop; the stop's state is kept in a data node
node = mbs.AddNode(Node1D(referenceCoordinates=[0]))
mbs.AddObject(ObjectMass1D(nodeNumber=node, mass=1))
mCoord = mbs.AddMarker(MarkerNodeCoordinate(nodeNumber=node, coordinate=0))
mGround = mbs.AddMarker(MarkerNodeCoordinate(nodeNumber=nGround, coordinate=0))
nData = mbs.AddNode(NodeGenericData(numberOfDataCoordinates=3, initialCoordinates=[0,0,0]))
mbs.AddObject(ObjectConnectorCoordinateSpringDamperExt(markerNumbers=[mGround, mCoord], nodeNumber=nData,
              stiffness=100, damping=20, useLimitStops=True, limitStopsLower=-1, limitStopsUpper=0.05,
              limitStopsStiffness=1e4, limitStopsDamping=100))
mbs.AddLoad(LoadCoordinate(markerNumber=mCoord, load=10))

mbs.Assemble()
mbs.SolveDynamic()

#spring and stop share the load: 100*q + 1e4*(q - 0.05) = 10
exu.sys['testResult'] = mbs.GetNodeOutput(node, exu.OutputVariableType.Coordinates) #0.050495

Relevant Examples (Ex) and TestModels (TM) with weblink to github: coordinateSpringDamper.py (Ex), involuteGearGraphics.py (Ex), lugreFrictionTest.py (Ex), massSpringFrictionInteractive.py (Ex), coordinateSpringDamperExtVelocityOffsetTest.py (TM), explicitSolversPostNewtonTest.py (TM), coordinateSpringDamperExt.py (TM)