```{raw} latex \clearpage ``` (sec-item-objectjointprismatic2d)= # ObjectJointPrismatic2D A prismatic joint in 2D; allows the relative motion of two bodies, using two RigidMarkers. ## Interface - Python names: `ObjectJointPrismatic2D` or `PrismaticJoint2D`, and `VPrismaticJoint2D` 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 'JointPrismatic2D': | name | type | size | default | description | |---|---|---|---|---| | **name** | String | | '' | constraints's unique name | | **markerNumbers** | ArrayMarkerIndex | | [ invalid (-1), invalid (-1) ] | list of markers used in connector | | **axisMarker0** | Vector3D | 3 | [1.,0.,0.] | direction of prismatic axis, given as a 3D vector in Marker0 frame | | **normalMarker1** | Vector3D | 3 | [0.,1.,0.] | direction of normal to prismatic axis, given as a 3D vector in Marker1 frame | | **constrainRotation** | Bool | | True | flag, which determines, if the connector also constrains the relative rotation of the two objects; if set to false, the constraint will keep an algebraic equation set equal zero | | **activeConnector** | Bool | | True | flag, which determines, if the connector is active; used to deactivate (temporarily) a connector or constraint | | **visualization** | VObjectJointPrismatic2D | | | parameters for visualization of item | ## Visualization parameters The parameters of `VObjectJointPrismatic2D`, 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 = radius of revolute joint; 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 joints](#sec-drawing-objectsjoint); a circle of diameter `drawSize` at each marker, the one of marker 0 red, and a line between them. ## 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 | |---|---|---| | Distance | $(\pv_1-\pv_0)\tp \Am_0 \tv_0 / \vert \tv_0\vert $ | position of marker m1 along the axis, measured from marker m0 | | Rotation | | the angle of marker m1 relative to marker m0 about $z$, from $\Am_0\tp \Am_1$ | | 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} = \Am_0\tp(\pv_1-\pv_0)$ | relative position of marker m1 in the frame of marker m0, which is the joint frame $J0$; its component along $\tv_0$ is Distance times $\vert \tv_0\vert $ | | ForceLocal | $\LU{J0}{\fv} = \Am_0\tp \nv_1 \lambda_0$ | the joint force normal to the axis, in the joint frame $J0$; as for the other joints the force on marker m0; the torque $\lambda_1$ is not included | | 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-objectjointprismatic2d)= ## Detailed description ### Definition of quantities | intermediate variables | symbol | description | |---|---|---| | marker positions | $\pv_0$, $\pv_1$ | global positions provided by marker m0 and m1 | | marker rotations | $\Am_0$, $\Am_1$ | rotation matrices provided by the two rigid markers | | prismatic axis | $\tv_0$ = `axisMarker0` | the axis, in the frame of marker m0 | | normal | $\mathbf{n}_1$ = `normalMarker1` | the normal to the axis, in the frame of marker m1 | | Lagrange multipliers | $[\lambda_0,\,\lambda_1]$ | the transverse force and the torque in the joint | ### Geometric relations The axis and the normal in the global frame are $\Am_0 \tv_0$ and $\Am_1 \mathbf{n}_1$; marker m1 may move along the axis, but not across it. ### Connector constraint equations On the position level (index 3) $$ (\pv_1-\pv_0)\tp \Am_1 \mathbf{n}_1 = 0 , \quad (\Am_0 \tv_0)\tp \Am_1 \mathbf{n}_1 = 0 , $$ the first keeping the relative position on the axis, the second keeping the axis normal to $\mathbf{n}_1$, which forbids the relative rotation. On the velocity level (index 2) their time derivatives, with the time derivatives of the rotated vectors from the angular velocities of the markers. With `constrainRotation = False` the second equation becomes $\lambda_1 = 0$ and the bodies may rotate relative to each other; with `activeConnector = False` both equations become $\lambda_i = 0$. (miniexample-objectjointprismatic2d)= ## Mini example ```python #a planar rigid body sliding along an axis of the ground: the axis in marker 0, the normal in marker 1 node = mbs.AddNode(NodeRigidBody2D(referenceCoordinates=[0,0,0])) body = mbs.AddObject(ObjectRigidBody2D(nodeNumber=node, mass=2, inertia=0.1)) mGround = mbs.AddMarker(MarkerBodyRigid(bodyNumber=oGround, localPosition=[0,0,0])) mBody = mbs.AddMarker(MarkerBodyRigid(bodyNumber=body, localPosition=[0,0,0])) mbs.AddObject(ObjectJointPrismatic2D(markerNumbers=[mGround, mBody], axisMarker0=[1,1,0], normalMarker1=[-1,1,0])) mbs.AddLoad(LoadForceVector(markerNumber=mBody, loadVector=[2,0,0])) #its part along the axis moves the body mbs.Assemble() mbs.SolveDynamic() #along the 45 degree axis: s = (F/sqrt(2))/(2m)*t^2, so x = s/sqrt(2) = F/(4m) at t=1 exu.sys['testResult'] = mbs.GetNodeOutput(node, exu.OutputVariableType.Coordinates)[0] #0.25 ``` Relevant Examples (Ex) and TestModels (TM) with weblink to github: [`sliderCrank3DwithANCFbeltDrive2.py`](https://github.com/jgerstmayr/EXUDYN/blob/master/python/Examples/sliderCrank3DwithANCFbeltDrive2.py) (Ex), [`geneticOptimizationSliderCrank.py`](https://github.com/jgerstmayr/EXUDYN/blob/master/python/Examples/geneticOptimizationSliderCrank.py) (Ex), [`connectorOutputVariablesTest.py`](https://github.com/jgerstmayr/EXUDYN/blob/master/python/TestModels/connectorOutputVariablesTest.py) (TM), [`PARTS_ATEs_moving.py`](https://github.com/jgerstmayr/EXUDYN/blob/master/python/TestModels/PARTS_ATEs_moving.py) (TM), [`scissorPrismaticRevolute2D.py`](https://github.com/jgerstmayr/EXUDYN/blob/master/python/TestModels/scissorPrismaticRevolute2D.py) (TM), [`sliderCrankFloatingTest.py`](https://github.com/jgerstmayr/EXUDYN/blob/master/python/TestModels/sliderCrankFloatingTest.py) (TM)