Skip to content
LIBRARY
PlanarMechanics.examples.ParallelKinematicRobot.md

PlanarMechanics.examples.ParallelKinematicRobot

Usage

MultibodyComponents.PlanarMechanics.examples.ParallelKinematicRobot(a_length=0.53, b_length=0.4374, c_length=0.5, d_length=0.15, link_mass=1.5, w0=-0.5, phi0=deg2rad(10), alpha_tf=0, link_radius=0.03, link_color=[0.9, 0.9, 0.9, 1.0])

Parameters:

NameDescriptionUnitsDefault value
a_lengthm0.53
b_lengthm0.4374
c_lengthm0.5
d_lengthm0.15
link_masskg1.5
w0rad/s-0.5
phi0Initial angle of the base->a revolute jointraddeg2rad(10)
alpha_tfrad0
link_radius0.03
link_color[0.9, 0.9, 0.9, 1]

Behavior

julia
using MultibodyComponents #hide
using ModelingToolkit #hide
@variables a_length #hide
@variables b_length #hide
@variables c_length #hide
@variables d_length #hide
@variables link_mass #hide
@variables w0 #hide
@variables phi0 #hide
@variables alpha_tf #hide
@variables link_radius #hide
@variables link_color #hide
@named sys = MultibodyComponents.PlanarMechanics.examples.ParallelKinematicRobot(a_length=a_length, b_length=b_length, c_length=c_length, d_length=d_length, link_mass=link_mass, w0=w0, phi0=phi0, alpha_tf=alpha_tf, link_radius=link_radius, link_color=link_color) #hide
full_equations(sys) #hide
<< @example-block not executed in draft mode >>

Source

dyad
example component ParallelKinematicRobot
  base = MultibodyComponents.PlanarMechanics.Fixed(r = [0.0, 0.520]) {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 260, "y1": 630, "x2": 460, "y2": 830, "rot": 0}
      },
      "tags": []
    }
  }
  base2 = MultibodyComponents.PlanarMechanics.Fixed(r = [0.15, 0.525]) {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 0, "y1": 240, "x2": 200, "y2": 440, "rot": 0}
      },
      "tags": []
    }
  }
  base_a = MultibodyComponents.PlanarMechanics.Revolute(radius = 1.3 * link_radius, color = link_color) {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 520, "y1": 630, "x2": 720, "y2": 830, "rot": 0}
      },
      "tags": []
    }
  }
  base2_b = MultibodyComponents.PlanarMechanics.Revolute(radius = 1.3 * link_radius, color = link_color) {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 260, "y1": 240, "x2": 460, "y2": 440, "rot": 0}
      },
      "tags": []
    }
  }
  a_cd = MultibodyComponents.PlanarMechanics.Revolute(radius = 1.3 * link_radius, color = link_color) {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 1040, "y1": 630, "x2": 1240, "y2": 830, "rot": 0}
      },
      "tags": []
    }
  }
  b_d = MultibodyComponents.PlanarMechanics.Revolute(radius = 1.3 * link_radius, color = link_color) {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 780, "y1": 240, "x2": 980, "y2": 440, "rot": 0}
      },
      "tags": []
    }
  }
  upper_arm = MultibodyComponents.PlanarMechanics.BodyShape(m = link_mass, r = [0, a_length], radius = link_radius, color = link_color) {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 780, "y1": 630, "x2": 980, "y2": 830, "rot": 0}
      },
      "tags": []
    }
  }
  link_b = MultibodyComponents.PlanarMechanics.BodyShape(m = link_mass, r = [0, b_length], radius = link_radius, color = link_color) {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 520, "y1": 240, "x2": 720, "y2": 440, "rot": 0}
      },
      "tags": []
    }
  }
  link_c = MultibodyComponents.PlanarMechanics.BodyShape(m = link_mass, r = [-c_length, 0], radius = link_radius, color = link_color) {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 1300, "y1": 630, "x2": 1500, "y2": 830, "rot": 0}
      },
      "tags": []
    }
  }
  link_d = MultibodyComponents.PlanarMechanics.BodyShape(m = link_mass, r = [d_length, 0], radius = link_radius, color = link_color) {
    "Dyad": {
      "placement": {
        "diagram": {
          "iconName": "default",
          "x1": 1170,
          "y1": 380,
          "x2": 1370,
          "y2": 580,
          "rot": 270
        }
      },
      "tags": []
    }
  }
  fixed_rotation_tf = MultibodyComponents.PlanarMechanics.FixedRotation(alpha = alpha_tf) {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 1560, "y1": 630, "x2": 1760, "y2": 830, "rot": 0}
      },
      "tags": []
    }
  }
  end_effector = EndEffector() {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 1810, "y1": 630, "x2": 2010, "y2": 830, "rot": 0}
      },
      "tags": []
    }
  }
  speed = RotationalComponents.Sources.SpeedSource() {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 260, "y1": 860, "x2": 460, "y2": 1060, "rot": 0}
      },
      "tags": []
    }
  }
  w0_const = BlockComponents.Sources.Constant(k = w0) {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 0, "y1": 860, "x2": 200, "y2": 1060, "rot": 0}
      },
      "tags": []
    }
  }
  world = MultibodyComponents.PlanarMechanics.World() {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 0, "y1": 550, "x2": 200, "y2": 750, "rot": 0}
      },
      "tags": []
    }
  }
  fixed = RotationalComponents.Components.Fixed() {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 310, "y1": 1130, "x2": 410, "y2": 1230, "rot": 0}
      },
      "tags": []
    }
  }
  parameter a_length::Length = 0.53
  parameter b_length::Length = 0.4374
  parameter c_length::Length = 0.5
  parameter d_length::Length = 0.15
  parameter link_mass::Dyad.Mass = 1.5
  parameter w0::AngularVelocity = -0.5
  "Initial angle of the base->a revolute joint"
  parameter phi0::Angle = deg2rad(10)
  parameter alpha_tf::Angle = 0
  parameter link_radius::Real = 0.03
  parameter link_color::Real[4] = [0.9, 0.9, 0.9, 1.0]
relations
  guess link_d.body.phi = 0
  guess link_d.translation.phi = 0
  guess link_b.translation.frame_b.fx = 1e-10
  guess end_effector.body.frame_a.tau = 1e-10
  guess link_b.translation.frame_b.fy = 1e-10
  guess link_b.body.phi = 1e-10
  guess link_b.translation.phi = 1e-10
  guess speed.phi = 1e-10
  guess end_effector.body.alpha = 1e-10
  initial base_a.phi = phi0
  # First chain: base → upper_arm → elbow
  connect(base.frame_b, base_a.frame_a) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
  connect(base_a.frame_b, upper_arm.frame_a) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
  connect(upper_arm.frame_b, a_cd.frame_a) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
  connect(a_cd.frame_b, link_c.frame_a, link_d.frame_a) {
    "Dyad": {
      "edges": [
        {"S": 1, "M": [], "E": -1},
        {"S": -1, "M": [], "E": 2},
        {"S": -1, "M": [], "E": 3}
      ],
      "junctions": [{"x": 1270, "y": 730}],
      "renderStyle": "standard"
    }
  }
  # Second chain: base2 → link_b → link_d (closes the loop)
  connect(base2.frame_b, base2_b.frame_a) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
  connect(base2_b.frame_b, link_b.frame_a) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
  connect(link_b.frame_b, b_d.frame_a) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
  connect(b_d.frame_b, link_d.frame_b) {
    "Dyad": {
      "edges": [{"S": 1, "M": [{"x": 1270, "y": 340}], "E": 2}],
      "renderStyle": "standard"
    }
  }
  # End-effector: on link_c via fixed rotation
  connect(link_c.frame_b, fixed_rotation_tf.frame_a) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
  connect(fixed_rotation_tf.frame_b, end_effector.frame_a) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
  # Drive the base revolute at constant angular velocity
  connect(speed.spline, base_a.flange_a) {
    "Dyad": {
      "edges": [{"S": 1, "M": [{"x": 620, "y": 960}], "E": 2}],
      "renderStyle": "standard"
    }
  }
  connect(w0_const.y, speed.w_ref) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
  connect(fixed.spline, speed.support) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
metadata {"Dyad": {"tests": {"case1": {"stop": 10}}}}
end
Flattened Source
dyad
example component ParallelKinematicRobot
  base = MultibodyComponents.PlanarMechanics.Fixed(r = [0.0, 0.520]) {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 260, "y1": 630, "x2": 460, "y2": 830, "rot": 0}
      },
      "tags": []
    }
  }
  base2 = MultibodyComponents.PlanarMechanics.Fixed(r = [0.15, 0.525]) {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 0, "y1": 240, "x2": 200, "y2": 440, "rot": 0}
      },
      "tags": []
    }
  }
  base_a = MultibodyComponents.PlanarMechanics.Revolute(radius = 1.3 * link_radius, color = link_color) {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 520, "y1": 630, "x2": 720, "y2": 830, "rot": 0}
      },
      "tags": []
    }
  }
  base2_b = MultibodyComponents.PlanarMechanics.Revolute(radius = 1.3 * link_radius, color = link_color) {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 260, "y1": 240, "x2": 460, "y2": 440, "rot": 0}
      },
      "tags": []
    }
  }
  a_cd = MultibodyComponents.PlanarMechanics.Revolute(radius = 1.3 * link_radius, color = link_color) {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 1040, "y1": 630, "x2": 1240, "y2": 830, "rot": 0}
      },
      "tags": []
    }
  }
  b_d = MultibodyComponents.PlanarMechanics.Revolute(radius = 1.3 * link_radius, color = link_color) {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 780, "y1": 240, "x2": 980, "y2": 440, "rot": 0}
      },
      "tags": []
    }
  }
  upper_arm = MultibodyComponents.PlanarMechanics.BodyShape(m = link_mass, r = [0, a_length], radius = link_radius, color = link_color) {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 780, "y1": 630, "x2": 980, "y2": 830, "rot": 0}
      },
      "tags": []
    }
  }
  link_b = MultibodyComponents.PlanarMechanics.BodyShape(m = link_mass, r = [0, b_length], radius = link_radius, color = link_color) {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 520, "y1": 240, "x2": 720, "y2": 440, "rot": 0}
      },
      "tags": []
    }
  }
  link_c = MultibodyComponents.PlanarMechanics.BodyShape(m = link_mass, r = [-c_length, 0], radius = link_radius, color = link_color) {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 1300, "y1": 630, "x2": 1500, "y2": 830, "rot": 0}
      },
      "tags": []
    }
  }
  link_d = MultibodyComponents.PlanarMechanics.BodyShape(m = link_mass, r = [d_length, 0], radius = link_radius, color = link_color) {
    "Dyad": {
      "placement": {
        "diagram": {
          "iconName": "default",
          "x1": 1170,
          "y1": 380,
          "x2": 1370,
          "y2": 580,
          "rot": 270
        }
      },
      "tags": []
    }
  }
  fixed_rotation_tf = MultibodyComponents.PlanarMechanics.FixedRotation(alpha = alpha_tf) {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 1560, "y1": 630, "x2": 1760, "y2": 830, "rot": 0}
      },
      "tags": []
    }
  }
  end_effector = EndEffector() {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 1810, "y1": 630, "x2": 2010, "y2": 830, "rot": 0}
      },
      "tags": []
    }
  }
  speed = RotationalComponents.Sources.SpeedSource() {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 260, "y1": 860, "x2": 460, "y2": 1060, "rot": 0}
      },
      "tags": []
    }
  }
  w0_const = BlockComponents.Sources.Constant(k = w0) {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 0, "y1": 860, "x2": 200, "y2": 1060, "rot": 0}
      },
      "tags": []
    }
  }
  world = MultibodyComponents.PlanarMechanics.World() {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 0, "y1": 550, "x2": 200, "y2": 750, "rot": 0}
      },
      "tags": []
    }
  }
  fixed = RotationalComponents.Components.Fixed() {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 310, "y1": 1130, "x2": 410, "y2": 1230, "rot": 0}
      },
      "tags": []
    }
  }
  parameter a_length::Length = 0.53
  parameter b_length::Length = 0.4374
  parameter c_length::Length = 0.5
  parameter d_length::Length = 0.15
  parameter link_mass::Dyad.Mass = 1.5
  parameter w0::AngularVelocity = -0.5
  "Initial angle of the base->a revolute joint"
  parameter phi0::Angle = deg2rad(10)
  parameter alpha_tf::Angle = 0
  parameter link_radius::Real = 0.03
  parameter link_color::Real[4] = [0.9, 0.9, 0.9, 1.0]
relations
  guess link_d.body.phi = 0
  guess link_d.translation.phi = 0
  guess link_b.translation.frame_b.fx = 1e-10
  guess end_effector.body.frame_a.tau = 1e-10
  guess link_b.translation.frame_b.fy = 1e-10
  guess link_b.body.phi = 1e-10
  guess link_b.translation.phi = 1e-10
  guess speed.phi = 1e-10
  guess end_effector.body.alpha = 1e-10
  initial base_a.phi = phi0
  # First chain: base → upper_arm → elbow
  connect(base.frame_b, base_a.frame_a) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
  connect(base_a.frame_b, upper_arm.frame_a) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
  connect(upper_arm.frame_b, a_cd.frame_a) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
  connect(a_cd.frame_b, link_c.frame_a, link_d.frame_a) {
    "Dyad": {
      "edges": [
        {"S": 1, "M": [], "E": -1},
        {"S": -1, "M": [], "E": 2},
        {"S": -1, "M": [], "E": 3}
      ],
      "junctions": [{"x": 1270, "y": 730}],
      "renderStyle": "standard"
    }
  }
  # Second chain: base2 → link_b → link_d (closes the loop)
  connect(base2.frame_b, base2_b.frame_a) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
  connect(base2_b.frame_b, link_b.frame_a) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
  connect(link_b.frame_b, b_d.frame_a) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
  connect(b_d.frame_b, link_d.frame_b) {
    "Dyad": {
      "edges": [{"S": 1, "M": [{"x": 1270, "y": 340}], "E": 2}],
      "renderStyle": "standard"
    }
  }
  # End-effector: on link_c via fixed rotation
  connect(link_c.frame_b, fixed_rotation_tf.frame_a) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
  connect(fixed_rotation_tf.frame_b, end_effector.frame_a) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
  # Drive the base revolute at constant angular velocity
  connect(speed.spline, base_a.flange_a) {
    "Dyad": {
      "edges": [{"S": 1, "M": [{"x": 620, "y": 960}], "E": 2}],
      "renderStyle": "standard"
    }
  }
  connect(w0_const.y, speed.w_ref) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
  connect(fixed.spline, speed.support) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
metadata {"Dyad": {"tests": {"case1": {"stop": 10}}}}
end


Test Cases

julia
using MultibodyComponents
using DyadInterface: TransientAnalysis, rebuild_sol, ODEAlg
using ModelingToolkit: toggle_namespacing, get_initial_conditions, @named
using CSV, DataFrames, Plots

snapshotsdir = joinpath(dirname(dirname(pathof(MultibodyComponents))), "test", "snapshots")
<< @setup-block not executed in draft mode >>

Test Case case1

julia
@named model_case1 = MultibodyComponents.PlanarMechanics.examples.ParallelKinematicRobot()
model_case1 = toggle_namespacing(model_case1, false)

model_case1 = toggle_namespacing(model_case1, true)
result_case1 = TransientAnalysis(; model = model_case1, alg = ODEAlg.Auto(), start = 0e+0, stop = 1e+1, abstol=1e-6, reltol=1e-6)
sol_case1 = rebuild_sol(result_case1)
<< @setup-block not executed in draft mode >>
  • Examples

  • Experiments

  • Analyses