```{raw} latex \clearpage ``` (sec-item-objectjointprismaticx)= # ObjectJointPrismaticX A prismatic joint in 3D; constrains the relative rotation of two rigid body markers and relative motion w.r.t. the joint $y$ and $z$ axes, allowing a relative motion along the joint $x$ axis (defined in local coordinates of marker 0 / joint J0 coordinates). The joint coordinate system is the frame of the markers; a rotation of it is given to the markers as their localHT. For easier definition of the joint, use `mbs.CreatePrismaticJoint(...)` for two rigid bodies (or ground). ```{image} /docs/figures/PrismaticJointX.png :width: 500 ``` **Simpler**: [`mbs.CreatePrismaticJoint`](#sec-mainsystemextensions-createprismaticjoint) adds this item, with what it needs, in one call. ## Interface - Python names: `ObjectJointPrismaticX` or `PrismaticJointX`, and `VPrismaticJointX` for its visualization - Markers it acts on: those providing `Position` and `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 'JointPrismaticX': | name | type | size | default | description | |---|---|---|---|---| | **name** | String | | '' | constraints's unique name | | **markerNumbers** | ArrayMarkerIndex | 2 | [ invalid (-1), invalid (-1) ] | (symbol: $[m0,m1]\tp$) list of markers used in connector | | **rotationMarker0** | Matrix3D | 9 | [[1,0,0], [0,1,0], [0,0,1]] | (symbol: $\LU{m0,J0}{\Rot}$) local rotation matrix for marker $m0$; translation and rotation axes for marker $m0$ are defined in the local body coordinate system and additionally transformed by rotationMarker0 | | **rotationMarker1** | Matrix3D | 9 | [[1,0,0], [0,1,0], [0,0,1]] | (symbol: $\LU{m1,J1}{\Rot}$) local rotation matrix for marker $m1$; translation and rotation axes for marker $m1$ are defined in the local body coordinate system and additionally transformed by rotationMarker1 | | **activeConnector** | Bool | | True | flag, which determines, if the connector is active; used to deactivate (temporarily) a connector or constraint | | **visualization** | VObjectJointPrismaticX | | | 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 `VObjectJointPrismaticX`, 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 | | **axisRadius** | float | | 0.1 | radius of joint axis to draw | | **axisLength** | float | | 0.4 | length of joint axis to draw | | **color** | Float4 | 4 | [-1.,-1.,-1.,-1.] | RGBA connector color; if R==-1, use default color | ## Drawing Drawn as [all joints](#sec-drawing-objectsjoint); the sliding axis as a cylinder at marker 0 inside a tube of `axisRadius` at marker 1, of length `axisLength`; with `connectors.showJointAxes` the frames of both markers. Settings beyond those of all joints: [`connectors.jointAxesLength`](#sec-vsettingsconnectors), [`connectors.jointAxesRadius`](#sec-vsettingsconnectors), [`connectors.showJointAxes`](#sec-vsettingsconnectors), [`general.axesTiling`](#sec-vsettingsgeneral), [`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 | |---|---|---| | Position | $\LU{0}{\pv}_{m0}$ | current global position of position marker $m0$ | | Velocity | $\LU{0}{\vv}_{m0}$ | current global velocity of position marker $m0$ | | DisplacementLocal | $\LU{J0}{\Delta\pv}$ | relative displacement in local joint0 coordinates; uses local J0 coordinates even for spherical joint configuration | | VelocityLocal | $\LU{J0}{\Delta\vv}$ | relative translational velocity in local joint0 coordinates | | Rotation | $\LU{J0}{\ttheta}= [\theta_0,\theta_1,\theta_2]\tp$ | relative rotation parameters (Tait Bryan Rxyz); if all axes are fixed, this output represents the rotational drift; for a revolute joint, it contains the rotation of this axis | | AngularVelocityLocal | $\LU{J0}{\Delta\tomega}$ | relative angular velocity in local joint0 coordinates; if all axes are fixed, this output represents the angular velocity constraint error; for a revolute joint, it contains the angular velocity of this axis | | ForceLocal | $\LU{J0}{\fv}$ | joint force in local $J0$ coordinates | | TorqueLocal | $\LU{J0}{\mv}$ | joint torque in local $J0$ coordinates; depending on joint configuration, the result may not be the according torque vector | | HomogeneousTransformation | $\LU{0}{\Hm}_{J0}$ | the joint frame $J0$ as homogeneous transformation: its rotation matrix and the position of marker $m0$, as 4x4 matrix $[\LU{0}{\Rot}_{J0}\;\LU{0}{\pv}_{m0};\;\Null\tp\;1]$; the Get...Output functions return it as exu.HT, a sensor stores its 16 values row by row | | HomogeneousTransformationLocal | $\LU{J0}{\Hm}_{J1} = \LU{0}{\Hm}_{J0}^{-1}\,\LU{0}{\Hm}_{J1}$ | the joint frame $J1$ relative to the joint frame $J0$: the relative rotation matrix $\LU{0}{\Rot}_{J0}\tp\LU{0}{\Rot}_{J1}$ and the relative position $\LU{0}{\Rot}_{J0}\tp(\LU{0}{\pv}_{m1}-\LU{0}{\pv}_{m0})$; for a joint the identity up to its free axes and its drift; returned and stored as HomogeneousTransformation | (description-objectjointprismaticx)= ## Detailed description (sec-objectjointprismaticx-definitionofquantities)= ### Definition of quantities | intermediate variables | symbol | description | |---|---|---| | marker m0 position | $\LU{0}{\pv}_{m0}$ | current global position which is provided by marker m0 | | marker m0 orientation | $\LU{0,m0}{\Rot}$ | current rotation matrix provided by marker m0 | | joint J0 orientation | $\LU{0,J0}{\Rot} = \LU{0,m0}{\Rot} \LU{m0,J0}{\Rot}$ | joint $J0$ rotation matrix | | joint J0 orientation vectors | $\LU{0,J0}{\Rot} = [\LU{0}{\tv_{x0}},\,\LU{0}{\tv_{y0}},\,\LU{0}{\tv_{z0}}]\tp$ | orientation vectors (represent local $x$, $y$, and $z$ axes) in global coordinates, used for definition of constraint equations | | marker m1 position | $\LU{0}{\pv}_{m1}$ | accordingly | | marker m1 orientation | $\LU{0,m1}{\Rot}$ | current rotation matrix provided by marker m1 | | joint J1 orientation | $\LU{0,J1}{\Rot} = \LU{0,m1}{\Rot} \LU{m1,J1}{\Rot}$ | joint $J1$ rotation matrix | | joint J1 orientation vectors | $\LU{0,J1}{\Rot} = [\LU{0}{\tv_{x1}},\,\LU{0}{\tv_{y1}},\,v\tv_{z1}]\tp$ | orientation vectors (represent local $x$, $y$, and $z$ axes) in global coordinates, used for definition of constraint equations | | marker m0 velocity | $\LU{0}{\vv}_{m0}$ | current global velocity which is provided by marker m0 | | marker m1 velocity | $\LU{0}{\vv}_{m1}$ | accordingly | | marker m0 velocity | $\LU{b}{\tomega}_{m0}$ | current local angular velocity vector provided by marker m0 | | marker m1 velocity | $\LU{b}{\tomega}_{m1}$ | current local angular velocity vector provided by marker m1 | | Displacement | $\LU{0}{\Delta\pv}=\LU{0}{\pv}_{m1} - \LU{0}{\pv}_{m0}$ | used, if all translational axes are constrained | | DisplacementLocal | $\LU{J0}{\Delta\pv}$ | $\left(\LU{0,m0}{\Rot}\LU{m0,J0}{\Rot}\right)\tp \LU{0}{\Delta\pv}$ | | VelocityLocal | $\LU{J0}{\Delta\vv}$ | $\left(\LU{0,m0}{\Rot}\LU{m0,J0}{\Rot}\right)\tp \LU{0}{\Delta\vv}$ $\ldots$ note that this is the global relative velocity projected into the local $J0$ coordinate system | | AngularVelocityLocal | $\LU{J0}{\Delta\omega}$ | $\left(\LU{0,m0}{\Rot}\LU{m0,J0}{\Rot}\right)\tp \left( \LU{0,m1}{\Rot} \LU{m1}{\omega} - \LU{0,m0}{\Rot} \LU{m0}{\omega} \right)$ | | algebraic variables | $\zv=[\lambda_0,\,\ldots,\,\lambda_5]\tp$ | vector of algebraic variables (Lagrange multipliers) according to the algebraic equations | ### Connector constraint equations **Equations for translational part (`activeConnector = True`)**: The two translational index 3 constraints for a free motion along the local $x$-axis read (in the coordinate system $J0$), $$ \begin{aligned} \LU{J0}{\pv}_{y,m1} - \LU{J0}{\pv}_{y,m0} &= \Null \\ \LU{J0}{\pv}_{z,m1} - \LU{J0}{\pv}_{z,m0} &= \Null \end{aligned} $$ and the translational index 2 constraints read $$ \begin{aligned} \LU{J0}{\vv}_{y,m1} - \LU{J0}{\vv}_{y,m0} &= \Null \\ \LU{J0}{\vv}_{z,m1} - \LU{J0}{\vv}_{z,m0} &= \Null \end{aligned} $$ **Equations for rotational part (`activeConnector = True`)**: Note that the axes are always given in global coordinates, compare the table in [](#sec-objectjointprismaticx-definitionofquantities). The index 3 constraint equations read $$ \begin{aligned} \LU{0}{\tv}_{z0}\tp \LU{0}{\tv}_{y1} &= 0 \\ \LU{0}{\tv}_{z0}\tp \LU{0}{\tv}_{x1} &= 0 \\ \LU{0}{\tv}_{x0}\tp \LU{0}{\tv}_{y1} &= 0 \end{aligned} $$ (eq-objectjointprismaticx-index3) The index 2 constraints follow from the derivative of {eq}`eq-objectjointprismaticx-index3` w.r.t., and are given in the C++ code. if `activeConnector = False`, $$ \zv = \Null $$ (miniexample-objectjointprismaticx)= ## Mini example ```python #a body that may only slide along the x-axis of the joint frame, here turned to the global y-axis inertia = InertiaCuboid(density=1000, sideLengths=[0.1,0.1,0.1]) node = mbs.AddNode(NodeRigidBodyEP(referenceCoordinates=[0,0,0]+eulerParameters0)) body = mbs.AddObject(ObjectRigidBody(nodeNumber=node, mass=inertia.Mass(), inertia=inertia.GetInertia6D())) HTjoint = exu.HT().SetRotationZ(0.5*np.pi) #the joint x-axis is the global y-axis mBody = mbs.AddMarker(MarkerBodyRigid(bodyNumber=body, localHT=HTjoint)) mGround = mbs.AddMarker(MarkerBodyRigid(bodyNumber=oGround, localHT=HTjoint)) mbs.AddObject(ObjectJointPrismaticX(markerNumbers=[mGround, mBody])) mbs.AddLoad(LoadForceVector(markerNumber=mBody, loadVector=[1,1,1])) #only the y-part moves the body mbs.Assemble() mbs.SolveDynamic() #y = F_y/(2m)*t^2 at t=1, x and z stay 0 exu.sys['testResult'] = sum(mbs.GetNodeOutput(node, exu.OutputVariableType.Displacement))*2*inertia.Mass() #1 ``` Examples (Ex) and TestModels (TM) that show this item, with weblink to github: [`revoluteJointPrismaticJointTest.py`](https://github.com/jgerstmayr/EXUDYN/blob/master/python/TestModels/revoluteJointPrismaticJointTest.py) (TM)