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:
| Name | Description | Units | Default value |
|---|---|---|---|
n1_a | Axis 1 of the universal joint, resolved in frame_a | – | [0, 0, 1] |
nAxis_ia | Axis vector from frame_a origin to frame_b origin, resolved in frame_ia | – | [1, 0, 0] |
s_offset | Relative 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 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)
frame_ia- Frame3D is the fundamental 3D connector used for 6DOF motion. Most components have one or severalFrame
connectors that can be connected together (Frame3D)
frame_ib- 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 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
| Name | Description | Units |
|---|---|---|
s | Relative distance between frame_a and frame_b along the connecting line minus s_offset | m |
f | Driving force in the axis (= axis.f) | N |
axisLength | Distance between frame_a and frame_b | m |
rAxis_0 | Position vector frame_a -> frame_b, resolved in world | m |
rAxis_a | Position vector frame_a -> frame_b, resolved in frame_a | m |
eAxis_a | Unit vector along the connecting line, resolved in frame_a | – |
n2_a | n1_a x eAxis_a (axis 2 of the universal joint), resolved in frame_a | – |
length2_n2_a | Squared length of n2_a | – |
length_n2_a | Length of n2_a | – |
e2_a | Unit vector along axis 2 of the universal joint, resolved in frame_a | – |
e3_a | Unit vector perpendicular to eAxis_a and e2_a, resolved in frame_a | – |
der_rAxis_a_L | der(rAxis_a) / axisLength | – |
w_rel_ia1 | Angular velocity of intermediate frame ia1 wrt frame_a, in ia1 basis | – |
f_c_a | frame_ia.f resolved in frame_a | – |
t_cd_a | frame_ia.tau + frame_ib.tau resolved in frame_a | – |
f_bd_a | frame_b.f + frame_ib.f resolved in frame_a (without spherical reaction) | – |
Behavior
Source
"""
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"}
}
]
}
}
endFlattened Source
"""
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"}
}
]
}
}
endTest Cases
No test cases defined.
Related
Examples
Experiments
Analyses