Skip to content
LIBRARY
Revolute.md

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:

NameDescriptionUnitsDefault value
iscutfalse
residualzeros(3)
statePriority4
rootedMultibodyCo...me.FrameA()
n_nonzeroStructural 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]
rendertrue
colorworld_defau...int_color()
specular_coefficient1.5
naxis of rotation[0, 0, 1]
radiusRadius of the revolute cylinder in animationsworld_defau...width() / 2
cylinder_lengthLength of the revolute cylinder in animationsworld_defau...nt_length()

Connectors

  • frame_a - Frame3D is the fundamental 3D connector used for 6DOF motion. Most components have one or several Frame

connectors that can be connected together (Frame3D)

  • frame_b - Frame3D is the fundamental 3D connector used for 6DOF motion. Most components have one or several Frame

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

NameDescriptionUnits
Rleaf
Rroot
phiRelative rotation angle from frame_a to frame_brad
wangular velocity (rad/s)rad/s
tauDriving torque in direction of axis of rotationN.m
R_rel

Behavior

Dict{MIME{Symbol("text/plain")}, String} with 1 entry: MIME type text/plain => "Error displaying result"

Source

dyad
"""
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"}
      }
    ]
  }
}
end
Flattened Source
dyad
"""
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"}
      }
    ]
  }
}
end


Test Cases

No test cases defined.