```{raw} latex \clearpage ``` (sec-item-markerkinematictreerigid)= # MarkerKinematicTreeRigid A position and orientation (rigid-body) marker attached to a kinematic tree. The marker is attached to the ObjectKinematicTree object and additionally needs a link number as well as a local position, similar to the SensorKinematicTree. The marker allows to attach loads (LoadForceVector and LoadTorqueVector) at arbitrary links or position. It also allows to attach connectors (e.g., spring dampers or actuators) to the kinematic tree. Finally, joint constraints can be attached, which allows for realization of closed loop structures. NOTE, however, that it is less efficient to attach many markers to a kinematic tree, therefor for forces or joint control use the structures available in kinematic tree whenever possible. ## Interface - Provides: `Position`, `Orientation` - Bodies it can be placed on: [](#sec-item-objectkinematictree) - Connectors, constraints and loads that can use it: [](#sec-item-objectconnectorspringdamper), [](#sec-item-objectconnectorcartesianspringdamper), [](#sec-item-objectconnectorrigidbodyspringdamper), [](#sec-item-objectconnectorlinearspringdamper), [](#sec-item-objectconnectortorsionalspringdamper), [](#sec-item-objectconnectorgravity), [](#sec-item-objectconnectorhydraulicactuatorsimple), [](#sec-item-objectconnectordistance), [](#sec-item-objectconnectorrollingdiscpenalty), [](#sec-item-objectcontactconvexroll), [](#sec-item-objectcontactspheresphere), [](#sec-item-objectcontactspheretorus), [](#sec-item-objectcontactspheretriangle), [](#sec-item-objectcontactcurvecircles), [](#sec-item-objectjointgeneric), [](#sec-item-objectjointrevolutez), [](#sec-item-objectjointprismaticx), [](#sec-item-objectjointspherical), [](#sec-item-objectjointrollingdisc), [](#sec-item-objectjointrevolute2d), [](#sec-item-objectjointprismatic2d), [](#sec-item-loadforcevector), [](#sec-item-loadtorquevector) ## Parameters The parameters of the item; in a dictionary, its type is 'KinematicTreeRigid': | name | type | size | default | description | |---|---|---|---|---| | **name** | String | | '' | marker's unique name | | **objectNumber** | ObjectIndex | | invalid (-1) | (symbol: $n_b$) body number to which marker is attached to | | **linkNumber** | UInt | | invalid (-1) | (symbol: $n_l$) number of link in KinematicTree to which marker is attached to; **must be given**: the default is only a placeholder | | **localPosition** | Vector3D | 3 | None (zero) | (symbol: $\LU{l}{\bv}$) local (link-fixed) position of marker at link $n_l$, using the link ($n_l$) coordinate system; the translation of localHT | | **localHT** | HomogeneousTransformation | | None (identity) | (symbol: $\LU{l}{\Hm}_{m}$) the frame of the marker in the link frame, as homogeneous transformation: its translation is localPosition, its rotation turns the marker frame against the link; a 4x4 matrix, its 16 values row by row or an exu.HT; None: not given; given together with localPosition, both must agree | | **visualization** | VMarkerKinematicTreeRigid | | | parameters for visualization of item | ## Visualization parameters The parameters of `VMarkerKinematicTreeRigid`, 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 | ## Drawing Drawn as [all markers](#sec-drawing-markers). (description-markerkinematictreerigid)= ## Detailed description ### Marker quantities The link frame of link $n_l$ - its position $\LU{0}{\pv}_{l}$, rotation $\LU{0l}{\Rot}$, velocity $\LU{l}{\vv}_{l}$ and angular velocity $\LU{l}{\tomega}_{l}$ in link coordinates - comes from the joint transformations of `ObjectKinematicTree`, evaluated from the base to the link. | marker quantity | symbol | description | |---|---|---| | marker position | $\LU{0}{\pv}_{m} = \LU{0}{\pv}_{l} + \LU{0l}{\Rot} \LU{l}{\bv}$ | global position of the local position $\LU{l}{\bv}$ on link $n_l$ | | marker velocity | $\LU{0}{\vv}_{m} = \LU{0l}{\Rot} \left(\LU{l}{\vv}_{l} + \LU{l}{\tomega}_{l} \times \LU{l}{\bv} \right)$ | global velocity | | marker rotation matrix | $\LU{0m}{\Rot} = \LU{0l}{\Rot} \LU{lm}{\Rot}$ | the rotation of the link frame, turned by the rotation $\LU{lm}{\Rot}$ of `localHT`; the local position does not rotate the marker | | marker angular velocity | $\LU{0}{\tomega}_{m} = \LU{0l}{\Rot} \LU{l}{\tomega}_{l}$ | global; the local angular velocity is $\LU{lm}{\Rot}\tp \LU{l}{\tomega}_{l}$ | ### Jacobians The Jacobians have one column per link of the tree, $\qv$ being the joint coordinates. Only the link $n_l$ and its parents down to the base have non-zero columns; for such a link $j$, with its joint axis $\av_j$ and the origin $\LU{0}{\pv}_j$ of its joint frame, both global, $$ \text{revolute:} \quad \Jm_{pos,j} = \av_j \times \left(\LU{0}{\pv}_{m} - \LU{0}{\pv}_j\right) , \quad \Jm_{rot,j} = \av_j ; \qquad \text{prismatic:} \quad \Jm_{pos,j} = \av_j , \quad \Jm_{rot,j} = \Null . $$ A force and a torque on the marker act on the joint coordinates as $\Qm = \Jm_{pos}\tp \LU{0}{\fv} + \Jm_{rot}\tp \LU{0}{\ttau}$. The derivative of the Jacobians is not implemented: a connector that needs it raises an error with this marker; `newton.numericalDifferentiation.forODE2Connectors = True` computes the connector's Jacobian numerically instead. (miniexample-markerkinematictreerigid)= ## Mini example ```python #a rigid body marker on link 0 of a kinematic tree with one prismatic joint along x nTree = mbs.AddNode(NodeGenericODE2(referenceCoordinates=[0.], initialCoordinates=[0.], initialCoordinates_t=[0.], numberOfODE2Coordinates=1)) oTree = mbs.AddObject(ObjectKinematicTree(nodeNumber=nTree, jointTypes=[exu.JointType.PrismaticX], linkParents=[-1], jointTransformations=exu.Matrix3DList([np.eye(3)]), jointOffsets=exu.Vector3DList([[0,0,0]]), linkInertiasCOM=exu.Matrix3DList([np.eye(3)]), linkCOMs=exu.Vector3DList([[0,0,0]]), linkMasses=[2.])) mLink = mbs.AddMarker(MarkerKinematicTreeRigid(objectNumber=oTree, linkNumber=0, localPosition=[0.5,0,0])) mbs.AddLoad(LoadForceVector(markerNumber=mLink, loadVector=[1,0,0])) mbs.Assemble() mbs.SolveDynamic() #q = F/(2m)*t^2 at t=1 exu.sys['testResult'] = mbs.GetNodeOutput(nTree, exu.OutputVariableType.Coordinates) #0.25 ``` Relevant Examples (Ex) and TestModels (TM) with weblink to github: [`humanRobotInteraction.py`](https://github.com/jgerstmayr/EXUDYN/blob/master/python/Examples/humanRobotInteraction.py) (Ex), [`openAIgymNLinkAdvanced.py`](https://github.com/jgerstmayr/EXUDYN/blob/master/python/Examples/openAIgymNLinkAdvanced.py) (Ex), [`reinforcementLearningRobot.py`](https://github.com/jgerstmayr/EXUDYN/blob/master/python/Examples/reinforcementLearningRobot.py) (Ex), [`serialRobotKinematicTreeDigging.py`](https://github.com/jgerstmayr/EXUDYN/blob/master/python/Examples/serialRobotKinematicTreeDigging.py) (Ex), [`stiffFlyballGovernorKT.py`](https://github.com/jgerstmayr/EXUDYN/blob/master/python/Examples/stiffFlyballGovernorKT.py) (Ex), [`kinematicTreeConstraintTest.py`](https://github.com/jgerstmayr/EXUDYN/blob/master/python/TestModels/kinematicTreeConstraintTest.py) (TM), [`kinematicTreePrismaticJacobianTest.py`](https://github.com/jgerstmayr/EXUDYN/blob/master/python/TestModels/kinematicTreePrismaticJacobianTest.py) (TM)