Revolute
Revolute joint: rotation about a single axis in 3D.
The rooted structural parameter determines which frame is closest to the base of the kinematic tree.
This component extends from PartialTwoFrames This component extends from Renderable This component extends from CutJoint
Usage
MultibodyComponents.Revolute(render=true, color=world_default_joint_color(), specular_coefficient=1.5, n=[0, 0, 1], n_sparse=[n[1] * n_nonzero[1], n[2] * n_nonzero[2], n[3] * n_nonzero[3]], radius=world_default_joint_width() / 2, cylinder_length=world_default_joint_length())
Parameters:
| Name | Description | Units | Default value |
|---|---|---|---|
iscut | – | false | |
residual | – | zeros(3) | |
statePriority | – | 4 | |
rooted | – | MultibodyCo...me.FrameA() | |
n_nonzero | Structural sparsity mask for the rotation axis: element i is true if n[i] may be nonzero. Components marked false are assembled as literal zeros, so the compiler can rely on the sparsity (e.g. avoids forming a dense outer product axis*axis' that defeats codegen). Defaults to all-true (no sparsity assumption). Must be set consistently with n. | – | [true, true, true] |
render | – | true | |
color | – | world_defau...int_color() | |
specular_coefficient | – | 1.5 | |
n | axis of rotation | – | [0, 0, 1] |
radius | Radius of the revolute cylinder in animations | – | world_defau...width() / 2 |
cylinder_length | Length of the revolute cylinder in animations | – | world_defau...nt_length() |
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)support- This connector represents a rotational spline with angle and torque as the potential and flow variables, respectively. (Spline)
Variables
| Name | Description | Units |
|---|---|---|
Rleaf | – | |
Rroot | – | |
phi | Relative rotation angle from frame_a to frame_b | rad |
w | angular velocity (rad/s) | rad/s |
tau | Driving torque in direction of axis of rotation | N.m |
R_rel | – |
Behavior
Dict{MIME{Symbol("text/plain")}, String} with 1 entry: MIME type text/plain => "Error displaying result"
Source
"""
Revolute joint: rotation about a single axis in 3D.
The `rooted` structural parameter determines which frame is closest to the base of the kinematic tree.
"""
component Revolute
extends PartialTwoFrames()
extends Renderable(color = world_default_joint_color())
extends CutJoint()
axis = Spline() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 450, "y1": 450, "x2": 550, "y2": 550, "rot": 0}
},
"tags": []
}
}
support = Spline() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 100, "y1": 450, "x2": 200, "y2": 550, "rot": 0}
},
"tags": []
}
}
# Visualization shape
shape = CylinderShape(render = render, color = color, r = frame_a.r_0, R = transpose(frame_a.R), r_shape = n * (-cylinder_length / 2), length_direction = n, length = cylinder_length, width = 2 * radius, height = 2 * radius)
structural parameter statePriority::Integer = 4 # One higher than prismatic
structural parameter rooted::RootedFrame = MultibodyComponents.RootedFrame.FrameA()
"axis of rotation"
parameter n::Real[3] = [0, 0, 1]
"Structural sparsity mask for the rotation axis: element i is true if n[i] may be nonzero. Components marked false are assembled as literal zeros, so the compiler can rely on the sparsity (e.g. avoids forming a dense outer product axis*axis' that defeats codegen). Defaults to all-true (no sparsity assumption). Must be set consistently with `n`."
structural parameter n_nonzero::Boolean[3] = [true, true, true]
"Rotation axis assembled with the declared sparsity (zeros are structural)."
final parameter n_sparse::Real[3] = [n[1] * n_nonzero[1], n[2] * n_nonzero[2], n[3] * n_nonzero[3]]
"Radius of the revolute cylinder in animations"
parameter radius::Real = world_default_joint_width() / 2
"Length of the revolute cylinder in animations"
parameter cylinder_length::Real = world_default_joint_length()
"Relative rotation angle from frame_a to frame_b"
variable phi::Angle(statePriority = statePriority)
"angular velocity (rad/s)"
variable w::AngularVelocity(statePriority = statePriority)
"Driving torque in direction of axis of rotation"
variable tau::Dyad.Torque
variable R_rel::Real[3, 3]
relations
# Kinematics
der(phi) = w
frame_a.r_0 = frame_b.r_0
# Relative rotation matrix (Rodrigues formula). Uses the sparsity-assembled
# axis so structurally-zero components are literal zeros in axis*axis'.
R_rel = RR(planar_rotation(n_sparse, phi, w))
# Axisflange: axis drives the joint, support is grounded
axis.phi = phi
axis.tau = tau
support.phi = 0
tau = -dot(frame_b.tau, n_sparse)
# Orientation propagation depends on which frame is rooted
switch rooted
case FrameA
# frame_b.R = R_rel * frame_a.R
Rleaf = frame_b.R
Rroot = R_rel * frame_a.R
frame_a.f = -transpose(R_rel) * frame_b.f
frame_a.tau = -transpose(R_rel) * frame_b.tau
case FrameB
# frame_a.R = transpose(R_rel) * frame_b.R
Rleaf = frame_a.R
Rroot = transpose(R_rel) * frame_b.R
frame_b.f = -R_rel * frame_a.f
frame_b.tau = -R_rel * frame_a.tau
end
metadata {
"Dyad": {
"icons": {"default": "dyad://MultibodyComponents/Revolute.svg"},
"labels": [
{
"label": "$(instance)",
"x": 500,
"y": 200,
"rot": 0,
"attrs": {"font-size": "160"}
}
]
}
}
endFlattened Source
"""
Revolute joint: rotation about a single axis in 3D.
The `rooted` structural parameter determines which frame is closest to the base of the kinematic tree.
"""
component Revolute
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": []
}
}
parameter render::Boolean = true
parameter color::Real[4] = [0.5, 0.5, 0.5, 1.0]
parameter specular_coefficient::Real = 1.5
structural parameter iscut::Boolean = false
final structural parameter residual::Real[3] = zeros(3) if iscut
variable Rleaf::Real[3, 3]
variable Rroot::Real[3, 3]
axis = Spline() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 450, "y1": 450, "x2": 550, "y2": 550, "rot": 0}
},
"tags": []
}
}
support = Spline() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 100, "y1": 450, "x2": 200, "y2": 550, "rot": 0}
},
"tags": []
}
}
# Visualization shape
shape = CylinderShape(render = render, color = color, r = frame_a.r_0, R = transpose(frame_a.R), r_shape = n * (-cylinder_length / 2), length_direction = n, length = cylinder_length, width = 2 * radius, height = 2 * radius)
structural parameter statePriority::Integer = 4 # One higher than prismatic
structural parameter rooted::RootedFrame = MultibodyComponents.RootedFrame.FrameA()
"axis of rotation"
parameter n::Real[3] = [0, 0, 1]
"Structural sparsity mask for the rotation axis: element i is true if n[i] may be nonzero. Components marked false are assembled as literal zeros, so the compiler can rely on the sparsity (e.g. avoids forming a dense outer product axis*axis' that defeats codegen). Defaults to all-true (no sparsity assumption). Must be set consistently with `n`."
structural parameter n_nonzero::Boolean[3] = [true, true, true]
"Rotation axis assembled with the declared sparsity (zeros are structural)."
final parameter n_sparse::Real[3] = [n[1] * n_nonzero[1], n[2] * n_nonzero[2], n[3] * n_nonzero[3]]
"Radius of the revolute cylinder in animations"
parameter radius::Real = world_default_joint_width() / 2
"Length of the revolute cylinder in animations"
parameter cylinder_length::Real = world_default_joint_length()
"Relative rotation angle from frame_a to frame_b"
variable phi::Angle(statePriority = statePriority)
"angular velocity (rad/s)"
variable w::AngularVelocity(statePriority = statePriority)
"Driving torque in direction of axis of rotation"
variable tau::Dyad.Torque
variable R_rel::Real[3, 3]
relations
if iscut
residue(Rleaf, Rroot) = residual
else
Rleaf = Rroot
end
# Kinematics
der(phi) = w
frame_a.r_0 = frame_b.r_0
# Relative rotation matrix (Rodrigues formula). Uses the sparsity-assembled
# axis so structurally-zero components are literal zeros in axis*axis'.
R_rel = RR(planar_rotation(n_sparse, phi, w))
# Axisflange: axis drives the joint, support is grounded
axis.phi = phi
axis.tau = tau
support.phi = 0
tau = -dot(frame_b.tau, n_sparse)
# Orientation propagation depends on which frame is rooted
switch rooted
case FrameA
# frame_b.R = R_rel * frame_a.R
Rleaf = frame_b.R
Rroot = R_rel * frame_a.R
frame_a.f = -transpose(R_rel) * frame_b.f
frame_a.tau = -transpose(R_rel) * frame_b.tau
case FrameB
# frame_a.R = transpose(R_rel) * frame_b.R
Rleaf = frame_a.R
Rroot = transpose(R_rel) * frame_b.R
frame_b.f = -R_rel * frame_a.f
frame_b.tau = -R_rel * frame_a.tau
end
metadata {
"Dyad": {
"icons": {"default": "dyad://MultibodyComponents/Revolute.svg"},
"labels": [
{
"label": "$(instance)",
"x": 500,
"y": 200,
"rot": 0,
"attrs": {"font-size": "160"}
}
]
}
}
endTest Cases
No test cases defined.
Related
Examples
Experiments
Analyses
Tests