ObjectConnectorCoordinateVector
A constraint which constrains the coordinate vectors of two markers Marker[Node|Object|Body]Coordinates attached to nodes or bodies. The marker uses the objects LTG-lists to build the according coordinate mappings.
Interface
Python names:
ObjectConnectorCoordinateVectororCoordinateVectorConstraint, andVCoordinateVectorConstraintfor its visualizationMarkers it acts on: those providing
Coordinates: MarkerNodeCoordinates, MarkerObjectODE2Coordinates
Parameters
The parameters of the item; in a dictionary, its type is ‘ConnectorCoordinateVector’:
name |
type |
size |
default |
description |
|---|---|---|---|---|
name |
String |
‘’ |
constraints’s unique name |
|
markerNumbers |
ArrayMarkerIndex |
[ invalid (-1), invalid (-1) ] |
(symbol: \([m0,m1]\tp\)) list of markers used in connector |
|
scalingMarker0 |
NumpyMatrix |
[] |
(symbol: \(\Xm_{m0} \in \Rcal^{n_{ae} \times n_{q_{m0}}}\)) linear scaling matrix for coordinate vector of marker 0; matrix provided in Python numpy format |
|
scalingMarker1 |
NumpyMatrix |
[] |
(symbol: \(\Xm_{m1} \in \Rcal^{n_{ae} \times n_{q_{m1}}}\)) linear scaling matrix for coordinate vector of marker 1; matrix provided in Python numpy format |
|
quadraticTermMarker0 |
NumpyMatrix |
[] |
(symbol: \(\Ym_{m0} \in \Rcal^{n_{ae} \times n_{q_{m0}}}\)) quadratic scaling matrix for coordinate vector of marker 0; matrix provided in Python numpy format |
|
quadraticTermMarker1 |
NumpyMatrix |
[] |
(symbol: \(\Ym_{m0} \in \Rcal^{n_{ae} \times n_{q_{m0}}}\)) quadratic scaling matrix for coordinate vector of marker 1; matrix provided in Python numpy format |
|
offset |
NumpyVector |
[] |
(symbol: \(\vv_\mathrm{off} \in \Rcal^{n_{ae}}\)) offset added to constraint equation; only active, if no userFunction is defined |
|
velocityLevel |
Bool |
False |
If true: connector constrains velocities (only works for ODE2 coordinates!); offset is used between velocities; in this case, the offsetUserFunction_t is considered and offsetUserFunction is ignored |
|
constraintUserFunction |
ObjectConnectorCoordinateVectorConstraintUserFunction |
0 |
(symbol: \(\cv_{user} \in \Rcal^{n_{ae}}\)) A Python user function which computes the constraint equations; to define the number of algebraic equations, set scalingMarker0 as a numpy.zeros((nAE,1)) array with nAE being the number algebraic equations; see description below |
|
jacobianUserFunction |
ObjectConnectorCoordinateVectorJacobianUserFunction |
0 |
(symbol: \(\Jm_{user} \in \Rcal^{(n_{q_{m0}}+n_{q_{m1}}) \times n_{ae}}\)) A Python user function which computes the jacobian, i.e., the derivative of the left-hand-side object equation w.r.t. the coordinates (times \(f_{ODE2}\)) and w.r.t. the velocities (times \(f_{ODE2_t}\)). Terms on the RHS must be subtracted from the LHS equation; the respective terms for the stiffness matrix and damping matrix are automatically added; see description below |
|
activeConnector |
Bool |
True |
flag, which determines, if the connector is active; used to deactivate (temporarily) a connector or constraint |
|
visualization |
VObjectConnectorCoordinateVector |
parameters for visualization of item |
Visualization parameters
VObjectConnectorCoordinateVector has no parameters.
Drawing
The item draws nothing.
Output variables
Available as OutputVariableType in sensors, Get...Output() and other functions:
output variable |
symbol |
description |
|---|---|---|
Displacement |
\(\Delta \qv\) |
relative scalar displacement of marker coordinates, not including scaling matrices |
Velocity |
\(\Delta \vv\) |
difference of scalar marker velocity coordinates, not including scaling matrices |
ConstraintEquation |
\(\cv\) |
(residuum of) constraint equations |
Force |
\(\tlambda\) |
constraint force vector (vector of Lagrange multipliers), resulting from action of constraint equations |
Detailed description
Definition of quantities
intermediate variables |
symbol |
description |
|---|---|---|
marker m0 coordinate vector |
\(\qv_{m0} \in \Rcal^{n_{q_{m0}}}\) |
coordinate vector provided by marker \(m0\); depending on the marker, the coordinates may or may not include reference coordinates |
marker m1 coordinate vector |
\(\qv_{m1} \in \Rcal^{n_{q_{m1}}}\) |
coordinate vector provided by marker \(m1\); depending on the marker, the coordinates may or may not include reference coordinates |
marker m0 velocity coordinate vector |
\(\dot \qv_{m0} \in \Rcal^{n_{q_{m0}}}\) |
velocity coordinate vector provided by marker \(m0\) |
marker m1 velocity coordinate vector |
\(\dot \qv_{m1} \in \Rcal^{n_{q_{m1}}}\) |
velocity coordinate vector provided by marker \(m1\) |
number of algebraic equations |
\(n_{ae}\) |
number of algebraic equations must be same as number of rows in \(\Xm_{m0}\) and \(\Xm_{m1}\) |
difference of coordinates |
\(\Delta \qv = \qv_{m1} - \qv_{m0}\) |
Displacement between marker m0 to marker m1 coordinates |
difference of velocity coordinates |
\(\Delta \vv= \dot \qv_{m1} - \dot \qv_{m0}\) |
Remarks
The number of algebraic equations depends on the maximum number of rows in \(\Xm_{m0}\), \(\Ym_{m0}\), \(\Xm_{m1}\) and \(\Ym_{m1}\). The number of rows of the latter matrices must either be zero or the maximum of these rows.
The number of columns in \(\Xm_{m0}\) (or \(\Ym_{m0}\)) must agree with the length of the coordinate vector \(\qv_{m0}\) and the number of columns in \(\Xm_{m1}\) (or \(\Ym_{m1}\)) must agree with the length of the coordinate vector \(\qv_{m1}\), if these matrices are not empty matrices. If one marker \(k\) is a ground marker (node/object), the length of \(\qv_{m,k}\) is zero and also the according matrices \(\Xm_{m,k}\), \(\Ym_{m,k}\) have zero size and will not be considered in the computation of the constraint equations.
Connector constraint equations
If activeConnector = True and no constraintUserFunction is defined, the index 3 algebraic equations
Note that the squared coordinates are understood as \(\qv^2_{m0} = [q^2_{0,m0}, \; q^2_{1,m0}, \; \ldots]\tp\), same for \(\qv^2_{m1}\).
The index 2 (velocity level) algebraic equation accordingly reads
The vector \(\dv\) in velocity level equations is zero, except if parameters.velocityLevel = True, then \(\dv=\vv_\mathrm{off}\).
Note that the index 2 equations are used, if the solver uses index 2 formulation OR if the flag parameters.velocityLevel = True (or both).
However, the constraintUserFunction has to be chosen accordingly by the user, either as position or as velocity level.
The user functions include dependency on time \(t\), but this time dependency is not respected in the computation of initial accelerations. Therefore,
If activeConnector = False, the (index 1) algebraic equation reads for ALL cases:
If a constraintUserFunction is defined, it also requires an according jacobianUserFunction (and vice versa).
Userfunction: constraintUserFunction(mbs, t, itemNumber, q, q_t, velocityLevel)
A user function, which computes algebraic equations for the connector based on the marker coordinates stored in q and q_t.
Depending on velocityLevel, the user function needs to compute either the position-level (velocityLevel=False) or
the velocity level (velocityLevel=True) constraint equations.
Note that for Index 2 solvers, the constraintUserFunction may be called with velocityLevel=True but jacobianUserFunction
is called with velocityLevel=False.
To define the number of algebraic equations, set scalingMarker0 as a numpy.zeros((nAE,1)) array with nAE being the number algebraic equations.
The returned vector of constraintUserFunction must have size nAE.
Note that itemNumber represents the index of the ObjectGenericODE2 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 |
|---|---|---|
|
MainSystem |
provides MainSystem mbs to which object belongs to |
|
Real |
current time in mbs |
|
Index |
integer number \(i_N\) of the object in mbs, allowing easy access to all object data via mbs.GetObjectParameter(itemNumber, …) |
|
Vector \(\in \Rcal^{(n_{q_{m0}}+n_{q_{m1}})}\) |
connector coordinates, subsequently for marker \(m0\) and marker \(m1\), in current configuration |
|
Vector \(\in \Rcal^{(n_{q_{m0}}+n_{q_{m1}})}\) |
connector velocity coordinates in current configuration |
|
Bool |
velocityLevel as currently stored in connector |
return value |
Vector \(\in \Rcal^{n_{ae}}\) |
returns vector (numpy array or list) of evaluated constraint equations for connector |
Userfunction: jacobianUserFunction(mbs, t, itemNumber, q, q_t, velocityLevel)
A user function, which computes the jacobian of the algebraic equations w.r.t. the ODE2 coordiantes (ODE2_t velocity coordinates if velocityLevel=True).
The jacobian needs to exactly represent the derivative of the constraintUserFunction.
The returned matrix of jacobianUserFunction must have nAE rows and len(q) columns.
arguments / return |
type or size |
description |
|---|---|---|
|
MainSystem |
provides MainSystem mbs to which object belongs to |
|
Real |
current time in mbs |
|
Index |
integer number \(i_N\) of the object in mbs, allowing easy access to all object data via mbs.GetObjectParameter(itemNumber, …) |
|
Vector \(\in \Rcal^{(n_{q_{m0}}+n_{q_{m1}})}\) |
connector coordinates, subsequently for marker \(m0\) and marker \(m1\), in current configuration |
|
Vector \(\in \Rcal^{(n_{q_{m0}}+n_{q_{m1}})}\) |
connector velocity coordinates in current configuration |
|
Bool |
velocityLevel as currently stored in connector |
return value |
MatrixContainer \(\in \Rcal^{(n_{q_{m0}}+n_{q_{m1}})\times n_{ae}}\) |
returns special jacobian for connector, as exu.MatrixContainer, numpy array or list of lists; use MatrixContainer sparse format for larger matrices to speed up computations; sparse triplets MAY NOT contain zero values! |
Mini example
#all coordinates of two nodes, tied by a coordinate vector constraint X1 qB - X0 qA = offset; the
#coordinates INCLUDE the reference values, so qB - qA = [1,0,0] keeps the two points where they are
nA = mbs.AddNode(NodePoint(referenceCoordinates=[0,0,0]))
nB = mbs.AddNode(NodePoint(referenceCoordinates=[1,0,0]))
mbs.AddObject(ObjectMassPoint(nodeNumber=nA, mass=1))
mbs.AddObject(ObjectMassPoint(nodeNumber=nB, mass=1))
mA = mbs.AddMarker(MarkerNodeCoordinates(nodeNumber=nA))
mB = mbs.AddMarker(MarkerNodeCoordinates(nodeNumber=nB))
mbs.AddObject(ObjectConnectorCoordinateVector(markerNumbers=[mA, mB], scalingMarker0=np.eye(3),
scalingMarker1=np.eye(3), offset=[1,0,0]))
mbs.AddLoad(LoadForceVector(markerNumber=mbs.AddMarker(MarkerNodePosition(nodeNumber=nA)), loadVector=[2,0,0]))
mbs.Assemble()
mbs.SolveDynamic()
#both masses move together: a = F/(2m) = 1, x = a/2*t^2 at t=1
exu.sys['testResult'] = mbs.GetNodeOutput(nB, exu.OutputVariableType.Displacement)[0] #0.5
Relevant Examples (Ex) and TestModels (TM) with weblink to github: coordinateVectorConstraint.py (TM), coordinateVectorConstraintGenericODE2.py (TM), rigidBodyAsUserFunctionTest.py (TM)