# No. 154 (Brown 1868): "Circular motion into alternating rectilinear motion, by the action of the studs on the rotary disk upon one end of the bell-crank, the other end of which has attached to it a weighted cord passing over a pulley."
#
# Model (cm): the disk (the one driven joint, 20 turns a minute, clockwise in the view) carries two studs 4.5 cm out, behind it, on opposite sides. Each in turn strikes arm 1 of a bell-crank pivoted at the right and swings it
# 46 degrees, to where the arm is clear of the studs. Arm 2 carries a cord that passes over a pulley and carries a weight (0.6 kg); the crank's swing draws the cord and raises the weight, and when the stud has passed the weight
# draws the crank back to its stop. The weight goes up and down twice a turn of the disk. Generator: opencode-runs/batch10/gen154.py.
number: 154
slug: disk-studs-bell-crank-weighted-cord
name: Studs, a bell-crank and a weighted cord over a pulley
brown: "Circular motion into alternating rectilinear motion, by the action of the studs on the rotary disk upon one end of the bell-crank, the other end of which has attached to it a weighted cord passing over a pulley."
units: cm
sim:
  timestep: 0.0002
  integrator: implicitfast
  iterations: 100
  solver: PGS
  multiccd: true
  duration_s: 9.0
  floor: false
bodies:
  - id: disk
    shape: part
    pos: [0, 0, 0]
    mass: 1.0
    friction: 0.05
    color: "#d9cfb6"
    pieces:
      - {kind: rod, from: [0, 0.0, 0], to: [0, 4.0, 0], radius: 0.9, collide: 0, color: "#8f8a80"}
      - {kind: disc, center: [0, 0], radius: 6.2, inner: 5.4, y: [0.0, 0.6], color: "#d9cfb6"}
      - {kind: disc, center: [0, 0], radius: 1.5, y: [0.0, 0.6], color: "#d9cfb6"}
      - {kind: poly, points: [[-0.45, 0.0], [-0.45, 5.7], [0.45, 5.7], [0.45, 0.0]], y: [0.0, 0.6], collide: 0, color: "#d9cfb6"}
      - {kind: poly, points: [[-0.0, 0.45], [5.7, 0.45], [5.7, -0.45], [0.0, -0.45]], y: [0.0, 0.6], collide: 0, color: "#d9cfb6"}
      - {kind: poly, points: [[0.45, 0.0], [0.45, -5.7], [-0.45, -5.7], [-0.45, -0.0]], y: [0.0, 0.6], collide: 0, color: "#d9cfb6"}
      - {kind: poly, points: [[0.0, -0.45], [-5.7, -0.45], [-5.7, 0.45], [-0.0, 0.45]], y: [0.0, 0.6], collide: 0, color: "#d9cfb6"}
      - {kind: rod, from: [-3.8971, 0.6, 2.25], to: [-3.8971, 3.2, 2.25], radius: 0.45, collide: 1, capsule: true, color: "#8f8a80"}
      - {kind: rod, from: [3.8971, 0.6, -2.25], to: [3.8971, 3.2, -2.25], radius: 0.45, collide: 1, capsule: true, color: "#8f8a80"}
  - id: crank
    shape: part
    pos: [8.5, 0, 0.0]
    mass: 0.1
    friction: 0.05
    color: "#a89a7e"
    pieces:
      - {kind: poly, points: [[8.5, -0.4], [1.5, -0.4], [1.5, 0.4], [8.5, 0.4]], y: [1.6, 2.4], collide: 2, color: "#a89a7e"}
      - {kind: poly, points: [[8.225, 0.0], [8.225, 6.0], [8.775, 6.0], [8.775, 0.0]], y: [1.6, 2.4], collide: 0, color: "#a89a7e"}
      - {kind: disc, center: [8.5, 0.0], radius: 1.0, y: [1.4, 2.7], color: "#8f8a80"}
      - {kind: disc, center: [8.5, 6.0], radius: 0.5, y: [1.4, 2.7], color: "#8f8a80"}
  - id: weight
    shape: part
    pos: [14.2, 0, -3.8]
    mass: 0.6
    friction: 0.05
    color: "#6b5a44"
    pieces:
      - {kind: poly, points: [[13.0, -5.1], [15.4, -5.1], [15.4, -2.5], [13.0, -2.5]], y: [1.0, 3.0], collide: 0, color: "#6b5a44"}
  - id: frame
    shape: part
    pos: [0, 0, 0]
    fixed: true
    color: "#cfc6b4"
    pieces:
      - {kind: poly, points: [[-11, -10.7], [18.0, -10.7], [18.0, -9.7], [-11, -9.7]], y: [-3.0, 5.0], collide: 0, color: "#b9b09c"}
      - {kind: poly, points: [[-1.0, -9.7], [1.0, -9.7], [0.8, -1.0], [-0.8, -1.0]], y: [3.4, 4.4], collide: 0, color: "#cfc6b4"}
      - {kind: poly, points: [[7.6, -9.7], [9.4, -9.7], [9.2, -1.0], [7.8, -1.0]], y: [2.8, 3.8], collide: 0, color: "#cfc6b4"}
      - {kind: poly, points: [[12.6, -9.7], [13.4, -9.7], [13.4, 7.0], [12.6, 7.0]], y: [2.6, 3.4], collide: 0, color: "#cfc6b4"}
      - {kind: disc, center: [13.0, 7.0], radius: 1.6, inner: 1.2, y: [1.1, 2.9], color: "#8f8a80"}
      - {kind: disc, center: [13.0, 7.0], radius: 1.2, y: [1.6, 2.4], color: "#a89a7e"}
      - {kind: rod, from: [13.0, 2.4, 7.0], to: [13.0, 3.0, 7.0], radius: 0.35, collide: 0, color: "#8f8a80"}
joints:
  - {id: j_d, type: hinge, body: disk, axis: [0, 1, 0], damping: 0.002}   # the one driven joint; + : clockwise
  - {id: j_c, type: hinge, body: crank, axis: [0, 1, 0], range: [-0.8029, 0], damping: 0.02}   # the bell-crank; + : clockwise (arm 2 swings right, the weight falls); rests against its stop at 0
  - {id: j_w, type: slide, body: weight, axis: [0, 0, 1], damping: 0.3}   # the weight; + : up
ropes:
  - {id: cord, from: {body: crank, at: [8.5, 2.0, 6.0]}, over: {center: [13.0, 2.0, 7.0], radius: 1.2, axis: y, side: [13.0, 2.0, 11.2]}, to: {body: weight, at: [14.2, 2.0, -2.5]}, width: 0.5, thickness: 0.3}
contact: {solref: [0.002, 1.0], solimp: [0.95, 0.99, 0.0005], margin: 0}
driver: {joint: j_d, kind: velocity, rpm: 20, kv: 20.0, max_torque: 20}
checks:
  - {type: follow, out: j_w, in: j_c, expect: -0.0597, tol: 0.0072, min_r2: 0.97, settle_s: 1.3, window_s: 0.2}
  - {type: follow, out: j_w, in: j_c, expect: -0.0597, tol: 0.0072, min_r2: 0.97, settle_s: 2.8, window_s: 0.2}
  - {type: follow, out: j_w, in: j_c, expect: -0.0597, tol: 0.0072, min_r2: 0.97, settle_s: 4.3, window_s: 0.2}
  - {type: position, joint: j_w, min: -0.3, max: 5.1813, settle_s: 0.0, window_s: 8.5}
camera: {target: [3, 0, -1.0], position: [-14.0, -62.0, 6.0], fov: 34}
display:
  output: j_w
  labels: {j_d: "Disk (driver)", j_c: "Bell-crank", j_w: "Weight"}
  proof: {label: "Studs out of contact", sub: "the disk turns but the crank and the weight stand"}

