```{raw} latex \clearpage ``` (sec-item-objectconnectortorsionalspringdamper)= # ObjectConnectorTorsionalSpringDamper An torsional spring-damper element acting on relative rotations around Z-axis of local joint0 coordinate system. It connects to orientation-based markers; if other rotation axis than the local joint0 Z axis shall be used, the joint rotationMarker0 / rotationMarker1 may be used. The joint perfectly extends a RevoluteJoint with a spring-damper, which can also be used to represent feedback control in an elegant and efficient way, by chosing appropriate user functions. It also allows to measure continuous / infinite rotations by making use of a NodeGeneric which compensates $\pm \pi$ jumps in the measured rotation (`OutputVariableType.Rotation`). ```{image} /docs/figures/itemImages/ObjectConnectorTorsionalSpringDamper.png :width: 500 ``` **Simpler**: [`mbs.CreateTorsionalSpringDamper`](#sec-mainsystemextensions-createtorsionalspringdamper) adds this item, with what it needs, in one call. ## Interface - Python names: `ObjectConnectorTorsionalSpringDamper` or `TorsionalSpringDamper`, and `VTorsionalSpringDamper` for its visualization - Nodes it takes: [](#sec-item-nodegenericdata) - Markers it acts on: those providing `Orientation`: [](#sec-item-markerbodyrigid), [](#sec-item-markernoderigid), [](#sec-item-markersuperelementrigid), [](#sec-item-markerkinematictreerigid) ## Parameters The parameters of the item; in a dictionary, its type is 'ConnectorTorsionalSpringDamper': | 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) | (symbol: $n_d$) node number of a NodeGenericData with 1 dataCoordinate for continuous rotation reconstruction; if this node is left to invalid index, it will not be used | | **stiffness** | Real | | 0. | (symbol: $k$) torsional stiffness [SI:Nm/rad] against relative rotation | | **damping** | Real | | 0. | (symbol: $d$) torsional damping [SI:Nm/(rad/s)] | | **rotationMarker0** | Matrix3D | 9 | [[1,0,0], [0,1,0], [0,0,1]] | local rotation matrix for marker 0; transforms joint into marker coordinates | | **rotationMarker1** | Matrix3D | 9 | [[1,0,0], [0,1,0], [0,0,1]] | local rotation matrix for marker 1; transforms joint into marker coordinates | | **offset** | Real | | 0. | (symbol: $\theta_\mathrm{off}$) rotational offset considered in the spring torque calculation (this can be used as rotation control input!) | | **velocityOffset** | Real | | 0. | (symbol: $\omega_\mathrm{off}$) angular velocity offset considered in the damper torque calculation (this can be used as angular velocity control input!) | | **torque** | Real | | 0. | (symbol: $\tau_c$) additional constant torque [SI:Nm] added to spring-damper; this can be used to prescribe a torque between the two attached bodies (e.g., for actuation and control) | | **activeConnector** | Bool | | True | flag, which determines, if the connector is active; used to deactivate (temporarily) a connector or constraint | | **springTorqueUserFunction** | ObjectConnectorTorsionalSpringDamperSpringTorqueUserFunction | | 0 | (symbol: $\mathrm{UF} \in \Rcal$) A Python function which computes the scalar torque between the two rigid body markers in local joint0 coordinates, if activeConnector=True; see description below | | **visualization** | VObjectConnectorTorsionalSpringDamper | | | parameters for visualization of item | Deprecated parameters, which still work and give a `DeprecationWarning` when set other than their default: `rotationMarker0` (deprecated since 1.12.244, removed in 2031): give the rotation to marker 0 as its localHT, e.g. MarkerBodyRigid(bodyNumber=b, localHT=exu.HT(rotation=A, translation=p)); `rotationMarker1` (deprecated since 1.12.244, removed in 2031): give the rotation to marker 1 as its localHT, e.g. MarkerBodyRigid(bodyNumber=b, localHT=exu.HT(rotation=A, translation=p)). ## Visualization parameters The parameters of `VObjectConnectorTorsionalSpringDamper`, 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); at each marker a short cylinder and a double arrow along the axis of rotation, of size `drawSize`. Settings beyond those of all connectors: [`general.axesTiling`](#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 | |---|---|---| | Rotation | $\Delta\theta$ | relative rotation around the spring-damper Z-coordinate, enhanced to a continuous rotation (infinite rotations $>+\pi$ and $<-\pi$) if a NodeGeneric with 1 coordinate as added | | AngularVelocityLocal | $\Delta\omega$ | scalar relative angular velocity around joint0 Z-axis | | TorqueLocal | $\tau_{SD}$ | scalar spring-damper torque around the local joint0 Z-axis | | PotentialEnergy | $V = \frac{1}{2} k\, (\varphi - \varphi_\mathrm{off})^2 + \tau_c\, \varphi$ | elastic energy of the spring and the potential of the constant torque; zero if the connector is not active; raises for a springTorqueUserFunction | (description-objectconnectortorsionalspringdamper)= ## Detailed description ### Definition of quantities | input parameter | symbol | description | |---|---|---| | rotationMarker0 | $\LU{m0,J0}{\Rot}$ | rotation matrix which transforms from joint 0 into marker 0 coordinates | | rotationMarker1 | $\LU{m1,J1}{\Rot}$ | rotation matrix which transforms from joint 1 into marker 1 coordinates | | markerNumbers[0] | $m0$ | global marker number m0 | | markerNumbers[1] | $m1$ | global marker number m1 | | nodeNumber | $n0$ | optional node number of a generic node (otherwise exu.InvalidIndex()) | | intermediate variables | symbol | description | |---|---|---| | marker m0 orientation | $\LU{0,m0}{\Rot}$ | current rotation matrix provided by marker m0 | | marker m1 orientation | $\LU{0,m1}{\Rot}$ | current rotation matrix provided by marker m1 | | marker m0 ang. velocity | $\LU{m0}{\tomega}_{m0}$ | current local angular velocity vector provided by marker m0 | | marker m1 ang. velocity | $\LU{m1}{\tomega}_{m1}$ | current local angular velocity vector provided by marker m1 | | AngularVelocityLocal | $\Delta\omega = \left( \LU{J0,m1}{\Rot} \LU{m1}{\tomega} - \LU{J0,m0}{\Rot} \LU{m0}{\tomega} \right)_Z$ | angular velocity around joint0 Z-axis | ### Connector forces If `activeConnector = True`, the vector spring force is computed as $$ \tau_{SD} = k \left(\Delta\theta - \theta_\mathrm{off} \right) + d \left(\Delta\omega - \omega_\mathrm{off} \right) + \tau_c $$ if `activeConnector = False`, $\tau_{SD}$ is set zero. If the springTorqueUserFunction $\mathrm{UF}$ is defined and `activeConnector = True`, $\tau_{SD}$ instead becomes ($t$ is current time) $$ \tau_{SD} = \mathrm{UF}(mbs, t, i_N, \Delta\theta, \Delta\omega, \mathrm{stiffness}, \mathrm{damping}, \mathrm{offset}) $$ and `iN` represents the itemNumber (=objectNumber). **Userfunction**: `springTorqueUserFunction(mbs, t, itemNumber, rotation, angularVelocity, stiffness, damping, offset)` A user function, which computes the scalar torque depending on mbs, time, local quantities (relative rotation, relative angularVelocity), which are evaluated at current time. Furthermore, the user function contains object parameters (stiffness, damping, offset). 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`. Detailed description of the arguments and local quantities: | 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, ...) | | `rotation` | Real | $\Delta \theta$ | | `angularVelocity` | Real | $\Delta \omega$ | | `stiffness` | Real | copied from object | | `damping` | Real | copied from object | | `offset` | Real | copied from object | | **return value** | Real | computed torque | *Example*: ```python #define simple cubic force for spring-damper: def UFforce(mbs, t, itemNumber, rotation, angularVelocity, stiffness, damping, offset): k = stiffness #passed as list u = rotation return k*u + 0.1*k*u**3 #markerNumbers and parameters taken from mini example mbs.AddObject(TorsionalSpringDamper(markerNumbers = [mGround, mBody], stiffness = k, damping = k*0.01, offset = 0, springTorqueUserFunction = UFforce)) ``` (miniexample-objectconnectortorsionalspringdamper)= ## Mini example ```python #example with rigid body at [0,0,0], with torsional load k=2e3 nBody = mbs.AddNode(RigidRxyz()) oBody = mbs.AddObject(RigidBody(mass=1, inertia=[1,1,1,0,0,0], nodeNumber=nBody)) mBody = mbs.AddMarker(MarkerNodeRigid(nodeNumber=nBody)) mGround = mbs.AddMarker(MarkerBodyRigid(bodyNumber=oGround, localPosition = [0,0,0])) mbs.AddObject(RevoluteJointZ(markerNumbers = [mGround, mBody])) #rotation around ground Z-axis mbs.AddObject(TorsionalSpringDamper(markerNumbers = [mGround, mBody], stiffness = k, damping = k*0.01, offset = 0)) #torque around z-axis; expect approx. phiZ = 1/k=0.0005 mbs.AddLoad(Torque(markerNumber = mBody, loadVector=[0,0,1])) #assemble and solve system for default parameters mbs.Assemble() mbs.SolveDynamic(exu.SimulationSettings()) #check result at default integration time exu.sys['testResult'] = mbs.GetNodeOutput(nBody, exu.OutputVariableType.Rotation)[2] ``` Relevant Examples (Ex) and TestModels (TM) with weblink to github: [`chainDriveExample.py`](https://github.com/jgerstmayr/EXUDYN/blob/master/python/Examples/chainDriveExample.py) (Ex), [`mobileMecanumWheelRobotWithLidar.py`](https://github.com/jgerstmayr/EXUDYN/blob/master/python/Examples/mobileMecanumWheelRobotWithLidar.py) (Ex), [`ROSMobileManipulator.py`](https://github.com/jgerstmayr/EXUDYN/blob/master/python/Examples/ROSMobileManipulator.py) (Ex), [`ROSTurtle.py`](https://github.com/jgerstmayr/EXUDYN/blob/master/python/Examples/ROSTurtle.py) (Ex), [`serialRobotInteractiveLimits.py`](https://github.com/jgerstmayr/EXUDYN/blob/master/python/Examples/serialRobotInteractiveLimits.py) (Ex), [`serialRobotTSD.py`](https://github.com/jgerstmayr/EXUDYN/blob/master/python/Examples/serialRobotTSD.py) (Ex), [`explicitSolversPostNewtonTest.py`](https://github.com/jgerstmayr/EXUDYN/blob/master/python/TestModels/explicitSolversPostNewtonTest.py) (TM), [`createFunctionsTest.py`](https://github.com/jgerstmayr/EXUDYN/blob/master/python/TestModels/createFunctionsTest.py) (TM), [`createItemNumbersTest.py`](https://github.com/jgerstmayr/EXUDYN/blob/master/python/TestModels/createItemNumbersTest.py) (TM), [`energiesTest.py`](https://github.com/jgerstmayr/EXUDYN/blob/master/python/TestModels/energiesTest.py) (TM), [`inactiveConnectorForceTest.py`](https://github.com/jgerstmayr/EXUDYN/blob/master/python/TestModels/inactiveConnectorForceTest.py) (TM), [`rotatingTableTest.py`](https://github.com/jgerstmayr/EXUDYN/blob/master/python/TestModels/rotatingTableTest.py) (TM), [`sliderCrank3Dbenchmark.py`](https://github.com/jgerstmayr/EXUDYN/blob/master/python/TestModels/sliderCrank3Dbenchmark.py) (TM)