Skip to content
LIBRARY
RevoluteWithLengthConstraint.md

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:

NameDescriptionUnitsDefault value
positive_branchtrue
n_nonzeroStructural 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]
nAxis of rotation, resolved in frame_a/frame_b[0, 0, 1]
phi_offsetRelative angle offset (angle = phi + phi_offset)0
phi_guessGuess value for the revolute angle, used to select the configuration0
length_constraintFixed length of the length constraint1

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)

  • bearing - This connector represents a rotational spline with angle and torque as the potential and flow variables, respectively. (Spline)

Variables

NameDescriptionUnits
tauDriving torque in direction of axis of rotationN.m
phiRelative rotation angle from frame_a to frame_brad
angle= phi + phi_offsetrad
r_aPosition vector to the frame_a side of the length constraint, resolved in frame_am
r_bPosition vector to the frame_b side of the length constraint, resolved in frame_bm

Behavior

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

Source

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


Test Cases

No test cases defined.

  • Examples

  • Experiments

  • Analyses