Skip to content
LIBRARY
JointUPS.md

JointUPS

Universal - prismatic - spherical joint aggregation. A universal joint at frame_a, a spherical joint at frame_b, and a prismatic joint along the line connecting the two frame origins. This joint aggregation has no mass and no inertia and introduces neither constraints nor potential state variables; it is mainly useful for building force elements along the connecting line (the distance between the frames is exposed through the axis/bearing flanges, with driving force f). frame_ia is fixed on the connecting line at frame_a; frame_ib is fixed on the line at frame_b and is always parallel to frame_ia. There is a singularity when axis n1_a is parallel to the connecting line.

This component extends from PartialTwoFrames

Usage

MultibodyComponents.JointUPS(n1_a=[0, 0, 1], nAxis_ia=[1, 0, 0], s_offset=0, eAxis_ia=nAxis_ia / norm_(nAxis_ia), e2_ia=cross(n1_a, eAxis_ia) / norm_(cross(n1_a, eAxis_ia)), e3_ia=cross(eAxis_ia, e2_ia))

Parameters:

NameDescriptionUnitsDefault value
n1_aAxis 1 of the universal joint, resolved in frame_a[0, 0, 1]
nAxis_iaAxis vector from frame_a origin to frame_b origin, resolved in frame_ia[1, 0, 0]
s_offsetRelative distance offset (distance between frame_a and frame_b = s + s_offset)0

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)

  • frame_ia - 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_ib - 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 mechanical flange with position and force as the potential and flow variables, respectively. (Flange)

  • bearing - This connector represents a mechanical flange with position and force as the potential and flow variables, respectively. (Flange)

Variables

NameDescriptionUnits
sRelative distance between frame_a and frame_b along the connecting line minus s_offsetm
fDriving force in the axis (= axis.f)N
axisLengthDistance between frame_a and frame_bm
rAxis_0Position vector frame_a -> frame_b, resolved in worldm
rAxis_aPosition vector frame_a -> frame_b, resolved in frame_am
eAxis_aUnit vector along the connecting line, resolved in frame_a
n2_an1_a x eAxis_a (axis 2 of the universal joint), resolved in frame_a
length2_n2_aSquared length of n2_a
length_n2_aLength of n2_a
e2_aUnit vector along axis 2 of the universal joint, resolved in frame_a
e3_aUnit vector perpendicular to eAxis_a and e2_a, resolved in frame_a
der_rAxis_a_Lder(rAxis_a) / axisLength
w_rel_ia1Angular velocity of intermediate frame ia1 wrt frame_a, in ia1 basis
f_c_aframe_ia.f resolved in frame_a
t_cd_aframe_ia.tau + frame_ib.tau resolved in frame_a
f_bd_aframe_b.f + frame_ib.f resolved in frame_a (without spherical reaction)

Behavior

Source

dyad
"""
Universal - prismatic - spherical joint aggregation. A universal joint at
`frame_a`, a spherical joint at `frame_b`, and a prismatic joint along the line
connecting the two frame origins. This joint aggregation has no mass and no
inertia and introduces neither constraints nor potential state variables; it is
mainly useful for building force elements along the connecting line (the distance
between the frames is exposed through the `axis`/`bearing` flanges, with driving
force `f`). `frame_ia` is fixed on the connecting line at `frame_a`; `frame_ib` is
fixed on the line at `frame_b` and is always parallel to `frame_ia`. There is a
singularity when axis `n1_a` is parallel to the connecting line.
"""
component JointUPS
  extends PartialTwoFrames()
  "Frame fixed on the connecting line at the origin of frame_a"
  frame_ia = Frame3D() {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 280, "y1": 450, "x2": 380, "y2": 550, "rot": 0}
      },
      "tags": []
    }
  }
  "Frame fixed on the connecting line at the origin of frame_b (parallel to frame_ia)"
  frame_ib = Frame3D() {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 610, "y1": 450, "x2": 710, "y2": 550, "rot": 0}
      },
      "tags": []
    }
  }
  "Translational flange that drives the prismatic joint"
  axis = Flange() {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 680, "y1": 950, "x2": 780, "y2": 1050, "rot": 0}
      },
      "tags": []
    }
  }
  "Translational flange of the prismatic joint bearing"
  bearing = Flange() {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 210, "y1": 950, "x2": 310, "y2": 1050, "rot": 0}
      },
      "tags": []
    }
  }
  "Axis 1 of the universal joint, resolved in frame_a"
  parameter n1_a::Real[3] = [0, 0, 1]
  "Axis vector from frame_a origin to frame_b origin, resolved in frame_ia"
  parameter nAxis_ia::Real[3] = [1, 0, 0]
  "Relative distance offset (distance between frame_a and frame_b = s + s_offset)"
  parameter s_offset::Real = 0
  final parameter eAxis_ia::Real[3] = nAxis_ia / norm_(nAxis_ia)
  final parameter e2_ia::Real[3] = cross(n1_a, eAxis_ia) / norm_(cross(n1_a, eAxis_ia))
  final parameter e3_ia::Real[3] = cross(eAxis_ia, e2_ia)
  "Relative distance between frame_a and frame_b along the connecting line minus s_offset"
  variable s::Length
  "Driving force in the axis (= axis.f)"
  variable f::Dyad.Force
  "Distance between frame_a and frame_b"
  variable axisLength::Length
  "Position vector frame_a -> frame_b, resolved in world"
  variable rAxis_0::Position[3]
  "Position vector frame_a -> frame_b, resolved in frame_a"
  variable rAxis_a::Position[3]
  "Unit vector along the connecting line, resolved in frame_a"
  variable eAxis_a::Real[3]
  "n1_a x eAxis_a (axis 2 of the universal joint), resolved in frame_a"
  variable n2_a::Real[3]
  "Squared length of n2_a"
  variable length2_n2_a::Real
  "Length of n2_a"
  variable length_n2_a::Real
  "Unit vector along axis 2 of the universal joint, resolved in frame_a"
  variable e2_a::Real[3]
  "Unit vector perpendicular to eAxis_a and e2_a, resolved in frame_a"
  variable e3_a::Real[3]
  "der(rAxis_a) / axisLength"
  variable der_rAxis_a_L::Real[3]
  "Angular velocity of intermediate frame ia1 wrt frame_a, in ia1 basis"
  variable w_rel_ia1::Real[3]
  "frame_ia.f resolved in frame_a"
  variable f_c_a::Real[3]
  "frame_ia.tau + frame_ib.tau resolved in frame_a"
  variable t_cd_a::Real[3]
  "frame_b.f + frame_ib.f resolved in frame_a (without spherical reaction)"
  variable f_bd_a::Real[3]
relations
  guess s = 1
  axisLength = s + s_offset
  bearing.s = 0
  axis.s = s
  axis.f = f
  rAxis_0 = frame_b.r_0 - frame_a.r_0
  rAxis_a = resolve2(frame_a.R, rAxis_0)
  axisLength = sqrt(dot(rAxis_0, rAxis_0))
  eAxis_a = rAxis_a / axisLength
  n2_a = cross(n1_a, eAxis_a)
  length2_n2_a = dot(n2_a, n2_a)
  length_n2_a = sqrt(length2_n2_a)
  e2_a = n2_a / length_n2_a
  e3_a = cross(eAxis_a, e2_a)
  der_rAxis_a_L = (resolve2(frame_a.R, der(rAxis_0)) - cross(angular_velocity2(ori(frame_a)), rAxis_a)) / axisLength
  w_rel_ia1 = [dot(e3_a, cross(n1_a, der_rAxis_a_L)) / length_n2_a, -dot(e3_a, der_rAxis_a_L), dot(e2_a, der_rAxis_a_L)]
  frame_ia.r_0 = frame_a.r_0
  frame_ib.r_0 = frame_b.r_0
  RotationMatrix(frame_ia.R) = absolute_rotation(frame_a, R_rel_ia_from(eAxis_a, e2_a, e3_a, eAxis_ia, e2_ia, e3_ia, w_rel_ia1))
  RotationMatrix(frame_ib.R) = ori(frame_ia)
  f_c_a = resolve1(R_rel_ia_from(eAxis_a, e2_a, e3_a, eAxis_ia, e2_ia, e3_ia, w_rel_ia1), frame_ia.f)
  t_cd_a = resolve1(R_rel_ia_from(eAxis_a, e2_a, e3_a, eAxis_ia, e2_ia, e3_ia, w_rel_ia1), frame_ia.tau + frame_ib.tau)
  f_bd_a = -eAxis_a * f - e2_a * (dot(n1_a, t_cd_a) / (axisLength * dot(n1_a, e3_a))) + e3_a * (dot(e2_a, t_cd_a) / axisLength)
  [0, 0, 0] = frame_b.f + resolve_relative(frame_ib.f, frame_ib.R, frame_b.R) - resolve_relative(f_bd_a, frame_a.R, frame_b.R)
  [0, 0, 0] = frame_b.tau
  [0, 0, 0] = frame_a.f + f_c_a + f_bd_a
  [0, 0, 0] = frame_a.tau + t_cd_a + cross(rAxis_a, f_bd_a)
metadata {
  "Dyad": {
    "icons": {"default": "dyad://MultibodyComponents/JointUPS.svg"},
    "labels": [
      {
        "label": "$(instance)",
        "x": 500,
        "y": 200,
        "rot": 0,
        "attrs": {"font-size": "160"}
      }
    ]
  }
}
end
Flattened Source
dyad
"""
Universal - prismatic - spherical joint aggregation. A universal joint at
`frame_a`, a spherical joint at `frame_b`, and a prismatic joint along the line
connecting the two frame origins. This joint aggregation has no mass and no
inertia and introduces neither constraints nor potential state variables; it is
mainly useful for building force elements along the connecting line (the distance
between the frames is exposed through the `axis`/`bearing` flanges, with driving
force `f`). `frame_ia` is fixed on the connecting line at `frame_a`; `frame_ib` is
fixed on the line at `frame_b` and is always parallel to `frame_ia`. There is a
singularity when axis `n1_a` is parallel to the connecting line.
"""
component JointUPS
  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": []
    }
  }
  "Frame fixed on the connecting line at the origin of frame_a"
  frame_ia = Frame3D() {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 280, "y1": 450, "x2": 380, "y2": 550, "rot": 0}
      },
      "tags": []
    }
  }
  "Frame fixed on the connecting line at the origin of frame_b (parallel to frame_ia)"
  frame_ib = Frame3D() {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 610, "y1": 450, "x2": 710, "y2": 550, "rot": 0}
      },
      "tags": []
    }
  }
  "Translational flange that drives the prismatic joint"
  axis = Flange() {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 680, "y1": 950, "x2": 780, "y2": 1050, "rot": 0}
      },
      "tags": []
    }
  }
  "Translational flange of the prismatic joint bearing"
  bearing = Flange() {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 210, "y1": 950, "x2": 310, "y2": 1050, "rot": 0}
      },
      "tags": []
    }
  }
  "Axis 1 of the universal joint, resolved in frame_a"
  parameter n1_a::Real[3] = [0, 0, 1]
  "Axis vector from frame_a origin to frame_b origin, resolved in frame_ia"
  parameter nAxis_ia::Real[3] = [1, 0, 0]
  "Relative distance offset (distance between frame_a and frame_b = s + s_offset)"
  parameter s_offset::Real = 0
  final parameter eAxis_ia::Real[3] = nAxis_ia / norm_(nAxis_ia)
  final parameter e2_ia::Real[3] = cross(n1_a, eAxis_ia) / norm_(cross(n1_a, eAxis_ia))
  final parameter e3_ia::Real[3] = cross(eAxis_ia, e2_ia)
  "Relative distance between frame_a and frame_b along the connecting line minus s_offset"
  variable s::Length
  "Driving force in the axis (= axis.f)"
  variable f::Dyad.Force
  "Distance between frame_a and frame_b"
  variable axisLength::Length
  "Position vector frame_a -> frame_b, resolved in world"
  variable rAxis_0::Position[3]
  "Position vector frame_a -> frame_b, resolved in frame_a"
  variable rAxis_a::Position[3]
  "Unit vector along the connecting line, resolved in frame_a"
  variable eAxis_a::Real[3]
  "n1_a x eAxis_a (axis 2 of the universal joint), resolved in frame_a"
  variable n2_a::Real[3]
  "Squared length of n2_a"
  variable length2_n2_a::Real
  "Length of n2_a"
  variable length_n2_a::Real
  "Unit vector along axis 2 of the universal joint, resolved in frame_a"
  variable e2_a::Real[3]
  "Unit vector perpendicular to eAxis_a and e2_a, resolved in frame_a"
  variable e3_a::Real[3]
  "der(rAxis_a) / axisLength"
  variable der_rAxis_a_L::Real[3]
  "Angular velocity of intermediate frame ia1 wrt frame_a, in ia1 basis"
  variable w_rel_ia1::Real[3]
  "frame_ia.f resolved in frame_a"
  variable f_c_a::Real[3]
  "frame_ia.tau + frame_ib.tau resolved in frame_a"
  variable t_cd_a::Real[3]
  "frame_b.f + frame_ib.f resolved in frame_a (without spherical reaction)"
  variable f_bd_a::Real[3]
relations
  guess s = 1
  axisLength = s + s_offset
  bearing.s = 0
  axis.s = s
  axis.f = f
  rAxis_0 = frame_b.r_0 - frame_a.r_0
  rAxis_a = resolve2(frame_a.R, rAxis_0)
  axisLength = sqrt(dot(rAxis_0, rAxis_0))
  eAxis_a = rAxis_a / axisLength
  n2_a = cross(n1_a, eAxis_a)
  length2_n2_a = dot(n2_a, n2_a)
  length_n2_a = sqrt(length2_n2_a)
  e2_a = n2_a / length_n2_a
  e3_a = cross(eAxis_a, e2_a)
  der_rAxis_a_L = (resolve2(frame_a.R, der(rAxis_0)) - cross(angular_velocity2(ori(frame_a)), rAxis_a)) / axisLength
  w_rel_ia1 = [dot(e3_a, cross(n1_a, der_rAxis_a_L)) / length_n2_a, -dot(e3_a, der_rAxis_a_L), dot(e2_a, der_rAxis_a_L)]
  frame_ia.r_0 = frame_a.r_0
  frame_ib.r_0 = frame_b.r_0
  RotationMatrix(frame_ia.R) = absolute_rotation(frame_a, R_rel_ia_from(eAxis_a, e2_a, e3_a, eAxis_ia, e2_ia, e3_ia, w_rel_ia1))
  RotationMatrix(frame_ib.R) = ori(frame_ia)
  f_c_a = resolve1(R_rel_ia_from(eAxis_a, e2_a, e3_a, eAxis_ia, e2_ia, e3_ia, w_rel_ia1), frame_ia.f)
  t_cd_a = resolve1(R_rel_ia_from(eAxis_a, e2_a, e3_a, eAxis_ia, e2_ia, e3_ia, w_rel_ia1), frame_ia.tau + frame_ib.tau)
  f_bd_a = -eAxis_a * f - e2_a * (dot(n1_a, t_cd_a) / (axisLength * dot(n1_a, e3_a))) + e3_a * (dot(e2_a, t_cd_a) / axisLength)
  [0, 0, 0] = frame_b.f + resolve_relative(frame_ib.f, frame_ib.R, frame_b.R) - resolve_relative(f_bd_a, frame_a.R, frame_b.R)
  [0, 0, 0] = frame_b.tau
  [0, 0, 0] = frame_a.f + f_c_a + f_bd_a
  [0, 0, 0] = frame_a.tau + t_cd_a + cross(rAxis_a, f_bd_a)
metadata {
  "Dyad": {
    "icons": {"default": "dyad://MultibodyComponents/JointUPS.svg"},
    "labels": [
      {
        "label": "$(instance)",
        "x": 500,
        "y": 200,
        "rot": 0,
        "attrs": {"font-size": "160"}
      }
    ]
  }
}
end


Test Cases

No test cases defined.

  • Examples

  • Experiments

  • Analyses