JointRRR
Joint assembly of three revolute joints with parallel axes (hence RRR), connected by two rigid rods. It is built on top of JointUSR (the universal joint there acts as the first two parallel-axis revolutes), so the non-linear loop closure is solved analytically.
The assembly has no mass and no inertia and introduces neither constraints nor potential states. Use it to close planar kinematic loops: it is far more efficient than the equivalent loop built from basic joints plus a cut joint.
Two configurations satisfy the constraints; positive_branch selects which one (elbow up/down), and phi_guess seeds the revolute angle.
This component extends from PartialTwoFrames
Usage
MultibodyComponents.JointRRR(n_a=[0, 0, 1], n_b=[0, 0, 1], rRod1_ia=[1, 0, 0], rRod2_ib=[-1, 0, 0], phi_offset=0, phi_guess=0, rod_radius=0.05, rod_color=[0.5, 0, 0.5, 1])
Parameters:
| Name | Description | Units | Default value |
|---|---|---|---|
positive_branch | – | true | |
n_b_nonzero | Structural sparsity mask for the frame_b revolute axis (threaded to the analytic revolute via JointUSR). | – | [true, true, true] |
n_a | Axis of the revolute joints, resolved in frame_a | – | [0, 0, 1] |
n_b | Axis of the revolute joint at frame_b, resolved in frame_b | – | [0, 0, 1] |
rRod1_ia | Vector from frame_a origin to the middle revolute joint, resolved in frame_ia | – | [1, 0, 0] |
rRod2_ib | Vector from frame_ib origin to the middle revolute joint, resolved in frame_ib | – | [-1, 0, 0] |
phi_offset | Relative angle offset of the revolute joint | – | 0 |
phi_guess | Guess value for the revolute angle at the initial time | – | 0 |
rod_radius | Rendering radius of the rods | – | 0.05 |
rod_color | RGBA color of the rods | – | [0.5, 0, 0.5, 1] |
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)
frame_im- 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)bearing- This connector represents a rotational spline with angle and torque as the potential and flow variables, respectively. (Spline)
Behavior
Source
"""
Joint assembly of three revolute joints with parallel axes (hence RRR),
connected by two rigid rods. It is built on top of `JointUSR` (the universal
joint there acts as the first two parallel-axis revolutes), so the non-linear
loop closure is solved analytically.
The assembly has no mass and no inertia and introduces neither constraints nor
potential states. Use it to close planar kinematic loops: it is far more
efficient than the equivalent loop built from basic joints plus a cut joint.
Two configurations satisfy the constraints; `positive_branch` selects which one
(elbow up/down), and `phi_guess` seeds the revolute angle.
"""
component JointRRR
extends PartialTwoFrames()
"Frame fixed in rod1 at the origin of frame_a"
frame_ia = Frame3D() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 290, "y1": 450, "x2": 390, "y2": 550, "rot": 0}
},
"tags": []
}
}
"Frame fixed in rod2 at the first-rod side of the middle revolute joint"
frame_ib = Frame3D() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 630, "y1": 450, "x2": 730, "y2": 550, "rot": 0}
},
"tags": []
}
}
"Frame fixed in rod2 at the middle revolute joint"
frame_im = Frame3D() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 450, "y1": 450, "x2": 550, "y2": 550, "rot": 0}
},
"tags": []
}
}
"Rotational flange driving the revolute joint at frame_b"
axis = Spline() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 690, "y1": 950, "x2": 790, "y2": 1050, "rot": 0}
},
"tags": []
}
}
"Rotational flange of the revolute joint bearing"
bearing = Spline() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 210, "y1": 950, "x2": 310, "y2": 1050, "rot": 0}
},
"tags": []
}
}
jointUSR = JointUSR(n1_a = n_a, n_b = n_b, n_b_nonzero = n_b_nonzero, rRod1_ia = rRod1_ia, rRod2_ib = rRod2_ib, phi_offset = phi_offset, phi_guess = phi_guess, positive_branch = positive_branch, rod_radius = rod_radius, rod_color = rod_color) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 450, "y1": 610, "x2": 550, "y2": 710, "rot": 0}
},
"tags": []
}
}
structural parameter positive_branch::Boolean = true
"Axis of the revolute joints, resolved in frame_a"
parameter n_a::Real[3] = [0, 0, 1]
"Axis of the revolute joint at frame_b, resolved in frame_b"
parameter n_b::Real[3] = [0, 0, 1]
"Structural sparsity mask for the frame_b revolute axis (threaded to the analytic revolute via JointUSR)."
structural parameter n_b_nonzero::Boolean[3] = [true, true, true]
"Vector from frame_a origin to the middle revolute joint, resolved in frame_ia"
parameter rRod1_ia::Real[3] = [1, 0, 0]
"Vector from frame_ib origin to the middle revolute joint, resolved in frame_ib"
parameter rRod2_ib::Real[3] = [-1, 0, 0]
"Relative angle offset of the revolute joint"
parameter phi_offset::Real = 0
"Guess value for the revolute angle at the initial time"
parameter phi_guess::Real = 0
"Rendering radius of the rods"
parameter rod_radius::Real = 0.05
"RGBA color of the rods"
parameter rod_color::Real[4] = [0.5, 0, 0.5, 1]
relations
connect(jointUSR.frame_a, frame_a) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 225, "y": 660}, {"x": 225, "y": 500}], "E": 2}],
"renderStyle": "standard"
}
}
connect(jointUSR.frame_b, frame_b) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 775, "y": 660}, {"x": 775, "y": 500}], "E": 2}],
"renderStyle": "standard"
}
}
connect(jointUSR.frame_ia, frame_ia) {
"Dyad": {
"edges": [
{
"S": 1,
"M": [{"x": 475, "y": 610}, {"x": 380, "y": 610}, {"x": 380, "y": 500}],
"E": 2
}
],
"renderStyle": "standard"
}
}
connect(jointUSR.frame_im, frame_im) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
connect(jointUSR.frame_ib, frame_ib) {
"Dyad": {
"edges": [
{
"S": 1,
"M": [{"x": 522, "y": 610}, {"x": 640, "y": 610}, {"x": 640, "y": 500}],
"E": 2
}
],
"renderStyle": "standard"
}
}
connect(jointUSR.axis, axis) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 523, "y": 890}, {"x": 740, "y": 890}], "E": 2}],
"renderStyle": "standard"
}
}
connect(jointUSR.bearing, bearing) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 476, "y": 890}, {"x": 260, "y": 890}], "E": 2}],
"renderStyle": "standard"
}
}
metadata {
"Dyad": {
"icons": {"default": "dyad://MultibodyComponents/JointRRR.svg"},
"labels": [
{
"label": "$(instance)",
"x": 500,
"y": 200,
"rot": 0,
"attrs": {"font-size": "160"}
}
]
}
}
endFlattened Source
"""
Joint assembly of three revolute joints with parallel axes (hence RRR),
connected by two rigid rods. It is built on top of `JointUSR` (the universal
joint there acts as the first two parallel-axis revolutes), so the non-linear
loop closure is solved analytically.
The assembly has no mass and no inertia and introduces neither constraints nor
potential states. Use it to close planar kinematic loops: it is far more
efficient than the equivalent loop built from basic joints plus a cut joint.
Two configurations satisfy the constraints; `positive_branch` selects which one
(elbow up/down), and `phi_guess` seeds the revolute angle.
"""
component JointRRR
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 in rod1 at the origin of frame_a"
frame_ia = Frame3D() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 290, "y1": 450, "x2": 390, "y2": 550, "rot": 0}
},
"tags": []
}
}
"Frame fixed in rod2 at the first-rod side of the middle revolute joint"
frame_ib = Frame3D() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 630, "y1": 450, "x2": 730, "y2": 550, "rot": 0}
},
"tags": []
}
}
"Frame fixed in rod2 at the middle revolute joint"
frame_im = Frame3D() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 450, "y1": 450, "x2": 550, "y2": 550, "rot": 0}
},
"tags": []
}
}
"Rotational flange driving the revolute joint at frame_b"
axis = Spline() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 690, "y1": 950, "x2": 790, "y2": 1050, "rot": 0}
},
"tags": []
}
}
"Rotational flange of the revolute joint bearing"
bearing = Spline() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 210, "y1": 950, "x2": 310, "y2": 1050, "rot": 0}
},
"tags": []
}
}
jointUSR = JointUSR(n1_a = n_a, n_b = n_b, n_b_nonzero = n_b_nonzero, rRod1_ia = rRod1_ia, rRod2_ib = rRod2_ib, phi_offset = phi_offset, phi_guess = phi_guess, positive_branch = positive_branch, rod_radius = rod_radius, rod_color = rod_color) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 450, "y1": 610, "x2": 550, "y2": 710, "rot": 0}
},
"tags": []
}
}
structural parameter positive_branch::Boolean = true
"Axis of the revolute joints, resolved in frame_a"
parameter n_a::Real[3] = [0, 0, 1]
"Axis of the revolute joint at frame_b, resolved in frame_b"
parameter n_b::Real[3] = [0, 0, 1]
"Structural sparsity mask for the frame_b revolute axis (threaded to the analytic revolute via JointUSR)."
structural parameter n_b_nonzero::Boolean[3] = [true, true, true]
"Vector from frame_a origin to the middle revolute joint, resolved in frame_ia"
parameter rRod1_ia::Real[3] = [1, 0, 0]
"Vector from frame_ib origin to the middle revolute joint, resolved in frame_ib"
parameter rRod2_ib::Real[3] = [-1, 0, 0]
"Relative angle offset of the revolute joint"
parameter phi_offset::Real = 0
"Guess value for the revolute angle at the initial time"
parameter phi_guess::Real = 0
"Rendering radius of the rods"
parameter rod_radius::Real = 0.05
"RGBA color of the rods"
parameter rod_color::Real[4] = [0.5, 0, 0.5, 1]
relations
connect(jointUSR.frame_a, frame_a) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 225, "y": 660}, {"x": 225, "y": 500}], "E": 2}],
"renderStyle": "standard"
}
}
connect(jointUSR.frame_b, frame_b) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 775, "y": 660}, {"x": 775, "y": 500}], "E": 2}],
"renderStyle": "standard"
}
}
connect(jointUSR.frame_ia, frame_ia) {
"Dyad": {
"edges": [
{
"S": 1,
"M": [{"x": 475, "y": 610}, {"x": 380, "y": 610}, {"x": 380, "y": 500}],
"E": 2
}
],
"renderStyle": "standard"
}
}
connect(jointUSR.frame_im, frame_im) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
connect(jointUSR.frame_ib, frame_ib) {
"Dyad": {
"edges": [
{
"S": 1,
"M": [{"x": 522, "y": 610}, {"x": 640, "y": 610}, {"x": 640, "y": 500}],
"E": 2
}
],
"renderStyle": "standard"
}
}
connect(jointUSR.axis, axis) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 523, "y": 890}, {"x": 740, "y": 890}], "E": 2}],
"renderStyle": "standard"
}
}
connect(jointUSR.bearing, bearing) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 476, "y": 890}, {"x": 260, "y": 890}], "E": 2}],
"renderStyle": "standard"
}
}
metadata {
"Dyad": {
"icons": {"default": "dyad://MultibodyComponents/JointRRR.svg"},
"labels": [
{
"label": "$(instance)",
"x": 500,
"y": 200,
"rot": 0,
"attrs": {"font-size": "160"}
}
]
}
}
endTest Cases
No test cases defined.
Related
Examples
Experiments
Analyses