```{raw} latex \clearpage ``` (sec-item-objectconnectorcoordinatespringdamper)= # ObjectConnectorCoordinateSpringDamper A 1D (scalar) spring-damper element acting on single {ref}`ODE2 ` coordinates and connecting to coordinate-based markers. NOTE that the coordinate markers only measure the coordinate (=displacement), but the reference position is not included as compared to position-based markers!; the spring-damper can also act on rotational coordinates. ## Interface - Python names: `ObjectConnectorCoordinateSpringDamper` or `CoordinateSpringDamper`, and `VCoordinateSpringDamper` for its visualization - Markers it acts on: those providing `Coordinate`: [](#sec-item-markernodecoordinate), [](#sec-item-markernodeode1coordinate), [](#sec-item-markernoderotationcoordinate), [](#sec-item-markerbodiesrelativetranslationcoordinate), [](#sec-item-markerbodiesrelativerotationcoordinate), [](#sec-item-markerbodycable2dshape), [](#sec-item-markerbodycable2dcoordinates) ## Parameters The parameters of the item; in a dictionary, its type is 'ConnectorCoordinateSpringDamper': | name | type | size | default | description | |---|---|---|---|---| | **name** | String | | '' | connector's unique name | | **markerNumbers** | ArrayMarkerIndex | | [ invalid (-1), invalid (-1) ] | list of markers used in connector | | **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: $l_\mathrm{off}$) offset between two coordinates (reference length of springs), see equation | | **activeConnector** | Bool | | True | flag, which determines, if the connector is active; used to deactivate (temporarily) a connector or constraint | | **springForceUserFunction** | ObjectConnectorCoordinateSpringDamperSpringForceUserFunction | | 0 | (symbol: $\mathrm{UF} \in \Rcal$) A Python function which defines the spring force with 8 parameters, see equations section / see description below | | **visualization** | VObjectConnectorCoordinateSpringDamper | | | parameters for visualization of item | ## Visualization parameters The parameters of `VObjectConnectorCoordinateSpringDamper`, 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](#sec-drawing-objectsconnector); 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`](#sec-vsettingsconnectors), [`connectors.drawSimplified`](#sec-vsettingsconnectors), [`connectors.springNumberOfWindings`](#sec-vsettingsconnectors), [`general.cylinderTiling`](#sec-vsettingsgeneral). ## Output variables Available as `OutputVariableType` in sensors, `Get...Output()` and other functions: ```{tabularcolumns} \Y{0.25}\Y{0.25}\Y{0.5} ``` | 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 force in connector | | PotentialEnergy | $V = \frac{1}{2} k\, (\Delta q - l_\mathrm{off})^2$ | elastic energy of the spring; zero if the connector is not active; raises for a springForceUserFunction | (description-objectconnectorcoordinatespringdamper)= ## 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), $$ \Delta q= q_{m1} - q_{m0} $$ and relative velocity, $$ \Delta v= v_{m1} - v_{m0} $$ If `activeConnector = True`, the scalar spring force vector is computed as $$ f_{SD} = k \left( \Delta q - l_\mathrm{off} \right) + d \cdot \Delta v $$ If the springForceUserFunction $\mathrm{UF}$ is defined, $\fv_{SD}$ instead becomes ($t$ is current time) $$ f_{SD} = \mathrm{UF}(mbs, t, i_N, \Delta q, \Delta v, k, d, l_\mathrm{off}) $$ and `iN` represents the itemNumber (=objectNumber). If `activeConnector = False`, $f_{SD}$ is set to zero. NOTE { that until 2023-01-21 (exudyn V1.5.76), the CoordinateSpringDamper included the parameters dryFriction and dryFrictionProportionalZone. These parameters have been removed and they are only available in CoordinateSpringDamperExt, HOWEVER, with different names. In order to use CoordinateSpringDamperExt instead of the old CoordinateSpringDamper with the same friction behavior, we recoomend: - USE CoordinateSpringDamperExt.dynamicFrictionForce INSTEAD of CoordinateSpringDamper.dryFriction - USE CoordinateSpringDamperExt.frictionProportionalZone INSTEAD of CoordinateSpringDamper.dryFrictionProportionalZone - CoordinateSpringDamperExt.frictionProportionalZone has a different behavior in case that it is zero; thus use 1e-16 in this case, to get as close as possible to previous behaviour - the variables stiffness, damping and offset have the same interpretation in both objects - keep every other friction, sticking and contact variables in CoordinateSpringDamperExt as default values - user functions obtained a new interface in CoordinateSpringDamperExt, which just needs to be adapted } **Userfunction**: `springForceUserFunction(mbs, t, itemNumber, displacement, velocity, stiffness, damping, offset)` A user function, which computes the scalar spring force depending on time, object variables (displacement, velocity) and object parameters . The object variables are passed to the function using the current values of the CoordinateSpringDamper object. 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`. | 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 | | **return value** | Real | scalar value of computed force | *Example*: ```python #see also mini example! NOTE changes above since 2023-01-23 def UFforce(mbs, t, itemNumber, u, v, k, d, offset): return k*(u-offset) + d*v ``` (miniexample-objectconnectorcoordinatespringdamper)= ## Mini example ```python #define user function: #NOTE: removed 2023-01-21: dryFriction, dryFrictionProportionalZone def springForce(mbs, t, itemNumber, u, v, k, d, offset): return 0.1*k*u+k*u**3+v*d nMass=mbs.AddNode(Point(referenceCoordinates = [2,0,0])) massPoint = mbs.AddObject(MassPoint(mass = 5, nodeNumber = nMass)) groundMarker=mbs.AddMarker(MarkerNodeCoordinate(nodeNumber= nGround, coordinate = 0)) nodeMarker =mbs.AddMarker(MarkerNodeCoordinate(nodeNumber= nMass, coordinate = 0)) #Spring-Damper between two marker coordinates mbs.AddObject(CoordinateSpringDamper(markerNumbers = [groundMarker, nodeMarker], stiffness = 5000, damping = 80, springForceUserFunction = springForce)) loadCoord = mbs.AddLoad(LoadCoordinate(markerNumber = nodeMarker, load = 1)) #static linear solution:0.002 #assemble and solve system for default parameters mbs.Assemble() mbs.SolveDynamic() #check result at default integration time exu.sys['testResult'] = mbs.GetNodeOutput(nMass, exu.OutputVariableType.Displacement)[0] ``` Examples (Ex) and TestModels (TM) that show this item, with weblink to github: [`tutorialSpringDamper.py`](https://github.com/jgerstmayr/EXUDYN/blob/master/python/Examples/notebooks/tutorialSpringDamper.py) (Ex), [`coordinateSpringDamper.py`](https://github.com/jgerstmayr/EXUDYN/blob/master/python/Examples/coordinateSpringDamper.py) (Ex), [`plotSensorExamples.py`](https://github.com/jgerstmayr/EXUDYN/blob/master/python/Examples/plotSensorExamples.py) (Ex), [`slidercrankWithMassSpring.py`](https://github.com/jgerstmayr/EXUDYN/blob/master/python/Examples/slidercrankWithMassSpring.py) (Ex), [`CoordinateSpringDamperTest.py`](https://github.com/jgerstmayr/EXUDYN/blob/master/python/TestModels/CoordinateSpringDamperTest.py) (TM)