RevoluteWithLengthConstraint
Revolute joint whose angle is determined analytically by a length constraint rather than being a free state. Used internally by JointUSR (and similar joint assemblies) to solve a kinematic loop in closed form.
The position vectors to the two sides of the length constraint, r_a (resolved in frame_a) and r_b (resolved in frame_b), are supplied by the enclosing assembly. Given the fixed length_constraint, the joint angle is computed with compute_angle; positive_branch selects between the two solutions (elbow up/down).
This component is not balanced on its own — r_a and r_b are inputs that the parent assembly must drive. It is not intended to be used standalone.
This component extends from PartialTwoFrames
Usage
MultibodyComponents.RevoluteWithLengthConstraint(n=[0, 0, 1], n_sparse=[n[1] * n_nonzero[1], n[2] * n_nonzero[2], n[3] * n_nonzero[3]], phi_offset=0, phi_guess=0, length_constraint=1, e=n_sparse / norm_(n_sparse))
Parameters:
| Name | Description | Units | Default value |
|---|---|---|---|
positive_branch | – | true | |
n_nonzero | Structural sparsity mask for the axis: components marked false are assembled as literal zeros (clean axis*axis' in the Rodrigues formula). Must be set consistently with n. | – | [true, true, true] |
n | Axis of rotation, resolved in frame_a/frame_b | – | [0, 0, 1] |
phi_offset | Relative angle offset (angle = phi + phi_offset) | – | 0 |
phi_guess | Guess value for the revolute angle, used to select the configuration | – | 0 |
length_constraint | Fixed length of the length constraint | – | 1 |
Connectors
frame_a- Frame3D is the fundamental 3D connector used for 6DOF motion. Most components have one or severalFrame
connectors that can be connected together (Frame3D)
frame_b- Frame3D is the fundamental 3D connector used for 6DOF motion. Most components have one or severalFrame
connectors that can be connected together (Frame3D)
axis- This connector represents a rotational spline with angle and torque as the potential and flow variables, respectively. (Spline)bearing- This connector represents a rotational spline with angle and torque as the potential and flow variables, respectively. (Spline)
Variables
| Name | Description | Units |
|---|---|---|
tau | Driving torque in direction of axis of rotation | N.m |
phi | Relative rotation angle from frame_a to frame_b | rad |
angle | = phi + phi_offset | rad |
r_a | Position vector to the frame_a side of the length constraint, resolved in frame_a | m |
r_b | Position vector to the frame_b side of the length constraint, resolved in frame_b | m |
Behavior
Dict{MIME{Symbol("text/plain")}, String} with 1 entry: MIME type text/plain => "Error displaying result"
Source
"""
Revolute joint whose angle is determined analytically by a length constraint
rather than being a free state. Used internally by `JointUSR` (and similar
joint assemblies) to solve a kinematic loop in closed form.
The position vectors to the two sides of the length constraint, `r_a` (resolved
in `frame_a`) and `r_b` (resolved in `frame_b`), are supplied by the enclosing
assembly. Given the fixed `length_constraint`, the joint angle is computed with
`compute_angle`; `positive_branch` selects between the two solutions
(elbow up/down).
This component is not balanced on its own — `r_a` and `r_b` are inputs that the
parent assembly must drive. It is not intended to be used standalone.
"""
component RevoluteWithLengthConstraint
extends PartialTwoFrames()
axis = Spline() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 650, "y1": 950, "x2": 750, "y2": 1050, "rot": 0}
},
"tags": []
}
}
bearing = Spline() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 230, "y1": 950, "x2": 330, "y2": 1050, "rot": 0}
},
"tags": []
}
}
structural parameter positive_branch::Boolean = true
"Axis of rotation, resolved in frame_a/frame_b"
parameter n::Real[3] = [0, 0, 1]
"Structural sparsity mask for the axis: components marked false are assembled as literal zeros (clean axis*axis' in the Rodrigues formula). Must be set consistently with `n`."
structural parameter n_nonzero::Boolean[3] = [true, true, true]
final parameter n_sparse::Real[3] = [n[1] * n_nonzero[1], n[2] * n_nonzero[2], n[3] * n_nonzero[3]]
"Relative angle offset (angle = phi + phi_offset)"
parameter phi_offset::Real = 0
"Guess value for the revolute angle, used to select the configuration"
parameter phi_guess::Real = 0
"Fixed length of the length constraint"
parameter length_constraint::Real = 1
final parameter e::Real[3] = n_sparse / norm_(n_sparse)
"Driving torque in direction of axis of rotation"
variable tau::Dyad.Torque
"Relative rotation angle from frame_a to frame_b"
variable phi::Angle
"= phi + phi_offset"
variable angle::Angle
"Position vector to the frame_a side of the length constraint, resolved in frame_a"
variable r_a::Position[3]
"Position vector to the frame_b side of the length constraint, resolved in frame_b"
variable r_b::Position[3]
relations
guess phi = phi_guess
angle = phi + phi_offset
axis.phi = phi
axis.tau = tau
bearing.phi = 0
frame_b.r_0 = frame_a.r_0
RotationMatrix(frame_b.R) = absolute_rotation(frame_a, planar_rotation(e, angle, der(angle)))
[0, 0, 0] = frame_a.f + resolve1(planar_rotation(e, angle, der(angle)), frame_b.f)
[0, 0, 0] = frame_a.tau + resolve1(planar_rotation(e, angle, der(angle)), frame_b.tau)
angle = compute_angle(length_constraint, e, r_a, r_b, positive_branch)
metadata {
"Dyad": {
"icons": {"default": "dyad://MultibodyComponents/RevoluteWithLengthConstraint.svg"},
"labels": [
{
"label": "$(instance)",
"x": 500,
"y": 200,
"rot": 0,
"attrs": {"font-size": "160"}
}
]
}
}
endFlattened Source
"""
Revolute joint whose angle is determined analytically by a length constraint
rather than being a free state. Used internally by `JointUSR` (and similar
joint assemblies) to solve a kinematic loop in closed form.
The position vectors to the two sides of the length constraint, `r_a` (resolved
in `frame_a`) and `r_b` (resolved in `frame_b`), are supplied by the enclosing
assembly. Given the fixed `length_constraint`, the joint angle is computed with
`compute_angle`; `positive_branch` selects between the two solutions
(elbow up/down).
This component is not balanced on its own — `r_a` and `r_b` are inputs that the
parent assembly must drive. It is not intended to be used standalone.
"""
component RevoluteWithLengthConstraint
frame_a = Frame3D() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": -50, "y1": 450, "x2": 50, "y2": 550, "rot": 0}
},
"tags": []
}
}
frame_b = Frame3D() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 950, "y1": 450, "x2": 1050, "y2": 550, "rot": 0}
},
"tags": []
}
}
axis = Spline() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 650, "y1": 950, "x2": 750, "y2": 1050, "rot": 0}
},
"tags": []
}
}
bearing = Spline() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 230, "y1": 950, "x2": 330, "y2": 1050, "rot": 0}
},
"tags": []
}
}
structural parameter positive_branch::Boolean = true
"Axis of rotation, resolved in frame_a/frame_b"
parameter n::Real[3] = [0, 0, 1]
"Structural sparsity mask for the axis: components marked false are assembled as literal zeros (clean axis*axis' in the Rodrigues formula). Must be set consistently with `n`."
structural parameter n_nonzero::Boolean[3] = [true, true, true]
final parameter n_sparse::Real[3] = [n[1] * n_nonzero[1], n[2] * n_nonzero[2], n[3] * n_nonzero[3]]
"Relative angle offset (angle = phi + phi_offset)"
parameter phi_offset::Real = 0
"Guess value for the revolute angle, used to select the configuration"
parameter phi_guess::Real = 0
"Fixed length of the length constraint"
parameter length_constraint::Real = 1
final parameter e::Real[3] = n_sparse / norm_(n_sparse)
"Driving torque in direction of axis of rotation"
variable tau::Dyad.Torque
"Relative rotation angle from frame_a to frame_b"
variable phi::Angle
"= phi + phi_offset"
variable angle::Angle
"Position vector to the frame_a side of the length constraint, resolved in frame_a"
variable r_a::Position[3]
"Position vector to the frame_b side of the length constraint, resolved in frame_b"
variable r_b::Position[3]
relations
guess phi = phi_guess
angle = phi + phi_offset
axis.phi = phi
axis.tau = tau
bearing.phi = 0
frame_b.r_0 = frame_a.r_0
RotationMatrix(frame_b.R) = absolute_rotation(frame_a, planar_rotation(e, angle, der(angle)))
[0, 0, 0] = frame_a.f + resolve1(planar_rotation(e, angle, der(angle)), frame_b.f)
[0, 0, 0] = frame_a.tau + resolve1(planar_rotation(e, angle, der(angle)), frame_b.tau)
angle = compute_angle(length_constraint, e, r_a, r_b, positive_branch)
metadata {
"Dyad": {
"icons": {"default": "dyad://MultibodyComponents/RevoluteWithLengthConstraint.svg"},
"labels": [
{
"label": "$(instance)",
"x": 500,
"y": 200,
"rot": 0,
"attrs": {"font-size": "160"}
}
]
}
}
endTest Cases
No test cases defined.
Related
Examples
Experiments
Analyses