PlanarMechanics.examples.trebuchet.Trebuchet
A planar trebuchet built from PlanarMechanics components.
The machine stands on two ideal (no-slip) rolling wheels so the whole frame can recoil horizontally as it fires. A heavy counterweight hangs from a hinge on the short side of the throwing arm; the long side of the arm whips a sling, modeled with the Cable component (an open chain of n rigid links). The projectile is a Body attached to the free end of the sling.
Releasing the projectile is a structural change (a connection is removed) that cannot happen mid-simulation. The structural parameter attached selects the two variants: attached = true keeps the projectile connected to the sling end (used until the arm reaches the release angle), attached = false lets the projectile fly freely. The companion script run_trebuchet.jl simulates the attached model, stops at the release angle, and restarts the free model from the captured end state.
Each wheel hub frame rotates with the rolling angle, so a bearing Revolute sits between every wheel and the chassis; the two ground contacts keep the chassis level while it rolls.
Usage
MultibodyComponents.PlanarMechanics.examples.trebuchet.Trebuchet(rw=0.3, wheelbase=1.4, post_dx=0.7, post_h=4.7, L_long=3.0, L_short=1.0, L_hang=0.8, l_sling=2.0, sling_dir=[0, -1], d_sling=1, c_sling=0.2, m_chassis=80, m_arm=20, m_cw=300, m_sling=2, m_proj=15, I_cw=5, I_proj=0.5, I_arm=m_arm * L_long ^ 2 / 12, I_chassis=m_chassis * wheelbase ^ 2 / 12, phi0=-1.0)
Parameters:
| Name | Description | Units | Default value |
|---|---|---|---|
attached | – | true | |
rw | Wheel radius | m | 0.3 |
wheelbase | Distance between the two wheel axles | m | 1.4 |
post_dx | Horizontal offset of the pivot from the rear wheel | m | 0.7 |
post_h | Height of the pivot above the wheel axles | m | 4.7 |
L_long | Length of the long (throwing) arm from the fulcrum to the sling attachment | m | 3.0 |
L_short | Length of the short arm from the fulcrum to the counterweight hinge | m | 1.0 |
L_hang | Length the counterweight hangs below its hinge | m | 0.8 |
l_sling | Total unstretched length of the sling | m | 2.0 |
sling_dir | Hanging direction of the straight sling, resolved in the arm-tip frame | – | [0, -1] |
d_sling | Viscous damping of each sling joint (slight, for a more realistic sling) | N.m.s/rad | 1 |
c_sling | Rotational stiffness of each sling joint (slight, for a more realistic sling) | N.m/rad | 0.2 |
m_chassis | Mass of the chassis beam | kg | 80 |
m_arm | Mass of the throwing arm | kg | 20 |
m_cw | Mass of the counterweight | kg | 300 |
m_sling | Total mass of the sling | kg | 2 |
m_proj | Mass of the projectile | kg | 15 |
I_cw | Moment of inertia of the counterweight about its center of mass | kg.m2 | 5 |
I_proj | Moment of inertia of the projectile about its center of mass | kg.m2 | 0.5 |
phi0 | Initial pivot angle: long arm down, counterweight raised | rad | -1.0 |
Behavior
Source
"""
A planar trebuchet built from PlanarMechanics components.
The machine stands on two ideal (no-slip) rolling wheels so the whole frame can
recoil horizontally as it fires. A heavy counterweight hangs from a hinge on the
short side of the throwing arm; the long side of the arm whips a sling, modeled
with the `Cable` component (an open chain of `n` rigid links). The projectile is
a `Body` attached to the free end of the sling.
Releasing the projectile is a structural change (a connection is removed) that
cannot happen mid-simulation. The structural parameter `attached` selects the two
variants: `attached = true` keeps the projectile connected to the sling end
(used until the arm reaches the release angle), `attached = false` lets the
projectile fly freely. The companion script `run_trebuchet.jl` simulates the
attached model, stops at the release angle, and restarts the free model from the
captured end state.
Each wheel hub frame rotates with the rolling angle, so a bearing `Revolute`
sits between every wheel and the chassis; the two ground contacts keep the
chassis level while it rolls.
"""
example component Trebuchet
world = MultibodyComponents.PlanarMechanics.World(render_ground = false, nominal_length = 2) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 140, "y1": 20, "x2": 240, "y2": 120, "rot": 0}
},
"tags": []
}
}
# --- chassis on two no-slip wheels (wheel -> bearing -> chassis beam) ---
wheel_rear = MultibodyComponents.PlanarMechanics.OneDOFRollingWheelJoint(radius = rw, x0 = 0) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 250, "y1": 680, "x2": 350, "y2": 780, "rot": 0}
},
"tags": []
}
}
wheel_front = MultibodyComponents.PlanarMechanics.OneDOFRollingWheelJoint(radius = rw, x0 = wheelbase) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 490, "y1": 680, "x2": 590, "y2": 780, "rot": 0}
},
"tags": []
}
}
bear_rear = MultibodyComponents.PlanarMechanics.Revolute(phi(initial = 0), w(initial = 0)) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 250, "y1": 580, "x2": 350, "y2": 680, "rot": 270}
},
"tags": []
}
}
bear_front = MultibodyComponents.PlanarMechanics.Revolute() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 490, "y1": 580, "x2": 590, "y2": 680, "rot": 270}
},
"tags": []
}
}
chassis = MultibodyComponents.PlanarMechanics.BodyShape(r = [wheelbase, 0], m = m_chassis, I = I_chassis, radius = 0.06) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 370, "y1": 510, "x2": 470, "y2": 610, "rot": 0}
},
"tags": []
}
}
post = MultibodyComponents.PlanarMechanics.FixedTranslation(r = [post_dx, post_h]) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 310, "y1": 380, "x2": 450, "y2": 520, "rot": 270}
},
"tags": []
}
}
# --- throwing arm + hinged counterweight, rotating about the fulcrum ---
pivot = MultibodyComponents.PlanarMechanics.Revolute(phi(initial = phi0), w(initial = 0)) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 330, "y1": 270, "x2": 430, "y2": 370, "rot": 270}
},
"tags": []
}
}
arm = MultibodyComponents.PlanarMechanics.BodyShape(r = [L_long, 0], m = m_arm, I = I_arm, radius = 0.05) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 350, "y1": 210, "x2": 250, "y2": 310, "rot": 0}
},
"tags": []
}
}
cw_ext = MultibodyComponents.PlanarMechanics.FixedTranslation(r = [-L_short, 0]) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 430, "y1": 210, "x2": 530, "y2": 310, "rot": 0}
},
"tags": []
}
}
cw_hinge = MultibodyComponents.PlanarMechanics.Revolute(phi(initial = -phi0), w(initial = 0)) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 540, "y1": 210, "x2": 640, "y2": 310, "rot": 0}
},
"tags": []
}
}
cw_rod = MultibodyComponents.PlanarMechanics.FixedTranslation(r = [0, -L_hang]) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 640, "y1": 270, "x2": 740, "y2": 370, "rot": 90}
},
"tags": []
}
}
cw = MultibodyComponents.PlanarMechanics.Body(m = m_cw, I = I_cw, radius = 0.35) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 590, "y1": 380, "x2": 790, "y2": 580, "rot": 90}
},
"tags": []
}
}
# --- sling + projectile ---
# A free pivot connects the sling to the arm tip. The cable uses
# `end_joints = false` so its far end is the last link's (massive) tip; this
# keeps the released model well-posed (an enabled end joint left unloaded
# after release would be a massless, undetermined rotational DOF).
sling_pivot = MultibodyComponents.PlanarMechanics.Revolute(phi(initial = 0), w(initial = 0)) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 240, "y1": 210, "x2": 140, "y2": 310, "rot": 0}
},
"tags": []
}
}
cable = MultibodyComponents.PlanarMechanics.Cable(n = 7, end_joints = false, l = l_sling, m = m_sling, dir = sling_dir, radius = 0.04, hasdamping = true, d_joint = d_sling, hasstiffness = true, c_joint = c_sling) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 100, "y1": 210, "x2": 0, "y2": 310, "rot": 0}
},
"tags": []
}
}
projectile = MultibodyComponents.PlanarMechanics.Body(m = m_proj, I = I_proj, radius = 0.12) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 0, "y1": 150, "x2": 100, "y2": 250, "rot": 90}
},
"tags": []
}
}
damper = RotationalComponents.Components.Damper(d = 3) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 160, "y1": 350, "x2": 220, "y2": 410, "rot": 90}
},
"tags": []
}
}
fixed = RotationalComponents.Components.Fixed() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 160, "y1": 430, "x2": 220, "y2": 490, "rot": 0}
},
"tags": []
}
}
# Projectile connected to the sling end (true) or free-flying (false)
structural parameter attached::Boolean = true
# --- geometry parameters ---
"Wheel radius"
parameter rw::Length = 0.3
"Distance between the two wheel axles"
parameter wheelbase::Length = 1.4
"Horizontal offset of the pivot from the rear wheel"
parameter post_dx::Length = 0.7
"Height of the pivot above the wheel axles"
parameter post_h::Length = 4.7
"Length of the long (throwing) arm from the fulcrum to the sling attachment"
parameter L_long::Length = 3.0
"Length of the short arm from the fulcrum to the counterweight hinge"
parameter L_short::Length = 1.0
"Length the counterweight hangs below its hinge"
parameter L_hang::Length = 0.8
"Total unstretched length of the sling"
parameter l_sling::Length = 2.0
"Hanging direction of the straight sling, resolved in the arm-tip frame"
parameter sling_dir::Real[2] = [0, -1]
"Viscous damping of each sling joint (slight, for a more realistic sling)"
parameter d_sling::RotationalDampingConstant = 1
"Rotational stiffness of each sling joint (slight, for a more realistic sling)"
parameter c_sling::RotationalSpringConstant = 0.2
# --- mass parameters ---
"Mass of the chassis beam"
parameter m_chassis::Mass = 80
"Mass of the throwing arm"
parameter m_arm::Mass = 20
"Mass of the counterweight"
parameter m_cw::Mass = 300
"Total mass of the sling"
parameter m_sling::Mass = 2
"Mass of the projectile"
parameter m_proj::Mass = 15
# --- inertia parameters ---
"Moment of inertia of the counterweight about its center of mass"
parameter I_cw::MomentOfInertia = 5
"Moment of inertia of the projectile about its center of mass"
parameter I_proj::MomentOfInertia = 0.5
"Moment of inertia of the throwing arm about its center of mass (thin rod)"
final parameter I_arm::MomentOfInertia = m_arm * L_long ^ 2 / 12
"Moment of inertia of the chassis beam about its center of mass (thin rod)"
final parameter I_chassis::MomentOfInertia = m_chassis * wheelbase ^ 2 / 12
# --- initial (cocked) configuration ---
"Initial pivot angle: long arm down, counterweight raised"
parameter phi0::Angle = -1.0
relations
# cocked configuration: arm held down, counterweight hanging vertically, at rest
# chassis carried by the two rolling wheels through bearings
connect(wheel_rear.frame_a, bear_rear.frame_a) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
connect(bear_rear.frame_b, chassis.frame_a) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 300, "y": 560}], "E": 2}],
"renderStyle": "standard"
}
}
connect(wheel_front.frame_a, bear_front.frame_a) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
connect(bear_front.frame_b, chassis.frame_b) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 540, "y": 560}], "E": 2}],
"renderStyle": "standard"
}
}
connect(chassis.frame_a, post.frame_a) {
"Dyad": {
"edges": [{"S": 1, "M": [], "E": -1}, {"S": -1, "M": [], "E": 2}],
"junctions": [{"x": 380, "y": 500}],
"renderStyle": "standard"
}
}
connect(post.frame_b, pivot.frame_a) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
# rigid lever about the fulcrum (pivot.frame_b)
connect(pivot.frame_b, arm.frame_a) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 380, "y": 260}], "E": 2}],
"renderStyle": "standard"
}
}
connect(pivot.frame_b, cw_ext.frame_a) {
"Dyad": {
"edges": [{"S": 1, "M": [], "E": -1}, {"S": -1, "M": [{"x": 380, "y": 260}], "E": 2}],
"junctions": [{"x": 380, "y": 280}],
"renderStyle": "standard"
}
}
connect(cw_ext.frame_b, cw_hinge.frame_a) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
connect(cw_hinge.frame_b, cw_rod.frame_a) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 690, "y": 260}], "E": 2}],
"renderStyle": "standard"
}
}
connect(cw_rod.frame_b, cw.frame_a) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
# sling pivots freely at the arm tip; projectile at the open end (removed on release)
connect(arm.frame_b, sling_pivot.frame_a) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
connect(sling_pivot.frame_b, cable.frame_a) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
connect(fixed.spline, damper.spline_b) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
connect(damper.spline_a, sling_pivot.flange_a) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
if attached
connect(cable.frame_b, projectile.frame_a)
end
metadata {"Dyad": {"tests": {}}}
endFlattened Source
"""
A planar trebuchet built from PlanarMechanics components.
The machine stands on two ideal (no-slip) rolling wheels so the whole frame can
recoil horizontally as it fires. A heavy counterweight hangs from a hinge on the
short side of the throwing arm; the long side of the arm whips a sling, modeled
with the `Cable` component (an open chain of `n` rigid links). The projectile is
a `Body` attached to the free end of the sling.
Releasing the projectile is a structural change (a connection is removed) that
cannot happen mid-simulation. The structural parameter `attached` selects the two
variants: `attached = true` keeps the projectile connected to the sling end
(used until the arm reaches the release angle), `attached = false` lets the
projectile fly freely. The companion script `run_trebuchet.jl` simulates the
attached model, stops at the release angle, and restarts the free model from the
captured end state.
Each wheel hub frame rotates with the rolling angle, so a bearing `Revolute`
sits between every wheel and the chassis; the two ground contacts keep the
chassis level while it rolls.
"""
example component Trebuchet
world = MultibodyComponents.PlanarMechanics.World(render_ground = false, nominal_length = 2) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 140, "y1": 20, "x2": 240, "y2": 120, "rot": 0}
},
"tags": []
}
}
# --- chassis on two no-slip wheels (wheel -> bearing -> chassis beam) ---
wheel_rear = MultibodyComponents.PlanarMechanics.OneDOFRollingWheelJoint(radius = rw, x0 = 0) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 250, "y1": 680, "x2": 350, "y2": 780, "rot": 0}
},
"tags": []
}
}
wheel_front = MultibodyComponents.PlanarMechanics.OneDOFRollingWheelJoint(radius = rw, x0 = wheelbase) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 490, "y1": 680, "x2": 590, "y2": 780, "rot": 0}
},
"tags": []
}
}
bear_rear = MultibodyComponents.PlanarMechanics.Revolute(phi(initial = 0), w(initial = 0)) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 250, "y1": 580, "x2": 350, "y2": 680, "rot": 270}
},
"tags": []
}
}
bear_front = MultibodyComponents.PlanarMechanics.Revolute() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 490, "y1": 580, "x2": 590, "y2": 680, "rot": 270}
},
"tags": []
}
}
chassis = MultibodyComponents.PlanarMechanics.BodyShape(r = [wheelbase, 0], m = m_chassis, I = I_chassis, radius = 0.06) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 370, "y1": 510, "x2": 470, "y2": 610, "rot": 0}
},
"tags": []
}
}
post = MultibodyComponents.PlanarMechanics.FixedTranslation(r = [post_dx, post_h]) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 310, "y1": 380, "x2": 450, "y2": 520, "rot": 270}
},
"tags": []
}
}
# --- throwing arm + hinged counterweight, rotating about the fulcrum ---
pivot = MultibodyComponents.PlanarMechanics.Revolute(phi(initial = phi0), w(initial = 0)) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 330, "y1": 270, "x2": 430, "y2": 370, "rot": 270}
},
"tags": []
}
}
arm = MultibodyComponents.PlanarMechanics.BodyShape(r = [L_long, 0], m = m_arm, I = I_arm, radius = 0.05) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 350, "y1": 210, "x2": 250, "y2": 310, "rot": 0}
},
"tags": []
}
}
cw_ext = MultibodyComponents.PlanarMechanics.FixedTranslation(r = [-L_short, 0]) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 430, "y1": 210, "x2": 530, "y2": 310, "rot": 0}
},
"tags": []
}
}
cw_hinge = MultibodyComponents.PlanarMechanics.Revolute(phi(initial = -phi0), w(initial = 0)) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 540, "y1": 210, "x2": 640, "y2": 310, "rot": 0}
},
"tags": []
}
}
cw_rod = MultibodyComponents.PlanarMechanics.FixedTranslation(r = [0, -L_hang]) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 640, "y1": 270, "x2": 740, "y2": 370, "rot": 90}
},
"tags": []
}
}
cw = MultibodyComponents.PlanarMechanics.Body(m = m_cw, I = I_cw, radius = 0.35) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 590, "y1": 380, "x2": 790, "y2": 580, "rot": 90}
},
"tags": []
}
}
# --- sling + projectile ---
# A free pivot connects the sling to the arm tip. The cable uses
# `end_joints = false` so its far end is the last link's (massive) tip; this
# keeps the released model well-posed (an enabled end joint left unloaded
# after release would be a massless, undetermined rotational DOF).
sling_pivot = MultibodyComponents.PlanarMechanics.Revolute(phi(initial = 0), w(initial = 0)) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 240, "y1": 210, "x2": 140, "y2": 310, "rot": 0}
},
"tags": []
}
}
cable = MultibodyComponents.PlanarMechanics.Cable(n = 7, end_joints = false, l = l_sling, m = m_sling, dir = sling_dir, radius = 0.04, hasdamping = true, d_joint = d_sling, hasstiffness = true, c_joint = c_sling) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 100, "y1": 210, "x2": 0, "y2": 310, "rot": 0}
},
"tags": []
}
}
projectile = MultibodyComponents.PlanarMechanics.Body(m = m_proj, I = I_proj, radius = 0.12) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 0, "y1": 150, "x2": 100, "y2": 250, "rot": 90}
},
"tags": []
}
}
damper = RotationalComponents.Components.Damper(d = 3) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 160, "y1": 350, "x2": 220, "y2": 410, "rot": 90}
},
"tags": []
}
}
fixed = RotationalComponents.Components.Fixed() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 160, "y1": 430, "x2": 220, "y2": 490, "rot": 0}
},
"tags": []
}
}
# Projectile connected to the sling end (true) or free-flying (false)
structural parameter attached::Boolean = true
# --- geometry parameters ---
"Wheel radius"
parameter rw::Length = 0.3
"Distance between the two wheel axles"
parameter wheelbase::Length = 1.4
"Horizontal offset of the pivot from the rear wheel"
parameter post_dx::Length = 0.7
"Height of the pivot above the wheel axles"
parameter post_h::Length = 4.7
"Length of the long (throwing) arm from the fulcrum to the sling attachment"
parameter L_long::Length = 3.0
"Length of the short arm from the fulcrum to the counterweight hinge"
parameter L_short::Length = 1.0
"Length the counterweight hangs below its hinge"
parameter L_hang::Length = 0.8
"Total unstretched length of the sling"
parameter l_sling::Length = 2.0
"Hanging direction of the straight sling, resolved in the arm-tip frame"
parameter sling_dir::Real[2] = [0, -1]
"Viscous damping of each sling joint (slight, for a more realistic sling)"
parameter d_sling::RotationalDampingConstant = 1
"Rotational stiffness of each sling joint (slight, for a more realistic sling)"
parameter c_sling::RotationalSpringConstant = 0.2
# --- mass parameters ---
"Mass of the chassis beam"
parameter m_chassis::Mass = 80
"Mass of the throwing arm"
parameter m_arm::Mass = 20
"Mass of the counterweight"
parameter m_cw::Mass = 300
"Total mass of the sling"
parameter m_sling::Mass = 2
"Mass of the projectile"
parameter m_proj::Mass = 15
# --- inertia parameters ---
"Moment of inertia of the counterweight about its center of mass"
parameter I_cw::MomentOfInertia = 5
"Moment of inertia of the projectile about its center of mass"
parameter I_proj::MomentOfInertia = 0.5
"Moment of inertia of the throwing arm about its center of mass (thin rod)"
final parameter I_arm::MomentOfInertia = m_arm * L_long ^ 2 / 12
"Moment of inertia of the chassis beam about its center of mass (thin rod)"
final parameter I_chassis::MomentOfInertia = m_chassis * wheelbase ^ 2 / 12
# --- initial (cocked) configuration ---
"Initial pivot angle: long arm down, counterweight raised"
parameter phi0::Angle = -1.0
relations
# cocked configuration: arm held down, counterweight hanging vertically, at rest
# chassis carried by the two rolling wheels through bearings
connect(wheel_rear.frame_a, bear_rear.frame_a) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
connect(bear_rear.frame_b, chassis.frame_a) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 300, "y": 560}], "E": 2}],
"renderStyle": "standard"
}
}
connect(wheel_front.frame_a, bear_front.frame_a) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
connect(bear_front.frame_b, chassis.frame_b) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 540, "y": 560}], "E": 2}],
"renderStyle": "standard"
}
}
connect(chassis.frame_a, post.frame_a) {
"Dyad": {
"edges": [{"S": 1, "M": [], "E": -1}, {"S": -1, "M": [], "E": 2}],
"junctions": [{"x": 380, "y": 500}],
"renderStyle": "standard"
}
}
connect(post.frame_b, pivot.frame_a) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
# rigid lever about the fulcrum (pivot.frame_b)
connect(pivot.frame_b, arm.frame_a) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 380, "y": 260}], "E": 2}],
"renderStyle": "standard"
}
}
connect(pivot.frame_b, cw_ext.frame_a) {
"Dyad": {
"edges": [{"S": 1, "M": [], "E": -1}, {"S": -1, "M": [{"x": 380, "y": 260}], "E": 2}],
"junctions": [{"x": 380, "y": 280}],
"renderStyle": "standard"
}
}
connect(cw_ext.frame_b, cw_hinge.frame_a) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
connect(cw_hinge.frame_b, cw_rod.frame_a) {
"Dyad": {
"edges": [{"S": 1, "M": [{"x": 690, "y": 260}], "E": 2}],
"renderStyle": "standard"
}
}
connect(cw_rod.frame_b, cw.frame_a) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
# sling pivots freely at the arm tip; projectile at the open end (removed on release)
connect(arm.frame_b, sling_pivot.frame_a) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
connect(sling_pivot.frame_b, cable.frame_a) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
connect(fixed.spline, damper.spline_b) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
connect(damper.spline_a, sling_pivot.flange_a) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
if attached
connect(cable.frame_b, projectile.frame_a)
end
metadata {"Dyad": {"tests": {}}}
endTest Cases
No test cases defined.
Related
Examples
Experiments
Analyses