RollingWheelSetJoint
Idealized two-wheel rolling axle (wheelset) without bodies.
Two parallel-axis revolute joints provide each wheel's spin angle; each is constrained by a RollingConstraintVerticalWheel. The wheelset center (frame_middle) is mounted to ground via prismatic-x → prismatic-z → revolute (around y), exposing planar coordinates (x, z, phi) and the two wheel spin angles (theta1, theta2) as states.
frame_middle: between the two wheels (z-axis along the axle, y-axis up)frame1/frame2: wheel-center frames, rotating with each wheelaxis1/axis2: 1-D rotational flanges driving each wheelsupport: 1-D support flange (mounted toframe_middle)
Usage
MultibodyComponents.RollingWheelSetJoint(radius=0.3, track=1.0, width_wheel=0.15 * radius)
Parameters:
| Name | Description | Units | Default value |
|---|---|---|---|
radius | m | 0.3 | |
track | m | 1.0 | |
width_wheel | m | 0.15 * radius |
Connectors
frame_middle- Frame3D is the fundamental 3D connector used for 6DOF motion. Most components have one or severalFrame
connectors that can be connected together (Frame3D)
frame1- Frame3D is the fundamental 3D connector used for 6DOF motion. Most components have one or severalFrame
connectors that can be connected together (Frame3D)
frame2- Frame3D is the fundamental 3D connector used for 6DOF motion. Most components have one or severalFrame
connectors that can be connected together (Frame3D)
axis1- This connector represents a rotational spline with angle and torque as the potential and flow variables, respectively. (Spline)axis2- 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
| Name | Description | Units |
|---|---|---|
x | m | |
z | m | |
phi | rad | |
theta1 | rad | |
theta2 | rad | |
der_theta1 | rad/s | |
der_theta2 | rad/s |
Behavior
Source
"""
Idealized two-wheel rolling axle (wheelset) without bodies.
Two parallel-axis revolute joints provide each wheel's spin angle; each is
constrained by a `RollingConstraintVerticalWheel`. The wheelset center
(`frame_middle`) is mounted to ground via prismatic-x → prismatic-z →
revolute (around y), exposing planar coordinates `(x, z, phi)` and the two
wheel spin angles `(theta1, theta2)` as states.
- `frame_middle`: between the two wheels (z-axis along the axle, y-axis up)
- `frame1`/`frame2`: wheel-center frames, rotating with each wheel
- `axis1`/`axis2`: 1-D rotational flanges driving each wheel
- `support`: 1-D support flange (mounted to `frame_middle`)
"""
component RollingWheelSetJoint
frame_middle = Frame3D() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 450, "y1": 450, "x2": 550, "y2": 550, "rot": 0}
},
"tags": []
}
}
frame1 = Frame3D() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": -50, "y1": 450, "x2": 50, "y2": 550, "rot": 0}
},
"tags": []
}
}
frame2 = Frame3D() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 950, "y1": 450, "x2": 1050, "y2": 550, "rot": 0}
},
"tags": []
}
}
axis1 = Spline() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": -50, "y1": 20, "x2": 50, "y2": 120, "rot": 0}
},
"tags": []
}
}
axis2 = Spline() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 950, "y1": 20, "x2": 1050, "y2": 120, "rot": 0}
},
"tags": []
}
}
support = Spline() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 450, "y1": 100, "x2": 550, "y2": 200, "rot": 0}
},
"tags": []
}
}
fixed = MultibodyComponents.Fixed(final r = [0, radius, 0]) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 450, "y1": 900, "x2": 550, "y2": 1000, "rot": 270}
},
"tags": []
}
}
rod1 = MultibodyComponents.FixedTranslation(final r = [0, 0, track / 2], render = false) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 420, "y1": 450, "x2": 320, "y2": 550, "rot": 0}
},
"tags": []
}
}
rod2 = MultibodyComponents.FixedTranslation(final r = [0, 0, -track / 2], render = false) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 590, "y1": 450, "x2": 690, "y2": 550, "rot": 0}
},
"tags": []
}
}
prismatic1 = MultibodyComponents.Prismatic(final n = [1, 0, 0], render = false, statePriority = 10) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 450, "y1": 830, "x2": 550, "y2": 930, "rot": 270}
},
"tags": []
}
}
prismatic2 = MultibodyComponents.Prismatic(final n = [0, 0, 1], render = false, statePriority = 10) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 420, "y1": 760, "x2": 320, "y2": 860, "rot": 0}
},
"tags": []
}
}
revolute = MultibodyComponents.Revolute(final n = [0, 1, 0], render = false) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 450, "y1": 640, "x2": 550, "y2": 740, "rot": 270}
},
"tags": []
}
}
revolute1 = MultibodyComponents.Revolute(final n = [0, 0, 1], render = false, radius = radius, cylinder_length = width_wheel, statePriority = 11) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 280, "y1": 450, "x2": 180, "y2": 550, "rot": 0}
},
"tags": []
}
}
revolute2 = MultibodyComponents.Revolute(final n = [0, 0, 1], render = false, radius = radius, cylinder_length = width_wheel, statePriority = 11) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 730, "y1": 450, "x2": 830, "y2": 550, "rot": 0}
},
"tags": []
}
}
rolling1 = MultibodyComponents.RollingConstraintVerticalWheel(final radius = radius, lateral_sliding_constraint = true) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 90, "y1": 580, "x2": 190, "y2": 680, "rot": 0}
},
"tags": []
}
}
rolling2 = MultibodyComponents.RollingConstraintVerticalWheel(final radius = radius, lateral_sliding_constraint = false) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 830, "y1": 590, "x2": 930, "y2": 690, "rot": 0}
},
"tags": []
}
}
mounting1D = MultibodyComponents.Mounting1D() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 450, "y1": 360, "x2": 550, "y2": 260, "rot": 0}
},
"tags": []
}
}
parameter radius::Length = 0.3
parameter track::Length = 1.0
parameter width_wheel::Length = 0.15 * radius
variable x::Length(statePriority = 100)
variable z::Length(statePriority = 100)
variable phi::Angle(statePriority = 100)
variable theta1::Angle(statePriority = 100)
variable theta2::Angle(statePriority = 100)
variable der_theta1::AngularVelocity(statePriority = 100)
variable der_theta2::AngularVelocity(statePriority = 100)
relations
prismatic1.s = x
prismatic2.s = z
revolute.phi = phi
revolute1.phi = theta1
revolute2.phi = theta2
der_theta1 = der(theta1)
der_theta2 = der(theta2)
connect(prismatic1.frame_a, fixed.frame_b) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
connect(prismatic1.frame_b, prismatic2.frame_a) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 500, "y": 810}], "E": 2}],
"renderStyle": "standard"
}
}
connect(revolute2.axis, axis2) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 780, "y": 70}], "E": 2}],
"renderStyle": "standard"
}
}
connect(frame_middle, mounting1D.frame_a) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
connect(mounting1D.flange_b, support) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
connect(frame2, revolute2.frame_b, rolling2.frame_a) {
"Dyad": {
"edges": [
{"S": 1, "M": [], "E": -1},
{"S": -1, "M": [], "E": 2},
{"S": 3, "M": [], "E": -1}
],
"junctions": [{"x": 880, "y": 500}],
"renderStyle": "standard"
}
}
connect(frame1, rolling1.frame_a, revolute1.frame_b) {
"Dyad": {
"edges": [
{"S": 1, "M": [], "E": -1},
{"S": -1, "M": [{"x": 140, "y": 500}], "E": 2},
{"S": 3, "M": [], "E": -1}
],
"junctions": [{"x": 140, "y": 500}],
"renderStyle": "standard"
}
}
connect(rod1.frame_b, revolute1.frame_a) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
connect(rod1.frame_a, frame_middle) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
connect(rod2.frame_a, frame_middle) {"Dyad": {"renderStyle": "standard", "edges": [{"S": 1, "E": 2, "M": []}]}}
connect(rod2.frame_b, revolute2.frame_a) {"Dyad": {"renderStyle": "standard", "edges": [{"S": 1, "E": 2, "M": []}]}}
connect(axis1, revolute1.axis) {
"Dyad": {
"renderStyle": "standard",
"edges": [{"S": 1, "M": [{"x": 230, "y": 70}], "E": 2}]
}
}
connect(prismatic2.frame_b, revolute.frame_a) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 320, "y": 750}, {"x": 500, "y": 750}], "E": 2}],
"renderStyle": "standard"
}
}
connect(revolute.frame_b, frame_middle) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
metadata {
"Dyad": {
"icons": {"default": "dyad://MultibodyComponents/RollingWheelSetJoint.svg"},
"labels": [
{
"label": "$(instance)",
"x": 500,
"y": 1080,
"rot": 0,
"attrs": {"font-size": "120"}
}
]
}
}
endFlattened Source
"""
Idealized two-wheel rolling axle (wheelset) without bodies.
Two parallel-axis revolute joints provide each wheel's spin angle; each is
constrained by a `RollingConstraintVerticalWheel`. The wheelset center
(`frame_middle`) is mounted to ground via prismatic-x → prismatic-z →
revolute (around y), exposing planar coordinates `(x, z, phi)` and the two
wheel spin angles `(theta1, theta2)` as states.
- `frame_middle`: between the two wheels (z-axis along the axle, y-axis up)
- `frame1`/`frame2`: wheel-center frames, rotating with each wheel
- `axis1`/`axis2`: 1-D rotational flanges driving each wheel
- `support`: 1-D support flange (mounted to `frame_middle`)
"""
component RollingWheelSetJoint
frame_middle = Frame3D() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 450, "y1": 450, "x2": 550, "y2": 550, "rot": 0}
},
"tags": []
}
}
frame1 = Frame3D() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": -50, "y1": 450, "x2": 50, "y2": 550, "rot": 0}
},
"tags": []
}
}
frame2 = Frame3D() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 950, "y1": 450, "x2": 1050, "y2": 550, "rot": 0}
},
"tags": []
}
}
axis1 = Spline() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": -50, "y1": 20, "x2": 50, "y2": 120, "rot": 0}
},
"tags": []
}
}
axis2 = Spline() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 950, "y1": 20, "x2": 1050, "y2": 120, "rot": 0}
},
"tags": []
}
}
support = Spline() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 450, "y1": 100, "x2": 550, "y2": 200, "rot": 0}
},
"tags": []
}
}
fixed = MultibodyComponents.Fixed(final r = [0, radius, 0]) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 450, "y1": 900, "x2": 550, "y2": 1000, "rot": 270}
},
"tags": []
}
}
rod1 = MultibodyComponents.FixedTranslation(final r = [0, 0, track / 2], render = false) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 420, "y1": 450, "x2": 320, "y2": 550, "rot": 0}
},
"tags": []
}
}
rod2 = MultibodyComponents.FixedTranslation(final r = [0, 0, -track / 2], render = false) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 590, "y1": 450, "x2": 690, "y2": 550, "rot": 0}
},
"tags": []
}
}
prismatic1 = MultibodyComponents.Prismatic(final n = [1, 0, 0], render = false, statePriority = 10) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 450, "y1": 830, "x2": 550, "y2": 930, "rot": 270}
},
"tags": []
}
}
prismatic2 = MultibodyComponents.Prismatic(final n = [0, 0, 1], render = false, statePriority = 10) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 420, "y1": 760, "x2": 320, "y2": 860, "rot": 0}
},
"tags": []
}
}
revolute = MultibodyComponents.Revolute(final n = [0, 1, 0], render = false) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 450, "y1": 640, "x2": 550, "y2": 740, "rot": 270}
},
"tags": []
}
}
revolute1 = MultibodyComponents.Revolute(final n = [0, 0, 1], render = false, radius = radius, cylinder_length = width_wheel, statePriority = 11) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 280, "y1": 450, "x2": 180, "y2": 550, "rot": 0}
},
"tags": []
}
}
revolute2 = MultibodyComponents.Revolute(final n = [0, 0, 1], render = false, radius = radius, cylinder_length = width_wheel, statePriority = 11) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 730, "y1": 450, "x2": 830, "y2": 550, "rot": 0}
},
"tags": []
}
}
rolling1 = MultibodyComponents.RollingConstraintVerticalWheel(final radius = radius, lateral_sliding_constraint = true) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 90, "y1": 580, "x2": 190, "y2": 680, "rot": 0}
},
"tags": []
}
}
rolling2 = MultibodyComponents.RollingConstraintVerticalWheel(final radius = radius, lateral_sliding_constraint = false) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 830, "y1": 590, "x2": 930, "y2": 690, "rot": 0}
},
"tags": []
}
}
mounting1D = MultibodyComponents.Mounting1D() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 450, "y1": 360, "x2": 550, "y2": 260, "rot": 0}
},
"tags": []
}
}
parameter radius::Length = 0.3
parameter track::Length = 1.0
parameter width_wheel::Length = 0.15 * radius
variable x::Length(statePriority = 100)
variable z::Length(statePriority = 100)
variable phi::Angle(statePriority = 100)
variable theta1::Angle(statePriority = 100)
variable theta2::Angle(statePriority = 100)
variable der_theta1::AngularVelocity(statePriority = 100)
variable der_theta2::AngularVelocity(statePriority = 100)
relations
prismatic1.s = x
prismatic2.s = z
revolute.phi = phi
revolute1.phi = theta1
revolute2.phi = theta2
der_theta1 = der(theta1)
der_theta2 = der(theta2)
connect(prismatic1.frame_a, fixed.frame_b) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
connect(prismatic1.frame_b, prismatic2.frame_a) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 500, "y": 810}], "E": 2}],
"renderStyle": "standard"
}
}
connect(revolute2.axis, axis2) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 780, "y": 70}], "E": 2}],
"renderStyle": "standard"
}
}
connect(frame_middle, mounting1D.frame_a) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
connect(mounting1D.flange_b, support) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
connect(frame2, revolute2.frame_b, rolling2.frame_a) {
"Dyad": {
"edges": [
{"S": 1, "M": [], "E": -1},
{"S": -1, "M": [], "E": 2},
{"S": 3, "M": [], "E": -1}
],
"junctions": [{"x": 880, "y": 500}],
"renderStyle": "standard"
}
}
connect(frame1, rolling1.frame_a, revolute1.frame_b) {
"Dyad": {
"edges": [
{"S": 1, "M": [], "E": -1},
{"S": -1, "M": [{"x": 140, "y": 500}], "E": 2},
{"S": 3, "M": [], "E": -1}
],
"junctions": [{"x": 140, "y": 500}],
"renderStyle": "standard"
}
}
connect(rod1.frame_b, revolute1.frame_a) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
connect(rod1.frame_a, frame_middle) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
connect(rod2.frame_a, frame_middle) {"Dyad": {"renderStyle": "standard", "edges": [{"S": 1, "E": 2, "M": []}]}}
connect(rod2.frame_b, revolute2.frame_a) {"Dyad": {"renderStyle": "standard", "edges": [{"S": 1, "E": 2, "M": []}]}}
connect(axis1, revolute1.axis) {
"Dyad": {
"renderStyle": "standard",
"edges": [{"S": 1, "M": [{"x": 230, "y": 70}], "E": 2}]
}
}
connect(prismatic2.frame_b, revolute.frame_a) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 320, "y": 750}, {"x": 500, "y": 750}], "E": 2}],
"renderStyle": "standard"
}
}
connect(revolute.frame_b, frame_middle) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
metadata {
"Dyad": {
"icons": {"default": "dyad://MultibodyComponents/RollingWheelSetJoint.svg"},
"labels": [
{
"label": "$(instance)",
"x": 500,
"y": 1080,
"rot": 0,
"attrs": {"font-size": "120"}
}
]
}
}
endTest Cases
No test cases defined.
Related
Examples
Experiments
Analyses